大数跨境

《从零 DIY 复刻 Microduck 双足机器人完整指南|Sim-to-Real 强化学习小黄鸭》

《从零 DIY 复刻 Microduck 双足机器人完整指南|Sim-to-Real 强化学习小黄鸭》 苏哲管理咨询
2026-10-24
7
导读:Microduck 是一款身高约 25 厘米的小型双足机器人,主打仿真到实物(Sim-to-Real)强化学习方案,为轻量化双足机器人研发提供低成本实践参考。整机搭载 15 个 Dynamixel X

编者摘要:Microduck 是一款身高约 25 厘米的小型双足机器人,主打仿真到实物(Sim-to-Real)强化学习方案,为轻量化双足机器人研发提供低成本实践参考。整机搭载 15 个 Dynamixel XL330 舵机作为驱动单元,支持 50Hz 闭环控制,硬件配置精简,适配小型机器人有限的负载与空间约束。

项目采用 MuJoCo 仿真环境完成强化学习策略训练,在虚拟环境中迭代步态控制算法,规避真机调试易损坏、试错成本高的痛点。训练完成的模型转为 ONNX 格式,直接部署到实体机器人,打通仿真策略迁移至硬件的完整链路。

这类小型双足平台降低了双足强化学习的落地门槛。不同于大型人形机器人,Microduck 体积小巧,更适合科研教学、算法快速验证。不过 Sim-to-Real 方案仍存在仿真与现实之间的域差问题,真实环境摩擦、机身间隙等扰动,会影响步态稳定性。整体来看,Microduck 用轻量化硬件 + 仿真预训练 + ONNX 端侧部署的组合,为低成本双足机器人的步态学习提供了可复用工程范式。

Q&A(10 个高频问题)

Q1:Microduck 必须用 Radxa Zero3W 吗?

A:官方运行时目标平台是 Radxa Zero3W;理论上其他 ARM 板可移植,但设备树、UART 时序、Rust 编译需要大量适配,不推荐新手。

Q2:基础行走必须摄像头、ToF、音频吗?

A:不需要。行走闭环只依赖舵机 + IMU;感知属于扩展模块。

Q3:为什么 IMU 要封装成 Dynamixel 从机,不用 USB IMU?

A:保证和舵机同一 SyncRead 帧同步采样,控制环内时间戳严格对齐,消除异步传感器的时间偏差;临时调试可以 FakeIo 虚拟 IMU,但不能长期真机步态。

Q4:可以直接用仿真导出的 STL 打印装配吗?

A:不行。STL 只有三角面片,没有关节旋转轴、限位、安装孔、紧固件,只能作为外形参考,需要在 CAD 里重新建模工程零件。

Q5:.pt 模型权重能不能直接转 ONNX 部署?

A:不可以,训练时的观测归一化逻辑不会被自动打包,真机观测数据没有归一化,策略输出完全错误,必须使用项目 export.py 导出。

Q6:如果改机器人腿长、换电池、外壳增重,直接调 action_scale 行不行?

A:短期勉强凑,但不稳定。动力学、惯量、质心改变,策略不再匹配,正确做法是更新 MJCF 模型、重训。

Q7:Dynamixel 总线 15 舵机 + IMU,能稳定跑 50Hz 吗?

A:硬件设计正确、return delay 调优、无总线冲突的前提下可以;总线负载、线缆压降、CRC 错误是最常见瓶颈。

Q8:home pose 是什么?是机器人站直的姿态?

A:home pose 是策略计算的基准参考角,所有动作是在 home pose 上叠加 action_scale × action;机械装配零位必须和 MJCF 里 home pose 完全对齐,不是肉眼看起来站直即可。

Q9:可以用 ROS2 重构控制环吗?

A:可以,但原版方案没有 ROS,50Hz 硬实时控制会引入额外延迟;sim-to-real 对时序非常敏感,新增框架会带来大量适配工作。

Q10:新手入门顺序是什么?

A:1)电脑跑通 microduck_rl 仿真;2)单舵机台架测试 Dynamixel 总线;3)IMU 桥接板验证;4)CAD 机械建模打印单关节样件;5)整机装配、电源;6)舵机校准;7)吊架策略调试;8)保护绳下地测试。

