做一台能横着走的麦克纳姆轮机器人
一台机器人:全程不转向地横移走完一个 1 m 的正方形,回到起点时误差在 5 cm 以内;你用手转动它时,它仍朝着地面上的同一方向行驶。
做的是什么
一台四轮机器人,可以朝地面上的任意方向移动而无需先转向,也可以原地转向而不改变前进方向。把它侧着推进一条勉强容得下它的过道;让相机始终对着某个目标、同时绕着它转;偏离直线 3 cm 时直接横移 3 cm 修正,而不是划一道弧出去、再划一道弧回来。
这是本站第一台拥有三个独立可控速度(而不是两个)的机器人。它也是第一台传动系统确实比传感器还难搞定的机器,这也正是几乎整台制作都是电机、编码器和控制回路的原因。
验收标准故意定得很直白:**全程横移走完一个 1 m 的正方形,回到起点时误差在 5 cm 以内,且航向不变。**差速驱动的机器人根本没法尝试这项测试。
贯穿整个项目的那一个数
这台机器上的一切最终都可以归结为一个常数:
k = lx + ly
其中 lx 是轴距的一半(从前轴到后轴的距离取一半),ly 是轮距的一半(从左轮到右轮的距离取一半)。在参考机型上,这两个值分别是 75 mm 和 85 mm,所以 k = 0.160 m。
这同一个数把旋转和各个轮子耦合在了一起。算错了车照样能开——但纯旋转指令会让它在地面上慢慢平移,纯横移则会走弧,因为旋转和平移在互相串扰。测量时要量轮中心到轮中心,而不是量底盘板,底盘板通常比你以为的要宽。
开工之前还值得用记号笔写在底盘上的几个数:
| 量 | 参考机型 | 来源 |
|---|---|---|
| 轮半径 r | 48.5 mm | 97 mm 的麦克纳姆轮 |
| 每个车轮转一圈的计数 | 1440 | 12 CPR × 30:1 × 4 个正交边沿 |
| 每个计数对应多少米 | 212 µm | 2πr ÷ 1440 |
| 轮子最高转速 V_MAX | 0.60 m/s | 架空实测后再留 15% 余量 |
| 对角速度上限 | 0.424 m/s | V_MAX ÷ √2,换电机也去不掉这个限制 |
| 加速度上限 | 5.9 m/s² | μ = 0.85 时的 μg/√2——质量约掉了 |
物料清单
| 物料 | 数量 | 大致价格 | 备注 |
|---|---|---|---|
| 麦克纳姆轮,80 或 97 mm | 4 | £28–70 | 按四只一套买——两左手、两右手 |
| N20 带编码器减速电机,30:1 | 4 | 每只 £9–14 | 要挑一致。轮子上 100–250 rpm 是有用的区间 |
| TB6612FNG 双 H 桥 | 2 | 每块 £4–8 | L298N 也能用,但要为此损失约 3 V;在 2S 电池上这几乎就是你全部的速度 |
| ESP32 开发板 | 1 | £6–12 | 四路 PWM 通道、四对编码器中断,还白送 Wi-Fi 遥测 |
| MPU6050 IMU | 1 | £2–4 | 平放,远离电机,装在底盘的中轴线上 |
| 2S LiPo,1500–2200 mAh,25C | 1 | £12–20 | 按电流而不是按容量来选——四台电机堵转时合计约 5 A |
| 5 V BEC 或降压模块 | 1 | £3–5 | 不要让 ESP32 走电机电源轨 |
| 底盘板,200 × 180 mm | 1 | £10–25 | 激光切割亚克力、3 mm 铝板,或者自己开料 |
| 电机座、轮毂、紧固件 | 1 套 | £8–15 | 轮毂孔径要配电机轴——3、4 或 6 mm |
| 大容量电容,470 µF | 2 | £1 | 每块驱动器的电机电源轨上各并一个 |
**合计 £90–170。**光是轮子和四倍的电机数量,就把两轮车 £50 的预算变成了这个数。
整体怎么接线
2S LiPo ──┬── 470 µF ── TB6612FNG #1 ── FL motor ── FL encoder ─┐
│ └── FR motor ── FR encoder ─┤
├── 470 µF ── TB6612FNG #2 ── RL motor ── RL encoder ─┼── ESP32
│ └── RR motor ── RR encoder ─┘ (4 PWM,
└── 5 V BEC ──────────────────────────────── ESP32 ────── 8 GPIO,
│ I²C)
MPU6050 ── I²C ─┘
三个不太显然的接线决定:
- **ESP32 用自己的稳压器。**四台电机同时启动会把电池电压拉得很低,而共用那条电源轨的控制器就会欠压,在指令执行到一半时重启。它的表现和固件崩溃一模一样。责怪代码之前,先读电源预算教程。
- **每块驱动器上并一个大容量电容。**470 µF,尽量贴近板子。H 桥是阵发式取电的,而引线里的电感会把这些阵发电流变成尖峰。
- **IMU 装在中轴线上,平放,并且尽可能远离电机。**偏航漂移本身已经够烦了,何必再掺进四台电机的磁场。
按里程碑来做
每一个里程碑都配一次测试。不要把失败带到下一步——在四电机机器人身上,失败会成倍放大。
1. 装上轮子,做 X 检查
把四个轮子装上,人站到机器人正上方。顺着每个轮子顶部能看见的滚子连线看。
**测试:**这四条线都指向机器人中心,画出一个 X。如果画出的是菱形,就把对角的两只轮子对调。通过:是个 X。这项五秒的检查能省下一天。
2. 逐个检查电机
四路全部接好,写一段程序,让轮子以 40% 占空比每次只驱动一个、持续一秒。
**测试:**依次调用,确认指定的轮子朝指定方向转。*通过:四个轮子、四个正确方向,没有接反的那一对。*接线问题要在硬件上改,不要在代码里加负号解决——你迟早会搞混。
3. 编码器
用手把每个轮子转一整圈。
**测试:**把计数打印出来。*通过:与 1440 相差在 2% 以内,且轮子正转时计数为正。*如果计数跳变或反向,说明你只在一个通道上触发中断,或者在读 volatile long 时没有关中断。
4. 架空验证运动学
把机器人架在垫块上,下发一个纯横移指令。
**测试:**对角的两只轮子方向相反——左前和右后朝一个方向,右前和左后朝另一个方向。*通过:正是这个规律。*然后下发一个纯旋转指令:左侧一边、右侧另一边。如果某个轮子不一致,说明它装错了角,第 1 步骗了你。
5. 单个速度环
先在垫块上、只用一个轮子调前馈再加 PI,然后再带载调。
**测试:**下发 0.3 m/s,用手指压住轮胎。*通过:速度保持得住,而且 PWM 明显上升。*这一步认真做好一次就行;另外三个只是它的复制品,只是各自有自己的 kS 和 kV。
6. 四路一起走直线
四个速度环、100 Hz、在地面上。走 3 m 直线。
**测试:**测量终点的横向漂移。*通过:小于 20 mm,而且三次跑下来都能重复。*开环情况下通常是 80–200 mm,并且每次都不一样。
7. 横移 1 m
**测试:**横向正好走一米,把距离和航向变化都量下来。*通过:距离在 5 cm 以内,航向在 3° 以内。*如果弧线每次都一样,说明 k 常数不对;如果杂乱无章,说明某个速度环没稳住。
8. IMU 与场地定向
开机时做偏置标定,再加一个航向复位按钮。
**测试:**把摇杆推向前方,用手把机器人整整转一圈。*通过:它仍然朝着同一个方向在地面上前进。*站着不动时,偏航漂移每分钟小于 3°。
9. 正方形
这就是验收测试。向前 1 m、向右 1 m、向后 1 m、向左 1 m,任何一段都不下发旋转指令。
**测试:**与起点的距离,以及航向变化。通过:分别在 5 cm 和 3° 以内。
做到什么程度算好
| 测量项 | 第一次尝试,开环 | 调好之后,闭环 |
|---|---|---|
| 3 m 直线的横向漂移 | 80–200 mm,随电池电量变化 | 小于 20 mm,可重复 |
| 1 m 横移精度 | 10–20 cm,能看出明显的弧线 | 5 cm 以内 |
| 横移正方形过程中的航向变化 | 10–30° | 小于 3° |
| 最高对角速度 | 削波之后还剩多少就是多少 | 0.42 m/s——干净地达到 √2 上限 |
| 电池从 8.4 V 掉到 7.0 V 时的速度 | 下降约 17% | 在电机饱和之前基本不变 |
| 走完正方形的里程计误差 | 不值得测 | 良好地面上 2–5 cm,积灰地面上差得多 |
最后一行是实话,而不是让人失望的话。在这套装动上,滚子打滑本身就是机理,所以即便一切正常,里程计也是整台车上最弱的一项。提前接受这个预期,而不是去追它。
值得注意的硬件细节
**轮子的左右手是整套才有的属性。**在同一个商品页里分两次单独下单买的两只,往往是同一只手性。开钻之前先确认。
**每个滚子都必须能自由转动。**装轮子之前用手拨一遍每一只。卡死的滚子会时好时坏地把那个角变成一只偏了 45° 的普通轮子,读起来和软件缺陷一模一样。
**麦克纳姆轮很重。**每只 180–400 g,也就是说整台车里最多有 1.6 kg 是轮子,而且是装在力臂末端的旋转质量。这会让机器人手感发沉,也是加速度上限之所以重要的原因。
**地面也是一个元件。**抛光水泥和塑胶地板的 μ 大约是 0.8。积灰的体育馆地面、别人在某台车上喷过发胶留下的一层、或者塑胶地板的接缝,都会让局部摩擦系数减半,机器人一跨过去行为就变了。在怪调参之前,先看看μ = 0.25 时会发生什么。
出问题时看这张表
| 现象 | 原因 | 处理 |
|---|---|---|
| 前进正常,横移却画弧并打转 | 某个轮子装错了角 | 做 X 检查;运动学残差会又大又稳定 |
| 横移方向与指令相反 | 四个轮子全都装反了 | 把左侧一对和右侧一对对调 |
| 原地旋转时还会平移 | k 算错了,或者量的是底盘尺寸 | 重新按轮中心到轮中心测量 |
| 四台电机同时启动时机器人复位 | 是欠压,不是死机 | 给 ESP32 配独立稳压;加大容量电容;检查电池内阻 |
| 对角移动比直线慢得多 | √2 上限——本来就是设计如此 | 无需处理 |
| 任何自动控制下过弯都向外倾 | 逐电机削波,而不是把指令整体缩放 | 按最弱的那只轮子缩放 |
| 手动开得挺好,自主模式下完全没救 | 问题是里程计,不是控制 | 用 IMU 算航向;每次跑短一点;考虑加死轮 |
| 有一只轮子始终饱和 | 指令给过头了,或者那台电机偏弱 | 把 V_MAX 降到四只轮子都真正维持得住的值 |
| 编码器计数在几分钟内漂移 | 高速时漏掉了边沿 | 两个通道都触发中断;确认 ISR 足够短 |
接下来可以往哪走
**死轮。**两到三个不驱动的全向轮,装在弹簧座上,各带自己的编码器。它们不传递扭矩,所以不会打滑,能把这台车上最弱的那一项变成最强的一项。
全向路径跟踪。纯跟踪和 Stanley都假设机器人靠转向来行驶。而一个能横移的底盘可以做得更好——把路径位置和航向分开跟踪,因为你有彼此独立的执行器。
**在能保持航向的底盘上装相机。**这是天生的搭配:当底盘在重新定位时相机还能一直对着目标,视觉管线要好做得多。全向驱动真正的用武之地就在这里。
**ROS 2。**在这套传动上,cmd_vel 的 linear.y——差速驱动机器人会明确忽略它——终于有了实际意义。把把 Twist 转成轮速的那个函数换成四行的麦克纳姆版实现,就是这项工作的绝大部分。
项目路线图
搭建路径
沿着技术树,从零件一路走到一台能正常工作的机器人。每个节点在其前置条件完成后解锁,你的进度会保存在这台设备上。
已完成 0 / 17
元器件
本路径中的教程
- 入门 · 25 分钟全向驱动对比:全向轮、麦克纳姆轮与舵轮四种底盘,三个自由度,以及每种方案为此向你收取的代价。
- 中级 · 阅读约 35 分钟麦克纳姆轮运动学:四个轮子,三个运动轴一个 45° 的滚子就能给出整个矩阵——外加一个没人用的第四个方程。
- 中级 · 35 分钟用编码器实现车轮速度的闭环控制前馈负责主要工作,积分负责收尾,机器人终于能走直线了。
- 中级 · 25 分钟场地坐标驾驶:让“前进”真正意味着前进把摇杆向量旋转负的航向角,机器人就不再和驾驶员对着干了。
- 入门 · 阅读约 17 分钟读取正交编码器,测出轮子的行驶距离与速度把正交编码器的脉冲变成可靠的车轮方向、距离和速度测量值。
- 中级 · 30 分钟车轮打滑:里程计为何漂移,又该如何应对每一篇讲里程计的文章都说打滑会毁掉位置估计。本文讲清打滑到底是什么,以及它的代价。
- 入门 · 30 分钟为什么电机一启动,机器人就复位看起来像代码 bug 的复位,几乎总是电池的问题。先做电流预算,再测量电压跌落。
- 入门 · 30 分钟为什么 delay() 会让机器人失灵:用 millis() 计时卡在 delay() 里的机器人什么也看不见。用 millis() 取代它,并把计数回绕时的比较写对。
接线之前先练习
用在线模拟器把它调好
搭建路径会经过一个浏览器实验台。先在这里把行为调对,再把参数迁移到真实的机器人上。
常见问题解答
可以用 Arduino Uno 来做吗?
不太好做,原因在于引脚数量而不是处理能力。四个轮子需要四路 PWM 输出,四个正交编码器需要四对支持中断的引脚。Uno 有六个 PWM 引脚,分布在三个定时器上——而一旦你用了 Servo 库或 tone(),其中两个就会失效——外部中断引脚则恰好只有两个。你可以用引脚电平变化中断凑合,再放弃一个编码器,但你会把整个周末花在和开发板较劲上,而不是在做机器人。ESP32 或 Mega 2560 只贵几英镑,却能让整个问题消失。本制作使用 ESP32,因为它还能提供 Wi-Fi 遥测,而当你同时调四个控制回路时,这确实非常有用。
做一台麦克纳姆轮机器人要花多少钱?
大约 90–170 英镑,取决于轮子尺寸和电机质量,大致是同等两轮机器人的两倍。增加的开销都在意料之中:四只麦克纳姆轮取代四只普通轮子是最大的一项,然后是四台电机而不是两台、四路 H 桥通道、四根编码器线,以及一块更大的电池,因为四台减速电机堵转时的最坏电流是两倍。控制器升级最容易让人措手不及——要在一开始就把它算进预算,而不是等底盘钻好孔之后才发现。
为什么我的麦克纳姆轮机器人前进正常,横移时却会打转?
有一只轮子装错了角,这是麦克纳姆轮制作中遥遥领先的最常见错误。前进看起来正常,是因为横向分量大部分仍然能互相抵消;暴露问题的是横移,因为装错的那只轮子会横着推向指令方向,而不是顺着指令方向推。站在机器人上方,垂直往下看,顺着每个轮子顶部能看见的滚子连线看:这四条线应该指向机器人中心,画出一个 X。如果画出的是菱形,就把对角的两只轮子对调。在你真的拥有一只装反的轮子之前,就可以在模拟器的“一只轮子装反”预设里,确切地看到它会造成什么后果。
需要 IMU 吗?
对自主测试来说不需要——没有它,机器人照样能走完正方形。对手动驾驶来说需要,而且大约在你拿起遥控器十秒之内就会发现。全向机器人可以车头朝着一个方向,却朝另一个方向移动,所以人几乎马上就会搞不清“侧向”现在到底指向哪边。场地定向控制用一个旋转矩阵就能解决这个问题,而它需要从某处获得偏航角。这是一个 2 英镑的零件加六行代码,而每一个跳过它的团队,都是在有人第一次把机器人开进桌子之后才把它加上的。
麦克纳姆底盘上的里程计有多准?
比本站那些两轮机器人差,而这不是调参的问题。滚子打滑正是横向运动得以发生的方式,所以车轮编码器测到的是轮子的转动,而不一定是相对地面的运动。可以预期,向前的航位推算大致和任何差速驱动机器人一样好,而横向的航位推算会明显更差——在好地面上误差为百分之几,在积灰的地面上要大得多。要为此做好规划:用 IMU 来测航向,让每次自主运行保持简短;如果机器人确实需要知道自己在哪里,就加装不驱动的全向死轮,它们不传递扭矩,因此不会打滑。
这台机器人能推东西吗?
推得很差。麦克纳姆轮只能沿着呈 45 度的滚子轴线方向咬住地面,摩擦限制的是整个力矢量,而只有沿滚动方向的分量才真正推动你前进——所以你大约只能得到同一台机器人装普通轮子时 71% 的牵引力,这还没算上滚子橡胶的抓地力通常不如轮胎。加重也没用,因为更大的质量带来成比例增加的摩擦,也带来成比例增加的惯性,两者正好抵消。如果推挤才是目的,那就改做一台装普通轮子的迷你相扑机器人;它每次都会赢。