交互式模拟器中级

线迷宫求解机器人模拟器:LSRB 路线规划

在浏览器里运行线迷宫求解器:胶带贴出的迷宫、路口检测,以及把含死胡同的路线折叠成最短路线的 LSRB 代换规则。

类别
Arduino
时长
2–3 小时
平台
浏览器 · Arduino
线迷宫求解机器人模拟器:LSRB 路线规划 技术示意图JUNCTIONS → L S R B → ROUTEBB

01 / 从这里开始

简介

线迷宫机器人就是一台还能做决策的循迹机器人。这个实验台驱动它沿着黑色胶带行进,对每一个路口进行分类,每走一步就写下一个字符。当它到达终点时,你会看到 LSRB 替换规则一条接一条地触发,把每一处死胡同绕行从记录中折叠掉,直到只剩下一个不含 B 的字符串——那就是最短路线,机器人随后会沿着它再跑一遍。

Live lab / Junction detection & LSRB route memory

Line maze simulator

A line follower drives a taped maze, recording every turn as L, S, R or B. Watch it back out of dead ends, then watch the substitution rules collapse that string into the shortest route — and drive it again.

Browser native
A line maze lab. A robot starts at the bottom-left of a taped maze and follows the left-hand rule to the finish at the top-right, recording one turn symbol per junction and backing out of every dead end. The LSRB substitution rules then collapse that record into the shortest route, which the robot drives again as a speed run. Use the controls below to run it or step one move at a time.

The dark lines are the tape. The orange trail is everywhere the robot drove while exploring, dead ends included; the teal line is the simplified route it speed-runs. The bar above the robot is its eight-channel reflectance array — a whole side lights up when a branch opens there.

  • Tape
  • Explored (dead ends included)
  • Simplified route
  • Finish

Route memory

The robot writes one symbol per move. Every B is a dead end it had to reverse out of.

Press Start — the string builds as the robot drives.

Simulation

Ready. Press Start to explore the line maze, or Step one move at a time.

Phase
Ready
Junction
—
Explored turns
— moves
Simplified turns
— moves
Saved
—
Maze
—

Keyboard: focus the maze, then use Space to run/pause, N to step, R to reset, M for a new maze, and F for full screen.

控件

模式用来在完整的三幕运行——探索、化简、再快速跑一遍—— 和直接跳到成品路线之间选择。运行速度设定机器人开得多快。 开始、暂停和单步让它连续运行或一次走一步, 重置重播同一个迷宫,新迷宫生成一个新的。 把画布聚焦之后,用空格、N、R、M 和 F 可以从键盘上使用同样的控制。

迷宫下面的路线记忆条是值得盯着看的部分。机器人行进时它每走一步 填入一个符号,然后在化简阶段随着每次替换触发而重写自己。

原理

线迷宫机器人是分两层建造的,而把它们分开正是它变得可处理的原因。

下层是一台普通的循迹机器人。八通道反射阵列读取胶带, 读数被压缩成一个加权误差,然后一个 PID 回路 把这个误差变成两个不同的轮速。这一层对迷宫一无所知。

上层只在胶带出现分支时才醒来。它对路口进行分类—— 左、右、T 字、十字、死胡同或终点——按左手法则挑一个分支, 并往一个字符串里追加一个字符。这个模拟器里画在机器人鼻子上横着的那条 就是那个阵列,而你可以看着一条分支打开时整侧亮起来。

麻烦在于那一瞬间的读数是有歧义的。T 字路口、十字路口和终点块 都会报告所有通道都是黑的。机器人必须越过路口做出承诺,然后再读一次, 才知道自己刚刚穿过的是什么。

算法

探索用的是左手法则:在每一个格子选最靠左的可行选项, 只有当死胡同让它别无选择时才掉头。在没有环的迷宫上这总能到达终点, 而且它无状态到能手工验证。

每走一步都追加一个符号。L、S 和 R 是转弯; B 只出现在机器人从死胡同掉头出来的地方。所以成品字符串里的每一个 B 都标记着一处错误,连同它前面那个转弯和后面那个转弯。

这个三字符窗口永远可以被一个单独的转弯替换,因为这三步不过是 加起来的角度。把左记作 −90°、直记作 0°、右记作 +90°、掉头记作 180°, L B L 的和是 0°,也就是 S——干脆直穿过去,根本不要拐进那条支路。 六条替换规则就是这套算术的制表版本。

一遍是不够的:把一处绕行折叠掉,可能会把两个转弯挤到一起, 而它们现在又构成了一个新的可折叠窗口。所以规则要反复施加, 直到没有任何变化为止。循环结束时,字符串里不再有 B, 这就是它已经完成的证明——任何残留的死胡同仍然会显示出一个。

源代码

