Microduck 进阶篇 —— 训练模型、搭建仿真、Rust 部署到 Radxa Zero 3、理解原理与移植
前置:先读 新手学习文档(概念与硬件路线)。本篇回答七个问题:
① 怎么自己训练模型并装上 Radxa Zero 3?② Rust 环境怎么搭?③ 仿真环境怎么搭?
④ 原理怎么理解?⑤ 怎么移植到别的项目?⑥ 从哪起步?⑦ 电路/结构/硬件怎么深化学习?所有命令都来自你工作区里的官方文档,出处随文标注。
0. 全链路地图(先看这一张图)
整个"自己训练、自己部署"是一条流水线,每一步都有独立的验收标准:
【你的电脑】 【Radxa Zero 3W】
microduck_rl 仓库 官方 Rust 运行时
├─ MuJoCo 仿真环境 ├─ robotd 50Hz 控制循环
├─ PPO 训练 (GPU / HF Jobs) ├─ duck-control 库(加载 ONNX)
▼ ├─ 安全层(跌倒/限位/deadman)
checkpoint (.pt) ▼
▼ 官方 export.py(把归一化层写进图里) /opt/robot/policies/current/
walk.onnx obs[1,61]→actions[1,14] ──拷贝──▶ sudo robotctl policy load walk xxx.onnx
▼ CPU MuJoCo 验证(infer_policy.py) ▼
在仿真里会走? ──────────▶ 真机上会走?(先吊装!)
两条铁律现在就记住:
1. 部署契约不可动:obs[1,61] → actions[1,14] @ 50Hz。改了观测顺序、归一化或关节顺序,权重再对也白搭(可复现训练与导出);
2. robotd 会拒绝一切输入输出形状不对的 ONNX——这是安全网,不是障碍(scripts/seed-policies.sh 头注释)。
1. 搭建仿真环境(你的电脑上,无需 GPU,一个下午)
完整版教程:open-microduck/simulation-first.md,以下是其精髓 + 补充解释。
1.1 装两个工具
# ① uv:Python 的包管理器(官方项目用它管理一切依赖)
curl -LsSf https://astral.sh/uv/install.sh | sh
# ② 确认 git 可用(你已经有了)
git --version
1.2 Clone 两个官方仓库并记下版本
git clone https://github.com/pollen-robotics/microduck_rl
git clone https://github.com/pollen-robotics/microduck
要做正式实验就固定 commit(OpenMicroDuck 校对过的基线):
cd microduck_rl && git checkout 29e887ecfbf5d37144759e5a9f8a176dfb83d547
cd ../microduck && git checkout 2c61dcc1f03440541cdc0729f7a375b2a9ea3005
平时探索可以跟最新分支,但发表/对比结果时必须记录 commit。
1.3 装依赖
cd microduck_rl
export UV_HTTP_TIMEOUT=600 # 依赖多,防超时
uv sync
第一次会下载较多东西,属正常。这一步只是 CPU 推理,不需要训练 GPU。
1.4 跑官方现成策略(第一个里程碑)
uv run scripts/infer_policy.py \
--walking /absolute/path/to/alpha_walking.onnx \
--standing /absolute/path/to/alpha_stand.onnx \
--sitstand /absolute/path/to/alpha_sitstand.onnx \
--roulade /absolute/path/to/roulade.onnx \
--new-cmd-obs
会弹出 MuJoCo 视窗,鸭子按你的指令走/站/翻滚。默认走 BAM 执行器模型(比理想电机更接近真机,见第 4 节原理)。
验收不只看"会动",按教程原话核对:MJCF 加载成功、ONNX 加载成功、61 维观测被正确接受、14 维动作顺序没错、机器人不是因接口错误而崩。
1.5 训练环境自检(还不是真训练)
uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 64 --agent.max-iterations 5
这个 5 迭代 Smoke Test 只验证:环境能构建、能 step、没 NaN、观测/奖励正常。过了它,你的仿真+训练环境才算搭好。
你仓库里还有现成的实验记录可对照:microduck-replica/rl-series/experiments/(exp000 首次 5 迭代、expC CPU 续训 2199 迭代的完整记录——结论是"不是模型不能走,是训练量不到")。
2. 训练自己的模型
完整版:可复现训练与 ONNX 导出 + 训练参数调整与新动作开发指南(882 行,按"你想改什么"查表)。
2.1 先想清楚:你要哪条路
| 你的情况 | 路线 | 成本 |
|---|---|---|
| 硬件与官方完全相同(含 XL330) | 不需要训练——官方 9 个 ONNX 直接用 | ¥0 |
| 只想微调行为(速度、步态风格) | 本地 GPU 训练 1–2 小时量级 | 一块 CUDA GPU |
| 没有 GPU | Hugging Face Jobs 云端训练 | 按小时计费,先查价 |
| 换了舵机/改了结构 | 必须重训(官方模型作废) | GPU + 见换舵机重训全流程 |
唯一不需要训练的情形就是"什么都不改"。 反过来,任何机械/执行器改动都会让官方 ONNX 失效——这就是为什么第 0 站要先决定舵机路线。
2.2 训练命令(完整四步)
# ① 训练(GPU;官方参考:4096 并行环境的 walking 任务约 1–2 小时出可用步态)
uv run train Mjlab-Velocity-Flat-MicroDuck --env.scene.num-envs 4096
# ② 回放训练结果(先分清"训练没成"还是"导出没成")
uv run play Mjlab-Velocity-Flat-MicroDuck --wandb-run-path <entity/project/run_id>
# ③ 导出 ONNX —— 必须用官方脚本!
# 它会把 observation 归一化层写进 ONNX 图;手工转 checkpoint ≠ 官方部署件
uv run scripts/export.py Mjlab-Velocity-Flat-MicroDuck --wandb-run-path <...>
# ④ 用第 1 节的方法验证"真正要部署的那个文件"
uv run scripts/infer_policy.py --walking output.onnx
没有 GPU 时走 HF Jobs:hf auth login + wandb login 后,第一次必须加 --dry-run 看清规格和费用再真提交,hf jobs cancel <id> 可取消(费用提醒见教程原文)。
2.3 改参数去哪改(不用读完 882 行,按目标查)
训练参数调整指南 第 6 节是一张"症状→文件"对照表,例如:
- 想改站立姿态/零位 → §6.1;想改关节行程/质量/摩擦 → §6.2–6.3
- 想走得更快 → §6.4;想让脚抬更高 → §6.5;想更稳 → §6.6
- 想加抗扰(sim-to-real 鲁棒性)→ §6.7;想调 PPO 超参 → §6.10
一次只改一类参数,用指南第 7 节的单变量 A/B 法记录假设和指标(你仓库的 rl-series/experiments/ 已有模板)。想开发跑步/舞蹈等新动作,看指南第 8–10 节(先"走快"再"跑"、舞蹈第一支只做四拍)。
2.4 常见错误(教程原文浓缩)
- 手工转 checkpoint 忘了归一化层;2. 悄悄改了观测顺序;3. 部署时加了训练时没验证的滤波;4. 把不同模型变体(walk/groundcontact/backlash)当同一个环境比;5. 仿真成功 = sim-to-real 完成——这是错觉。
3. 搭建 Rust 环境并部署到 Radxa Zero 3W
3.1 先分清两台机器
- 开发机(你的 Mac/Linux):写代码、编译、跑 942 个测试;
- 板子(Radxa Zero 3W,aarch64 Linux):运行编译产物。不在板子上装 Rust。
3.2 开发机:五分钟装好
# ① 装 Rust(需要 1.89+ stable)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add aarch64-unknown-linux-gnu # 交叉编译目标
# ② 验证:整个工作区测试(macOS 上 942 个测试全过,无需硬件/网络/Docker)
cd /Volumes/dev/dev/microduck # 官方主仓根目录
cargo test --workspace
Linux 开发机额外装 C 依赖(macOS 不需要):
sudo apt-get install -y libudev-dev libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev
改了板子专属代码(configd/btd 是 Linux-only)要按板子目标 lint:
RUSTFLAGS="-D warnings" cargo clippy -p configd --all-targets --target aarch64-unknown-linux-gnu
3.3 板子:从空白到"开发板"(一次性)
# ① Armbian imager 选 Radxa Zero 3 + Armbian 26.2.1 Minimal
# 刷之前在界面里填好 WiFi + 用户名密码(省掉串口线)
# ② 加入你的 ssh key(后续全自动流程靠它)
ssh-copy-id microduck@192.168.1.42 # 换成板子实际 IP
# ③ 一键装机:发 dev key、装系统依赖、编译部署 daemon、重启、健康检查
export DUCK_TOKEN=ghp_xxx # 仓库若已公开可省
./scripts/provision-board.sh --pause-btd-on-pair --name my-duck microduck@192.168.1.42
# ④ 验证
robotctl health
grep -c 'DEV BOARD' /var/lib/robot/provision.log # 输出 1 = dev key 装好了
--pause-btd-on-pair 不是可省的仪式感:aic8800 无线芯片在手柄首次配对时需要它,漏了会得到一个"怎么都查不出原因的配不上的手柄"(install-dev.md 用一整节解释了三种配置怎么选)。
3.4 把代码推上板(日常循环,约一分钟)
# 一次性准备:交叉编译工具(二选一)
cargo install cargo-zigbuild --locked && brew install zig # 方案 A
# 方案 B:什么都不装,每次加 --docker(需要 Docker 在跑)
# 开发板需要团队 dev 私钥在 ~/.duck-keys/team.dev.key
# 日常:改代码 → 一条命令
scripts/dev-push.sh microduck@192.168.1.42
# 它做:交叉编译 → 打包 → 用 dev key 签名 → scp 到板子 → 走健康门安装 → 等守护进程报新版本
注意:dev-push 装的是 daemon(控制程序)。它和"装模型"是两条通道——这正是官方刻意设计的:改步态不需要重发 daemon,修 daemon 也不用重新下载 6MB 权重。
3.5 安装你自己训练的 ONNX(终点站)
# 把导出的 onnx 拷上板(scp 就行)
scp walk.onnx microduck@192.168.1.42:/home/microduck/
# 加载到 walk 槽位 —— 就是这一条:
sudo robotctl policy load walk /home/microduck/walk.onnx
# 机器人会先回 HOME 姿态、加载、继续驱动;形状不对会被 robotd 拒绝
# 查看/恢复
robotctl policy list # 7 个槽位 + 技能表
sudo robotctl policy reset walk # 恢复官方该槽位策略
策略安装在 /opt/robot/policies/current(在 release 之外,见 scripts/seed-policies.sh 头注释——"步态重训不应该需要 daemon 发版")。官方策略缺失时机器人保持姿态并报告 degraded,不会乱动。
首个真机验收顺序(30 天计划 D25–26):不装腿先空跑 HOME 姿态 → 吊装测试 → 软垫 → 平地。第一次必须手扶。
4. 原理怎么理解:六层地图,按序通读
"原理"不是一本书,是六层。每层给你:一句话本质 + 你仓库里的对应教材。建议按序,每层花一晚上。
L1 强化学习是什么(1 晚,零代码到玩具代码)
本质:不写规则,给奖励让 AI 自己试错。先跑 learning/duck_food_qlearning.py(7 格世界 Q-learning,半小时),再看 小白术语表 的 Observation→Policy→Action→Reward 图。之后记住 PPO 只是一句:"好动作多来点,坏动作少来点"的概率化版本。
L2 61→14 契约(1 晚)
61 维 = 姿态(IMU) + 各关节位置/速度/力矩 + 上一步动作 + 指令(速度/转向) 等,拼成一个向量;14 维 = 14 个关节的目标。看 指南 §4 和 rl-series/scripts/diagram_obs_layout.py(画出每个维度的含义)。这是模型与机器人的全部接口,改哪一层都不能碰它。
L3 控制循环 50Hz(1 晚)
每 20ms:一次 sync_read 从总线读回 16 台设备(15 舵机 + 200 号 IMU)→ 拼 61 维观测 → ONNX 推理 → 电压自适应 → sync_write 下发。看 docs/design/architecture.md(为什么 7 个守护进程分开、为什么只有 robotd 能碰机器人)+ 控制循环与数据流。
L4 总线与电子(1 晚)
1Mbps 单线半双工 TTL,Dynamixel 协议 V2,菊花链,ID 寻址;IMU 伪装成 200 号舵机挂同一条线。看 硬件入门 和 硬件规格速查,配合新手篇第 5 节的原理图课。
L5 Sim-to-real(1–2 晚,最精彩的一层)
为什么仿真里学的能搬到真机?三个手段:域随机化(训练时故意随机化摩擦/质量/延迟,逼策略皮实)、BAM 执行器模型(XL330 的真实摩擦/回差建模,你仓库 bam/ 就是它)、backlash 变体(仿真里加齿轮间隙)。看 Sim-to-real 参数总表 + model-and-rl。
L6 安全与更新(1 晚)
为什么敢让它自己动?robotd 内置跌倒检测、关节/温度限位、意图心跳(deadman);updaterd 每次更新验签→健康门→不健康自动回滚。看 architecture.md 和 updater/tests/apply.rs(CONTRIBUTING 说这是"它到底保证了什么"的诚实答案)。
5. 如何移植到其他项目
"移植"在这个项目里有四种含义,难度递增:
5a. 复用代码库(容易,几天)
duck-control/(总线驱动、观测、安全)、kinematics/(MJCF 运动学)是独立库,任何用 Dynamixel 总线舵机的项目都能拆走用。bam/ 的执行器模型也是通用 Python 库。
5b. 大脑架构模式移植(中等)
"一个 50Hz 循环 + 策略网络 + 安全层,其余守护进程走 JSON-RPC"这套架构不绑定鸭子。你自己的机器人只要能提供同结构的观测(姿态+关节)并接受同结构的动作,就能套用。
5c. 给别的机器人训练策略(真正意义上的移植,数周)
步骤固定:① 给新机器人建 MJCF 模型(几何/质量/惯量/关节轴)→ ② 定义新的 obs/action 空间 → ③ 用 BAM 辨识你舵机的动力学参数(换舵机重训全流程 的四层判定法原样适用)→ ④ 重训 → ⑤ L1–L7 测试金字塔上真机。官方 ONNX 不可移植——它是"这只 737g 鸭子"的肌肉记忆。
5d. 接入小智语音(独立支线,可并行)
官方架构预留了"服务端 LLM 经 WebSocket 发意图"的路径(architecture §5.3);小智 ESP32 支持 MCP 设备端控制。组合拳:小智做语音前端 → 意图 → 鸭子执行。这是你 ESP32 硬件的正经用途,等鸭子能站了再接。
6. 如何起步(今天就能敲的命令)
# ① 装 uv(1 分钟)
curl -LsSf https://astral.sh/uv/install.sh | sh
# ② clone 两个官方仓(5 分钟)
cd ~/dev && git clone https://github.com/pollen-robotics/microduck_rl
git clone https://github.com/pollen-robotics/microduck
# ③ 装依赖 + 跑官方策略(第一次约 20–40 分钟,主要是下载)
cd microduck_rl && export UV_HTTP_TIMEOUT=600 && uv sync
uv run scripts/infer_policy.py --walking /absolute/path/to/alpha_walking.onnx --new-cmd-obs
看到鸭子在仿真里走起来,你就完成了整个项目里性价比最高的一个里程碑:零硬件成本,验证了模型、策略、接口三层。之后再按第 2 节跑 5 迭代 Smoke Test,按第 3 节准备 Radxa。
三条起步铁律:先推理后训练(官方模型能跑通之前不碰训练);先仿真后真机;每次只改一类变量并记录(rl-series/experiments/ 有模板)。
7. 电路图、结构、硬件知识怎么深化
新手篇第 5、6 节教了"怎么读",这里给"怎么练":
电路(每周一个小实验,全部用现有器材)
1. 万用表周:量电池电压、量 USB 线 5V、测通断——建立"电是可测量的"手感;
2. SG90 周:Pi 2 点亮第一只舵机(信号/电源/共地三件事);
3. 总线周:USB 调试板 + 1 只总线舵机 + Dynamixel Wizard,改 ID、读角度;
4. 读图周:把 imu_to_dxl 原理图 讲给别人听(讲不出来 = 没懂);
5. 嘉立创 EDA 周:打开 imu_to_dxl.eprj2,把每个元件的 datasheet 下载来对照引脚。
系统教材推荐:B 站搜"上电"系列/《电子电路入门》类视频即可起步,不必啃大学教材——这个项目的电路量(一块 5 芯片小板 + 一块官方开源 HAT)用项目驱动学刚刚好。
结构(从装配到设计的三级跳)
1. 读:21 页装配安装说明书 翻三遍,对照 23 张组件图;
2. 装:打印测试片定补偿 → 装一条腿(第 4 周)→ 装整机(第二个月);
3. 改:FreeCAD 打开 cad/ 装配体 → 30 分钟小任务(加走线槽/卡扣)→ 再学 Fusion 360 系统课。设计感只能从"装过 50 颗 M2 螺丝"里长出来。
硬件系统知识(读仓库自带的设计文档,这是最被低估的资源)
官方 docs/design/ 是一整套"为什么这么设计"的写作:architecture.md(架构)、updater-design.md(更新/回滚)、policy-channel-design.md(策略通道)。复刻仓 docs/ 是一整套"为什么这么复刻":硬件方案逆向、执行器选型。看完这两套,你对机器人系统的理解就超过大多数只玩过成品的人。
和新手篇同一句话收尾:这条流水线上没有魔法——仿真跑通、训练出步态、导出验证、一条命令上板,每一步都有现成的命令和文档,你要补的只是按顺序把它们各跑一遍。