在 Windows 上复现 Microduck 机器鸭仿真

上面这段就是最终效果:官方 ONNX 策略驱动下的 Microduck,在 MuJoCo 棋盘场景里行走。下面记录从零到复现的完整过程。
目录
一、机器鸭是什么,为什么值得复现
Microduck 是 Hugging Face 与 Pollen Robotics 在 2026 年 8 月联合开源的桌面级双足机器人:25 cm 高、约 800 g、15 个舵机、50 Hz 控制循环,售价 399 美元。会走路、会轮滑、能用喙叼东西、会踢球、摔倒还能自己爬起来。
它的价值不在硬件,而在整套强化学习训练栈是开源且可复现的:
| 组件 | 说明 |
|---|---|
| 训练框架 | mjlab(MuJoCo Warp GPU 后端)+ rsl_rl(PPO 实现) |
| 物理引擎 | MuJoCo 3.10 + mujoco-warp 3.8.1 |
| 执行器建模 | BAM M6 模型,仿真真实的 Dynamixel XL330 舵机(含电压控制律与摩擦) |
| 策略资产 | 10 个官方 ONNX 策略,总共只有 6.8 MB |
| 许可 | 代码 Apache-2.0;3D 模型为 CC BY-SA-NC,非商用 |
关键前提:它的文档假设你用的是 Linux
这是整篇文章存在的理由。仓库里的推理脚本 scripts/infer_policy.py 直接 import termios / import tty------两个 Linux 专属模块。官方 README 也默认你在 Linux 或 macOS 上工作。
所以「Windows 复现」这件事,本质上不是把命令抄一遍,而是把三类 Linux 假设逐个拆掉:终端 I/O、缓存路径、GPU wheel 选择。
二、先选路线,再动手
同一个仓库,两条用途完全不同的路线:
| 路线 A:跑推理 | 路线 B:自己训练 | |
|---|---|---|
| 目的 | 加载官方 ONNX 策略,键盘操控 | 从零训练新的步态 / 技能 |
| 命令 | python scripts/infer_policy.py |
uv run train Mjlab-Velocity-Flat-MicroDuck |
| GPU 需求 | 不需要(CPU 即可) | 需要 CUDA,或走云端 --hf-jobs |
| 磁盘占用 | 约 5 GB | 约 5 GB 起(训练日志另算) |
两者用的是同一个环境、同一个仓库,区别只在执行哪条命令。本文只覆盖路线 A。
存储对比:Microduck 这条路约 5 GB;而 NVIDIA 自家的 Isaac Sim / Isaac Lab 路线,安装包 + Omniverse Kit + 资产缓存需要 50~100 GB,官方还推荐 RTX 4080 级显卡。对个人开发者来说,Microduck 是门槛低一个数量级的选择。
三、五步走完复现流程

