手上这台机器人已经跑了三个月,累计拆装不下二十次,从最初的一堆舵机到现在能做出“慢速直行—原地转向—单腿微抬”这一套动作,中间踩过的坑比想象中多得多。这篇博文就围绕“中配低成本类人机器人”展开,把机械结构和电子系统两部分彻底拆开讲清楚。
先交代一下“中配”是什么档位。低配是网上最常见的四轴六轴玩具,只有头、手能转,脚是摆设;高配是带力控、几十个自由度、一套下来上万甚至几十万的工程样机。而我做的这一版,定位在两者之间:身高70厘米左右,全身22个自由度,理论成本控制在三千元上下,用市面上最容易买到的MG996R和MG90S舵机,配合STM32主控和PCA9685舵机驱动板。这个配置足够研究步态规划、重心控制和基本姿态反馈,又能控制返工成本和调试复杂度。如果你也打算从零开始做人形机器人,这篇文章可以直接照着抄作业。
1. 整体设计思路与自由度分配
1.1 中配方案到底指什么
做类人机器人最忌讳一上来就追求“全都要”。我见过很多朋友第一次规划就打算做26甚至32个自由度,结果钱包扛不住,装配调试也扛不住,最后烂尾。人形机器人的自由度数,决定的是动作上限,但同时也直接决定结构复杂度、电源功率、代码规模和调试难度。
这版中配方案全身上下22个自由度:头部2个、双臂各6个(肩2+肘1+腕3)、腰部2个(前后/左右倾斜)、双腿各6个(髋3+膝1+踝2)。相比高端方案的每只手都单独做五指自由度,这版把腕部的复杂动作简化成俯仰、偏摆两个方向,省略手指和脚趾。省下的费用和调试精力,全部投入到腿部的稳定性和姿态控制上——对人形机器人来说,能站稳、能走起来才是核心价值。
1.2 自由度怎么分配最划算
自由度分配的核心标准是“每个舵机都得有不可替代的作用”。检验方法是:如果某关节砍掉之后仍然能完成核心动作,那这个自由度就该砍掉。
我的实际分配逻辑是这样的:
| 部位 | 自由度 | 舵机选型 | 核心作用 |
|---|---|---|---|
| 头颈 | 2 | MG90S x2 | 左右转头、上下点头 |
| 双臂 | 12 | 肩/肘用6个MG996R,腕用6个MG90S | 挥手、抓取演示 |
| 腰部 | 2 | MG996R x2 | 重心调节、上身倾斜补偿 |
| 双腿 | 12 | 髋/膝/踝均用MG996R,髋前后和膝可考虑双机构 | 站立、重心转移、步态移动 |
其中双腿以髋关节的3个自由度最为复杂:俯仰(前后踢)、偏摆(左右开合)、旋转(大腿扭转)。中配方案里我给髋关节的俯仰和膝关节做了“双舵机并联”,其余都是单舵机。这个细节直接决定了机器人是稳稳站着还是不可控地劈叉,后面机械结构章节会细讲。
1.3 一体化骨架对后续升级很关键
自由度分配完就要确定骨架方案。很多人习惯先买舵机再找外壳,结果材料到了发现尺寸对不上。我建议反过来:先画一版简化的人体比例图,梳理每个关节之间的连杆长度,再去采购舵机和结构件。
这版设计的人体比例参照了7头身简化模型:整机高70cm,大腿30cm、小腿25cm、脚掌15cm,髋部到肩部大约20cm。为什么大腿要比小腿长?因为大腿短、小腿长时,走路会显得僵硬,重心起伏大;大腿略长则步态更接近人类,姿态规划也更容易。实际加工时还要注意,大腿和小腿的连杆不是简单直线,而是带有“膝关节偏置”——为避免弯腰时大腿与小腿的舵机摇臂干涉,膝关节处应留出2到3厘米的偏移空间。
2. 机械结构:材料选型与关节设计
2.1 骨架材料怎么选
中配机器人不建议一上来就用碳纤维或全金属加工,成本高且一旦尺寸误差返工就是钱。我自己用的是“3D打印+铝合金板材混合结构”:
- 主体骨架(大腿、小腿、上臂、前臂)用PLA+打印,壁厚设计在3mm以上,必要时内部加十字筋板。PLA+比普通PLA韧性好,不容易在舵机振动下开裂;
- 骨盆、肩部这类受力集中且需要高精度的位置,用2mm厚6061铝合金板材CNC切割或线切割,安装孔位公差控制在±0.1mm;
- 脚板用3mm铝合金板,底面贴防滑胶垫,兼顾重量与抓地力。
为什么不用全金属?一个很现实的原因是重量。金属大腿虽然稳,但会让髋关节舵机长期过载,走不了几步就开始发烫。3D打印件虽然强度不如金属,但在中配这个负载量级下配合筋板设计完全够用。还有一个容易被忽略的点:打印件要预留舵机安装孔和走线槽。打印前务必确认舵机耳朵的孔径与螺距,多数MG996R用的耳朵孔是2.5mm直径,螺丝选M2或M2.5,孔径要留0.2mm余量,否则打进去直接胀裂。
2.2 关节尺寸与扭矩计算
关节尺寸不是拍脑袋定的,每个舵机承受多少扭矩必须先算清楚,否则做出来就是个“站立即瘫”的模型。这里以髋关节为例教你估算:
- 单腿总质量估算:大腿350g、小腿300g、脚板及传感器100g,合计约750g;
- 单腿质心到髋关节的力臂,近似取大腿中部偏下,约25cm;
- 静载扭矩 ≈ 0.75×9.8×0.25 ≈ 1.84N·m,约18.8kg·cm;
- 考虑步行摆动时的冲击和加速度,通常乘以2.5到3倍的安全系数,峰值需求约47到56kg·cm。
单个MG996R的标称堵转扭矩约11kg·cm(6V供电时),显然不够。所以髋关节俯仰和膝关节采用双舵机并联,两个舵机加一起有效输出大约24kg·cm,配合减重后的腿部结构,刚好压住静态站立和慢速步态的峰值。如果你觉得余量不足,预算再宽裕一点可以直接上DS3218(20kg·cm级),单电机就能覆盖需求,结构也更简单。
2.3 关节组装的三个关键细节
第一个细节是舵机安装方向。以膝关节为例,单舵机方案的舵机输出轴必须指向身体内侧(朝外的一侧加装限位挡片),这样既减少干涉又能让走线贴近骨架。双舵机并联时,两个舵机要镜像安装,输出轴通过双孔联动臂合并到一个旋转点上。联动臂买现成的“U型舵机延长支架”,自己打印也行,但要注意两个舵机的中位角度必须一致,否则互相别劲。
第二个细节是线缆管理。所有舵机线束走骨架内侧,每隔5厘米用扎带或热熔胶固定一次。关节处要预留足够的活动余量,我建议在转轴位置留出一小段弹簧式预弯,避免转动时线缆被反复拉扯导致内部断芯。舵机线头是3pin杜邦头,装配过程中特别容易被压断或拉脱,最好在最外侧加一层螺旋保护管。
第三个细节是腕部和踝部这种小空间关节。不要直接用舵机本身固定输出,先在舵盘和连杆之间加0.5mm垫片消除轴向虚位,再用螺丝胶(中强度243)锁死机械螺丝。这一步能明显减少“机器人在那站着,手腕自己在抖”的尴尬情况。
3. 电子系统:舵机、主控与供电
3.1 舵机选型和PWM原理
中配方案最核心的选型就是MG996R和MG90S的组合。MG996R是标准尺寸金属齿舵机,工作电压4.8V到7.2V,标称堵转扭矩约11kg·cm,适合腿部和肩部这类高载关节。MG90S是微型金属齿舵机,扭矩约1.8kg·cm,适合头部和手腕。两条线的共同点是价格便宜、坏了对换成本低,缺点是精度一般(标称死区约5微秒),但中配阶段完全够用。
舵机的控制原理,说穿了就是用PWM脉宽控制角度。常规舵机接收50Hz的PWM信号(周期20ms),脉宽1ms对应0度,1.5ms对应90度,2ms对应180度。MG996R实际可调范围约500到2500微秒,对应约0到180度。控制核心在STM32里做的事很简单:计算每个关节的目标角度,换算成对应的脉宽数值,通过I2C总线写入PCA9685驱动板,由驱动板生成精确的PWM波。
PCA9685是16路PWM驱动芯片,12位分辨率,意味着每路脉宽有4096个细分档位。常用的设置如下:内部时钟25MHz,50Hz频率时计数范围是0到4096,这时代码里“脉宽=375”就对应90度(1.5ms),具体映射表我们可以通过实测校准确定,不建议直接套网上模板,因为不同厂家舵机存在个体差异。
3.2 主控方案:为什么选STM32而非树莓派
中配机器人不建议拿树莓派当主控。树莓派本身需要5V/2A电源,开机慢,实时性也容易被系统调度抢占。对舵机控制这种周期性任务,最合适的反而是具备定时器中断和硬件I2C接口的单片机。
我用的主控是STM32F103C8T6(蓝丸板),主频72MHz,Flash 64KB,价格30元左右。它的优势在你的上层程序可以完全控制每个定时器中断,保证舵机刷新是严格50Hz稳定输出;同时自带多个UART可以接串口命令调试、连蓝牙模块甚至接无线手柄接收器。实际接线图非常清晰:
- STM32 PA0-PA1 / 或I2C1(PB6、PB7)接PCA9685控制板的SCL/SDA;
- PCA9685供电从主供电源接入,板载稳压会输出5V给逻辑部分;
- MPU6050姿态传感器接在另一组I2C接口(如PB8、PB9);
- 串口1接USB转TTL模块,用来打印姿态数据和接收上位机指令。
如果你完全没接触过STM32,可以先从Arduino兼容板开始跑通逻辑再迁移到STM32,但不管哪种,最后的舵机刷新频率和中断优先级一定要做成高优先级,否则舵机容易出现“卡顿感”。
3.3 电源系统怎么分配
电源是整个项目最容易被轻视、也最容易出事故的环节。中配方案22个舵机,如果共用一颗降压模块,舵机启动瞬间会让电压跌落,轻则STM32复位,重则舵机抽搐、伤到塑料齿轮。
我的电源架构分三路:
| 用电器 | 电压/电流 | 来源 |
|---|---|---|
| 主控STM32、MPU6050 | 5V/2A | 独立5V降压模块(UBEC 5V/3A) |
| 舵机总线 | 6V/10A | 可调降压模块(大功率BEC),电池直供前先过保险丝 |
| 辅助传感器(超声波、灯带等) | 5V/1A | 同主控电源,串口隔离 |
电池方面我用了一块3S 2200mAh锂聚合物电池,满电12.6V,通过一个可调降压模块输出6V给舵机。MG996R标称最高7.2V,但长时间顶着高压跑发热严重,降到6V后在扭矩和发热之间比较均衡。注意,所有降压模块负极要共地,且主控电源和舵机电源完全分开——这是一条铁律,共用电源会让舵机噪声通过地线直接干扰单片机IO口,轻则姿态误判,重则程序跑飞。
还有一个容易踩的坑:舵机电源入口处要并联大容量电解电容(我用的是两个1000μF/16V并联),并在每个舵机信号线靠近驱动板端串一个100Ω电阻。前者吸收尖峰,后者能明显抑制舵机线缆干扰。整体电源线用AWG16或更粗的硅胶线,不要用细杜邦线直接引大电流,否则线上压降足以让远端舵机欠压抖动。
3.4 传感器与扩展接口
只用舵机同步动作做出来的机器人,本质上是个“盲人”。加传感器不是为了炫技,是为了让机器人感知自己到底是直立的还是已经前倾了。这版机器人我加了三个模块:
- MPU6050六轴传感器(三轴加速度+三轴陀螺仪),安装在骨盆正中心位置,用来解算机身倾角和角速度;
- 脚底压力传感器,用薄膜压感片或自制的应变片桥,放在脚板前后两端,判断重心是否在支撑多边形内;
- HC-SR04超声波或VL53L0X激光测距,安装在胸前正中,用于前方障碍物距离检测,给步态规划提供“停/走”信号。
传感器姿态数据的处理上,强烈建议做数据融合,不要直接用原始加速度值求倾角。零速静止状态下加速度计数据抖动大,典型滤波方法是“互补滤波”:把陀螺仪积分得到的高频姿态与加速度计得到的低频姿态以一定比例融合。核心公式(简化示意):
float angle = 0.98 * (angle + gyroRate * dt) + 0.02 * accelAngle;这个0.98/0.02的比例可以根据实测调整。比例太偏向陀螺仪,角度会漂;太偏向加速度计,数据噪声大。我调试后固定下来是0.985。
4. 实操:组装、接线与初调
4.1 舵机中位校准
组装完成后的第一次上电,第一件事不是让它站起来,而是校准所有舵机的中位。这一步如果跳过,后面所有步态数据都会偏。
校准方法是:先用上位机或串口发指令,让所有通道输出1.5ms脉宽(即90度位),然后手动挑选舵机的舵盘位置,使其带动连杆指向“零位”方向。装舵盘时先不给舵机通电,手动转到中点附近再锁紧螺丝,这能避免上电瞬间舵机猛跳到机械限位处把齿轮崩断。
我踩过最惨的一次:忘记校准膝关节,上电后一条腿直接踢到前胸,把髋关节固定件干裂了。所以要养成习惯,每次装完一个关节,在主控程序里先执行一次全关节中位测试脚本,确认无异常再装配下一个关节。
中位校准完成后,还需要让每个舵机记住自己PCA9685通道号和角度映射关系。我用一个结构体数组把所有关节配置固化在代码里:
typedef struct { uint8_t ch; // PCA9685通道 float midOffset; // 中位偏移,单位/度 float minAngle; // 机械限位最小角 float maxAngle; // 机械限位最大角 } JointConfig;机械限位角千万要在结构设计时就确认好,否则舵机转到位后继续憋力,轻则齿轮扫齿,重则烧驱动或拉断打印件。
4.2 底层驱动代码怎么组织
PCA9685的驱动,网上有很多现成封装,但我的经验是不要直接抄大而全的库,只保留自己需要的函数,代码量小、调试也直观。核心初始化代码如下:
// PCA9685地址默认0x40 PCA9685.begin(0x40); PCA9685.setPWMFreq(50); // 50Hz,周期20ms // 脉宽换算函数:输入角度,输出PCA9685计数 uint16_t angleToTicks(float angle) { // 90度为375(1.5ms),每度对应约2.5个tick return (uint16_t)(375.0f + (angle - 90.0f) * 2.5f); }这里2.5这个系数要实测校准:发一个90度脉宽,用示波器或直接观察舵机是否对准中位;不行就微调系数。不同厂家的MG996R响应范围有差异,我用几只测出来的系数在2.4到2.6之间。
姿态数据读取也比较简单,前提是正确处理I2C地址和寄存器:
// MPU6050地址0x68 MPU6050_Init(); MPU6050_GetData(&ax, &ay, &az, &gx, &gy, &gz);上电后MPU6050需要静置2秒完成寄存器校准,代码里要加上这个延时,否则前几百组数据全是歪的。对STM32硬件I2C如果调试不顺,可以选择软件模拟I2C,稳定性和输出速度都够用,而且能绕开I2C外设的时序坑。
4.3 上电五检与第一次站立测试
第一次让机器人站起来,我的习惯是执行“上电五检”,每一条都不过关就严禁通电:
- 检查每个关节的机械位置是否在中位附近,并确认无干涉;
- 检查电池电压和两组降压模块输出是否正常(舵机端6V、主控端5V);
- 用串口查看MPU6050姿态数据是否在水平放置时接近0度;
- 手动把所有关节搬到“待机位”(双膝微屈、手臂自然下垂、重心压低);
- 第一次上电必须手扶机架或把机器人的髋部用绳子吊住,防止突然跌倒损坏结构。
完成五检后,第一次“站立”目标不是直腿站,而是“微蹲站”。双膝弯曲约10到15度,髋关节略微前倾,把整体重心降低到接近脚掌中心。这种姿态下对舵机误差和结构虚位的容忍度高得多。测试时观察三件事:机身是否明显抖动、脚底压力是否基本均匀、MPU6050的俯仰角是否稳定在几度以内。如果脚底压力某一侧明显偏大,说明重心投影偏移,直接调整骨盆位置的电池位置来配重,比调步态参数快得多。
4.4 从站立到慢速步态的调试顺序
站立稳定后,不要急着写完整的走路步态。我的调试路径是“起身-微蹲-重心转移-抬脚-落脚-单步”六步走:
- 第一周只做起身和微蹲,让机身习惯重心变化;
- 重心转移:站立状态下,控制髋侧向移动,把重心平移至左腿上,观察右脚是否可微抬;
- 抬脚测试:在重心完全偏向右脚的瞬间,控制左腿髋和膝做小角度抬升(先2厘米),保持1秒后放下;
- 单步完整流程:重心转移→抬脚→摆腿→落脚→重心回中,每一步切换之间至少留500ms缓冲时间。
动作切换之间的缓冲时间,是起步阶段最重要的参数。过快切换会让舵机瞬间吃大电流,也会让姿态控制器来不及修正,直接摔倒。我建议每步动作之间至少延时300ms,整套动作执行周期不低于2秒,先把“慢得看起来像树懒”的步态跑顺,再逐步提速。
5. 常见问题与排查实录
5.1 舵机抖动、复位与过载
我实测下来,这三个问题八成以上是电源问题。
舵机抖动,多半是电源电压在舵机负载瞬间跌落导致的。检查顺序是:先用万用表测舵机端电压,如果摆动时低于5.5V就换更大电流的降压模块,或者在舵机总线上并联更大容量的电解电容。如果电压稳定但依然抖,检查信号线是否过长或与舵机电源线捆在一起,信号线加100Ω电阻或独立走线都能缓解。
机器人上电瞬间猛跳一下就复位,通常是PCA9685在上电初期输出不确定电平导致的。解决方法是:主控程序里在初始化I2C之前,先把PCA9685的OE(输出使能)引脚拉高并接一个10kΩ上拉电阻,等初始化完成后再拉低使能输出。这个方案是我后期加上的,实测能消除90%的上电猛跳问题。
舵机发热严重,尤其是膝关节这种持续承重的关节,第一步先考虑机械问题:齿轮是否卡阻、连杆预紧力是否过大、双舵机并联时是否互相别劲。排除机械原因后,如果只是发热但不剧烈,可以把舵机电压从6.5V降到6.0V减少热损耗,代价是扭矩略微下降。中配方案本来就是性能紧平衡,动作设计时尽量避免长时间大角度弯腿急停。
5.2 姿态漂移与零点漂移
MPU6050的姿态角漂移,几乎每个做机器人都会遇到。表现是:开机静止时角度是0,过两分钟变成2度,再过五分钟更大。这不是硬件坏了,而是陀螺仪零点偏置没有校准。
解决分两步:第一步,上电后抓取前500组数据求平均作为零点补偿量,之后每组数据都减去这个零偏;第二步,姿态解算中把陀螺仪积分结果与加速度计结果做互补滤波,抑制积分漂移。还有一点容易被忽略:MPU6050的安装方向必须精确对齐机身坐标轴,差哪怕1度,实际站立时候的姿态都会显得歪斜。安装时用直角三角尺校准,不要目测。
5.3 典型问题速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 某个舵机完全不动 | 信号线松动/通道配置错误 | 先替换舵机验证,再查PCA9685通道号 |
| 所有舵机上电猛跳 | 输出使能未在初始化前关断 | OE脚先拉高,初始化完成再拉低 |
| 腿部舵机频繁过载 | 双舵机并联不同步 | 校准两舵机中位并检查联动臂间隙 |
| 站立后持续往一侧倒 | 重心偏移或左右腿长度差异 | 调整电池配重,检查左右连杆实际长度差 |
| 姿态数据噪声大 | 电源地线干扰或传感器固定松动 | 独立电源地共点,MPU6050与机架减震连接 |
| 步态执行卡顿 | 刷新频率不稳定/中断被占用 | 把PWM刷新放到最高优先级定时器中断 |
5.4 几个避开返工的小技巧
分享几个实操过程中积累的小技巧,能帮你少拆几次机。
第一,给每个舵机做标签。拆卸时最容易搞混线序和通道,我就吃过亏:装完发现膝关节和髋关节信号线插反,机器人站起来时大腿往反方向别。做法很简单:每根舵机线两头贴标签纸,标注“左腿-髋-俯仰”。这个习惯在后期拆装维护时能省大量时间。
第二,紧固件用“两次锁紧法”。装配时第一次先拧到六成紧,调整好关节对中后再锁到八成紧,不要一次拧到死。打印件上的螺孔一旦滑丝,几乎没法修复,只能换件重打。
第三,姿态数据一定要写日志。每次调试步态时,把MPU6050的姿态数据和右脚压力数据通过串口打印并记录到电脑,跑完一组就能回放数据,判断到底哪一步重心转移不到位。这种回溯分析比肉眼盯着机器人猜原因高效太多。
第四,舵机信号线和电源线在关节处不要并行走线。信号线贴近舵机电源线时,舵机电流冲击的磁场会在信号线上感应出毛刺,表现出来就是舵机偶尔自己动一下。走线时让信号线走骨架另一侧,交叉处尽量成90度。
6. 后续还能怎么扩展
当这套22自由度平台能稳定完成慢速步态后,再往上走的方向其实很多。
可以把脚底换用真正的FSR力传感器阵列,配合重心控制算法,让机器人在受到外部推力时能主动迈步保持平衡——这一步开始进入动态平衡的范畴。也可以增加一个ESP32做上位机,通过WiFi接收手机控制指令,底层STM32负责实时舵机控制,主从架构对学习来说也很友好。如果想走视觉路线,在头部加一个USB摄像头,用边缘计算模块识别地面标记物,引导机器人朝标记方向前进,这就把“感知-规划-控制”的完整链路打通了。
不过要提醒一句:扩展功能前一定要先把基础平台调稳。我这个机器人目前依然不会连续动态行走,只在慢速静步态下可靠工作,距离“类人”还很远。但正是这种“勉强能走、随时会倒”的状态,逼着我把很多底层问题搞清楚——舵机扭矩的瓶颈、重心转移的时序、传感器噪声的表现,这些经验是从任何案例或视频里都学不到的。我把这些原原本本记录下来,也是想告诉你:中配预算做个能站稳的机器人,一点都不丢人,它是一个足够扎实的起点。