☰
Microduck双足机器鸭首次运行指南:Makefile构建与舵机回中位标定
2026/10/30 1:11:10 网站建设 项目流程

1. 项目缘起与整体设计思路

1.1 为什么是“双足机器鸭”而不是四足或轮式

Microduck 这个项目第一次出现在我视野里的时候,我正折腾完一轮轮式小车和四足平台,说实话有点审美疲劳。轮式底盘稳、控制简单,但永远绕不开“地面平整度”这个爹;四足虽然能爬楼梯,但十二个自由度起步的舵机阵列,光是调步态就能把人熬秃。Microduck 走的是另一条路——双足、低自由度、开源,用最少的舵机数量换一个“能站、能走、能回中位”的最小可行系统。

这个取舍非常聪明。双足机器人天然是不稳定系统,倒立摆模型摆在那里,重心稍微偏一点就往前扑。但正因为不稳定,它才适合拿来学控制。你拿一个轮式小车,PID 调半天可能只是让循迹更顺滑;你拿一个双足平台,光是让它站着不摔,就已经把重心投影、关节零位、舵机中位校准这几个核心概念全过了一遍。Microduck 的设计目标不是做一只表演型的机器鸭,而是做一个教学与原型验证平台——结构件能 3D 打印,舵机用常见的总线舵机,主控跑在树莓派上,软件全开源。这意味着你拿到的不只是一只鸭子,而是一整套“从机械到控制”的链路。

我特别看重它的一点是:首次运行的目标被明确设定为“站起来并回中位”。很多开源机器人项目一上来就让你跑复杂步态,结果新手连舵机方向都没搞对,一通电整只鸭子直接劈叉。Microduck 把第一步拆得很干净——先让所有关节回到预设的零位姿态,确认每个舵机的转向、行程、中位值都对,再谈走路。这个顺序符合工程直觉,也是我后面要重点展开的部分。

1.2 软件部署为什么选 Makefile 而不是一堆脚本

热词里出现了“Makefile”“生成 makefile”“cmake 和 makefile 区别”,说明不少人对构建系统这块是懵的。Microduck 的软件部署走的是Makefile 驱动的路线,而不是给你一堆散装的python xxx.py。这个选择背后有实际考量。

树莓派上跑机器人软件,通常涉及几类东西:C/C++ 写的底层舵机通信库、Python 写的上层控制逻辑、可能还有标定工具和测试程序。如果全靠手动敲命令,今天记得住明天就忘,换台机器又要重新查。Makefile 的价值在于把“编译什么、链接什么、装到哪里、依赖哪些头文件”固化成一个可复现的入口。你只需要make一下,该编的编、该拷的拷。对于 Microduck 这种需要反复烧录、反复调试的项目,构建系统的稳定性直接决定了你调试的心情。

那为什么不直接上 CMake?CMake 确实更现代,跨平台能力更强,但它对新手来说多了一层“先生成再构建”的心智负担。Microduck 的目标平台基本锁定在树莓派这类 Linux 环境,源码规模也不算庞大,手写 Makefile 完全够用,而且看得见摸得着——每一行编译规则都摆在眼前,出错了你能顺着规则去查,而不是在 CMake 生成的几百行缓存里迷路。当然,如果你后续想把项目移植到别的架构,CMake 的优势才会显现出来。就首次运行而言,Makefile 是更轻、更直接的选择。

1.3 树莓派在整只鸭子里的角色定位

热词里树莓派相关的内容占了半壁江山,从引脚图到风扇转速到装 OpenCV,说明大家对它的期待很杂。但在 Microduck 里,树莓派的角色要收敛一下:它是大脑,不是肌肉。舵机的供电和驱动不走树莓派的 GPIO 直接拉电流,而是通过独立的舵机驱动板或总线舵机控制器,树莓派只负责发指令、读传感器、跑控制循环。

