第一次接触四足机器人步态时,我最困惑的并不是“让四条腿动起来”,而是怎样判断一套关节命令真的形成了对角支撑:左前腿抬起时,究竟是哪两条腿在承受机身;足端反力是否与相位切换一致;机身又会不会在接触切换时持续下沉。为了把这些问题放在同一个模型里观察,我检索了“Modelica 四足机器人 trot 足地接触”等关键词,在 MoHub 的案例页发现了 QuadrupedRobot,完整地址在这里:https://mohub.net/model/26065/summary

这个案例没有一开始就堆叠复杂控制算法,而是把自由机身、四条两自由度机械腿、足地接触和对角小跑发生器放进一个可追踪的数据链路中。下面按实际模型文件和保留的仿真结果记录,梳理一次从加载到看结果的过程。

先把问题缩小:这个模型验证什么

顶层入口是 QuadrupedRobot.Examples.QuadrupedTrotDemo。模型的目标是在重力沿 -z 方向的水平地面上,按对角线小跑方式驱动四条腿:左前 LF 与右后 RH 同相,右前 RF 与左后 LH 同相,两组相差 180°。输入是步态周期、名义步长、抬腿高度、机身和腿部几何/质量参数,以及接触刚度、阻尼和摩擦参数;输出可以从机身位置、关节命令和四个足端法向力中读取。
在这里插入图片描述

图1:QuadrupedTrotDemo 顶层模型结构

从适用范围看,它适合做步态相位、足地接触和机身响应之间的联合验证。例如,学习 MultiBody 建模时可以据此理解自由刚体、转动副和世界坐标系的连接方式;做步态原型时可以先扫查 gaitPeriod、stepLength、liftHeight 对支撑切换的影响;做接触参数敏感性分析时,可以观察接触刚度、阻尼与摩擦系数如何改变法向力波形。它不适合直接证明实机的能耗、复杂地形通过性、结构强度或闭环抗扰稳定性,因为模型采用开环关节位置命令、水平地面和简化接触力。

如何运行并查看同一组量

运行时先加载案例根目录的 package.mo,再打开顶层模型 QuadrupedRobot.Examples.QuadrupedTrotDemo。模型依赖 Modelica 多体动力学组件;顶层 experiment 标注给出了 0—60 s 的仿真区间、0.01 s 输出间隔和 1e-5 容差,实验设置记录中的求解算法为 Dassl。按这个设置运行后,60 s 对应 6001 个输出时刻。

我建议不要一开始就把所有变量都摊开。第一组先看 robotBody.body.r_0[1] 与 robotBody.body.r_0[3],分别对应机身 x 向位置和 z 向位置;第二组看 controller.hipLF、controller.hipRF、controller.kneeLF、controller.kneeRF;第三组看 contactLF.normalForce、contactRF.normalForce、contactLH.normalForce、contactRH.normalForce。这样能沿着“命令—接触—机身响应”的顺序判断,而不是只凭动画印象判断步态。

对角小跑命令是怎样生成的

控制器 TrotGaitController 的核心不是优化器,而是两组相差 π 的周期相位:thetaA = 2πt / gaitPeriod,thetaB = thetaA + π。

对 A 组,LF 与 RH 共用髋、膝命令;对 B 组,RF 与 LH 共用另一组命令。髋关节命令围绕 hipNeutral 做正弦摆动,摆幅由 stepLength/(2*thighLength) 决定。膝关节则把正弦信号拆成两个半波:正半波作为摆动相抬腿量,负半波作为支撑相的小幅伸展量。因此,抬腿高度通过 liftHeight/shankLength 进入膝关节摆动幅值,而不是直接指定足端轨迹。

