如何从零 DIY 复刻一只可爱的 Microduck

这是一份 Microduck 小型双足机器人的 DIY 复刻指南。它先说明整机结构与控制链路(15 个 Dynamixel 舵机、其中 14 个策略关节、50 Hz 控制环、ONNX 策略与 MuJoCo 训练的 sim-to-real 流程),再依次给出需要的知识基础、关键词表、BOM 与工具清单,并逐步讲解如何跑通官方仿真环境、如何从 MJCF 恢复装配关系并重建 CAD,以及舵机动作顺序、61 维观测布局和 ONNX 部署契约等最容易出错的地方。;本段承接 Microduck 复刻流程,说明从 MJCF/STL 转 CAD 后的工程件检查与单关节试制,讨论质量、材料、电源、Dynamixel 总线、IMU 桥接、主控 Linux 运行时、整机校准、策略导出与分级真机调试,并列出硬件变化后需要重新训练的条件。;本段列出常见故障排查表和项目验收清单。排查表按现象、高概率原因、优先检查组织,覆盖舵机、总线、IMU、ONNX、真机等常见问题;验收清单从仿真与训练、机械、电气、软件与校准、真机五个方面逐项检查,强调结果可重复。

Microduck 是一只约 25 cm 高的小型双足机器人。

Microduck 双足机器人整机外观

Microduck 用 15 个 Dynamixel 舵机构成双腿、颈部、头部和嘴部,其中 14 个关节由行走策略控制,嘴部单独控制。主控板持续读取舵机位置和 IMU 姿态,把这些数据交给一个 ONNX 神经网络,再把网络输出转换成新的关节目标。这个循环每秒运行 50 次。

与传统预先写好每一步关节角度的机器人不同,Microduck 的步态先在 MuJoCo 仿真器中通过强化学习训练,再部署到真机。

因此,复刻工作需同时完成四件事:

  • 重建与仿真模型一致的机械结构
  • 搭建舵机、电源、IMU 和主控系统
  • 让真机使用与训练一致的关节顺序、坐标系和控制频率
  • 将训练策略导出为 ONNX,并分阶段调试到能够站立和行走

机器人组成部分

从机械上看,Microduck 可以分为躯干、左右腿和头颈三条运动链:

  • 躯干是整机根节点,安装主控、电源、电池和通信板
  • 每条腿有髋 yaw、髋 roll、髋 pitch、膝和踝五个关节,两条腿共 10 个
  • 头颈有颈俯仰、头俯仰、头偏航和头侧倾四个策略关节
  • 嘴部还有一个单独舵机,因此总数是 15 个舵机、14 个策略动作
  • 运动 IMU 安装在机身上,为策略提供角速度和重力方向

机器人站立时,神经网络每 20 ms 根据最新姿态重新计算下一组关节目标。被轻推或落脚产生偏差后,下一周期的动作会随状态变化,这就是它能够闭环保持平衡的基础。

开始前需要什么基础

你不需要是强化学习专家,但最好具备以下基础:

  • 会使用终端执行命令,能安装 Linux 软件和查看日志
  • 会使用一种 CAD 软件,并做过基本的 3D 打印装配
  • 能使用万用表,理解电压、电流、共地和稳压的概念
  • 了解舵机的 ID、零位、方向和机械限位

如某一项还不熟悉,可先完成仿真和单舵机台架,暂时不要直接制作整机。

七个关键词

  • MJCF:描述机器人刚体、关节、质量、惯量、网格和碰撞关系的 XML 模型
  • MuJoCo:运行 MJCF、模拟机器人运动和接触的物理仿真器
  • Dynamixel:带位置反馈、可设 ID、能通过总线批量通信的智能舵机
  • ONNX policy:训练完成后导出的神经网络;输入机器人状态,输出 14 个关节动作
  • sim-to-real:让仿真中学会的动作尽可能迁移到真实机器人上的过程
  • home pose:所有关节共同使用的参考姿态;策略动作会在这组基准角度上叠加
  • RPI Robot HAT:安装在 Radxa 40 针排针上的接口与电源板,承担 Dynamixel 物理接口、主控供电以及音频和扩展传感器连接

本教程带你做到的程度

最终目标是一只能够完成以下闭环的复刻鸭:IMU 和舵机产生状态数据,主控以 50 Hz 运行策略,15 个舵机收到目标位置,机器人完成站立和行走。

摄像头、ToF、音频和 NFC 属于后续扩展,不影响第一版行走闭环。RPI Robot HAT 上与行走无关的音频、第二 IMU 和扩展接口也可以不装,但它承担的总线收发和主控供电功能须由原板或等效模块实现。

整个过程分成八个阶段:

  1. 固定源码版本
  2. 跑通仿真
  3. MJCF → 装配图与 CAD
  4. 机械试制电源、总线与 IMU
  5. 主控与运行时
  6. 校准、训练与 ONNX
  7. 分级真机调试

官方仓库用于确定控制接口、仿真和部署流程,第三方 microduck-replica 用于恢复装配关系并辅助 CAD 重建。

目录

  1. 系统架构与控制链
  2. 舵机、动作与关节顺序
  3. 61 维观测与 ONNX 契约
  4. 材料与工具
  5. 跑通仿真
  6. 从 MJCF 重建装配图与 CAD
  7. 电源与 Dynamixel 总线
  8. IMU 到 Dynamixel 桥接
  9. 主控、Linux 与运行时
  10. 舵机编号、零位与整机校准
  11. 训练、导出与部署策略
  12. 分级真机调试
  13. 硬件变化与重新训练
  14. 常见故障排查
  15. 项目验收清单

1. 系统架构与控制链

先不要急着购买零件,理解数据怎样在机器人里流动,后面的接线、校准和部署才不会变成照抄命令。

可以把 Microduck 看成“主控电脑 + 接口与电源板 + 一条设备总线 + 传感器 + 神经网络”:

  • 主控从总线读取状态
  • 神经网络计算动作
  • 主控再把动作写回舵机

后面的接线、校准和部署,都是在维护这条数据链。

1.1 硬件路径

主控、HAT 与 Dynamixel 总线的硬件连接路径图

这里的单线指单根数据线,完整连接仍包含数据、VDD 和 GND。官方 HAT 同时提供 TTL 与 RS-485 接口,但 Microduck 的 XL330 使用三针 TTL 接口。

1.2 每个 20 ms 周期发生什么

官方 robotd 当前设计为 50 Hz:

50 Hz 控制周期内读取状态到写入舵机目标的时序图

电压和温度不需要塞进每个 20 ms 周期。官方设计每秒另读一次慢速传感器寄存器,降低总线占用。

1.3 软件服务

官方运行时是 Rust workspace,没有采用 ROS 作为核心框架。当前架构把职责拆成多个守护进程:

  • robotd:50 Hz 控制环、舵机总线、IMU、策略、安全
  • configd:Wi-Fi、身份、配对和系统配置
  • updaterd:签名更新、健康检查和自动回滚
  • btd:手机 BLE 入口
  • padd:手柄输入并发送高层 intent
  • mediad:摄像头、音频、WebRTC 和部分感知
  • tofd:8×8 ToF 深度流

控制接口使用 Unix socket 上的 JSON-RPC。

客户端发送“走多快、头看哪里、执行什么动作”,不是直接远程写舵机寄存器。

2. 舵机、动作与关节顺序

现在把控制链落到具体关节上。Microduck 有 15 个物理舵机,但行走策略只输出 14 个动作,因为嘴部不参加步态控制。运行时需要把 14 个动作插入一个包含嘴部槽位的 15 元目标数组,再发送到总线。

