• 欢迎访问少将全栈,学会感恩,乐于付出,珍惜缘份,成就彼此、推荐使用最新版火狐浏览器和Chrome浏览器访问本网站。
  • 吐槽,投稿,删稿,交个朋友
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏少将全栈吧

Microduck 的双足步态是怎么炼出来的?从 ZMP 到 PPO 的完整拼图

Build in Public admin 49分钟前 3次浏览 已收录 扫描二维码

# Microduck 的双足步态是怎么炼出来的?从 ZMP 到 PPO 的完整拼图

Meta Description: Microduck 的步态不是手写的,而是 PPO 在 MuJoCo 里自己”摸索”出来的。但 RL 不是凭空变魔术——奖励函数里藏着经典控制理论的影子。拆开从 ZMP 到 sim2real 的完整链路。


如果你玩过 Microduck 的模拟器,可能会觉得它走路的样子挺自然的——脚抬起来、重心平移、落地缓冲,每一步都像那么回事。

但这里有个反常识的事实:Microduck 的步态不是手写出来的。没有人在代码里写”左脚抬 15 度、前移 3 厘米、落地”这种硬编码轨迹。它走路的技能,是 PPO 在 MuJoCo 仿真里,通过 4096 个平行环境跑了上千万步,自己”摸索”出来的。

那问题来了——一个神经网络怎么就知道走路要抬脚、要前倾、要落地缓冲?

答案是:奖励函数里藏了经典控制理论的影子。

从 ZMP 说起:双足步态的”物理学铁律”

如果你研究过双足机器人,一定听过 ZMP(Zero Moment Point,零力矩点)。这是 Miomir Vukobratović 在 1968 年提出的概念,至今仍是双足步态规划的理论基石。

核心思想很简单:一个双足机器人要站住,它的压力中心必须落在脚掌范围内。ZMP 一旦跑到脚掌外面,机器人就倒了。传统步态规划的做法是:

  1. 预规划 ZMP 轨迹(通常走 S 型曲线)
  2. 用线性倒立摆模型(LIPM)反推 CoM 运动
  3. 通过逆运动学解出关节角度
  4. 走一步,再走下一步

ASIMO、Atlas(早期版本)、HRP 系列都是这条路线。效果好,但工程量巨大——每个步态参数都要手动调,遇到不平整地面就很容易翻车。

Microduck 走了完全不同的路。

不规划轨迹,改”教”神经网络走路

Microduck 的步态训练跑在 microduck_rl 仓库里,基于 mjlab(MuJoCo + Warp)和 PPO。核心任务叫 Mjlab-Velocity-Flat-MicroDuck,目标是:给定一个速度指令,让机器人往前走

它的观测空间是 61 维——48 维本体感知(14 个关节的位置、速度、上一个动作 + 机身线速度/角速度/姿态)加上 13 维命令(前进/侧移/转向的 twist 3 维、头姿态 4 维、身体姿态 6 维)。

但真正体现”经典控制理论如何渗透到 RL 奖励设计”的,是奖励函数。

奖励函数里的”隐形倒立摆”

翻看 microduck_rl 的 mdp.pymicroduck_velocity_env_cfg.py,你会发现一组精心设计的奖励项。如果把它们的核心意图翻译成控制理论的语言,大致是这样:

1. 前进追踪 — 开环激励

reward_tracking_lin_vel = exp(-(cmd_vx - actual_vx)² / σ²)

这是最大头的奖励。PPO 要最大化这个值,就必须让实际速度跟上指令速度。等于说:”往前走就是对的,走错了方向扣分。” 这是策略学习的主信号——没有这个,其他所有奖励都白搭。

有意思的是,前进速度是用足端触地传感器间接算出来的。Microduck 每只脚底有一个力传感器,通过检测”哪只脚着地、着地多久”来推断运动状态。这和 ZMP 里”压力中心必须在脚掌内”的物理约束是同源的——只不过 ZMP 用它规划轨迹,RL 用它作为学习的反馈信号。

2. 姿态跟踪 — 线性化控制

reward_tracking_body_pose = exp(-‖cmd_roll - actual_roll‖² / σ²)

