ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Microduck开源双足机器鸭:树莓派+舵机千元内DIY步态控制实战

Microduck开源双足机器鸭:树莓派+舵机千元内DIY步态控制实战

1. 这只鸭子凭什么火出圈

第一次刷到 Microduck 的演示视频时,我盯着屏幕看了三遍。一只用 3D 打印件、舵机和树莓派拼出来的双足机器鸭,摇摇晃晃地在地上走,遇到障碍会自己调整重心,用蓝牙手柄一推摇杆还能原地转圈。评论区一堆人问“这玩意儿能上街遛吗”,我当时的反应是:能,但得先把几个坑填了。

Microduck 是一个完全开源的桌面级双足机器人项目,核心定位是“低成本、可复现、可扩展”。它不像那些动辄上万的科研级双足平台,而是把物料成本压到了千元以内,用最常见的树莓派作为主控,配合舵机驱动板和 3D 打印结构件,让任何一个有基础动手能力的人都能在周末搭出一只属于自己的机器鸭。它解决的问题很具体:让双足机器人的入门门槛从“实验室级别”降到“车库级别”。适合谁来参考?嵌入式爱好者、机器人方向的学生、想给孩子做 STEM 项目的家长,以及所有对双足步态算法好奇但不想一上来就啃论文的开发者。

我前后搭过三只 Microduck,第一只摔断了腿,第二只烧了一个舵机,第三只才真正能稳定地“上街遛”。这篇文章就把我踩过的坑、调过的参数、以及从零到能走能转的完整路径拆开讲清楚。你不需要有机器人学背景,但需要会拧螺丝、会烧录系统、能看懂简单的 Python 代码。

2. 整体设计思路与方案选型拆解

2.1 为什么是双足而不是轮式或四足

双足机器人的魅力在于它的“不稳定”。轮式平台永远倒不了,四足平台静态稳定,但双足必须靠动态平衡才能站住。Microduck 选择双足路线,核心考量是教学价值和趣味性。你让一个轮式小车走直线,没人会觉得惊讶;但一只鸭子摇摇晃晃地迈出两步然后站稳,那种“活过来”的感觉是完全不同的。

从技术角度看,双足平台强迫你面对三个核心问题:重心投影点(CoM)与支撑多边形的关系、舵机扭矩与关节角度的映射、以及步态周期中的相位切换。这些概念在轮式平台上根本不会出现。Microduck 用最简化的 6 自由度结构(每条腿 3 个关节:髋、膝、踝)来呈现这些问题,既不会复杂到让人放弃,也不会简单到学不到东西。

另一个现实原因是成本。四足需要至少 8 个舵机,双足只需要 6 个,而且四足的结构件打印量几乎是双足的两倍。对于想先试试水的人来说,双足是更友好的起点。

2.2 主控为什么选树莓派而不是单片机

这是被问得最多的问题。用 Arduino 或者 STM32 不能做吗?能,但会很难受。Microduck 的步态算法需要实时计算逆运动学、处理蓝牙手柄输入、同时还要留出扩展接口给摄像头或传感器。树莓派的 Linux 环境让你可以用 Python 快速迭代,numpy 做矩阵运算,scipy 做插值,这些库在单片机上要么没有,要么得自己移植。

更重要的是调试体验。树莓派可以 SSH 进去改代码、看日志、甚至跑一个 Flask 服务用手机浏览器监控关节角度。单片机每次改代码都要重新烧录,调试效率差了一个数量级。当然代价是树莓派的实时性不如单片机,但 Microduck 的步态频率在 1-2 Hz 左右,Linux 的调度延迟完全在可接受范围内。

我实测过树莓派 4B 和树莓派 5,两者都能跑,但树莓派 5 的 PWM 输出更稳,舵机抖动明显小一些。如果手头只有 4B,也没问题,把步态周期稍微放慢一点就行。

2.3 舵机选型与扭矩计算

