本文永久链接 – https://tonybai.com/2026/09/01/microduck-rust-robot-brain-deep-dive
大家好,我是Tony Bai。
【导读】
最近刷屏的机器鸭子 Microduck,是 Hugging Face 旗下 Pollen Robotics 继十万级出货的桌面机器人 Reachy Mini 之后推出的新物种:一只 25 厘米高、不到 800 克重的双足机器人,售价 399 美元,在线开卖后被迅速下单一空,官网预订要等到年底才发货。比起“能不能抢到”,我们更好奇的是它“是怎么造出来的”——控制系统用 Rust 从零手写、没有依赖任何框架,七个守护进程通过 Unix Socket 上的 JSON-RPC 协同工作;而它会走路、会摔倒后自己爬起来、会踢球、会轮滑,靠的是在 MuJoCo 仿真里用 PPO 训练出来的强化学习策略,再通过 sim2real 流程搬到真实硬件上。这篇文章把 Microduck 的软件架构和训练流程拆开揉碎讲清楚。
【文章要点】
- Microduck 是 Pollen Robotics(Hugging Face 旗下机器人公司)继 Reachy Mini 之后的第二款开源机器人,定位“会动的物理 AI”而非“会聊天的桌面助手”。
- 硬件规格:25 cm 高、约 800 g 重、15 个舵机、一颗摄像头、一个深度传感器、两颗 IMU,售价 399 美元(税前),四种配色。
- 控制系统由
robotd、updaterd、configd、btd、padd、mediad、tofd七个守护进程组成,纯 Rust 实现、不依赖任何 Web 框架,统一用 Unix Socket 上的 JSON-RPC 2.0(NDJSON)通信。 - 系统更新走“整体替换 + 健康门禁 + 自动回滚”,设计目标是一次失败的 OTA 也不会把机器人变砖。
- 强化学习训练用 MuJoCo Warp(mjlab)+ PPO,动作器物理模型精细到电压控制律、反电动势、齿轮间隙(backlash),并大量使用 domain randomization 缩小仿真与现实的差距。
- 部署时使用统一的 61 维观测接口,让走路、起身、坐下、踢球、轮滑等多套策略可以在机器人运行时相互热切换。
- 这也是又一个用 Rust 写核心系统的“网红”机器人项目,非常适合作为学习 Rust 系统编程的真实案例。

当机器人不再只是“讲话”
去年,Pollen Robotics 推出了桌面机器人 Reachy Mini:会看、会听、会说话,主打的是人机交互,一年多时间卖出了一万多台。但团队一直在想一个问题——如果一个小机器人的主要工作不是待在桌上陪你聊天,而是要在真实世界里“动起来”,它应该长什么样?
Microduck 就是这个问题的答案。

它是一只 25 厘米高的双足机器人,浑身上下 15 个舵机,配一颗摄像头、一个小型深度传感器、两颗 IMU,还有一个可以用来叼取物体的关节化“鸭嘴”。它能走路、能坐下、能蹲、能在摔倒后从多数常见姿势里自己站起来,甚至还能轮滑。
整机不到 800 克,能放进一只手心,官网定价 399 美元(税前运费另计),首批发货目标是 2026 年圣诞节前,覆盖北美、欧洲和英国。
Pollen 官方把 Reachy Mini 和 Microduck 的关系总结得很直接:
- Reachy Mini 是“会交互的 AI”平台,围绕视觉、语音、表达设计;
- Microduck 是“会行动的 AI”平台,核心问题变成了——怎么在仿真里训练一个行为,把它搬到真实硬件上,观察哪里出了问题,再重新来一遍。
两者共享同一套哲学:第一次开机就要好玩,写第一行代码就要顺手,项目做深了又能撑起严肃的开发工作。
为什么要做得这么小?答案很朴素:学习“动作”这件事本身就很“糟糕”——机器人必须不断尝试、摔倒、再尝试。在一台大型人形机器人上,每一次失败的尝试都可能很贵、很难复位,甚至有安全风险。
而把机器人做小做轻之后,一次失败的行为通常只是“一只小鸭子躺在地板上”,而不是一次事故;再加上能自己爬起来,你甚至不用每次实验后都弯腰去捡它。小尺寸同时也把价格和上手门槛拉了下来——学习双足运动这件事,不再需要买一台昂贵的科研平台,或者蹭一间专门的实验室。
麻雀虽小,五脏俱全:一个纯 Rust、零框架的控制系统
如果说训练策略是 Microduck 的“灵魂”,那么装在瑞芯微Rockchip RK3566 上的这套控制系统就是它的“神经中枢”。这部分代码全部用Rust写成,而且刻意不依赖任何应用框架——这在动辄用 ROS 堆出来的机器人软件栈里,是一个相当“硬核”的工程选择。
官方仓库的架构文档把整个系统总结成一句话:一块板子上跑七个守护进程,通过 Unix Socket 通信。其中一个真正驱动机器人,另外三个的存在就是为了在第一个崩溃时,板子依然可以被够到;剩下的是纯粹的传输层和传感器,不拥有任何状态。

