MicroDuck 国产飞特舵机版电子书(首版)
本书以 Pollen Robotics 开源的 MicroDuck 为蓝本,系统呈现一条国内可复现、低成本的双足机器人技术路线:从 MJCF 逆向与 Onshape→MJCF 自动化动力学建模、HD1910 串口总线舵机 BAM 台架辨识,到扩展域随机化 + 课程学习的 PPO 策略训练,再到 RK3566 板端 50 Hz 实时推理与真机闭环迭代,完整覆盖「CAD → 动力学 → 执行器 → 仿真 → 真机」的全栈工程闭环。
前言
配套图书阅读入口
- 在线电子书(GitHub Pages 自动编译):https://unitclaw.github.io/microduck-wwduck/
- 英文版(American academic English edition):https://unitclaw.github.io/microduck-wwduck/en/
- 书稿源码仓库:https://github.com/UnitClaw/microduck-wwduck(
book/中文版、book-en/英文版,mdbook 编写,随提交自动编译部署为网页电子书)
本书每一章书稿都与配套工程仓库的 commit hash 一一绑定,读者可 checkout 到对应版本,完整复现书中每一步实验。 电子书每个章节右上角都有两个入口:📝「编辑」图标直达该章源文件、Octocat 图标直达仓库首页。
电子书章节 ↔ 仓库资源对照
每一章都对应仓库里的具体工程资源,点击即可跳转查阅源码、图纸、清单与日志:
| 电子书章节 | 仓库对应资源 |
|---|---|
| 配件商城 | PARTS.md · 官网商城 |
| 最小仿真 Demo | software/training/ |
| CAD 模型解析 | cad/ · CAD 仓库 |
| Onshape → MJCF | scripts/ |
| 3D 打印与装配 | print/ · BOM.md |
| 硬件电路与总线 | hardware/ |
| RK3566 镜像与固件 | software/image/ · software/studio/ |
| 舵机 / IMU 标定 | tools/ |
| 仿真与训练 | software/training/ |
| ONNX 部署 | software/studio/ |
| 真机步态 | software/ |
| 工程化与开源 | NOTICE.md · LICENSE |
| BOM 采购清单 | BOM.md |
| 故障排查 | 踩坑记录.md |
仓库侧反向入口:仓库
README.md顶部有电子书在线阅读链接与配件商城入口;PARTS.md、BOM.md等文档也标注了对应电子书章节。
核心工程亮点(本书重点创新)
本书在社区 microduck-replica 复刻项目的基础上,补齐了六大工程闭环,构成相对 Pollen 原版与社区复刻的重点创新:
亮点 1|Onshape → MJCF 自动化流水线(对标 Pollen 原厂)
完整复刻 Pollen 原厂 Onshape → MJCF 自动化工作流:从整机 STEP 装配导入,自动计算每个连杆的质量、重心、惯性张量,配合 validate_mjcf.py 自动校验惯性张量、关节限位与整机总质量,彻底告别 replica 手动估算惯性参数带来的 Sim2Real 偏差。
对应第 4 章 · 交付物:
scripts/cad2mjcf/export_mjcf.py+validate_mjcf.py
亮点 2|HD1910 舵机 BAM 台架实测辨识
对飞特 HD1910 做台架实测辨识,拟合 BAM(Bandwidth-Aware Motor)模型全套参数——带宽、粘性摩擦、库仑摩擦、转子惯量、齿隙,解决原版 replica 使用经验估算参数导致的 Sim2Real 迁移偏差。
对应第 8、10 章 · 交付物:
scripts/calibration/hd1910_bench_data_process.py
亮点 3|扩展域随机化 + 课程学习
在基础域随机化上扩展 8 维参数集(质量、摩擦、扭矩、带宽、齿隙、IMU 噪声、地面摩擦、重力),配合课程学习从站立逐步过渡到行走、转向、爬坡;并以消融实验对比不同随机策略的真机迁移成功率。
对应第 11、12 章 · 交付物:
domain_rand扩展参数集 + 课程调度逻辑
亮点 4|仿真观测空间 ↔ 板端固件自动校验
提供仿真观测空间 ↔ 板端 Rust 固件自动校验脚本,一键比对观测/动作的维度、缩放与顺序,杜绝 Sim2Real 最常见的维度/缩放不一致隐性 bug。
对应第 7、14 章 · 交付物:
scripts/validation/check_obs_act_space.py
亮点 5|完整实验管理体系(可复现)
建立标准化的实验管理体系:每一次训练保存 config.yaml、MJCF 快照、BAM 参数、训练日志与 TensorBoard 曲线,任一实验可一键复现、可回溯。
对应第 17 章 · 交付物:
experiments/目录规范(config / mjcf / bam_params / logs / readme)
亮点 6|Docker 锁定依赖版本
用 Docker 锁定 CUDA、Python、MuJoCo-Warp、mjlab 等依赖版本,消除「本地能跑、别人跑不起来」的环境问题,一键复现训练环境。
对应第 2、17 章 · 交付物:
Dockerfile+requirements-lock.txt
为什么写这本书
2025 年,Pollen Robotics 联合 Hugging Face 发布 MicroDuck,一台基于 Sim2Real 强化学习的开源双足机器鸭。它的核心范式是:在 GPU 仿真环境中训练机器人策略,再直接部署到真实硬件,不需要传统步态规划。
原版 MicroDuck 使用 Dynamixel 舵机,海外预售,中国大陆无法直邮,整机 399 美元,加上转运、关税成本高昂,普通爱好者与国内高校实验室很难获取。社区诞生了 microduck-replica 复刻项目,将 MicroDuck 的机械结构移植,使用国产飞特 HD1910 总线舵机。
但原始复刻项目存在明显短板:
- MJCF 动力学模型依靠手动估算连杆惯性、重心,仿真与真机动力学差异大,Sim2Real 迁移困难;
- HD1910 舵机 BAM 模型参数为经验估算,没有台架实测标定流程;
- 缺少标准化实验管理,训练配置、模型、日志零散,难以复现;
- 没有一键容器化环境,CUDA、Warp、mjlab 版本依赖极易冲突;
- 缺少完整工程踩坑记录,读者遇到仿真倒地、真机抖动、舵机丢包等问题时无系统排查方案。
本书的目标,就是补齐这套工程闭环:完整复刻 Pollen 原厂 Onshape→MJCF 自动化工作流,把 HD1910 舵机 BAM 实测辨识、域随机化、课程学习、RK3566 板端部署全部落地,形成一套国内可复现、低成本的国产舵机版 MicroDuck 全栈工程实践。
本书不是纯理论的强化学习教科书,也不是简单的零件组装手册。它是工程实践日志:包含成功的实验、失败的尝试、参数消融对比、仿真与真机之间的 Gap 诊断。
本书定位与读者
- 机器人、具身智能、强化学习方向研究生/本科生;
- 高校机器人实验室工程师、开源硬件爱好者;
- 想入门 Sim2Real、MuJoCo-Warp、低成本双足强化学习机器人开发者。
阅读路径推荐:
- 先跑【最小仿真Demo】,Docker 一键启动仿真,直观看到机器鸭仿真步态;
- 理解 Sim2Real 整体链路之后,再阅读机械 CAD、3D 打印、硬件装配章节;
- 进阶读者深入 BAM 模型、系统辨识、域随机化消融实验。
全书技术链路
STEP装配 → Onshape云端CAD(设置零件密度、舵机质量覆盖) → onshape-to-robot导出MJCF → MuJoCo-Warp GPU仿真 → BAM舵机模型(台架实测辨识HD1910参数) → 域随机化+课程学习PPO多任务训练 → ONNX策略导出 → RK3566 Rust固件50Hz实时推理 → 真机采集IMU/关节数据 → 系统辨识修正动力学模型 → 迭代重训
加入交流群
扫码入群 · 有效期至 2026-10-31
欢迎加入微信交流群,与社区一起交流复刻经验、反馈勘误、共建国产低成本双足机器人开源生态。
⚠️ 微信群二维码 7 天自动失效(本图有效期至 2026-10-31)。过期后请访问官网 https://www.wwntai.com/parts.html 获取最新二维码,或在 GitHub 仓库提 issue 更新。
开源许可边界(务必阅读)
- 本书书稿正文:CC-BY 4.0,自由阅读、分享,引用时保留署名;
- 上游软件代码:Apache 2.0;
- 机械 CAD 模型:CC BY-NC-SA,仅限非商用学习、科研。
若读者需要商用产品,必须独立正向设计机械结构,脱离本套 CAD 模型。
本书配套工程仓库:所有代码、脚本、实验记录、Docker 配置、书稿源码全部托管在 GitHub,每一个书稿章节绑定仓库 commit hash,你可以 checkout 到对应版本,保证代码与书中内容完全一致。
版权与免责声明
版权声明
本书(含正文、图表、代码片段与配套文档)的著作权归 广东省万物拟态机器人有限公司(WWNT Robotics,开源生态 GitHub UnitClaw)所有。
Copyright © WWNT Robotics (Guangdong WWNT Robotics Co., Ltd.) All rights reserved.
除另行注明外,本书正文按 CC-BY 4.0 许可开放阅读与引用(引用时须保留署名);上游代码遵循 Apache-2.0,机械 CAD 模型遵循 CC BY-NC-SA(仅限非商用学习与研究)。
责任免除声明(务必阅读)
本书是一份开源工程实践记录,部分技术资料(仿真参数、BAM 辨识结果、固件配置、装配公差等)来自特定硬件批次与实验环境,尚未全部经过真机充分验证。硬件装配、电路接线、上电调试本身存在短路、烧毁、机械损伤等固有风险;仿真模型与真机动力学之间存在固有 Gap,直接照搬可能无法稳定行走;舵机、主控、传感器等参数会随批次、固件版本、供电与负载条件变化。
因此,万物拟态机器人不对任何读者照搬本书内容而导致的实验失败、财产损失或人身伤害承担任何责任。请务必在安全环境下逐步验证——先仿真、后台架、再真机——并做好供电隔离与防护。您使用本书即表示已理解并接受上述风险与责任边界。
知识产权与侵权声明
- 本项目是基于 Pollen Robotics 开源 MicroDuck 的第三方独立复刻研究,与 Pollen Robotics 无隶属、授权、背书或赞助关系;「MicroDuck」及相关商标、品牌归其各自权利人所有。
- 本书与配套仓库仅为教学、科研与非商业开源学习目的,不构成对任何上游商业产品、商标或专利的授权使用。
- 若读者基于本书内容开展商用活动,须自行独立正向设计机械结构、脱离本套 CAD 模型,并自行完成对相关权利人知识产权、商标与专利的合规审查与必要授权。
- 因读者擅自商用、侵权使用或未取得必要授权而引发的任何纠纷与损失,万物拟态机器人不承担任何责任。
致谢
感谢 Pollen Robotics 开源 MicroDuck、mjlab 与 microduck_rl;感谢 fanhao375 开源 microduck-replica 与 microduck-replica-cad;感谢飞特提供 HD1910 舵机硬件与技术文档;感谢所有开源社区开发者。
完整的公司介绍与致谢(Pollen、飞特、fanhao375、机械行者Robo、kissqy、LuwuDynamics、Rhoban 等)见书末 【致谢】 章节。
本书持续迭代,工程实验会持续更新;勘误、改进建议欢迎提交 GitHub Issue。
绪论:Pollen MicroDuck 与开源具身智能
本章目标:理解 MicroDuck 是什么、Sim2Real 范式如何运作、为什么国内难以获取原版,以及社区复刻方案的选型逻辑。
1.1 一个会走路的开源机器鸭
2025 年,Pollen Robotics(Hugging Face 旗下的机器人团队)开源了一台名为 MicroDuck 的双足机器鸭。它体型小巧(约 0.7kg)、价格亲民,但核心价值不在硬件本身,而在它的运动方式——用强化学习训练出来的步态。
传统四足/双足机器人(如 Spot、Atlas)依赖复杂的运动学规划:先建立精确的动力学模型,再逐帧解算关节力矩。MicroDuck 走的完全是另一条路:
- 在 GPU 仿真环境(MuJoCo-Warp)中,让一只"数字鸭子"随机摔倒、随机行走;
- 用 PPO 强化学习算法,通过奖励函数引导它学会站立、行走、摔倒自恢复;
- 把训练好的策略导出为 ONNX 模型,直接部署到实体鸭子的大脑(RK3566 板卡)上;
- 实体鸭子以 50Hz 的频率读取 IMU 和关节角度,推理 ONNX 得到舵机目标位置,完成闭环控制。
这就是 Sim2Real(仿真到现实) 范式的完整闭环。它不需要工程师手写步态,只需要设计好奖励函数和仿真环境。
1.2 为什么"先仿真,后现实"是范式革命
| 维度 | 传统步态规划 | Sim2Real 强化学习 |
|---|---|---|
| 建模成本 | 需要精确动力学模型,误差敏感 | 用域随机化容忍模型误差 |
| 步态来源 | 工程师手工设计 | 算法自动发现 |
| 抗扰动 | 依赖精确反馈,脆弱 | 训练中见过各种扰动,鲁棒 |
| 复杂地形 | 难以手工规划 | 奖励函数引导即可 |
Sim2Real 的核心不是"仿真",而是**"仿真与现实之间的鸿沟(gap)怎么填"**——这正是本书从第 4 章到第 15 章反复处理的核心问题。
1.3 为什么国内难买到原版
MicroDuck 原版采用 Dynamixel XL330 舵机,官方预购价 399 美元。更关键的限制是供应链:
- 官方直邮地区:美、加、欧盟、英国、挪威、瑞士、日本、韩国;
- 中国大陆不在直邮列表,需转运或代订;
- 399 美元 + 国际运费 + 关税 + 清关,实际到手成本显著高于标价;
- 新订单预估等待 4~6 个月。
这些现实约束,让国内爱好者和高校实验室很难低成本获取一台原版机器鸭。国产复刻因此成为一个有真实价值的工程命题。
1.4 国产复刻的舵机选型:为什么是飞特 HD1910
原版的核心执行器是 Dynamixel XL330,属于串行总线舵机。国产替代主要有两类选择:
| 舵机 | 类型 | 扭矩@4.8V | 重量 | 通信 | 价格区间 |
|---|---|---|---|---|---|
| Dynamixel XL330 | 磁编码总线舵机 | ~6.5 kg·cm | 约 16g | TTL | 高 |
| 飞特 HD1910 | 磁编码 TTL 总线舵机 | 9 kg·cm | 21±2g | TTL | 低 |
飞特 HD1910 的核心指标:
- 型号:HD-1910-C001,双轴磁编码 TTL 总线舵机,空心杯电机,金属齿轮;
- 工作电压:4.8~8.4V;
- 堵转扭矩:9 kg·cm @ 4.8V;
- 空载转速:0.137 sec/60°(约 73RPM)@ 4.8V;
- 重量:21±2g;
- 通信:TTL 总线,波特率最高 1Mbps,360° 磁编码,多圈位置读取。
⚠️ 选型警示:国产舵机的扭矩、摩擦、带宽、齿隙参数与原版差异巨大。原版预训练的步态模型不能直接移植,必须重新标定舵机模型并重新训练(详见第 10 章)。
1.5 社区复刻项目全景
| 仓库 | 性质 | 舵机 | 配套 |
|---|---|---|---|
pollen-robotics/microduck_rl | 原版 RL 内核 | XL330 | 仅训练代码 |
UnitClaw/microduck-wwduck | WWNTRobotics 优化版 | HD1910 | 训练+CAD+固件+镜像+工程优化 |
fanhao375/microduck-replica | 完整复刻工程 | XL330 + HD1910 | 训练+CAD+固件+镜像 |
fanhao375/microduck-replica-cad | 机械图纸 | XL330 + HD1910 | SolidWorks/STL |
LuwuDynamics/xgoduck_hardware | 飞特合作机器鸭 | HD1910 | 独立机器人 |
边界说明:晨芯时代科技是国内硬件方案商,基于原版做国产化硬件适配,但没有独立的 Microduck GitHub 仓库,只交付适配 RK 平台的镜像与 BSP。飞特官方也未发布同名 Microduck 仓库。
1.6 本书目标
本书将完成一件社区尚未做完整的事:用国产飞特 HD1910 舵机,从零搭建一套可复现的 MicroDuck 全栈工程闭环,并重点补齐原版复刻项目的五个短板:
- 动力学建模:用 Onshape→MJCF 自动化流水线替代手动估算惯性参数(第 4 章);
- 舵机建模:台架实测辨识 HD1910 的 BAM 执行器参数(第 10 章);
- 训练鲁棒性:扩展域随机化 + 课程学习缩小 Sim2Real gap(第 11 章);
- 工程化:Docker 环境、自动化校验、实验管理(第 9 章);
- 真机闭环:真机步态迭代与系统辨识(第 15 章)。
本章小结:你已理解 MicroDuck 的价值与国产复刻的必要性。下一章先用 Docker 一键跑通仿真,建立对整条链路的第一手直觉。
最小仿真示例
本章目标:无需 3D 打印、无需硬件、无需焊接,在 GPU 电脑上一键跑通飞特 HD1910 版 MicroDuck 仿真环境,理解 Sim2Real 完整链路全貌。 前置:Docker + NVIDIA GPU 驱动(CUDA 支持);仓库已切换至
book-dev分支。
2.1 为什么把 Demo 放在最前面
传统机器人教程习惯从机械图纸、硬件装配开始,读者投入大量时间打印零件,最后才发现仿真根本跑不起来。 本书采用问题驱动、由虚到实的学习路径:
- 先在仿真世界验证机器人动力学、舵机模型、强化学习策略;
- 确认仿真环境行为符合预期后,再进入机械设计、3D 打印、硬件装配;
- 仿真里发现的动力学缺陷(惯性、重心、舵机参数),提前修正,避免真机返工。
本章最小 Demo 只做三件事:
- 加载飞特 HD1910 版本 MJCF 机器人模型;
- 校验模型合法性(惯性、关节限位);
- 加载预训练站立策略,启动 MuJoCo-Warp 仿真,可视化机器鸭站立。
本章不训练新策略,只复现一个已经收敛的站立策略,快速验证整套软件栈是否正常工作。
2.2 环境准备(Docker 一键容器)
仓库内置 Dockerfile,锁定 CUDA、Python、MuJoCo-Warp、mjlab 版本,消除版本依赖冲突。
# 拉取代码,切换本书开发分支
git clone https://github.com/你的用户名/microduck-replica.git
cd microduck-replica
git checkout book-dev
# 构建并启动 GPU 仿真容器
cd docker
docker-compose up --build
容器会自动挂载本地仓库目录,代码修改在宿主机直接生效,不需要重新打包镜像。
新开终端,进入容器环境:
docker exec -it microduck-replica-sim bash
2.3 模型校验(必须执行)
Sim2Real 工程中,MJCF 模型错误是最高发故障。仓库内置自动化校验脚本,检查惯性张量、总质量、关节限位。
python scripts/validation/validate_mjcf.py \
--mjcf software/training/assets/robots/microduck_feetech.xml
✅ 正常输出示例:
✅ MJCF加载成功,连杆数量: 16
✅ 整机总质量: 0.726 kg
✅ MJCF基础校验完成
❌ 报错场景:惯性张量非正定、关节限位超出舵机物理范围,需要回到 CAD/Onshape 环节修正。
2.4 运行最小 Demo:加载预训练站立策略
python software/training/train_ppo.py \
config=experiments/exp01_standup/config.yaml \
resume=experiments/exp01_standup/checkpoints/latest.onnx
执行后,MuJoCo-Warp 启动 GPU 并行仿真,弹出可视化窗口,机器鸭保持站立。
2.4.1 实验配置说明(exp01_standup/config.yaml)
robot_xml: "software/training/assets/robots/microduck_feetech.xml"
bam_params: "experiments/exp01_standup/bam_params.json"
num_envs: 256
control_freq: 50
policy_type: "ppo"
task: "stand"
domain_randomization: false
control_freq: 50:和 RK3566 板端 50Hz 控制频率严格对齐,是 Sim2Real 迁移的关键;domain_randomization: false:最小 Demo 关闭域随机化,保证行为稳定;后续章节开启域随机化做消融实验。
2.5 观察现象与基础诊断
观察仿真行为:
- 机器鸭稳定站立,无缓慢倾倒;
- 关节角度在 HD1910 物理限位内;
- 仿真无大量数值爆炸警告。
常见故障排查(本章踩坑实录)
- 启动立刻倒地:大概率 MJCF 重心/惯性参数错误;回到第 4 章 CAD→MJCF 流程复核;
- 关节剧烈抖动:BAM 舵机参数不匹配,需要第 8 章台架标定;
- CUDA out of memory:减小
num_envs。
2.6 本章小结
你已经验证了整套仿真软件栈:MJCF 模型、BAM 舵机模型、MuJoCo-Warp、PPO 策略加载。
仿真只是数字世界,仿真的动力学参数是否贴近真实机器人,决定后续真机迁移成败。 下一章进入机械 CAD,第 4 章:Onshape 自动化导出 MJCF,从源头计算连杆惯性、重心,告别手动估算。
实验记录:本次实验归档于
experiments/exp01_standup/,可在 TensorBoard 查看观测、奖励曲线。
HD1910 CAD 模型解析
本章目标:读懂
microduck-replica-cad仓库的机械结构,理解两套舵机版本的零件差异,并学会导出整机 STEP 装配,为第 4 章的 Onshape 自动化 MJCF 导出做准备。
3.1 仓库结构总览
机械 CAD 图纸独立存放于 fanhao375/microduck-replica-cad:
microduck-replica-cad/
├── feetech/ # 飞特 HD1910 版本装配 + 全部零件
│ ├── microduck_feetech.SLDASM # 整机装配体
│ └── ... *.sldprt # 单个零件
├── xl330/ # 原版 Dynamixel XL330 版本
│ ├── microduck_xl330.SLDASM
│ └── ... *.sldprt
└── stl/ # 可直接打印的 STL 文件
关键区分:两套舵机版本的零件不能通用。飞特 HD1910 与原版 Dynamixel 的外形、安装凸台方向、出轴位置均不同,打印时必须按对应版本取件,避免装配时发现装不上。
3.2 机器鸭的机械拓扑
MicroDuck 是双足机器人,单侧腿部大致包含:
| 关节 | 说明 | 数量(单侧) |
|---|---|---|
| 髋部 | 允许腿部前后摆动与左右开合(pitch/roll/yaw 组合) | 3 |
| 膝部 | 允许小腿屈伸(pitch) | 1 |
| 踝部 | 允许脚掌俯仰与侧倾(pitch/roll) | 2 |
整机共 14~15 颗舵机(部分复刻版在尾部/头部增加自由度),具体数量与限位以你的 CAD 装配树为准。
3.3 运动学树梳理(为 MJCF 做准备)
第 4 章导出 MJCF 时,需要告诉 Onshape/onshape-to-robot 哪些零件是连杆、哪些关节是可动关节。这一步必须提前理清。推荐的运动学树(以 14 自由度为例):
base(躯干/底座)
├── thigh_right (髋 pitch) ── knee_right(膝) ── ankle_right(踝)
└── thigh_left (髋 pitch) ── knee_left (膝) ── ankle_left (踝)
髋部的 roll/yaw 通常放在躯干与大腿之间;若你的装配把 roll/yaw 放在髋 pitch 之后,导出 MJCF 时关节层级必须与实际一一对应,否则仿真直接报错。
3.4 导出整机 STEP 装配
microduck-replica-cad 仓库默认上传的是 SolidWorks 源文件(.sldasm/.sldprt),不会直接给出打包好的 STEP,需要你手动导出:
- 用 SolidWorks 打开
feetech/microduck_feetech.SLDASM; - 菜单「文件 → 另存为」;
- 文件类型选择 STEP AP214(推荐,兼容性最好);
- 保存得到
microduck_feetech.step。
没有 SolidWorks?可用免费开源 FreeCAD 打开
.sldasm再导出 STEP,但 FreeCAD 对 SolidWorks 装配约束兼容性一般,部分装配约束可能丢失,导出前需检查装配完整性。
3.5 导出 STEP 前的三项检查
- 装配层级不塌缩:确认零件不是全部平铺在根节点,否则导出的 MJCF 关节层级会错乱;
- 无过定义/欠定义:装配约束完整,否则 STEP 导入 Onshape 后关节位置漂移;
- 舵机安装方向正确:飞特 HD1910 的安装凸台方向必须与大腿/小腿零件匹配,这是两套版本最常出错的点。
3.6 工程踩坑实录
- 脚踝关节卡死:这是复刻版经典问题。3D 打印后舵盘与相邻结构干涉,导致转动受限甚至卡死。需要在 CAD 里检查舵盘与外壳的间隙,必要时在 STEP 源文件里修正装配干涉、加宽间隙。
- 零件壁厚过薄:部分结构件壁厚不足,打印后受力易断裂。建议加厚受力部位,或提高填充率。
- 打印错件:同时下载了 feetech 与 xl330 两套 STL,打印时取错版本,导致装配不上。建议分目录、按版本标记打印。
3.7 本章小结
你现在应该能:
- 找到
microduck-replica-cad中飞特版本的正确零件; - 理解 MicroDuck 的运动学树(为 MJCF 关节定义做准备);
- 从 SolidWorks 导出整机 STEP AP214。
下一章,把这份 STEP 导入 Onshape,用
onshape-to-robot自动生成带精确惯性参数的 MJCF 模型,告别手动估算。
Onshape→MJCF 自动化建模
本章是本书核心创新章节:替代原始 replica 手动填写惯性参数的方式,复刻 Pollen 原厂 CAD→MJCF 全自动化流水线,自动计算连杆质量、重心、惯性张量。 配套脚本:
scripts/cad2mjcf/export_mjcf.py+onshape_config.json。
4.1 痛点:为什么不能手动估算惯性
原始 microduck-replica 的 MJCF 模型,连杆质量、惯性、重心依靠人工估算。 仿真中步态完美,但部署真机直接倾倒,核心根源就是动力学模型和真实机器人不一致(Sim2Real gap)。
Pollen 原版 MicroDuck 的解决方案: SolidWorks 装配 → 导入 Onshape,设置零件密度 → onshape-to-robot 自动导出 MJCF,几何自动计算惯性张量。 本书完整复刻这套流水线,适配国产 HD1910 舵机。
4.1.1 工作流总链路
STEP整机装配文件 → Onshape导入 → 零件密度赋值 → 舵机质量覆盖配置 → onshape-to-robot导出STL网格 + MJCF模型 → 自动MJCF校验 → 替换仿真机器人xml
4.2 Onshape 前置准备
- 将整机 STEP 装配导入 Onshape 文档;
- 给每一个 3D 打印零件设置 PLA 等效密度:
1240 kg/m³; - HD1910 舵机零件不使用几何计算质量,在配置文件强制覆盖质量 21g;
舵机内部空心杯、磁编码、齿轮结构复杂,几何计算质量不准,必须使用厂商标称重量覆盖。
- 在 Onshape 装配中,定义关节(旋转副 revolute),记录关节 ID、旋转方向、物理限位。
4.2.1 PLA 等效密度参考
| 填充率 | 等效密度 (g/cm³) |
|---|---|
| 20% | 0.35~0.45 |
| 40% | 0.6~0.7 |
| 实体 PLA | ~1.24 |
4.2.2 Onshape API 密钥准备
需要申请 Onshape API 密钥,用于脚本远程读取装配几何:
- Onshape 个人账号 → 开发者控制台 → 创建 API Key;
- 导出两个环境变量:
export ONSHAPE_ACCESS_KEY="你的access_key"
export ONSHAPE_SECRET_KEY="你的secret_key"
密钥不要提交到 Git 仓库,加入
.gitignore。
4.3 配置文件讲解:onshape_config.json
路径:scripts/cad2mjcf/onshape_config.json
{
"url": "https://cad.onshape.com/documents/【文档ID】/w/【工作区ID】/e/【装配ID】",
"output_format": "mjcf",
"output_dir": "./output",
"mesh_type": "stl",
"units": "meters",
"joints": {
"thigh_right": {"type":"revolute","limits":[-1.57,1.57]},
"thigh_left": {"type":"revolute","limits":[-1.57,1.57]},
"knee_right": {"type":"revolute","limits":[-1.57,1.57]},
"knee_left": {"type":"revolute","limits":[-1.57,1.57]},
"hip_pitch_right": {"type":"revolute","limits":[-1.57,1.57]},
"hip_pitch_left": {"type":"revolute","limits":[-1.57,1.57]},
"hip_roll_right": {"type":"revolute","limits":[-1.0,1.0]},
"hip_roll_left": {"type":"revolute","limits":[-1.0,1.0]},
"hip_yaw_right": {"type":"revolute","limits":[-1.0,1.0]},
"hip_yaw_left": {"type":"revolute","limits":[-1.0,1.0]},
"ankle_pitch_right": {"type":"revolute","limits":[-1.57,1.57]},
"ankle_pitch_left": {"type":"revolute","limits":[-1.57,1.57]},
"ankle_roll_right": {"type":"revolute","limits":[-0.8,0.8]},
"ankle_roll_left": {"type":"revolute","limits":[-0.8,0.8]}
},
"override_mass": {
"hd1910_servo": 0.021
}
}
units: meters:MuJoCo 强制使用米、千克、秒国际单位;limits单位为弧度,严格匹配 HD1910 机械硬限位,防止仿真中关节超程;override_mass:强制覆盖舵机质量,优先于几何计算。
4.4 一键导出 MJCF 脚本 export_mjcf.py
路径:scripts/cad2mjcf/export_mjcf.py
脚本逻辑:
- 读取 JSON 配置;
- 调用
onshape-to-robot库远程访问 Onshape,导出 STL 网格与 MJCF; - 导出完成自动调用 MJCF 校验脚本;
- 校验通过后提示,将
robot.xml复制到仿真 assets 目录。
4.4.1 执行命令
python scripts/cad2mjcf/export_mjcf.py --config scripts/cad2mjcf/onshape_config.json
正常输出:
=== 启动 onshape-to-robot 导出MJCF ===
✅ 导出完成,开始校验MJCF模型
✅ MJCF加载成功,连杆数量: 16
✅ 整机总质量: 0.726 kg
✅ MJCF基础校验完成
✅ 全部完成!MJCF路径:scripts/cad2mjcf/output/robot.xml
提示:可将此robot.xml复制到 software/training/assets/robots/microduck_feetech.xml
4.5 校验脚本做了什么(validate_mjcf.py)
- 加载 MJCF 模型,读取连杆数量;
- 计算整机总质量;
- 遍历每一个连杆,检查惯性张量正定(ixx, iyy, izz 必须 > 0);
惯性张量非正定,MuJoCo 会出现数值不稳定、仿真爆炸。
4.6 闭环迭代流程(本书新增,原版 replica 没有)
CAD 导出 MJCF 只是第一步,完整闭环:
- Onshape 导出初始 MJCF;
- 仿真跑站立 Demo,观察重心稳定性;
- 3D 打印零件,单独称重,记录在
data/cad_weigh_records/; - 对比 CAD 自动计算质量 vs 真实称重;
- 在 Onshape 微调零件密度,重新导出 MJCF;
- 迭代直到 CAD 计算质量和实测质量误差 < 5%。
4.7 工程踩坑实录
- 单位错误:Onshape 使用毫米,导出未转米,模型尺寸放大 1000 倍,仿真直接崩溃;
- 关节限位写反,仿真关节向物理禁止方向转动;
- 舵机没有 override_mass,几何计算质量偏小,仿真重心上移;
- STL 网格破面,MuJoCo 碰撞检测报错。
4.8 本章小结
本章完成动力学建模自动化,不再依靠经验估算惯性。
但机器人仿真除了刚体动力学,还需要舵机模型。下一章进入 BAM 舵机模型,使用 HD1910 台架实测数据拟合参数。
3D 打印、装配与公差
本章目标:把 CAD 图纸变成一台能动的机器鸭。包含完整 BOM 清单、打印参数、装配顺序与公差控制,以及装配后的称重流程(供第 4 章 MJCF 标定使用)。
5.1 完整 BOM 清单
| 类别 | 部件 | 规格/数量 | 备注 |
|---|---|---|---|
| 执行器 | 飞特 HD1910 | 14~15 颗 | 双轴磁编码 TTL 总线舵机 |
| 主控 | RK3566 板卡 | 1 块 | 跑 ONNX 推理 + Rust 固件 |
| 传感器 | IMU(MPU6050/ICM20948) | 1 块 | 姿态解算 |
| 供电 | 锂电池 | 1 块 | 2S 或 3S,需配 BMS |
| 电源管理 | BMS 保护板 | 1 块 | 低压保护、过流保护 |
| 结构 | 3D 打印件 | 1 套 | PLA 打印,见 5.2 |
| 紧固件 | M2/M3 螺丝 | 若干 | 舵盘、结构固定 |
| 线材 | 舵机 TTL 总线线 | 若干 | 串接 15 颗舵机 |
| 杂项 | 垫片、轴承 | 若干 | 减少摩擦、定位 |
采购建议:舵机、板卡、IMU 为关键件,优先选正规渠道;紧固件与线材可本地采购。BOM 采购清单提供推荐采购渠道与备选替代件。
5.2 3D 打印参数
| 参数 | 建议值 | 说明 |
|---|---|---|
| 材料 | PLA | 易打印、成本低 |
| 层厚 | 0.2mm | 平衡速度与精度 |
| 填充率 | 20%~40% | 受力件用 40%,轻量件用 20% |
| 支撑 | 按需 | 悬空结构需加支撑 |
| 打印方向 | 轴向受力件竖直 | 提高强度 |
⚠️ 打印填充率直接改变整机动力学!20% 与 40% 填充的等效密度不同,会在第 4 章 MJCF 标定时引入误差。务必记录每批打印的填充率,并在 MJCF 标定时使用对应的等效密度。
5.3 分步装配顺序
- 先单腿测试:先打印并装配一条腿(髋、膝、踝),验证舵机装配、转动范围、舵盘固定;
- 躯干装配:把 IMU、主控板固定在躯干,走线;
- 双腿合拢:两条腿装配到躯干底座,确认左右对称;
- 总线串联:按舵机 ID 顺序串接 TTL 总线,避免 ID 冲突;
- 整机通电测试:先不加载步态,测试每个舵机能否独立转动、回读位置。
强烈建议:不要一次性打印全套零件。先打印单腿验证设计,再打整机,避免设计缺陷导致整批报废。
5.4 公差控制要点
| 部位 | 公差要求 | 处理方式 |
|---|---|---|
| 舵盘与输出轴 | 过盈配合 | 打印时留出装配余量 |
| 轴承座孔 | 配合精度 | 必要时扩孔或加垫片 |
| 舵机安装孔 | 对准 | 检查两套舵机版本孔位差异 |
3D 打印本身有 ±0.1~0.3mm 的收缩误差,复杂装配建议预留装配间隙,或用垫片/轴承补偿。
5.5 装配后整机称重(供仿真标定)
Sim2Real 成败关键之一:仿真模型质量必须与真机一致。装配完成后执行:
- 整机称重:记录整机总质量;
- 拆分称重:把每条大腿、小腿、躯干拆开,用精度 0.01g 的电子秤单独称重;
- 记录到
data/cad_weigh_records/:
part,target_cad_mass_kg,measured_mass_kg,fill_ratio
thigh_right,0.042,0.038,20%
knee_right,0.020,0.019,40%
...
- 与第 4 章 Onshape 自动计算的 CAD 质量对比,若误差 >5%,回到 Onshape 微调零件密度,重新导出 MJCF。
5.6 常见装配问题与排查
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 舵盘打滑 | 舵盘与输出轴过盈不足 | 换更紧舵盘或加胶固定 |
| 线束干涉 | 走线未沿结构走 | 重排线束,用扎带固定 |
| 重心偏移 | 装配不对称 | 检查左右零件是否一致 |
| 关节卡死 | 打印干涉/间隙不足 | 见 3.6 修正 CAD |
5.7 本章小结
完成本章,你应有一台机械装配正确、总线串联完成、可以独立转动每个舵机的机器鸭实体,并且拿到了整机与各连杆的实测质量数据。
下一章进入硬件电路与 TTL 总线系统,解决舵机通信与供电的底层问题。
硬件电路与 TTL 总线
本章目标:搭建 MicroDuck 的电气系统——供电、舵机总线通信、IMU 接入,并掌握最常见的故障排查(舵机丢包、通信超时、过流保护)。
6.1 系统电气架构
锂电池 → BMS → 电源分配
├─ RK3566 主控(5V/3.3V 逻辑)
├─ IMU(I2C/SPI)
└─ 舵机总线(TTL,串接 15 颗 HD1910)
关键:舵机供电与主控逻辑供电要分离。15 颗舵机同时运动时电流很大,若与主控共地但共电源,会造成主控电压跌落、复位。
6.2 电源方案与 BMS
- 电池:2S(7.4V)或 3S(11.1V)锂电;舵机标称 4.8~8.4V,2S 更稳妥;
- BMS:必须带低压保护和过流保护。低电压时舵机扭矩骤降、位置回读漂移,策略会不稳定;过流会烧舵机驱动;
- 建议加一个电源软启动(浪涌限制),避免上电瞬间电容充电电流冲击总线。
6.3 飞特 HD1910 TTL 总线拓扑
15 颗舵机通过 TTL 总线串联(菊花链),每颗舵机有唯一 ID:
主控 UART(TTL) ── HD1910 ID=1 ── ID=2 ── ... ── ID=15
- 波特率:最高 1Mbps,推荐从低速(如 500kbps)开始调试;
- 半双工 TTL:收发共线,需主控端支持方向控制;
- 每颗舵机需先配置 ID 与波特率,ID 冲突会导致整条总线通信错乱。
6.4 IMU 接入与安装
- 型号:MPU6050 / ICM20948;
- 接口:I2C 或 SPI;I2C 速度有限,建议用 SPI 提高采样率;
- 安装位置:尽量靠近整机质心,固定在躯干刚性部位;
- 安装倾角:IMU 的安装姿态会进入姿态解算初值。若安装有倾角,必须在固件里补偿,否则姿态角直接漂移,Sim2Real 失效。
6.5 总线故障排查
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 某颗舵机无响应 | ID 冲突 / 地址错误 | 重新配置 ID |
| 随机丢包 | 总线过长、信号干扰 | 降低波特率、加总线隔离 |
| 上电后总线卡死 | 供电不足 / 某舵机短路 | 逐颗上电排查 |
| 位置回读漂移 | 供电电压跌落 | 检查 BMS 与线径 |
⚠️ 长线干扰:15 颗舵机串接,线缆较长时 TTL 信号易受 EMI 干扰。建议使用屏蔽线,或加总线隔离芯片。这是从仿真到真机最容易忽视的坑。
6.6 供电与信号分离的接线规范
- 舵机电源线(粗线)直接来自 BMS,不经过主控;
- 主控与舵机仅通过信号共地,逻辑电平由主控驱动;
- 舵机总线端串联一个限流电阻/熔断器,保护主控 UART。
6.7 工程踩坑实录
- 共电源导致主控复位:多颗舵机急停时电流尖峰拉低主控电压,系统重启。改分离供电后解决。
- ID 冲突整条总线瘫痪:两颗舵机被配成同一 ID,所有指令乱套。逐颗单独上电重配 ID 恢复。
6.8 本章小结
你应能搭建一套分离供电、总线正确、IMU 已接入的电气系统,并掌握舵机丢包与供电故障的排查方法。
下一章把系统跑起来:烧录 RK3566 镜像、部署 Rust 固件、理解 50Hz 控制环。
RK3566 镜像与固件
本章目标:把预编译的 RK3566 系统镜像烧录到板卡,理解板端 Rust 固件的进程架构,并掌握 50Hz 实时控制环的实现与验证。
7.1 系统镜像烧录
仓库 software/image/ 提供预编译 RK3566 镜像。烧录流程:
- 准备:RK3566 板卡、SD 卡(≥8GB)、读卡器、镜像文件;
- 烧录:用
balenaEtcher或dd写入 SD 卡:
# Linux 环境(假设 SD 卡为 /dev/sdX,务必确认设备号)
sudo dd if=software/image/microduck_rk3566.img of=/dev/sdX bs=4M status=progress
sync
- 配置:首次启动后配置 Wi-Fi、SSH、时区;
- 验证:确认系统启动、
robotd服务运行。
7.2 板端软件架构
RK3566 上运行的是 Rust 编写的多守护进程系统,典型结构:
├── robotd # 主控制守护进程(50Hz 控制环)
├── configd # 配置服务(舵机ID、波特率、IMU校准)
├── busd # 舵机总线管理(TTL通信)
└── webui # 调试用 WebUI(可视化 IMU/关节/策略输出)
进程间通过 Unix socket + JSON-RPC 通信,职责分离,便于独立调试与故障隔离。
7.3 50Hz 实时控制环(核心)
控制环是 Sim2Real 在真机上落地的关键。伪代码:
#![allow(unused)] fn main() { loop { let t0 = Instant::now(); // 1. 读取 IMU 姿态 let imu = imu_read(); // 四元数/欧拉角 // 2. 读取舵机当前位置(回读磁编码) let q = servo_read_positions(); // 3. 打包观测向量(必须与仿真观测空间严格一致) let obs = build_observation(imu, q); // 4. ONNX 推理,得到目标关节位置 let action = onnx_infer(&obs); // 输出 14 维动作 // 5. 下发舵机目标位置 servo_write_targets(action); // 6. 保持 50Hz(20ms)周期 let dt = t0.elapsed(); if dt < Duration::from_millis(20) { sleep(20ms - dt); } } }
⚠️ 观测空间一致性是 Sim2Real 最高发的 bug。仿真里观测向量是 61 维(含 IMU、关节位置、速度等),板端固件打包的观测必须维度相同、缩放相同。本书提供
check_obs_act_space.py自动校验脚本(见 7.5)。
7.4 ONNX 推理优化
RK3566 算力有限,1GB 内存,跑 ONNX 步态需注意:
- 用 RKNN/ONNX Runtime 做板端推理;
- 单次推理控制在几毫秒内,留足控制环余量;
- 若无法同时跑高分辨率视觉 + RL 策略,视觉任务需降级或分时处理。
7.5 观测/动作空间自动校验脚本
scripts/validation/check_obs_act_space.py:读取仿真配置与板端固件的观测定义,自动比对维度与缩放因子。
python scripts/validation/check_obs_act_space.py \
--sim-cfg experiments/exp02_walk_flat/config.yaml \
--firmware-src software/firmware/src/obs.rs
输出:若维度或缩放不一致,直接报错,杜绝"仿真能走、真机乱走"的隐性 bug。
7.6 WebUI 调试
板端 WebUI 提供实时可视化:
- IMU 姿态曲线;
- 各关节角度回读;
- 策略输出(动作值);
- 控制环延迟统计。
真机调试时,通过 WebUI 观察控制环是否超时、关节是否抖动、姿态是否漂移。
7.7 工程踩坑实录
- 控制环超时:推理 + 总线通信耗时超过 20ms,控制环掉帧,步态抖动。优化方向:降低推理耗时、用 DMA 批量收发舵机指令。
- 总线丢包:舵机通信超时,回读位置缺失,观测向量填了脏数据。需要在
busd里做超时重传与数据有效性标记。
7.8 本章小结
你应能把 RK3566 跑起来,理解 50Hz 控制环的每个环节,并掌握观测空间一致性与总线超时的排查。
下一章做真机标定:舵机零位、IMU 六面校准、台架采集 HD1910 的动力学数据。
舵机与 IMU 标定
本章目标:做三件真机侧的标定工作——舵机零位校准、IMU 六面校准、以及 HD1910 台架数据采集(为第 10 章的 BAM 参数拟合提供实测数据)。
8.1 舵机零位校准
舵机出厂的中位未必与机械零位一致。零位校准流程:
- 给舵机发送 0 位置指令;
- 手动检查舵盘是否指向机械设计零位;
- 若不齐,记录偏移量,写入
configd的偏移表; - 每个关节独立校准,保存偏移到板端配置。
# 示例:通过配置服务校准单个舵机
configd set-servo-offset --id 1 --offset +12
零位不准会直接导致策略动作落在错误位置,表现为"鸭子歪着站"。这是 Sim2Real 之前必须先解决的硬件前提。
8.2 关节限位标定
每个关节的物理转动范围必须写入仿真(MJCF 的 limits)和板端(舵机目标限制):
- 手动缓慢驱动每个关节,记录机械硬限位角度;
- 与第 4 章 MJCF 的
limits对比; - 若仿真范围大于硬件,训练出的策略可能在真机上到达"不可能的角度",造成机械卡死或舵机堵转。
8.3 IMU 六面校准
IMU 零偏漂移是步态不稳定的另一大来源。六面校准法:
- 让 IMU 依次朝上、朝下、朝前、朝后、朝左、朝右六个方向静置;
- 采集每面加速度计/陀螺仪读数,求零偏;
- 写入 IMU 校准参数,消除静态漂移。
# 示例:进入校准模式,依次放置六面
robotd imu-calibrate --faces 6
8.4 HD1910 台架数据采集(核心,供 BAM 拟合)
第 10 章要用实测数据拟合 BAM 模型,需要先做台架实验。把 HD1910 固定到台架,进行四类测试:
8.4.1 阶跃响应测试(拟合带宽)
给舵机输入阶跃位置指令,记录目标位置、实际磁编码位置、时间序列。
t,target_pos,actual_pos,torque,voltage
0.000,0.0,0.001,0.00,7.4
0.002,0.5,0.003,0.01,7.4
0.004,0.5,0.012,0.02,7.4
...
8.4.2 扭矩-转速测试
不同负载/电压下,记录最大持续扭矩与空载转速,用于拟合最大扭矩参数。
8.4.3 摩擦与齿隙测试
- 正反方向慢速转动,测量粘性摩擦与库仑摩擦;
- 来回摆动,测量死区/滞后(齿隙)。
8.4.4 转子惯量
结合阶跃响应与已知负载,反向辨识转子惯量。
8.5 台架数据 → BAM 参数拟合脚本
仓库提供 scripts/calibration/hd1910_bench_data_process.py:
python scripts/calibration/hd1910_bench_data_process.py \
--csv data/hd1910_bench/hd1910_step_response.csv \
--out experiments/exp01_standup/bam_params.json
输出 bam_params.json:
{
"bandwidth_hz": 22.0,
"b_viscous": 0.0018,
"tau_coulomb": 0.009,
"J_rotor": 1.2e-6,
"servo_model": "HD1910",
"voltage": 7.4,
"unit": "SI(kg,m,s,rad)"
}
拟合算法:对简化一阶带宽模型做最小二乘拟合(scipy.optimize.minimize),见第 10 章代码详解。
8.6 消融对比设计(写入书稿实验)
为量化标定的价值,设计对照:
- 方案 A:使用经验估算的 BAM 参数训练;
- 方案 B:使用台架实测拟合的 BAM 参数训练;
- 对比两者在真机上的迁移成功率(站立稳定时长、行走成功率)。
8.7 工程踩坑实录
- IMU 未六面校准:姿态缓慢漂移,鸭子越站越歪。校准后恢复。
- 台架数据采样率不足:阶跃响应太快,采样跟不上,带宽拟合失真。提高采样率(>500Hz)后重采。
8.8 本章小结
完成本章,你已有:
- 校准好的舵机零位与关节限位;
- 校准好的 IMU;
- 一份可用于 BAM 拟合的 HD1910 台架实测数据。
下一章进入仿真世界:搭建 MuJoCo-Warp + mjlab 环境,为训练做准备。
MuJoCo-Warp 仿真环境
本章目标:理解 GPU 并行仿真原理,解决最让人头疼的环境部署问题,并掌握观测/动作空间的定义。
9.1 MuJoCo-Warp 与 mjlab 是什么
- MuJoCo-Warp(NVIDIA):MuJoCo 物理引擎的 GPU 并行版本,可同时跑数百个仿真实例,大幅加速强化学习;
- mjlab(Pollen 自研):在 MuJoCo-Warp 之上封装的机器人仿真库,提供环境 API、执行器模型(BAM)、域随机化支持。
两者组合构成了 MicroDuck 的训练底座。
9.2 环境部署痛点与 Docker 方案
原版环境依赖链复杂,mjlab、mujoco-warp、BAM 库版本绑定严格,常见问题:
- CUDA 版本不匹配;
- Python 包版本冲突;
- Windows 原生不支持,只能 WSL2 / Linux + NVIDIA CUDA GPU;
- CPU 无法训练。
仓库提供 Docker 一键方案解决这些问题:
cd docker
docker-compose up --build
配套 requirements-lock.txt 锁定所有依赖版本,保证"换个环境也能跑"。
9.3 环境自动校验脚本
每次修改代码后,先跑仿真环境自检,避免把错误带入训练:
python scripts/validation/test_env.py
import torch
from mjlab import env
def test_sim_env():
env = env.MicroDuckEnv(robot="feetech")
obs, info = env.reset()
for i in range(200):
action = torch.zeros((1,14))
obs, reward, done, trunc, info = env.step(action)
print("✅ Simulation environment test passed")
if __name__ == "__main__":
test_sim_env()
9.4 观测空间与动作空间
MicroDuck 的标准接口:
- 动作空间:14 维关节动作(舵机目标位置),范围通常归一化到 [-1,1];
- 观测空间:61 维,含 IMU 姿态(四元数/欧拉角)、关节位置、关节速度、上一时刻动作等。
关键约定:动作在仿真里是"位置指令",不是力矩。因为真机用的是位置控制舵机,仿真里也必须按位置执行器建模,这正好引出第 10 章的 BAM 模型。
9.5 并行环境数量与训练速度
# 训练配置关键参数
num_envs: 256 # 并行仿真实例数
control_freq: 50 # 控制频率(Hz),必须与板端一致
num_envs越大,采样越快,但吃显存;显存不足时减小;control_freq=50是硬约束,与 RK3566 控制环严格对齐,保证 Sim2Real 时序一致。
9.6 工程踩坑实录
- CUDA 版本不匹配:容器里 CUDA 与宿主机驱动不兼容,仿真启动即崩。用 Docker 锁定 CUDA 版本解决。
- 版本漂移:依赖升级后环境不收敛,重装版本锁定文件后恢复。
9.7 本章小结
你现在能在容器里跑起仿真环境,理解观测/动作空间与 50Hz 时序约定。
下一章深入 BAM 舵机模型——这是 MicroDuck Sim2Real 成败的核心,也是本书最重要的技术章节之一。
BAM 执行器建模与辨识
本章是本书最重要的技术章节之一。目标:理解 BAM(Bandwidth-Aware Motor)模型为什么是 Sim2Real 成败的核心,学会用台架实测数据拟合 HD1910 的 BAM 参数,并正确实现齿隙模型。
10.1 为什么要给舵机"建模型"
真机用的是位置控制舵机,不是理想力矩源。舵机有扭矩上限、摩擦、带宽、齿隙、响应延迟。如果在仿真里把舵机当成"指哪打哪"的理想执行器,训练出的策略在真机上会:
- 跟不上(带宽不足);
- 抖(摩擦/齿隙);
- 摔倒(扭矩不够)。
BAM 模型就是用来在仿真里精确模拟这些特性的执行器模型,是 Pollen 原版 Sim2Real 成功的核心。
10.2 BAM 模型的物理成分
BAM 模型包含五个关键参数:
| 参数 | 物理含义 | 影响 |
|---|---|---|
最大扭矩 torque_max | 舵机最大输出扭矩 | 动作是否"没劲" |
转子惯量 J_rotor | 电机+齿轮的转动惯量 | 响应快慢 |
粘性摩擦 b_viscous | 与速度成正比 | 阻尼、平滑 |
库仑摩擦 tau_coulomb | 与速度无关的恒定摩擦 | 抖动、死区 |
闭环带宽 bandwidth | 舵机跟随指令的速度上限 | 跟不上指令 |
此外还有齿隙 backlash——齿轮间隙造成的滞后。
10.3 原版 XL330 与飞特 HD1910 的差异
原版 microduck_rl 内置的是 Dynamixel XL330 专属参数(反电动势、电压-扭矩曲线、摩擦、齿隙、响应延迟经过台架标定)。而飞特 HD1910:
- 扭矩常数、转子惯量不同;
- 摩擦、带宽、齿隙特性不同;
- 电压特性不同。
**直接用原版预训练模型跑飞特舵机,步态必然失效。**必须重新标定 BAM 参数并重训。
10.4 HD1910 参数拟合(实测 vs 估算)
第 8 章做了台架数据采集。这里用 scripts/calibration/hd1910_bench_data_process.py 拟合。
10.4.1 拟合脚本代码详解
#!/usr/bin/env python3
"""
scripts/calibration/hd1910_bench_data_process.py
从台架CSV拟合BAM模型参数(带宽、粘性摩擦、库仑摩擦、转子惯量)
"""
import argparse, json
import pandas as pd, numpy as np
from scipy.optimize import minimize
def bam_model_step(t, params, target):
"""简化一阶带宽模型"""
w, b, tau_c, J = params
return target * (1 - np.exp(-w * t)) # 一阶响应近似
def loss_fn(params, t, target, measured):
pred = bam_model_step(t, params, target[0])
return np.mean((pred - measured)**2)
def fit_bam(csv_path, out_json):
df = pd.read_csv(csv_path)
t = df["t"].values
target = df["target_pos"].values
actual = df["actual_pos"].values
x0 = [22.0, 0.003, 0.012, 1.2e-6] # 经验初值
bounds = [(1,60), (1e-6,0.1), (1e-6,0.1), (1e-8,1e-4)]
res = minimize(loss_fn, x0, args=(t, target, actual),
bounds=bounds, method="L-BFGS-B")
bam_result = {
"bandwidth_hz": float(res.x[0]),
"b_viscous": float(res.x[1]),
"tau_coulomb": float(res.x[2]),
"J_rotor": float(res.x[3]),
"servo_model": "HD1910", "voltage": 7.4,
"unit": "SI(kg,m,s,rad)"
}
print(json.dumps(bam_result, indent=2))
with open(out_json, "w", encoding="utf-8") as f:
json.dump(bam_result, f, indent=2, ensure_ascii=False)
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("--csv", required=True)
p.add_argument("--out", required=True)
a = p.parse_args()
fit_bam(a.csv, a.out)
10.4.2 拟合得到的参考参数(实测后替换)
hd1910_params = {
"torque_max": 12.0, # N·cm,HD1910 标称堵转扭矩@12V
"rotor_inertia": 1.2e-6, # kg·m²
"damping": 0.0018, # 粘性摩擦
"coulomb_friction": 0.009, # 库仑摩擦
"bandwidth": 22, # Hz,约20~25Hz
"backlash": 0.0025, # 齿隙(rad)
"voltage": 12.0
}
10.4.3 修改 bam_actuator.py
在 software/training/mjlab/actuators/bam_actuator.py 的 Feetech 分支加入:
class FeetechHD1910BAMActuator(FrictionDRBamActuator):
def __init__(self, **kwargs):
super().__init__(
torque_max=12.0, rotor_inertia=1.2e-6,
damping=0.0018, coulomb_friction=0.009,
bandwidth=22, backlash=0.0025, voltage=12.0,
**kwargs
)
10.5 齿隙模型:最容易出错的地方
关键设计:Pollen 原版的齿隙放在舵机输出端(编码器在齿隙之后)。这意味着:
- 编码器读到的位置是"输出轴"位置,而不是电机轴位置;
- 齿隙造成的位置误差会进入观测(反馈),影响策略。
原版实现了 BacklashEncoderBamActuator,这是 Sim2Real 成功最核心的设计。复刻时必须完整实现,否则来回摆动、抖动、跟随误差都会失配。
⚠️ 齿隙
backlash是 Sim2Real 最大影响项之一。真机上来回摆动基本就是齿隙不准导致的。拟合后建议在域随机化里给它加扰动(见第 11 章)。
10.6 消融实验:估算 vs 实测
为证明实测拟合的价值,设计对照实验(写入书稿附录数据):
- 方案 A:经验估算 BAM 参数训练;
- 方案 B:台架实测拟合 BAM 参数训练;
- 指标:真机站立稳定时长、行走成功率、跌倒恢复成功率。
预期结论:实测拟合参数显著提升真机迁移成功率,尤其在行走与粗糙地面场景。
10.7 工程踩坑实录
- 齿隙放错位置:齿隙放在电机轴而非输出端,导致仿真观测与真机编码器读数不一致,真机来回摆。
- 带宽拟合失真:台架采样率不足,阶跃响应太快,拟合带宽偏小,仿真里舵机"跟不上"。提高采样率(>500Hz)后重采重拟合。
10.8 本章小结
你现在能:
- 理解 BAM 模型的五个核心参数;
- 用台架数据拟合 HD1910 的 BAM 参数;
- 正确实现齿隙模型(编码器在输出侧)。
下一步,给训练加上域随机化,让策略对参数误差鲁棒,进一步缩小 Sim2Real gap。
域随机化
本章目标:理解域随机化原理,学会扩展随机化参数集,并结合课程学习(Curriculum Learning)从站立逐步过渡到行走、爬坡。
11.1 为什么需要域随机化
仿真模型永远无法 100% 精确复现真机。打印填充率、舵机参数误差、地面材质差异,都会导致"仿真能走、真机摔倒"。域随机化的思路是:训练时不断随机扰动仿真参数,让策略"见过"各种可能的情况,从而对模型误差鲁棒。
Pollen 原版就是靠域随机化(区分平地/粗糙地形)实现产品级 Sim2Real。复刻项目基础域随机化参数偏少,需要扩展。
11.2 扩展域随机化参数集
在 software/training/train_ppo.py 的 domain_rand 部分扩展:
domain_rand = {
"mass_scale": [0.85, 1.15], # 连杆质量 ±15%(覆盖打印填充率差异)
"friction_scale": [0.7, 1.3], # 摩擦系数 ±30%
"actuator_torque_scale": [0.8, 1.2], # 舵机最大扭矩 ±20%
"bandwidth_noise": [18, 26], # 舵机带宽随机 18~26Hz
"backlash_noise": [0.001, 0.004], # 齿隙随机扰动
"imu_noise_std": [0.002, 0.008], # IMU 噪声随机
"ground_friction": [0.4, 1.2], # 地面摩擦(地毯/木地板)
"gravity_noise": [0.98, 1.02] # 重力微小扰动
}
质量随机化
mass_scale尤其重要:它能覆盖 3D 打印填充率变化带来的整机质量波动(见第 4、5 章)。
11.3 域随机化的代码接入方式
在每个环境 reset() 时,从分布采样一次随机参数,应用到本 episode 的所有 step:
def reset(self):
# 采样本 episode 的随机化参数
self.rand = {
k: np.random.uniform(*v) for k, v in domain_rand.items()
}
# 应用到模型:缩放质量、摩擦等
self.model = self.apply_domain_rand(self.model, self.rand)
return self.get_obs()
def apply_domain_rand(self, model, r):
# 实际修改 MuJoCo 模型参数
model.body_mass *= r["mass_scale"]
# 摩擦、扭矩等类似处理
return model
11.4 课程学习 Curriculum Learning
单靠全参数随机可能让策略"什么都学不会"。课程学习从简单逐步过渡到困难,提升收敛稳定性和最终性能:
| 阶段 | 任务 | 域随机化强度 |
|---|---|---|
| 1 | 原地站立 | 低 |
| 2 | 原地下蹲 | 低 |
| 3 | 低速行走 | 中 |
| 4 | 粗糙地面行走 | 中 |
| 5 | 转向 | 中 |
| 6 | 爬坡 | 高 |
课程自动推进:当上一阶段策略达到成功率阈值,自动提升难度。
11.5 奖励函数平滑项
域随机化之外,奖励函数也要抑制抖动。增加动作平滑惩罚,避免策略输出剧烈跳变:
action_smooth_penalty = -0.05 * torch.sum(torch.square(next_action - prev_action), dim=-1)
reward = reward + action_smooth_penalty
11.6 消融实验设计(写入书稿)
为量化域随机化价值,设计消融:
- 方案 A:不开域随机化;
- 方案 B:仅质量随机;
- 方案 C:全参数域随机化。
对比三者在真机上的迁移成功率,结果写入本书附录实验数据。预期:C > B > A,尤其在行走场景差距显著。
11.7 工程踩坑实录
- 随机化过强导致不收敛:一开始全参数大幅随机,策略学不会站立。先用低强度,再逐步增强(配合课程学习)。
- 质量随机化未生效:随机化代码没接到 MuJoCo 模型,参数改了但仿真没变。用校验脚本验证
body_mass确实被修改。
11.8 本章小结
你已掌握:扩展域随机化参数、接入 reset 逻辑、课程学习推进、奖励平滑。
下一章把这一切组装成 PPO 多任务训练:从站立到行走、转向、爬坡,一个策略全部支持。
PPO 多任务训练
本章目标:理解 PPO 在机器人运动中的角色,学会设计多任务奖励函数,实现"一个 ONNX 支持多种步态"的单策略方案,并掌握训练调参与导出。
12.1 PPO 基础
PPO(Proximal Policy Optimization)是机器人强化学习的常用策略:
- 在旧策略与新策略之间做裁剪(clip),防止更新过猛导致训练崩溃;
- 适合连续动作空间(关节目标位置);
- 实现成熟、调参相对简单。
MicroDuck 的 PPO 用 MuJoCo-Warp 并行数百环境采样,配合 mjlab 训练循环。
12.2 多任务单策略方案
原版是连续速度指令控制。为支持多种步态,本书采用多任务单策略方案:
在观测向量里追加 one-hot 任务编码:
| 编码 | 任务 |
|---|---|
[1,0,0,0,0,0] | 原地站立 |
[0,1,0,0,0,0] | 向前行走 |
[0,0,1,0,0,0] | 左转 |
[0,0,0,1,0,0] | 右转 |
[0,0,0,0,1,0] | 摔倒自恢复 |
[0,0,0,0,0,1] | 低速爬坡 |
板端固件只需传入任务 id,即可切换步态,无需加载多个 ONNX。
12.3 多任务奖励函数设计
按任务分支奖励。以行走为例:
forward_reward = torch.clip(obs[:, 0] * 1.2, 0, 1.5) # x 方向前进速度
height_reward = -torch.square(obs[:, 2] - 0.22) # 保持身体高度
tilt_penalty = -(torch.square(obs[:, 3]) + torch.square(obs[:, 4])) # 抑制倾斜
action_penalty = -0.01 * torch.sum(action**2, dim=-1) # 动作惩罚
smooth_penalty = -0.05 * torch.sum((action - prev_action)**2, dim=-1)
reward = forward_reward + height_reward + tilt_penalty \
+ action_penalty + smooth_penalty
各任务奖励要点:
| 任务 | 关键奖励项 |
|---|---|
| 站立 | 保持高度、抑制倾斜、抑制抖动 |
| 行走 | 前进速度 +、保持高度 +、抑制侧倾 |
| 转向 | 绕 yaw 角速度 +、横向位移 - |
| 摔倒自恢复 | 身体抬升 +、关节复位、站立奖励 |
| 爬坡 | 保持稳定 + 沿斜面前进(见 16.3) |
12.4 训练配置与调参
# 训练配置要点
num_envs: 256
learning_rate: 3e-4
batch_size: 8192
update_epochs: 10
clip_range: 0.2
task: "multitask" # 多任务模式
domain_randomization: true
control_freq: 50
调参速查:
| 问题 | 调整方向 |
|---|---|
| 不收敛 | 降低学习率、提高奖励尺度 |
| 动作发散 | 增加动作/平滑惩罚 |
| 训练崩溃 | 减小 clip_range、降域随机强度 |
| 过拟合仿真 | 增强域随机化 |
12.5 导出 ONNX 策略
训练完成后导出可部署的 ONNX:
# export_onnx.py
import torch
from policy import PPOPolicy
policy = PPOPolicy.load("outputs/best_model.pt")
policy.eval()
dummy_input = torch.randn(1, policy.obs_dim)
torch.onnx.export(
policy, dummy_input,
"microduck_feetech_multitask.onnx",
opset_version=17, input_names=["obs"], output_names=["action"]
)
产物 microduck_feetech_multitask.onnx 放入 software/training/pretrained/。
大文件管理:ONNX 模型体积大,建议用 Git LFS 管理,不直接提交 git 主仓库(见第 17 章)。
12.6 预训练权重开箱即用
仓库 pretrained/ 应提供训练好的预训练 ONNX,供读者开箱即用、验证整条链路,不必从零训练。每个权重需附带:
- 对应的 MJCF 版本;
- BAM 参数文件;
- 训练配置;
- 实验记录链接。
12.7 工程踩坑实录
- 观测/动作缩放不一致:仿真归一化 [-1,1],板端未归一化,真机动作溢出。用
check_obs_act_space.py校验。 - 多任务奖励权重失衡:行走奖励权重过大,站立任务被忽略。按任务分 episode 采样,平衡训练。
12.8 本章小结
你现在能:设计多任务奖励、调参 PPO、导出并管理 ONNX 预训练权重。
下一章处理仿真调试:训练不收敛、抖动、动作发散的定位方法。
仿真调试与诊断
本章目标:学会用 TensorBoard 观察训练,掌握训练失败(不收敛、抖动、动作发散)的定位方法,并判断问题是出在奖励函数、动力学还是观测空间。
13.1 用 TensorBoard 观察训练
训练过程记录奖励曲线、损失、动作分布、观测统计:
tensorboard --logdir experiments/exp02_walk_flat/tensorboard
关键指标:
- reward:是否整体上升、有无平台期;
- action std:动作是否收敛(不发散);
- value loss / policy loss:是否震荡。
13.2 常见训练失败定位
现象1:训练不收敛 / 奖励平台期
排查顺序:
- 奖励函数:奖励是否过于稀疏?是否信号太小?
- 观测:关键状态(高度、速度)是否进入观测?
- 学习率:是否过大导致震荡,过小导致太慢?
现象2:动作抖动 / 发散
排查顺序:
- 动作惩罚缺失:加
action_penalty与smooth_penalty(见 12.3); - 奖励函数有高频波动:抑制剧烈动作;
- 执行器带宽过低:仿真舵机跟不上(见第 10 章)。
现象3:总是摔倒
排查顺序:
- 动力学错误:MJCF 重心/惯性参数错误(回第 4 章复核);
- 域随机化过强:训练太困难,降低强度或配合课程学习;
- 奖励不鼓励站立:增加站立奖励、高度奖励。
13.3 仿真与真机差异定位框架
当"仿真完美、真机乱走",按优先级排查:
| 优先级 | 检查项 | 工具/章节 |
|---|---|---|
| 1 | 观测空间一致性 | check_obs_act_space.py(RK3566 镜像与固件) |
| 2 | 关节限位对齐 | MJCF limits vs 硬件(HD1910 CAD 模型解析 / 舵机与 IMU 标定) |
| 3 | IMU 零偏/安装 | 六面校准(舵机与 IMU 标定) |
| 4 | BAM 参数精度 | 台架拟合(BAM 执行器建模与辨识) |
| 5 | 整机质量/重心 | 称重对比 CAD(3D 打印、装配与公差) |
这个框架是本书反复强调的核心:Sim2Real gap 不是单一原因,而是从观测、动力学、执行器到传感器的一整条链路,必须逐层排查。
13.4 仿真自检脚本
每次修改代码,先跑环境自检,把错误挡在训练前:
python scripts/validation/test_env.py
python scripts/validation/validate_mjcf.py --mjcf software/training/assets/robots/microduck_feetech.xml
13.5 工程踩坑实录
- MJCF 单位错误:Onshape 用毫米导出未转米,模型放大 1000 倍,仿真崩溃(见第 4 章)。
- 奖励被噪声淹没:奖励信号幅度远小于 action_penalty,策略"摆烂"只输出极小动作。调整奖励权重。
13.6 本章小结
你已掌握训练失败的定位框架,以及"仿真好、真机差"的逐层排查方法。
下一章进入部署:把 ONNX 策略送到 RK3566 板端,跑通真机控制环。
策略部署与板端推理
本章目标:把训练好的 ONNX 策略上传到板端,验证推理链路,并重点解决观测/动作缩放对齐问题——Sim2Real 最常踩的坑。
14.1 部署流程
- 上传 ONNX:将
microduck_feetech_multitask.onnx上传到 RK3566 板卡:
scp software/training/pretrained/microduck_feetech_multitask.onnx user@rk3566:~/microduck/
- 配置加载路径:让
robotd加载该策略文件; - 验证加载:确认板端成功加载 ONNX,输出维度为 14。
14.2 板端推理链路
IMU + 关节回读 → 打包观测(61维) → ONNX推理 → 动作(14维) → 舵机目标位置
关键:观测空间和动作缩放必须与仿真严格一致(见第 7 章)。仿真里归一化到 [-1,1] 的动作,板端必须反归一化到实际舵机位置范围(弧度/角度)再下发。
14.3 观测/动作缩放对齐(最容易踩坑)
三种典型 bug:
- 维度不一致:仿真观测 61 维,板端只打包 60 维,推理报错或静默错位;
- 缩放不一致:仿真用弧度,板端用角度下发,舵机转错方向;
- 顺序不一致:观测里关节顺序与板端回读顺序不同,策略"看不懂"数据。
用
check_obs_act_space.py自动校验,杜绝这类隐性 bug(见第 7.5 节)。
14.4 50Hz 控制环时序校验
控制环必须以 20ms 周期稳定运行:
- 用 WebUI 查看每次迭代耗时;
- 若推理 + 总线通信超时,步态会抖动;
- 优化:用 RKNN 加速推理、DMA 批量收发舵机指令。
# 在板端检查控制环延迟统计
robotd status
# 期望输出:control_loop_avg_ms < 20
14.5 首次通电部署步骤(安全)
- 先站立:加载站立任务,观察鸭子能否稳定站住;
- 再下蹲/复位:确认动作在物理限位内;
- 最后行走:确认稳定后再测试行走。
每个阶段都观察:是否抖动、是否漂移、是否超出关节限位。
14.6 工程踩坑实录
- 动作未反归一化:仿真动作 [-1,1] 直接当位置下发,舵机转出物理限位,机械卡死。加反归一化 + 限幅。
- 观测顺序错位:板端回读关节顺序与仿真训练时不一致,策略行为异常。用自动校验 + 单关节激励测试对齐。
14.7 本章小结
你已把 ONNX 策略部署到板端,跑通 50Hz 控制环,并重点解决了观测/动作缩放对齐。
但"能跑"不等于"走得好"。下一章做真机步态迭代,闭环调优 Sim2Real。
Sim2Real 闭环迭代
本章目标:掌握真机测试流程、抖动/漂移/摔倒的诊断方法,并实现"仿真训练 → 真机测试 → 采集数据 → 修正模型 → 重训"的闭环迭代。这是 Sim2Real 的终极工程能力。
15.1 真机测试分级
| 阶段 | 任务 | 判定标准 |
|---|---|---|
| 1 | 站立 | 稳定站住 30s,无持续漂移 |
| 2 | 下蹲/复位 | 动作在限位内,无卡死 |
| 3 | 原地转向 | 绕垂直轴转动,不倾倒 |
| 4 | 平地行走 | 直线前进,不抖动 |
| 5 | 摔倒自恢复 | 跌倒后能自行站起 |
15.2 真机抖动、漂移、摔倒诊断
现象A:持续抖动
排查顺序:
- BAM 参数:带宽/齿隙不准 → 回第 10 章重标定;
- 动作平滑:奖励函数缺平滑惩罚 → 重训;
- 控制环超时:推理太慢,控制周期不稳(见第 14 章)。
现象B:姿态漂移(慢慢歪)
排查顺序:
- IMU 零偏:未六面校准 → 回第 8 章;
- IMU 安装倾角:未补偿 → 固件加补偿;
- 重心偏移:装配不对称 → 回第 5 章称重。
现象C:经常摔倒
排查顺序:
- 观测/动作缩放:维度或缩放错位 →
check_obs_act_space.py; - MJCF 惯性错误:重心不对 → 回第 4 章;
- 整机质量与仿真差异:填充率不同 → 域随机化覆盖或重标定。
15.3 真机数据采集(闭环关键)
在真机上记录 IMU、关节角度、策略输出、时间戳,保存到 data/real_robot_logs/:
t,imu_qw,imu_qx,imu_qy,imu_qz,q0,...,q13,a0,...,a13
这些数据是系统辨识与参数修正的依据,也是书稿附录实验数据的来源。
15.4 反向系统辨识(高级闭环)
用真机激励数据反向辨识整机惯性,修正 CAD 导出模型的偏差:
- 给机器人施加激励(小幅摆动、阶跃);
- 记录 IMU + 关节响应;
- 用最小二乘反向拟合真实质量/重心/惯量;
- 把辨识结果回写到 MJCF,重新训练。
# 脚本:scripts/calibration/system_id_fit.py
# 输入:真机激励CSV + 当前MJCF
# 输出:修正后的惯性参数建议
这是学术界 Sim2Real 的进阶手段,能修正 Onshape 几何计算的残余误差(打印、装配误差)。
15.5 闭环迭代流程
仿真训练 → ONNX导出 → 真机测试
↓(采集数据)
诊断问题 → 修正 BAM/MJCF/域随机
↓
重新训练 → 再测(迭代)
每个迭代周期记录到 experiments/,形成可复现的迭代历史。
15.6 步态性能评估指标
为量化进步,定义指标:
- 行走速度(m/s);
- 站立稳定时长;
- 抗扰动能力(推一下能否恢复);
- 摔倒恢复成功率;
- 转弯角度精度。
这些指标与原版 Pollen MicroDuck 对比,形成本书的性能评估章节(第 16 章延伸)。
15.7 工程踩坑实录
- 一次迭代全改:同时改了 BAM、MJCF、奖励,问题仍无法定位。一次只改一个变量,记录每次结果。
- 真机数据未打时间戳:无法对齐 IMU 与关节时序。采集前先统一时钟。
15.8 本章小结
你已掌握真机步态诊断与闭环迭代,能把仿真模型不断逼近真机。
下一章任务拓展,把 MicroDuck 从"会走"变成"会各种走"。
任务拓展
本章目标:在基础行走之上,实现转向、爬坡、避障三个进阶任务,把一个"只会直走"的鸭子变成"会各种走"的鸭子。
16.1 转向步态
在基础行走任务上,把奖励从"x 方向前进"改为"绕 yaw 角速度"驱动:
yaw_rate = obs[:, yaw_vel_idx] # 绕垂直轴角速度
turn_reward = clip(target_yaw_speed * yaw_rate, 0, 1.0)
# 抑制横向滑移
lateral_penalty = -torch.abs(obs[:, yaw_vel_idx_side])
reward = turn_reward + lateral_penalty + stance_rewards
真机验证:鸭子原地转向指定角度,不倾倒、不滑移。
16.2 斜面爬坡
16.2.1 斜面环境搭建
在 MuJoCo 中把地面改为斜面,或在 MJCF 里增加斜面 geom:
<geom type="box" size="..." pos="..." quat="..."/>
<!-- 或用 ground 加倾斜 -->
16.2.2 爬坡奖励
爬坡的难点是沿斜面的投影前进 + 保持稳定:
slope_forward = obs[:, proj_along_slope_idx]
reward = clip(slope_forward * 1.0, 0, 1.0) + stability_terms
配合课程学习:先平地,再小坡度(5°),逐步到 15°(见第 11 章)。
16.2.3 真机验证
在垫木块或斜面垫上测试爬坡,观察是否打滑、后仰。地面摩擦域随机化在此场景尤其关键。
16.3 避障(进阶)
16.3.1 视觉感知接入思路
RK3566 算力有限(1GB),无法同时跑高分辨率视觉 + RL 策略。推荐降级方案:
- 用 YOLO 轻量版(如 YOLOv5-nano / YOLO11-nano)做障碍物检测;
- 只输出"前方有无障碍、距离"的低维信息,并入观测向量;
- 或者分时处理:视觉低频(如 5Hz),RL 控制高频(50Hz)。
16.3.2 避障奖励
if obstacle_detected:
reward += turn_away_reward # 鼓励转向避开
else:
reward += forward_reward # 无障碍时前进
16.3.3 局限性说明
- 视觉闭环是本书进阶拓展,涉及相机选型、标定、vLA/感知策略集成,工作量较大;
- 本书主链路完成"本体平衡 + 行走/转向/爬坡",视觉避障作为可选延伸。
16.4 多任务合并训练
把转向、爬坡合并进第 12 章的多任务 one-hot 编码,一个 ONNX 支持全部动作:
| 编码 | 任务 |
|---|---|
[0,1,0,0,0,0] | 向前行走 |
[0,0,1,0,0,0] | 左转 |
[0,0,0,1,0,0] | 右转 |
[0,0,0,0,1,0] | 摔倒自恢复 |
[0,0,0,0,0,1] | 爬坡 |
16.5 工程踩坑实录
- 爬坡后仰:奖励只奖励前进,没奖励重心稳定,鸭子爬坡时后仰摔倒。加重心投影奖励。
- 转向滑移:地面摩擦太小,转向时横向滑移。增强地面摩擦域随机化,训练更鲁棒转向。
16.6 本章小结
你已实现转向、爬坡、避障(进阶)三个拓展任务,MicroDuck 从"会走"进阶为"会各种走"。
下一部分进入工程化与开源合规:如何把你的整套工程做成规范、合规、可复现的开源仓库。
工程化与开源合规
本章目标:把整套工程做成规范、可复现、开源合规的仓库。包含分支管理、文档工程化、自动化测试与开源许可详解。
17.1 Fork 仓库工作流与分支管理
正确的分支策略能避免"上游同步冲突":
main # 上游跟踪分支,仅同步 fanhao375/microduck-replica 更新
book-dev # 本书开发主分支(书稿、脚本、Docker、实验)
feature/cad2mjcf # 功能分支,开发完成合并到 book-dev
feature/bam-id
feature/docker
为什么要分开:
main保持和上游接近,方便拉取上游更新;- 你的定制(删联系方式、新增英文文档、改 RL 代码)全放
book-dev; - 上游更新时同步
main,再合并进book-dev,冲突最少。
上游同步操作
git fetch upstream
git checkout main
git merge upstream/main
git checkout book-dev
git merge main # 解决可能出现的冲突
17.2 文档工程化
仓库文档分层:
README.md:中文快速上手;README_EN.md:英文版本;book/:本书 mdbook 书稿;docs/tutorials/:独立分步教程(不嵌入书稿);docs/engineering_log/:工程踩坑日志(书稿素材)。
建议增加中英双语
README_EN.md,这是原复刻仓库缺失、也是你计划的改进点。
17.3 自动化测试与 CI
.github/workflows/test-sim.yml:每次提交自动加载 MJCF、校验模型,把错误挡在合并前。
name: Sim Validate
on: [push, pull_request]
jobs:
test-mjcf:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.10" }
- run: pip install mujoco
- run: python scripts/validation/validate_mjcf.py --mjcf software/training/assets/robots/microduck_feetech.xml
build-book.yml:mdbook 自动编译,部署 GitHub Pages 网页电子书。
17.4 实验管理规范
所有训练实验存入 experiments/,每个实验文件夹必须含:
config.yaml:训练配置、域随机化、BAM 参数;mjcf/:MJCF 快照;bam_params.json:舵机参数;logs/+tensorboard/;readme.md:目标、消融变量、结果、失败分析。
保证每个实验可复现、可回溯,是工程化与书稿案例的核心。
17.5 Git LFS 管理大文件
ONNX、STL、STEP、CSV、Tensorboard 日志体积大,用 Git LFS:
# .gitattributes
*.onnx filter=lfs diff=lfs merge=lfs -text
*.stl filter=lfs diff=lfs merge=lfs -text
*.step filter=lfs diff=lfs merge=lfs -text
*.csv filter=lfs diff=lfs merge=lfs -text
17.6 开源许可详解(务必合规)
| 内容 | 许可 | 商用限制 |
|---|---|---|
| 软件代码(training/firmware) | Apache 2.0 | ✅ 可商用 |
| 机械 CAD 模型(replica-cad) | CC BY-NC-SA | ❌ 禁止商用 |
| 本书书稿正文 | CC-BY 4.0 | 可自由分享,引用需署名 |
Fork 合规要点
- 不能删除 LICENSE 文件、原作者版权归属声明;
- 可删除 README 里私人联系方式(微信、邮箱);
- 保留来源署名:
基于 pollen-robotics/microduck_rl 与 fanhao375/microduck-replica 衍生开发; - 不可抹除来源、宣称完全原创;
- 若要商用产品,必须独立正向设计机械结构,脱离 CC BY-NC-SA 模型。
图片合规
优先使用自己实验产出的图;原版 Pollen 图片谨慎引用,避免图片版权问题。
17.7 工程踩坑实录
- 直接改 main 分支:上游更新后冲突一堆。改用 book-dev + feature 分支后大幅减少冲突。
- 未锁版本:依赖升级后环境跑不起来。用
requirements-lock.txt锁定。
17.8 本章小结
你已掌握分支管理、文档工程化、CI、实验管理、Git LFS 与开源许可合规。
最后一章展望进阶方向:硬件升级、算法进阶与商业化边界。
展望与拓展
本章目标:为读者指明 MicroDuck 之后的进阶路径——硬件升级、算法进阶、商业化边界。本章是开放的展望,不做完整实现。
18.1 硬件升级方向
| 方向 | 说明 |
|---|---|
| 更高算力板卡 | RK3588 / 边缘 GPU,支撑高分辨率视觉 + RL 并行 |
| 深度相机 | 接入 RGB-D,实现稠密感知与避障 |
| 手部执行器 | 增加自由度,探索抓取操作 |
| 更高性能舵机 | 换用扭矩/带宽更高的总线舵机,扩展负载能力 |
升级注意:换舵机会改变整机动力学,MJCF 惯性、BAM 参数需重新标定(回第 4、10 章)。
18.2 算法进阶方向
18.2.1 在线自适应
在真机上根据实时数据微调策略,进一步压缩 Sim2Real gap:
- 残差策略:仿真学基础,真机学修正;
- 在线域适应:实时更新动力学假设。
18.2.2 多模态感知策略
- 视觉 + 本体感知融合,进 vLA(视觉-语言-动作)方向;
- 用空间 VLM 引导机械臂/身体动作,实现语义级任务。
这是"具身智能"的方向,工作量与研究性远超本书主链路,作为进阶课题。
18.3 性能评估与对标
建立量化指标体系,与原版 Pollen MicroDuck 对比:
- 行走速度;
- 抗扰动能力;
- 摔倒恢复成功率;
- 能耗。
对比数据可作为本书升级版 / 论文素材,检验国产飞特方案的竞争力。
18.4 商业化边界(重要合规提醒)
- 软件可商用:Apache 2.0 训练/固件代码可商用;
- CAD 不可商用:CC BY-NC-SA 机械模型禁止商用,必须重新正向设计;
- 品牌与商标:不得盗用 Pollen/MicroDuck 商标;
- 若要商业产品,需独立设计 + 自研软件,脱离开源 CAD 模型。
这与第 17 章的许可边界一脉相承。商业落地是方向,但必须建立在合规的重构之上。
18.5 社区协作与持续迭代
- 维护
docs/engineering_log/,记录每次踩坑; - 开放 Issue / PR,社区共同迭代;
- 书稿与仓库同步更新,读者可复现每个版本。
18.6 本章小结
本书主链路(机械→仿真→训练→真机闭环)到此完成。本章为进阶指明方向:硬件升级、算法自适应、性能对标、合规商业化。
全书六篇 18 章到此结束。附录提供代码清单、BOM、故障排查、术语表与参考文献。
代码清单
本书配套的全部代码、脚本与配置,按仓库路径索引。所有代码以仓库
book-dev分支为准。
A.1 仿真与训练代码(software/training/)
| 文件 | 用途 | 对应章节 |
|---|---|---|
mjlab/actuators/bam_actuator.py | BAM 舵机模型(HD1910 参数) | BAM 执行器建模与辨识 |
assets/robots/microduck_feetech.xml | 飞特版 MJCF 模型 | Onshape→MJCF 自动化建模、MuJoCo-Warp 仿真环境 |
train_ppo.py | PPO 训练主脚本(含域随机化) | 域随机化、PPO 多任务训练 |
export_onnx.py | 导出 ONNX 策略 | PPO 多任务训练 |
test_env.py | 仿真环境自检 | MuJoCo-Warp 仿真环境 |
requirements.txt / requirements-lock.txt | 依赖清单 | MuJoCo-Warp 仿真环境 |
A.2 标定与系统辨识(scripts/calibration/)
| 文件 | 用途 | 对应章节 |
|---|---|---|
hd1910_bench_data_process.py | 台架CSV→BAM参数拟合 | 舵机与 IMU 标定、BAM 执行器建模与辨识 |
system_id_fit.py | 真机数据→惯性参数辨识 | Sim2Real 闭环迭代 |
A.3 CAD 导出(scripts/cad2mjcf/)
| 文件 | 用途 | 对应章节 |
|---|---|---|
onshape_config.json | Onshape 装配配置 | Onshape→MJCF 自动化建模 |
export_mjcf.py | onshape-to-robot 一键导出 | Onshape→MJCF 自动化建模 |
validate_mjcf.py | MJCF 惯性/限位校验 | Onshape→MJCF 自动化建模 |
A.4 校验脚本(scripts/validation/)
| 文件 | 用途 | 对应章节 |
|---|---|---|
check_bam_params.py | BAM 参数物理合理性校验 | BAM 执行器建模与辨识 |
check_obs_act_space.py | 仿真↔板端观测空间比对 | RK3566 镜像与固件、策略部署与板端推理 |
mass_inertia_check.py | 整机质量/惯性校验 | 3D 打印、装配与公差 |
A.5 容器与配置(docker/)
| 文件 | 用途 | 对应章节 |
|---|---|---|
Dockerfile | GPU 训练环境镜像 | MuJoCo-Warp 仿真环境 |
docker-compose.yml | 一键启动 | MuJoCo-Warp 仿真环境 |
A.6 实验配置示例(experiments/)
| 目录 | 用途 | 对应章节 |
|---|---|---|
exp01_standup/config.yaml | 站立训练配置 | 最小仿真示例 |
exp02_walk_flat/config.yaml | 平地行走配置 | PPO 多任务训练 |
exp03_domain_rand/config.yaml | 域随机化消融 | 域随机化 |
exp04_curriculum/config.yaml | 课程学习配置 | 域随机化 |
A.7 板端固件(software/firmware/)
Rust 多守护进程:robotd(主控制环)、configd(配置)、busd(总线)、webui(调试界面)。对应第 7 章。
配件商城与备料指南
本章与官网配件商城同步:https://www.wwntai.com/parts.html 价格与库存以官网实时为准;下文产品图均来自官网商城。
复刻 MicroDuck 前先备料:本章把官网配件商城的散件与配件(舵机、主控、电池、摄像头等)图文并茂收录进来,方便读者对照 BOM 一站式采购。
19.1 现货配件(IN STOCK · 7 天内发货)
Radxa ZERO 3W 主板

