第三章:worldbody与几何体定义 - 几何体类型与属性缺失错误

好,咱们进入第三章。前两章我们把 MuJoCo 的 XML 骨架搭起来了,也把常见的基础语法坑填了。这一章,咱们要真正往场景里「放东西」了——也就是定义几何体。

说白了,worldbody 就是你的虚拟世界容器,而几何体就是这个世界里的桌椅板凳、地面墙壁、机器人外壳。我见过太多新手,模型加载出来一片漆黑,或者仿真器直接崩溃,十有八九都是几何体定义出了问题。

核心认知: MuJoCo 的几何体不是「画」出来的,而是「算」出来的。它需要精确的类型、尺寸、位置和物理属性。少一个参数,轻则报错,重则仿真直接崩。

3.1 worldbody:一切几何体的根容器

先看一个最基础的 worldbody 结构:

<mujoco model="demo">
  <worldbody>
    <light pos="0 0 1.5" dir="0 0 -1"/>
    <geom name="ground" type="plane" size="2 2 0.1" pos="0 0 0" rgba="0.8 0.8 0.8 1"/>
    <body name="box_body" pos="0 0 0.5">
      <geom name="box" type="box" size="0.2 0.2 0.2" rgba="0.2 0.6 1.0 1"/>
      <joint name="free" type="free"/>
    </body>
  </worldbody>
</mujoco>

这里有个关键点:worldbody 本身就是一个特殊的 body,它的位置固定在世界原点,不能移动。所有其他 body 和 geom 都挂在它下面。我个人习惯把地面、环境光、静态障碍物直接放在 worldbody 下,而把可动部件包在 body 里。

常见错误: 把动态物体的 geom 直接放在 worldbody 下,而不是包在 body 里。这样物体将无法添加关节,也就动不了。

3.2 几何体类型:选错类型,仿真全乱

MuJoCo 支持十几种几何体类型,但常用的就那几种。我整理了一张表,你对照着看:

类型 (type) 说明 size 参数格式 典型用途
plane 无限平面 x y thickness 地面、墙壁
box 长方体 half_x half_y half_z 箱子、障碍物
sphere 球体 radius 球、关节球
cylinder 圆柱体 radius half_height 轮子、轴
capsule 胶囊体 radius half_height 连杆、手指
mesh 自定义网格 需配合 <mesh> 引用 复杂外形

嗯,这里要注意:size 参数的单位是「半尺寸」。比如一个 box 的 size 写 0.2 0.2 0.2,实际边长是 0.4。我刚开始用的时候,总把 size 当全长写,结果模型比预期大了一倍,碰撞检测全乱套。

我的经验: 写 size 之前,先在脑子里过一遍:「这个几何体在三个轴向上的半长是多少?」养成习惯后,基本不会错。

3.3 属性缺失:最常见的报错根源

MuJoCo 对属性要求很严格。少写一个,解析器就直接罢工。我总结了几个高频缺失属性:

  • 缺少 type:MuJoCo 不知道你要画什么形状,默认不报错但也不显示。
  • 缺少 size:几何体没有尺寸,加载时直接报 XML parse error。
  • 缺少 pos:几何体会默认放在 (0,0,0),可能和其他物体重叠。
  • 缺少 rgba:颜色默认白色,在白色背景下根本看不见。

举个例子,下面这段代码就会出问题:

<geom name="bad_geom" type="box"/>

运行后你会看到类似这样的错误:

Error: XML element 'geom' requires attribute 'size'

我曾经在做一个多足机器人项目时,因为少写了一个 size,排查了整整两个小时。最后发现是复制粘贴时漏了参数。从那以后,我写每个 geom 都会对照检查清单。

3.4 几何体属性检查清单

为了避免你重蹈我的覆辙,我整理了一个检查清单。每次写完几何体,对照过一遍:

  1. type:是否指定了正确的几何体类型?
  2. size:尺寸参数是否完整?格式是否正确?
  3. pos:位置是否合理?会不会和其他物体重叠?
  4. rgba:颜色是否可见?alpha 通道是否大于 0?
  5. name:是否命名?方便后续调试和引用。
  6. mass(动态物体):是否设置了质量?默认质量为 0 会导致物理异常。

避坑指南: 我曾经在定义地面时,把 plane 的 size 写成了 2 2(只给了两个参数),结果 MuJoCo 直接崩溃。后来查文档才发现,plane 的 size 需要三个参数:x 半长、y 半长、厚度。少一个都不行。

3.5 几何体类型与属性缺失错误关系图

下面这张图帮你理清几何体定义时的常见错误路径:

几何体类型与属性缺失错误关系图 几何体定义常见错误路径 定义几何体 geom 类型错误 属性缺失 type 拼写错误 size 格式不匹配 缺少 size 属性 缺少 rgba 属性 仿真加载失败 / 模型不可见 提示:使用检查清单逐一核对,可避免 90% 的几何体定义错误

3.6 实战:修复一个报错的模型

来看一个实际案例。假设你拿到这样一个模型文件:

<mujoco model="broken_model">
  <worldbody>
    <geom name="floor" type="plane" size="5 5"/>
    <body name="robot" pos="0 0 1">
      <geom name="torso" type="box" size="0.3 0.2" rgba="0 1 0 1"/>
      <joint name="root" type="free"/>
    </body>
  </worldbody>
</mujoco>

加载后,MuJoCo 报了两个错误:

  1. plane 的 size 缺少第三个参数(厚度)。
  2. box 的 size 缺少第三个参数(高度)。

修复后应该是这样:

<mujoco model="fixed_model">
  <worldbody>
    <geom name="floor" type="plane" size="5 5 0.1"/>
    <body name="robot" pos="0 0 1">
      <geom name="torso" type="box" size="0.3 0.2 0.15" rgba="0 1 0 1"/>
      <joint name="root" type="free"/>
    </body>
  </worldbody>
</mujoco>

小技巧: 如果你不确定某个几何体的 size 格式,可以直接在 MuJoCo 的官方文档里搜「geom type」,里面有每个类型的详细说明。我电脑桌面就一直开着这个页面。

3.7 几何体属性速查表

最后,送你一个速查表。写 geom 的时候,对照着看,基本不会漏:

属性 是否必填 默认值 说明
type 是 无 几何体类型,如 plane、box、sphere
size 是 无 尺寸参数,格式因类型而异
pos 否 0 0 0 位置坐标 (x, y, z)
rgba 否 0.5 0.5 0.5 1 颜色和透明度 (r, g, b, alpha)
mass 否 0 质量,动态物体建议显式设置
condim 否 3 接触维度,3 为摩擦接触
friction 否 1.0 0.005 0.0001 摩擦系数 (滑动, 扭转, 滚动)

嗯,这一章的内容就到这里。几何体定义是 MuJoCo 建模的基础,也是出错的高发区。你只要把类型和属性这两个关键点抓牢,后面就顺了。