2. link标签详解:视觉、碰撞、惯性 & 几何体
写URDF的时候,link 就是机器人的骨头。每个刚体部件——底盘、轮子、机械臂关节——都得用一个 link 描述。我刚开始接触URDF时,以为 link 就是画个形状而已,后来才发现里面藏着三个关键属性:visual、collision、inertial。今天咱们就把它们掰开揉碎。
2.1 visual —— 你看到的样子
visual 定义机器人长什么样。说白了,就是给 rviz 或者 Gazebo 看的“皮肤”。
我习惯把 visual 放在最前面写,因为调试时第一眼看到的就是它。里面必须包含一个 <geometry>,然后可以加 <origin> 和 <material>。
<link name="base_link">
<visual>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<material name="blue">
<color rgba="0.2 0.3 0.9 1.0"/>
</material>
</visual>
</link>
注意 origin 的 rpy 是弧度,别写成角度了。我见过有人写 rpy="90 0 0",结果模型直接翻倒——嗯,ROS 里默认是弧度。
2.2 collision —— 物理引擎的“硬骨头”
collision 用于碰撞检测。它和 visual 长得几乎一样,但 不关心颜色。Gazebo 或者 MoveIt 做碰撞检查时,用的是 collision 的几何体,不是 visual。
我曾经偷懒没写 collision,结果 Gazebo 里两个零件直接穿模——物理引擎根本不知道它们该撞上。所以,每个 link 最好都显式写 collision,哪怕和 visual 一样。
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder radius="0.1" length="0.3"/>
</geometry>
</collision>
2.3 inertial —— 动起来的关键
惯性属性决定了这个 link 有多“重”、转动惯量多大。没有它,机器人就像在太空中飘——完全不受力。
inertial 包含 mass 和 inertia 矩阵。很多人觉得 inertia 难算,其实对于简单几何体,有公式可以直接套。
| 几何体 | 惯性矩公式 (沿主轴) | 说明 |
|---|---|---|
| box | Ixx = (m/12)*(y²+z²) | 尺寸为半长 |
| cylinder | Ixx = (m/12)*(3r²+h²) | 沿轴向 |
| sphere | Ixx = (2/5)*m*r² | 均匀球体 |
<inertial>
<mass value="2.0"/>
<inertia ixx="0.01" ixy="0" ixz="0"
iyy="0.01" iyz="0"
izz="0.01"/>
</inertial>
2.4 几何体类型:cylinder / box / sphere / mesh
四种几何体,各有各的用法。我按使用频率排个序:
- box —— 方方正正的零件,比如底盘、控制箱。用
size指定长宽高。 - cylinder —— 轮子、关节轴。参数
radius和length。 - sphere —— 万向轮、球铰。只要一个
radius。 - mesh —— 复杂外形,比如机械臂外壳。用
filename指向 .stl 或 .dae 文件。
<geometry>
<mesh filename="package://my_robot/meshes/arm.stl" scale="1 1 1"/>
</geometry>
路径推荐用 package://,这样移植性好。我习惯把 mesh 文件放在 meshes/ 文件夹下。
2.5 避坑指南 & 个人习惯
- origin 偏移:visual 和 collision 的 origin 可以不同。比如 visual 用精细 mesh,collision 用一个居中的盒子,但位置要匹配,否则看着撞不上。
- 单位制:URDF 默认单位是米、千克、弧度。我见过有人把尺寸写成厘米,结果机器人变成巨无霸。
- inertia 近似:如果实在不知道怎么算,可以用
urdf_sim_tutorial里的脚本自动生成。但别全用零,物理引擎会罢工。
好了,link 标签的核心就这些。你写 URDF 时,记得把 visual、collision、inertial 当成三件套,缺一不可。下一章咱们聊 joint,那个更刺激——关节动起来,机器人才能活。