附录  Microduck 复刻项目

Microduck:约 25cm 高小型双足机器人,Sim-to-Real 强化学习双足,15 个 Dynamixel XL330 舵机,50Hz 闭环控制,MuJoCo 仿真训练策略,ONNX 部署到真机。

一、核心原理

传统双足:硬编码固定关节角度时序; Microduck:强化学习在 MuJoCo 仿真里训练步态,再迁移到实物机器人(sim-to-real)

  1. 控制循环 20ms / 50Hz:主控读取舵机位置 + IMU 姿态 → 拼成 61 维观测向量送入 ONNX 神经网络 → 网络输出 14 维关节动作指令 → 下发舵机。
  2. 15 舵机:14 个参与行走策略,嘴部舵机独立控制,不进神经网络
    • 双腿:每条腿 5 舵机(髋偏航、髋滚转、髋俯仰、膝、踝),合计 10 个
    • 头颈:颈俯仰、头俯仰、头偏航、头侧倾,4 个策略关节
    • 嘴:1 个独立舵机
  3. IMU 方案:IMU 封装成 Dynamixel 从机(ID=200),和舵机共用同一条 TTL 总线,输出三轴陀螺 + 四元数姿态,不需要单独 I2C/USB 传感器链路。

二、复刻四大核心任务(缺一不可)

  1. 机械重建:复刻 MJCF 定义的机器人刚体、关节轴线、限位、质量惯量
  2. 电控搭建:Dynamixel 总线、电源、IMU 桥接板、Radxa 主控
  3. 对齐契约:关节顺序、坐标系、单位、50Hz 控制周期,仿真与真机严格一致
  4. 策略部署:强化学习训练 → 导出带归一化器的 ONNX 模型,分阶段真机调试

三、前置基础要求

不需要强化学习专家,但需要:

  • Linux 终端操作,会看日志、安装软件
  • CAD+3D 打印装配经验
  • 万用表,理解电压、电流、共地、稳压
  • Dynamixel 舵机基础:ID、零位、转向、机械限位

不熟悉的话:优先跑仿真 + 单舵机台架,不要直接整机制作

四、核心术语

名词
含义
MJCF
MuJoCo 机器人描述 XML,定义刚体、关节、质量、碰撞
MuJoCo
物理仿真器,用于 RL 步态训练
Dynamixel XL330
智能串行舵机,带位置反馈,总线通信
ONNX policy
训练好的神经网络,输入 61 维观测,输出 14 维动作
sim-to-real
仿真策略迁移实物机器人
home pose
基准零姿态;策略动作是在 home pose 基础上叠加偏移
RPI Robot HAT
Pollen 官方板卡,Radxa 40Pin 扩展板,Dynamixel TTL 总线 + 主控供电

五、系统架构与控制链路

硬件链路:Radxa Zero3W 主控 ↔ RPI Robot HAT ↔ 半双工 TTL 总线 ↔ 15 个舵机 + ID200 IMU 软件:Rust 编写robotd作为核心守护进程,不使用 ROS,多服务拆分:

  • robotd:50Hz 控制环、舵机总线、IMU、ONNX 策略、安全保护(最核心)
  • configd:WiFi、系统配置
  • updaterd:固件更新、回滚
  • btd:蓝牙 BLE(手机通信)
  • padd:手柄输入
  • mediad /tofd:摄像头、音频、ToF(扩展,基础行走不需要) 通信接口:Unix socket JSON-RPC;上层下发行走速度 / 头部姿态高层指令,不直接写舵机

20ms 周期流程:

  1. SyncRead 一次性读取全部舵机 + IMU 状态
  2. 组装 61 维观测向量
  3. ONNX 推理,输出 14 维动作
  4. 映射 14 维动作到 15 舵机目标数组(插入嘴部舵机槽位)
  5. SyncWrite 下发舵机目标位置
  6. 慢速任务(电压温度)1 秒读一次,不占用 50Hz 环

⚠️ 最容易踩坑:关节索引映射

策略输出数组(14 维):左腿5 → 头颈4 → 右腿5整机目标数组(15 维):左腿5 → 头颈4 →【嘴部1】→右腿5

❗ 直接把 action [9] 写入数组 index9,会把右髋指令发给嘴舵机,右腿整体错位!