七个守护进程各司其职,分工非常明确:
| 守护进程 | 负责什么 | 备注 |
|---|---|---|
robotd |
电机控制、运动学、里程计、步态策略、传感、安全 | 唯一能碰电机的进程,50 Hz 控制环 |
configd |
WiFi、机器人身份、手柄配对、重启 | robotd 挂了也必须能用,否则联网配置都进不去 |
updaterd |
发布包校验、安装、切换、健康门禁、回滚 | 整个系统里最先被开发的模块 |
btd |
蓝牙 GATT 透传,暴露 API 的一个子集 | 不拥有任何状态,纯传输适配器 |
padd |
读取手柄输入,转发同样的意图指令 | 同样不拥有状态 |
mediad |
摄像头/麦克风、编码、感知推理、WebRTC | 最重的服务,也是远程访问的"前门" |
tofd |
头部 8×8 深度传感器 | 只发布数据、不读任何人的数据 |
有几条设计原则值得展开讲:
只有 robotd 能碰电机。 15 个舵机和 IMU 共享一条串口总线,50 Hz 的控制环独占这条总线。任何客户端发过来的都是“意图”(intent)——“往这个方向走这么快”、“看那边”、“站起来”——真正决定这个意图能不能被执行、怎么被安全地执行,是 robotd 内部的安全层说了算。系统里没有任何一条路径能绕过它直接下发电机指令。
三个进程必须在 robotd 挂掉之后还能活着。 configd、updaterd、btd 对 robotd 没有 systemd 依赖,不带任何机器学习运行时,也不带媒体栈——因为它们就是“急救通道”:一台控制环起不来的机器人,恰恰就是最需要被重新配置、更新或回滚的那台机器人。这也是为什么 WiFi 配置放在 configd 而不是 robotd 里——配网正是机器人出问题时用户最需要的操作。
发布是“整体替换”,不是“打补丁”。 一次构建会作为完整目录落到 /opt/robot/daemon/releases/<版本号>/ 下,updaterd 校验签名、把 current 这个符号链接指向新版本、重启对应的 systemd 单元,然后主动去问 robotd “你健康吗”。答案是否定的话,它会自己把旧版本换回去;如果连这一步都失控进入了重启死循环,还有一个启动计数器兜底。

通信协议的选择也很“Rust 味”。 官方文档里罗列了一张对比表,从 jsonrpsee、varlink、zbus(D-Bus)、axum(HTTP/WS)、tarpc 一路对比到 tonic(gRPC),最后选定的是 Unix Socket 上的 JSON-RPC 2.0,一行一个 JSON 对象(NDJSON),用 tokio_util::codec::LinesCodec 做分帧,消息类型就是普通的 serde 结构体。理由很实际:
- 文件系统权限本身就是免费的访问控制——一个 0660 权限、专属用户组的 socket,天然只有被允许的进程能碰;而 TCP 端口默认对整台机器上的所有进程和用户开放,想做到同等安全级别还得再搭一层鉴权。
SO_PEERCRED能拿到调用方的 uid/gid/pid,一是用于审计日志(“谁触发了这次回滚”永远是支持团队问的第一句话),二是用于权限判断。- “监听错误的网卡”这一类 bug 从物理上不存在了——用 TCP 的话,一次
0.0.0.0的手滑配置,就可能把固件更新的控制权限暴露到公网上;用 Unix Socket,这种失误根本无法表达。 - 同一套消息类型后续还要跑在 BLE 和 WebRTC 数据通道上,纯
serde结构体可以直接复用,而 D-Bus 的类型系统做不到这一点。
这套“控制平面用 tokio 异步等待、CPU 密集型任务丢进 spawn_blocking”的取舍,也是 Rust 系统编程里的一个经典范式:签名校验、zstd/tar 解压、递归删除这些在树莓派级别硬件上要跑几秒的操作,如果留在异步 worker 上会直接把 IPC 任务卡住,导致 status/subscribe 这些查询在更新过程中失去响应。
从“摔倒”到“站起来”:一只鸭子是怎么在仿真里学会走路的
如果说 Rust 写的控制系统负责“执行”,那真正让 Microduck “会动”的,是另一个独立仓库 microduck_rl 里跑的强化学习流程。

