4、连杆(link)详解
连杆,说白了就是机器人身上的每一个“硬块”。底盘、轮子、手臂、摄像头支架……统统都是 link。我刚开始学URDF时,总觉得link就是画个方块,后来才发现——惯性、碰撞、视觉,每个子标签都藏着坑。今天咱们就把link的骨架拆开,一个一个讲透。
4.1 link 标签的骨架
一个完整的 <link> 长这样:
<link name="base_link">
<inertial> ... </inertial>
<visual> ... </visual>
<collision> ... </collision>
</link>
嗯,结构不复杂。但每个子标签里的门道,够你琢磨一阵子。我个人习惯是先写 visual,再补 collision,最后才填 inertial。为什么?因为视觉上能看到形状,碰撞可以复制视觉的几何,惯性则需要单独算——这个顺序不容易漏。
4.2 惯性参数(inertial)—— 物理仿真的灵魂
如果你只在 Rviz 里看模型,inertial 可以随便写。但一旦扔进 Gazebo 或别的物理引擎,惯性参数错了,机器人会像纸片一样飘,或者原地抖成筛子。我曾经在一个四轮底盘项目里,因为惯性张量少写了一个零,车子一加速直接翻跟头……
<inertial> 包含三个部分:
- mass —— 质量,单位 kg。别写太大也别太小,真实值最好。
- origin —— 惯性坐标系相对于 link 坐标系的偏移。一般用默认
xyz="0 0 0" rpy="0 0 0"就够。 - inertia —— 惯性张量,6 个独立分量:ixx, ixy, ixz, iyy, iyz, izz。单位 kg·m²。
<inertial>
<mass value="2.5"/>
<origin xyz="0 0 0" rpy="0 0 0"/>
<inertia ixx="0.012" ixy="0" ixz="0"
iyy="0.024" iyz="0" izz="0.024"/>
</inertial>
注意:ixy, ixz, iyz 如果物体对称且坐标系在质心,通常填 0。但如果你把 origin 偏移了,这些值可能非零。别偷懒,算一下。
4.3 视觉参数(visual)—— 你看到的样子
visual 只负责“看起来像什么”,不影响物理碰撞。它包含:
- geometry —— 形状。常用
<box>,<cylinder>,<sphere>,<mesh>。 - origin —— 几何体相对于 link 坐标系的位姿。
- material —— 颜色/纹理。可以用
<color rgba="..."/>或引用已有 material。
举个例子,一个红色圆柱体:
<visual>
<geometry>
<cylinder radius="0.1" length="0.3"/>
</geometry>
<origin xyz="0 0 0.15" rpy="0 0 0"/>
<material name="red">
<color rgba="1 0 0 1"/>
</material>
</visual>
<robot> 层级,多个 link 共用。比如 <material name="blue"><color rgba="0 0.4 0.8 1"/></material>,然后 visual 里直接 <material name="blue"/>。整洁,好改。
4.4 碰撞参数(collision)—— 物理引擎的“触觉”
collision 的结构和 visual 几乎一样,也有 geometry 和 origin。但它的形状可以比 visual 更简化。比如一个复杂的机械臂末端,visual 用精细的 STL 网格,collision 就用一个球体或立方体包起来。为什么?碰撞检测越简单,仿真跑得越快。
我曾经犯过一个错:直接把 visual 的 mesh 复制给 collision,结果 Gazebo 卡成 PPT。后来我把碰撞形状换成粗略的圆柱,速度直接提升 5 倍。
<collision>
<geometry>
<box size="0.2 0.15 0.1"/>
</geometry>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
</collision>
4.5 三个参数如何配合?一张表说清楚
| 参数 | 作用域 | 是否必须 | 典型值/建议 |
|---|---|---|---|
| inertial | 物理仿真 | 强烈推荐 | 质量按实际,惯性张量用公式或软件算 |
| visual | 可视化 | 通常需要 | 用 box/cylinder/mesh,颜色分明 |
| collision | 碰撞检测 | 推荐提供 | 尽量用简单几何体,包络住 visual |
你想想看,如果只写 visual 不写 collision,物理引擎会默认没有碰撞形状——机器人会直接穿过地面。反过来,只写 collision 不写 visual,你在 Rviz 里就看不见它。所以一般三个都写,各司其职。
4.6 避坑指南 & 个人经验
- 惯性张量别用默认值。 我曾经见过有人把所有 link 的 inertia 写成
ixx="0.01" iyy="0.01" izz="0.01",结果机器人像在水里游泳。每个连杆的形状不同,张量必须单独算。 - visual 和 collision 的几何中心。 如果 link 的原点不在几何中心,记得用 origin 偏移。比如轮子,原点在轴心,但圆柱体中心在几何中点,需要把 origin 的 z 偏移半个长度。
- 材质名称全局唯一。 不同 link 用相同材质名,颜色会互相覆盖。我习惯用
material_底盘、material_手臂这样区分。
📌 核心原则: visual 给人看,collision 给物理引擎看,inertial 给动力学看。三者可以不同,但必须协调。尤其是 collision 和 visual 的 origin,一定要对齐,否则调试时你会怀疑人生。
好了,link 的里里外外就这些。下一章咱们聊关节——连杆之间怎么连、怎么动,那才是机器人建模的关节(字面意思)。