2GB / 无 eMMC / 带排针。超小型 RK3566 单板计算机,WiFi 6 + USB 3.0 + MIPI CSI,适合 IoT 与边缘计算。
| 项目 | 规格 |
|---|---|
| 处理器 | RK3566 四核 Cortex-A55 @1.6GHz |
| GPU | Mali-G52-2EE(Vulkan 1.1 / OpenCL 2.0) |
| 内存 | 2GB LPDDR4 |
| 存储 | MicroSD 卡(无板载 eMMC) |
| 无线 | WiFi 6 + 蓝牙 5.4 |
| 接口 | USB 3.0 + USB 2.0 OTG(Type-C) |
| 显示 | Micro HDMI 1080p60 |
| 摄像头 | MIPI CSI(22-Pin) |
| 尺寸 | 65 × 30 mm · 系统 Debian/Ubuntu |
¥385 · 立即购买
Radxa Camera 8M 219 摄像头

Sony IMX219 · 800 万像素。高分辨率摄像头模组,默认 FPC 排线适配 ZERO 3W/3E,即插即用。
| 项目 | 规格 |
|---|---|
| 传感器 | Sony IMX219,800 万像素 |
| 分辨率 | 3280 × 2464 |
| 帧率 | 最高 30fps(全像素) |
| 镜头 | 焦距 2.95mm · 光圈 F2.5 |
| 视角 | D74° H62° V49° · 畸变 <0.3% |
| 排线 | 150mm(22-Pin 0.5mm) |
| 应用 | 人脸识别 · 车牌识别 · 标线识别 |
¥180 · 立即购买
Radxa ZERO 3E PoE HAT

