
2025 年夏天北京举办了一场世界人形机器人运动会。期间一个画面被网友传得到处都是一台人形机器人在场上走得歪歪扭扭步子越来越小膝盖发软身体左右摇摆最后以一种“上头了”的姿态跌倒在地。弹幕和评论区很快给它起了个名字——醉酒机器人。大多数人只是在玩梗。但如果你做过足式机器人看到这个画面的第一反应不会是好笑而是一身冷汗。因为那台机器人的状态恰恰是双足机器人从演示走向落地时最怕遇到的情况硬件没有断电、关节还有输出、系统还在努力维持但整体运动已经失控。它不是在表演而是在失稳边缘挣扎。这里先把问题说清楚“醉酒机器人”到底是什么技术问题为什么人形机器人在公开场合尤其容易出这种状态以及如果换成你在现场调试该怎么定位和解决。这篇文章不打算追着热搜解释某一家公司的具体故障因为就公开信息来看现场环境、机器人配置和具体失控原因并没有一个完整对外说明追着猜意义不大。我更想把它翻译成一个双足机器人平衡控制的工程问题从 ZMP、质心、步态规划这些基础概念开始先讲清楚“醉”的本质再用一个可运行的 Python 仿真演示扰动如何把机器人推离稳定域最后给出现场调试和防护的建议。这对真正打算做人形机器人、仿人足式机器人或者准备参加机器人竞赛的开发者尤其有用。1. 这篇文章真正要解决的问题话说回来为什么“醉酒机器人”能火因为画面里那台机器人的动作细节比任何“机器人摔倒视频”都更有“人味”它的双腿不是突然被绊住而是像人喝多了一样小步踉跄、反复尝试伸腿支撑最终失败。这种“努力又徒劳”的感觉让机器人显得格外拟人于是网友把它彻底人格化了。但“努力又徒劳”从控制理论角度讲非常准确。它的控制算法每一步都在尝试修正姿态和落点但每一步都没能把系统拉回稳定域于是出现了一个很长的失稳过程而不是瞬间倒掉。这其实比突然摔倒信息量大得多说明机器人的感知、决策、执行链路还在工作但整条链路的协同裕度已经耗尽。那台机器人当时的状态从公开视频看比较接近“扰动过大控制增益偏低或响应偏迟”的典型表现。这篇文章要解决的核心问题有三个对应三类读者如果你只是对机器人好奇可以带着“为什么机器人会走路还会像人一样跌倒”这个问题读下去。如果你正在做人形机器人或四足机器人需要把“像醉酒一样的失稳”当成一个工程异常来对待怎么复现、怎么定位、怎么调参。如果你在准备机器人比赛或公开演示这篇文章给出的排查清单和现场检查项能帮你降低翻车概率。所以先给出全文的核心判断醉酒机器人的本质不是某一个传感器或舵机坏了而是双足机器人动态平衡系统的整体鲁棒性不足。在一个不可控的真实环境里状态估计、执行器响应、步态规划、地面交互任何一环出现一点偏差叠加起来就会表现为“像喝醉一样”。它不是一个段子而是一堂真实环境给人形机器人行业上的公开课。2. “醉酒”的本质双足机器人平衡控制系统是怎么失效的2.1 双足行走是一连串“向前跌倒”的循环要理解机器人为什么会“醉”先要理解机器人为什么会走路。人的平衡主要由前庭系统、小脑和本体感觉协作维持走路时大脑会持续预测下一步的落点同时根据视觉和体感修正。人喝醉后前庭感知被扰乱小脑的运动协调变慢视觉也开始含糊于是脚底板找不到地面的准确位置身体就歪了。机器人的“前庭系统”是惯性测量单元也就是 IMU它提供加速度和角速度“小脑”对应平衡控制算法“本体感觉”对应关节编码器和足底压力传感器。正常行走时机器人每个控制周期都在做同一件事感知当前姿态计算身体偏离决定下一步脚落在哪里再驱动关节执行。从物理层面看双足行走的本质是一个不断“向前跌倒再伸出腿接住自己再向前跌倒”的动态过程。静止站立是平衡行走则是一种受控的不稳定。更技术一点说双足机器人常用“线性倒立摆模型”近似自己的质心运动把整个人体简化成一个高为 h 的倒立摆只要质心水平位置的动力学被控制在某个范围内机器人就不会倒。2.2 稳定域与落脚点判断机器人是否稳定最经典的概念是零力矩点 ZMP。ZMP 可以理解为地面给机器人的反作用力合力的作用点。如果这个点始终落在支撑多边形内也就是双脚构成的平面范围内机器人就基本处于稳定状态。ZMP 向脚掌边缘移动意味着接近失稳一旦超过支撑边缘机器人就会绕脚掌边缘旋转像一根被推倒的杆子。此时如果控制器反应够快可以重新把 ZMP 拉回中心反应慢了身体姿态已经偏出可恢复范围就只能靠迈步去“接”自己。所以机器人在走路这件事上靠的不是静态稳定而是高频率的“预测-执行-修正”。公开视频里那台机器人小步越迈越碎本质上就是控制算法试图通过加快迈步频率来维持 ZMP但每一步的误差都在累积。这里列一个简单的概念对照方便建立坐标系概念通俗解释稳定判断作用CoM 质心机器人所有质量的平均中心质心位置和速度是控制系统的目标状态CoP 压力中心地面实际压力的合力作用点用于验证建模精度和传感器一致性ZMP 零力矩点水平等效合力点不产生额外力矩落在支撑多边形内则动态稳定支撑多边形双脚及脚掌覆盖的地面区域ZMP 一旦出界就开始绕脚边缘翻转LIPM 线性倒立摆把人形简化为一个移动支点的倒立摆用来估算质心轨迹和落点策略这几个词在双足机器人工程文档里经常一起出现把它们分开理解是后面调试的基础。这里不展开太难的控制推导但后面写代码示例时你会看到即使一个很简单的倒立摆模型也能复现出“越救越歪”的醉酒感。2.3 “醉酒”的本质是什么到了这里可以给一个相对完整的定义机器人表现出“醉酒”其实是一系列失稳信号的叠加。第一姿态状态估计误差在持续增大机器人以为自己是直的实际已经歪了。第二执行器响应跟不上规划期望的落点没有在正确的时刻落地。第三步态规划器还在按照正常地形规划没有意识到地面的摩擦、硬度或坡度已经发生变化。第四安全裕度耗尽每一步都处于临界状态任何微小扰动都会让系统继续恶化。换句话说“醉酒”不是一种单一故障而是一种“系统还在闭环但裕度不足”的边界状态。这也是为什么它在公开活动上比在实验室更容易出现场地不熟悉、地面材料复杂、光照变化、人群移动带来的气流扰动、电磁干扰、长时间运行导致的关节温度上升都会从不同方向压掉那点生存空间。3. 从“歪歪扭扭”到“倒地不起”失稳的三个阶段3.1 第一阶段扰动被放大任何行走中的机器人都会受到内部和外部的扰动。内部扰动包括关节摩擦波动、电机扭矩脉动、控制延迟外部扰动包括风力、地面不平、与人或障碍物的轻微接触。扰动输入系统后状态估计器会把它反映为姿态角和速度的变化。正常系统会在几百毫秒内把影响平息。但如果扰动频率接近系统的自然摆频或者控制器增益偏低扰动就会被放大。最直观的表现就是机器人开始出现比正常步态更明显的身体晃动。这种晃动通常还能收回但已经消耗了 ZMP 的安全裕度。在这个阶段系统一般还能自我恢复。如果你在现场看到机器人“晃了一下又稳住了”说明控制器在正常工作。真正危险的是那种“晃得幅度越来越大”的趋势它通常意味着扰动没有被收敛而是在持续累积。3.2 第二阶段落点误差累积平衡算法应对晃动的主要手段之一是调整落脚点身体往哪边倒就把脚往哪边伸。这个策略成立的前提是——状态估计是准的落脚时刻是准的脚落地后能提供预期的支撑力。问题往往在第二个环节出现。公开视频里机器人出现“腿发软、迈小碎步”的状态很可能就是落点误差在累积。它每一次都试图把脚放在某个位置但要么放得不够远要么放得太靠近身体要么脚落地时因为地面摩擦不足还轻微打滑导致身体动量并没有被完全吸收。下一步开始时初始位置和速度都和规划不一致于是错误被不断继承。这里有一个工程判断标准如果每一步结束后的落点误差始终在零附近随机波动说明系统是健康的如果落点误差开始单向增大比如连续多步都偏右说明要么状态估计存在偏差要么地面条件发生了变化要么控制增益已经不足以完成任务。3.3 第三阶段步态规划被击穿当落点误差累积到某一代步步态规划器会发现自己无论如何选落点都无法让 ZMP 回到支撑多边形内部。此时系统进入一种“绝望维持”的状态关节电流接近限幅、姿态偏差越拉越大、抬腿高度降低、迈步频率主动加快。这一步很有迷惑性因为在外部看机器人似乎还在“努力”实际上已经没有任何恢复策略能起效。接下来就是绕脚边缘旋转并倒地。这种失稳路径不是专门针对某一家公司的实现而是一种通用现象。对你调试自己的机器人来说意义在于一旦从日志中发现“ZMP 裕度连续多步下降”“落点误差单步超过阈值”“关节电流持续撞限幅”这三个信号就没必要再继续让它走下去应该立刻停机和复盘。这种问题不是临场喊一声“稳住”能解决的。因为它发生在算法的底层和“控制器的参数已经调到了临界状态”有关也和“真实环境里的扰动分布超出了设计假设”有关。现场能做的只能是止损和记录真正的修正在调试间里。4. 环境准备与最小仿真示例用倒立摆模拟“醉酒”4.1 你要准备什么为了把上面讲的失稳过程直观跑出来这里用一个非常精简的 Python 倒立摆仿真。它不是一个完整的人形机器人仿真器但能清楚展示“扰动噪声”和“落点控制策略”对稳定性的影响。用真实机器人复现这样的过程成本很高仿真能让你以最低成本感受什么叫“越救越醉”。环境准备Python 3.8 及以上版本以你本机为准numpymatplotlib安装依赖pip install numpy matplotlib如果你已经装了 Anaconda直接用 base 环境就可以。个人项目建议还是建一个虚拟环境python -m venv .bipedal_venv source .bipedal_venv/bin/activate # Windows 下执行 .bipedal_venv\Scripts\activate pip install numpy matplotlib4.2 最小动态平衡仿真代码下面这个脚本模拟一个 2D 双足行走模型上半身看作质心支撑脚在一个周期内固定每个步态周期结束时切换支撑脚并生成新的落点。我们故意在落点上增加高斯噪声用于模拟“路面条件变化”或“状态估计误差”。# 文件路径simulate_drunk_biped.py import numpy as np import matplotlib.pyplot as plt G 9.81 H 0.8 # 质心高度单位 m DT 0.01 # 仿真步长单位 s STEP_DUR 0.25 # 单步时长单位 s MAX_STEP 0.30 # 单步最大跨距单位 m SUPPORT_RADIUS 0.12 # 等效支撑半径ZMP 超过即视为失稳 def run_simulation(noise_std, feedback_gain2.0, damping_gain1.5): x, v 0.0, 0.0 # 质心相对支撑点的横向位置和速度 t 0.0 step_count 0 log_x [] log_t [] while t 5.0: # 线性倒立摆模型x (g / h) * x acc (G / H) * x v acc * DT x v * DT t DT log_x.append(x) log_t.append(t) if t (step_count 1) * STEP_DUR: # 反馈落点根据当前真实状态决定脚往哪放 desired -feedback_gain * x - damping_gain * v * STEP_DUR # 落点扰动模拟传感器估计误差和轨迹跟踪误差 actual desired np.random.normal(0, noise_std) actual np.clip(actual, -MAX_STEP, MAX_STEP) # 切换支撑脚后坐标原点变化 x x - actual v v * 0.98 # 落地瞬间的轻微能量耗散 step_count 1 if abs(x) SUPPORT_RADIUS: print(f失稳发生在第 {step_count} 步质心偏移 {x:.3f} m) break else: print(5 秒内保持稳定) return log_t, log_x if __name__ __main__: plt.figure(figsize(10, 5)) for noise in [0.0, 0.03, 0.08]: ts, xs run_simulation(noise_stdnoise) plt.plot(ts, xs, labelfnoise_std{noise}) plt.axhline(0.12, colorred, linestyle--, linewidth1) plt.axhline(-0.12, colorred, linestyle--, linewidth1, labelsupport limit) plt.xlabel(Time (s)) plt.ylabel(CoM offset (m)) plt.legend() plt.title(Bipedal CoM offset under different disturbance levels) plt.grid(True) plt.show()解释一下关键逻辑倒立摆加速度公式是把机器人简化成倒立摆质心高度保持恒定。水平位置一旦偏离支点就会产生加速度偏离越大倒得越快。反馈落点中的feedback_gain和damping_gain是一组很朴素的步态落点策略它根据当前质心位置和速度决定下一步脚落回哪里。noise_std模拟的是落点不准。它一旦变大机器人每一步都会踩偏接着就只能靠下一步继续纠偏如果再配合过大的阻尼就会出现典型的“小碎步”状态和“醉酒”高度相似。4.3 运行结果与验证保存文件后执行python simulate_drunk_biped.py正常情况noise_std0下机器人质心偏移会被收敛到支撑半径附近5 秒保持稳定。而noise_std0.08时通常在前 20 步内就会触发“失稳”。运行后你会看到一条曲线在某个时刻突然越过红色虚线这就是 ZMP 出界的直观可视化。如果你想让“醉酒感”更强可以试着把damping_gain调小或者把feedback_gain调大。相对保守的控制会让机器人动作迟缓、容易摇晃过于激进的控制又容易震荡。真实人形机器人调试时平衡控制器的增益就是这么一点点试出来的。这里能引出一个重要的工程认知“稳不稳”从来不是绝对概念而是“在多大扰动范围内还能保持稳定”。这个范围就是前文反复提到的安全裕度。5. 如何让机器人“醒酒”从状态估计到步态重规划5.1 先解决“