双足机器人的门槛,很多时候不是死在硬件上,而是死在让机器“站起来”那半秒——电机抖动、姿态回不到原点、一上电就倒地抽搐。Microduck 这个开源项目最吸引我的地方,就是它把“站立”和“回中位”这个过程拆得足够细,让新手也能跟着一步步调通。这篇文章就围绕它的软件部署和首次运行展开,完整记录我从小鸭上电、固件烧录、参数配置到它真正站稳并回中位的全过程,包括踩过的坑和排查思路,给同样在折腾 Microduck 的朋友一条可以直接照抄的路径。
Microduck 本质上是一个桌面级的开源双足机器人平台,核心由主控板、两个带减速箱的舵机、一块电池和一组轻量结构件组成,整体成本控制在几百元以内。它的软件栈走的是轻量化路线——固件基于 C/C++ 编写,上层调试通过串口或命令行完成,不需要重型 IDE,也不需要额外的仿真环境。对于想入门双足运动控制、嵌入式软件开发或者机器人调试的人来说,这是一个非常合适的起步级项目。
1. 项目整体设计与思路拆解
1.1 Microduck 的硬件架构与信号流向
在动手部署软件之前,先弄清楚 Microduck 的硬件架构非常关键。这个小家伙看起来简单,但它其实是“低压嵌入式系统 + 串行总线舵机 + 运动控制算法”三者结合的典型。它的主控板通常基于常见的低成本 MCU(比如 STM32 系列或 ESP32 系列),板载一个串口转 TTL 的调试接口,再加上一个能给舵机供电的电源管理电路。简单说,主控板负责“思考”,舵机负责“出力”。
信号流向是这样的:MCU 通过串行通信协议(通常是 UART,半双工模式)向舵机发送位置指令;舵机内部的控制电路解析指令后,驱动电机转动到指定角度,并锁住位置。Microduck 用的舵机是串行总线舵机,也就是说两根线(信号和数据)就能把多个舵机串在一条总线上,每个舵机有自己的 ID 地址,主控可以单独给某个 ID 发指令,也可以广播指令。这个设计大幅减少了接线复杂度——你不需要给每个电机单独拉三根线,只需要把两个舵机并联在同一条总线上,然后靠 ID 区分。
电源方面要特别注意。舵机启动和堵转时的瞬时电流可以到 1A 甚至更高,如果主控板和舵机共用同一路电源,电压跌落会导致 MCU 复位,表现就是“鸭子一发力就重启”。Microduck 的板子上通常有独立的稳压和滤波电容,但如果你自己改装或者更换电池,务必确认供电裕量,建议至少用 7.4V 2S 锂电池或 6V/2A 以上的稳压电源。
1.2 软件栈选型:为什么是轻量固件方案
接触过开源机器人项目的朋友应该知道,有些平台动辄要拉 Docker 镜像、装 ROS、配 Gazebo 仿真,折腾一整天环境还没跑起来。Microduck 选择了完全相反的路线:固件本体是一个裸机程序,不依赖操作系统,也不依赖复杂框架。它直接在 MCU 上跑一个死循环,不断读取目标姿态数据,解析为舵机角度指令,然后通过串口总线发送给舵机。这种方案的优点极其明显——开机即起,逻辑可追踪,方便调试。
它的软件部署过程也走的是极简路线:拉取源码、用 gcc 或者 arm-none-eabi 交叉编译工具链编出固件,然后用烧录器(比如 ST-Link 或者板载 USB 转串口配合 bootloader)把固件烧进 MCU。没有复杂的依赖管理器,没有环境变量地狱,核心依赖就是编译工具链和烧录工具,这一点非常友好。
还有一个值得点赞的设计是:Microduck 的固件把姿态控制参数(比如站立时两个舵机的目标角度、回中位速度、PWM 分辨率等)做成可配置项,存放在独立配置区。这意味着你改运动参数不需要重新编译固件,只需要在命令行里发一条配置指令,重启后生效。这一点对新手排查问题极其重要——你可以在“不知道是不是角度设错”和“不知道是不是程序写错”之间快速隔离风险。
2. 核心细节解析与实操要点
2.1 舵机角度约定与回中位的定义
机器的“回中位”是首次运行时最容易懵的地方。所谓中位,是指舵机输出轴在其整个行程范围内的中间位置。对于标准串行总线舵机,通常把中位定义在 1500us 脉宽对应的角度,或者按数字量定义在量程的 50% 位置(比如 0-1000 的数值范围,中位就是 500)。但是 Microduck 的设计里,“回中位”并不是让舵机回到它自身的中位,而是回到“机器能保持稳定姿态的机械中位”——也就是两个舵机角度都处于 90 度附近、双腿对称且重心落在支撑多边形正中心的位置。
这里必须区分两个概念:舵机绝对角度和机器姿态。舵机绝对角度是舵机输出轴相对于其自身机械零点的角度;机器姿态是两条腿和躯干在空间中的相对位置。Microduck 在出厂时,机械装配会把两个舵机的零点预设在让鸭子能够“站立”的位置附近,校正码初始值一般就是两个舵机的中位值。但这个中位值可能不为 90°——因为结构公差、舵机安装时齿位偏差、腿部零件的形变,都会让实际能达到稳定平衡的“角度”偏离理想值。这就是为什么首次运行必须先做一次回中位校准,把机器拉到它在现实中真正的平衡位置。
2.2 参数配置表:你需要知道的那几个关键值
Microduck 的参数配置集中在 config 模块里,不同的基础平台略有差别,但核心参数基本一致。我整理了一份首次部署时最需要关注的参数表:
| 参数名 | 典型范围 | 说明 | 注意事项 |
|---|---|---|---|
| SERVO_ID_LEFT / SERVO_ID_RIGHT | 1 / 2 | 左右腿舵机的总线 ID | 必须先确认硬件上的 ID 设定,和代码一致 |
| SERVO_MIN_PULSE / SERVO_MAX_PULSE | 500 / 2500 | 舵机脉宽范围 | 不要超出舵机手掰可转动范围,会堵转发热 |
| SERVO_MID_PULSE | 1500 | 舵机自身中位脉宽 | 这是舵机的绝对中位参考值,不是机器姿态中位 |
| STAND_ANGLE_LEFT / STAND_ANGLE_RIGHT | 90 ± 40 | 站立时目标角度 | 需要结合回中位校准后的值来调整 |
| CALIB_OFFSET_LEFT / CALIB_OFFSET_RIGHT | 通常 -30 ~ +30 | 角度软校正偏移量 | 用来补偿机械装配误差,回中位后应更新这两个值 |
| RETURN_SPEED | 100 ~ 500 | 回中位的角速度(单位取决于固件接口) | 速度太快会冲过目标,太慢会显得僵硬 |
| UART_BAUDRATE | 115200 | 串口与舵机通信的波特率 | 必须与舵机本身设置的波特率一致,否则舵机不响应 |
其中 CALIB_OFFSET 是精华所在。你可以通过串口命令动态修改这个偏移值,让鸭子往左倒就往右加,往右倒就往左加,直到它稳稳站住。这个过程中你不需要烧录固件,只需要重新下发校准指令,这种操作方式对第一次接触串行舵机控制的人来说非常友好。
2.3 工具链安装与固件编译注意事项
如果你是第一次在电脑上给嵌入式板子编译固件,建议直接装一套完整的 arm-none-eabi-gcc 工具链,不要混着用系统自带的 gcc,因为两者生成的指令集不同。以 Ubuntu/Debian 系为例,一条命令安装:sudo apt install gcc-arm-none-eabi。macOS 用户用 brew 装arm-none-eabi-gcc。Windows 用户建议直接使用板子厂商提供的 IDE,或者装 WSL 后在 Linux 环境下编译,这样可以避开驱动和工具链配置的很多坑。
编译流程一般是进入 Microduck 源码根目录,执行make或者针对具体板型的make BOARD=xxx。第一次编译时大概率会遇到缺少某个头文件或者链接脚本路径不对的问题,解决办法通常是检查 Makefile 里的TOOLCHAIN_PATH和LINKER_SCRIPT两处配置是否与你本机的实际路径匹配。我遇到的典型报错是fatal error: stm32f1xx_hal.h: No such file or directory,这通常不是源码问题,而是子模块依赖没有拉全。解决办法是执行git submodule update --init --recursive,把 HAL 库等依赖模块补全后再重新编译。
烧录过程有两条典型路径。如果你有 ST-Link,直接make flash就能完成烧录和复位;如果板子自带烧录引导,则可能需要先把固件放到一个指定目录,再通过串口工具发送烧录指令。Microduck 这一类板子很多都支持 DFU 模式,就是按键上电时进入 USB 下载模式,然后用dfu-util或厂商烧录工具把 bin 文件灌进去。我用 ST-Link 比较多,因为它的调试监视功能在排查问题时非常好用,可以在线看 MCU 的寄存器状态和变量变化。
3. 实操过程与核心环节实现
3.1 首次上电前的安全检查清单
说实话,很多机器不是被调坏的,而是被“盲上电”烧坏的。Microduck 的操作电压范围在 5V 到 8.4V 之间,如果你用的是 3S 锂电池(11.1V 满电),直接上板会把稳压芯片和舵机烧掉。上电前必须先做一轮检查:
- 确认电池电压在板子的额定输入范围内,最好用万用表实测,不要只看电池标称值
- 确认舵机总线接线没有反接,特别是“信号线”和“电源线”不要插反。串行舵机的 3 线接口通常标注为 VCC / GND / SIG(或 DATA),颜色和位置分布不同厂家不一样,务必对着原理图核实
- 确认舵机输出轴没有被异物卡死,鸭子的双腿处于自由可动状态,避免上电瞬间堵转导致过流
- 确认串口调试线连接正确,尤其是 FTDI 或 CH340 这类 USB 转串口模块的 TX 和 RX 是否交叉连接
检查完这四条,再上电也不迟。首次上电时,我建议先不装电池,直接用 USB 线给主控板供电,先确认 MCU 能启动、串口有输出、舵机初始化不抖动。如果你一上电舵机就发烫或者嗡嗡响,先不要想着调试,立刻断电检查接线和舵机 ID 冲突。
3.2 从串口工具发送回中位指令的完整流程
Microduck 的回中位指令和大多数串行舵机控制指令类似,是通过命令行交互的方式下发。连接串口后,打开任意串口终端工具(我用的是 screen 或者 minicom,Windows 下用 MobaXterm 的串口模式)。波特率设定为 115200,数据位 8,停止位 1,无校验。连接成功后,你会看到板子打印的启动日志,或者至少能通过回车看到命令行提示符。
回中位的指令通常是home或者reset,不同固件版本略有差异,可以在命令行输入help查看支持的命令列表。我实测中用的指令形式是servo set 1 mid和servo set 2 mid,分别让左右舵机回到自身中位。这里有个关键细节,如果你想让鸭子回到“机械平衡姿态中位”,光发这一组 mid 指令是不够的,还需要叠加校准偏移量。
正确的回中位顺序如下:
- 先让两个舵机进入自由状态(通常指令是
servo free),此时舵机不锁定,你可以用手轻轻掰动鸭腿,感受它的活动范围,确认机械上没有被卡死。 - 通过指令让舵机回到自身绝对中位:
servo set 1 mid、servo set 2 mid。此时鸭子大概率不是站直的,会偏向某一侧,这是正常的。 - 观察鸭子倒向哪一侧:如果往左倒,就增加右腿舵机的角度偏置;如果往前趴,则需要调整左右腿的前后角度偏移。Microduck 的
calib指令就是干这个的,执行calib 1 10之类,给一号舵机加 10 个单位的偏移量。 - 反复微调,直到鸭子能不需要外力扶着,自己保持站立姿态 10 秒以上。这时记录下当前的偏移量,写入配置文件,重启板子让它自动加载。
3.3 调参失败时不烧固件的软校准方法
硬件装配完成后,第一次让鸭子站稳,我花了大概 20 分钟,主要时间都花在“反复烧固件”上。后来我发现一个省事得多的思路:不修改源码里的固定角度值,而是通过软校准命令把偏移量实时调好,最后再固化到配置区。
具体操作上,打开串口终端,先用calib query查看当前左右舵机的偏移值,然后根据鸭子倒向每次增减 2 ~ 3 个单位,观察一次,稳住后再继续微调。这个过程就像调平一个两脚桌:一边高了就垫一块薄片,只不过这里“垫”的是软件偏移量。等到鸭子站得稳了,用config save把当前参数写入持久化存储,然后重启验证是否自动加载。之后你再也不需要天天烧固件调角度了。
这个方法对后续做步态实验也很有用。鸭子走起来之后,左右腿摆动角度始终不对称,八成是回中位校准时粗调留下的尾巴,直接用软校准偏移量补偿,比改代码然后重新编译烧录快得多。调参的过程建议一次只改一个变量,记录每次修改的结果;别同时调左右两个偏移量加回中位速度,那样你永远不会知道是谁把姿态搞坏的。
4. 常见问题与排查技巧实录
4.1 舵机不响应:先查波特率和总线终端电阻
舵机不响应是最常见的首发问题,症状是串口能收到板子的日志,但发指令后舵机就是不动。这种问题八成出在固件和舵机的通信链路上,而不是舵机本身坏了。首先确认舵机的波特率与实际配置一致——总线舵机的波特率出厂通常设在 115200,但如果之前有人调过,变成 9600 或 100000(这是某些厂商的特殊波特率),那板子用 115200 发指令它自然不理会。
第二件事是检查总线终端电阻。串行总线舵机的要求和 RS485 类似,总线两端要匹配阻抗,否则信号反射会导致指令无法正确解析。Microduck 主板上如果已经预留了 120 欧终端电阻的焊接位置,确认它和总线末端的舵机侧电阻只在总线两端各存在一份即可。
第三件事是确认舵机 ID 有没有冲突和主控板地址是否匹配。两个舵机 ID 如果都设成 1,指令会被两个舵机同时响应,轻则动作错乱,重则总线冲突发热。排查时把其中一个舵机单独从总线上拔下来,只接一个,发指令测试,一个一个排除。
4.2 站立后持续抖动:不是 PID 的问题,是惯性问题
鸭子站稳之后开始高频抖动——幅度小、频率快、像在发抖——很多人会误以为这是力反馈控制或者 PID 参数没调好。实际上 Microduck 没有闭环力控,纯靠舵机的位置锁定,抖动多来自两个原因:一是舵机在目标位置附近反复过冲,原因是回中位速度设得太高,舵机内部的位置环超调,最终在目标角度附近来回震荡;二是机械结构松动,尤其是舵盘和腿部的紧定螺丝没拧紧,载荷在静态下产生间隙,舵机为了维持位置就会反复纠正,形成振荡。
排查方法是先按住鸭子的身体,让它的腿不再受力,看抖动是否消失。如果按住就不抖了,基本就是舵盘和结构件之间的机械虚位问题,把相关螺丝全部检查拧紧;如果空载还是抖,就是舵机速度参数和回中位速度的匹配问题,把速度参数降低 50% 再试。
4.3 一站立就“劈叉”或失去平衡
鸭子好不容易站起来,一松手就往前或者往两侧劈叉,这大概率不是程序问题,而是物理重心没落在两脚支撑区域内。Microduck 的腿部零件是塑料或金属的,装配缝隙必然存在,如果你用默认的站立角度,实际姿态往往不是设计姿态。解决办法很简单:先用手扶着鸭子,不断调整身体前后倾的角度,找到一个“松手后它不会立刻倒下”的临界点;然后观察此时两条腿的角度读数,把这个角度写进校准偏移量。没有经验的朋友可能要试很多次,我的建议是每次移动 5 度左右,先粗调再精调,找到平衡范围后记录中点值。
这里还要特别提醒一个细节:两条腿的舵机齿轮中心轴未必完全共面。机械装配时如果左腿舵机安装位置比右腿高 2mm,鸭子站直后骨盆就是歪的,怎么改软件都救不回来。这时候唯一的办法是松开结构件安装螺丝,把两只腿的舵机轴心调到同一水平线上再锁紧。我在第一次组装时忽略了这一步,调了一晚上参数都站不稳,检查机械结构二次装配后才解决。
4.4 首次运行串口无输出的处理步骤
还有一个很容易碰到的情况:接线没问题、电压正常、固件烧录成功,但串口终端什么反应都没有。处理顺序建议如下:
- 先看看 USB 转串口模块在系统里是否被识别,Linux 下用
ls /dev/ttyUSB*或/dev/ttyACM*,Windows 下打开设备管理器看端口号。 - 确认你选择的串口号是板子对应的那个,而不是蓝牙或者其他 USB 设备。
- 尝试调换 TX 和 RX 两根跳线。很多 USB 转串口模块上没有标明 RX/TX 和板子 RX/TX 的对端定义,交叉连接的规则是“模块 TX 接板子 RX,模块 RX 接板子 TX”,装反了最常见。
- 如果这些都没问题,拔掉 USB 转串口模块再插回去,或重启板子再试。注意如果板子上有占用串口的跳线帽,确认它处在“UART 模式”而不是“boot 模式”。
5. 从回中位到下一步:扩展运动控制的个人体会
回中位只是 Microduck 漫长可玩性的起跑线。一旦鸭子能站稳,下一步就是让它抬腿、转向、走步,甚至通过 IMU 反馈做动态姿态调整。很多玩家觉得“能让鸭子站起来”已经很满足了,但我个人经验是:回中位这个过程中建立的调参思维和排查方法,才是这个项目最值钱的部分。你会在这几十上百次的微调中,建立起对舵机特性、结构公差、重心位置和通信时序的直觉——这个直觉比任何现成的 Demo 都更持久。
最后的建议是:建议准备一个“调参笔记本”,记录每次修改的参数、观察到的现象、以及最终的稳定值。至少我在调完 Microduck 后回头看就会发现,很多问题答案其实早就藏在上一轮实验里;如果你不想在同一个坑里跌第三次,记录是你最可靠的伙伴。鸭子站稳之后,试试给它设计一个简单的左右抬腿动作序列,你会发现它比你想象中要聪明得多,也会比你预想中更折磨人——但这就是玩开源机器人的乐趣所在。