IEEE 802.3af/at。PoE 以太网供电扩展板,单根网线同时供电 + 联网,简化布线。
| 项目 | 规格 |
|---|---|
| 标准 | IEEE 802.3af/at |
| 功能 | 单网线同时供电 + 数据传输 |
| 连接 | 40-Pin GPIO 堆叠 |
| 尺寸 | 65 × 30 mm |
| 附件 | 铜柱 ×4 + 螺丝 ×8 |
| 说明 | 需配合 PoE 交换机/路由器使用 |
¥118 · 立即购买
HD-1910-C001 串口总线舵机 15 个套装

FEETECH 空芯杯串口总线舵机,AI 开源专用,适配 MicroDuck 等仿生机器人关节。6V 12kg·cm 堵转扭矩、12 位磁编码 360° 位置反馈、TTL 总线菊花链串联(详细参数见第 1、8、10 章)。
¥1380 · 立即购买
FE-URT2-C001 调试板 + 线材

飞特 USB 转 TTL/485 总线调试板(Type-C · 2.54 排针),配 AMP2.0 双头转接线,用于舵机 ID 配置与总线调试。
¥49.5 · 立即购买
VL53L8CX ToF 模块

ST 8×8 多区域 ToF 测距传感器,64 分区同步探测、65° 视角、最远 400cm,实现避障、手势识别与深度感知。
¥54.9 · 立即购买
唯卓仕 NP-F550 电池组