训练框架是 mjlab(基于 MuJoCo Warp 的物理仿真 + rsl_rl),算法是 PPO。策略在仿真里以 50 Hz 频率训练,导出成 ONNX 格式,最终由前面提到的 robotd 在真实机器人上加载运行。整条 sim2real 链路可以画成这样:

有几个细节能看出这个团队在 sim2real 上确实下了功夫:
电机模型精细到“电压控制律”级别。
所有任务用的都是 BAM 项目提供的 M6 动作器模型,专门针对 Microduck 使用的 Dynamixel XL330 舵机,把电压控制律、反电动势、库仑摩擦/Stribeck 摩擦、负载相关摩擦都建了模,并对电池电压、负载下的电压跌落、指令延迟、摩擦系数大小做逐环境的域随机化。官方给出的理由很直白:在这个尺度上(小舵机驱动一只不到 800 克的双足机器人),动作器的精度决定了仿真与现实之间差距的大部分——所以宁可牺牲仿真速度,也要把理想 PD 控制器换成真实的电压控制律。
连齿轮间隙都被仿真出来了。
每一个主任务都有一个 Backlash 版本的孪生任务,在仿真模型的 14 个舵机关节上串联 ±1°(共 2°)的齿轮空转间隙。这个间隙被建模成一个不受驱动的 passive_<joint>_backlash 铰链;因为真实编码器装在传动链的输出端,也就是间隙的“下游”,所以固件的 PD 模拟(BacklashEncoderBamActuator)和 joint_pos/joint_vel 观测都要“穿过”这个间隙去读数(qpos[伺服] + qpos[间隙])。观测和动作维度完全不变,这意味着 ONNX 导出和真机运行时代码都不需要为此做任何改动——这是一处很典型的“仿真复杂度增加,但部署接口保持稳定”的工程设计。
一套观测接口,服务十几种行为。 目前训练环境里注册了十几个任务:
| 任务系列 | 说明 |
|---|---|
Velocity(走/Flat·Rough) |
主任务:速度指令 + 头部姿态指令下的行走 |
VelStand |
走路 + 摔倒恢复合并在同一个策略里 |
StandUp |
从趴下/仰面/坐姿站起,并保持站立与身体姿态可控 |
SitStand |
坐下/站起指令控制,动作柔和,头部可控 |
GroundPick |
蹲下用嘴尖碰地,再回到站立 |
BallKick |
向前踢一颗 70mm/15g 的球(策略本身"看不见"球) |
Roulade |
前滚翻,落地时用脚站住 |
Rollers/Swizzle/Spin 等轮滑系列 |
脚下装被动轮子后的花式动作,包括经典的对称滑步和原地快速旋转 |
这些策略共享同一套 61 维观测:48 维本体感知信息,加上速度、头部姿态(4 维)、身体姿态(6 维)三类指令。
正是这个统一接口,让运行时可以在机器人开机运行的过程中“热切换”策略——走路策略、起身策略、坐立策略、前滚翻策略互不冲突,可以在同一个观测/动作契约下随时互相接管。microduck_rl 仓库里的 infer_policy.py 就是这套热切换逻辑的最小复现,用键盘就能在同一次运行里切换走路、起身、坐立、前滚翻和踢球动作。
“网红”背后:为什么值得学 Rust
Microduck 的爆火,某种程度上又验证了一个越来越明显的趋势——这一代“叫好又叫座”的开源硬件/机器人项目,底层控制系统正在越来越多地选择 Rust。原因并不复杂:
- 需要在资源有限的嵌入式板子(这里是 Rockchip RK3566)上跑一个 50 Hz 的实时控制环,内存安全和无 GC 停顿是硬指标;
- 需要同时管理多个异步 IO(Socket、串口、D-Bus、WebRTC)与少量 CPU 密集任务,
tokio的异步生态刚好能把“哪里该等、哪里该算”这件事表达清楚; - 系统关乎安全(走路机器人、可控电机),Rust 的类型系统能在编译期挡掉一整类“忘记检查边界”、“悬垂指针”式的错误;
- 团队甚至可以做到“不用任何 Web 框架”,纯手写七个进程加一套 JSON-RPC 协议,代码量和依赖数都可控——这也是文档里那张“依赖数量对比表”想说明的事:30 个依赖能撑起一整套跨蓝牙、跨 WebRTC、跨 Unix Socket 复用的通信协议,而不是随手拉一个大框架进来。
如果你也想搞懂“为什么一个机器人团队宁愿手写 JSON-RPC 也不用现成框架”、“异步和同步任务该怎么拆”、“Unix Socket 权限模型是怎么替代应用层鉴权的”——这些恰恰是系统级 Rust 编程要解决的核心问题。这也是我在做《Rust 第一课》这门专栏时反复强调的东西:Rust 真正的价值不在语法多新潮,而在于它能撑起 Microduck 这种“跑在真实硬件上、不能随便崩、还要能远程升级”的严肃系统。感兴趣的话,欢迎找我聊聊《Rust 第一课》。
写在最后

