搭建路径高级一个周末

用 MPU6050 和 PID 做一台自平衡机器人

一台能自己站起来的两轮机器人:推它也不倒,而且能守在地上的原位,不会越漂越远。

用 MPU6050 和 PID 做一台自平衡机器人 技术示意图θTILT → PID → DRIVE UNDER IT

做的是什么

一台靠两个轮子站着、除了算术之外没有任何东西扶住它的机器人。

机械部分确实简单——两台电机、一个机架、一个传感器、一块电池。让这个项目值得一做的是,它要解决的控制问题没有软性失败:一台循迹车哪怕增益平庸,也还是能跟着线走,只是走得难看;而一台平衡机器人增益平庸,直接就躺在地上了。正是这种尖锐,让它成为真正理解 PID 的最佳途径。

做完车站起、推不倒、大概放哪定哪。

为什么难

机器人的全部质量都位于车轴之上。这让它成为一个倒立摆:竖直是一个平衡点,就像把铅笔立在笔尖上时的平衡——原理上是真实存在的,但没有持续的修正就毫无希望。稍微倾斜一点,重力就会产生一个扭矩,让它倾斜得更多、更快。

机器人唯一的防御手段,是它能够移动自己的底盘。让轮子向前转,就会把车轴推回质心下方,使机身重新转回竖直。这就引出了统治整个项目的反直觉规则:要阻止它向前倒,就向前开。

由此引出两个后果,它们塑造了下面的一切:

  1. 你无法直接控制位置。如果按照位置误差去驱动电机,底盘会在质心下方加速冲出去,于是机器人朝与你期望方向相反的方向倒下。位置必须通过倾角来间接控制。
  2. 存在一个硬性的恢复极限,大约是 35°。超过这个角度,所需的加速度就超出了轮子能在机身落地之前提供的范围,任何增益都无济于事。

物料单

零件 数量 约价 说明
Arduino Uno 或 Nano 1 $5 内环 100–200 Hz,Uno 舒服跑
MPU-6050 1 $2 刚性水平安装,贴轮轴
N20 编码器电机 2 $16 **必须是金属减速箱,没有商量。**见下文
TB6612FNG 1 $3 L298N 那约 2 V 的压降,恰好就落在精细修正所在的位置
两轮底盘 1 $10 高窄。电池装高处——反直觉
电池包 1 $10 2×18650。它同时也是那份有用的质量

合计约 $45–60。

这三项选择都是承重的,其中任何一项弄错,得到的都不只是一台更差的机器人,而是一台根本调不出来的机器人。

**金属减速箱电机。**平衡机器人每秒要做几百次小增量的换向。背隙在每一次换向时都会被计入一次,于是塑料减速箱的死区恰好落在修正必须起作用的地方。结果就是机器人绕着竖直方向来回振荡、永远稳定不下来,无论增益调得多细都没用——而且它看上去非常像是一个调参问题。

**用 MOSFET 驱动器。**L298N 在电机拿到电压之前就烧掉了大约 2 V,这意味着那些细小的修正指令会落到电机根本转不起来的电压之下。这又是一个恰好位于精细修正所在位置的死区。

把电池装在高处。这是最让人意外的一条。车体更高、质量位置更高,倒下去的速度反而更慢——因为摆的周期正比于长度的平方根——这给了控制环更多反应时间。矮而重心低的平衡机器人是更难平衡,而不是更容易。

制作顺序

按这个顺序做。每一步都能单独验证,在一个终态非黑即白的项目上,这一点极其重要。

**1——拿到一个可信的倾角。**接好 MPU6050,按用 MPU6050 读取倾角那一篇做。在扶正时角度接近零、往哪边推就往哪边动、机器人静止时读数保持不动之前,不要往下走。下游的一切都建立在这个数字之上。

**2——让这个角度在运动中站得住。**加速度计单独用在运动中的机器人身上没法用,而陀螺仪单独用几秒内就会漂移。互补滤波用一行代码把两者融合。测试方法是抓着机器人整体晃动而不让它旋转——角度应该几乎不动。

**3——在模拟器里调内环。**在任何硬件倒下之前,先用平衡模拟器建立直觉,理解每个增益各自起什么作用。在一台当前能站住的机器人上把微分增益设为零,看着振荡逐渐变大直到倒下;在模拟器里看到这种失败,比在书桌上看到要便宜得多。

**4——让它站起来。**按级联 PID 平衡控制写出内环,外环保持关闭。这一步的成功标准是一台能保持竖直、并且被允许到处游走的机器人。先不要急着去修这种游走。

**5——加入编码器和外环。**用正交计数得到真实的轮子位置后,开启外环,让机器人守在一个位置上。它的起始增益要设得远低于你直觉上觉得合理的值——因为它的作用是间接的,而且两个环路很容易互相打架。

真正要紧的硬件注意事项

**把电池装在高处。**这违反直觉,却是整个项目里最有用的一项机械选择。抬高重心会增大摆的周期,于是机器人倒得更慢,控制环就有更多机会把它接住。矮而重心低的机器人要难平衡得多。

**金属减速箱。**平衡车每秒几百次换向。塑料减速电机背隙每次换向前几度白干,环调参绕不过。N20 编码器电机 常规答案。

用 TB6612FNG,不要用 L298N。TB6612FNG 在输出级上的压降小得多。而在 L298N 上,细小的修正指令会落到电机根本转不起来的电压之下——这就在精细修正所在的位置造出了一个死区。