要求机身保持水平,不要歪着走。这等价于传统控制里的姿态内环——经典方法用一个 PD 控制器维持机身水平,RL 则是让神经网络自己学会这个”保持水平”的行为。

在 microduck_rl 的 CLAUDE.md 里,开发团队特别强调了一个教训:Tracking Gaussian 的标准差不能太紧。Microduck 的脑袋占了整机重量的 38%,走路时必然晃动。如果头姿追踪奖励的 σ 设太小,策略会为了”脑袋不晃”而直接原地罚站。所以最终设了一个松紧合适的 σ——只惩罚 DC 偏移,允许高频振荡自然衰减。

3. 动作平滑 — 二阶低通约束

action_rate_penalty = -‖action_t - action_{t-1}‖
joint_acceleration_penalty = -‖joint_vel_t - joint_vel_{t-1}‖

这两项惩罚动作突变和关节加速度。翻译成控制语言:限制了策略的带宽和 slew rate。经典控制里用二阶低通滤波器做这件事,RL 用惩罚项达到同样的效果。

而且 microduck_rl 的实现更精细——它把腿部和颈部的动作平滑度分开惩罚。腿部动作允许更快变化(走路需要快速响应),颈部动作则要求更平滑(摄像头稳定)。这个区分在经典控制里对应不同关节的不同带宽需求。

4. 扭矩率 — 力控边界

torque_rate_penalty = -‖τ_t - τ_{t-1}‖

惩罚扭矩突变。在 XL330 这种微型舵机上,扭矩突变意味着齿轮冲击。这个奖励项的物理意义就是保护执行器。传统方法通过加速度规划来实现,RL 通过惩罚项让策略”自己学会”平缓发力。

从”手写步态”到”学出来的步态”——为什么更鲁棒?

传统 ZMP 步态规划的最大问题是什么?对模型精度极度敏感。

你的动力学参数(质量分布、摩擦系数、舵机响应延迟)差一点点,ZMP 轨迹就偏了,机器人就倒了。所以传统双足机器人花了大量时间做模型辨识参数标定

Microduck 的策略训练使用了 域随机化(Domain Randomization)——每次环境重置,电池电压、摩擦系数、舵机延迟、质量分布都在一定范围内随机变化。策略在”各种不同身体”上训练过,到了真机上自然就适应了偏差。

这就是为什么一个在 MuJoCo 里训练的神经网络,能在真实的 Microduck 上走路——它不是在执行一条死板轨迹,而是在处理一个61 维状态空间里的连续决策问题,而这个状态空间天然包含了各种不确定性的扰动。

两种路径,同一目标

说 Microduck 的步态完全是”RL 黑盒”也不对。奖励函数的设计大量借鉴了控制理论:

  • 速度追踪 → 位置/速度环的反馈概念
  • 姿态跟踪 → 姿态内环的等价表达
  • 动作平滑 → 低通滤波器
  • 扭矩率惩罚 → 力控的平滑约束

区别在于:经典控制把这些约束写成显式方程(PD 增益、截止频率、S 曲线规划),而 RL 把它们编码成奖励项的权重和分布参数。前者是”告诉机器人怎么做”,后者是”告诉机器人什么重要,让它自己摸索怎么做”。

最后的结果是同一个——Microduck 站稳了,走起来了。

写在最后

如果你正在复刻 Microduck(像我一样),理解这套奖励函数背后的控制理论,比直接抄参数更有用。因为在更换国产舵机、调整 BAM 参数后,原来的奖励权重可能全要重新调。知道为什么设这个项,比知道设多少重要得多。


参考来源:

  • Pollen Robotics. microduck_rl 仓库. GitHub. CLAUDE.md, mdp.py, microduck_velocity_env_cfg.py. 2026.
  • Rhoban Lab. BAM: Better Actuator Models for Sim-to-Real Transfer. ICRA 2025.
  • Vukobratović, M., Borovac, B. Zero-Moment Point — Thirty Five Years of Its Life. International Journal of Humanoid Robotics, 2004.
  • 复刻项目进度记录: duck.whatled.com
喜欢 (0)
[🍬谢谢你请我吃糖果🍬🍬~]
分享 (0)
关于作者:
少将,关注Web全栈开发、项目管理,持续不断的学习、努力成为一个更棒的开发,做最好的自己,让世界因你不同。