4500元,手搓一台会走路的人形机器人 | 第 14 章 抬脚与重心转移:细节决定成败
上一节:4500元,手搓一台会走路的人形机器人|第 13 章 跨步恢复:被推倒时如何自救
第四部分:平衡控制算法
第 14 章 抬脚与重心转移:细节决定成败 从双脚站立到单脚支撑,每一步都如履薄冰
14.1 原地跨步的关节验证
第13章讲了跨步恢复的整体框架。但在写代码让机器人迈步之前,我犯了一个错误——直接写代码,结果要么抬脚太低拖地,要么抬太高失去平衡。折腾了好几天才发现,问题不在代码,在姿势。我应该先用关节测试工具验证每个关节在抬腿时应该到什么角度。
关节测试工具可以逐个关节、逐个角度地发送指令,实时观察机器人姿态。抬腿验证的流程:先让机器人进入站立姿势,然后手动调整抬腿腿的膝关节(21→50度)、髋关节前摆(-5→15度)、踝关节(-11→0度),最后用手推测试稳定度。花了大概半天,但值——一旦确定了标准姿势,代码只需复现,不需要反复试错。
经过反复测试,确定的抬腿姿势如下:
| 关节 | 站立姿势 | 抬腿姿势 | 变化量 | 说明 |
|---|---|---|---|---|
| 膝关节 (knee) | 21° | 50° | +29° | 弯曲抬腿,提供主要抬腿高度 |
| 髋关节前后 (hip_pitch) | -5° | 15° | +20° | 前摆大腿,控制迈步方向 |
| 踝关节前后 (ankle_pitch) | -11° | 0° | +11° | 保持脚掌水平,防止戳地 |
| 髋关节侧向 (hip_roll) | 8° | 8° | 0° | 保持不动,维持左右稳定 |
| 踝关节侧向 (ankle_roll) | -8° | -8° | 0° | 保持不动,维持左右稳定 |
膝关节从21°到50°,让脚掌离地约3-4cm——足够越过地面不平整,又不会太高。髋关节前摆20°,大腿前送约10-15cm。侧向关节保持不动,因为抬腿是前后方向的动作。
其实不只是抬腿,站立的参考姿势(第12章讲的踝-11°、腰-9°等)也是通过关节测试工具先验证的。这个「先验证,再编码」的流程,是我整个项目中最重要的工作习惯——把「猜」变成了「验」。
抬腿姿势不是算出来的,是试出来的。关节测试工具让你在写代码之前,就知道每个关节应该到什么角度。这个「先验证,再编码」的流程,帮我省了无数调试时间。
14.2 重心转移的实战
第13章讲了重心转移的理论——用ZMP反馈控制,把重心从双脚中心移到支撑脚上。这一节讲实战细节。
14.2.1 从双脚到单脚的过程
重心转移不是瞬间动作,而是持续约0.5-1.0秒的渐进过程。具体步骤:
- 初始状态:ZMP在双脚中心,两只脚压力各约50%。
- 开始转移:髋关节侧向缓慢调整。要抬右脚时,左髋微外展、右髋微内收,把上半身重心往左移。
- 持续监测:每10ms读取一次ZMP,如果偏离目标方向就微调髋关节角度。
- 到达目标:ZMP到达支撑脚掌中心,支撑脚承受95%以上体重。
- 稳定确认:ZMP在目标位置停留至少200ms后,才允许抬脚。
14.2.2 ZMP追踪控制器
我用代码实现了一个ZMP追踪PID控制器,核心逻辑:比较当前ZMP和目标ZMP,用误差驱动髋关节侧向移动。
# ZMP追踪控制器核心逻辑
# 比较当前ZMP和目标ZMP,用误差驱动髋关节侧向移动
zmp_error = target_zmp - current_zmp
hip_roll_adjust = Kp_zmp * zmp_error \
+ Kd_zmp * zmp_error_rate
# 限制调整速度,防止过快导致重心冲过头
hip_roll_adjust = max(-max_speed,
min(max_speed, hip_roll_adjust))
ZMP追踪参数:Kp_zmp = 0.3(每1cm误差调整髋关节0.3°),Kd_zmp = 0.05,max_speed = 0.3 rad/s。这些参数比站立平衡的PD参数慢,因为ZMP追踪可以接受50-100ms级响应,不需要10ms级。
14.2.3 双重确认抬脚时机
我同时使用两个信号判断是否可以抬脚:ZMP在支撑脚内,且被抬脚的压力降到初始值的10%以下并持续100ms。ZMP是计算值,有延迟和噪声;压力传感器是直接测量——「脚上没压力了」就是最直接的信号。两者必须同时满足,双重确认,确保万无一失。
脚底板离地的时机不能只靠ZMP判断。ZMP是计算值,有延迟;压力传感器是直接测量,更可靠。两者同时满足,才允许抬脚。
14.3 抬脚的机械实现
确定了抬腿姿势,完成了重心转移,现在可以真正抬脚了。但「抬脚」不是「把三个关节角度设为目标值」这么简单——速度、加速度、协同顺序,每个细节都影响成败。
14.3.1 抬脚指令的分步启动
抬脚时三个关节不是同时到达目标角度的,而是有先后顺序:
第一步:膝关节先弯曲。 从21°到50°,约0.3秒,把脚从地面提起。此时髋关节和踝关节保持不动。
第二步:膝关节弯到一半时,髋关节开始前摆。 从-5°到15°,约0.3秒。此时小腿继续弯曲,大腿同时前送。
第三步:髋关节前摆到一半时,踝关节开始调整。 从-11°到0°,约0.2秒,让脚掌保持水平。此时三个关节同时动作,完成抬腿。
如果三个关节同时启动,重心会突然变化,容易失衡。分步启动虽然总时间稍长,但每个阶段只有1-2个关节在动,重心变化更平滑。
14.3.2 速度和加速度限制
全速转动会导致惯性晃动、多关节合力推倒机器人、齿轮冲击。所以我对抬脚做了限制:最大角速度 0.5 rad/s,最大角加速度 2.0 rad/s²。膝关节从21°到50°(29°变化),最快约1秒;从静止加速到最大速度需约0.25秒。这些限制让抬脚从「啪」一下变成「缓缓抬起」,稳定性大大提高。
14.3.3 落脚缓冲与稳定性恢复
落脚缓冲分三级:快速下落(脚掌>2cm,膝0.3 rad/s)→ 缓冲减速(1-2cm,降至0.1 rad/s)→ 轻柔触地(<1cm,降至0.05 rad/s)。全过程约0.7-1.0秒,是落脚后不弹跳的关键。这部分在第13章已有详细展开,这里不再重复。
脚落地后,机器人还需要0.5-1.0秒的调整期。期间PD控制器以较高增益快速把ZMP拉回中心,重心从单脚恢复到双脚均匀承重。当ZMP回到双脚中心且压力分布恢复到50%±10%时,切换回正常站立PD参数,完成整个恢复流程。
抬脚不是关节的简单组合,而是有顺序的协同。膝先弯、髋再摆、踝最后调。分步启动比重心同时变化更安全。
14.4 避坑清单
抬脚和重心转移的坑,主要集中在细节上。每一个坑都伴随着至少一次摔倒。
| 序号 | 坑 | 现象 | 原因 | 解决 |
|---|---|---|---|---|
| 1 | 未验证抬腿姿势就写代码 | 抬腿时姿态怪异 | 关节角度不合适 | 先用关节测试工具验证 |
| 2 | 三关节同时启动 | 抬腿瞬间机器人晃动 | 重心突变 | 膝先弯再髋后踝分步启动 |
| 3 | 抬脚速度太快 | 抬腿过程中失衡 | 惯性过大 | 限速0.5 rad/s |
| 4 | 仅靠ZMP判断抬脚时机 | ZMP显示OK但抬脚后倒 | ZMP计算有延迟 | 加压力传感器双重确认 |
| 5 | 压力阈值太高 | 抬脚时脚还有压力 | 未完全卸载就抬脚 | 压力小于10%才允许 |
| 6 | 落脚无分级缓冲 | 落脚冲击大机器人弹跳 | 单速下落 | 三级缓冲快中慢 |
| 7 | 落脚后立刻切换参数 | 参数切换导致抖动 | 重心未恢复就切换 | 落脚后等待0.5-1.0s调整期 |
| 8 | 抬腿时侧向关节动了 | 左右方向失衡 | 侧向关节参与前后动作 | 侧向关节保持不动 |
| 9 | 踝关节未调整 | 脚尖戳地 | 脚掌未保持水平 | 踝关节调至0° |
| 10 | 迈步距离过大 | 重心超出支撑面 | 步幅超过关节活动范围 | 正常迈步10-15cm |
抬脚和重心转移是双足机器人最核心的动作基元。走路、上下楼梯、跨障碍——所有这些高级动作,都是抬脚和重心转移的组合。把这两个基础动作做好,后面的一切都会容易很多。
第14章 完
第四部分完结 | 下一部分:参数调优与数据驱动
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)