2. link标签详解:视觉、碰撞、惯性 & 几何体

写URDF的时候,link 就是机器人的骨头。每个刚体部件——底盘、轮子、机械臂关节——都得用一个 link 描述。我刚开始接触URDF时,以为 link 就是画个形状而已,后来才发现里面藏着三个关键属性:visual、collision、inertial。今天咱们就把它们掰开揉碎。

link visual collision inertial cylinder/box/sphere/mesh cylinder/box/sphere/mesh link 三大属性 + 几何体类型

2.1 visual —— 你看到的样子

visual 定义机器人长什么样。说白了,就是给 rviz 或者 Gazebo 看的“皮肤”。

我习惯把 visual 放在最前面写,因为调试时第一眼看到的就是它。里面必须包含一个 <geometry>,然后可以加 <origin> 和 <material>。

一个简单的 visual 例子:
<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 比 visual 简单。比如一个复杂的机械臂末端,visual 可以用精细的 mesh,collision 用一个圆柱或盒子包起来。这样仿真跑得快,还不容易卡住。

我曾经偷懒没写 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 难算,其实对于简单几何体,有公式可以直接套。

几何体惯性矩公式 (沿主轴)说明
boxIxx = (m/12)*(y²+z²)尺寸为半长
cylinderIxx = (m/12)*(3r²+h²)沿轴向
sphereIxx = (2/5)*m*r²均匀球体
注意: inertia 矩阵必须对称正定,否则 Gazebo 会报错甚至崩溃。我遇到过一回去掉一个微小的非对角项,仿真就稳了。
<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 文件。
mesh 使用示例:
<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 里的脚本自动生成。但别全用零,物理引擎会罢工。
我曾经踩过的坑: 给一个轮子写 collision 时用了 sphere,结果轮子在地上打滑,因为球体碰撞模型没有“滚动摩擦”的概念。后来改成 cylinder 就好了。所以,轮子一定要用圆柱!

好了,link 标签的核心就这些。你写 URDF 时,记得把 visual、collision、inertial 当成三件套,缺一不可。下一章咱们聊 joint,那个更刺激——关节动起来,机器人才能活。