2. URDF标签详解(上):<robot>、<link>、<visual> 标签的使用与属性配置
URDF 是 ROS 里描述机器人模型的骨架。说白了,它就是一堆 XML 标签,告诉系统你的机器人长什么样、关节怎么动。今天咱们先啃最核心的三个标签:<robot>、<link> 和 <visual>。我个人习惯把这三个标签称为「URDF 三兄弟」——没有它们,模型根本立不起来。
2.1 <robot> —— 模型的根,一切从这里开始
<robot> 是所有 URDF 文件的顶层标签。你想想看,没有它,其他标签往哪儿放?它就像一栋房子的地基,所有 <link> 和 <joint> 都得包在里面。
<robot name="my_robot">
<link> ... </link>
<joint> ... </joint>
</robot>
name 属性是必填的,我建议你起个有意义的名字,比如 turtlebot3_waffle 或者 chassis_v2。千万别用 test 或 aaa——我在项目里见过有人这么干,结果三个月后自己都忘了这个模型是干啥的。
2.2 <link> —— 机器人的每一个刚体部件
每个 <link> 代表一个刚体零件。底盘、轮子、激光雷达支架……都是 link。它本身不包含几何形状,但可以挂载 <visual>、<collision> 和 <inertial> 子标签。
嗯,这里要注意:<link> 必须有一个 name 属性,而且名字在整个模型里不能重复。我曾经因为把两个轮子都叫 wheel,导致 TF 树直接崩溃,查了半天才发现是重名。
left_front_wheel、base_link。这样在 rviz 里看 TF 树一目了然。
2.3 <visual> —— 让 link 变得「看得见」
<visual> 是 <link> 的子标签,用来定义这个零件的可视化外观。没有它,你的机器人在 rviz 里就是一堆看不见的坐标轴。它包含三个核心子元素:<geometry>、<origin> 和 <material>。
2.3.1 geometry —— 形状由你定
支持四种基本几何:box、cylinder、sphere 和 mesh。我平时用得最多的是 box 和 cylinder,因为简单可靠。但如果你要搞一个酷炫的机器人外壳,那就得上 mesh 了。
| 几何类型 | 属性 | 示例 |
|---|---|---|
| box | size (xyz) | <box size="0.4 0.3 0.1"/> |
| cylinder | radius, length | <cylinder radius="0.1" length="0.05"/> |
| sphere | radius | <sphere radius="0.2"/> |
| mesh | filename, scale | <mesh filename="package://my_robot/meshes/arm.stl" scale="1 1 1"/> |
2.3.2 origin —— 位置和朝向
用来调整 visual 相对于 link 坐标系的偏移。默认原点在 link 中心,但很多时候你需要微调。比如把轮子视觉模型往下挪一点,让它贴地。
<origin xyz="0 0 -0.05" rpy="0 0 0"/>
rpy 是绕固定轴的旋转(roll, pitch, yaw),单位弧度。我刚开始总搞混顺序,后来记住「先绕 X 转,再绕 Y,最后绕 Z」就再也没错过。
2.3.3 material —— 给点颜色看看
可以定义颜色或纹理。颜色用 RGBA,范围 0~1。比如红色:<color rgba="1 0 0 1"/>。你也可以在 <robot> 里预先定义材质,然后通过 material="red" 引用,这样多个 link 就能共用颜色。
<visual> 里只写了 geometry,忘了写 origin,结果模型在 rviz 里飞到了半空中。后来我养成了习惯——每个 visual 都显式写 origin,哪怕全是 0。
2.4 完整示例:一个带底盘的机器人
下面是一个极简 URDF,包含一个底盘 link 和它的 visual。你可以直接复制到 .urdf 文件里试试。
<?xml version="1.0"?>
<robot name="simple_chassis">
<link name="base_link">
<visual>
<geometry>
<box size="0.5 0.4 0.12"/>
</geometry>
<origin xyz="0 0 0.06" rpy="0 0 0"/>
<material name="blue">
<color rgba="0.2 0.4 0.9 1"/>
</material>
</visual>
</link>
</robot>
你想想看,这个底盘就是一个 0.5m × 0.4m × 0.12m 的蓝色方块,中心在 base_link 坐标系上方 0.06m 处。保存后用 check_urdf 命令验证,再用 urdf_to_graphiz 就能看到结构图。
mesh 文件,路径一定要用 package:// 开头,不要写路径。我曾经把同事的 STL 文件放在桌面,用 /home/xxx/desktop/part.stl,结果换台电脑就找不到模型了。用 package:// 才是 ROS 的规范做法。
2.5 三个标签的协作逻辑
简单总结一下:<robot> 是总容器,<link> 是零件,<visual> 是零件的「皮囊」。一个 link 可以有多个 visual(比如一个轮子既有橡胶纹理又有轮毂),但通常一个就够了。我个人习惯把 visual 和 collision 分开写,虽然麻烦点,但后期调导航代价地图时能省不少事。
嗯,这一章的内容其实不多,但都是基本功。下一章我们会继续聊 <collision>、<inertial> 和 <joint>,到时候就能让机器人动起来了。