策略动作顺序是整个项目最不能重排的部分。顺序错一位,网络能正常推理,但动作会被送到错误的关节。

2.1 策略动作顺序

  • Action 索引 0:左 hip_yaw,对应总线 ID 20
  • Action 索引 1:左 hip_roll,对应总线 ID 21
  • Action 索引 2:左 hip_pitch,对应总线 ID 22
  • Action 索引 3:左 knee,对应总线 ID 23
  • Action 索引 4:左 ankle,对应总线 ID 24
  • Action 索引 5:neck_pitch,对应总线 ID 30
  • Action 索引 6:head_pitch,对应总线 ID 31
  • Action 索引 7:head_yaw,对应总线 ID 32
  • Action 索引 8:head_roll,对应总线 ID 33
  • mouth,不在策略动作中,对应总线 ID 34
  • Action 索引 9:右 hip_yaw,对应总线 ID 10
  • Action 索引 10:右 hip_roll,对应总线 ID 11
  • Action 索引 11:右 hip_pitch,对应总线 ID 12
  • Action 索引 12:右 knee,对应总线 ID 13
  • Action 索引 13:右 ankle,对应总线 ID 14

2.2 14 维动作到 15 槽目标数组

在运行时内部,15 个电机目标可以理解为:

[左腿 5 | 头颈 4 | 嘴 1 | 右腿 5]
  0..4     5..8      9      10..14

策略动作数组则是:

[左腿 5 | 头颈 4 | 右腿 5]
  0..4     5..8      9..13

不能把 action 9 直接写给 15 槽数组的 index 9。那会把右髋命令写到嘴上,并让整条右腿错位。

2.3 被动关节不是策略关节

轮子和回差模型中的关节使用 passive_* 命名。它们可能出现在 MuJoCo 的 qpos/qvel 中,但不进入 14 维策略关节列表。

roller 或 backlash 模型会改变 MuJoCo 索引,因此自定义代码应调用官方辅助函数解析舵机关节。

3. 61 维观测与 ONNX 契约

神经网络并不会直接看到机器人,它只接收一个按固定顺序排列的 61 维数字数组,其中包含 IMU、关节状态、上一时刻动作和运动命令,网络返回 14 个动作值。

所谓部署契约,就是训练端和真机端必须对这些数字的顺序、单位和缩放达成完全一致。

最容易犯的错是网络能够运行、输入形状也正确,但某些字段顺序或单位不一致,导致真机做出错误动作。

3.1 完整布局

  • 0..3,3 维:躯干坐标系角速度 gyro,rad/s
  • 3..6,3 维:躯干坐标系中的投影重力 projected_gravity,单位向量
  • 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  neck_pitch, head_pitch, head_yaw, head_roll
55..61  body x, y, z, roll, pitch, yaw

其中 vx、vy 使用 m/s,vyaw 使用 rad/s。四个头部目标和 body 的 roll、pitch 使用 rad,body 的 z 使用 m。

运行时把 body 的 x、y 和 yaw 固定为零,z、roll、pitch 只有在 body-pose 模式下才非零。

固定为零不代表可以删掉这些槽位,共享 61 维布局正是不同策略能够切换的前提。

3.2 ONNX 必须满足的条件

  • 输入形状是 [1, 61]
  • 输出形状是 [1, 14]
  • 关节顺序与上节一致
  • 单位、符号、home pose 和动作缩放与训练一致
  • 观测归一化器已经烘进 ONNX
  • 推理前应先做一次 warm-up,避免第一次调用延迟出现在控制周期中

3.3 归一化与导出

在仿真里直接 play 时,框架会应用训练时的观测归一化器,因此一个错误导出的网络可能仍然表现正常。

真机运行时没有外部 Python 训练器替你补这一步,必须使用官方导出路径:

不要手工把 .pt checkpoint 转 ONNX 后就部署,会漏掉观测归一化器。

4. 材料与工具

第一版先围绕“能站、能走”的核心闭环采购。摄像头、ToF、音频和 NFC 不参与基础行走,可以在步态稳定后再增加。

下面的 BOM 是功能清单,不要求一次买齐。建议先购买主控、1–3 个舵机、总线接口和限流电源完成台架测试,再扩展到 15 个舵机和整机结构。

4.1 最小核心 BOM

  • 主控:Radxa Zero 3W,RK3566,当前运行时目标平台
  • 主接口与电源板:Pollen RPI Robot HAT,或经验证的等效方案
  • 舵机:Dynamixel XL330 ×15,14 个策略关节 + 1 个嘴部舵机
  • 具体舵机变体:第三方资料推断为 XL330-M288-T,市售版电压规格与 RL 电压模型存在差异,采购前必须核对
  • 运动 IMU:实现 imu_to_dxl v2 接口的完整板卡与固件,ID 200;已有第三方原理图与 PCB 参考工程,但未打样、未实物验证,也未找到随工程交付的可编译或可烧录桥接固件,见第 8 章
  • IMU 芯片:LSM6DSV16X,与当前 v2 数据路径匹配
  • 电池:官方运行时以 NP-F550 类 2S 锂离子为背景,DIY 电源设计另行验证;不代表可直接给市售 XL330 供电
  • 结构件:依据 MJCF 定位,逐件检查 STL,必要时重画;15 个刚体组不是 15 个打印件,见第 6 章的数量口径与试制方法
  • 总线接口:使用 HAT 的三针 Dynamixel TTL 端口,或等效自动换向接口;1 Mbps、3.3 V 逻辑、单线半双工、Protocol 2.0
  • 电源转换:HAT 板载主控电源,或独立稳定 5 V;舵机侧使用合规母线;HAT 输入范围不能代替舵机数据手册
  • 电源保护:保险丝、总开关、快速断电和反接保护;台架和整机都需要

4.2 主接口 PCB 选择

RPI Robot HAT 不是只能根据照片重画的未知板卡。Pollen Robotics 已经公开 elec_RPI_Robot_HAT,仓库包含 KiCad 原理图与 PCB、生产用 Gerber、BOM、贴片坐标和机械模型。

这些是有价值的制作依据,在打板前须逐项核对 PCB 修订号、板框和固定孔、器件与连接器高度、40 针接口、电源网络,以及与所用 Radxa 和外壳的兼容性。

官方 PCB 的板框约为 65.0 × 30.9 mm,板厚 1.0 mm。设计卡槽、支柱和连接器开口时,应从该修订的 KiCad/Gerber 及实际器件尺寸建立配合,不能直接用仿真 STL 的近似板框。

HAT 集中四类功能:

  • 把 Radxa 的 UART2 接到 Dynamixel TTL/RS-485 物理接口。Microduck 使用其中的三针 TTL 接口
  • 接受电机连接器一侧的电源输入,并为主控生成电源
  • 提供 TLV320AIC3104 音频 codec、板载麦克风和扬声器连接
  • 提供 BMI088 和 Qwiic/Stemma 扩展接口,ToF 可由此接入

基础行走版可以不复刻音频、BMI088 和 Qwiic 部分,也可以不用完整原版 HAT,但不能把整板简单理解为音频附件。

采用简化方案时,要重新实现经过验证的单线半双工 TTL 收发、Dynamixel 接插件、主控稳定 5 V、共地和电源保护。