**给电机单独一路电源。**一块在堵转电流下会电压下垂的电池包,会在修正进行到一半时让单片机欠压。于是机器人摔倒的原因与你的控制环毫无关系,而这种问题调试起来非常痛苦。

边做边验

检查 证明
手扶保持竖直时角度约 0° 测量里没有残留的安装偏差
不旋转地晃动时角度几乎不动 滤波器在加速期间相信陀螺仪
前倾轮子往前转 内环符号对
推它一把能抗住并稳定下来、晃动不放大 微分增益在起作用
外环开不漂 编码器外环接对

做好长什么样

测量 勉强站住 调好
内环(倾角)频率 100 Hz 200–500 Hz
外环(位置)频率 20 Hz 20–50 Hz——比内环慢好几倍
静止倾角振荡 ±3–5° ±1° 内
60 s 漂离起点 1–2 m 30 cm 内
扛推 轻碰 结实一掌
互补滤波常数 0.98 0.98–0.995,选不抄
游走开去之前的运行时长 几秒 可以一直跑下去

环路频率之比是大多数第一版会搞错的那个数字。内环负责保持倾角,外环则通过请求一个倾斜量来前进。如果外环的运行频率接近内环,它就是在追一个内环还没达到的目标,于是两个环互相打架。相差五到十倍是一条好用的经验规则。

“漂移”那一行正是编码器的用处所在,而且值得说清楚:一台只有倾角环的机器人会平衡得漂亮无比,然后在房间里到处游走,因为没有任何东西告诉它自己在哪里。它是竖直的,也是迷失的。加上外层位置环,才把它从一件演示变成一台机器人。

符号约定:浪费一晚上的东西

有四个符号必须一致,而且没有道理可讲能把它们推导出来——你只能把机器人拿在手里,在台架上一个个检查:

检查 手扶车…… 应该……
IMU 符号 把它向前倾 报出正的倾角(或者始终为负也行——只要定死一种)
电机符号 指令正输出 轮子往前转
内环符号 环跑着前倾 轮子往前指令,接住倒
外环符号 静止往前推 后仰回来

第三项如果反了,机器人会狠狠地加速自己正在进行的倒下,方向正是它已经在倒的那个方向。这个现象绝不会认错,而且值得在轮子离地的情况下测试。

不工作的时候看哪里

几乎每个失败五之一,长得分得出:

  • 一上电就瞬间倒下——内环符号反了。
  • 振荡不断变大直到摔倒——微分增益太小,或者微分项取自差分后的角度而不是陀螺仪角速度。
  • 站住时嗡嗡响——比例增益太大,或者环路运行得太慢、撑不住这些增益。
  • 毫无抵抗地瘫倒下去——比例增益太小,或者电机已经饱和。
  • 能站住却开走了——存在安装偏差,而积分项不足以吸收它。

失效模式表对每一条都有更详细的说明,而且每一条都可以在模拟器里被刻意复现出来——这是学会识别它们最快的途径。

项目路线图

搭建路径

沿着技术树,从零件一路走到一台能正常工作的机器人。每个节点在其前置条件完成后解锁,你的进度会保存在这台设备上。

已完成 0 / 16

100%
搭建

让它站起来

制作

目标

让它守住原位

目标

元器件

本路径中的教程

接线之前先练习

用在线模拟器把它调好

搭建路径会经过一个浏览器实验台。先在这里把行为调对,再把参数迁移到真实的机器人上。

常见问题解答

自平衡机器人作为第一个项目有多难?

它是一个糟糕的第一个项目,却是一个极好的第三个项目。接线方面没有任何困难,但被控对象是不稳定的,这意味着没有部分得分——机器人要么站得住,要么站不住;而在你知道该看什么之前,一个弄反的符号和一组糟糕的增益看起来一模一样。先做一台循迹车,让 PID 调参和电机驱动都变得熟悉,这样这个项目就会变成一个专注于一个控制环的问题,而不是同时面对五个未知数。

为什么我的平衡机器人会抖动,而不是稳稳站着?

通常是比例增益相对你的环路频率来说太高,或者是减速箱背隙。先试着降低 Kp。如果增益调低后抖动仍然存在,就观察车轮换向的那一刻:如果它们动起来之前有一段明显的死区,那问题就出在减速箱上,换一台金属齿轮电机,就能解决再怎么调参也解决不了的问题。

真的需要编码器吗?

站起来不需要。内环只需要一个倾角,所以一台完全没有编码器的机器人也能平衡得很好——它只是会漂移,因为没有任何东西告诉它自己在哪里。编码器是外环守住位置所需要的。如果你愿意,可以先不装编码器,把平衡调出来,再把它们加上。

控制环需要跑多快?

对内环来说,200 Hz 是一个合理的下限,越快越好。机器人的自然倒下时间决定了截止期限:一台小机器人从竖直到无法挽回,远远用不了一秒,所以一个以 50 Hz 运行的环路几乎没有几次干预的机会。要用硬件定时器来驱动它,而不是用 delay(),因为对微分项来说,时序的一致性比确切的频率更重要。

为什么它能平衡,却会慢慢开到房间另一头?

是 IMU 的安装偏差。如果传感器偏离竖直一度,控制环就会保持在那个错误的角度上,而保持一个恒定的倾斜就意味着恒定的加速度。用手把机器人扶到真正竖直的位置来测出这个偏差,把它作为常数减掉,剩下的交给积分项去吸收。你可以用模拟器里的偏差滑块精确地复现这个现象。