解读 55 · 单摆台架:辨识实验的物理设计
解读对象:
microduck-replica/docs/换舵机重训全流程.md§2,交叉引用bam/bam/testbench.py的Pendulum类与microduck-replica/upstream/microduck_rl/src/mjlab_microduck/robot/testbench_constants.py
需要的前置:解读 54(为什么要建执行器模型)
辨识的核心难题:摩擦藏在整个机器人里没法单独量。解决办法是把执行器拆出来,挂一个动力学完全已知的负载——单摆。摆的惯量和重力力矩都能用公式算出来,剩下的、模型解释不了的部分,就全是执行器自己的特性。
为什么是摆
bam/bam/testbench.py 把这件事写成了代码。抽象基类 Testbench 的类注释给出台架方程:τ_m + τ_e(q) = M(q)·q̈——电机力矩加外部力矩等于惯量乘加速度。它的子类 Pendulum 实现了两个已知量:
compute_mass():inertia = mass·length² + (arm_mass/3)·length²——点质量挂在均质杆末端的转动惯量;compute_bias():(mass + arm_mass/2)·g·length·sin(q)——重力力矩,零位是摆臂竖直向下。
未知量只剩执行器。 所以记录里必须写清 mass、arm_mass、length 三个键——摆本身算不准,后面全白搭。上游微鸭台架的实际配置在 testbench_constants.py:TESTBENCH_ARM_MASS = 0.12(真实设备挂 120 g 负载),_set_arm_mass() 把这个质量按比例写进 MJCF 的 arm 刚体(质量与惯量同步缩放)。
测什么、怎么测、进哪个参数
换舵机重训全流程 §2 把台架分成两步。§2.1 电气与通信(半天):协议连通(PING/读写位置)、1 Mbps 收发 1000 包误包率 ≈0、6.6/7.4/8.2 V 各跑 10 分钟、堵转 2 秒读电流。§2.2 动力学辨识(一天,重训数据全从这来):
| 测什么 | 怎么测 | 进哪个参数 |
|---|---|---|
| PD 阶跃响应 | 位置阶跃(如 30°),高频回读画曲线 | kp / kd |
| 堵转力矩-速度曲线 | 逐速度点堵转读力矩 | forcerange |
| 回差 | 正反两方向趋近同一目标位,读差值 | backlash 模型 |
| 摩擦 | 匀速转动测维持力矩 | friction_base / friction_viscous |
| 转子反射惯量 | 空载加减速拟合 | armature |
训练参数调整指南 §11.4 又补了采集矩阵的" dense 度":多个电压、多个固件 P 增益、空载和带已知负载、正向与反向、慢速摩擦/阶跃/正弦/抬落轨迹、冷机到热机、指令到运动的延迟。每一维都是后面仿真里的一个域随机化范围的来源。
买 1–2 只,不是 15 只
全流程 §2 的标题就是"第一步永远是:单舵机台架测试(对,先测一只)"——15 只大单之前做完上面所有事。个体差异大的舵机,随机化范围按台架实测离散度放大(§3 表)。
你带走的收获
- 辨识实验的通用套路:已知负载 + 激励轨迹 + 高频记录 → 用"公式算得出的部分"反推"算不出的部分"。任何执行器、任何关节都适用。
- 台架方程
τ_m + τ_e = M·q̈里每一项都要么可测(位置/速度)要么可算(摆的惯量与重力力矩),不留自由参数。 - 记录元数据(mass/arm_mass/length/vin/kp)和轨迹本身同等重要——元数据错了,拟合出的 JSON 全错。
- 先测一只再买 15 只:台架成本是一个下午,装错舵机的成本是拆 15 次。
- 激励要"稠":多电压、多增益、正反双向、冷热状态,覆盖仿真里要随机化的每个维度。