2. URDF核心元素:link、joint、几何与碰撞
各位好,我是你们的老朋友。今天咱们来啃URDF里最硬核的几块骨头——link、joint、几何原点、惯性参数和碰撞检测。说实话,这些概念刚接触时容易绕晕,但只要你理清了,后面MoveIt调参就跟玩一样。
2.1 link 标签——机器人的骨骼
每个link代表机器人身上的一个刚体部件。你可以把它想象成一块骨头。我习惯把link分成三类:视觉link(长得什么样)、碰撞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"/>
</visual>
<collision>
<geometry>
<cylinder radius="0.2" length="0.5"/>
</geometry>
<origin xyz="0 0 0.25" rpy="0 0 0"/>
</collision>
<inertial>
<mass value="5.0"/>
<inertia ixx="0.1" ixy="0" ixz="0" iyy="0.1" iyz="0" izz="0.1"/>
</inertial>
</link>
嗯,这里要注意:origin 是相对于link自身坐标系的偏移。我见过很多新手把视觉和碰撞的origin搞混,结果仿真时机器人看着没撞,实际却卡住了。说白了,碰撞几何要尽量贴合真实外形,但可以简化——比如用圆柱代替复杂的爪子。
2.2 joint 标签——让骨头动起来
joint连接两个link,定义它们之间的相对运动。我个人最常用的类型是 revolute(旋转关节)和 prismatic(移动关节)。固定关节 fixed 也经常用来把传感器“粘”在机器人上。
| 关节类型 | 自由度 | 典型用途 |
|---|---|---|
| fixed | 0 | 固定连接,如相机支架 |
| revolute | 1 (旋转) | 电机驱动关节,有角度限制 |
| prismatic | 1 (平移) | 伸缩臂、滑台 |
| continuous | 1 (无限旋转) | 轮子、转台 |
| floating | 6 | 移动基座(很少直接用在URDF) |
<limit>,结果MoveIt规划时直接报错。记住,effort 和 velocity 也要填,不然控制器会“软绵绵”。
<joint name="shoulder_pan" type="revolute">
<parent link="base_link"/>
<child link="shoulder_link"/>
<origin xyz="0 0 0.2" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="20" velocity="1.0"/>
</joint>
你想想看,axis 定义了旋转轴的方向。如果想让关节绕着X轴转,就把 xyz="1 0 0"。我刚开始总把轴方向搞反,后来养成了一个习惯:在Rviz里加一个坐标轴显示,一眼就能看出问题。
2.3 geometry 与 origin——形状与位置
URDF支持四种基本几何:box、cylinder、sphere 和 mesh。我个人偏爱用mesh导入STL文件,这样外观更真实。但碰撞检测时,我会用简化几何体——比如用几个球体包络机械臂,计算量小很多。
origin 的 xyz 和 rpy 控制几何体相对于link坐标系的偏移。举个例子:你想让圆柱体竖着放,但默认圆柱的轴线是Z轴,如果模型是横着的,就旋转 rpy="0 1.57 0"(绕Y轴转90度)。
2.4 惯性参数——仿真真实感的灵魂
没有惯性参数的机器人,就像在太空中飘着。MoveIt做轨迹规划时,如果惯性矩阵给得离谱,规划出来的轨迹加速度会特别奇怪。我踩过最大的坑:给了一个连杆质量0.001kg,结果仿真时轻轻一碰就飞出去了。
惯性矩阵 <inertia> 有6个独立分量:ixx, ixy, ixz, iyy, iyz, izz。对于简单几何,可以用公式估算。比如一个长方体,质量m,尺寸a×b×c:
- ixx = m*(b² + c²)/12
- iyy = m*(a² + c²)/12
- izz = m*(a² + b²)/12
- 其他交叉项设为0(如果坐标系在质心)
快速估算技巧: 我经常用SolidWorks或Fusion 360导出URDF,它们会自动计算惯性。但如果你手写URDF,可以用这个在线小工具:惯性计算器(其实就是一个Python脚本)。嗯,别偷懒,惯性参数不准,后面PID调死你。
2.5 碰撞检测——安全第一
碰撞检测分两层:自碰撞(机器人和自己打架)和环境碰撞(撞到桌子、墙壁)。URDF里通过 <collision> 标签定义碰撞形状。MoveIt默认使用FCL(Flexible Collision Library)进行检测。
我曾经在调试一个六轴机器人时,发现规划出来的路径总是莫名其妙地抖动。查了两天,最后发现是碰撞几何里有一个mesh的顶点数太多,导致距离计算不稳定。换成简化圆柱后,问题立刻消失。