简介:这是一份面向机器人爱好者、电子工程与嵌入式开发学习者的16舵机双足机器人完整工程资料,适合具备一定单片机与电路基础、希望深入理解多关节机器人控制的中高级实践者。资源包共147个文件,约3.72MB,以PCB与原理图文件为主,包含49个pcb、44个sch、7个prjpcb及配套的pcblib、schlib等设计文件,另有12个h头文件、6个c源码、6个pdf文档和2个xls表格,完整覆盖硬件设计与软件编程两条主线。项目围绕16路舵机的PWM独立控制、电源管理与驱动电路设计展开,程序部分涉及嵌入式微控制器编程、步态算法与运动学计算,并集成nrf24l01无线模块实现遥控通信。读者可从中获取从电路原理图到源码实现的整套方案,理解舵机角度与速度控制、多通道PWM分配、无线收发配置及抗干扰处理等关键环节,适合对照学习与二次开发。目前已有489人学习下载。
1. 16舵机双足机器人:从“能站住”到“走得稳”的分水岭
很多人第一次做 16舵机双足机器人,都会掉进同一个坑:舵机全部装好、代码烧进去,机器人却像喝醉一样原地抽搐,要么直接劈叉趴下。问题不在舵机数量,而在于 16 个自由度怎么分配、重心怎么算、步态怎么排。16 舵机双足机器人通常指每条腿 6 个自由度(髋 3、膝 1、踝 2),再加腰部 2 个或手臂 2 个,凑满 16 路 PWM。它解决的是“让双足平台在不依赖昂贵谐波减速器的前提下,用 hobby 舵机做出可编程步态”这件事。适合有单片机基础、想入门足式机器人但预算有限的开发者,也适合拿它当控制算法验证平台的人。这一章先把边界划清楚,后面才好动手。
2. 16 个舵机怎么分:自由度分配与选型账
2.1 每条腿 6 个自由度到底装在哪
双足机器人要稳定行走,至少需要 6 个自由度每腿:髋关节 3 个(pitch 前后摆、roll 侧摆、yaw 旋转)、膝关节 1 个(pitch)、踝关节 2 个(pitch、roll)。这样脚掌才能在不平地面上保持贴地,重心才能左右转移。16 舵机方案里,剩下 4 个通常分给腰部 yaw/pitch 和双臂各 1 个,或者干脆把腰部做成 2 个、手臂各 1 个,用来做配重摆动。
我一般会先画一张关节分配表,再买舵机。表里写清楚每个关节的扭矩需求、运动范围、安装方向。髋 roll 和踝 roll 承受的是侧向力矩,扭矩要比髋 pitch 大 20% 左右。膝关节在蹲起瞬间峰值扭矩最高,别按静态力矩选。
| 关节 | 数量 | 典型扭矩需求 | 运动范围 | 备注 |
|---|---|---|---|---|
| 髋 pitch | 2 | 15-20 kg·cm | -60°~+60° | 前后迈步主力 |
| 髋 roll | 2 | 20-25 kg·cm | -30°~+30° | 侧向重心转移 |
| 髋 yaw | 2 | 10-15 kg·cm | -30°~+30° | 转向用 |
| 膝 pitch | 2 | 25-30 kg·cm | 0°~+90° | 蹲起峰值最高 |
| 踝 pitch | 2 | 15-20 kg·cm | -30°~+30° | 脚掌俯仰 |
| 踝 roll | 2 | 15-20 kg·cm | -20°~+20° | 脚掌侧倾 |
| 腰/臂 | 4 | 10-15 kg·cm | 按需 | 配重或摆臂 |
选型时别只看标称扭矩,要看堵转扭矩和速度曲线。常见做法是选 20 kg·cm 级别的数字舵机,金属齿轮、双轴承输出。模拟舵机便宜但回中精度差,走起来会越走越歪。数字舵机支持更高 PWM 频率,响应快,但电流也大,电源要留余量。
2.2 电源与总线:16 路舵机同时动的电流账
16 个舵机同时动作,峰值电流能到 20A 以上。很多人用一块 5V 2A 的降压模块,结果一迈步就复位。正确做法是动力电源和逻辑电源分开:舵机用 2S 锂电经大电流 DC-DC 降到 6V 或 7.4V,控制板单独用 5V。每个舵机的电源线尽量星型接到配电板,别串糖葫芦。
控制接口上,16 路 PWM 用单片机直接出比较吃引脚。常见方案是 PCA9685 这类 16 路 PWM 驱动板,I2C 控制,一条总线搞定。但 PCA9685 输出的是 50Hz PWM,对数字舵机够用,对高性能舵机偏慢。另一种是串行总线舵机,每个舵机带 ID,一根线串下去,接线少但成本高。
# 以 PCA9685 为例,初始化 16 路舵机 import board import busio from adafruit_pca9685 import PCA9685 i2c = busio.I2C(board.SCL, board.SDA) pca = PCA9685(i2c) pca.frequency = 50 # 舵机标准 50Hz # 舵机脉宽标定:0.5ms~2.5ms 对应 0~180 度 def set_servo(channel, angle): min_us = 500 max_us = 2500 us = min_us + (max_us - min_us) * angle / 180.0 duty = int(us / 20000.0 * 65535) # 20ms 周期 pca.channels[channel].duty_cycle = duty set_servo(0, 90) # 髋 pitch 回中这段代码里frequency=50是舵机标准刷新率,min_us和max_us必须按你手上舵机的实际标定改,别直接用 500/2500。很多舵机实际是 600~2400,写错会撞限位。duty_cycle是 16 位值,对应 20ms 周期内的占空比。上电前先把所有舵机设到中位,再装舵盘,否则一通电就拧到极限。
3. 步态生成:从静态站立到动态行走的代码路径
3.1 逆运动学:把脚掌位置翻译成关节角
双足行走的核心是逆运动学(IK)。给定脚掌在髋坐标系下的目标位置 (x, y, z),反解出髋 pitch、膝 pitch、踝 pitch 的角度。每条腿可以简化成 2D 平面内的三连杆模型,先解矢状面,再叠加侧向 roll。
import math def leg_ik(x, y, z, l1=0.08, l2=0.08, l3=0.04): # l1 大腿, l2 小腿, l3 脚掌到踝 # 先算髋 roll 和 yaw 的补偿,这里简化到矢状面 d = math.sqrt(x**2 + z**2) # 膝关节余弦定理 cos_knee = (l1**2 + l2**2 - d**2) / (2 * l1 * l2) cos_knee = max(-1.0, min(1.0, cos_knee)) knee = math.acos(cos_knee) # 髋 pitch alpha = math.atan2(x, z) beta = math.acos((l1**2 + d**2 - l2**2) / (2 * l1 * d)) hip = alpha + beta # 踝 pitch 保持脚掌水平 ankle = -(hip - knee) return math.degrees(hip), math.degrees(knee), math.degrees(ankle)l1、l2、l3是你机器人实际的大腿、小腿、脚掌长度,单位米。cos_knee要做 clamp,防止目标点超出工作空间导致acos报错。返回的角度是弧度转角度,直接喂给舵机。注意这里只解了矢状面,实际还要用髋 roll 和踝 roll 补偿侧向偏移,否则脚掌会内外翻。
3.2 步态周期:支撑相与摆动相的时间分配
步态生成就是把一个周期拆成支撑相和摆动相。静态行走时,重心先移到一只脚,另一只脚才抬起。动态行走则靠惯性,重心不用完全移到支撑脚上方。16 舵机方案建议从静态步态起步,周期 1.5~2 秒,支撑相占 60%,摆动相占 40%。
def gait_cycle(t, period=2.0, step_height=0.03, step_length=0.06): phase = (t % period) / period if phase < 0.6: # 支撑相:脚掌从前往后推 s = phase / 0.6 x = step_length * (0.5 - s) z = 0.0 else: # 摆动相:脚掌抬起再落下 s = (phase - 0.6) / 0.4 x = step_length * (s - 0.5) z = step_height * math.sin(math.pi * s) return x, zperiod是完整步态周期,step_height决定抬脚高度,太高会晃,太低会拖地。step_length是步幅,别超过脚掌到髋距离的 40%,否则 IK 解不出来。这个函数只生成单脚轨迹,另一只脚相位差 0.5。实际跑的时候要把 x、z 送进 IK,再叠加髋 roll 的重心转移。
3.3 重心轨迹:ZMP 简化版怎么算
ZMP(零力矩点)是判断机器人会不会翻倒的指标。简化做法是让 ZMP 始终落在支撑多边形内。静态行走时,支撑多边形就是单脚掌面积,重心投影要落在脚掌中心附近。动态行走时,ZMP 可以超前或滞后。
我一般会先算重心位置:把各连杆质量按质心加权,得到整体 CoM。然后根据 CoM 加速度反推 ZMP:
def zmp_from_com(com_x, com_z, acc_x, g=9.81): # 简化二维 ZMP zmp_x = com_x - (com_z / g) * acc_x return zmp_xcom_z是重心高度,acc_x是水平加速度。这个公式假设地面反力垂直,忽略惯性力矩。实际用的时候,把 ZMP 和支撑脚中心比较,偏差超过脚掌长度 30% 就减速或加大髋 roll 补偿。别一上来就追动态行走,静态步态走稳了再提速。
4. 避坑与排查:16 舵机双足最常见的 5 个翻车现场
4.1 上电瞬间所有舵机乱抖
现象:一通电,16 个舵机同时往一个方向拧,有的还发出咔咔声。原因通常是 PWM 信号没初始化,或者舵机电源和逻辑电源共地没做好。解决:上电前先把所有舵机通道设到中位脉宽,再使能输出;动力地和逻辑地必须单点共地,别形成地环路。另外检查舵机电源电压是否在额定范围内,电压过低会导致舵机内部逻辑复位。
4.2 走两步就复位,控制板重启
现象:机器人迈步瞬间,控制板重启,串口断开。原因是舵机峰值电流把动力电源拉低,DC-DC 输入跌破控制板欠压阈值。解决:动力电池到 DC-DC 的线要短且粗,DC-DC 输出并一个大电容(1000uF 以上);控制板单独用一路 5V,别和舵机共用。用示波器看动力轨,迈步瞬间压降超过 0.5V 就要加电容或换更大电流的 DC-DC。
4.3 IK 解算报 math domain error
现象:步态跑着跑着,程序抛ValueError: math domain error。原因是目标脚掌位置超出了腿的工作空间,acos的参数超出 [-1,1]。解决:在 IK 里对cos_knee做 clamp,同时检查步幅和抬脚高度是不是太大。另外确认大腿小腿长度参数是不是写反了,l1和l2搞反会导致解算空间完全不对。
4.4 机器人越走越歪,直线走成弧线
现象:没有转向指令,机器人自己走偏。原因通常是舵机中位没标定,或者左右腿安装角度不对称。解决:逐个舵机做中位标定,用舵机测试仪找实际中位脉宽,写进代码;左右腿的髋 roll 和踝 roll 安装角度要用夹具保证一致。另外检查脚掌是否打滑,橡胶垫比塑料脚掌抓地好很多。
4.5 舵机发热严重,几分钟就烫手
现象:走几分钟舵机外壳烫得摸不得。原因是舵机长期在堵转附近工作,或者重心分配不对导致某些关节持续出力。解决:先称整机重量,确认每个关节的静态力矩不超过舵机额定扭矩的 50%;调整重心,让髋 pitch 和膝 pitch 在站立时接近垂直受力;如果还热,降低步态频率或减小步幅。数字舵机内部有温度保护,但别等它触发,烫手就说明选型余量不够。
5. 进阶技巧:用 IMU 闭环把“能走”变成“走得稳”
静态步态跑通之后,下一步是加 IMU 做姿态闭环。16 舵机双足机器人没有力传感器,IMU 就是唯一的“后悔药”。我一般用六轴 IMU,读加速度和角速度,做互补滤波得到俯仰角和横滚角,再叠加到踝关节和髋 roll 上做补偿。
# 互补滤波:融合加速度计和陀螺仪 alpha = 0.98 pitch = 0.0 last_time = time.time() def update_imu(ax, ay, az, gx, dt): global pitch, last_time acc_pitch = math.atan2(ay, math.sqrt(ax**2 + az**2)) pitch = alpha * (pitch + gx * dt) + (1 - alpha) * acc_pitch return pitchalpha取 0.98 是常见经验值,陀螺仪短期准、加速度计长期准。dt是采样间隔,别用固定值,用实际时间差。算出来的 pitch 直接加到踝 pitch 目标角上,横滚角加到髋 roll 和踝 roll 上。补偿量别超过 5 度,否则会振荡。
验证方法很简单:用手推机器人上身,看它脚掌能不能自动保持贴地。如果脚掌跟着倾斜,说明补偿方向反了,把符号取反。如果振荡,降低alpha或加死区。我习惯在代码里留一个串口调参接口,实时改alpha和补偿增益,不用反复烧录。
还有一个技巧是步态相位同步。IMU 检测到横滚角超过阈值时,暂停迈步,先做重心转移。这比硬走安全得多。16 舵机方案没有关节力矩反馈,IMU 闭环是性价比最高的稳定性提升手段。先把静态步态走稳,再加 IMU,别反过来。希望帮到你。
本文还有配套的精品资源,点击获取