简介:16舵机双足机器人是一份融合机械结构、驱动电路与嵌入式控制的综合工程资料,适合机器人爱好者、电子工程师及高校相关专业学生用于学习多舵机协调控制和双足步态设计。压缩包共147个文件、约3.72MB,其中49个PCB与44个SCH文件为主,覆盖电路板布局与原理图设计,另含C/H源码、PDF手册及仿真文档,便于从硬件到程序完整还原项目;工程文件组织结构清晰,可按电路、源码、文档分模块查阅。该资料目前已有488人学习。内容对舵机PWM控制、多通道驱动电路设计、微控制器编程及NRF24L01无线遥控等关键环节均有展开,并附有步态算法与动作序列代码,可直接移植或二次开发。通过研读PCB/SCH可理解电源分配与保护电路,结合C源码可快速掌握16路舵机独立控制逻辑与无线收发调试思路,适合课程设计、毕业设计及从零搭建具备远程操控能力的双足机器人平台。
1. 16舵机双足机器人:从“能抬腿”到“能立住”,到底卡在哪
16舵机双足机器人,听起来就是给机器人装上16个舵机凑出两条腿,可真实情况是:一抬腿就摔。我第一次给一台16舵机双足机器人做上电测试,左脚刚离地2厘米,整台机器直接朝右侧栽倒,查到最后根本不是舵机没力,而是重心还停在两脚中间,支撑脚压根没吃上力。这份资源就是围绕16舵机双足机器人这套硬件配置展开的完整落地笔记,覆盖自由度分配、舵机选型与供电、步态状态机、逆运动学解算和调参顺序。适合买过双足套件却始终走不稳的新手,也适合做课程设计或机器人竞赛但不想从零踩坑的老手。思路清楚了再动手,比盲目烧录要省两个晚上的调试时间。
2. 硬件架构:16路舵机怎么分配自由度,选型和供电的血泪经验
2.1 自由度分配:为什么是双腿12路、上身4路
双足机器人要稳定行走,腿部的自由度分配几乎决定了后续所有控制算法的复杂度。16舵机方案最常见的做法是双腿各6个自由度,剩余4个自由度给上肢或头部。这看起来是普通的计数问题,但每个自由度负责的动作完全不同,选错了关节类型,后面写步态的时候会非常别扭。
我拆过的方案里,髋关节占2个自由度:侧摆(roll)负责左右方向的重心补偿,前摆(pitch)负责前后方向的迈腿动作。膝关节占1个自由度,只有前摆,弯曲角度决定抬腿高度。踝关节占2个自由度:前摆控制脚掌俯仰,侧摆控制脚掌左右水平。这样单腿共5个自由度,但髋关节还需要额外的偏航自由度(yaw)来让脚尖朝外或朝内,所以单腿按6个自由度配齐,两条腿就是12路舵机。
剩余4路舵机通常给头部偏航与俯仰各1个,左右手臂各1个。如果要减配,先把手臂去掉,头部保留偏航用于视觉巡线时转向。千万不要砍踝关节的侧摆自由度,那是维持左右平衡的关键,砍掉之后单脚支撑阶段就只能靠髋关节硬扛,步态参数稍微大一点就翻车。
| 部位 | 关节 | 自由度 | 作用 |
|---|---|---|---|
| 髋 | 前摆 pitch | 2 | 迈腿前后摆动,驱动步幅 |
| 髋 | 侧摆 roll | 2 | 重心左右偏移 |
| 髋 | 偏航 yaw | 2 | 脚尖朝向调整 |
| 膝 | 前摆 pitch | 2 | 抬腿高度控制 |
| 踝 | 前摆 pitch | 2 | 脚掌俯仰,维持躯干水平 |
| 踝 | 侧摆 roll | 2 | 左右地面贴合 |
| 头 | 偏航+俯仰 | 2 | 传感器视角调整 |
| 手臂 | 前摆 | 2 | 姿态抵消,视觉平衡 |
2.2 舵机扭矩估算:别信标称力矩,动载系数要留足
很多人选舵机只看“标称多少公斤”,然后整机装好后发现抬腿时舵机吱吱叫,甚至直接堵转。以我调过的本机重量约1.5kg为例,单脚支撑时髋关节需要承受整机重量,如果重心到髋关节的水平距离约5cm,静扭矩约为1.5乘以9.8乘以0.05,约合7.5公斤·厘米。但步行时重心不是静态的,身体前倾、落地冲击都会让实际力矩瞬间翻倍,所以动载系数至少要留2.5到3倍,髋关节舵机选20公斤·厘米级别才稳。
这里有个容易被忽略的点:踝关节同样不能减配。脚掌着地时,踝关节要维持躯干水平,落地冲击产生的反作用力直接作用在踝关节上,选型和髋关节一样用同一级别。全机统一舵机型号还能减少备件压力,坏了任意一个位置都能直接替换,不用区分大小舵机。
供电方面更要提前算账。16个舵机同时动作时,瞬时电流可能冲到10安培以上,USB供电或者普通的5V稳压模块一拉就崩。我一般用2S锂电作为总电源,再通过一路输出能力在10A以上的 BEC 给舵机供电。这是个典型的“看起来电压够了,实际电流不够”的坑,后续避坑章节会再展开。
2.3 供电与配重:掉电压比缺扭矩更容易翻车
供电问题的表现往往是“机器人走着走着开始抽搐”,不是舵机坏了,是瞬间压降导致舵机内部逻辑复位。PWM舵机对电压波动特别敏感,跌到4.8V以下就可能出现不受控抖动。解决思路分两条线:硬件上在舵机电源总线并联大容量电解电容,软件上让舵机动作错峰。
配重的位置也很有讲究。电池尽量放在骨盆高度附近,也就是髋关节横轴的位置。把电池背在胸口虽然换电池方便,但重心明显上移,机器人走路时身体像喝醉一样左右晃。重心低,转动惯量小,步态控制时才会觉得机器人“听话”。
结构件方面,3D打印PLA只能用低填充率做原型验证,长期行走建议用PETG或者碳纤维管作为腿部主要受力件。舵机臂固定螺丝一定要打低强度螺纹胶,这个属于高频振动环境下的基本操作,不加的话走着走着螺丝松了,角度全偏。
注意:扭矩计算用的1.5kg是整机重量,如果你加了机械手臂或者大电池,按实际重量重新算一遍,不要照抄。
3. 步态控制:从重心偏移到静步态,让代码告诉舵机怎么走
3.1 双足步态的基本逻辑:先移重心,再抬腿
双足行走的底层逻辑其实是一个平衡问题:重心在地面上的投影必须落在支撑多边形内。双脚着地时,支撑多边形是两只脚加上中间区域;抬脚之后,支撑多边形立刻缩成单脚脚掌那一小块。所以代码里最核心的一步不是“抬腿”,而是“把重心先挪到支撑脚上方”。
静步态控制适合16舵机这种没有力反馈关节的配置。整个步态周期拆成5个阶段:重心偏移、抬腿、摆腿、落腿、重心回中。每个阶段只驱动部分舵机动作,等机械到位之后才进入下一个阶段。千万不要用连续的Sin曲线去扫髋关节角度,那样看着连续,实际上舵机响应速度跟不上,轨迹会严重变形。
重心偏移是通过控制支撑腿一侧的髋关节侧摆角度来实现的。以向左迈步为例,先把髋关节整体向右侧移大约25到35毫米,感觉就是身体向右倾斜,此时重心投影落在右脚脚掌内,然后抬起左脚,完成摆腿落地,再把重心移回两脚中间。整个过程里,躯干始终保持接近水平,这是踝关节前摆舵机在持续修正的结果。
3.2 步态状态机:C语言的实现
我比较习惯用状态机来管理步态阶段。每个状态对应一组舵机角度目标,状态切换时先检查“是否所有舵机已经到达目标”,确认后再进入下一阶段。这里给一个精简的状态机代码片段:
// 步态阶段定义 typedef enum { PHASE_SHIFT, // 阶段1: 重心偏移 PHASE_LIFT, // 阶段2: 抬腿 PHASE_SWING, // 阶段3: 摆腿 PHASE_LAND, // 阶段4: 落腿 PHASE_RETURN // 阶段5: 重心回中 } GaitPhase; // 步态参数结构体 typedef struct { int shift_xy; // 重心偏移量,单位mm int lift_h; // 抬腿高度,单位mm int stride; // 步长,单位mm int phase_time; // 每个阶段的等待时间ms } GaitParam; GaitParam gp = {35, 20, 25, 400}; // 阶段切换函数: 返回当前阶段 int gait_run(int step) { switch (step) { case PHASE_SHIFT: // 控制髋侧摆,让身体重心移到支撑脚上方 hip_roll_cmd(LEFT, -gp.shift_xy); hip_roll_cmd(RIGHT, -gp.shift_xy); break; case PHASE_LIFT: // 抬腿: 膝关节弯曲,踝关节收缩 knee_pitch_cmd(SWING_LEG, gp.lift_h); ankle_pitch_cmd(SWING_LEG, -gp.lift_h * 0.3); break; case PHASE_SWING: // 摆腿: 髋关节前摆,步长由髋pitch决定 hip_pitch_cmd(SWING_LEG, gp.stride); break; case PHASE_LAND: // 落腿: 膝关节伸直,踝关节回平 knee_pitch_cmd(SWING_LEG, 0); ankle_pitch_cmd(SWING_LEG, 0); break; case PHASE_RETURN: // 重心回中 hip_roll_cmd(LEFT, 0); hip_roll_cmd(RIGHT, 0); break; } return 0; }代码里的shift_xy、lift_h、stride三个参数是整个步态调试的核心变量。重心偏移量如果太小,抬腿时重心投影靠近脚掌边缘,机器人会往侧面倒;太大则机器人姿态倾斜,支撑腿舵机负载飙升。抬腿高度也不是越高越好,20毫米左右足够避开地面轻微不平,太高会让重心在竖直方向上大幅波动。等待时间这里用了400毫秒,具体数值要看舵机实际速度,带载后动作变慢,等待时间要适当加长到500到600毫秒。
3.3 动作同步与死区补偿:细节决定站不站得稳
状态机写好了,但实际运行时还有两个细节必须处理。第一是舵机动作的错峰。16路舵机如果同时输出角度指令,电源瞬间被拉出一个很大的低谷,此时如果相邻舵机还在保持扭矩,就会出现整体抖动。所以每一帧里我通常只更新4到6个舵机的目标角度,其余舵机保持原角度输出,让电流曲线平缓一些。
第二是舵机死区。数字舵机都有死区,指令角度和目标角度差值小于一定范围时,舵机不会动作。状态机里如果频繁微调0.5度、1度,舵机根本不动,机械结构却已经到位,此时查代码会觉得“明明发了指令怎么没反应”。我一般设定最小角度差为3度,小于这个值就拉一个“舵机到位”的判断,避免无意义等待。
4. 逆运动学与关键参数:几何法解算腿部位置
4.1 为什么需要逆运动学,不用预设角度表
预设角度表的做法是给每个步态阶段直接写死具体角度,比如“髋关节30度,膝关节40度”,但这样每次调整步长或者抬腿高度,整张表全部要重改。逆运动学的思路是把脚踝相对髋关节的位置作为输入,让程序算出髋、膝、踝三个关节的角度,步长和抬腿高度都变成坐标变化,改参数只改坐标,角度由算法自动解算。
我用的几何解法建立在腿部简化模型上:大腿长度a,小腿长度b,髋关节到踝关节连线的长度由目标位置决定。这个三角形在腿部平面内直接求解,不需要复杂的矩阵运算,16位单片机也能实时算出来。
具体坐标系定义为:髋关节中心为原点,x轴朝前,z轴向下。输入目标坐标(dx, dz) 是指踝关节相对髋关节的位置。股骨长a和小腿长b分别是腿部连杆长度,单位毫米。程序需要输出的角度为髋关节角、膝关节角和踝关节角。
4.2 几何解算:Python参考实现
这里给一个Python版本的参考实现,逻辑和单片机上的C版完全一致:
import math def leg_ik(dx, dz, thigh=45.0, shank=45.0): """ 输入: 踝关节相对髋关节的位置 dx(前向), dz(向下) 输出: hip_angle(髋), knee_angle(膝), ankle_angle(踝) 单位: 输入mm, 输出角度(度) """ # 计算髋到踝的直线距离 dist = math.sqrt(dx*dx + dz*dz) # 可达域校验: 腿部伸直时距离最大 max_reach = thigh + shank if dist > max_reach: print("目标超出可达范围, 距离:", dist, "最大:", max_reach) return None if dist < abs(thigh - shank): print("目标距离过近, 腿部无法弯曲到该位置") return None # 余弦定理求膝关节角度(弯曲角) cos_knee = (thigh*thigh + shank*shank - dist*dist) / (2 * thigh * shank) knee_bend = math.acos(max(-1.0, min(1.0, cos_knee))) * 180.0 / math.pi # 求髋关节角度: 腿杆方向角 + 三角形内角 leg_dir = math.atan2(dx, dz) * 180.0 / math.pi cos_hip = (thigh*thigh + dist*dist - shank*shank) / (2 * thigh * dist) hip_offset = math.acos(max(-1.0, min(1.0, cos_hip))) * 180.0 / math.pi hip_angle = leg_dir - hip_offset # 踝关节角度: 让脚掌保持水平 ankle_angle = -(hip_angle + knee_bend) return hip_angle, knee_bend, ankle_angle代码里最关键的是可达域校验。如果输入的dx、dz让dist大于大腿加小腿的长度,比如90毫米,几何上根本够不到,此时直接返回错误比输出一个NaN角度要安全得多,舵机不会因为非法角度卡到极限位置。另外math.atan2(dx, dz)用了双参数反正切,x为零时也不会除零报错。大腿和小腿长度根据实际结构件尺寸填写,我这边用的是各45毫米,如果你改了连杆长度,参数表同步改掉。
这个函数输出的角度是基于几何关系的理论值。实际装调时,舵机安装方向不同,角度可能要做反向或偏移映射,我在使用时会加一个角度偏置表,把计算角度和实际安装角度对齐。
4.3 关键参数地图:每个参数对应什么“手感”
| 参数 | 常见范围 | 调大后果 | 调小后果 |
|---|---|---|---|
| 重心偏移量 | 25-40mm | 幅度大,重心超出脚掌边界 | 抬腿时向侧面倾倒 |
| 抬腿高度 | 15-30mm | 重心竖直波动大、落地冲击大 | 容易绊到地面障碍物 |
| 步长 | 20-35mm | 重心前移不够,身体前倒 | 行走速度太慢 |
| 阶段等待时间 | 400-600ms | 走一步要一秒以上,动作卡顿 | 舵机未到位直接切换,姿态突变 |
这四个参数是联动的,不是孤立调整。步长加大,重心偏移也要跟着加大,否则迈出的腿带不动身体。等待时间缩短,落地冲击变大,需要用踝关节缓冲。我一般把参数表做成全局变量,方便在串口调试时直接修改,这个习惯会在最后一章展开说。
5. 避坑与排查:供电、抖动、重心、通信四大翻车现场
5.1 一模一样的指令,走几步就抽搐,是舵机坏了还是供电崩了
现象:机器人能正常走几步,然后某个腿的舵机开始“咔咔”抖动,像一直被卡住又一直在反抗。停下程序后抖动停止,重新上电又正常。
原因:舵机瞬间电流需求超过供电模块的带载能力,电压被拉低到欠压阈值,舵机内部逻辑开始复位。16路舵机在步态相位切换的瞬间会同时启动,峰值电流可能超过BEC额定电流的数倍。
解决:先看供电模块的峰值输出能力,至少10A以上;再在舵机电源总线上并联两个3300微法电解电容,吸收瞬态峰值。软件层面做错峰,把同一帧的16路角度更新拆成4批,每批间隔10毫秒。用示波器或万用表量舵机电源端的电压,如果低于5V,说明BEC的动态响应跟不上,换更大电流的模块。
5.2 抬腿瞬间直接摔倒,调大扭矩也没用
现象:程序设定先抬左脚,但左脚刚离地,机器人就朝右侧倒下去,试了很多次都这样,换更大扭矩舵机也没解决。
原因:重心没有先偏移到右脚上方。抬起左脚之后,支撑多边形只剩右脚,如果重心仍在两脚中间甚至偏左,重力矩会迅速把机器人往右侧拉倒。这属于步态逻辑问题,不是力矩问题。
解决:把步态状态机里的阶段顺序改成:先让髋关节侧摆动作,让重心投影落到支撑脚脚掌内,稳定300毫秒以上,再执行抬腿动作。这里有一个可以验证的硬指标:重心偏移量要大于等于脚掌宽度的一半减去安全余量,比如脚掌宽40毫米,偏移量至少25毫米。
5.3 PWM舵机走久了位置漂移,角度回不到零位
现象:连续行走两三分钟后,机器人的姿态慢慢偏斜,一条腿的脚踝角度从0度变成了3度,行走轨迹呈弧线。
原因:PWM舵机没有位置反馈,内部电位器的测量存在累积误差,加上负载情况下齿轮回差,指令角度和实际角度会逐渐偏离。
解决:不想换总线舵机的话,在每个步态周期的“重心回中”阶段,强制给所有舵机补发一次零位角度指令,持续200毫秒,利用舵机的死区特性消除累积误差。如果补发次数多了还是漂移,检查舵机齿轮是否磨损,特别是髋和踝关节的常载舵机。预算允许就换支持角度回读的总线舵机,在代码里实时比对应答角度,偏差大于2度时自动补偿。
5.4 舵机臂螺丝反复松脱,走着走着角度就乱了
现象:拧紧的舵机臂固定螺丝,走一段时间再检查,发现已经松动,舵机臂能用手轻微晃动。
原因:舵机输出轴在堵转时会有高频振动,普通的十字螺丝在这种振动下会逐渐回退。加上金属舵机臂和舵机盘之间摩擦系数低,螺丝一旦松动,回差就变大。
解决:每个舵机输出轴的固定螺丝都要涂低强度螺纹胶,不要涂高强度,否则后续拆装维护很痛苦。安装舵机臂时先锁定舵机输出轴到零位,再套舵机臂,避免输出轴在受力状态下锁紧导致齿轮崩齿。结构件与舵机之间的空隙用尼龙垫片补齐,不要用螺丝硬拉。
6. 最后100米:验证清单与在线调参习惯
6.1 上电前的验证清单
双足机器人的调试顺序必须是线性的,跳过任何一步,后面走不稳都很难定位是哪个环节出的问题。我固定的验证顺序如下:零点校准、静态站立、重心偏移验证、单脚抬腿验证、平地慢走、步速递增。
零点校准阶段,给所有舵机发90度中位信号,拆下舵机臂,手动调整到水平位置再装臂。静态站立阶段,检查四条腿的脚掌是否完全平贴地面,踝关节角度是否归零。重心偏移验证阶段,只执行PHASE_SHIFT,观察机器人整体倾斜方向是否与预期一致,支撑脚掌是否压实。单脚抬腿验证阶段,手动抬起非支撑腿,看机器人能否保持3秒以上不晃。这一步做扎实之前,不要启动连续行走的代码。
6.2 串口在线调参:不再反复烧录固件
我习惯在固件里预留一套可在线修改的步态参数,通过串口命令注入,调参时不用反复重新编译烧录。思路是把步态参数做成全局变量,命令行解析到一个简单的状态机里。用这种方式调步长和重心偏移,一次试走的时间从“改代码加烧录加复位”的几分钟压缩到十几秒,一个晚上就能从站不稳调到能走三步,这是调试效率最大的提升。
从那以后,我在给任何双足机器人上电之前都会强制走一遍这套验证清单,先让它在原地站够半分钟,再谈走路的事。希望帮到你。
本文还有配套的精品资源,点击获取