ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

人型机器人ZMP零力矩点控制:从倒立摆模型到动态步态稳定性实战

人型机器人ZMP零力矩点控制:从倒立摆模型到动态步态稳定性实战 1. 从零力矩点说起人型机器人为什么离不开ZMP人型机器人走路这件事外行看热闹内行看门道。很多人第一次接触双足机器人控制脑子里想的都是关节怎么转、步态怎么规划但真正上手之后才会发现最核心的问题其实只有一个——机器人会不会摔。而判断它会不会摔最经典、最基础、也最经得起时间考验的工具就是零力矩点Zero Moment Point简称ZMP。我第一次认真研究ZMP是在调试一台小型双足平台的时候。当时机器人静态站着没问题一旦迈步就往前扑调了无数遍PID都没用。后来才意识到问题根本不在关节控制而在于整个身体的质心投影和地面反作用力之间的关系没搞对。ZMP这个概念就是用来描述这个关系的。简单来说ZMP是地面上的一个点在这个点上地面反作用力的合力矩在水平方向上的分量为零。换句话说如果机器人脚底和地面之间的压力分布可以等效为一个合力那么ZMP就是这个合力的作用点。只要ZMP落在支撑多边形也就是脚掌与地面接触形成的区域内部机器人就不会绕边缘翻倒。这个判据非常直观ZMP在脚掌范围内稳ZMP跑到脚掌外面倒。这套理论最早由南斯拉夫的Vukobratović教授在1960年代末提出后来成为整个人型机器人领域的基石。日本本田的ASIMO、索尼的QRIO、波士顿动力的Atlas早期步态规划都绕不开ZMP。即使现在很多团队转向了基于模型预测控制MPC或者强化学习的方案ZMP仍然是最常用的稳定性约束之一。你可以不直接用ZMP做控制器但你很难完全忽略它。这篇文章适合谁看如果你正在做双足机器人、外骨骼、或者任何需要动态平衡的运动控制项目ZMP是你必须吃透的概念。如果你只是刚接触机器人运动控制想找一个切入点ZMP也是最好的起点之一——它数学上不复杂物理意义清晰而且有大量可复现的实操路径。下面我会从整体设计思路、核心细节、实操过程、常见问题几个方面把ZMP这套东西拆开讲清楚。2. 整体设计思路为什么用ZMP而不是别的2.1 ZMP的核心逻辑与适用边界ZMP的本质是把一个复杂的多刚体动力学问题简化成一个地面上的点是否在安全区域内的问题。这个简化非常聪明因为它抓住了双足行走最关键的矛盾机器人是一个倒立摆。你的身体重心越高脚掌越小就越容易倒。ZMP就是用来量化这个“容易倒”的程度。但ZMP不是万能的。它有几个明确的适用边界。第一它假设地面是刚性且水平的脚底和地面之间没有滑动。如果地面是软的、斜的或者脚底打滑ZMP判据就会失效。第二ZMP只考虑水平方向的力矩不直接处理绕垂直轴的旋转。如果机器人需要快速转身ZMP本身不够还需要配合摩擦锥约束。第三ZMP是一个准静态或者动态判据它不直接告诉你关节该怎么动只告诉你“当前状态安不安全”。我见过不少新手一上来就想用ZMP做全身控制结果发现计算出来的ZMP一直在支撑多边形边缘疯狂试探机器人走起来像喝醉酒。问题不在于ZMP错了而在于他们把ZMP当成了控制器而不是约束。正确的思路是用ZMP做稳定性判据用别的算法比如逆运动学、MPC、或者简单的步态生成器去生成关节轨迹然后不断检查ZMP是否越界。2.2 为什么不用纯静态平衡或者纯动力学有人会问既然ZMP这么麻烦为什么不干脆让机器人慢慢走每一步都静态稳定答案是效率。静态行走要求质心投影始终在支撑脚内这意味着机器人必须频繁地停下来调整重心步速极慢能耗极高。ASIMO早期演示的静态步态走一步要好几秒看起来像老爷爷过马路。而动态行走允许质心短暂地“失控”利用惯性往前冲ZMP可以在支撑多边形边缘甚至短暂越界只要整体轨迹能拉回来。这就是为什么ZMP在动态步态里更有价值。另一个极端是纯动力学控制比如用全身动力学加QP优化。这套方法理论上更精确但计算量大对模型精度要求极高而且调参非常痛苦。ZMP的好处是降维你不需要精确知道每个连杆的惯量只需要知道整体质心和角动量的大致范围就能做出一个可用的稳定性判断。对于大多数中小型双足平台ZMP加上简单的倒立摆模型已经能走出相当稳定的步态。2.3 方案选型从倒立摆到ZMP的完整链路我实际用的方案通常是这样一条链路步态规划器生成质心轨迹和落脚点 → 用线性倒立摆模型LIPM计算ZMP → 检查ZMP是否在支撑多边形内 → 如果越界调整质心轨迹或者落脚点 → 逆运动学解算关节角 → 底层关节伺服。这条链路里LIPM是关键。它假设机器人是一个质量集中在质心的倒立摆腿是质量为零的伸缩杆。这个假设在质心较高、腿部质量较小的情况下非常准。LIPM的动力学方程很简单质心水平加速度与质心到ZMP的距离成正比。具体来说如果质心高度是h重力加速度是g那么ZMP的位置x_zmp x_com - (h/g) * x_com_ddot。这个公式就是ZMP计算的核心。为什么选LIPM而不是完整动力学因为完整动力学需要知道每个连杆的质量、惯量、关节角计算量大而且模型误差会直接反映到ZMP上。LIPM只需要质心高度和质心水平位置参数少鲁棒性好。实测下来对于身高1米以内、质心高度0.5米左右的小型双足LIPM算出来的ZMP和实际测力台数据误差在1-2厘米以内完全够用。3. 核心细节解析ZMP计算与支撑多边形3.1 ZMP的数学定义与离散计算ZMP的严格定义是地面上一点p使得地面反作用力绕p点的力矩在水平方向的分量为零。对于多刚体系统ZMP可以通过以下公式计算x_zmp (Σ m_i * (x_i * (z_i_ddot g) - z_i * x_i_ddot)) / (Σ m_i * (z_i_ddot g))其中m_i是第i个连杆的质量x_i, z_i是连杆质心位置x_i_ddot, z_i_ddot是加速度。这个公式看起来复杂但实际用的时候如果你用LIPM简化就变成前面说的那个简单形式。在代码里我通常这样实现def compute_zmp(com_pos, com_acc, com_height, g9.81): com_pos: 质心水平位置 (x, y) com_acc: 质心水平加速度 (ax, ay) com_height: 质心高度 zmp_x com_pos[0] - (com_height / g) * com_acc[0] zmp_y com_pos[1] - (com_height / g) * com_acc[1] return zmp_x, zmp_y这个函数就是整个ZMP控制的核心。你可能会问为什么是减号因为当质心往前加速时ZMP会往后移这是倒立摆的物理直觉你往前冲脚底压力会往后压防止你往前倒。3.2 支撑多边形的构建与动态更新支撑多边形是ZMP必须落在里面的区域。对于双足机器人支撑多边形取决于当前哪些脚着地。单脚支撑时支撑多边形就是那只脚的脚掌轮廓双脚支撑时是两只脚掌轮廓的凸包。实际实现时我不会去算精确的凸包而是用脚掌的四个角点或者八个角点来近似。比如一只脚长20厘米、宽10厘米我就取四个角(0.1, 0.05), (0.1, -0.05), (-0.1, 0.05), (-0.1, -0.05)然后根据脚的位置和朝向变换到世界坐标系。双脚支撑时把两只脚的角点合在一起取凸包。这里有个坑支撑多边形不是固定不变的。当机器人抬脚时支撑多边形会从双脚变成单脚面积瞬间缩小一半。如果质心轨迹没有提前调整ZMP很容易在切换瞬间越界。我的做法是在步态规划阶段就预留一个安全裕度比如让ZMP始终保持在支撑多边形内缩5厘米的区域内。这样即使有模型误差或者地面不平也不容易翻。3.3 质心高度与ZMP灵敏度的关系质心高度h对ZMP的影响非常大。从公式x_zmp x_com - (h/g) * x_com_ddot可以看出h越大同样的质心加速度会导致ZMP偏移越大。这意味着高个子机器人更难控制因为质心高稍微一加速ZMP就跑到脚掌外面了。我实测过同一台机器人质心高度从0.4米调到0.6米同样的步态参数下ZMP波动范围扩大了约50%。所以如果你在调试时发现机器人走路晃得厉害可以先试试降低质心——比如把电池或者重物往下放。这是最直接有效的稳定手段比调任何参数都管用。另外h也不是越小越好。质心太低腿部伸缩空间受限步幅做不大而且能耗会增加。一般小型双足质心高度在0.3-0.5米比较合适中型人型0.6-0.9米大型的1米以上就要非常小心了。4. 实操过程从步态生成到ZMP验证4.1 线性倒立摆步态生成我用的步态生成方法是基于LIPM的解析解。给定一个步长和步时可以算出质心的自然轨迹。LIPM的方程是x_com_ddot (g / h) * (x_com - x_zmp)如果假设ZMP固定在支撑脚中心那么质心轨迹是一个双曲余弦函数。但实际行走时ZMP会随着脚步移动所以更常用的方法是预览控制提前知道未来几步的ZMP位置然后反推质心轨迹。具体步骤确定落脚点序列比如每步0.2米步时0.5秒。假设ZMP在单脚支撑时位于脚掌中心双脚支撑时线性过渡。用LIPM的离散递推公式从初始质心位置和速度出发计算未来N步的质心轨迹。检查每一步的ZMP是否在支撑多边形内。如果越界调整初始速度或者落脚点重新计算。这个过程我通常用Python写一个离线规划器跑一遍看轨迹图。如果ZMP曲线始终在支撑多边形内就把质心轨迹和落脚点发给机器人执行。4.2 逆运动学解算与关节角生成质心轨迹有了接下来要解算关节角。对于双足机器人通常用解析逆运动学因为腿是6自由度或者5自由度的串联结构。以常见的6自由度腿为例髋关节3个roll, pitch, yaw膝关节1个pitch踝关节2个roll, pitch。给定脚的位置和姿态以及髋关节位置可以解析求出所有关节角。这里的关键是髋关节位置。髋关节位置由质心位置和上半身姿态决定。如果上半身保持竖直髋关节就在质心正下方一定距离。如果上半身有俯仰髋关节会前后偏移。我一般让上半身尽量保持竖直减少耦合。逆运动学解算完还要做关节限位检查和速度限幅。我踩过的坑是规划出来的质心轨迹很漂亮但逆解出来的膝关节角超过了机械限位机器人直接卡死。所以每次解算完都要检查一遍关节角是否在范围内速度是否超过电机最大转速。4.3 ZMP实时验证与安全策略离线规划好了实际跑的时候还要做实时ZMP验证。我用的是足底压力传感器或者六维力/力矩传感器装在脚踝或者脚底。传感器数据经过滤波后可以直接算出实际ZMP。如果实际ZMP和规划ZMP偏差超过阈值比如3厘米就触发安全策略要么减速要么切换成静态站立要么直接断电保护。实测中我发现滤波很关键。原始力传感器信号噪声很大直接算ZMP会跳来跳去。我一般用二阶低通滤波器截止频率设在20-30Hz。截止频率太低ZMP响应滞后来不及保护太高噪声滤不掉。这个参数需要根据机器人质量和步频来调。另外安全策略要有分级。轻微偏差只报警不动作中等偏差降低步速严重偏差立即停止。我见过有人一上来就设很紧的阈值结果机器人走两步就停根本没法用。阈值要慢慢收紧先保证能走再保证走稳。5. 常见问题与排查技巧实录5.1 ZMP计算值跳动剧烈怎么办这是最常见的问题。原因通常有三个传感器噪声、质心估计误差、或者加速度计算不准。排查顺序先看原始力传感器信号如果噪声大加滤波如果滤波后还跳检查质心位置估计是不是用了错误的连杆质量最后检查加速度是不是用了差分导致噪声放大。我的经验是加速度最好用规划值不要用传感器差分值。规划值平滑差分值噪声大。如果非要用传感器至少加一个卡尔曼滤波器。5.2 机器人走路时ZMP总是偏向一侧这通常是机械不对称或者质心偏移导致的。比如电池装偏了或者某条腿的电机重一些。解决办法先做一次静态标定让机器人静止站立测量实际ZMP然后调整质心估计的偏移量直到ZMP落在脚掌中心。这个偏移量可以写进配置文件每次启动时加载。5.3 步态切换时ZMP越界单脚支撑和双脚支撑切换时支撑多边形突变ZMP容易越界。我的做法是在切换前提前移动质心让ZMP平滑过渡。具体来说在双脚支撑阶段让ZMP从一只脚的中心线性移动到另一只脚的中心而不是瞬间跳变。这个过渡时间一般取步时的20%-30%。5.4 常见问题速查表问题现象可能原因排查方法解决措施ZMP跳动剧烈传感器噪声查看原始信号加低通滤波截止频率20-30HzZMP偏向一侧质心偏移静态站立测ZMP标定质心偏移量写入配置切换时越界支撑多边形突变检查切换时刻ZMP提前移动质心平滑过渡走路前扑质心加速度过大检查规划加速度降低步速增大步时走路后仰质心加速度反向检查ZMP轨迹调整落脚点前移ZMP关节卡死逆解超限检查关节角加限位检查调整步态5.5 独家避坑技巧第一个技巧先用仿真跑通再上真机。我见过太多人直接上真机调ZMP结果摔了几次之后信心全无。用Gazebo或者PyBullet建一个模型把ZMP计算和步态生成跑一遍确认轨迹合理再上真机。仿真里摔一百次都不心疼。第二个技巧从静态站立开始调。不要一上来就走。先让机器人站着看ZMP是否在脚掌中心。如果站着都不稳走路肯定没戏。静态稳了再试单脚支撑再试慢速行走最后才加速。第三个技巧记录数据事后分析。每次跑完把ZMP、质心、关节角、传感器数据都存下来。摔了之后回放看ZMP是在哪个时刻越界的越界前质心在干什么。这比盯着机器人看有用得多。6. 从ZMP到更高级的运动控制ZMP是入门但不是终点。实际项目中我通常会把ZMP和**模型预测控制MPC**结合。MPC可以在线优化质心轨迹和落脚点同时把ZMP作为约束。这样机器人可以走得更快、更自然而且能应对一定的外部扰动。另一个方向是全身控制。ZMP只考虑质心和地面反作用力不直接处理手臂和上半身的运动。如果机器人需要边走边操作比如开门、搬东西就需要把手臂动力学也纳入进来。这时候ZMP仍然是稳定性判据但控制变量多了很多。还有一个趋势是基于学习的步态。用强化学习训练双足行走可以不需要显式的ZMP计算。但即使在这种方案里ZMP也常被用作奖励函数的一部分鼓励策略保持稳定。所以ZMP这套东西学透了不亏。我个人在实际操作中的体会是ZMP最大的价值不是它有多精确而是它提供了一个可解释、可调试、可复现的框架。当你面对一台走路摇摇晃晃的机器人时ZMP能告诉你问题出在哪是质心太高是落脚点太近还是加速度太大。这种诊断能力比任何黑箱控制器都珍贵。
返回列表