Action 索引
关节
总线 ID
0~4
左腿 5 关节
20,21,22,23,24
5~8
头颈 4 关节
30,31,32,33
-
嘴(非策略)
34
9~13
右腿 5 关节
10,11,12,13,14

六、61 维观测向量(ONNX 输入契约,顺序绝对不能乱)

网络输入[1,61],输出[1,14],单位、坐标系、归一化仿真真机必须完全对齐 | 区间 | 维度 | 内容 | |---|---|---| |0~3|3 | 躯干坐标系陀螺仪,rad/s| |3~6|3 | 投影重力向量(单位向量)| |6~20|14 | 关节角度 - home pose,rad(不含嘴)| |20~34|14 | 关节角速度 rad/s(不含嘴)| |34~48|14 | 上一轮原始策略输出 | |48~61|13 | 命令块:twist (3)+head_pose (4)+body_pose (6)|

命令块明细: 48-51:vx,vy,vyaw;51-55:颈俯仰、头俯仰、头偏航、头侧倾;55-61:body x,y,z,roll,pitch,yaw

⚠️ 重要:不能手动把.pt 权重直接转 ONNX;必须使用官方 export.py 导出,归一化器要打包进 ONNX,否则真机观测没有归一化,直接失效。推理前需要 warm-up 消除首帧延迟。

七、BOM 物料清单(基础行走最小版本,不含摄像头 / 音频 / NFC)

  1. 主控:Radxa Zero3W(RK3566)
  2. HAT 板:Pollen RPI Robot HAT(可复刻 KiCad 工程,基础版可删减音频 / BMI088)
  3. 舵机:Dynamixel XL330 ×15(XL330-M288-T,14 策略 + 1 嘴)
  4. IMU 桥接板(ID200):MCU STM32G031 + LSM6DSV16X,封装成 Dynamixel 从机
  5. 电池:NP-F550 规格 2S 锂电;注意:2S 满电 8.4V,XL330 推荐 5V,必须稳压!原版运行时默认按 2S 电池电压做安全检测,修改舵机供电后需要修改软件电压保护逻辑
  6. 结构件:基于 MJCF 导出 STL,3D 打印;PLA 试模,PETG/ASA 正式件;重载关节考虑 PA
  7. 电源配件:保险丝、总开关、反接保护、限流电源

工具清单:万用表、可调限流电源、逻辑分析仪、Dynamixel 调试器、电子秤、卡尺、3D 打印机

八、软件仓库(4 个核心仓库)

  1. microduck
    真机 Rust 运行时、robotd、设备树、配置
  2. microduck_rl
    MuJoCo 仿真环境、PPO 强化学习、模型训练、ONNX 导出脚本
  3. elec_RPI_Robot_HAT
    官方 HAT KiCad 原理图 PCB、Gerber 生产文件
  4. microduck-replica
    第三方逆向装配重建,MJCF 导出整机 STL、爆炸图

仿真训练流程

  1. Python 版本锁定 3.12~3.13,uv 管理依赖
  2. 冒烟测试:64 环境、5 迭代,快速验证环境
uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 64 --agent.max_iterations 5
  1. 正式训练:4096 并行环境,CUDA 显卡约 1~2 小时得到可用步态;无本地显卡可提交 HuggingFace Jobs
uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 4096
  1. 导出 ONNX(必须)
uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck --wandb-run-path <entity/project/run_id>
  1. CPU 复演 ONNX,验证策略正确性
uv run scripts/infer_policy.py --walking output.onnx

九、机械重建(最容易踩坑:STL≠MJCF)

仿真 STL 只是视觉网格,关节轴线、父子关系、惯量、限位全部存在 MJCF XML 里

  1. microduck-replica 脚本读取 MJCF,做前向运动学,把分散网格变换到世界坐标,合并为 15 个刚体 STL
  2. 导入 CAD 只作为外形参考;必须重新建立参数化实体、关节旋转副、运动限位,不能直接用三角网格做运动仿真
  3. 整机仿真质量约 737.2g;实物打印 + 电池 / 线束后通常到 1kg+;质量、质心改动大,必须更新 MJCF 并重训策略,不能硬调 action_scale 凑
  4. 试制顺序:单关节样件 → 腿总成 → 整机;打印件优先热熔螺母,不薄壁攻丝

