资讯动态

足式机器人平衡算法:从倒立摆模型到实机部署的完整指南

发布时间:2026/10/14 18:18:06 来源:尧图企业网站定制
简介足式机器人平衡算法的经典文献源自Marc H. Raibert的《Legged Robots that Balance》适合机器人控制、仿生运动与人工智能交叉领域的研究者及进阶学习者阅读。文档系统梳理了腿足式机器人从弹性腿模型到三维空间奔跑控制的发展脉络并围绕主动平衡、运动控制、动力学建模、传感器融合与反馈控制等关键环节展开论述。压缩包内为1份PDF全文大小7.13MB适合离线阅读与批注。该资源已有394人学习下载可作为足式机器人控制理论入门的参考资料。内容除正文外还包含目录框架与作者的前言叙述章节安排从研究动机、动力学与平衡性分析到奔跑控制分解、三维空间运动及多腿系统均有系统性论述读者亦可从中了解Leg实验室的研究历程、实验录像带索引以及动态腿部系统控制中尚未解决的开放问题有助于把握平衡算法的核心思路与历史背景。1. 足式机器人平衡算法从经典文献到能跑的控制器四足、双足机器人真正难住人的从来不是机构设计而是让那条单腿在落地瞬间不“跪”下去的那几百毫秒。市面上大多数开源足式机器人项目硬件装起来一周但调平衡稳定至少要一个月——原因在于大家把“平衡”理解成了“静态站稳”而真实场景里机器人每一步落地都是一次动态冲击。doc1里那份经典文献《Legged Robots that Balance》早在几十年前就把答案写清楚了平衡不是力大出奇迹而是把机身建模成一个倒立摆用关节力矩去“追”质心的加速度轨迹。这篇笔记我会按照从原理到落地的顺序把倒立摆建模、ZMP 判据、仿真到实机的迁移、增益整定这些环节逐个拆开给出可以直接复用的代码与参数经验。如果你正在做四足机器人或者双足项目的姿态控制发现自己明明PID 调得很“稳”但机器人一走起来就东倒西歪那这篇文章就是给你写的。我会刻意绕开那些玄学调参套路用一条从状态方程到代码实现的完整链路让你知道每一步在干什么、为什么这么干以及实机上最常见的翻车点在哪。2. 平衡算法核心模型倒立摆与 ZMP 的理论基础2.1 为什么线性倒立摆模型能描述足式机器人的动态平衡足式机器人平衡算法里最经典、也最容易被新手误用的模型是线性倒立摆模型Linear Inverted Pendulum ModelLIPM。理解它的第一步是接受一个事实我们不是要模拟机器人每条腿的完整动力学而是把整个机身等价成一个集中质量点这个点位于质心位置腿则被抽象成一根无质量的可伸缩杆杆底端就是支撑脚与地面的接触点。之所以能做这种简化是因为足式机器人行走过程中支撑腿承受的力主要沿腿轴方向而摆动腿的惯性力相对整机质量来说占比极小。把动力学方程在质心高度恒定的约束下做线性化之后水平方向的运动方程会变成x_ddot g / z_c * (x - p_x)这里x是质心水平位置z_c是质心高度假设恒定p_x是 ZMP零力矩点位置g是重力加速度。这个方程的价值在于它把“平衡”这个问题从关节空间直接映射到了“质心- ZMP”这对变量上。控制目标因此变得极其清晰——你不需要关心每条腿的关节角是多少只需要保证 ZMP 落在支撑多边形内部机器人就不会翻倒。实际工程中我在做双足机器人时通常把目标 ZMP 轨迹规划成前后摆动的正弦曲线然后反解出质心轨迹作为前馈四足机器人对角小跑时则用同样的方程分别解出前后方向和左右方向的质心运动。这里有个容易犯的错误LIPM 只在质心高度近似恒定时才成立如果你把机器人做成一跳一跳的弹跳步态那么就必须换成弹簧倒立摆模型SLIP否则模型误差会直接让控制器发散。2.2 ZMP 判据的物理意义与工程简化ZMPZero Moment Point零力矩点的定义是地面对机器人反作用力的合力在地面上的作用点且该点处合力矩为零。听起来很学术但工程上的意义非常直白——如果 ZMP 落在支撑脚的凸包范围之外机器人就会绕支撑多边形边缘翻转也就是说ZMP 就是“机器人会不会倒”的判据。实际测量 ZMP 有两种方式一种是依靠力传感器通过六个力/力矩传感器直接计算地面反力的作用点另一种是依靠动力学模型估计用关节角度、角速度和力矩通过浮基动力学方程推算。我个人的经验是如果硬件条件允许优先用脚底力传感器测 ZMP因为模型估计的方式依赖惯量参数标定而惯量参数在实机上很难标准——尤其是在加了各种载荷之后。ZMP_x - (M_y x_com * F_z z_com * F_x) / F_z注意这个计算里最容易被忽略的项是z_com * F_x。当机器人快速前进或后退时水平方向的惯性力会产生一个绕 y 轴的力矩这个力矩直接改变了 ZMP 位置。很多同学在实机上看到的“机器人加速时前倾翻车”本质上就是没有把质心高度的水平加速度产生的力矩算进 ZMP 里。工程简化上我一般把 ZMP 算出来之后做一个低通滤波截止频率设在 510Hz 左右因为力传感器的噪声很大直接拿原始值做闭环控制会让关节抖动得厉害。滤波引入的延迟大约 2050ms对平衡控制来说是可以接受的但对快速扰动比如突然踢一脚的响应会有明显延迟所以控制频率至少要跑到 1kHz 以上才有足够的相位裕度。2.3 捕食者-猎物模型LIPM 如何转化为可执行的控制量有了 LIPM 状态方程和 ZMP 目标轨迹之后接下来要解决的是“怎么把 ZMP 误差换算成关节力矩”。常见做法是分两层上层是质心轨迹跟踪用 ZMP 误差做反馈修正质心加速度下层是关节力矩映射把质心加速度通过逆动力学换算成各关节力矩指令。上层控制我常用的形式是比例-积分控制加前馈x_cmd_ddot x_ref_ddot Kp * (x_ref - x) Kd * (x_ref_dot - x_dot) Ki * integral(zmp_ref - zmp)这里x_ref_ddot是从规划器来的前馈加速度Kp和Kd是质心位置和速度的反馈增益。Ki项针对 ZMP 误差做积分用来消除脚底打滑或者斜坡导致的静态偏差。积分项的系数要很小否则容易在支撑脚切换时产生较大的过冲。下层转换到关节力矩我一般直接用浮基逆动力学Floating Base Inverse Dynamics而不是逐关节做 PID。原因很简单足式机器人是闭链系统加浮基关节空间 PID 处理不了身体姿态和质心运动的耦合。具体实现上可以用开源的任务空间控制库来解算也可以手动推导拉格朗日方程后做数值求解。实际调试中Kp和Kd的初始值可以按临界比例法来定先把Kd设为零Kp从 0.5 开始逐步增加直到机器人出现等幅振荡记录此时的Kp_crit和振荡周期T_crit然后按经典 Ziegler-Nichols 的经验公式取Kp 0.6 * Kp_critKd取0.1 * Kp_crit * T_crit附近做微调。后面整定章节我会详细说这个过程的踩坑。3. 从仿真到实机的平衡控制器实现路径3.1 在 MuJoCo 里搭建一个四足机器人的平衡仿真环境先说明这里的仿真环境搭建目的不是做步态规划而是专门验证平衡算法的鲁棒性。我的习惯是先搭一个包含四条腿的简化刚体模型躯干用一个大质量的长方体代替每条腿三个自由度髋关节横滚、髋关节俯仰、膝关节俯仰这样既能体现足式机器人的主要动力学特性又不会因为模型太复杂导致仿真速度过慢。MuJoCo 的 XML 模型文件里核心要设置好三个地方关节的armature电机转子惯量折算、frictionloss关节库仑摩擦和接触参数。armature这个参数直接影响关节响应的快速性设太小会让仿真里的关节像“空心轴”一样反应过度灵敏实机上根本达不到。我通常会把电机转子惯量等效到关节上大概占连杆惯量的 10%20% 之间。接触参数里最关键的solimp和solref分别控制接触的硬度和阻尼。这里有一个经验值让接触硬度适中避免仿真中脚底接触地面时出现高频振铃。如果仿真里脚底一落地就弹起来多半是接触参数设置过刚把solref的第二个值调大增加阻尼就能解决。default joint armature0.05 damping0.5 frictionloss0.5/ geom friction1.0 solimp0.9 0.95 0.001 solref0.01 1.0/ /default上面的friction设置的是库仑摩擦系数solimp的前两个值决定接触力的非线性过渡形状solref决定接触动力学的时间常数。仿真中如果发现机器人站不稳先别急着调控制器参数优先检查接触参数是否合理——这是最容易被忽视的坑。3.2 单腿站立平衡的最小闭环控制代码当模型建好之后第一个要跑通的任务是“单腿站立平衡”。这里我直接用 LIPM 质心反馈作为外环内环用关节空间的力矩映射。下面这段代码是一个最小可运行版本重点展示状态获取、平衡控制律计算、力矩下发三个环节import mujoco import numpy as np # 获取状态 data.qpos # 关节位置 data.qvel # 关节速度 x, z data.qpos[0], data.qpos[2] # 机身质心位置 dx, dz data.qvel[0], data.qvel[2] # LIPM 平衡控制器 z_c 0.45 # 质心高度目标 g 9.81 x_ref 0.0 # 期望质心位置 dx_ref 0.0 # 期望质心速度 kp 80.0 # 等效比例增益 kd 2 * np.sqrt(kp) # 临界阻尼对应的微分增益 # 计算期望的质心水平加速度 x_ddot_ref g / z_c * (x - x_ref) kd * (dx - dx_ref) # 期望的足底反力 质量 * 加速度 重力补偿 m data.body(trunk).mass f_x m * x_ddot_ref f_z m * g m * dz # 垂直方向做重力补偿加阻尼 # 利用雅可比矩阵映射为关节力矩简化版 J np.zeros((2, 3)) # 此处应从 MuJoCo 获取对应雅可比 tau J.T np.array([f_x, f_z]) data.ctrl tau这段代码的核心逻辑是外环把机器人当成一个倒立摆计算出需要施加在质心上的水平力内环通过雅可比矩阵把这个力分配到腿部各关节的力矩上。参数里最关键的是kp和kd的匹配关系kd 2*sqrt(kp)给出的是临界阻尼响应也就是机器人回到平衡位置时既不超调也不振荡的理想状态。实际运行中你会发现单腿站立时机器人的髋关节横滚方向侧向比前后方向更难稳定原因在于侧向的支撑多边形宽度更窄ZMP 允许的移动范围更小。所以我会在侧向通道把kp适当调低 30% 左右同时增大kd用更“肉”的响应换取稳定裕度。3.3 步态切换时的平衡保持策略从静态到动态的过渡单腿站稳之后下一个难点是走路过程中支撑腿切换瞬间的平衡保持。这里最常见的设计模式是“分时控制”单腿支撑期用 LIPM 平衡控制双腿支撑期用位置插值过渡切换时刻用冲击力补偿来处理载荷转移。我做四足对角小跑时通常把每个步态周期分成四个阶段支撑前段对角两条腿着地质心向前移动、支撑后段后腿蹬地产生推进力、腾空相四条腿全部离地靠躯干姿态控制维持姿态、落地缓冲前腿落地吸收冲击。其中腾空相对平衡算法最不友好因为此时 ZMP 没有任何物理意义必须切换到姿态控制模式。落地缓冲的瞬间是最容易翻车的时刻。我常用的做法是在落地前 30ms 预测落地腿的位置提前将落地腿的关节力矩设为“软阻尼”模式也就是只提供阻尼力、不提供位置跟踪力让腿像弹簧一样缓冲落地冲击。落地完成后 50ms 再把控制权交还给 LIPM 平衡控制器。# 落地缓冲状态切换伪代码 if leg_contact and not prev_contact: set_leg_impedance(low_stiffness, high_damping) enter_landing_buffer_mode() elif time_since_contact 50ms: set_leg_impedance(normal_stiffness, normal_damping) enter_lipm_balance_mode()这个切换过程在仿真里很容易被忽略但实机上极其重要——很多同学的四足机器人在仿真里走路很稳一上实机每走一步都像踩棉花一样晃大概率就是落地缓冲没有做相当于每次落地都是一次随机冲击输入。4. 平衡控制器增益整定从仿真参数到实机鲁棒性4.1 增益整定的三个层次关节内环、姿态中环、平衡外环足式机器人平衡控制器的参数整定我的经验是必须分层进行绝对不能在整定完关节内环之前就去调平衡外环。层次之间有一个不可跳过的顺序关节力矩环电流环→ 关节位置环PD 或 PID→ 机身姿态环横滚、俯仰、偏航→ 质心平衡环LIPM 控制器。每一层都有独立的响应带宽要求。关节力矩环带宽要最高通常期望在 100Hz 以上关节位置环带宽 1030Hz姿态环带宽 38Hz质心平衡环带宽再低一些。如果上一层比下一层的带宽没有拉开 3 倍以上的差距那么下一层会把上一层的动态耦合进来整个系统就会出现“你调我的、我调你的”的相互干扰。拿一个我做过的双足项目举例某次机器人站立时出现持续横滚方向抖动频率约 4Hz。我当时以为是 ZMP 反馈增益太高把Kp调低了一倍结果抖动反而加剧了。后来排查发现是姿态环带宽当时约 12Hz和平衡环带宽约 5Hz之间差距不够姿态环的修正力矩干涉了平衡环的质心控制。把姿态环带宽降到 6Hz 之后抖动立刻消失。4.2 用轨迹圆滑度评估整定参数好坏的量化方法调参不能靠手感需要有可量化的评估指标。我常用的一个指标是“支撑腿关节力矩的平滑度”具体计算方式是相邻两个控制周期内关节力矩差值的 RMS均方根值τ_smoothness RMS(τ(t) - τ(t - ΔT))这个值越小说明控制器输出越平滑也意味着机械磨损越少。如果这个值偏大有两种可能一是传感器噪声大、滤波不够二是某个反馈环增益偏高导致输出出现“毛刺感”。在仿真里我会把力矩平滑度和 ZMP 误差的 RMS 放在一起看两个值同时低才算全局最优。另外有个很实用的技巧记录机器人受到冲击后的恢复时间。具体做法是在机身后方用绳子拉住然后释放记录机身俯仰角从最大偏差恢复到 ±2° 以内所用的时间。这个时间如果小于 1 秒说明姿态环的响应够快如果大于 2 秒说明增益偏低或者摩擦模型不准导致控制力矩在前几拍被摩擦力吃掉了。4.3 实机调试时参数需要妥协的三个地方电机饱和、结构共振、地面打滑仿真里可以无限追求跟踪精度但实机上有三个物理约束直接决定了你最终用的参数一定是一个“折中值”而不是“最优值”。第一个约束是电机力矩饱和。LIPM 控制器给出的期望质心加速度在仿真里可以放大Kp到任意值来增强抗扰能力但实机上髋关节电机的峰值力矩是固定的。当 ZMP 误差较大时期望力矩会超过电机饱和值这时控制器的实际输出被截断等效增益瞬间下降。解决方法是做“力矩限幅下的抗积分饱和”在积分项里加入torque_saturated的反馈项让控制器意识到输出已经限幅停止继续积分。第二个约束是结构共振。每个足式机器人都有机械共振频率通常在 820Hz 之间。如果你的姿态环增益过高修正力矩的频率可能正好落在共振点附近机械本身会被激励起来表现为机身持续高频振动而且你会看到关节角度反馈正常、但机身传感器数据在剧烈波动。对策是在控制器输出前加一个低通滤波器截止频率设在 15Hz并避免在共振频率附近设置过高的增益。第三个约束是地面打滑。脚底与地面的摩擦系数取决于接触材料在干燥地毯上和潮湿瓷砖上差异很大。ZMP 控制的前提是支撑脚相对地面不打滑一旦打滑ZMP 反馈会给出错误的“平衡”信号控制器会往错误方向加力越拉越倒。实机上我至少会在两种以上地面测试一遍参数如果最优参数差异超过 30%就得做“地面自适应”用一个滑动窗口估计脚底速度检测到滑动时降低 ZMP 反馈增益。5. 平衡算法实战避坑指南三条血泪经验与排查路径5.1 仿真里站得稳实机上一站就倒摩擦模型与接触刚度的差异现象仿真环境中单腿站立可以保持 5 分钟不晃但同一套代码部署到实机后机器人站上去 2 秒内就向某个方向倾倒反复试都一样。原因90% 以上的情况是仿真里的接触参数和实机的脚底-地面接触差异过大。MuJoCo 默认的接触刚度很高脚底微小的滑移会被模型自动约束掉相当于“虚拟钉子”而实机上橡胶脚垫有法向形变和切向柔顺导致 ZMP 的实际支撑边界比仿真里小等效支撑多边形缩水了。解决在仿真里故意降低接触刚度同时调高摩擦系数到 1.21.5 左右让模型“变笨”一点。具体做法是把solref的时间常数调大 35 倍并减少friction到实际材料的保守值。如果调完参数后仿真里的机器人也开始偶尔滑动恭喜你仿真终于和实机“对齐”了。我通常还会在两个仿真环境下跑对比——一个默认参数、一个保守参数控制器的参数必须同时通过这两个环境才算合格。5.2 站立时持续低频抖动姿态环与平衡环带宽打架现象机器人站立时看起来在“打哆嗦”机身以 35Hz 频率持续前后或左右小幅振荡振幅不大但一直不衰减。原因这是最典型的控制带宽耦合问题。姿态修正的响应带宽和质心平衡环的带宽重叠姿态环检测到微小姿态偏差就产生修正力矩这个力矩改变了支撑腿的受力分布进而让 ZMP 发生变化平衡环感知到 ZMP 变化后再次输出修正形成闭环振荡。解决先把姿态环的带宽降下来同时在 ZMP 反馈通道加带通滤波把 35Hz 这个频段的信号衰减掉。需要注意的是不要只调一个环的参数——要同时调整两个环的带宽比例让姿态环带宽至少是平衡环带宽的 2 倍以上或者反过来让平衡环慢到不会去响应姿态环的修正动作。还有一个容易被忽略的点机身 IMU 的安装位置如果不在质心附近角速度测量的耦合误差也会激发这种振荡排查时绕着 IMU 底座加点减震垫往往有奇效。5.3 单腿落地瞬间脚跟“软掉”或“硬顶”切换逻辑时序不对现象机器人在行走步态中支撑腿落地的那一刻膝关节先是不受力一样地弯曲然后突然变硬机身明显顿挫一下严重时直接把机身弹向反方向。原因落地缓冲和位置跟踪两种模式的切换时序不当。如果切换太早——脚还没真正触地就把关节切成低刚度模式那么落地那一刻腿会因为自重快速弯曲没有足够的支撑力如果切换太晚——已经触地了还在执行高刚度的位置跟踪那么落地冲击会被直接传导到机身表现为硬碰硬的冲击。解决用脚底接触传感器力传感器或触觉开关作为模式切换的真值触发而不要用时间估算。切换逻辑做成两段式预测触地前 20ms 进入“快接近模式”中等刚度、高阻尼实际触地后 40ms 进入“缓冲模式”低刚度、极高阻尼等机身运动速度归零后再恢复位置跟踪。这里面有个小技巧判断缓冲模式结束不能只看时间要看机身垂直方向速度是否已经低于某个阈值比如 0.05m/s否则在楼梯等不规则地形上会因为固定时间过长而摔倒。6. 更进一步的平衡技巧用加速度反馈补偿足端力矩干扰当你的机器人已经能站稳、能走直线之后如果还想提升抗冲击能力我推荐一个进阶方向加速度反馈补偿。基础版的 LIPM 控制器相当于一个质心位置/速度的 PD 控制它只能被动地响应扰动。也就是说机器人必须先被推一下产生位置偏差控制器才能开始修正。这在静平台上是够用的但如果在行走中遇到地形突变或外力冲击被动响应往往来不及。我常用的做法是加入机身加速度前馈。具体实现在机身质心位置安装一个三轴加速度计或者从 IMU 中提取加速度信号把这个加速度信号直接加到质心期望加速度上x_ddot_final x_ddot_ref K_ff * (x_ddot_measured - x_ddot_model)这里的K_ff通常在 0.10.4 之间。它做的事情本质上是当外力让机身产生加速度变化时控制器立刻感知到这个变化通常是滞后 5ms 内直接调整力矩输出而不需要等位置积分出偏差。这个技术对于抗侧向踢腿效果非常明显——不加这个补偿时侧向推一下大约要 300ms 才能恢复平衡加上之后100ms 内就能把机身拉回目标位置。但要注意一个非常隐蔽的坑加速度计测量到的信号包含重力分量所以在做加速度反馈之前必须先做重力解耦。如果你直接把 IMU 的三轴加速度数值拿来用K_ff只要大于 0.1机器人就会因为重力分量被当成干扰反馈而持续产生错误力矩表现就是站立时关节“发硬”且伴有低频哼声。我见过不止一个同学在这个问题上卡了一周最后发现是忘了减掉[0, 0, 9.81]这个重力偏置。另外一个实用技巧是把加速度信号做 30Hz 左右的低通滤波之后再做反馈因为加速度计的高频噪声很大不过滤波引入的延迟也会让补偿效果打折扣。我的做法是用互补滤波——加速度信号经过低通、角速度信号经过高通两者融合后得到一个比单独用加速度计噪声更小、比单独用角速度延迟更低的反馈信号。方法层面讲到这里最后分享一个自己总结的调试习惯每次给足式机器人换一套平衡参数我都会先在地面铺一层 3cm 厚的软垫上测试然后把软垫换成硬木板再到瓷砖地面。这样从阻尼最充足到最小摩擦的过渡过程中你能清晰感觉到控制器在哪个环节开始力不从心——是电机饱和了还是接触模型不对了还是带宽耦合了。调平衡算法没有“一次到位”的灵丹妙药但有了这条感知链路和上面的排查路径至少每一轮迭代都知道该往哪个方向使劲。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