这个分工必须搞清楚,否则很容易踩坑。我见过有人直接把舵机信号线插到树莓派 GPIO 上,结果舵机一动,树莓派直接重启——因为舵机启动瞬间的电流冲击把 5V 轨拉垮了。Microduck 的部署流程里,软件层面要处理的是串口通信、舵机 ID 映射、中位值标定,而不是去折腾 GPIO 的 PWM 占空比。树莓派在这里更像一个“指挥官”,通过串口或 I2C 把角度指令下发给舵机控制器,控制器再去驱动具体的舵机。理解这一层,后面看代码和接线才不会乱。

2. 部署前的环境准备与依赖梳理

2.1 树莓派系统选择与基础配置

拿到树莓派第一件事是选系统。Microduck 的软件栈依赖 Linux 环境下的编译工具链和串口权限管理,所以官方 64 位 Raspberry Pi OS 是首选。别去折腾那些奇奇怪怪的轻量发行版,也不要想着在树莓派上装 Windows——热词里那个“树莓派安装 windows xp”纯属猎奇,真跑起来驱动和性能都是灾难,对机器人项目没有任何帮助。

系统烧录完之后,有几个基础配置必须做掉。第一是开启串口。树莓派的硬件串口默认可能被蓝牙占用或者被内核控制台占用,你需要通过raspi-config把串口登录 shell 关掉、把硬件串口打开。具体路径是Interface Options -> Serial Port,第一个问题“是否登录 shell 可访问串口”选 No,第二个问题“是否启用串口硬件”选 Yes。这一步不做,后面舵机控制器根本收不到指令。

第二是修改软件源。热词里“树莓派修改源”出现频率很高,因为默认源在国内访问速度感人。换成国内镜像源之后,apt update和apt install的效率会高很多。这个操作网上教程很多,核心就是改/etc/apt/sources.list和/etc/apt/sources.list.d/下的文件,把raspbian.raspberrypi.org替换成对应镜像站地址。注意要匹配你的系统版本代号(bookworm、bullseye 等),版本对不上会报一堆 404。

第三是确认 SSH 可用。热词里“树莓派 ssh 密码不对的解决方法”说明很多人在这卡过。默认用户名密码在较新的系统里已经不再是无脑的pi/raspberry了,首次启动时如果你没在烧录工具里预设账号,可能根本连不上。我的建议是烧录时就用 Raspberry Pi Imager 的高级选项把用户名、密码、WiFi、SSH 全部预设好,省得后面接显示器键盘折腾。

2.2 编译工具链与依赖库安装

Microduck 的 Makefile 会调用gcc、make、git这些基础工具,树莓派官方系统通常预装了gcc和make,但git和某些开发库可能需要手动补。部署前先跑一遍:

sudo apt update sudo apt install -y build-essential git cmake libserial-dev

这里解释一下为什么把cmake也装上。虽然 Microduck 主构建走 Makefile,但某些第三方依赖或者后续扩展可能会用到 CMake,提前装好省得临时抓瞎。libserial-dev是串口编程常用的库,如果你的舵机控制器走串口通信,这个库能省不少事。

还有一个容易被忽略的点是Python 环境。树莓派系统自带 Python3,但 pip 和虚拟环境工具不一定齐全。如果 Microduck 的上层控制脚本是 Python 写的,建议装好:

sudo apt install -y python3-pip python3-venv

然后强烈建议用虚拟环境来管理 Python 依赖,而不是直接pip install到系统环境。树莓派系统里很多系统工具依赖特定的 Python 包版本,你一通乱装很可能把系统搞崩。虚拟环境的操作很简单:

python3 -m venv ~/microduck-env source ~/microduck-env/bin/activate pip install -r requirements.txt

这样所有依赖都隔离在microduck-env里,系统环境干干净净。

2.3 舵机控制器与树莓派的物理连接确认

软件部署之前,物理连接必须先确认。Microduck 用的舵机控制器通常通过串口(UART)或 I2C与树莓派通信。以串口为例,你需要确认树莓派的 TX、RX 引脚和控制器是对接的——树莓派的 TX 接控制器的 RX,树莓派的 RX 接控制器的 TX,交叉连接,这个和当年接串口模块一个道理,接反了就是收不到数据。

