第1章 · URDF基础入门
URDF,全称是 Unified Robot Description Format,统一机器人描述格式。说白了,它就是 ROS 世界里用来描述机器人长什么样、关节怎么连的一套 XML 语言。我刚开始接触 ROS 的时候,觉得这玩意儿不就是个配置文件嘛,后来才发现——URDF 是机器人建模的基石,导航、控制、仿真全都得靠它。
这一章我们不讲虚的,直接拆解 URDF 的核心概念。你想想看,一个机器人再怎么复杂,拆到底也就是「刚体」加「关节」。URDF 里用 <link> 表示刚体,用 <joint> 表示关节。就这么简单。
什么是 URDF?
URDF 是一种基于 XML 的格式,专门用来描述机器人的运动学和动力学属性。你可以把它想象成机器人的「身份证」—— 上面写了你有几个胳膊几条腿,每个关节能怎么动。ROS 里的 robot_state_publisher 就是靠 URDF 来发布 tf 变换的。
URDF 文件结构
一个标准的 URDF 文件长这样:
<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"/>
<axis xyz="0 1 0"/>
</joint>
</robot>
最外层是 <robot> 标签,里面包含若干 <link> 和 <joint>。我个人习惯把 base_link 放在最前面,它是整个机器人的根坐标系。
link 与 joint 的概念
link 就是刚体,比如底盘、轮子、机械臂的连杆。每个 link 可以定义视觉外观、碰撞模型和惯性参数。我记得有一次调试导航,机器人一直原地打转,最后发现是 base_link 的惯性矩阵写错了,导致里程计计算异常。嗯,惯性参数千万别乱填。
joint 连接两个 link,并定义它们之间的相对运动。joint 有几种常用类型:
| 类型 | 说明 | 自由度 |
|---|---|---|
| fixed | 固定连接,不能运动 | 0 |
| revolute | 旋转关节,有角度限制 | 1 |
| continuous | 连续旋转关节,无限制(如轮子) | 1 |
| prismatic | 平移关节,有位移限制 | 1 |
| floating | 6自由度浮动关节(很少用) | 6 |
continuous,机械臂关节用 revolute,摄像头支架用 fixed。我曾经见过有人把轮子关节设成 revolute 还加了限位,结果小车只能转半圈…… 别犯这种低级错误。
第一个 URDF 模型
我们来写一个最简单的两轮差速底盘。只有三个 link:一个底盘和两个轮子,外加两个 continuous joint。
<robot name="simple_diff_drive">
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.3 0.08"/>
</geometry>
<material name="blue">
<color rgba="0 0.5 1 1"/>
</material>
</visual>
</link>
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.04"/>
</geometry>
<material name="gray">
<color rgba="0.3 0.3 0.3 1"/>
</material>
</visual>
</link>
<link name="right_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.04"/>
</geometry>
<material name="gray">
<color rgba="0.3 0.3 0.3 1"/>
</material>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="-0.15 0.2 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
<joint name="right_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="right_wheel"/>
<origin xyz="-0.15 -0.2 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</robot>
把这个文件保存为 diff_drive.urdf,然后用 check_urdf diff_drive.urdf 验证一下。如果输出 Robot successfully validated,恭喜你,第一个 URDF 模型就搞定了。
origin 坐标一定要相对于 base_link。我刚开始写 URDF 时,把轮子原点写成了相对于世界坐标系,结果轮子飞到了天上去…… 记住,origin 是相对于父 link 的。
你可以在 Rviz 里直接加载这个 URDF,用 robot_state_publisher 发布 tf,就能看到小车模型了。嗯,看到自己写的第一个机器人动起来,还是挺有成就感的。