1 · URDF基础入门
机器人描述文件是什么?为什么需要URDF?XML语法速览与URDF文件结构。
🤖 机器人描述文件到底是什么?
说白了,URDF 就是机器人的「电子身份证」+「骨架说明书」。它用 XML 格式把机器人长什么样、胳膊怎么转、轮子装在哪,全部写成结构化的文本。我刚开始接触 ROS 时也觉得这东西有点多余——直接写代码不就行了?后来在项目里被坑过一次:没有 URDF,导航根本不知道你的机器人是圆是方,代价地图都没法算。
URDF 的全称是 Unified Robot Description Format,统一机器人描述格式。它是 ROS 生态里的老牌标准,虽然现在有了更灵活的 SDF 和 xacro,但 URDF 依然是 Nav2、MoveIt 的基石。你想想看,没有它,路径规划器连机器人的 footprint 都不知道,怎么避障?
⚙️ 为什么非要用 URDF?
我个人习惯把原因归纳成三点,简单直接:
- 统一接口 —— 不管你是两轮差速底盘还是四足机器人,URDF 提供了一套所有 ROS 工具都认识的描述方式。Rviz、Gazebo、Nav2 都直接读它。
- 物理属性分离 —— 模型的外观、碰撞体积、惯性参数各写各的。我在调一个六轴机械臂时,只改了碰撞盒子的尺寸就解决了规划器卡死的问题,不用动其他代码。
- 自动生成 TF 树 —— 你定义好关节,TF 广播器自动帮你算坐标变换。省了多少手写变换的功夫!
嗯,还有一点很实际:团队协作时,给一个 URDF 文件比发十几张 CAD 图纸高效得多。我曾经在项目里用 URDF 直接给机械工程师看模型,他们改完 link 尺寸我这边马上就能仿真。
📐 XML 语法速览 —— 别怕,就那么几个标签
URDF 基于 XML,但你需要记住的标签不超过 8 个。我列个常用清单:
| 标签 | 作用 | 出现次数 |
|---|---|---|
| <robot> | 根元素,所有内容包在里面 | 1 |
| <link> | 定义刚体(底盘、手臂、轮子) | ≥1 |
| <joint> | 连接两个 link,描述运动副 | ≥0 |
| <geometry> | 形状:box、cylinder、sphere、mesh | 每个 link 内 |
| <origin> | 位置 xyz 和姿态 rpy | 常用 |
| <inertial> | 质量、惯性矩阵(仿真用) | 可选 |
| <visual> | 显示用的外观 | ≥0 |
| <collision> | 碰撞检测用的简化形状 | 推荐定义 |
你看,核心就这些。写一个简单的两轮机器人底盘,连 30 行都用不了。
🧱 URDF 文件结构 —— 树状思维
URDF 本质上是一棵树。根是 <robot>,下面挂着 link 和 joint。每个 joint 连接两个 link,形成父子关系。我画个简单的结构你就懂了:
<robot name="my_robot">
<link name="base_link">
<visual>
<geometry><box size="0.4 0.3 0.1"/></geometry>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="-0.2 0.15 0" rpy="0 0 0"/>
</joint>
<link name="left_wheel">
<visual>
<geometry><cylinder radius="0.05" length="0.04"/></geometry>
</visual>
</link>
</robot>
注意看:base_link 是父 link,left_wheel 是子 link。关节定义了它们之间的相对位置。这就是 URDF 的核心逻辑——用关节把 link 串起来。
🔍 深入理解:为什么 XML 适合做机器人描述?
XML 的树状结构和机器人运动链天然匹配。每个关节就是一个节点,每个 link 就是一段骨骼。而且 XML 的标签语义化很强,就算你不懂代码,看到 <link> 也知道是零件。我个人觉得,相比 JSON 或 YAML,XML 的注释和属性扩展更方便——比如给 link 加一个 material 颜色,直接写在标签里,一目了然。
当然,URDF 也有缺点:文件长了会冗余。不过后面我们会学 Xacro,那就是专门解决这个问题的。这一章先把基础打牢。
• URDF = 机器人的 XML 骨架
• 三大要素:link(零件)、joint(连接)、geometry(形状)
• 树状结构,父关节驱动子 link
• 写完后用
check_urdf 命令验证,我每次必做