唯卓仕 VILTROX NP-F550 锂电池:2200mAh / 7.4V,USB-C 直充约 2 小时,4 格 LED 电量显示,尺寸 70.7×38.5×25mm,重约 110g,可拆卸快换。
¥49 · 立即购买
扬声器模组

扬声器模组,让机器鸭能「说」,支持语音反馈与提示音。
¥5.9 · 立即购买
萤石 64G 监控专用高速 TF 卡

萤石 64G 内存卡,监控专用高速卡,视频录像 TF 存储卡,读速 90MB/s。
¥60 · 立即购买
标准件套装(轴承 · 螺丝 · 螺纹胶 · 防滑垫)
| 内容 | 数量 |
|---|---|
| 轴承 10×15×3 | ×3 |
| 轴承 16×22×4 | ×11 |
| 轴承 6×12×3(轮滑) | ×4 |
| 自攻螺丝 平尾 M2×5 | ×1包 |
| 自攻螺丝 平尾 M2×6 | ×1包 |
| 自攻螺丝 平尾 M2×8 | ×1包 |
| 自攻螺丝 平尾 M2.5×6 | ×1包 |
| 自攻螺丝 平尾 M2.5×8 | ×1包 |
| 乐泰螺纹胶 243 | ×1 |
| 鞋底防滑垫 | ×1 |
¥99 · 立即购买
代装整机服务
散件代装 + 首跑调试一站式服务。专业工程师组装、烧录、首跑验证,到手即用,适合想省心的用户。
¥699 · 立即购买
19.2 MicroDuck 国产版配件(即将上线)
开源双足机器鸭的散件与扩展配件,个人开发者友好。
整机散件包