Microduck 官方推荐的是 MG996R 金属齿轮舵机,扭矩标称 9.4 kg·cm(6V)。为什么是这个规格?我们来算一笔账。

假设鸭子总重 800g,每条腿承担 400g。髋关节到地面的力臂大约是 8cm,那么髋关节需要的静态扭矩是 0.4kg × 8cm = 3.2 kg·cm。但双足行走时动态载荷可能是静态的 2-3 倍,所以需要 6.4-9.6 kg·cm 的扭矩。MG996R 在 6V 下刚好卡在这个区间,留了一点余量。

如果你用 SG90 那种 1.8 kg·cm 的小舵机,静态都撑不住,一通电就直接趴下。我第一只鸭子就是用了便宜的塑料齿轮舵机,走了三步就扫齿了。后来换成 MG996R,连续走半小时也只是温热。

注意:MG996R 有假货,标称扭矩可能只有 5 kg·cm。买的时候看齿轮是不是全金属,用手拧一下输出轴,阻力均匀且没有虚位的基本靠谱。

2.4 结构件打印的关键参数

3D 打印件是 Microduck 的骨架,强度直接决定能走多久。官方 STL 文件在 GitHub 上可以下载,但打印参数得自己调。我试过三种材料:PLA、PETG 和 ABS。

PLA 最硬但脆,摔一次就断腿。PETG 韧性好,层间结合力强,是首选。ABS 强度够但打印时翘边严重,不推荐新手。层高建议 0.2mm,壁厚至少 3 层,填充率 40% 以上。关键受力部位(髋关节支架、脚掌连接件)可以单独把填充率提到 60%。

还有一个细节:打印方向。髋关节支架如果竖着打印,层间受力方向刚好和行走时的弯矩垂直,容易分层。应该横着打印,让层纹方向与受力方向平行。这个细节官方文档没写,是我断了两次腿之后才悟出来的。

3. 核心细节解析与实操要点

3.1 硬件清单与成本拆解

先把账算清楚,免得做到一半发现预算超了。以下是我第三只鸭子的实际采购清单,价格按国内电商平台常见价位估算。

部件型号/规格数量单价(元)小计(元)
主控板树莓派 4B 2GB1350350
舵机MG996R625150
舵机驱动板PCA9685 16路11515
蓝牙手柄通用安卓手柄16060
锂电池2S 7.4V 2000mAh14545
降压模块LM2596 可调2510
3D 打印件PETG 约 200g14040
螺丝轴承等M3 套装13030
杜邦线若干11010
合计710

如果你已经有树莓派,成本直接降到 360 左右。这个价格在双足机器人里算是地板价了。

3.2 舵机驱动板与树莓派的接线逻辑

PCA9685 通过 I2C 和树莓派通信,只需要两根线:SDA 接树莓派的 GPIO2(物理引脚 3),SCL 接 GPIO3(物理引脚 5)。VCC 接 3.3V,GND 共地。舵机的电源单独走锂电池经过降压模块到 6V,不要从树莓派取电,否则一走动树莓派就会重启。

这里有个坑:PCA9685 的 V+ 引脚是给舵机供电的,但板子上的 VCC 是给芯片供电的,两者不能混。我第一次接线时把 6V 直接灌到了 VCC,芯片瞬间冒烟。正确的做法是 VCC 接树莓派 3.3V,V+ 接降压模块输出的 6V,GND 全部共地。

树莓派 5 的引脚定义和 4B 基本兼容,I2C 引脚位置一样。但树莓派 5 的 GPIO 电平是 3.3V,和 4B 相同,所以不需要额外电平转换。

3.3 逆运动学求解的简化方法

双足行走的核心是逆运动学:给定脚掌的目标位置,反推髋、膝、踝三个关节的角度。Microduck 用的是解析法,把腿简化为二维平面上的两连杆机构。

