如何从零DIY复刻一只可爱的Microduck机器鸭(一)

2026-10-28 11:27:48 17阅读

Microduck成品机器人整机图

Microduck是一只约25 cm高的小型双足机器人。这家总部位于布鲁克林的公司通常被描述为开源人工智能模型的GitHub,在Nvidia以129亿美元收购该公司的消息传出后不久,推出了四种配色的Microduck。该机器人是与Hugging Face的子公司Pollen Robotics合作开发的。

Microduck用15个Dynamixel舵机构成双腿、颈部、头部和嘴部,其中14个关节由行走策略控制,嘴部单独控制。主控板持续读取舵机位置和 IMU 姿态,把这些数据交给一个ONNX 神经网络,再把网络输出转换成新的关节目标。这个循环每秒运行50次与传统预先写好每一步关节角度的机器人不同,Microduck的步态先在MuJoCo仿真器中通过强化学习训练,再部署到真机。

Microduck关节结构示意图

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

•  重建与仿真模型一致的机械结构

•  搭建舵机、电源、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所有关节共同使用的参考姿态;策略动作会在这组基准角度上叠加
commitGit 仓库某一时刻的版本哈希;记录它才能复现同一套代码和模型

本教程带你做到的程度

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

摄像头、ToF、音频和NFC属于后续扩展,不影响第一版行走闭环。

整个过程分成七个阶段:

1.固定源码版本

2.跑通仿真

3.MJCF → 装配图与CAD

4.机械试制电源、总线与IMU

5.主控与运行时

6.校准、训练与ONNX

7.分级真机调试

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

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

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

1.主控从总线读取状态

2.神经网络计算动作

3.主控再把动作写回舵机

1.1硬件路径

Microduck硬件路径框图

这里的单线指单根数据线,完整连接仍包含数据、VDD和GND。

1.2 每个20 ms周期发生什么

官方robotd当前设计为50 Hz:

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

1.3 软件服务

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

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

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

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

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

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

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

2.1 策略动作顺序

Action 索引关节对应总线 ID
0左 hip_yaw20
1左 hip_roll21
2左 hip_pitch22
3左 knee23
4左 ankle24
5neck_pitch30
6head_pitch31
7head_yaw32
8head_roll33
—mouth,不在策略动作中34
9右 hip_yaw10
10右 hip_roll11
11右 hip_pitch12
12右 knee13
13右 ankle14

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..33躯干坐标系角速度 gyro,rad/s
3..63躯干坐标系中的投影重力 projected_gravity,单位向量
6..2014关节位置减去 home pose,rad,嘴部除外
20..3414关节速度,rad/s,嘴部除外
34..4814上一时刻策略的原始输出,动作缩放前
48..6113命令块

命令块为:

twist(3) + head_pose(4) + body_pose(6)

当前运行时文档进一步明确其顺序:

48..51  vx, vy, vyaw

49.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训练器替你补这一步,必须使用官方导出路径:

uv run scripts/export.py \  Mjlab-Velocity-Flat-MicroDuck \  --wandb-run-path

不要手工把 .pt checkpoint 转 ONNX 后就部署。

4. 材料与工具

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

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

4.1 最小核心BOM

类别建议说明
主控Radxa Zero 3W,RK3566当前运行时目标平台
舵机Dynamixel XL330 ×1514 个策略关节 + 1 个嘴部舵机
具体舵机变体第三方资料推断为 XL330-M288-T市售版电压规格与 RL 电压模型存在差异,采购前必须核对
运动 IMUimu_to_dxl v2兼容板总线 ID 200
IMU 芯片LSM6DSV16X与当前 v2 数据路径匹配
电池NP-F550 类 2S 锂离子可拆卸电池形态
结构件从 MJCF/STL 重建并参数化不能直接把仿真网格当生产件
总线接口1 Mbps、3.3 V 逻辑、单线半双工 TTLDynamixel Protocol 2.0
电源转换主控稳定 5 V;舵机侧独立稳压母线电压按舵机数据手册设计
电源保护保险丝、总开关、快速断电和反接保护台架和整机都需要

4.2 可选感知与交互

功能当前资料指向说明
摄像头IMX219 / Raspberry Pi Camera v2 路径第三方根据设备树推导
ToFVL53L5CX 或 VL53L8CX,8×8当前 tofd支持两代
音频 codecTLV320AIC3104第三方逆向 HAT
第二 IMUBMI088,当前路径可能 dormant不进入当前 RL 观测
NFC官方产品有两天线第一版行走验证不需要

4.3 工具

•  数字万用表

•  可调限流电源

•  逻辑分析仪或示波器

•  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/fanhao375/microduck-replica.git

作用分别是:

仓库用途
microduck真机 Rust 运行时、服务、设备树、配置和控制设计
microduck_rlMuJoCo 模型、训练环境、PPO、BAM、导出和 CPU 推理
microduck-replica第三方装配重建、紧固件和电控逆向参考

5.2 准备训练环境

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