4.3 可选感知与交互

  • 摄像头:IMX219 / Raspberry Pi Camera v2 路径,第三方根据设备树推导
  • ToF:VL53L5CX 或 VL53L8CX,8×8;当前 tofd 支持两代,可接官方 HAT 的 Qwiic/Stemma 接口
  • 音频 codec:TLV320AIC3104,官方 RPI Robot HAT 已公开原理图和 BOM
  • 第二 IMU:BMI088,官方 HAT 实装,但当前运行时将其视为 dormant,不进入 RL 观测
  • NFC:官方产品有两天线,第一版行走验证不需要

4.4 工具

  • 数字万用表
  • 可调限流电源
  • 逻辑分析仪或示波器
  • Dynamixel USB/TTL 调试接口
  • 精度至少 0.1 g 的电子秤
  • 游标卡尺
  • FDM 或树脂打印机
  • CAD 软件
  • 螺纹规、钻头、铰刀和热熔螺母工具
  • 机械吊架或测试绳
  • 护目镜和耐火电池袋

第三方逆向认为,整机主要使用 M2 紧固系统,并推断了轴承尺寸和孔型。

5. 跑通仿真

第一项实际操作是在电脑上跑通官方训练环境,这样做有两个目的:

  • 确认软件依赖和任务名称正确
  • 在制作硬件前,亲眼看到策略的输入、输出和机器人关节如何对应

不需要真实舵机,主要是测试通过、训练冒烟测试能够运行,并能在仿真中播放一个策略。

5.1 四套资料

git clone https://github.com/pollen-robotics/microduck.git
git clone https://github.com/pollen-robotics/microduck_rl.git
git clone https://github.com/pollen-robotics/elec_RPI_Robot_HAT.git
git clone https://github.com/fanhao375/microduck-replica.git

作用分别是:

  • microduck:真机 Rust 运行时、服务、设备树、配置和控制设计
  • microduck_rl:MuJoCo 模型、训练环境、PPO、BAM、导出和 CPU 推理
  • elec_RPI_Robot_HAT:官方 HAT 的 KiCad 工程、生产文件、BOM 和机械模型
  • microduck-replica:第三方装配重建、紧固件和电控逆向参考

5.2 准备训练环境

当前 microduck_rl 要求 Python >=3.12,<3.13,并使用 uv 管理环境。

先按 uv 官方安装文档 完成安装。

再检查工具和显卡:

uv --version
nvidia-smi

进入 microduck_rl 后,后续的 uv run ... 会根据项目锁文件自动创建和同步 Python 环境,不需要先手工建立虚拟环境。

ARM 主机首次同步约 2 GB CUDA 依赖时,可先执行 export UV_HTTP_TIMEOUT=600,避免默认下载超时。

训练主路径要求 NVIDIA CUDA GPU。查看任务、运行部分 CPU 测试和 ONNX CPU 复演不需要本地 CUDA 训练。

5.3 检查任务注册表

cd microduck_rl
uv run list-envs

仓库当前包含行走、行走加跌倒恢复、起身、坐站、触地拾取、踢球、前滚翻和多种轮滑任务。

5.4 运行测试

uv run --with pytest pytest tests/

这些 CPU 测试会检查关节索引、奖励符号、NaN 防护等基础约束。

5.5 训练冒烟测试

官方项目把“64 个环境、5 次迭代”作为低成本冒烟测试,用来提前发现配置、观测和导出问题。

5.6 正式训练

官方给出的参考是现代 CUDA GPU 上约 1–2 小时可得到可用步态,但实际时间取决于 GPU、代码版本和训练配置,不能作为保证。

本地没有 CUDA GPU 时,可以让同一条命令通过 Hugging Face Jobs 执行:

会把任务提交到 Hugging Face Jobs,需要相应账号、权限和算力额度。

当前官方 MuJoCo Warp 训练路径要求 CUDA。

6. 从 MJCF 重建装配图与 CAD

仿真仓库里的网格不是一套可以直接生产的 CAD 图纸,每个 STL 只描述一个局部网格,真正的装配位置、父子关系和旋转轴保存在 MJCF 中。

本阶段任务是先恢复零件应该摆在哪里、绕哪里转,再把这些几何参考重建为可加工、可装配的参数化零件。

完成后,应得到一个包含 15 个刚体组和正确关节基准的 CAD 装配,而不是一堆堆在原点的 STL。

6.1 MJCF 比单个 STL 更重要

STL 只保存三角网格。MJCF 还保存:

  • 刚体父子关系
  • 关节轴线
  • 关节限位
  • 相对位姿
  • 质量和惯量
  • 碰撞几何
  • keyframe

官方 RL 仓库当前主要模型包括:

  • robot_walk.xml:行走,简化部分躯干/头部碰撞
  • robot_groundcontact.xml:起身、坐站、拾取、踢球、翻滚等接触任务,原 allcollisions 家族的新名称
  • robot_groundcontact_rollers.xml:对应的被动轮子任务
  • robot_allcollisions.xml:新增的更完整碰撞模型;本快照任务配置尚未使用它,本文用其视觉网格恢复装配
  • robot_*_backlash.xml:带关节回差的派生模型

行走模型为训练效率删除部分碰撞,不应直接拿它当完整机械干涉检查模型。

6.2 第三方装配恢复项目的输出

第三方 microduck-replica 中,使用官方 robot_allcollisions.xml 和其中引用的视觉网格完成了四类输出:

  1. 从 MJCF 恢复零位姿态下的运动学装配关系
  2. 将 47 个局部坐标系网格按刚体归并为 15 个装配部件
  3. 生成四张普通视图、两张爆炸图和一张分色对照图
  4. 导出 15 个已应用世界变换的 STL、一个整机合并 STL,以及源网格对照 JSON

该项目报告的零位外包尺寸约为 144 × 141 × 264 mm,整机合并网格为 796,792 个三角面,仿真刚体总质量约 737.2 g。

这些是第三方脚本对特定版本模型的输出,不是官方制造尺寸或成品称重值。

从 MJCF 恢复的 Microduck 零位装配态渲染图

仓库导出的是已经摆到正确世界坐标的三角网格集合,便于一起导入 FreeCAD、Fusion 360、SolidWorks 或 Blender。它不是带特征树、配合约束、材料表和可编辑尺寸的原生 STEP/FCStd/SLDASM 装配体。

6.3 从 MJCF 得到装配树

第三方脚本按 MJCF 的 body 层级把网格归到 15 个刚体组。零位结构可概括为:

躯干、双腿与头颈 15 个刚体组的零位装配结构图

躯干和头部总成在仿真中分别约 199 g 和 189 g。这个质量分布提示头部对整机质心影响很大,摄像头、屏幕、扬声器或外壳材料一旦变化,应重新测量头部质量和惯量。

  • 01 躯干主体(MJCF body:trunk_base):合并 10 个源网格,仿真质量 199 g
  • 02 左髋 yaw→roll(yaw2roll):合并 4 个源网格,仿真质量 23 g
  • 03 左髋 roll(hip_l):合并 2 个源网格,仿真质量 6 g
  • 04 左大腿(upper_leg_left):合并 5 个源网格,仿真质量 48 g
  • 05 左小腿(leg):合并 2 个源网格,仿真质量 22 g
  • 06 左踝与脚(ankle_left):合并 4 个源网格,仿真质量 30 g
  • 07 颈根(neck):合并 4 个源网格,仿真质量 37 g
  • 08 颈俯仰(neck_pitch):合并 2 个源网格,仿真质量 6 g
  • 09 头 yaw/roll(yaw_roll_motion):合并 4 个源网格,仿真质量 49 g
  • 10 头部总成与喙(jaw_soft):合并 16 个源网格,仿真质量 189 g
  • 11 右髋 yaw→roll(bearing_roll):合并 4 个源网格,仿真质量 23 g
  • 12 右髋 roll(hip_l_2):合并 2 个源网格,仿真质量 6 g
  • 13 右大腿(upper_leg_right):合并 5 个源网格,仿真质量 48 g
  • 14 右小腿(leg_2):合并 2 个源网格,仿真质量 22 g
  • 15 右踝与脚(ankle_right):合并 4 个源网格,仿真质量 30 g