设大腿长度 L1=6cm,小腿长度 L2=6cm,脚掌目标位置相对于髋关节的坐标为 (x, y)。那么膝关节角度 θ_knee 可以通过余弦定理求出:

d = sqrt(x^2 + y^2) cos(θ_knee) = (L1^2 + L2^2 - d^2) / (2 * L1 * L2) θ_knee = acos(cos(θ_knee))

髋关节角度 θ_hip 则需要先求出目标方向角:

θ_hip = atan2(y, x) - atan2(L2 * sin(θ_knee), L1 + L2 * cos(θ_knee))

踝关节角度 θ_ankle 用来保持脚掌水平,通常是 θ_ankle = -(θ_hip + θ_knee) 再加上一个补偿角。

这套公式在 Python 里用 math 库就能实现,不需要任何机器人学库。我实测下来,只要 L1 和 L2 测量准确,角度误差在 1 度以内,鸭子走起来就不会有明显的内八或外八。

提示:L1 和 L2 不是打印件的理论长度,而是舵机输出轴到下一个关节中心的实际距离。用游标卡尺量,别信图纸。

3.4 蓝牙手柄的映射策略

Microduck 用蓝牙手柄控制,左摇杆控制前后和转向,右摇杆控制身体高度和俯仰。映射逻辑在 Python 里用 evdev 库读取手柄事件,然后转换成步态参数。

关键参数有三个:步幅(stride)、步频(frequency)和转向偏置(turn_offset)。左摇杆的 Y 轴映射到步幅,范围 -3cm 到 +3cm;X 轴映射到转向偏置,范围 -15 度到 +15 度。右摇杆的 Y 轴映射到身体高度,范围 8cm 到 12cm。

我试过用 pygame 读手柄,延迟比 evdev 高不少,而且树莓派上 pygame 的 joystick 模块偶尔会丢事件。evdev 直接读 /dev/input/eventX,稳定得多。

4. 实操过程与核心环节实现

4.1 系统烧录与基础环境配置

树莓派系统用 Raspberry Pi OS Lite 64 位版本,不需要桌面环境,省资源。烧录用官方 Imager,配置好 WiFi 和 SSH,插电就能连。

第一次启动后先做三件事:改源、更新、装依赖。国内网络环境下,默认源速度感人,换成清华源或者阿里源会快很多。具体操作是编辑 /etc/apt/sources.list 和 /etc/apt/sources.list.d/raspi.list,把 deb 地址替换掉。

然后安装核心依赖:

sudo apt update sudo apt install -y python3-pip python3-numpy python3-smbus i2c-tools pip3 install adafruit-circuitpython-pca9685 evdev

启用 I2C 接口:

sudo raspi-config # 选择 Interface Options -> I2C -> Enable

重启后用i2cdetect -y 1检查 PCA9685 是否被识别,地址应该是 0x40。如果显示的是--,说明接线有问题,先查 SDA 和 SCL 有没有接反。

4.2 舵机中位校准与角度映射

舵机上电之前,先把所有舵机拧到机械中位。MG996R 的中位是 1.5ms 脉宽,对应 PCA9685 的计数值大约是 307(50Hz 下)。但每个舵机的机械中位都有偏差,需要逐个校准。

校准方法是:先给舵机一个 1.5ms 的信号,然后松开舵盘螺丝,手动把舵盘转到腿伸直的位置,再拧紧。这样电信号的中位就和机械中位对齐了。

然后在代码里建立角度到脉宽的映射表。MG996R 的有效角度范围是 0-180 度,对应脉宽 0.5ms-2.5ms。PCA9685 在 50Hz 下的计数值范围是 102-512。映射公式:

def angle_to_pulse(angle): pulse_min = 102 pulse_max = 512 return int(pulse_min + (angle / 180.0) * (pulse_max - pulse_min))

我建议在代码里给每个舵机单独存一个偏移量,因为六个舵机的机械中位不可能完全一致。校准的时候用input()手动输入角度,观察腿的实际位置,记下偏差值。