供电是另一个大坑。舵机控制器和舵机通常需要独立的 5V 到 7.4V 电源,绝对不能从树莓派的 5V 引脚取电。树莓派的 5V 引脚能提供的电流有限,几个舵机同时动作瞬间就能把电压拉到 4V 以下,树莓派会直接欠压重启。正确做法是舵机电源单独走一块电池或稳压模块,树莓派和舵机控制器共地即可。共地这一步不能省,否则串口通信的电平参考不一致,数据全是乱码。

连接确认完之后,可以在树莓派上跑一下ls /dev/tty*看看串口设备有没有出现。常见的可能是/dev/ttyAMA0、/dev/ttyS0或者 USB 转串口的/dev/ttyUSB0。这个设备名后面要写进配置文件,所以先记下来。

3. Makefile 构建流程的深度拆解

3.1 Makefile 到底在做什么:从源码到可执行文件

很多人对 Makefile 的恐惧来自于“看不懂那些规则”。其实把它拆开,核心就三件事:编译、链接、安装。编译是把.c或.cpp源文件变成.o目标文件,链接是把多个.o文件和库文件拼成一个可执行程序,安装是把生成的可执行文件和配置文件放到系统能找到的位置。

Microduck 的 Makefile 里通常会有几个关键变量:CC指定编译器(一般是gcc或g++),CFLAGS指定编译选项(比如-I加头文件路径、-O2开优化),LDFLAGS指定链接选项(比如-l加要链接的库),TARGET指定最终生成的可执行文件名。规则部分长这样:

$(TARGET): $(OBJS) $(CC) $(OBJS) -o $(TARGET) $(LDFLAGS) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@

第一段说“可执行文件依赖所有目标文件,用编译器把它们链接起来”,第二段说“每个.o由对应的.c编译而来”。$<是第一个依赖,$@是目标,这些自动变量是 Makefile 的语法糖,记住就行。

热词里“makefile 头文件路径 rv1106”说明有人卡在头文件找不到的问题上。如果你的源码里#include "xxx.h"但编译器报No such file or directory,就是CFLAGS里缺了-I路径。比如头文件在include/目录下,就要加-Iinclude。这个路径是相对于 Makefile 所在目录的,别写成绝对路径,否则换台机器就废了。

3.2 首次 make 的完整流程与常见报错

拿到 Microduck 源码后,标准流程是:

git clone <microduck-repo-url> cd microduck make

如果一切顺利,你会看到编译器刷刷刷地输出一堆编译命令,最后生成一个可执行文件。但首次 make 大概率不会一次过,常见报错有这么几类:

第一类:make: *** No targets specified and no makefile found. Stop.这个报错的意思是当前目录下没有 Makefile。热词里“make 没有指明目标并且找不到 makefile”说的就是这个。解决办法很简单,ls一下确认你在正确的目录,Makefile 可能藏在子目录里,或者文件名是makefile(小写)而不是Makefile。Linux 下文件名大小写敏感,Makefile和makefile是两个不同的文件。

第二类:fatal error: xxx.h: No such file or directory头文件找不到。前面说了,检查CFLAGS里的-I路径。还有一种可能是依赖库没装,比如用了wiringPi但系统里没有,那就sudo apt install wiringpi。

第三类:undefined reference to xxx链接错误,说明函数声明有但实现没找到。通常是LDFLAGS里缺了对应的库,比如用了串口函数但没加-lserial。找到报错的函数名,查一下它属于哪个库,把库名补上。

第四类:权限错误比如安装步骤要往/usr/local/bin写文件但当前用户没权限。这种要么sudo make install,要么改 Makefile 里的安装路径到用户目录。

我个人的习惯是首次 make 之前先make -n跑一遍“干跑”,把要执行的命令打印出来但不真正执行。这样你能提前看到编译器和链接器会收到什么参数,心里有底。确认没问题再make。

3.3 编译产物的组织与安装路径选择

make 成功之后,产物通常包括可执行文件、可能还有共享库和配置文件。Microduck 的 Makefile 一般会提供make install目标,把东西装到系统目录。但我的建议是首次运行先不要 install,直接在源码目录里跑可执行文件,确认功能正常再考虑安装。