同名源网格可能在多个位置实例化,因此源网格数是各刚体引用次数,不等于唯一 STL 文件数。

6.4 坐标变换

上游网格的顶点位于各自局部坐标系。直接把 47 个 STL 一起导入 CAD,它们会堆在原点附近,恢复装配必须使用 MuJoCo 在零位前向运动学后给出的每个 geom 世界位姿。

局部网格经世界位姿变换摆到正确装配位置的示意图

对应的数学关系是:

p_world = R_world_geom · p_local + t_world_geom

第三方导出脚本中的等价实现为:

d.qpos[:] = 0
d.qpos[3] = 1.0                 # freejoint: qw = 1
mujoco.mj_forward(m, d)

mid = m.geom_dataid[g]          # 此处 g 已筛选为视觉 mesh geom
va, vn = m.mesh_vertadr[mid], m.mesh_vertnum[mid]
fa, fn = m.mesh_faceadr[mid], m.mesh_facenum[mid]
V = m.mesh_vert[va:va + vn]     # 编译后的顶点,不是另读的原始 STL
F = m.mesh_face[fa:fa + fn]     # 对应的局部面索引
R = d.geom_xmat[g].reshape(3, 3)
p = d.geom_xpos[g]
W_mm = (V @ R.T + p) * 1000.0
triangles_mm = W_mm[F]

脚本只选择 geom_group == 2 的视觉网格,并按 geom_bodyid 分组。

这一选择适合生成外观装配图,不代表碰撞几何、关节标记或工程基准已经被写入导出的 STL。

6.5 重现装配图与定位 STL

第三方脚本有一套独立于 RL 训练环境的轻量依赖。进入 microduck-replica 后,先建立虚拟环境:

python3 -m venv .venv
source .venv/bin/activate
python -m pip install mujoco numpy pillow

然后在仓库根目录执行:

# 拉取官方 microduck_rl 与 microduck 仓库
bash scripts/fetch_upstream.sh

# 从 robot_allcollisions.xml 重新渲染 7 张装配图
python scripts/render_assembly.py upstream/microduck_rl assembly-drawings

# 导出 15 个刚体分组 STL、整机 STL 和零件对照表
python scripts/export_assembly_stl.py upstream/microduck_rl cad

应看到脚本正常退出,cad 中同时存在 15 个分组 STL、00_Microduck_整机装配体.stl 和 零件对照表.json。

脚本依赖 mujoco、numpy 和 pillow,渲染还需要可用的 OpenGL 离屏上下文。

爆炸图不是从 CAD 约束自动生成的。第三方渲染脚本沿每个 body 的父链累加偏移,并以约 48 mm 的步长将链末端逐级移远。它表达的是运动学层级,不是实际拆装方向、螺丝抽出方向或线束拆卸顺序。

6.6 从定位 STL 建立可编辑 CAD 装配体

按以下步骤把第三方转成自己的工程装配:

  1. 将 01–15 的定位 STL 一次性导入,保持原始毫米单位和导入变换不变
  2. 用 07_分色对照_装配态 .png 和 零件对照表 .json 检查是否有漏件、镜像错误或单位错误
  3. 把每个网格转换为独立 mesh/body,仅把它当作外形参考

从 MJCF 重新创建 14 个策略旋转副,并单独创建嘴部机构;

  • 在每个 joint 的 pos 建局部坐标系,以 axis 定义旋转轴,以 range 定义运动限位;
  • 用参数化实体重画舵机支架、轴承座、壳体分缝、连接器孔和紧固件结构;
  • 将视觉网格隐藏,只保留重画后的可制造零件做干涉和运动检查;
  • 为每个总成建立质量、材料、版本和实测偏差属性。

若需要从 MJCF 计算 CAD 中的关节基准,可使用:

T_world_body = T_world_parent · T_parent_body(q=0)
p_world_joint = p_world_body + R_world_body · p_body_joint
axis_world_joint = R_world_body · axis_body_joint

定位 STL 本身不保存 joint pos、axis 或 range,所以只把网格导入 CAD 并不能得到可运动装配,必须同时读取 MJCF 关节定义。

MJCF 关节坐标系与 STL 网格导入 CAD 的对照图

6.7 从仿真网格到可打印工程件

定位网格进了 CAD,只说明恢复了模型里的摆放关系,还要检查哪些是真正需要制造的零件。先恢复 joint 基准和限位,再检查承力件的舵机、轴承和紧固件配合;单关节试片通过后,再做腿部和头颈总成。

本次按当前模型的视觉实例分类,结构类网格有 30 类、36 个实例;这是装配模型的核对口径,不是已确认的生产 BOM。数量重复的六类为 yaw2roll、bearing_roll、hip_l、upper_leg_rigidity_plate、leg、neck,各两件,其余结构类各一件。第三方打印清单中的 41 件与这份模型不一致,不能直接照抄。它也不包含足够的螺钉长度、垫片、线束与工艺信息。

建议把重新生成的 JSON 整理成自己的制造清单,逐项列出“网格名—所在刚体—实例数—制造/采购—材料—版本—配合结果”,不要以孔洞数量反推螺丝采购量。

真正的工程件还缺这些内容:

  • STL 网格修复、封闭和合理减面;
  • XL330 本体、舵盘、从动轴承和紧固件的真实安装界面;
  • 热熔螺母、嵌件、螺钉头和工具操作空间;
  • 轴承座压配或间隙配合公差;
  • 关节全行程线束弯曲半径、夹线风险和连接器拔插空间;
  • 壳体分件、打印方向、支撑面和层间受力;
  • 软限位之外的物理止挡以及摔倒碰撞路径。

第三方紧固件分析可以作为孔型调查的起点,但孔径统计不能自动确定每一颗螺丝的长度、材料、锁紧方式和装配顺序。

6.8 单关节试制

至少验证:

  • XL330 能否装入
  • 输出轴与从动轴承是否同心
  • 舵盘和外壳是否干涉
  • 螺丝刀是否有实际操作空间
  • 舵机线是否能转弯并承受全行程
  • 正负限位是否与 MJCF 一致
  • 连续摆动后孔位是否松动
  • 摔落冲击是否会沿层纹劈裂

6.9 质量与质心

对每个装配总成单独称重,并记录:

  • 左/右腿各段质量
  • 躯干质量
  • 头部与嘴部质量
  • 电池、主控、HAT 和线束质量
  • 整机质心位置

结构从约 800 g 增长到 1.2 kg,不是小误差,而是另一套执行器和动力学系统。若质量或质心明显改变,应更新 MJCF 并重训,不要只提高动作缩放硬顶。

6.10 材料选择

  • 尺寸验证件:PLA
  • 第一版可用结构:PETG、ABS 或 ASA
  • 高负载关节:考虑 PA 或纤维增强材料,但先验证层间强度
  • 轴承座:按实际打印机和材料做公差样条
  • 螺纹位置:优先热熔螺母或贯穿螺栓,不要依赖薄壁塑料直接攻丝承受冲击
  • 足底与软嘴:分别核对摩擦、柔性和连接方式,不应与承力结构统一用一种硬料打印,更换足底材料后须重测接触摩擦