4.3 步态生成与相位控制

Microduck 的步态是周期性的,一个完整步态周期分四个相位:左腿支撑右腿摆动、双腿支撑、右腿支撑左腿摆动、双腿支撑。每个相位持续的时间由步频决定。

我用一个状态机来实现:

class GaitState: def __init__(self): self.phase = 0 self.cycle_time = 0.8 # 秒 self.t = 0 def update(self, dt): self.t += dt if self.t >= self.cycle_time: self.t = 0 self.phase = self.t / self.cycle_time

然后根据 phase 的值计算左右脚的目标位置。摆动腿的轨迹用贝塞尔曲线,支撑腿保持直线。贝塞尔曲线的控制点决定了抬脚高度和落地缓冲,我调了大概二十次才找到不摔跤的参数。

关键心得:抬脚高度不要超过 2cm,落地时脚掌要有一个轻微的下压动作,模拟真实行走的足跟落地。这个下压角度大概是 5 度,能显著减少前倾摔倒的概率。

4.4 蓝牙手柄配对与实时控制

树莓派自带蓝牙,用 bluetoothctl 配对手柄:

bluetoothctl scan on # 找到手柄的 MAC 地址 pair XX:XX:XX:XX:XX:XX connect XX:XX:XX:XX:XX:XX trust XX:XX:XX:XX:XX:XX

配对成功后,手柄会出现在 /dev/input/eventX。用 evdev 读取事件:

from evdev import InputDevice, categorize, ecodes gamepad = InputDevice('/dev/input/event3') for event in gamepad.read_loop(): if event.type == ecodes.EV_ABS: if event.code == ecodes.ABS_X: turn_offset = (event.value - 128) / 128 * 15 elif event.code == ecodes.ABS_Y: stride = (event.value - 128) / 128 * 3

这里要注意手柄的摇杆中位值不一定是 128,可能是 127 或 129。我建议在启动时先读一次中位值,后续用相对值计算。

注意:树莓派 5 的蓝牙模块和 4B 不同,配对某些手柄时可能需要先power off再power on才能被扫描到。这是固件层面的问题,不是配置错误。

4.5 上街遛鸭的实战记录

第一次带 Microduck 出门是在小区楼下。地面是水泥砖,接缝处有 5mm 左右的高差。鸭子走了大概十米,在第三个接缝处绊了一下,前倾摔倒,右腿舵机扫齿。

复盘原因:脚掌的离地高度不够,只有 1.5cm,遇到 5mm 的凸起时摆动腿的脚尖会刮到地面。后来把抬脚高度加到 2.5cm,同时在步态里加了一个“探测-调整”逻辑:如果某个舵机的电流突然增大(堵转),就立即抬高该腿并缩短步幅。

第二次出门换了平整的沥青路面,走了五十米没摔。但转弯时如果速度太快,离心力会让鸭子向外侧倾倒。解决办法是转弯时自动降低步频,同时把身体重心向内侧偏移 2-3 度。

第三次我试着让它走盲道,那种条纹凸起反而成了优势,因为脚掌的橡胶垫能卡进条纹里,抓地力更好。但走到盲道尽头时有一个 3cm 的台阶,鸭子直接撞上去摔了。所以上街遛鸭的前提是:路面高差不超过 1cm,没有超过 3cm 的垂直障碍。

5. 常见问题与排查技巧实录

5.1 舵机抖动与供电不足的排查

舵机抖动是最常见的问题,表现是静止时舵机嗡嗡响,或者走动时突然抽一下。九成原因是供电不足。

排查步骤:先用万用表量降压模块的输出电压,空载应该是 6V,接上舵机后如果掉到 5V 以下,说明降压模块的电流不够。LM2596 标称 3A,但实际持续输出 2A 就很烫了。六个 MG996R 同时动作的峰值电流可能到 5A,所以要么换大电流的降压模块,要么在电源端并一个大电容(1000uF 以上)缓冲。