原因很简单:install 之后文件散落到/usr/local/bin、/usr/local/lib、/etc等地方,出问题不好定位。在源码目录里跑,所有东西都在眼皮底下,日志、配置、可执行文件一目了然。等确认舵机能动、能回中位了,再sudo make install固化下来。

如果 Makefile 没有提供 install 目标,你也可以手动把可执行文件拷到~/bin或者加个软链接。关键是保证运行时能找到配置文件。很多机器人程序默认从当前工作目录读配置,你换个目录跑就找不到config.yaml了。解决办法是在代码里用绝对路径,或者通过命令行参数指定配置路径。

4. 首次运行:让小鸭站起来并回中位

4.1 回中位的物理含义与控制逻辑

“回中位”这三个字听起来简单,但它是整个首次运行的核心目标。所谓中位,就是每个舵机被设定到一个预设的基准角度,这个角度对应机械结构上的一个标准姿态——通常是双腿直立、关节角度对称、重心投影落在支撑多边形内。对于双足机器人,这个姿态就是它能稳定站住的前提。

为什么要有中位这个概念?因为舵机的实际角度和机械零位之间是有偏差的。你买回来的舵机,标称 0 到 180 度,但装上机械臂之后,真正的“腿伸直”可能对应舵机的 87 度而不是 90 度。这个偏差来自机械装配公差、舵机内部电位器的一致性、舵盘安装的齿位误差。如果不做中位标定,你发 90 度指令,左腿和右腿的实际角度可能差好几度,鸭子站上去就是歪的,重心一偏就倒。

Microduck 的回中位逻辑通常是:程序启动后,读取配置文件里每个舵机的中位值(offset),然后通过舵机控制器把每个舵机驱动到中位值 + 目标角度的位置。首次运行时,目标角度全部设为 0,也就是所有舵机都回到各自的中位。这个过程要缓慢执行,不能瞬间跳变,否则机械结构会受到冲击,舵机也可能因为堵转发热。

4.2 舵机 ID 映射与中位值标定实操

在跑回中位程序之前,必须先确认舵机 ID 映射是对的。总线舵机每个都有一个 ID,控制器通过 ID 来区分是哪个舵机。如果你的代码里写“ID 1 是左髋”,但实际接的是右髋,一回中位鸭子就直接劈叉。

标定的流程我一般这么走:

  1. 单独测试每个舵机。写一个最简单的脚本,让指定 ID 的舵机从 0 度转到 180 度再转回来,观察是哪个关节在动。记下 ID 和关节的对应关系。
  2. 确定机械零位。手动把每个关节摆到设计姿态(腿伸直、身体水平),然后读取当前舵机的角度值。这个值就是该舵机的机械中位。
  3. 写入配置文件。把每个舵机的 ID、中位值、方向(有些舵机装反了需要取反)写进config.yaml或类似的配置文件。

方向这个事特别容易翻车。两个对称的舵机,一个正装一个反装,你发同样的角度指令,一个往前一个往后。解决办法是在配置里给每个舵机加一个direction字段,值为 1 或 -1,代码里计算目标角度时乘上这个系数。这样上层逻辑不用管机械怎么装的,统一发“左腿前摆 10 度”,底层自动处理方向。

标定过程中有个实用技巧:先把舵机扭矩关掉或者调到最小。很多总线舵机支持设置扭矩限制,标定时把扭矩调小,这样即使角度发错了,舵机也不会硬顶着机械结构较劲,你能用手轻轻掰动关节来确认方向。等标定完了再把扭矩调回正常值。

4.3 首次上电的完整操作序列与观察要点

一切配置就绪后,首次上电要按顺序来,不能急:

  1. 先上舵机控制器电源,再上树莓派电源。或者反过来也行,但关键是不要同时上,避免上电瞬间的电流冲击叠加。我习惯先给舵机控制器供电,确认控制器指示灯正常,再给树莓派上电。
  2. SSH 登录树莓派,进入源码目录。
  3. 运行回中位程序。命令可能是./microduck --calibrate或者python3 calibrate.py,具体看项目文档。
  4. 观察鸭子的动作。正常情况应该是所有关节缓慢、同步地移动到中位姿态,然后停住。如果某个关节不动、抖动、或者往反方向跑,立刻断电检查。
  5. 确认站立稳定性。回中位完成后,轻轻推一下鸭子,看它是否能保持姿态。如果一推就倒,说明中位姿态的重心投影不在支撑面内,需要调整中位值或者机械结构。

