URDF vs MJCF:机器人描述格式对比
URDF 和 MJCF 是机器人仿真的两大主流模型描述格式。本文对比两者结构、表达能力差异,并讨论何时该选哪一个。
在机器人开发里,几乎所有仿真器、可视化器、控制器都需要一个统一的机器人描述文件——它告诉程序:机器人有哪些连杆、关节怎么连接、质量分布如何、可视模型长什么样。今天生态里事实上的两大格式就是 URDF 与 MJCF。本文用一份对比清单帮你快速建立直觉。
URDF:ROS 世界的"通用语"
URDF(Unified Robot Description Format)是 ROS 社区提出的一种 XML 格式,用于描述机器人的运动学和质量属性。它定义了三件事:
- Link(连杆):质量、惯性、视觉模型、碰撞模型
- Joint(关节):连接两个 link,定义类型(revolute / prismatic / fixed / continuous 等)、轴向、限位
- Material:视觉模型的颜色或纹理
一份最简单的 URDF 片段大概长这样:
<robot name="two_link">
<link name="base">
<inertial>
<mass value="1.0"/>
<inertia ixx="0.001" ixy="0" ixz="0" iyy="0.001" iyz="0" izz="0.001"/>
</inertial>
</link>
<link name="link1"/>
<joint name="joint1" type="revolute">
<parent link="base"/>
<child link="link1"/>
<origin xyz="0 0 0.1" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
</joint>
</robot>URDF 的最大优势是生态广:ROS、RViz、MoveIt、Gazebo、PyBullet、drake、Pinocchio、your favorite viewer——几乎所有工具都能直接读 URDF。机器人大厂(Boston Dynamics、Franka Emika、UR、Willow Garage 等)也都会发布官方 URDF。
但 URDF 也有几个硬伤:
- 只能描述树状拓扑——闭环机构(如四足的平行连杆、Delta 机器人)写不出来,必须用
<gazebo>这种私有插件 hack。 - 没有仿真参数——摩擦、接触模型、执行器、传感器这些不属于"模型几何"的东西不在 URDF 标准里,要靠 Gazebo / SDF 的扩展标签。
- 不支持 include——大机器人得拆成 xacro(一种宏语言)来组织。
MJCF:MuJoCo 的原住民格式
MJCF(MuJoCo XML)是 MuJoCo 仿真器自己的描述格式。和 URDF 不同,它从第一天起就是为快速、可微、接触丰富的物理仿真服务的。一份最小 MJCF 长这样:
<mujoco model="two_link">
<option timestep="0.002" gravity="0 0 -9.81"/>
<worldbody>
<body name="base" pos="0 0 0">
<geom type="box" size="0.05 0.05 0.05" mass="1"/>
<body name="link1" pos="0 0 0.1">
<joint name="joint1" type="hinge" axis="0 0 1" range="-3.14 3.14"/>
<geom type="capsule" fromto="0 0 0 0 0 0.2" size="0.02" mass="0.5"/>
</body>
</body>
</worldbody>
<actuator>
<motor joint="joint1" gear="1"/>
</actuator>
</mujoco>注意 MJCF 把仿真器配置(timestep、gravity)、几何(geom)、关节、执行器、传感器全部塞进了同一个文件——它本质上是一个"完整可仿真系统的描述"。
MJCF 的优势:
- 闭环、并列约束、Parallel-toe、Soft contacts 都是一等公民
- 执行器、传感器、tendon、equality constraint 直接写在文件里
- 加载速度极快(MuJoCo 解析 + 编译只需毫秒级)
- 可微 + GPU 加速(MuJoCo XLA / MJX)天然支持
缺点也明显:
- MuJoCo 专属——拿到 ROS / RViz / Drake 里需要转换
- 细节多——同一台机器人可以写出"卡顿版"也可以写出"丝滑版",调参文化较重
何时用哪个?一张决策表
| 场景 | 推荐 | 原因 |
|---|---|---|
| ROS / MoveIt 控制 | URDF | MoveIt 强依赖 URDF + SRDF |
| PyBullet 仿真 | URDF | PyBullet 原生支持 |
| MuJoCo / MJX 强化学习 | MJCF | 充分利用接触 / 执行器模型 |
| 四足 / Delta / 闭环机构 | MJCF | URDF 表达不了闭环 |
| 工业机械臂(树状) | URDF | 厂商直接给,省事 |
| Sim-to-real + 可微仿真 | MJCF | MuJoCo 提供梯度 |
经验法则:如果你的目标是接 ROS 生态或者厂商已经给了 URDF,从 URDF 起步;如果你要做 RL 训练或仿真速度是瓶颈,转 MJCF。
互转工具
URDF ↔ MJCF 并不是无损的(语义上有差),但有几个常用工具可以救急:
# MuJoCo 自带:URDF -> MJCF(编译到 MuJoCo 模型)
python -m mujoco.mjxml --input=robot.urdf --output=robot.xml
# mujoco_menagerie 仓库里有大量已经手调过的 MJCF
git clone https://github.com/google-deepmind/mujoco_menagerie
# mujoco_warp / mjx:把 MJCF 进一步转成 GPU 友好格式
python -m mujoco.mjx --model=robot.xml反向(MJCF → URDF)较少使用,通常借助 mujoco_menagerie 等社区脚本,需要手工修补惯性参数和限位。
小结
URDF 和 MJCF 不是非此即彼——很多团队的工作流是 URDF 做控制接口、MJCF 做仿真训练,再用一个 build 脚本保持两者同步。理解两者的设计取舍,是在机器人仿真这条路上走得长远的关键第一步。