一只机器鸭子能火,表面上是因为它足够可爱、足够便宜、放在桌上不违和;但真正支撑它“好玩又能打”的,是背后两套扎实的工程体系——一套是纯 Rust、零框架、以可靠性为第一目标的机器人控制系统,另一套是从电机物理特性到齿轮间隙都不放过的强化学习 sim2real 流水线。
Pollen 官方也说得很清楚:现在随机器人出厂的这些行为,并不是它能做的全部,而只是一个起点,后面的花样要靠社区一起往上叠。
如果你想亲自上手,可以直接去 Hugging Face Space 上的在线仿真器里试驾一把,或者去 GitHub 把两个仓库都克隆下来看代码;如果你更想搞懂“这只鸭子的大脑到底是怎么用 Rust 写出来的”,欢迎从《Rust 第一课》开始。
相关链接
- 官方博客《Meet Microduck》:https://pollen-robotics.com/microduck/blog/introducing-microduck/
- 在线仿真器(Hugging Face Space):https://huggingface.co/spaces/pollen-robotics/microduck-simulator
- 主仓库(机器人运行时,Rust):https://github.com/pollen-robotics/microduck
- 强化学习训练仓库(Python + mjlab):https://github.com/pollen-robotics/microduck_rl
- 预购页面:https://pollen-robotics.com/microduck
还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 《从0 开始构建 Agent Harness》 将带你:
- 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
- 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
- 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
- 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
- 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”
扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。

「Go & AI 精进营」已全面升级为「Go, Rust & AI 精进营」知识星球,快来加入星球,开启你的技术跃迁之旅吧!
我们致力于打造一个高品质的 现代系统级开发(Go / Rust) 与 前沿 Agentic AI 工程实践 平台。在这里,你将获得:
- 体系化 Go 核心进阶内容: 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏,夯实你的 Go 语言内功。
- 硬核 Rust 专项实战赋能: 同步解锁全年 54 讲独家专栏「事不过三:Rust 系统级入门实战课」,通过 4 个里程碑项目(命令行工具、KV引擎、多线程Web服务、异步Redis),带你彻底攻克所有权与并发高山,拿下 Rust 核心壁垒。
- 前沿 Agentic AI 落地实践: 紧跟时代步伐,系统学习「Agent开发实战课」、「Agentic软件工程课」、「Claude Code开发工作流实战」、「Harness工程设计」等,掌握 AI 时代的系统架构新技能。
- 星主 Tony Bai 亲自答疑: 遇到疑难杂症?星主第一时间为你深度解析,扫清 Go、Rust 与 AI 实践中的学习与工程障碍。
- 高活跃 Gopher & Rustacean 交流圈: 与众多优秀的技术极客探讨系统设计、分享前沿心得、碰撞思想火花。
- 独家资源与专栏首发: 博客深度长文、专栏教程更新、精选技术资源,星球会员第一时间触达,加入星球即可免费阅读全套进阶专栏!
衷心希望「Go, Rust & AI 精进营」能成为你拓宽技术边界、持续精进与交流的温暖港湾。让我们在此相聚,享受代码与工程之美以及技术精进的快乐!欢迎你的加入!

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。