这里有个经验:首次运行时把舵机速度设慢。很多舵机控制器支持设置运动速度,首次运行把速度降到正常值的 30% 到 50%。慢速运动给你足够的反应时间来断电,也能减少机械冲击。等确认姿态正确了,再逐步提高速度。

5. 常见问题排查与避坑经验

5.1 舵机不动或抖动:从电源到信号的排查顺序

舵机不动是最常见的问题,排查要按顺序来,别一上来就怀疑代码。我的排查顺序是:电源 -> 信号 -> ID -> 代码。

先量电源。用万用表测舵机控制器的供电电压,空载和带载都测一下。空载 5V,一给指令掉到 4V,那就是电源功率不够。舵机堵转电流能到 1A 以上,几个舵机同时动,电源得留足余量。

再查信号。树莓派和控制器之间的串口线有没有接对,TX/RX 有没有交叉,波特率对不对。用minicom或者screen连上串口,手动发几条指令看控制器有没有反应。

然后确认 ID。如果控制器支持扫描总线上的舵机,先扫一遍,看看实际在线的 ID 有哪些,和你配置里写的是否一致。

最后才看代码。如果前面都正常,那可能是代码里的角度计算有问题,或者配置文件路径不对导致读的是默认值。

抖动通常是供电不稳或者舵机内部齿轮间隙导致的。供电不稳就换电源,齿轮间隙是机械问题,便宜的舵机多少都有点,只要不影响站立姿态就忍了。

5.2 串口权限与设备名漂移的处理

树莓派的串口默认属于dialout组,普通用户没有读写权限。你直接跑程序会报Permission denied。解决办法是把当前用户加到dialout组:

sudo usermod -a -G dialout $USER

然后重新登录才生效。注意是重新登录,不是重新开个终端窗口,组的变更需要重新建立会话。

设备名漂移是另一个烦人的问题。今天串口是/dev/ttyUSB0,明天插拔一下变成/dev/ttyUSB1,配置文件里写死的路径就失效了。解决办法是用udev 规则给设备起一个固定的别名。找到设备的 vendor id 和 product id(用lsusb查),然后写一条 udev 规则:

sudo nano /etc/udev/rules.d/99-microduck.rules

内容类似:

SUBSYSTEM=="tty", ATTRS{idVendor}=="xxxx", ATTRS{idProduct}=="yyyy", SYMLINK+="microduck"

这样无论设备名怎么变,你都可以用/dev/microduck来访问。这个技巧在机器人项目里非常实用,强烈建议配置上。

5.3 回中位后站立不稳的调整思路

回中位程序跑完了,鸭子也站住了,但一松手就慢慢往一边倒。这种情况通常是重心投影不在支撑面中心。调整思路分两层:机械层和软件层。

机械层先看:两条腿的长度是否一致,脚底是否水平,身体配重是否偏了。如果机械上就歪,软件怎么调都是治标不治本。

软件层可以微调中位值。比如鸭子往前倾,说明重心偏前,可以把髋关节的中位值稍微往后调一点,让身体后仰一些。每次调 1 到 2 度,调完重新跑回中位,观察效果。这个过程需要耐心,因为双足系统的重心对关节角度非常敏感,调多了直接往后倒,调少了没效果。

还有一个容易被忽略的点是脚底摩擦。如果鸭子站在光滑桌面上,脚底打滑,重心稍微偏一点就滑出去了。给它脚底贴一层防滑垫,站立稳定性会明显提升。这个属于机械小改动,但效果立竿见影。

5.4 常见问题速查表