先按 uv 官方安装文档(

https://docs.astral.sh/uv/getting-started/installation/) 完成安装。

再检查工具和显卡:

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 训练冒烟测试

uv run train \

Mjlab-Velocity-Flat-MicroDuck \  --env.scene.num-envs 64 \  --agent.max_iterations 5

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

5.6 正式训练

uv run train \  Mjlab-Velocity-Flat-MicroDuck \  --env.scene.num-envs 4096

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

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

uv run train \  Mjlab-Velocity-Flat-MicroDuck \  --env.scene.num-envs 4096 \  --hf-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_allcollisions.xml起身、坐站、拾取、踢球、翻滚等全身接触任务
robot_allcollisions_rollers.xml被动轮子任务
robot_*_backlash.xml带关节回差的派生模型

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

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

第三方 microduck-replica 在(https://github.com/fanhao375/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。

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

Microduck爆炸图

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

6.3 从 MJCF 得到装配树

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

MJCF装配树结构图

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

输出部件MJCF body合并的源网格数仿真质量口径
01 躯干主体trunk_base10199 g
02 左髋 yaw→rollyaw2roll423 g
03 左髋 rollhip_l26 g
04 左大腿upper_leg_left548 g
05 左小腿leg222 g
06 左踝与脚ankle_left430 g
07 颈根neck437 g
08 颈俯仰neck_pitch26 g
09 头 yaw/rollyaw_roll_motion449 g
10 头部总成与喙jaw_soft16189 g
11 右髋 yaw→rollbearing_roll423 g
12 右髋 rollhip_l_226 g
13 右大腿upper_leg_right548 g
14 右小腿leg_2222 g
15 右踝与脚ankle_right430 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) R = d.geom_xmat[g].reshape(3, 3) p = d.geom_xpos[g] W = (V @ R.T) + p W_mm = W * 1000.0

脚本只选择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

脚本依赖 mujoco、numpy 和 pillow,渲染还需要可用的 OpenGL 离屏上下文。复现时先记录 microduck_rl 与 microduck-replica 的 commit,因为 MJCF 路径、body 名称和 geom 分组可能变化。

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

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

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

1.将01–15的定位STL一次性导入,保持原始毫米单位和导入变换不变;

2.用07_分色对照_装配态.png和零件对照表.json 检查是否有漏件、镜像错误或单位错误;

3.把每个网格转换为独立 mesh/body,仅把它当作外形参考;

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

5.在每个 joint 的 pos 建局部坐标系,以 axis 定义旋转轴,以range 定义运动限位;

6.用参数化实体重画舵机支架、轴承座、壳体分缝、连接器孔和紧固件结构;

7.将视觉网格隐藏,只保留重画后的可制造零件做干涉和运动检查;

8.为每个总成建立质量、材料、版本和实测偏差属性。

若需要从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关节定义。

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

从仿真网格到工程件流程图

必须补做的工程内容包括:

•  STL网格修复、封闭和合理减面;

•  XL330本体、舵盘、从动轴承和紧固件的真实安装界面;

•  热熔螺母、嵌件、螺钉头和工具操作空间;

•  轴承座压配或间隙配合公差;

•  关节全行程线束弯曲半径、夹线风险和连接器拔插空间;

•  壳体分件、打印方向、支撑面和层间受力;

•  软限位之外的物理止挡以及摔倒碰撞路径。

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

6.8 单关节试制

至少验证:

1.XL330 能否装入

2.输出轴与从动轴承是否同心

3.舵盘和外壳是否干涉

4.螺丝刀是否有实际操作空间

5.舵机线是否能转弯并承受全行程;

6.正负限位是否与MJCF一

7.连续摆动后孔位是否松动

8.摔落冲击是否会沿层纹劈裂

6.9 质量与质心

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

•  - 左/右腿各段质量

•  - 躯干质量

•  - 头部与嘴部质量

•  - 电池、主控、HAT和线束质量

•  - 整机质心位置

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

6.10 材料选择

•  - 尺寸验证件:PLA

•  - 第一版可用结构:PETG、ABS或ASA

•  - 高负载关节:考虑 PA 或纤维增强材料,但先验证层间强度

•  - 轴承座:按实际打印机和材料做公差样条

•  - 螺纹位置:优先热熔螺母或贯穿螺栓,不要依赖薄壁塑料直接攻丝承受冲击

7. 电源与Dynamixel总线

机械件能够装起来以后,先在台架上完成电气系统,不要直接把15个舵机全部装进机身。Dynamixel 允许多颗舵机共用一条数据线,但每颗设备必须有唯一ID,供电还要承受多个关节同时启动造成的瞬时电流。

让主控稳定发现所有设备,并在1 Mbps下连续批量读取和写入,不是让机器人马上运动。

7.1 电源树

电源树示意图

不要把主控直接接到未经确认的舵机母线。主控、摄像头、ToF和音频的稳压与瞬态需求应单独计算。

供电要点:XL330-M288手册给出的工作电压上限为6.0 V,而满电2S电池约为8.4 V。舵机侧应使用数据手册范围内的稳压电源,不要直接连接 2S 电池。

资料矛盾:官方RL的XL330 执行器模型把输入电压随机化在6.5–8.2 V,运行时也从舵机回报值估计2S电池电压。但ROBOTIS对市售XL330-M288-T标出的输入范围是3.7–6.0 V、推荐5.0 V。当前公开资料没有说明量产机是否使用特殊版本舵机,或电源路径是否还有未公开设计。因此,复刻时不能仅凭RL 参数把市售 XL330 直接接到2S。应按手中实物的手册设计稳压,并把实测母线和执行器响应回填到BAM模型后重新训练。若希望复用官方ONNX,则还需先独立确认原机舵机版本与供电路径,不能把第三方推断当作电气规格。

本文原作者:yishanyishan。


作者:电机传感器师
链接:https://www.aiddithome.com/p/f36399b0661d6.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
0条评论
还没有人评论过~