十、电源 & TTL 总线要点

  1. Microduck 使用3.3V 逻辑半双工 TTL 单线 Dynamixel 2.0 协议,1Mbps,普通 USB-TX/RX 双线串口无法直接替代,需要方向控制电路
  2. HAT 电源网络:电池 + BATT 直接接到舵机端口;独立 5V 降压芯片给 Radxa 主控;舵机端口没有内置稳压
  3. 台架上电顺序:单独 HAT 测主控供电 → 单舵机 ID 配置、1Mbps 通信 → 逐颗增加 → 最后接入 IMU(ID200)

十一、IMU 桥接板原理

LSM6DSV16X → STM32G031 读取 SFLP 姿态融合,打包三轴 i16 陀螺 + fp16 四元数,伪装成 Dynamixel 设备 ID200,和舵机在同一个 SyncRead 帧读取。

  • 数据块地址 124 起,12 字节;运行时会做坐标系映射
  • IMU 必须刚性固定在躯干,不能装在头部;上电等待足够姿态融合稳定,否则观测错误

十二、主控部署(Radxa Zero3W + Armbian 26.2.1 Minimal)

  1. 系统烧录,配置 SSH;运行 provision-board.sh 自动部署 robotd 等服务
  2. 关键坑:Armbian 默认 serial-getty 占用/dev/ttyS2串口,会抢占 Dynamixel 总线,必须 mask 禁用
sudo systemctl mask --now serial-getty@ttyS2.service
  1. 服务管理
robotctl version
robotctl health
sudo systemctl restart robotd
  1. 假硬件测试(--fake,不上真实电机,验证软件栈)
sudo systemctl stop robotd
sudo /opt/robot/daemon/current/bin/robotd --fake --no-policy

无策略真实硬件:--no-policy,仅关节控制,不加载行走神经网络,适合校准 home pose

十三、舵机整机校准

校准目标:机械零位 ↔ MJCF home pose ↔ 舵机编码器读数三者统一

  1. 逐个离线配置舵机 ID、波特率 1Mbps,记录零位、转向
  2. 吊架固定机器人,缓慢回 home pose:sudo robotctl robot init;结束 relax 释放扭矩
sudo robotctl robot init
sudo robotctl robot relax --yes

relax 之后机器人失去支撑,必须提前有支架托住,防止跌落损坏

十四、分级真机调试(十级流程,逐级验证,不跳级)

  1. 单舵机小角度运动测试
  2. 单腿悬空 5 关节验证
  3. 15 舵机上电、扭矩关闭,读取状态
  4. 接入 IMU,验证 16 设备 SyncRead 稳定
  5. 吊架内缓慢回 home pose,检查干涉 / 反转
  6. 离地悬空运行行走策略,检查动作映射
  7. 双脚着地,外部扶持,站立策略
  8. 保护绳 + 软垫,独立站立
  9. 扶持小速度行走
  10. 短距离自由行走

日志记录:robotctl monitor --json --hz 50 > run.jsonl,摔倒后可和仿真数据比对定位问题

十五、故障排查速查表

现象
根因优先排查
所有舵机无法识别
串口被 getty 占用、总线供电、半双工电路错误
一上扭矩直接撞限位
关节方向 / 零位 / 单位 / 动作索引错位
左腿正常,右腿动作错乱
14 维动作映射 15 槽数组,嘴部索引错位
仿真正常,ONNX CPU 复演出错
导出脚本错误,归一化器缺失
CPU 复演正常,真机一站就倒
IMU 坐标系、零位、整机质量惯量不匹配
站立可以,迈步就掉电
舵机瞬时大电流,电源稳压 / 线阻不足

十六、验收清单

分为仿真训练、机械、电气、软件校准、真机五大模块,逐项打勾;不是能走一次就算成功,要求可复现、日志完整



【声明】内容源于网络
0
0
苏哲管理咨询
为企业及组织提供AI+战略、数智化转型咨询及观点、建议等
内容 2402
粉丝 0
苏哲管理咨询 为企业及组织提供AI+战略、数智化转型咨询及观点、建议等
总阅读71.7k
粉丝0
内容2.4k