按默认参数,gaitPeriod=1.0 s、stepLength=0.10 m、liftHeight=0.045 m、thighLength=shankLength=0.28 m。因此髋关节摆幅为约 0.1786 rad,膝关节摆动相附加幅值约 0.1607 rad。下面这张图由控制器文件中的同一公式计算,横轴为 0—2 s 时间、纵轴为关节命令角度(rad);蓝色和红色分别是两组髋关节命令,绿色和品红色分别是两组膝关节命令。
在这里插入图片描述

图2:TrotGaitController 输出命令的两周期曲线

足地作用由 FootGroundContact 完成。模型先用足端世界坐标的 z 分量计算穿透深度:只有足底低于地面时才接触。法向力是“接触刚度×穿透深度 + 接触阻尼×压入速度”的非负截断值;x、y 向摩擦力再按 -μ×normalForce×tanh(v/slipVelocity) 计算。tanh 让零速度附近的摩擦过渡平滑,避免理想库仑摩擦的突变给数值积分带来额外困难。

从结果中看到的三件事

第一,机身确实在前进,但不应把这理解为实机速度指标。保留的 60 s 仿真记录中,robotBody.body.r_0[1] 从 0 m 增加到约 3.7768 m;robotBody.body.r_0[3] 在约 0.5597—0.5735 m 之间变化,结束时约为 0.5702 m。也就是说,在这组开环命令和接触参数下,模型没有出现持续下沉或明显的竖直发散,但仍存在由落足、支撑转换引起的高度起伏。

第二,关节命令的相位关系真正传递到了支撑关系。controller.hipLF 与 controller.hipRF 的范围都约为 -0.8686—-0.5114 rad;两组膝关节命令约为 1.3000—1.5407 rad。由于两组相差半个周期,10.25 s 时 LF/RH 处于摆动抬腿侧,而 RF/LH 处于支撑侧;到 10.75 s,关系反转。这里最值得检查的不是“曲线是否漂亮”,而是命令切换后足端力是否同步切换。

第三,法向力给出了更直接的证据。10.25 s 时,contactRF.normalForce 约为 73.61 N、contactLH.normalForce 约为 31.52 N,LF 与 RH 接近离地;10.75 s 时,contactLF.normalForce 约为 73.63 N、contactRH.normalForce 约为 31.53 N,RF 与 LH 转入摆动。两次支撑腿法向力之和都约为 105 N。模型总质量由 8 kg 机身、四条腿的两段 0.36 kg 杆件和 0.08 kg 足端组成,约为 11.2 kg;支撑力总和与重力水平接近而并不恒等,这与机身竖直加速度和接触阻尼共同作用相符。

单足法向力全程峰值约为 133—151 N。这个数值可以帮助定位接触冲击较大的时段,却不能直接当作实机结构载荷:模型没有执行器动力学、柔性结构、传感器噪声和不平地形,接触刚度与阻尼也属于简化参数。若要继续扩展,我会先加入关节力矩限制和机身姿态反馈,再逐步替换为更接近目标场地的地形与接触模型。

用这个模型继续排查什么

如果只是修改一个参数,我会优先比较三个变量组而不是只看位移终值。减小 gaitPeriod 后,先检查四个 normalForce 的峰值和切换时刻是否更密集;增大 stepLength 后,检查髋关节摆幅与 x 向位移是否同步增大,以及是否引起 z 向波动放大;增大 liftHeight 后,检查摆动相膝角是否增加、足端是否减少拖地。接触刚度和阻尼则应成对调整:刚度升高会减少穿透,但也可能放大数值上的落足冲击;阻尼过小容易出现回弹,过大又会改变接触转换的瞬态。这些比较都应以同一仿真时长、同一组输出变量为前提,才不会把参数变化和观察窗口变化混在一起。

结语

这次复现让我更明确地看到,对角小跑不是“对角腿同时摆动”这么简单:需要先在命令层建立半周期错相,再通过足地接触把相位关系转换成轮换的法向支撑,最后用机身位置检查这种支撑是否带来连续前进和可控的高度变化。对于想从多体动力学视角读懂四足步态的人,这个案例提供了一个边界清晰的起点。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