2 · Link与Geometry

link标签是URDF的骨骼,每个刚体部件都靠它定义。说白了,link就是机器人的一块骨头——它得有形状、大小,还得告诉仿真引擎“我长什么样,哪里能碰,哪里不能碰”。

我个人习惯把link拆成三部分来看:视觉(visual)、碰撞(collision)、以及几何(geometry)。几何是形状,视觉是皮肤,碰撞是硬壳。嗯,咱们一个一个说清楚。

link visual 视觉 collision 碰撞 geometry 外观 物理边界 box / cylinder / sphere / mesh

link标签详解

一个典型的link长这样:

<link name="base_link">
    <visual>
        <geometry>
            <box size="0.4 0.3 0.1"/>
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0"/>
        <material name="blue">
            <color rgba="0 0 1 1"/>
        </material>
    </visual>
    <collision>
        <geometry>
            <box size="0.4 0.3 0.1"/>
        </geometry>
        <origin xyz="0 0 0" rpy="0 0 0"/>
    </collision>
</link>

注意看,visual 和 collision 里面都包了一个 geometry。它们可以不一样——我在项目里就经常把碰撞模型做得比视觉模型简单一点,省计算量。

核心要点: link必须有名字(name),而且整个机器人里不能重名。visual和collision都是可选的,但如果你要做碰撞检测或仿真,collision最好别省。

几何形状定义

URDF支持四种基本几何:box、cylinder、sphere、mesh。我按使用频率给你排个序:

形状标签参数典型用途
长方体<box>size="长 宽 高"基座、连接件、外壳
圆柱体<cylinder>radius, length关节、轮子、轴
球体<sphere>radius关节球、末端执行器
网格<mesh>filename, scale复杂外形(STL/DAE)

举个例子,轮子我一般用cylinder:

<geometry>
    <cylinder radius="0.08" length="0.04"/>
</geometry>

而机械臂的复杂外壳,我肯定用mesh,直接导入CAD导出的STL文件。不过要小心——mesh文件路径必须放在package:// 或者路径下,否则Gazebo会找不到模型。我曾经因为这个排查了整整一下午……

视觉属性(visual) vs 碰撞属性(collision)

这两个东西经常被新手搞混。我直接说人话:

  • visual —— 给人看的。决定机器人长什么样,颜色、材质、透明度。不影响物理。
  • collision —— 给物理引擎算的。决定哪里能撞、哪里能接触。形状越简单,仿真越快。

你想想看,如果碰撞模型和视觉模型完全一样,那当然没问题。但有时候视觉模型太精细(比如一个带花纹的壳体),碰撞检测会卡成PPT。我的习惯是:视觉用mesh,碰撞用box或cylinder包络。

我在做移动机器人底盘时,视觉模型是一个带圆角的STL外壳,碰撞模型直接用一个扁box代替。仿真速度提升了将近3倍,而且碰撞检测完全够用。
我曾经犯过一个错:只写了visual,没写collision。结果在MoveIt里做运动规划时,机器人直接“穿模”了——因为没有碰撞边界,规划器认为空间无限大。所以,做规划之前一定检查collision有没有定义。

origin与rpy —— 位置和姿态

每个visual和collision都可以通过 <origin> 设置相对于link坐标系的偏移。xyz是平移,rpy是旋转(roll, pitch, yaw)。

<origin xyz="0.1 0 0.05" rpy="0 0 1.57"/>

这个很实用。比如你想把摄像头装在机器人前方,直接改origin就行,不用重新建模。我个人习惯把视觉和碰撞的origin保持一致,除非有特殊需求。

material —— 给视觉加点颜色

visual里可以嵌套 <material>,定义颜色或纹理。颜色用rgba,范围0~1。比如:

<material name="light_gray">
    <color rgba="0.8 0.8 0.8 1.0"/>
</material>

material可以复用。在robot标签里定义好,然后link里引用name就行。嗯,这个后面第5章会细讲,这里先提一嘴。

一句话总结本章: link是机器人的零件,visual负责好看,collision负责好算,geometry是它们的形状基础。写URDF时,先搭collision骨架,再套visual皮肤——这是最不容易出错的顺序。