MicroDuck 全部零件一次配齐:3D 打印结构件、电子件、15 颗 HD-1910-C001 舵机、RK3566 主控、NP-F550 电池组。附中英双语组装教程,从零件到会走路的机器鸭,开箱即装。
¥2580 · 即将上线
3D 打印结构件套装

全套外壳 + 骨架结构件,FDM / 光固化工艺可选,图纸全量开源。公差与干涉问题清单公开,打印即装,复现成功率高。
¥128 · 即将上线
轮滑套件

轮滑套件,让机器鸭从「走」进化到「滑」,解锁轮滑行为,移动更快更流畅。
¥49 · 即将上线
游戏手柄
蓝牙手柄,零代码直接玩。连上即可遥控机器鸭行走、踢球,秒变遥控玩具。
¥79 · 即将上线
电子件
- imu_to_dxl 电路板:IMU 转 Dynamixel 协议桥接板,microduck-replica 开源方案的姿态数据转换。价格待定。
- Banana PCB + 香蕉插头 PCB(铜镀金):2.5mm 香蕉插头 PCB(铜镀金)× 2 + banana PCB(嘉立创)× 1。价格待定。
19.3 待上线(COMING SOON)
| 产品 | 状态 |
|---|---|
| Radxa ZERO 3W 1GB 版 | 待上线 |
| Radxa ZERO 3W 4GB 版 | 待上线 |
| Radxa ZERO 3W 8GB 版 | 待上线 |
| Radxa ZERO 3E(千兆网口版) | 待上线 |
19.4 如何购买
- 点击购买:在官网商城卡片上点「立即购买」,自动带入所选配件;
- 支付宝扫码付款:核对金额后扫码付款,记下转账单号;
- 填单提交:填写转账单号,把订单信息发给客服,确认后安排发货。
加入配件交流群(下单/答疑)