// Repeat until a full pass changes nothing: collapsing one detour
// can push two turns together that are themselves reducible.
void simplify(String& route) {
  bool changed = true;
  while (changed) {
    changed = false;
    for (int i = 1; i + 1 < route.length(); i++) {
      if (route[i] != 'B') continue;          // windows centre on a turn-back
      route = route.substring(0, i - 1)
            + fold(route[i - 1], route[i + 1])
            + route.substring(i + 2);
      changed = true;
      break;
    }
  }
}

fold 就是那张替换表,它很短,因为它只是角度算术: 把 180° 掉头两侧的两个转弯相加,卷回 ±180°,再把结果映射回一个符号。

假设与硬件差异

胶带被渲染成完美的黑配完美的白,没有卷曲、反光或阴影, 反射阵列在固定高度上报告理想的二值。真实的红外阵列看到的是 会随环境光、传感器高度和胶带磨损而变化的灰阶反射, 所以每次上硬件都必须先按接线那一节的说明扫标定白和黑。 模拟器还以完美的周期运行 PID 回路,并且每个决策干净地前进一格; 而在 Arduino 上,回路抖动、轮子打滑和 2 mm 的安装偏移 都会表现为路口误分类。请把这里的增益和 LSRB 字符串当作要迁移的逻辑, 而不是可以照抄的数字。

电路图

这个实验台所建模的机器人,就是线迷宫求解机器人制作路线 里的那一台:一块 Arduino Nano 通过模拟引脚读取一个八通道反射阵列, 并通过 TB6612FNG 驱动两个减速电机。

最要紧的接线规则是电源的分离。电机电池只接驱动器的 VM 引脚,别接别处; Arduino 的 5 V 只供逻辑;而每一处地——板子、驱动器、传感器阵列、电池负极 ——都必须连在一起,否则控制信号没有参考,故障会悄无声息。

硬件清单

元器件

  • Arduino Nano 或 Uno
  • 八通道红外反射式传感器阵列
  • TB6612FNG 双路电机驱动
  • 装在 2WD 底盘上的两个减速直流电机
  • 贴在浅色板上的黑色电工胶带

探索关联图谱

哪里用到这个模拟器

以这个实验台为基础的项目、学习路线和教程。

继续搭建

下载资源

完成项目时可以参考本页上的这些资料。可下载的项目包只会在其源文件和版本发布之后才会添加。

常见问题

常见问题解答

什么是线迷宫机器人?

就是在循迹机器人之上加了一个决策层。下层用反射阵列和 PID 回路让机器人保持在黑色胶带的中央,和普通的循迹机器人完全一样。上层则留意胶带出现分支的时刻,判断这是哪一种路口,选择一个方向,并把这次转弯记录下来。正是这份记录,让它第二次跑这个迷宫时一个弯都不会走错。

线迷宫和 Micromouse 迷宫有什么不同?

两者的环境和感知方式完全不同。线迷宫是贴在浅色板上的黑色胶带,由朝下的反射阵列读取;Micromouse 迷宫则有实体的墙,由距离传感器读取。换过来之后依然成立的是策略——先探索以收集信息,再跑最佳路线。线迷宫的制作成本低得多,这也是中学和大学竞赛通常采用它的原因。可以在迷宫求解模拟器里比较这两者。

LSRB 代表什么?

左(Left)、直行(Straight)、右(Right)和掉头(Back)——机器人在路口能做的四件事。在探索运行中,机器人每走一步就追加一个字符,而每一个 B 都标记着一个它不得不掉头退出来的死胡同。随后,六条替换规则会把每个以 B 为中心的三字符窗口,替换成能达到同样效果的单个转弯,从而把这段绕行彻底删掉。

为什么机器人不能在看到路口的那一刻就做决定?

因为传感器的读数模式是有歧义的。T 字路口、十字路口和终点标记都会让整个阵列同时亮起,而左侧分支无论线是否还继续向前延伸,读数都一样。机器人必须记下出现了哪些分支,向前开大约一个车身的长度,再读一次,才能知道前方是否还有直行的路。凭第一次读数就做决定,是那些“自信满满地拐错弯”最常见的原因。

LSRB 对所有迷宫都适用吗?

只适用于完美迷宫——没有环路、任意两点之间恰好只有一条路线相连的迷宫。用胶带贴成的竞赛迷宫几乎总是这样,本模拟器生成的也是这种迷宫。如果迷宫里有环,左手法则可能会永远绕圈,而且也没有死胡同可供规则折叠;这时你就需要一张真正的地图和一种图搜索算法,比如洪水填充。

这在 Arduino 上要占用多少内存?

几乎不占,这正是它的全部魅力所在。整张地图就是一个字符数组——对竞赛迷宫来说也就几十个字节——因为机器人从不存储迷宫本身,只存储它走过的转弯。相比之下,洪水填充机器人要为网格里的每一个格子保存一个距离值。这就是其中的取舍:LSRB 极其小巧,但需要没有环路的迷宫;洪水填充更占资源,但什么迷宫都能应付。

延伸阅读

参考资料

权威资料,帮助你越过本模拟器有限的教学模型,进一步深入学习。