7. 电源与 Dynamixel 总线

机械件能装起来后,电气系统仍应先留在台架上。RPI Robot HAT 把主控供电和 Dynamixel 物理接口集中到了一块板上,但它不会替你解决舵机选型、电池保护和整机瞬时电流。

Dynamixel 允许多颗舵机共用一条数据线,每颗设备仍要有唯一 ID。先把 HAT 或等效接口、1 Mbps 批量读写和限流供电跑稳定,再把 15 个舵机塞进狭窄的机身,后续排查会轻松得多。

7.1 先看清 HAT 上哪些电源脚相通

电源设计最容易混淆三件事:电池电压、舵机供电电压、主控的 5 V。HAT 没有把每个 Dynamixel 插口变成独立稳压输出。

下面是核对的 C1 PCB 电源网络关系,用于解释原理,不是可以照接的 DIY 接线图:

C1 PCB 上 Dynamixel 接口与电源网络连接关系图

C1 接点与网络/作用:

  • J13、J14 三针 TTL:1 脚,GND
  • J13、J14 三针 TTL:2 脚,+BATT,两口共网
  • J13、J14 三针 TTL:3 脚,TTL DATA
  • J3、J11 四针接口:2 脚,同一个 +BATT;不是另一组独立电源
  • U9 AP63205 输入:+BATT;固定 5 V 降压支路
  • J4 主控排针:2、4 脚,+5V,与 +BATT 不是同一网络

把电池接到一个电机口,再把低压舵机接到另一个口,不会自动给舵机降压。两种不同电压源也不能分别接入这些共网端口。图中的电源转换支路面向主控,不是 15 个舵机的独立稳压器。

官方 HAT 资料标注 5–28 V 输入,但 U9 是固定 5 V 的降压芯片,不是升降压芯片。若前级仅提供 5 V,考虑芯片、开关路径和线束压降后,不能据此保证主控端仍有稳定的 5 V。C1 的 LM5050/Q2 电源 OR-ing 路径也不代表所有端口都有完整反接保护。TH1 位于 TTL 数据路径,不是电机电源上的限流器。

7.2 DIY 供电与运行时必须一起适配

市售 XL330-M288 手册规定 3.7–6.0 V,推荐 5.0 V。满电 2S 电池约 8.4 V,不能直接接给它。另一方面,官方 RL 执行器模型使用 6.5–8.2 V 的电压随机化,运行时也把舵机回报电压当作 2S 电池电压。现有材料不足以解释实物版本是否有特殊舵机或其他电源安排。不要用仿真参数覆盖器件规格。

给舵机加稳压只是第一步。当前运行时以 6.6 V 为空电量、8.2 V 为满电量,默认开启 safety.battery_empty_shutdown。若舵机改为 5 V,未适配的程序会把正常母线判为空电池,进入坐下后关机或直接解除扭矩并关机的路径。第一个有效读数就能作为电压平滑器初值,不应期待必有十秒缓冲。

制作前要落实以下四项,并在台架上联合验证:

  1. 分别定义电压域。 列明电池、舵机、主控及传感器的实际输入范围、额定与瞬时电流;若保留 C1,明确怎样与其共网电源脚兼容。本文不提供未经验证的割线、改焊或并接方案。
  2. 分别测量电池和舵机母线。 稳压后的 5 V 不再代表电池剩余电量,需要独立电池测量与对应的欠压处理。只降低软件阈值或永久关闭保护,不能恢复正确的电量估算。
  3. 对齐模型中的全部电压假设。 修改 BAM 的实际工作电压、随机化范围和最低电压等参数,并验证响应。运行时的 policy.voltage_adapt 默认关闭,若启用,还要处理其 6.0–9.5 V 钳位与标称电压假设。
  4. 实测瞬态。 分别观察舵机启动、多个关节同时动作和电源切换时的舵机母线、主控 5 V、远端压降与温升,再继续整机装配。

选择电源时按多舵机启动及堵转瞬态考虑线径、连接器、保险和物理断电。控制与传感器接口按设计共地。首次使用限流台架电源,不直接接电池。C1 生产配置不是 NP-F550 充电板,电池应使用匹配的独立充电方案。

本次没有完成适配市售 XL330 的整套电源、电池检测和 C1 改接实物验证。在这些项目完成前,可以继续做仿真、CAD 与独立单舵机测试,但不要把 5 V 舵机 + 原版默认运行时当作已经验证的整机方案。

7.3 总线物理层

当前官方基线:

  • 接口:TTL 半双工
  • 数据线:单线
  • 数据逻辑:3.3 V TTL(ROBOTIS 标注 5 V tolerant)
  • 协议:Dynamixel Protocol 2.0
  • 速率:1,000,000 baud
  • 端口:/dev/ttyS2

这里的 3.3 V 指数据线逻辑电平,不是舵机供电电压。官方 HAT 同时做出了三针 TTL 和四针 RS-485 Dynamixel 接口,Microduck 的 XL330 应接三针 TTL 端口。普通 USB-UART 的 TX、RX 两线直接并接不能代替半双工接口。如果不用官方 HAT,需要正确的收发或自动方向电路,并确认高阻态、上拉和电平兼容。

7.4 台架顺序

  • 只给 HAT 或等效板上电,不接舵机,测量主控 5V 并确认没有异常发热;
  • 启动 Radxa,确认 /dev/ttyS2 空闲;
  • 通过 TTL 端口接一颗舵机,读取型号、ID、位置、电压和温度;
  • 设置唯一 ID,并验证 1 Mbps;
  • 增加第二颗并做 sync_read;
  • 扩展到一条腿;
  • 扩展到 15 颗;
  • 最后加入 ID 200 的 IMU 板。

前几步使用独立的 Dynamixel 调试工具,并保持 robotd 停止。每次只增加一个变量。

8. IMU 到 Dynamixel 桥接

行走策略除了关节位置,还必须知道机器人正在向哪边倾斜。Microduck 没有让主控通过另一条 USB 或 I²C 路径单独读取运动 IMU,而是把 IMU 包装成一个 Dynamixel 从设备,与舵机共用同一条总线。

这里需要完整的传感器、桥接电路和固件,不是一块裸 LSM6DSV16X 模块。现有第三方 microduck-replica 提供原理图、PCB 工程、STEP、板框 DXF 和接线表,可以在这份设计上继续评审与开发,不必从空白开始。

8.1 运行时接口

imu_to_dxl v2 作为 ID 200 的 Dynamixel 从设备,与 15 个舵机在同一次 sync_read 中返回数据。控制环从地址 124 开始读取 12 字节,源码以半开区间 124–136 表示,末地址 136 本身不属于数据块。

当前路径使用 LSM6DSV16X 的 SFLP 姿态融合,12 字节块包含三轴陀螺和压缩的四元数分量。

字节与编码:

  • 0..6:gyro x/y/z,三个小端有符号 i16,量程 ±500 dps,17.5 mdps/LSB;运行时转为 rad/s
  • 6..12:SFLP 四元数 x/y/z,三个 IEEE fp16;运行时按单位四元数恢复 w

