3. link标签详解:惯性参数、视觉参数、碰撞参数、几何形状定义

好,咱们接着聊。上一章我们把URDF的骨架搭起来了,robot和link的基本结构大家应该心里有数了。今天我要重点讲讲link标签里最核心的几个参数——惯性、视觉、碰撞,还有几何形状怎么定义。

说实话,我刚接触URDF那会儿,觉得link就是个名字加个形状,随便写写就行了。结果第一次在Gazebo里仿真,机器人直接躺地上起不来,物理引擎报错报得飞起。后来才明白,link里的每个参数都有它的意义,少一个都不行。

3.1 惯性参数(inertial)—— 物理仿真的灵魂

惯性参数是干嘛用的?说白了,就是告诉物理引擎:这个零件有多重、质量分布在哪。没有这个,仿真里的机器人就是一坨没有重量的幽灵。

核心三要素:

  • mass:质量,单位kg。别写太大也别写太小,真实机器人一个关节电机大概0.5-2kg
  • origin:质心位置,相对于link坐标系
  • inertia:惯性张量,一个3x3的对称矩阵

惯性张量这块,我估计很多人会头疼。其实你不需要手动算,我有个笨办法:

<inertial>
  <mass value="1.0"/>
  <origin xyz="0 0 0" rpy="0 0 0"/>
  <inertia ixx="0.01" ixy="0.0" ixz="0.0"
            iyy="0.01" iyz="0.0"
            izz="0.01"/>
</inertial>

上面这个例子,质量1kg,质心在原点,惯性张量对角线都是0.01。这对应什么形状?一个边长大约0.17m的立方体。为什么?因为实心立方体的惯性矩公式是 (1/12)*m*(a²+b²),我懒得算的时候就用这个近似值。

注意:惯性张量不能全填0!ROS2的物理引擎会直接崩溃。我曾经见过有人偷懒把ixx、iyy、izz都写成0,结果仿真一开始机器人就飞了。

3.2 视觉参数(visual)—— 让机器人看得见

视觉参数就是给机器人穿衣服。它不影响物理仿真,只影响你在RViz里看到的样子。

视觉参数包含三个部分:

  • geometry:几何形状,决定长什么样
  • origin:相对于link坐标系的偏移
  • material:颜色和材质
<visual>
  <geometry>
    <box size="0.2 0.1 0.05"/>
  </geometry>
  <origin xyz="0.1 0 0" rpy="0 0 0"/>
  <material name="blue">
    <color rgba="0 0 1 1"/>
  </material>
</visual>

这里有个小技巧:material可以定义在robot标签里复用。我习惯把所有颜色集中定义,后面每个link直接引用名字就行,改颜色时只改一处。

3.3 碰撞参数(collision)—— 物理世界的边界

碰撞参数决定了机器人怎么跟环境互动。它和视觉参数长得几乎一样,但用途完全不同。

我的经验:碰撞模型尽量简化!视觉模型可以很精细,但碰撞模型用简单的几何体包络就行。比如一个复杂的机械爪,视觉上可以做成精细的STL,碰撞模型用几个box和cylinder组合就够了。这样物理引擎算得快,不容易卡死。

<collision>
  <geometry>
    <cylinder radius="0.05" length="0.2"/>
  </geometry>
  <origin xyz="0 0 0.1" rpy="0 0 0"/>
</collision>

3.4 几何形状定义 —— 三种基本形状

URDF支持三种基本几何体,加上一种网格文件:

形状 标签 参数 适用场景
立方体 <box> size="x y z" 基座、外壳
圆柱体 <cylinder> radius, length 关节、轮子
球体 <sphere> radius 关节球、传感器
网格 <mesh> filename, scale 复杂外形

网格文件我多说两句。STL和DAE格式都支持,但我推荐用DAE。为什么?DAE可以带颜色信息,STL只有几何。而且DAE文件小,加载快。不过要注意,文件路径要用package://的格式,别写路径。

<geometry>
  <mesh filename="package://my_robot/meshes/arm.dae" scale="0.001 0.001 0.001"/>
</geometry>

scale参数经常被忽略。很多CAD软件导出的单位是毫米,但URDF默认单位是米。所以如果你导出的模型是毫米单位,scale要填0.001。这个坑我踩过,第一次加载模型发现手臂大得像栋楼,找了半天才发现是单位问题。

3.5 知识体系结构图

下面这张图把link标签的完整结构画出来了,建议保存下来对照着写URDF:

link标签结构 link inertial mass | origin | inertia visual geometry | origin | material collision geometry | origin geometry 形状定义 <box> <cylinder> <sphere> <mesh> size="x y z" radius, length radius filename, scale 💡 碰撞模型尽量简化,视觉模型可以精细

3.6 避坑指南

最后分享几个我踩过的坑:

  • 惯性参数别乱填:我曾经图省事,所有link的惯性张量都填一样的值。结果仿真时机器人像果冻一样晃来晃去,物理引擎完全没法收敛。
  • 碰撞模型别用精细网格:一个复杂的STL文件做碰撞检测,CPU直接拉满。用几个基本几何体包络一下,效果差不多,性能提升十倍。
  • origin的rpy别搞错:rpy的顺序是绕固定轴X-Y-Z旋转,不是绕自身轴。这个顺序搞反了,零件位置全乱套。
  • 单位统一:URDF默认单位是米、千克、弧度。如果你从SolidWorks导出的模型是毫米、克、度,记得换算。

嗯,link标签的内容差不多就这些了。记住一个原则:视觉模型往细了做,碰撞模型往粗了做,惯性参数往准了做。这三者平衡好了,你的URDF模型就能跑得又稳又好看。

小技巧:写完URDF后,用check_urdf命令检查一下语法。ROS2里可以用urdf_to_graphiz生成结构图,一眼就能看出哪个link少了参数。

可可精品资料库