另一个原因是 I2C 通信干扰。舵机的 PWM 信号和 I2C 走线如果平行且距离近,会产生串扰。把舵机线束和 I2C 线分开走,垂直交叉,能明显改善。

5.2 步态不稳的常见原因速查

现象可能原因解决方法
走路时向一侧偏左右腿的 L1/L2 长度不一致重新测量并修正代码中的长度参数
前倾摔倒重心投影点超出支撑多边形降低步频,减小步幅,增加脚掌下压角度
后仰摔倒髋关节角度过大减小髋关节的摆动幅度,检查中位校准
原地踏步不前进脚掌与地面的摩擦力不足在脚掌底部贴橡胶垫,增加摩擦系数
转弯时外侧腿拖地转向偏置没有配合步频调整转弯时自动降低步频 20%
走几步就重启树莓派供电不足树莓派单独供电,不要和舵机共用电池

5.3 树莓派系统层面的坑

树莓派 4B 和 5 在 GPIO 和 I2C 上基本兼容,但有一个坑:树莓派 5 的 I2C 时钟频率默认是 100kHz,而 4B 是 100kHz 但实际可能跑在 400kHz。如果你的 PCA9685 在 5 上工作不稳定,可以在 /boot/firmware/config.txt 里加一行dtparam=i2c_arm_baudrate=100000强制降速。

还有一个问题是树莓派 5 的散热。跑步态算法时 CPU 占用大概 30%,但如果你同时开了摄像头或者跑了其他服务,温度会飙到 80 度以上,然后触发降频,步态就会卡顿。加一个散热片或者小风扇,成本不到二十块,但稳定性提升明显。

5.4 蓝牙手柄断连的处理

蓝牙手柄在树莓派上断连是家常便饭,尤其是树莓派 4B 的蓝牙模块和 WiFi 共用天线,2.4G 频段拥挤时容易丢包。

我的解决方案是写一个守护脚本,每 5 秒检查一次手柄设备是否还在 /dev/input/ 下,如果不在就自动重连:

#!/bin/bash while true; do if ! ls /dev/input/event* | xargs -I {} udevadm info {} | grep -q "Gamepad"; then bluetoothctl connect XX:XX:XX:XX:XX:XX fi sleep 5 done

另外,手柄的电池电量低时也会频繁断连,换新电池或者插 USB 线供电能解决。

5.5 进阶扩展的方向

Microduck 的扩展性很好,树莓派的 GPIO 还剩不少,I2C 总线也可以挂多个设备。我试过加一个 OV5647 摄像头模块做视觉巡线,用 OpenCV 识别地面上的黑色胶带,然后把手柄控制切换成自动跟随。效果还行,但树莓派的算力有限,帧率只有 10fps 左右,走快了会跟丢。

另一个方向是加超声波传感器做避障。HC-SR04 接在 GPIO 上,检测到前方 20cm 内有障碍就自动停下并后退。这个逻辑很简单,但很实用,尤其是在室内遛鸭的时候。

还有人把 Microduck 的步态算法移植到了其他双足平台上,比如用 STM32 做底层控制,树莓派只负责高层决策。这种架构的实时性更好,但开发复杂度也上去了。如果你已经能把 Microduck 走稳,可以试试这个方向。

我个人在实际操作中的体会是,Microduck 最大的价值不是它本身能走多好,而是它把双足机器人的所有核心问题都暴露出来了:供电、通信、机械校准、步态规划、实时控制。每一个问题你都得亲手解决一遍,解决完了,你对双足机器人的理解就不再是纸上谈兵了。最后分享一个小技巧:调试步态的时候,把鸭子吊在一个支架上,让脚悬空,这样你可以安全地观察每个关节的运动轨迹,不用追着它满屋子跑。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进