Meta: 拆解 BAM(Better Actuator Models)如何在 Microduck 上完成从单摆实验到 MuJoCo 仿真部署的完整执行器辨识流程,含 M1-M6 六阶段参数拟合详解。
写 sim2real 绕不开一个问题:为什么仿真里走得稳的策略,一上真机就原地抖?
Pollen Robotics 的 Microduck 用了一个叫 BAM 的开源工具来解决这个问题。BAM 全称 Better Actuator Models,由 Rhoban 实验室开发,2025 年发表在 ICRA 上。核心思路很直接——把舵机建模这件事从「给个阻尼系数就完事」升级到「把电机、摩擦、反弹间隙全部分离辨识」。
这篇文章把 BAM 的整个工作流拆开讲,结合 Microduck 的实际复刻经验。
为什么默认的摩擦模型不够用
MuJoCo 默认的摩擦模型是 Coulomb + Viscous,也就是常说的干摩擦加粘滞摩擦。对大多数仿真来说够了,但到双足机器人这个尺度——15 个微型舵机驱动一个 800g 的躯体——就出问题了。
问题出在三个地方:
- Stribeck 效应:低速时摩擦力反而更大,这对步态切换瞬间影响巨大
- 负载依赖:同一个舵机,关节受力和不受力时摩擦参数完全不一样
- 回差(Backlash):齿轮间隙在 MuJoCo 里默认不存在,但 Microduck 的 XL330 有大约 ±1° 的齿隙
Pollen 团队实测过,用默认 Coulomb-Viscous 模型训出来的策略在真机上会「感觉像踩在冰面上」——因为仿真里的关节响应太理想化了。
BAM 的论文(Duclusaud et al., ICRA 2025)对这个问题做了定量分析:扩展摩擦模型能把仿真和真机的关节轨迹误差降低 60% 以上。
BAM 的 6 阶段辨识流程
BAM 的辨识管线分 6 个阶段,从搭台架到输出可部署模型,每步产出可验证的参数。
M1:台架搭建与数据采集
需要一个单摆台架:把舵机固定在支架上,摆臂水平伸出,末端挂已知质量的重物。目的是让舵机在受载情况下做正弦扫频运动,记录输入(电压指令)和输出(实际角度)。
数据采集的关键参数:
- 采样率:100Hz 以上(Microduck 控制循环是 50Hz,采集需要 2 倍以上)
- 激励信号:chirp 信号,1-20Hz 扫频
- 记录内容:指令位置、实际位置、电流、温度
- 持续时间:每条轨迹 10-20 秒,重复 3 次取平均
对于复刻场景(用飞特 HL-1910 替代 XL330),这一步是必须重做的——不同舵机的电气特性完全不同。
M2:运动学参数拟合
用采集到的数据拟合最基本的参数:齿轮比、电位计零点偏移、输出轴角度范围。
BAM 用一个非线性最小二乘优化器来解这个拟合问题,损失函数是预测角度和实测角度的 RMSE。这一阶段通常在 1-2 分钟内收敛。
M3:电机动力学参数
这一阶段辨识电机本身的电气参数:反电动势常数(Kv)、绕组电阻(R)、电感(L)。BAM 通过分析电压-电流关系来分离这些参数,不依赖外部测量设备。
核心公式是电压平衡方程:
Vapplied = R × I + L × dI/dt + Kv × ω
BAM 从实测的电压阶跃响应中提取这些系数。对 XL330,BAM 开源库已经给出了参考值,但如果换舵机,这一阶段的实验数据是必采的。
M4:摩擦模型参数
这是最关键的阶段。BAM 支持 6 种摩擦模型,从简单到复杂:
- Coulomb + Viscous(MuJoCo 默认)
- Coulomb + Viscous + Stribeck(添加低速摩擦峰值)
- Coulomb + Viscous + Stribeck + Load-dependent(添加负载相关项)
- Coulomb + Viscous + Stribeck + Quadratic(添加二次项)
- Coulomb + Viscous + Stribeck + Load-dependent + Quadratic(完整 5 参数模型)
- M6 完整模型:在 5 参数基础上再加方向依赖和温度补偿
Microduck 在训练中使用的是 M6 模型。为什么选最复杂的?因为 PPO 训练时,仿真里差一个摩擦参数,策略学到的「最优动作」就完全不一样。Pollen 团队在 AGENTS.md 里专门强调过:在微型舵机这个尺度,执行器保真度占据了 sim2real gap 的大部分。
M5:回差(Backlash)参数
BAM 支持单独辨识齿轮间隙。Microduck 的 XL330 有大约 ±1° 的回差——看起来不大,但在 50Hz 控制循环里,每次换向时这 2° 的死区会造成明显的轨迹跟踪误差。
BAM 用正弦激励下的滞后环(hysteresis loop)来拟合 backlash。具体做法是给舵机发一个完整周期的正弦指令,测量实际响应和指令之间的相位滞后和幅值衰减,从中反推出齿轮间隙宽度。
M6:验证与集成
最后一步:把拟合好的模型放到 MuJoCo 里跑一遍,和真机的响应做对比。BAM 提供了一个叫 bam.mujoco.MujocoController 的接口,直接在 MuJoCo 里模拟电压控制舵机。
验证标准:在 50Hz 控制循环下,仿真关节轨迹和真机关节轨迹的 RMSE 不超过 3°。Pollen 团队报告的数据是在 5° 以内可接受,3° 以内算好。
域随机化:给仿真加「噪声毯」
单靠 BAM 还不够——任何模型都有残差。Microduck 的 RL 训练用域随机化来兜底。
从 microduck_rl 仓库的源码可以看到具体的随机化维度:
- 电池电压:7.4V ± 0.5V(模拟 2S LiPo 放电曲线)
- 电压降落:负载时额外 -0.3V
- 指令延迟:±1 个控制周期(模拟串行总线延迟)
- 摩擦幅值:±20%
- IMU 噪声:角速度 ±0.1 rad/s,加速度 ±0.2 m/s²
- 质量分布:躯干质心 ±5mm
关键技巧:随机化参数必须在每次 reset 时重新采样,不能跨 episode 累积——Pollen 团队踩过这个坑,累积的 CoM 随机化曾导致连续几个月的训练退化。
在复刻场景下的实操建议
如果你像我一样用国产飞特 HL-1910 替代 XL330,BAM 流程需要完整重走一遍:
- 飞特舵机的寄存器表和 XL330 不一样——TTL 电平、波特率、协议格式都需要适配
- BAM 目前没有内置飞特 HL 系列的参数库,所以 M1-M6 全部要从头跑
- 好消息:BAM 的代码和文档质量很高,单摆台架的搭建指南在 readthedocs 上有完整说明
实际投入估算:
- 台架搭建:2-3 小时
- 数据采集:1 小时(15 个舵机逐个测)
- M2-M4 拟合:每舵机 10-15 分钟
- M5 回差辨识:每舵机 5 分钟
- M6 验证:1 小时
- 总计:大约一个工作日的投入
对比省下的成本(¥1,080 舵机差价 + 后续训练时间的节省),这笔投入的 ROI 很高。BAM 做好的策略在新舵机上训,比不辨识直接硬训要快得多。
小结
BAM 解决的是 sim2real 中最底层的问题:执行器建模。没有准确的舵机模型,域随机化调得再好,策略在真机上也会出现奇怪的失败模式。
对做开源机器人复刻的开发者来说,BAM 的价值尤其大——因为你大概率不会用原厂舵机。换舵机 = 重训策略,重训策略的前提是准确的执行器模型。BAM 提供了这条链路中缺失的一环。
Microduck 的复刻进度和 BAM 实验记录持续更新在 duck.whatled.com。