当前运行时默认把传感器原始轴映射为躯干轴 [+raw_z, +raw_y, -raw_x],并等待至少 25 个有效融合姿态样本后才把 IMU 标为就绪,约相当于 100 Hz 下的 0.25 s。替代板若安装方向不同,应修改安装四元数或固件映射,而不是在策略输入端临时交换数组槽位。

8.2 兼容板的数据路径

LSM6DSV16X 由小型 MCU 通过 SPI 或 I²C 读取,MCU 把陀螺和 SFLP 四元数打包到地址 124 开始的 12 字节区间,再以 ID 200 的 Dynamixel Protocol 2.0 从机身份接入半双工 TTL 总线。

需要落实板上稳压与逻辑电平、MCU 固件、Protocol 2.0 CRC 与字节填充、Sync Read 的回复顺序、寄存器一致更新及安装方向。

可以参考设计如下表,MCU、缓冲器、电源器件和板框不是从官方实物完整确认的 BOM。

  • MCU:STM32G031F8P6
  • 传感器:LSM6DSV16XTR,通过 SPI 连接 MCU
  • TTL 收发缓冲:SN74LVC2G241DCUR
  • 板上稳压:HT7533-1,配有局部保护与去耦设计
  • 板框:45 × 22 mm、两层板,两个对角 M2 安装孔。非官方尺寸

安装时,运动 IMU 应与 trunk_base 刚性连接,不能装在会相对躯干转动的头部后仍沿用躯干观测。

8.3 验收条件

  • 1 Mbps 下连续运行至少一小时无 CRC/超时错误
  • 50 Hz 下每个样本都更新
  • 静止时陀螺零偏稳定
  • 旋转方向与仿真坐标系一致
  • 直立时 projected_gravity 接近运行时期望
  • 四元数归一化且无 NaN
  • 翻转和跨越四元数符号时不产生突跳
  • 上电后在姿态融合尚未稳定时明确报告“未就绪”,不要伪造零姿态

如果暂时无法实现这块板,可以先在台架上用 FakeIo 或修改后的传感器后端验证软件,但这不代表真机策略已经可用。基本行走不能长期依赖与训练模型不匹配的 USB IMU 临时方案。

9. 主控、Linux 与运行时

硬件总线稳定后,再把控制权交给 Radxa Zero 3W 上的官方 Rust 运行时。主控板负责启动系统服务、独占 UART、读取设备、运行 ONNX,并向上层应用提供控制接口。

本阶段先验证操作系统和守护进程,不加载真实行走策略。这样可以把 Linux 配置问题与机器人动力学问题分开。

9.1 开发板路径

官方开发文档当前要求在 Radxa Zero 3 上使用 Armbian 26.2.1 Minimal。官方 roadmap 记录了 Radxa Zero 3W 上的实际行走 bring-up。

由于官方安装文档和发布系统仍在演进,第三方复刻者应先阅读当前仓库中的:

docs/robot/install-dev.md
docs/robot/cheatsheet.md
docs/design/architecture.md
docs/design/robotd-design.md

不要只执行旧教程里的安装命令。开发构建可能涉及签名密钥、发布通道和官方板卡假设。

9.2 刷写并配置开发板

