3. 四足机器人躯干建模

躯干是四足机器人的骨架核心。四条腿、传感器、控制器,全都要挂在这个身体上。说白了,躯干建模的质量,直接决定了后面所有仿真的稳定性。

我个人习惯,第一步先把躯干搭出来。不用太复杂,一个 box geom 就够了。等后面调试好了,再慢慢加细节。

3.1 躯干 XML 结构:从零开始写

在 MuJoCo 里,所有模型都写在 .xml 文件里。躯干部分,我们只需要三个标签:body、inertial、geom。

先看一个最简版本:

<mujoco model="quadruped_torso">
  <worldbody>
    <body name="torso" pos="0 0 0.3">
      <inertial pos="0 0 0" mass="5.0" diaginertia="0.05 0.1 0.05"/>
      <geom name="torso_geom" type="box" size="0.25 0.12 0.06" 
            rgba="0.8 0.2 0.2 1.0" friction="0.8 0.1 0.01"/>
    </body>
  </worldbody>
</mujoco>

这段代码干了三件事:

  • body:定义了一个叫 "torso" 的刚体,位置在 (0, 0, 0.3),离地面 30 厘米。
  • inertial:设置质量 5kg,惯性矩用对角矩阵近似。
  • geom:画了一个长方体,长宽高分别是 0.5m、0.24m、0.12m。
我的习惯:先把 body 的 pos 设高一点,比如 0.3m。这样机器人掉下来时,有足够时间观察落地姿态。我曾经设成 0.05m,结果一运行就砸地,还以为模型写错了。

3.2 物理属性:质量、颜色、摩擦系数

这几个参数,每个都有讲究。我按顺序讲。

3.2.1 质量(mass)

质量放在 inertial 标签里。单位是 kg。四足机器人躯干一般在 3~8kg 之间。5kg 是个不错的起点。

为什么质量重要?

  • 质量太小 → 腿一蹬就飞,仿真像在月球。
  • 质量太大 → 电机扭矩不够,机器人站不起来。

我建议先按真实物理样机的重量来。没有样机?那就参考同类开源机器人,比如 Unitree A1 躯干约 4.5kg。

3.2.2 颜色(rgba)

颜色写在 geom 的 rgba 属性里。四个值:红、绿、蓝、透明度。

比如 rgba="0.8 0.2 0.2 1.0" 是深红色,完全不透明。

我个人习惯用亮色,比如亮蓝或亮红。为什么?因为在仿真里,深色物体在深色背景下根本看不清。你想想看,调试时眼睛盯着屏幕,颜色太暗,关节角度都看不准。

推荐配色方案:
  • 躯干:亮红 (0.9 0.2 0.2 1.0)
  • 左前腿:亮蓝 (0.2 0.4 0.9 1.0)
  • 右前腿:亮绿 (0.2 0.8 0.3 1.0)
  • 左后腿:橙色 (0.9 0.6 0.1 1.0)
  • 右后腿:紫色 (0.7 0.2 0.8 1.0)

3.2.3 摩擦系数(friction)

摩擦系数也是 geom 的属性。三个值:滑动摩擦、扭转摩擦、滚动摩擦。

典型设置:friction="0.8 0.1 0.01"

  • 0.8:滑动摩擦,橡胶对地面的典型值。
  • 0.1:扭转摩擦,防止机器人原地打转。
  • 0.01:滚动摩擦,对足式机器人影响不大。

嗯,这里要注意。摩擦系数不是越大越好。我遇到过一个问题:摩擦设成 1.5,结果机器人走路时像粘在地上,腿抬不起来。后来降到 0.8,步态就正常了。

3.3 惯性矩:别用默认值

很多初学者会忽略 diaginertia。MuJoCo 如果不设置,会自动计算。但自动计算的结果,往往和实际物理不符。

对于长方体,惯性矩有公式:

  • Ixx = (1/12) * mass * (height² + depth²)
  • Iyy = (1/12) * mass * (width² + depth²)
  • Izz = (1/12) * mass * (width² + height²)

拿我们的尺寸算一下:

轴 公式 计算结果 (kg·m²)
Ixx (1/12)*5*(0.12² + 0.24²) 0.030
Iyy (1/12)*5*(0.5² + 0.24²) 0.128
Izz (1/12)*5*(0.5² + 0.12²) 0.110

你看,三个值差别很大。如果全设成 0.05,仿真时躯干转动惯量就不对,转弯会特别奇怪。

避坑:我曾经偷懒,把 diaginertia 三个值写成一样。结果机器人原地转弯时,躯干像陀螺一样乱晃。排查了半天,才发现是惯性矩的问题。从那以后,我每次都老老实实算一遍。

3.4 完整躯干模型代码

把上面所有内容整合起来,就是一份可运行的躯干模型:

<mujoco model="quadruped_torso">
  <compiler angle="radian" coordinate="local"/>
  
  <option gravity="0 0 -9.81" timestep="0.002"/>
  
  <worldbody>
    <light name="top" pos="0 0 2" dir="0 0 -1"/>
    
    <geom name="ground" type="plane" size="2 2 0.1" 
          rgba="0.3 0.3 0.3 1.0"/>
    
    <body name="torso" pos="0 0 0.3">
      <inertial pos="0 0 0" mass="5.0" 
                diaginertia="0.030 0.128 0.110"/>
      <geom name="torso_geom" type="box" 
            size="0.25 0.12 0.06" 
            rgba="0.9 0.2 0.2 1.0" 
            friction="0.8 0.1 0.01"/>
    </body>
  </worldbody>
</mujoco>

保存为 torso.xml,用 MuJoCo 打开。你应该能看到一个红色长方体,悬浮在半空,然后自由落体落到地面上。

3.5 知识结构总览

下面这张图,把躯干建模的核心知识点串起来了:

躯干建模知识结构 躯干 body inertial 标签 mass:质量 (kg) diaginertia:惯性矩 geom 标签 type:box / cylinder / sphere size:半长宽高 rgba:颜色 + 透明度 friction:摩擦系数 body 属性 pos:初始位置 (x y z) euler / quat:初始姿态

3.6 调试小技巧

模型写好了,怎么验证对不对?我分享几个经验:

  1. 看落地方向:躯干应该平稳落地,不会翻转。如果翻转,检查惯性矩是否合理。
  2. 看穿透:躯干不能陷入地面。如果陷进去,检查摩擦系数或地面 geom 的 size。
  3. 看颜色:确保 rgba 的 alpha 值是 1.0,否则躯干会半透明,看不清。
快速验证:在 MuJoCo 里按 F3 打开信息面板,查看躯干的质量和惯性矩。如果显示的质量和设置的不一致,说明 XML 解析有问题。