06-如何做自己的microduck:从硬件选型到第一行代码的完整路线图
引子:分析完了,动手!
大家好,我是黒漂技术佬。
前五篇文章,我们把 microduck 这只 25 厘米小鸭子的技术细节拆了个底朝天:架构、控制环、进程通信、OTA、sim2real。分析别人的作品很爽,但真正的收获,永远是"自己做一个"。
今天开始系列二的第一篇(也是本系列目前规划里的一篇重磅收尾):如何做自己的 microduck。
先泼一盆冷水,也是实话:你大概率不会真的做出一个和 microduck 一模一样的鸭子。 15 个 Dynamixel 舵机 + RK3566 板卡 + 定制的结构件 + MuJoCo 仿真训练,全套下来成本轻松破千甚至几千元,而且 3D 打印结构、舵机调参、RL 训练的门槛都不低。
但这不意味着这件事不值得做。恰恰相反,做一个"丐版 microduck" 的收益极高:
- 你可以用几百元预算、手头现有的板子(树莓派、RK 板、甚至 ESP32 也行),复刻它的软件架构思想;
- 你可以不搞 RL,先用手写步态(或者说"机械步态")跑通整个链路,RL 是后话;
- 你收获的不是一只鸭子,而是一套完整的"单板机器人软件工程"能力——这玩意在面试、在项目中都值钱。
这篇文章就是你的施工蓝图。我会按照"硬件 → 系统 → 软件骨架 → 控制 → 进阶(RL)"的顺序,给你一条从零到一的路线图,每一阶段都标注清楚:要买什么、要写什么、会遇到什么坑。
一、路线图总览:五个阶段
先看全貌,再逐段拆解:
阶段一:硬件选型 选主控、舵机、传感器、结构 (约 500~1500 元)
阶段二:系统底座 装 Linux、配开发环境 (半天)
阶段三:舵机控制 打通总线,让舵机动起来 (1~2 天)
阶段四:控制环骨架 实现自己的 50Hz 控制环 (2~3 天)
阶段五:进阶玩法 手写步态 → 仿真 RL → OTA (按需投入)
关键原则:先用最便宜的方式跑通最小闭环,再逐步升级。 千万别一上来就买齐 15 个高级舵机 + 3D 打印机 + GPU 服务器——那是把"学习项目"做成了"创业项目"。
二、阶段一:硬件选型(丐版 vs 完整版)
2.1 主控(大脑)
microduck 用的是瑞芯微 RK3566。选择理由很典型:四核 A55 + 0.8 TOPS NPU + 支持 MPP 硬解码 + 价格便宜(核心板一百多元),是嵌入式 AI 视觉机器人的性价比之王。
你的选择:
| 方案 | 主控 | 适合场景 | 成本 |
|---|---|---|---|
| 丐版 | 树莓派 Zero 2W / 4B | 快速上手、生态好、资料多 | 100~300 元 |
| 主流 | RK3566 核心板(如香橙派 3B、Radxa Zero 3W) | 对标 microduck,有 NPU 可玩视觉 | 200~400 元 |
| 进阶 | RK3588 | 算力强(6 TOPS NPU),但价格上浮 | 600+ 元 |
我的建议:入门首选树莓派(社区资料最全,能少踩一半的坑);想对标 microduck 且后续要跑视觉/RL 端侧推理,选 RK3566 方案。
顺带一提:microduck 的文档里透露他们用的是 Radxa Zero 3W(一款 RK3566 小板的调试记录)。你想复刻,可以直接抄这个作业。
2.2 舵机(肌肉)
这是整个项目最烧钱的部分,也是决定成败的部分。
microduck 用的是 Dynamixel(ROBOTIS 出品)——串行总线舵机,15 个串联在一条 UART 上。它的优势:位置/速度/力矩控制精度高、可回读角度、串联方便、菊花链拓扑省线。
但 Dynamixel 的价格劝退很多人——一个 XL330 就要一百多元,15 个就是两千多。
丐版替代方案:
| 方案 | 舵机 | 优点 | 缺点 |
|---|---|---|---|
| 总线舵机(国产) | 乐迪/LX-16A、飞特 STS3215 等 | 价格低(几十元/个)、串行总线、可回读 | 精度/耐用性略逊 Dynamixel |
| PWM 舵机 | SG90/MG996R(航模舵机) | 几元到十几元一个,极其便宜 | 只能发角度、不能回读位置、精度差 |
| Dynamixel 正品 | XL330 系列 | 官方同款、精度高、生态好 | 贵 |
我的建议:预算允许就上国产总线舵机(STS3215 这类)——可回读位置是控制环的刚需。PWM 舵机不能回读,意味着你的控制环只能"开环"(发指令就认为执行到位),精度和鲁棒性都会差一截,但作为入门验证够用。
注意一个架构层面的约束:总线舵机 + IMU 共享一条 UART 是 microduck 控制环设计的前提(第 02 篇讲过)。选舵机时,优先选支持串口总线的,这样你能完整复刻它的"单总线 + 独占"设计。
2.3 传感器(感官)
- IMU(惯性测量单元):MPU6050(十几元)或 ICM-20948,用于姿态感知——这是平衡控制的关键传感器;
- 距离/深度(可选):VL53L5CX ToF 传感器(microduck 同款,8×8 深度矩阵),用于避障/交互;
- 摄像头(可选):树莓派/RK 板都有现成 Camera 模块,后续做视觉识别用。
2.4 结构(骨架)
microduck 是 25cm 双足。自己做的话:
- 丐版:用铝型材 + 舵机支架搭一个简易双足(很多舵机厂家出配套支架),或者直接用3D 打印(如果你有打印机);
- 进阶:下载 microduck 的模型文件,用 3D 打印复刻它的结构(项目开源,模型应该可以拿到);
- 简化版思路:先做单腿站立/单关节的验证机,比如"一只会摆动的机械腿",把总线控制跑通,再考虑完整双足。
2.5 供电
这是新手最容易翻车的环节,单独立一条警告:
多个舵机同时大扭矩动作时,瞬间电流很大,USB 口供电必死,电池电压会瞬间跌落导致主控重启。
- 电池:2S/3S 锂电池或 7.4V 航模电池;
- 电调/稳压:舵机总线要稳定的电压(Dynamixel 要求 7.4V 左右),主控要 5V——必须做电压分离,舵机电源和主控电源分开;
- 大电容:舵机电源端并一个大电容(1000µF+),吸收瞬间电流冲击。
三、阶段二:系统底座(半天)
硬件到齐后,先把"大脑"跑起来:
# 1. 烧系统(以 RK3566 为例,树莓派类似)
# 用官方工具把 Armbian 或 Debian 镜像烧到 TF 卡/SD 卡
# 2. 串口登录,配网,SSH
# 这一步正好可以用我们前几篇文章讲过的 Dropbear:
# Armbian 系统自带 OpenSSH,如果你用的是自建 rootfs,就装 dropbear
# 3. 安装 Rust 工具链(板子上直接装,或者交叉编译)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc --version
开发方式决策:小项目直接在板子上编译(A55 编 Rust 项目几秒钟到几十秒,能接受);项目大了就交叉编译(PC 上配 aarch64-linux-gnu 工具链)。
四、阶段三:舵机控制(1~2 天)
这是第一个"里程碑":让 15 个舵机中的一个动起来。
如果你用的是 Dynamixel 或国产串行总线舵机,控制协议类似:通过串口发送指令帧。
4.1 打开串口
# 查看串口设备(USB 转串口或板载 UART)
ls /dev/ttyUSB0 /dev/ttyS0
# 测试串口能否正常打开(用 Python 或直接 cat)
python3 -c "import serial; s=serial.Serial('/dev/ttyUSB0', 1000000); print('OK')"
4.2 发一个舵机指令
以 Dynamixel 协议为例(Protocol 2.0),让 ID=1 的舵机转到 512(中位):
import serial, struct
s = serial.Serial('/dev/ttyUSB0', 1000000, timeout=0.1)
# Dynamixel Protocol 2.0 写指令帧:
# 包头(FF FF) + 舵机ID + 长度 + 指令(0x03=Write) + 地址 + 数据 + 校验和
def dxl_write(servo_id, addr, data):
length = 3 + len(data) # 指令(1) + 地址(2) + 数据(n)
packet = b'\xff\xff' + bytes([servo_id, length, 0x03, addr & 0xff, addr >> 8]) + data
packet += bytes([(sum(packet[2:]) & 0xff) ^ 0xff]) # 校验和
s.write(packet)
# 设置舵机目标位置(地址 116,32 位),转到 2048(0 度附近)
dxl_write(1, 116, struct.pack('<I', 2048))
验证:舵机转到对应角度,说明总线打通了。
注意几个坑:
- 波特率:Dynamixel 默认 57600 或 1Mbps,要和舵机配置一致;
- ID:新舵机默认 ID 都可能是 1,多个舵机前要挨个改 ID;
- 地线:总线舵机必须共地,电源负极、主控 GND、舵机 GND 要连在一起,否则通信会随机失败;
- 方向:USB 转串口模块要支持 TTL 电平且能处理舵机的半双工应答(有些需要外加电平转换/方向控制电路)。
五、阶段四:控制环骨架(2~3 天)
舵机能动之后,进入真正的"工程"阶段——实现一个 50Hz 控制环。
5.1 最小控制环(Rust 示例)
核心就是那个 20ms 的循环,我们用 Rust 的 tokio + 串口库实现一个骨架:
use std::time::{Duration, Instant};
use tokio::time::sleep;
// 一次"读状态→算动作→写舵机"的周期
async fn control_tick() {
// ① 读 15 个舵机角度 + IMU 姿态(串口总线读取)
let angles = read_servos().await;
let imu = read_imu().await;
// ② 状态估计:用最新样本更新姿态/里程计
let state = estimate_state(&angles, &imu);
// ③ 策略推理:查表 or 神经网络(这里先用简单的目标角度)
let targets = compute_targets(&state);
// ④ 安全校验:关节限位、姿态异常
let targets = safety_check(&state, targets);
// ⑤ 下发 15 个舵机目标角度
write_servos(&targets).await;
}
#[tokio::main]
async fn main() {
loop {
let start = Instant::now();
control_tick().await;
// ⑥ 计时:如果提前完成,睡到 20ms 边界
let elapsed = start.elapsed();
if elapsed < Duration::from_millis(20) {
sleep(Duration::from_millis(20) - elapsed).await;
}
// 如果超了 20ms,也继续跑(记录超时次数,别让循环停摆)
}
}
这个骨架已经包含了 microduck 控制环的四个核心要素:
- 固定周期(50Hz 的 sleep 到边界);
- 读-算-写流水线;
- 安全校验层(第 ④ 步);
- 不阻塞(全是异步调用,没有
thread::sleep卡死)。
5.2 让鸭子站起来:手写步态(可选但强烈推荐)
RL 是后话,先用最朴素的方式让机器人动起来,能极大增强信心:
- 姿态平衡(PID):读 IMU 的俯仰角,用 PID 控制器输出髋/踝关节修正——让机器人"站住";
- 简易步态:左右腿交替抬脚 + 重心转移。先别追求优雅,能"挪动"就是胜利;
- 这个阶段你会真切体会到第 02 篇说的那些设计(控制频率、总线时序、安全限位)为什么是刚需。
六、阶段五:进阶玩法(按需投入)
基础跑通后,你有三条进阶路径,按兴趣选:
路径 A:仿真 RL(对标 microduck 的完整路线)
- 建 URDF 模型:用 Fusion 360/SolidWorks 导出机器人几何,或直接找 microduck 的模型;
- MuJoCo 仿真:Python + mujoco 库,加载 URDF,验证动力学;
- PPO 训练:用 microduck_rl 项目(开源)的代码作为起点,或参考 RL 教程搭一个 gymnasium 环境;
- 域随机化 + 奖励设计:抄第 05 篇的作业——摩擦随机、舵机延迟随机、平滑惩罚;
- ONNX 导出 + 端侧部署:PyTorch → ONNX → Rust 加载,接进你的 50Hz 控制环。
这条路径的终点就是"你自己的 microduck"。需要一台带 GPU 的电脑(哪怕是云 GPU)。
路径 B:视觉 + 自主行为
- 用 RK3566 的 NPU 跑鸭子检测器(microduck 的 npu-bringup 文档里正好有);
- 摄像头采集 → 目标检测 → 生成行为意图 → 发给控制环。这正好用上你做视觉的经验。
路径 C:OTA + 遥控(工程化)
- 抄第 04 篇的 updaterd:签名验证 + 版本切换 + 健康门控;
- 加 WebRTC 远程视频(第 03 篇的 mediad 思路);
- 做手机 App / 手柄遥控——把"玩具"做成"产品"。
七、常见坑速查表(自制 microduck 版)
| 坑 | 现象 | 解决 |
|---|---|---|
| USB 供电不足 | 舵机一动,主控重启 | 电池供电 + 电压分离 + 大电容 |
| 串口乱码/通信失败 | 指令发出去没反应 | 检查波特率、共地、TTL 电平、半双工方向 |
| 舵机 ID 冲突 | 发指令所有舵机一起动 | 逐个改 ID,别让默认 ID 撞车 |
| 控制环卡顿导致抖动 | 机器人抽搐 | 检查是不是有阻塞调用;把日志/网络操作移出控制环 |
| 一走路就摔 | 步态参数没调好 | 先做姿态平衡(PID),再谈走路;降低重心、放慢步频 |
| RL 训练很久不收敛 | 奖励太稀疏 | 加密集中间奖励、加平滑惩罚、加域随机化 |
| 舵机过热 | 长时间大扭矩 | 检查负载、降低速度限制、加强散热 |
| 电池掉电快 | 续航短 | 这是双足机器人的宿命,多备电池 |
八、总结
"做自己的 microduck"这件事,核心不是复刻一个鸭子,而是跑通一条完整的嵌入式机器人开发链路:
- 硬件:主控(树莓派/RK3566)+ 总线舵机 + IMU + 独立供电——先用丐版跑通,再升级;
- 系统:Linux 底座 + Rust 工具链,一个最小开发环境;
- 舵机:打通串行总线,让一个舵机动起来——这是第一个里程碑;
- 控制环:实现 50Hz 的"读-算-写"骨架,加上安全校验——这是你的 robotd;
- 进阶:手写步态 → 仿真 RL → OTA 遥控,按兴趣和预算选择。
最后送你一句我的真心话:这条路我走过,最大的教训是——别追求一步到位,先把"最小闭环"跑起来。 一个只能摆动一条腿的"半只鸭子",比一份画在纸上的"完整鸭子设计图"有价值一百倍。因为前者让你真正理解控制环、理解总线时序、理解嵌入式实时系统的血与肉;后者只是让你觉得自己懂了。
从一只舵机开始,慢慢来。
我是黒漂技术佬,咱们下篇见。