用 Armbian Imager (https://www.armbian.com/radxa-zero-3/) 选择 Radxa Zero 3 和 Armbian 26.2.1 Minimal。

为了与下面的命令和默认路径一致,建议在 Imager 的 profile 中把用户名设为 radxa,并填入 Wi-Fi 和密码。如果选择其他用户名,后文所有 radxa 和 /home/radxa 都要相应替换。

首次启动并接入网络后,从电脑写入 SSH 公钥:

ssh-copy-id radxa@<开发板_IP>

下面的脚本必须从电脑上的 microduck 仓库根目录运行,不要在开发板上运行:

脚本会通过 SSH 传送开发密钥、配置系统、处理重启并在最后执行健康检查。--pause-btd-on-pair 用于规避部分 AIC8800 无线模块在手柄首次配对时的冲突。如果不使用手柄,它不影响基础行走闭环。仓库公开时通常不需要 DUCK_TOKEN。

配置结束后登录开发板并确认版本与服务状态:

ssh radxa@<开发板_IP>
robotctl version
robotctl health

9.3 HAT、GPIO 与设备树

官方 HAT 通过 40 针排针连接 Radxa。基础行走使用 UART2 驱动 Dynamixel TTL 总线,音频、BMI088 和外接 ToF 还会用到 I²C/I²S。

不要把插在 40 针排针上理解成系统一定会自动识别全部外设:当前生产文件中的 HAT EEPROM 位置未装,设备树 overlay 仍要由安装流程明确配置。

如果只验证行走,先让 UART2 和 TTL 总线工作,不要同时引入音频与 ToF。需要启用 HAT 的 I²C 外设时,再按当前 microduck 仓库的 overlay 和安装脚本配置。Radxa 的 I²C3 引脚复用会影响 USB-C PD 协商,不能照搬普通树莓派 HAT 教程。

9.4 UART2 登录控制台冲突

Armbian 默认可能在 /dev/ttyS2 启动 serial-getty,占住舵机串口。官方文档明确记录了这个问题。

先检查:

sudo fuser -v /dev/ttyS2

若确认为登录控制台占用,再禁用:

sudo systemctl mask --now [email protected]

不要在不知道占用者是谁时盲目停止系统服务。

9.5 总线独占

robotd、旧 runtime、调试脚本和 USB 适配器不能同时控制同一条串口。两个进程交错发送包会表现为随机硬件故障。

调试原则:

  • 运行 robotd 时关闭其他舵机工具
  • 用独立初始化命令前先停止守护进程
  • 不要让系统登录控制台重新启用
  • 所有维护脚本都应显式获取独占权

9.6 假硬件验证与无策略验证

--fake 不打开真实电机总线。--no-policy 只是取消策略加载,单独使用它仍会走真实硬件路径。

下面是在已安装 daemon 的开发板上进行假硬件检查的示例。先保持实体电机电源断开,并停止可能占用默认 socket 的真实 robotd 服务

sudo systemctl stop robotd
sudo /opt/robot/daemon/current/bin/robotd --fake --no-policy

在另一个 SSH 窗口读取状态:

robotctl health
robotctl monitor

检查 daemon 能否启动、接口能否读取、循环是否运行。fake 数据不是仿真动力学结果,也不能证明 IMU、真实串口或步态已通过。

结束时用 Ctrl+C 停止前台程序。只有第 7、8、10 章的电源、IMU 与单舵机准备完成,才重新交给真实 robotd 服务接管总线。无策略真硬件测试也要满足这些条件,不要把删掉 --fake 当作无风险的下一步。

10. 舵机编号、零位与整机校准

同一份策略只有在仿真和真机共享同一套“零点与正方向”时才有意义。校准不是让机器人看起来大致站直,而是建立舵机编码器读数、机械安装角和 MJCF 关节角之间的准确对应。

建议从单颗舵机开始,再校准一条腿,最后处理完整的 15 设备总线。任何方向错误都应在低幅度、无负载状态下发现。

10.1 单颗舵机配置

先把其他舵机全部从台架断开,使用与 XL330 相容的独立 Dynamixel 调试接口和工具,例如 ROBOTIS 的 DYNAMIXEL Wizard 2.0。按所购型号手册扫描当前 ID、波特率和固件版本,不要默认新舵机已经是本文所需的 1 Mbps。

关闭扭矩后,按手册设置位置控制模式、ID 和通信参数。EEPROM 项目的写入条件与 RAM 项目不同。每配置一颗,单独重新连接验证,再贴上第 2.1 节的 ID 标签,最后才并回总线。不要让多颗默认同 ID 的舵机一起接受广播配置。

建议逐颗保存以下记录:型号/固件、原 ID 与新 ID、1 Mbps 通信结果、工作模式、返回延迟、软限位、方向、零位以及小角度测试结果。

官方启动代码会校验并校正 return_delay_time=0、baud_rate=3(1 Mbps)、pwm_slope=255、shutdown=52 等少数项。

10.2 无负载方向测试

方向测试应在完整连杆安装前完成。对每个关节执行很小的正向命令,核对:

  • 仿真中正方向
  • 真实舵机正方向
  • 编码器读数方向
  • home pose
  • 机械限位
  • 左右镜像关系

10.3 home pose

home pose 是策略输出的参考中心:

target = home_pose + action_scale × action

运行时把原始位置计数转换为:

q(rad)= 2π × raw / 4096 − π

在这套读数约定下,raw=2048 对应 q=0。它并不会自动证明连杆此时已与 MJCF 的零角装配一致。舵盘安装、机械方向和任何零位配置都要一起核对。

如果某个关节零位偏 5°,策略看到的是在正确位置,真实机械却已偏离。它会用其他关节补偿,常见结果是抖动、歪站、膝盖过热或一迈步就倒。

10.4 整机缓慢回到 home pose

机器人必须先固定在吊架或支架上。确认 15 个舵机和 IMU 状态正常后,用官方命令给关节上电,并在约两秒内渐变到 home pose:

sudo robotctl robot init

这条命令会移动所有关节,而且不需要加载策略。若方向、零位或机械干涉有任何异常,立即断电。完成检查后,用下面的命令解除扭矩:

sudo robotctl robot relax --yes

relax 后机器人会失去支撑并倒下,所以必须先由支架或手稳妥承重。这两条命令都通过 robotd 访问总线,不要同时运行另一个舵机调试程序。

10.5 校准验收

  • 断电后手动摆到 home pose,左右结构应对称
  • 读取的 14 维关节位置应接近训练定义
  • 所有关节在小范围运动时无碰撞
  • 嘴部 ID 34 可单独运动,不影响策略索引
  • 15 颗舵机温度、电压和位置都能读到
  • IMU ID 200 的样本连续更新
  • 总线 50 Hz 连续运行一小时无持续丢包

11. 训练、导出与部署策略

机械质量、舵机、电压和控制频率与模型对齐后,才能把仿真策略迁移到真机。

训练得到的 checkpoint 不能直接交给 Rust 运行时。需要通过官方导出脚本转换为包含观测归一化的 ONNX 文件。

我们需要完成同一个 ONNX 能在 CPU MuJoCo 中正确复演,并满足真机运行时的输入、输出和延迟要求。

详细资料可参考:

yishan@tspy
X 引用
从零跑通 Microduck 强化学习训练与仿真模拟

从零跑通 Microduck 强化学习训练与仿真模拟

这篇内容记录从零跑通 Microduck 强化学习训练与仿真的工程流程,前半部分介绍项目组成、训练与仿真分工、PPO 与策略控制原理、软硬件环境,以及训练和仿真环境的配置步骤,并进入训练方案制定。;本段内容覆盖 Microduck 强化学习训练与仿真的后半程:奖励与域随机化配置、PPO 参数、执行计划、W&B 配置、正式训练与监控、checkpoint 横向选择、ONNX 导出…

阅读完整整理 →

11.1 选择匹配的模型

第一版应尽量保持:

  • XL330 执行器
  • 相同的 14 关节顺序
  • 相近质量和惯量
  • 相同关节限位
  • 相同控制频率
  • 相同动作缩放和运行时后处理
  • 相同 IMU 坐标系和观测单位

11.2 sim-to-real 配置

官方项目还包括:

  • BAM M6 的 XL330 电压级执行器模型
  • 反电动势
  • Coulomb、Stribeck 和负载相关摩擦
  • 电池电压随机化
  • 负载压降
  • 命令延迟
  • 摩擦随机化
  • 编码器偏差和 IMU 误差
  • 可选的 ±1° 回差模型
  • 观测噪声与 NaN 防护

删掉这些内容,仿真里的策略可能更漂亮,但真机迁移通常更差。

11.3 检查训练结果

观察内容如下:

  • 足底是否持续打滑
  • 头部是否用作不合理的配重
  • 是否通过撞地获取奖
  • 关节是否长期贴限位
  • 动作是否高频抖动
  • 碰撞是否依赖被简化掉的模型区域

11.4 ONNX CPU 复演

uv run scripts/infer_policy.py --walking output.onnx

这一步使用部署用 ONNX,而不是训练 checkpoint,可提前发现导出、归一化和命令布局错误。

11.5 把 ONNX 放到机器人上

先从电脑把策略复制到开发板:

scp output.onnx radxa@<开发板_IP>:/home/radxa/my_walking.onnx
ssh radxa@<开发板_IP>

在开发板上运行交互式配置工具:

sudo robotctl configure

将 policy.walk 指向新文件。写入 /etc/robot/robotd.toml 后,对应配置应为:

[policy]
walk = "/home/radxa/my_walking.onnx"

保存时接受工具给出的 robotd 重启建议,也可以退出后显式重启并检查:

sudo systemctl restart robotd
robotctl version
robotctl health
robotctl monitor

如果模型路径错误、ONNX 无法加载或输入输出宽度不是 61/14,robotctl health 会报告异常。修复前不要给机器人上扭矩。再次运行 sudo robotctl configure,在 policy.walk 上按 u 恢复默认值,即可重新使用随官方 release 提供的策略。robotctl monitor 会持续显示实时状态,按 Ctrl+C 退出。

11.6 部署检查

  • ONNX 输入 [1,61]
  • ONNX 输出 [1,14]
  • 由官方导出脚本生成
  • 观测归一化器已烘入
  • 14 个动作顺序正确
  • 嘴部槽位不会吞掉右腿 action 9
  • home pose 与真机零位一致
  • action scale 与策略版本一
  • 运行时滤波与训练/官方配置匹配
  • 推理 warm-up 成功
  • 单次推理稳定小于控制周期预算
  • 任何 NaN 或非有限目标都会被拒绝

策略本身不内嵌动作 EMA,头部和腿部低通位于运行时后处理链。

12. 分级真机调试

第一次真机测试的目标不是行走,而是逐层排除错误。先验证一颗舵机,再验证一条腿、完整总线、IMU、home pose 和离地策略。只有前一级结果正确,才让机器人承担更多重量和自由度。

把“接线错误、索引错误、零位错误和策略不匹配”分开处理,避免整机摔倒后只能猜测原因。

12.1 十级调试顺序

任一级出现方向、限位、供电、温升、时序或通信异常,都应停在该级修复,不要带着已知问题进入下一阶段。

推荐顺序:

  • Test 1:单舵机 读取位置、速度、电压、温度,做 ±5° 小运动。
  • Test 2:一条腿 卸载或悬空,验证五关节顺序、方向和限位。
  • Test 3:15 舵机在线但扭矩关闭 确认每个 ID 唯一,状态读取稳定。
  • Test 4:加入 IMU 确认 16 个设备一次 sync_read 能稳定运行,姿态方向正确。
  • Test 5:缓慢回 home pose 机器人固定在吊架上,使用缓慢插值,观察是否有反向或干涉。
  • Test 6:脚离地运行策略 检查动作顺序、幅度和对称性。此时不能判断平衡性能,但能发现严重映射错误。
  • Test 7:双脚接触、外部扶持 只加载站立策略,逐步增加支撑负载。
  • Test 8:保护绳下独立站立 地面铺软垫,急停在手边,先测试 5–10 秒。
  • Test 9:扶持行走 小速度命令,记录 IMU、关节、action、目标和总线时序。
  • Test 10:短距离自由行走 从 0.2 m 开始,不以“一米”作为第一次目标。

12.2 调试日志

先用 robotctl monitor 观察实时状态;需要保存机器可读日志时,可以使用:

robotctl monitor --json --hz 50 > run.jsonl

最少记录:

  • 61 维 observation
  • 14 维 action
  • 15 个目标位置
  • 15 个实测位置和速
  • IMU 原始块与投影重力
  • 母线电压
  • 各舵机温度
  • 控制周期、读写耗时和丢包
  • 视频

没有日志的摔倒只能重看视频猜,有日志的摔倒可以与 MuJoCo 同步对比。

13. 硬件变化与重新训练

强化学习策略会适应训练模型中的重量、惯量、摩擦、回差和执行器响应。更换舵机、加厚外壳或改变电池位置,不只是机械层面的修改,也改变了策略面对的动力学系统。

小改动先实测并回填模型,当质量、质心或执行器特性明显变化时,应重新训练,而不是只靠增大动作幅度补偿。

以下变化通常会破坏现成策略的迁移条件:

  • 换成不同型号舵机
  • 关节减速比、速度或力矩曲线变化
  • 关节回差变化
  • 舵机通信延迟变化
  • 整机增重或质心移动
  • 腿长、足底形状或摩擦改变
  • IMU 安装角度变化
  • 控制频率改变
  • 位置增益或动作滤波改变
  • 电池电压范围改变

正确做法不是只调 action_scale,还要:

  • 测量新硬件
  • 更新 MJCF,质量、惯量、几何、限位
  • 辨识执行器,摩擦、回差、延迟
  • 更新 domain randomization
  • smoke test
  • 重新训练
  • 导出 ONNX
  • CPU 复演
  • 真机扶持测试

14. 常见故障排查

排查时先判断问题属于哪一层:设备是否在线、控制周期是否稳定、关节映射是否正确、仿真与真机是否一致。一次只改变一个变量,并保存修改前后的日志。

下面的表格按“现象 → 高概率原因 → 第一项检查”组织,可作为台架和真机测试时的快速索引。

  • 所有舵机都不可见:/dev/ttyS2 被登录控制台占用、未供电、物理层错误;优先检查 fuser、母线电压、半双工接口。
  • 单颗舵机偶尔掉线:连接器、线径、重复 ID、return delay、压降;优先检查单颗台架、ID 表、示波器。
  • 16 设备时达不到 50 Hz:返回延迟、总线错误、第二写入者、IMU 响应慢;优先检查 EEPROM、独占端口、时序日志。
  • 姿态静止不动但总线无报错:IMU 样本冻结;优先检查样本计数、连续块是否完全相同。
  • 一上扭矩就猛烈撞限位:关节方向、零位、动作映射或单位错误;优先检查单关节小运动、home pose、action 顺序。
  • 左腿正常、右腿乱动:嘴部 index 9 插入错误或右腿映射错一位;优先检查 14 动作到 15 槽目标的映射。
  • 仿真正常,ONNX CPU 复演异常:导出或观测归一化器错误;优先检查只用官方 scripts/export.py。
  • CPU 复演正常,真机立即倒:质量/质心、IMU 坐标、零位、滤波、执行器模型不匹配;优先检查与仿真逐项对齐日志。
  • 站立正常,迈步就掉电重启:电源瞬态、线阻、稳压器余量不足;优先检查示波器测舵机母线和 5 V。
  • 关节持续发热:零位偏差、结构卡滞、增益或摩擦不匹配;优先检查无负载电流、机械手感、目标-实测误差。
  • ToF 服务慢或影响系统:I²C 配置、固件加载、错误地放进控制环;优先检查独立运行 tofd,不要阻塞 robotd。
  • 更新后行为变了但版本看似正确:守护进程未重启、策略和二进制不匹配、配置覆盖;优先检查 robotctl version、health、策略路径。

15. 项目验收清单

不要只用“走起来了”来判断项目是否完成。按下面的清单逐项验收,可以保证仿真、机械、电气、软件和真机结果都能够重复,而不是偶然成功一次。

仿真与训练

  • [ ] uv run list-envs 正常
  • [ ] CPU 测试通过
  • [ ] 64 个环境 / 5 次迭代的冒烟测试通过
  • [ ] 策略可在仿真查看器中运行
  • [ ] ONNX 由官方脚本导出
  • [ ] ONNX CPU 复演正常

机械

  • [ ] 关节树和轴线与 MJCF 一致
  • [ ] 15 个刚体组与分色装配图、零件对照表.json 一致
  • [ ] 在 CAD 中重建了 joint pos、axis 和 range,没有把定位 STL 当作可运动装配
  • [ ] 单关节测试件通过
  • [ ] 左右腿方向和限位正确
  • [ ] 全行程干涉、线束运动包络和工具拆装空间已检查
  • [ ] 每个总成已称重
  • [ ] 质心和整机质量已记录
  • [ ] 线束在全行程不拉扯、不夹线

电气

  • [ ] 电源有限流、保险和物理急停
  • [ ] 实测舵机母线在所购舵机的数据手册范围内,未依据第三方推测直连 2S
  • [ ] 主控 5 V 在舵机动作时稳定
  • [ ] 15 个舵机 ID 唯一
  • [ ] 1 Mbps 总线稳定
  • [ ] ID 200 IMU 连续更新
  • [ ] 50 Hz 运行一小时无持续错误

软件与校准

  • [ ] UART2 无第二占用者
  • [ ] home pose 与实物零位一致未错位
  • [ ] home pose 与实物零位一致
  • [ ] 关节方向、单位和范围一致
  • [ ] robotctl health 可读
  • [ ] 策略输入输出形状正确
  • [ ] 观测归一化器、action scale 和滤波匹配

真机

  • [ ] 吊架下回 home pose
  • [ ] 离地运行策略无异常
  • [ ] 扶持站立稳定
  • [ ] 保护绳下独立站立
  • [ ] 小速度扶持行走
  • [ ] 短距离自由行走
  • [ ] 每次测试有日志和视频
[ ] 每次测试有日志和视频

本文提及与引用

原文提到的内容里,已在本站整理好的可以直接接着读;标注「原文来源」的还没有整理成站内文章。

内容核验说明

价值在于把 Microduck 从仿真到真机的接缝摊开:舵机 ID 与策略索引的对应、61 维观测字段顺序、嘴部槽位插入、ONNX 归一化器、UART2 被登录控制台占用、仿真 6.5–8.2 V 与市售 XL330 的 5 V 冲突。这些对不上的地方,官方文档基本没写。适合有 3D 打印和 Linux 基础、准备动手的人当核对清单。

文中的仿真刚体质量、整机外包尺寸、网格面数、BAM 电压随机化区间等数据来自原作者公开披露及第三方逆向项目输出,诀.com 未独立验证。作者本人标注 IMU 桥接板未打样、未实物验证,适配市售 XL330 的电源与电池检测方案也未完成实物验证, experiencia 型步骤结果不保证复现。

原始来源

原作者:yishan(@tspy)

本文对公开来源内容进行了结构化整理,原观点与内容归原作者所有。

查看原文