现象可能原因排查方法解决措施
make 报找不到 Makefile目录不对或文件名大小写不符ls确认当前目录和文件名进入正确目录或重命名文件
编译报头文件缺失CFLAGS 缺 -I 路径检查 Makefile 中 CFLAGS补上头文件所在目录的相对路径
链接报 undefined referenceLDFLAGS 缺库查报错函数所属库在 LDFLAGS 中加 -l库名
串口 Permission denied用户不在 dialout 组groups查看当前用户组加入 dialout 组并重新登录
设备名漂移系统自动分配插拔前后ls /dev/tty*配置 udev 规则固定别名
舵机不动电源、信号、ID、代码按顺序逐项排查对应解决
舵机抖动供电不稳或齿轮间隙万用表测带载电压换电源或接受机械公差
回中位后站不稳重心投影偏了观察倾倒方向微调中位值或加防滑垫
舵机方向反了机械安装方向不同单独测试每个舵机配置 direction 字段取反
上电后树莓派重启舵机从树莓派取电检查供电接线舵机独立供电,共地

6. 从首次运行到后续扩展的衔接

6.1 回中位之后可以做什么

回中位跑通之后,Microduck 其实已经具备了最基础的能力:知道自己的零位在哪,能稳定站住。接下来可以往几个方向扩展。第一个方向是单关节测试,写个脚本让某个关节单独摆动,观察运动范围和响应速度,为后续步态设计积累数据。第二个方向是重心反馈,如果鸭子上装了 IMU(比如热词里提到的 ADXL345 这类加速度计),可以读取姿态角,做简单的平衡控制——往哪边倒就往哪边迈腿。第三个方向是步态生成,从最简单的原地踏步开始,让两条腿交替抬起落下,再逐步过渡到往前迈步。

这些扩展都建立在首次运行成功的基础上。如果中位都没标定好,后面全是空中楼阁。所以我一直强调,首次运行不要贪快,把回中位这一步做扎实。

6.2 构建系统的后续维护建议

Makefile 跑通之后,随着项目迭代,你可能会加新的源文件、新的依赖库。每次加文件都要更新 Makefile 里的OBJS列表,这是手工维护 Makefile 的一个小负担。如果源文件多起来了,可以考虑用通配符自动收集:

SRCS := $(wildcard src/*.c) OBJS := $(SRCS:.c=.o)

这样新增.c文件不用改 Makefile,make会自动发现。但通配符也有坑:它只在 make 启动时展开一次,如果你在 make 运行过程中新增了文件,它不会感知到。对于机器人这种迭代频繁的项目,我建议还是显式列出源文件,虽然麻烦一点,但可控性更强,出问题好定位。

另外,建议在 Makefile 里加一个clean目标:

clean: rm -f $(OBJS) $(TARGET)

这样编译出问题的时候可以make clean && make从头来过,避免旧的.o文件干扰。

6.3 树莓派性能与实时性的现实考量

最后聊一个现实问题:树莓派跑机器人控制,实时性到底够不够。树莓派运行的是通用 Linux 系统,不是实时操作系统,任务调度有不确定性。对于 Microduck 这种双足平台,控制循环的频率要求不算极端,50Hz 到 100Hz 通常够用。但如果你在树莓派上同时跑视觉处理(比如 OpenCV)和控制循环,CPU 抢占会导致控制周期抖动,鸭子走起来一顿一顿的。

我的建议是控制循环和视觉处理分开。如果一定要在同一块树莓派上跑,至少把控制循环的优先级调高,用nice或者chrt给它更高的调度优先级。更彻底的做法是加一块单片机(比如树莓派 Pico)专门跑舵机控制,树莓派只负责发高层指令。热词里“树莓派 pico 控制舵机”说的就是这个思路。Pico 负责精确的 PWM 时序和舵机更新,树莓派负责决策,两者通过串口通信。这样分工之后,树莓派的性能波动就不会直接影响舵机的运动质量。

我在实际项目里踩过的坑是:一开始把所有东西都塞在树莓派上,结果一开摄像头,舵机就开始抽搐。后来把舵机控制挪到 Pico 上,世界立刻清净了。这个经验分享给准备深入折腾 Microduck 的朋友,少走弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询