4. Link详解:惯性属性、碰撞属性、视觉属性
各位好,我是你们的机器人建模课讲师。今天咱们深入聊聊 Link 这个家伙。你想想看,一个机器人模型里,Link 就是每一块“骨头”——底盘、手臂连杆、摄像头支架,全是它。URDF 里 Link 有三个核心属性:视觉 (visual)、碰撞 (collision) 和 惯性 (inertial)。很多人只把视觉画得漂漂亮亮,结果仿真一跑就穿模,或者动力学直接崩了。嗯,这里要注意,三个属性各有各的活儿,一个都不能少。
4.1 视觉属性 (visual) —— 面子工程,但必须做
视觉属性决定了机器人“长什么样”。说白了就是给 Link 套上一层皮,让它在 Rviz 或 Gazebo 里能被看到。我个人习惯把视觉几何做得稍微精细一点,方便调试时一眼认出哪个零件是哪个。
<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 0 0.8 1"/>
</material>
</visual>
</link>
这里 origin 是视觉网格相对于 Link 坐标系的偏移。我记得有一次把 rpy 写成了 90 度,结果整个底盘在 Rviz 里是侧着飞的……排查了半天,最后发现是视觉原点没对齐。所以,视觉原点一定要和碰撞、惯性保持一致,否则你看到的和仿真算的不是同一个东西。
4.2 碰撞属性 (collision) —— 物理世界的硬边界
碰撞属性才是仿真引擎真正“摸得到”的几何。你视觉画得再花哨,碰撞体如果是个大箱子,那机器人就真的像个箱子一样去撞墙。我建议碰撞体尽量用简单的形状——盒子、圆柱、球体。为什么?因为复杂网格会让碰撞检测慢得像蜗牛。
<collision>
<origin xyz="0 0 0" rpy="0 0 0"/>
<geometry>
<cylinder radius="0.15" length="0.4"/>
</geometry>
</collision>
你可能会问:碰撞体的 origin 和视觉的 origin 必须一模一样吗?不一定,但强烈建议保持一致。否则你看到机械臂还没碰到东西,仿真里已经撞上了——这种“灵异事件”我调过不止一次。
4.3 惯性属性 (inertial) —— 动力学的心脏
惯性属性是 Link 的“体重”和“转动惯量”。没有它,机器人就像在太空中飘——完全不受重力影响。URDF 里惯性包括质量 mass 和惯量张量 inertia(ixx, ixy, ixz, iyy, iyz, izz)。
<inertial>
<origin xyz="0 0 0" rpy="0 0 0"/>
<mass value="2.5"/>
<inertia ixx="0.03" ixy="0" ixz="0"
iyy="0.04" iyz="0"
izz="0.03"/>
</inertial>
举个例子:一个 0.4m×0.3m×0.1m 的盒子,质量 2.5kg,质心在几何中心。那惯量大概就是上面那个数值。你可以用在线惯量计算器算一下,别凭感觉填。
4.4 三个属性的协作关系
视觉、碰撞、惯性,三者各自独立,但共用同一个 Link 坐标系。我习惯把它们写在一起,方便对照:
| 属性 | 作用域 | 推荐复杂度 | 常见错误 |
|---|---|---|---|
| visual | 可视化显示 | 中等(可带材质) | origin 偏移导致显示错位 |
| collision | 物理碰撞检测 | 尽量简单 | 使用复杂网格导致仿真卡顿 |
| inertial | 动力学计算 | 精确估算 | 惯量全零或随意填写 |
你想想看,如果视觉是个精细的机械臂模型,碰撞却是个大球,那仿真时机械臂还没碰到桌子,球就先撞上了——这显然不对。所以三个属性的几何中心最好重合,或者至少保证碰撞包络能真实反映机器人的外形。
4.5 一个完整的 Link 示例
下面我把三个属性拼在一起,这是一个简单的机器人底盘 Link:
<link name="chassis">
<visual>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<geometry>
<box size="0.5 0.4 0.1"/>
</geometry>
<material name="dark_gray">
<color rgba="0.2 0.2 0.2 1"/>
</material>
</visual>
<collision>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<geometry>
<box size="0.5 0.4 0.1"/>
</geometry>
</collision>
<inertial>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<mass value="3.0"/>
<inertia ixx="0.04" ixy="0" ixz="0"
iyy="0.06" iyz="0"
izz="0.04"/>
</inertial>
</link>
注意这里 origin 的 z 偏移了 0.05,因为盒子的高度是 0.1,质心在几何中心,所以把原点抬高一半。嗯,这种细节最容易忘,但忘了机器人就“陷地”了。
好了,关于 Link 的三个属性就聊到这儿。视觉是面子,碰撞是里子,惯性是底子。三者配合好,你的 URDF 模型才算真正“活”了。下一章我们会讲 Joint,但今天先把 Link 吃透——毕竟关节连的就是这些 Link 嘛。