小鸭子的配件(主板,舵机群 2) · 下单:https://wwntai.com
使用微信或企业微信扫码加入。
⚠️ 微信群二维码 7 天自动失效(本图有效期至 2026-10-31)。过期后请访问官网 https://www.wwntai.com/parts.html 获取最新二维码,或在 GitHub 仓库提 issue 更新。
19.5 创始人寄语
MicroDuck 配件商城 · 写给同样踩过坑的你
做开源机器人,最磨人的往往不是代码,而是零件。
配件突然断货,等了两周发现发不了;买回来的摄像头排线对不上主板;舵机参数看着差不多,装上去才发现协议不兼容;为了凑齐一套标准件,跑了三家店、付了三次运费,最后还少一颗螺丝。这些事,我们自己都经历过。
MicroDuck 配件商城不是一开始就规划好的平台,它更像是被这些坑一点点逼出来的一个货架。我们能力有限,做不到大而全,只能尽量把一件事做好:让个人开发者在复现开源机器人时,少一次选型焦虑,少一趟冤枉路。
我们正在努力做的几件小事
- 把库存状态说清楚:现货可下单的配件标注 7 天内发货,即将上线的提前公示,不让人下了单才发现要无限等待。供应不稳定是现实,我们选择把现实讲在前面。
- 把匹配关系写明白:摄像头排线适配哪块板、舵机适配哪个关节、PoE HAT 需要什么前提、标准件套装里到底有几颗什么规格的螺丝——这些细节不藏着,因为选错一次的成本,开发者比谁都清楚。
- 把质量来源摆出来:传感器型号、舵机品牌、电池规格、TF 卡用途,关键参数尽量公开可查。我们不敢说每一件都是最优解,但至少让你知道自己在买什么。
- 把零散采购收拢到一张订单:整机散件、结构件、电子件、标准件、可选配件放在一起,明码标价,点击即购。代装整机服务也是给想省心的朋友多一个选择,不是必须。
商城现在有什么
现货可下单的有 Radxa ZERO 3W 主板、8M 219 摄像头、PoE HAT、15 颗 HD-1910-C001 舵机套装、调试板、VL53L8CX ToF 模块、NP-F550 电池组、扬声器模组、64G 高速 TF 卡、标准件套装和代装整机服务。
即将上线的有 MicroDuck 国产版整机散件包、3D 打印结构件套装、轮滑套件、游戏手柄、imu_to_dxl 电路板、香蕉插头 PCB,以及 ZERO 3W 1GB/4GB/8GB 和 ZERO 3E 千兆网口版。结构件图纸全量开源,公差与干涉问题清单也公开,复现成功率高一些,是我们能给的诚意。
购买路径也尽量简单:点击购买 → 支付宝扫码付款 → 填收货信息与转账单号 → 复制订单发客服。
一点心里话
我们知道这个商城还远不完美。品类不够多,部分配件还在路上,客服可能也不是随叫随到。但它是围绕真实复现场景一点点搭起来的,每一条参数、每一张图、每一个「即将上线」,都来自我们自己装机器时遇到过的具体问题。
如果你在采购或组装过程中发现哪里写错了、缺了什么、哪里还能更清楚,欢迎直接告诉我们。个人开发者做硬件已经够不容易了,能在这个小货架上帮你省下一点时间,就是我们做它的意义。
—— 万物拟态 CEO 叶志青(Henry Ip)
MicroDuck 配件商城 —— 我们也在学,尽量不让后来的人再踩同一个坑。
BOM 采购清单
完整物料清单,含推荐采购渠道与备选替代件。价格为参考价,随市场浮动。
B.1 核心电子件
| 部件 | 规格 | 数量 | 参考单价 | 采购建议 |
|---|---|---|---|---|
| 舵机 | 飞特 HD1910(双轴磁编码 TTL) | 14~15 | 中低 | 飞特官方/正规分销 |
| 主控 | RK3566 板卡 | 1 | 中 | 正规渠道 |
| IMU | MPU6050 / ICM20948 | 1 | 低 | 通用模组 |
| 电池 | 2S/3S 锂电 | 1 | 低 | 配 BMS |
| BMS | 锂电保护板 | 1 | 低 | 带低压/过流保护 |
B.2 结构与紧固件
| 部件 | 规格 | 数量 | 说明 |
|---|---|---|---|
| 3D 打印件 | PLA | 1套 | 20%~40% 填充 |
| M2 螺丝 | 若干 | 舵盘固定 | |
| M3 螺丝 | 若干 | 结构固定 | |
| 垫片/轴承 | 若干 | 减摩擦、定位 |
B.3 线材与杂项
| 部件 | 说明 |
|---|---|
| 舵机 TTL 总线线 | 串接 15 颗,用屏蔽线防干扰 |
| 供电粗线 | 舵机电源,来自 BMS |
| 扎带/热缩管 | 走线固定 |
B.4 采购分层建议
按预算分三档:
| 套餐 | 内容 | 用途 |
|---|---|---|
| 最小仿真套餐 | 仅 GPU 电脑 | 跑仿真,不需硬件 |
| 半实物套餐 | RK3566 + IMU + 少量舵机 | 验证总线/标定 |
| 完整整机套餐 | 全套 BOM | 整机装配与部署 |
建议先采购【半实物套餐】验证总线通信与标定,再上完整整机,降低一次性投入风险。
B.5 成本核算对比(参考)
| 方案 | 主要成本 |
|---|---|
| 原版 MicroDuck | 399 USD + 转运/关税 |
| 国产飞特整机 | 舵机+板卡+打印+杂项,明显更低 |
国产方案的核心价值是低成本 + 国内供货 + 可控,具体数字因采购渠道浮动,书稿正文以实际采购为准。
故障排查手册
全书故障排查速查,按现象定位。每条给出最可能原因与对应章节。
C.1 仿真侧故障
| 现象 | 可能原因 | 处理 | 章节 |
|---|---|---|---|
| 仿真崩溃/数值爆炸 | MJCF 单位错误 / 惯性非正定 | 检查单位、validate_mjcf.py | Onshape→MJCF 自动化建模 |
| 启动即倒地 | 重心/惯性参数错误 | 复核 CAD→MJCF | Onshape→MJCF 自动化建模 |
| 关节剧烈抖动 | BAM 参数不匹配 | 台架重标定 | BAM 执行器建模与辨识 |
| CUDA 内存不足 | num_envs 过大 | 减小 num_envs | MuJoCo-Warp 仿真环境 |
| 训练不收敛 | 奖励稀疏 / 学习率不当 | 调奖励、降学习率 | PPO 多任务训练 |
| 动作发散 | 缺动作/平滑惩罚 | 加 penalty | PPO 多任务训练 |
C.2 真机侧故障
| 现象 | 可能原因 | 处理 | 章节 |
|---|---|---|---|
| 某舵机无响应 | ID 冲突 | 重配 ID | 硬件电路与 TTL 总线 |
| 总线随机丢包 | 信号干扰 | 降波特率、加隔离 | 硬件电路与 TTL 总线 |
| 上电卡死 | 供电不足/短路 | 分离供电、逐颗排查 | 硬件电路与 TTL 总线 |
| 位置漂移 | 供电电压跌落 | 检查 BMS、线径 | 硬件电路与 TTL 总线 |
| 步态抖动 | BAM 不准/控制环超时 | 重标定/优化推理 | BAM 执行器建模与辨识、策略部署与板端推理 |
| 姿态慢慢歪 | IMU 零偏/安装倾角 | 六面校准/补倾角 | 舵机与 IMU 标定 |
| 经常摔倒 | 观测缩放错位 | check_obs_act_space.py | RK3566 镜像与固件、策略部署与板端推理 |
C.3 Sim2Real 差异排查(优先级)
| 优先级 | 检查项 | 工具 |
|---|---|---|
| 1 | 观测空间一致性 | check_obs_act_space.py |
| 2 | 关节限位对齐 | MJCF vs 硬件 |
| 3 | IMU 零偏/安装 | 六面校准 |
| 4 | BAM 参数精度 | 台架拟合 |
| 5 | 整机质量/重心 | 称重对比 CAD |
原则:一次只改一个变量,每次记录结果,避免多因素同时改导致无法定位。
C.4 机械侧故障
| 现象 | 可能原因 | 处理 | 章节 |
|---|---|---|---|
| 舵盘打滑 | 过盈不足 | 换舵盘/加胶 | 3D 打印、装配与公差 |
| 关节卡死 | 打印干涉 | 修正 CAD 间隙 | HD1910 CAD 模型解析 |
| 重心偏移 | 装配不对称 | 检查左右一致性 | 3D 打印、装配与公差 |
| 打印件断裂 | 壁厚/填充不足 | 加厚、提高填充 | 3D 打印、装配与公差 |
术语表
| 术语 | 全称/解释 | 对应章节 |
|---|---|---|
| Sim2Real | Simulation-to-Real,仿真到现实迁移,核心范式 | 全书 |
| BAM | Bandwidth-Aware Motor,带宽感知舵机执行器模型 | BAM 执行器建模与辨识 |
| MJCF | MuJoCo 机器人建模文件格式 | Onshape→MJCF 自动化建模 |
| PPO | Proximal Policy Optimization,近端策略优化算法 | PPO 多任务训练 |
| Domain Randomization | 域随机化,训练时随机扰动仿真参数 | 域随机化 |
| Curriculum Learning | 课程学习,从易到难推进训练 | 域随机化 |
| ONNX | Open Neural Network Exchange,模型交换格式 | PPO 多任务训练、策略部署与板端推理 |
| MuJoCo-Warp | NVIDIA GPU 并行物理仿真 | MuJoCo-Warp 仿真环境 |
| mjlab | Pollen 自研机器人仿真库 | MuJoCo-Warp 仿真环境 |
| TTL 总线 | 半双工串行通信总线(舵机用) | 硬件电路与 TTL 总线 |
| 齿隙(backlash) | 齿轮间隙造成的滞后 | BAM 执行器建模与辨识 |
| 域随机化强度 | 随机扰动参数的范围大小 | 域随机化 |
| Sim2Real gap | 仿真与现实之间的动力学差距 | 仿真调试与诊断、Sim2Real 闭环迭代 |
| 系统辨识 | System Identification,反向辨识真实参数 | Sim2Real 闭环迭代 |
| RKNN | RK 平台神经网络推理工具 | RK3566 镜像与固件、策略部署与板端推理 |
| BMS | Battery Management System,电池管理系统 | 硬件电路与 TTL 总线 |
| onshape-to-robot | CAD→MJCF 自动导出工具 | Onshape→MJCF 自动化建模 |
| 观测空间 | 策略输入的传感器数据向量 | MuJoCo-Warp 仿真环境、PPO 多任务训练 |
| 动作空间 | 策略输出的控制指令向量 | MuJoCo-Warp 仿真环境、PPO 多任务训练 |
参考文献与项目索引
E.1 开源项目
| 项目 | 地址 |
|---|---|
| Pollen microduck_rl | https://github.com/pollen-robotics/microduck_rl |
| Pollen microduck(固件) | https://github.com/pollen-robotics/microduck |
| Pollen mjlab | https://github.com/pollen-robotics/mjlab |
| fanhao375 microduck-replica | https://github.com/fanhao375/microduck-replica |
| fanhao375 microduck-replica-cad | https://github.com/fanhao375/microduck-replica-cad |
| UnitClaw microduck-wwduck(WWNTRobotics 优化版) | https://github.com/UnitClaw/microduck-wwduck |
| LuwuDynamics xgoduck_hardware | https://github.com/LuwuDynamics/xgoduck_hardware |
| onshape-to-robot | https://github.com/onshape-to-robot/onshape-to-robot |
| NVIDIA Warp | https://github.com/NVIDIA/warp |
E.2 官方与文档
| 内容 | 地址 |
|---|---|
| MicroDuck 产品主页 | https://pollen-robotics.com/microduck/ |
| MicroDuck 预购商店 | https://store.pollen-robotics.com/products/microduck |
| HF 在线仿真 | https://huggingface.co/spaces/pollen-robotics/microduck-simulator |
| onshape-to-robot 文档 | https://onshape-to-robot.readthedocs.io/ |
| Onshape | https://cad.onshape.com/ |
| Warp 文档 | https://nvidia.github.io/warp/ |
| MJCF 文档 | https://mujoco.readthedocs.io/en/latest/modeling.html |
| FreeCAD | https://www.freecadweb.org/ |
| 飞特 HD1910 产品页 | https://www.feetech.cn/500263.html |
| HD1910 XGO-Duck 套件 | https://www.feetech.cn/en/509038.html |
E.3 基础文献(写作引用)
以下为方法论层面的经典文献,需在写作时检索确认具体条目后引用。
- PPO:Schulman 等人,Proximal Policy Optimization Algorithms。
- Domain Randomization:NVIDIA Tobin 等人相关工作。
- BAM 舵机模型:Pollen MicroDuck 相关技术论文 / 技术博客。
- Sim-to-Real 低成本双足:Pollen MicroDuck 技术论文。
写作规范:正式出版时,所有文献需核对 DOI / 卷期页码;书稿正文引用时标注来源,不抹除原作者署名。
E.4 参考资料归档
全书原始资料归档于仓库 book/materials/,按以下子目录分类:
pollen_original/:原版 RL、固件、博客、论文;replica_source/:microduck-replica 源码快照;cad/:CAD 图纸、STEP、onshape 配置;feetech_hd1910/:舵机规格、协议、校准文档;hardware/:RK3566、IMU、电源;framework_docs/:MuJoCo-Warp、mjlab、PPO;scripts/:配套脚本;references/:文献与术语。
说明:部分外部资源无法直接下载打包,归档时给出访问链接 + 获取方法 + 保存要点;HD1910 完整 PDF 规格书与串口协议文档需联系飞特客服索取。
致谢
这本书是一份社区协作的产物。它站在众多开源作者与厂商的肩膀上,没有他们的慷慨分享,就没有这份国产低成本双足机器人的全栈工程实践。在此一一郑重致谢。
关于万物拟态机器人(WWNT Robotics)
本书由 万物拟态机器人(WWNT Robotics,全称「广东省万物拟态机器人有限公司」)编写并维护。
万物拟态机器人是一家专注于具身智能与 AI 机器人教育的企业,坚持「开源驱动、全栈赋能」,双轮驱动:
- 国内:面向高校 AI / 机器人专业做产教融合,提供硬件整机、开源课程、实训室、校园大模型与「校中厂」一站式方案;
- 海外:开拓北美市场,输出机器人本体与关节模组。
公司由创始人叶志青与联合创始人严超磊共同创立,开源生态托管于 GitHub UnitClaw 组织,官网为 wwntai.com(国内)与 wwnt.ai(国际)。
本书正是这套理念的落地之一:把一个海外商业产品的复刻过程,整理成一份国内可复现、低成本的工程书,免费开放给每一位高校师生、实验室工程师与开源硬件爱好者。
致谢
Pollen Robotics
感谢 Pollen Robotics 开源 MicroDuck、mjlab 与 microduck_rl,把 Sim2Real 强化学习双足机器人的完整技术路线公开给社区。本书的机械结构、仿真模型与训练范式均源自他们的开源工作。
需要说明:本项目是 Microduck 的第三方复刻研究,与 Pollen Robotics 无隶属关系,未获其背书。
Hugging Face
感谢 Hugging Face 提供开放平台与机器人生态——MicroDuck 正是其旗下机器人团队 Pollen Robotics 的开源项目,在线仿真(HF Spaces)与相关训练工具链也都依托于 Hugging Face 的开放社区。正是这份开放,让「在云端看机器鸭走路」与「本地复现训练」成为可能。
飞特(Feetech)
感谢 飞特(Feetech) 提供 HD-1910 串口总线舵机硬件与官方技术文档。正是这颗高性价比的国产舵机,让 MicroDuck 有了「便宜一半、力矩 2.5 倍」的国产方案,也让本书的 BAM 台架实测辨识有了真实的标定对象。
fanhao375
感谢 @fanhao375 —— 本项目的原作者。逆向研究、装配图、爆炸图、硬件分析与文档最初都由他完成(原仓库 fanhao375/microduck-replica)。本书与配套仓库都是在他的基础上继续前行。
机械行者Robo
感谢 机械行者Robo —— SolidWorks 图纸、装配 BOM 与装配视频的建模整理者。他让「从零件到会走路」这件事真正变得可上手、可复现。
kissqy
感谢 kissqy —— 飞特 HD-1910 适配(训练中控、IMU 陀螺融合等)的关键贡献者。他的中控受个人非商业条款约束,本书与仓库尊重这一约定,未收录其中控改动。
LuwuDynamics 与 Rhoban
感谢 LuwuDynamics 分享 1910 M6 的 BAM 参数与配套配置,作为本书仿真训练的基线;感谢 Rhoban 开源 BAM 执行器模型与辨识库,为舵机建模提供了理论工具。
所有开源社区开发者
感谢每一位在 GitHub Issue、Pull Request、社区讨论中提供反馈、勘误与建议的开发者。开源的意义,正在于这份「众人拾柴」的协作。
一起共建
这本书和配套仓库都还很年轻,难免有错漏与不足。我们怀着谦逊之心,邀请你一起把它做得更好:
- 发现勘误、表述不清,欢迎提 Issue;
- 有改进、补充,欢迎提 Pull Request;
- 复现成功、踩过坑,欢迎把你的经验回馈给社区。
请尊重各部分的许可边界(代码 Apache-2.0,机械 CAD 与文档 CC BY-NC-SA,详见 NOTICE)。低成本双足机器人的国产开源生态,需要每一个人的参与。 让我们一起,把「让机器人梦想落地」这件事,做得更普惠、更开放。
—— 万物拟态机器人(WWNT Robotics)
版权与免责声明:本书著作权归广东省万物拟态机器人有限公司所有(Copyright © WWNT Robotics)。本书为开源工程实践记录,部分技术资料尚未经过真机充分验证;万物拟态机器人不对照搬失败、财产损失、人身伤害或任何擅自商用引发的侵权纠纷承担任何责任。完整声明详见【前言】之「版权与免责声明」。