Step 1 · 克隆仓库
bash
git clone --depth 1 https://github.com/pollen-robotics/microduck_rl.git
仓库不大(234 个文件,几十 MB),但第一次就会卡住------见坑 2。
Step 2 · 创建 conda 环境
bash
conda create -n microduck python=3.12 -y
这里必须加 --solver classic,原因见坑 1:
bash
conda create -n microduck python=3.12 -y --solver classic
注意:项目要求 Python
<3.13,3.12 是稳妥选择。
Step 3 · 安装依赖
项目用 uv 锁版本(仓库里有 uv.lock),所以要让 uv 装进我们刚建的 conda 环境,而不是自己新建一个 venv:
bash
cd microduck_rl
export UV_PROJECT_ENVIRONMENT=/path/to/conda/envs/microduck
uv sync
国内网络建议加上镜像源与超时:
bash
export UV_DEFAULT_INDEX=https://mirrors.aliyun.com/pypi/simple/
export UV_HTTP_TIMEOUT=600
装完共 124 个包 ,其中核心的:mjlab 1.3.0、mujoco 3.10.0、mujoco-warp 3.8.1、bam 1.0.1、onnxruntime、torch 2.9.1。
中间
uv要从 GitHub 拉一个 git 依赖(BAM 舵机模型库),这一步也是坑 2 的重灾区。
Step 4 · 打 Windows 兼容补丁
原脚本的键盘输入用的是 POSIX 的 cbreak 模式:
python
import select, termios, tty # ← Windows 上直接 ImportError
修复思路很直接:保留原实现,另写一个 Windows 版本,按平台选择。
键盘输入被封装成独立类,所以改动是局部的------新增一个 TerminalInputWindows,用 msvcrt.kbhit() / msvcrt.getwch() 实现同样的「非阻塞读键 + 按键规范化」接口,然后:
python
TerminalInput = TerminalInputWindows if os.name == "nt" else TerminalInputPosix
接口不变、实现分流,这样 POSIX 逻辑一行没动,Windows 上也能用。
Step 5 · 下载官方策略
官方策略托管在 Hugging Face 的 pollen-robotics/microduck-policies 仓库,10 个文件:
text
alpha_walking.onnx alpha_stand.onnx alpha_sitstand.onnx
alpha_ground_pick.onnx ball_kick_left.onnx ball_kick_right.onnx
roulade.onnx roller.onnx roller_crouch.onnx
manifest.json
总共只有 6.8 MB(每个约 800 KB)。
huggingface_hub 的下载器在受限环境下容易失败(坑 4),最简单的绕法是用 hf-mirror 直链:
bash
curl -L -o alpha_walking.onnx \
https://hf-mirror.com/pollen-robotics/microduck-policies/resolve/main/alpha_walking.onnx
八个坑速查
上面五步里,有八处会让你停下来查资料。逐个列出,方便对号入座:

四、把鸭子玩起来
双击 play_official.bat

启动后会弹出 MuJoCo 仿真窗口。先用鼠标点一下 3D 窗口,再按键------终端和 3D 窗口都能接收按键,但点 3D 窗口最省事(不会输入法干扰)。
三种模式
- 速度模式(默认):方向键控制前后与横移,A/E 转向,空格一键停下,T 暂停推理,P 随机推它一把
- 技能触发键:G 叼东西、Y 坐站、K/L 踢球、R 前滚翻(后两者会自动切回原策略)
- 调试模式:按 B 或 H 进入身体姿态 / 头部微调
关于「按 G 画面变暗」
这不是 bug,是按键冲突:MuJoCo viewer 自带一整套渲染快捷键,字母键几乎被占满------G 是雾效、K/L 是天空盒与叠加混合、R 是反射、T 是半透明、H 是凸包、B 是扰动力。
而且这套内置绑定无法关闭 ,key_callback 拿到按键的同时 viewer 自己也会执行。真正的修法是快照 + 回滚:
- 启动时把渲染状态快照下来(正确的位置是
viewer.scn.flags和viewer.opt.flags两个数组,而不是model.vis------后者是 C++ 结构体,写不回去) - 每次按键回调结束后,把这两个数组还原成快照值
这样你的按键照常控制鸭子,viewer 顺带改掉的画面效果会被立刻撤销。
看懂运行日志
程序每秒打印一次速度对比:
text
[vel 1s avg] achieved/cmd fwd=+0.11/+0.30 lat=+0.02/+0.00 m/s yaw=-0.19/+0.00 rad/s trunk_z=120.1 mm
| 字段 | 含义 |
|---|---|
fwd |
前后速度:实测 / 指令 |
lat |
横向速度 |
yaw |
转向角速度(正 = 左转) |
trunk_z |
躯干离地高度,最关键的"健康指标" |
trunk_z 站立时约 116 mm。如果它掉到 60 mm 以下并稳定保持,说明鸭子摔趴了;缓慢下降则是要跌倒的前兆。
本文基于一次真实的 Windows 复现过程整理,所有命令与报错均为实测。