做一台带 LSRB 路线记忆的线迷宫求解机器人
一台机器人:能自己探索胶带线迷宫,记住遇到的每一个路口,然后从起点到终点跑出最短路线,一个弯都不走错。
循迹车只是跟随,线迷宫求解器却要做决定。这就是本项目要跨越的全部一步,而且它比看上去要大:机器人不再是一个带轮子的控制回路,而变成了会去探索从未见过的环境、记住自己发现了什么、并据此行动的东西。
诀窍在于,这些东西一样都没有替换循迹车——它是在循迹车之上搭起来的。底下还是那套反射阵列和那个 PID 回路,负责让机器人保持在胶带中线上,对迷宫一无所知。上面是一层很薄的决策层,负责盯住线路分岔的瞬间,判断遇到的是哪种路口,选定一个方向,并记下一个字符。正是这种分层让项目变得可做,而真实机器人在任何地方用的都是同一个两层划分。
所以制作顺序比平时更要紧。你得先让单纯的循迹真正稳定下来——先在模拟器里调,再在用真胶带贴成的大椭圆上跑——之后才加路口。跳过这份纪律,那么每一个机械问题、每一次标定漂移、每一只偏了 2 mm 的轮子都会伪装成迷宫求解的缺陷冒出来。
下面的技术树请从上往下走。每个节点在前置条件完成后解锁,你的进度会保存在这台设备上,因此可以用一个周末做完这台机器人,而不会丢掉进度。
物料清单
| 零件 | 数量 | 大致价格 | 备注 |
|---|---|---|---|
| Arduino Nano | 1 | $5 | A0–A7 提供八个模拟通道;Uno 的六个不够用 |
| 红外反射阵列,8 通道 | 1 | $8–12 | **要八通道,而且是模拟的。**路口检测需要最外侧的传感器 |
| TB6612FNG | 1 | $3 | 在这里值得花这个钱:L298N 约 2 V 的压降会拖累那些要求精确的低速动作 |
| TT 减速电机 | 2 | $4 | 强烈推荐带编码器的版本,转弯才能可重复 |
| 两轮底盘 | 1 | $6–10 | |
| 电池包 | 1 | $6 | 2 节 18650,带保护电池盒 |
| 哑光黑胶带,19 mm | 1 卷 | $3 | 还需要一大块浅色地面或板子来摆放迷宫 |
合计大约 $35–45。八通道阵列是唯一不该省钱的部件,原因很具体:机器人判断出现了左岔,靠的是发现最外侧的左侧传感器变黑,而中间传感器仍然压在线上。宽度只比胶带宽出一点的阵列在物理上看不到这一点,于是路口检测就变成了猜谜,代码写得再好也没用。
为什么阵列必须比线宽
left branch array (8 channels, ~60 mm wide)
────────────────┐ [ x x x . . . . . ] outer left dark -> a branch
│
════════════════╪═══════ [ . . . x x . . . ] centre still on the line
│
经验法则:阵列宽度应当至少是胶带宽度的三倍。对 19 mm 胶带来说约等于 60 mm,而 8 mm 间距的八通道阵列正好是这个宽度。再窄一些,机器人就分不清“线急弯”和“线分岔”,而这正是整个项目赖以成立的核心判断。
按里程碑来做
这里的制作顺序比本站任何一个其他项目都更重要。迷宫求解器就是一个加了决策层的循迹车,而循迹部分出现的每一个机械或标定故障,都会伪装成迷宫求解的缺陷再冒出来。
| # | 里程碑 | 测试 | 通过的样子 |
|---|---|---|---|
| 1 | 循迹正常 | 在大素椭圆上跑十圈 | 零次脱线。不是“基本不脱”——是零 |
| 2 | 转弯可重复 | 命令原地转 90° 十次并测量 | 在 ±3° 以内,且可重复 |
| 3 | 看得见路口 | 慢慢开过一个 T 形口,打印阵列 | 外侧传感器比中间先变黑 |
| 4 | 路口分类 | 慢慢开过每一种路口 | 左 / 右 / T / 十字 / 死胡同全部叫对 |
| 5 | 执行一次转弯 | 遇到左岔、左转、恢复循迹 | 重新抓住线并继续 |
| 6 | 路径记录 | 开过一个小迷宫,打印出字符串 | 得到类似 LSRB 的序列,与你看到的相符 |
| 7 | LSRB 化简 | 把记录的路径喂进化简器 | LBL 变成 S,每条规则都正确触发 |
| 8 | 第二趟 | 跑化简后的路径 | 不走错任何转弯、不用探索就到达终点 |
| 9 | 完整迷宫 | 一个有好几个死胡同的迷宫 | 先探索、再化简,然后跑最短路线 |
里程碑 1 没有商量余地。“基本上能跟线”会变成“偶尔凭空造出一个路口”,然后你会花一个晚上去调路径化简,而真正的故障其实是一只偏了 2 mm 的轮子。
**里程碑 2 是大家会跳过的那一个。**迷宫求解器一趟要执行几百次转弯,而一个每次都少转 5° 的转弯会不断累积,直到机器人彻底脱线。这正是减速箱背隙暴露的地方——误差会随方向改变符号的,是机械问题,不是调参问题。
代码里的两层划分
让这个项目变得可做的那个分层,值得显式看一遍:
┌─────────────────────────────────────┐
decision │ classify junction -> choose turn │ runs only at junctions
layer │ record a character -> simplify │ knows nothing about PWM
└──────────────────┬──────────────────┘
│ "turn left" / "keep going"
┌──────────────────▼──────────────────┐
following │ read array -> position -> PID │ runs every loop, ~200 Hz
layer │ -> left and right wheel speeds │ knows nothing about mazes
└─────────────────────────────────────┘
下面那层永远不会学到迷宫是什么。上面那层永远不碰电机。出了问题时,这条边界会告诉你该查哪一半——如果你说不清一个问题住在哪一半,那说明这两层并没有分好。
做到什么程度算好
| 测量项 | 典型值 |
|---|---|
| 探索速度 | 0.15–0.25 m/s——慢到足以可靠地判断路口 |
| 回跑速度 | 0.3–0.5 m/s——没有决策要做,可以放开跑 |
| 路口分类准确率 | 100%。低于这个数,记录下来的路径就是错的 |
| 转弯可重复精度 | ±3° |
| 路径化简 | 30 个字符的探索路径通常能化简到 8–12 个 |
路口准确率确实是全有或全无的,这一点常常让人意外。一个路口读错就会污染记录下来的字符串,化简器随后会给出一条看起来合法但其实错误的路径,然后回跑就自信地一头撞进墙里。没有部分得分——这也正是为什么探索要慢慢跑,而时间要从回跑那里赚回来。
故障排查
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 看见并不存在的路口 | 一个急弯被读成了分岔 | 把阵列加宽;要求外侧传感器持续变黑至少一小段距离才算 |
| 漏掉路口 | 开得太快,或阵列太窄 | 把探索跑慢;检查阵列宽度是否 ≥3 倍胶带宽 |
| 转弯不一致 | 背隙,或者没有编码器 | 每次都以相同方式进入转弯;量出间隙 |
| 记录路径多出字符 | 同一个路口被检测了两次 | 在路口之后加一段不响应时间,再去找下一个 |
| 化简结果是一条错路径 | 规则应用顺序错了 | 先单独测 LBL→S、LBR→B、SBL→R 这类规则 |
| 回跑在第一个转弯就失败 | 路径是相对错误的航向记录的 | 这个字符串是相对转弯的序列——检查约定 |
| 这个迷宫行,那个迷宫不行 | 路口间距对不响应时间来说太密 | 缩短不响应时间,或者再放慢速度 |
| 转弯之后脱线 | 转过头冲过了新线路 | 转到中间传感器重新抓住线为止,而不是按固定角度转 |
| 越跑漂得越厉害 | 电池电压下垂,等效增益发生变化 | 用编码器闭合一个速度环 |
接下来可以往哪走
**加上编码器,按距离转弯而不是按时间。**定时转弯是第一台迷宫求解器最大的不可靠来源,因为所需时间会随电池电压和地面而变。基于编码器的转弯不会。
转向墙式迷宫——也就是微型迷宫鼠——它用墙取代胶带,用洪水填充取代 LSRB 规则。那才是真正更大的一步:LSRB 是一种沿墙走的启发式算法,能找到一条路,而洪水填充算出的是最短的那条,并且会随着新墙被发现而重新规划。
**优化回跑。**一旦路径已知,就没有任何决策要做了,机器人可以在直线上加速,只在转弯前减速。在已知路线上套一条运动曲线,明显的时间提升就来自这里——往往能把回跑时间砍掉一半。
项目路线图
搭建路径
沿着技术树,从零件一路走到一台能正常工作的机器人。每个节点在其前置条件完成后解锁,你的进度会保存在这台设备上。
已完成 0 / 21
元器件
本路径中的教程
- 入门 · 阅读约 20 分钟制作循迹机器人:从传感器到 PID 转向从红外反射传感器到加权误差,再到平滑的 PID 转向——循迹机器人究竟是如何工作的。
- 入门 · 20 分钟读取用于循迹的红外反射传感器阵列把一排红外传感器的读数变成一个平滑的线位置,用它来控制转向。
- 入门 · 阅读约 18 分钟如何整定 PID 控制器:一份实用指南一套动手整定 P、I、D 增益的顺序,不再靠猜——以及如何实时尝试每一步。
- 中级 · 阅读约 14 分钟用红外传感器阵列检测线迷宫中的路口用反射阵列区分 T 型路口、十字路口、左转、右转、死胡同和终点,并解决有歧义的情况。
- 中级 · 阅读约 15 分钟面向线迷宫机器人的 LSRB 路径化简把每次转弯记为 L、S、R 和 B,再把每一段死胡同绕行折叠成最优路线。
接线之前先练习
用在线模拟器把它调好
搭建路径会经过一个浏览器实验台。先在这里把行为调对,再把参数迁移到真实的机器人上。
常见问题解答
怎样用 Arduino 做一台迷宫求解机器人?
先做出一台能用的循迹车:一个反射阵列、一个 PID 回路和一个电机驱动。然后在上面加一层决策层,让它注意到路口,按左手法则选一个分支,并把每一次转弯记成四个字符之一——L、S、R 或 B。机器人到达终点后,替换规则会把字符串里每一段死胡同绕路都压缩掉,第二趟就沿着化简后的路线跑。这条制作路线会带你走完整个链条,而且你会先在浏览器模拟器里调好循迹层。
循迹车里的 LSRB 算法是什么?
LSRB 代表 Left(左转)、Straight(直行)、Right(右转)、Back(掉头)——机器人在路口能做的四件事。机器人在探索时每经过一个路口就记下一个字符,而每一个 B 都标志着一个它不得不倒退出来的死胡同。六条替换规则会把每一个以 B 为中心的三字符窗口,替换成能达到同样效果的单次转弯,从而把绕路彻底去掉。反复进行,直到不再有 B,你就得到了最短路线。
线迷宫和墙式迷宫有什么区别?
线迷宫是浅色板面上的黑色胶带,用朝下的反射阵列来感知;墙式迷宫——也就是微型迷宫鼠(Micromouse)的形式——有实体墙,用距离传感器来感知。两者的感知方式完全不同,但上面那一层是一样的:先探索以获取信息,再跑最佳路线。线迷宫的制作成本低得多,这也是中学和大学的比赛通常采用它的原因。
开始这个项目之前需要先买零件吗?
不需要。循迹层、它的 PID 增益,以及先探索再优化的行为,都可以在浏览器模拟器里运行,所以你可以在花任何钱之前先理解整台机器人。只有最后四步——接线、标定、探索趟和回放——才需要实体的 Arduino、传感器阵列、驱动器、电机、底盘和电池。
为什么我的迷宫机器人会在错误的路口转弯?
几乎总是因为它决定得太早。瞬时的传感器图样无法区分 T 形口和十字路口——两者在整个阵列上读到的都是一片黑。机器人必须先记下出现了哪些分支,再往前开大约一个车身长度,然后重新读一次,才能知道线是否也继续向前延伸。凭第一次读数就做决定,是那些自信的错误转弯最常见的单一原因。
LSRB 对任何迷宫都有效吗?
只对完美迷宫有效——也就是没有环路、任意两点之间恰好只有一条路径相连的迷宫。胶带线迷宫几乎总是这样。如果迷宫里有环,左手法则可能会永远绕圈,也不存在可供规则压缩的死胡同;这时你需要一张真正的地图,以及洪水填充之类的图搜索算法。