4. 机器人建模基础:URDF文件格式、关节与连杆定义、惯性参数设置
做机器人仿真,第一步就是得把机器人“说”给仿真器听。用什么说?URDF,全称是 Unified Robot Description Format。说白了,就是一个 XML 文件,里面描述了机器人长什么样、胳膊腿怎么连、每个部件有多重。
我记得刚入行那会儿,觉得 URDF 不就是个配置文件嘛,随便写写就行。结果第一次把模型丢进 Gazebo,机器人直接瘫在地上,跟面条似的。后来才发现,惯性参数没设对。嗯,从那以后我再也不敢小看这个文件了。
4.1 URDF 文件的核心结构
URDF 的核心就两个东西:连杆(link)和关节(joint)。连杆是刚体,关节是连接方式。一个机器人就是由连杆和关节交替组成的运动链。
来看一个最简单的 URDF 骨架:
<robot name="simple_arm">
<link name="base_link">
<visual>
<geometry>
<box size="0.2 0.2 0.1"/>
</geometry>
</visual>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="arm_link"/>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
</joint>
<link name="arm_link">
<visual>
<geometry>
<cylinder length="0.3" radius="0.02"/>
</geometry>
</visual>
</link>
</robot>
这个例子定义了一个底座加一个旋转关节带一根手臂。你想想看,每个关节必须指定父连杆和子连杆,这样仿真器才知道运动链怎么走。
关键点:URDF 要求机器人结构必须是一棵树,不能有闭环。如果你要做并联机构或者四足机器人,URDF 本身搞不定,得用 xacro 或者直接上 SDF 格式。
4.2 连杆定义:视觉、碰撞与惯性
每个 link 可以包含三个子块:visual、collision 和 inertial。很多人只写 visual,觉得能看见就行。但仿真器真正用的是 collision 和 inertial。
4.2.1 visual —— 看着像就行
visual 只负责显示。你可以用 box、cylinder、sphere 或者 mesh 导入 STL 文件。我个人习惯在调试阶段用简单几何体,最后再替换成精细的 mesh 文件,不然每次加载都卡半天。
4.2.2 collision —— 仿真器真正撞的是这个
collision 的几何体决定了碰撞检测的边界。你可以让它和 visual 一样,也可以简化。比如一个复杂的机械爪,visual 用精细 mesh,collision 用一个长方体包起来就行。这样碰撞计算快很多。
我的经验:collision 几何体尽量用凸包或者基本几何体。凹面体或者太复杂的 mesh 会导致碰撞检测不稳定,机器人会莫名其妙地弹飞。我曾经被这个问题坑了整整两天。
4.2.3 inertial —— 最容易被忽略,也最致命
inertial 块定义质量、质心和惯性张量。格式如下:
<inertial>
<mass value="1.5"/>
<origin xyz="0 0 0.02" rpy="0 0 0"/>
<inertia ixx="0.01" ixy="0.0" ixz="0.0"
iyy="0.01" iyz="0.0"
izz="0.005"/>
</inertial>
这里 origin 是质心相对于连杆坐标系的位置。inertia 是 3x3 惯性张量的六个独立分量。为什么是六个?因为矩阵是对称的,ixy = iyx,以此类推。
警告:千万不要把惯性张量全设成 0!ROS 和 Gazebo 会直接报错,或者给你一个诡异的默认值。我见过有人把 ixx/iyy/izz 设成 0.001 这种极小值,结果机器人一跑就疯狂抖动。惯性参数必须和几何体尺寸、质量匹配。
4.3 关节定义:类型与运动轴
URDF 支持六种关节类型。我整理了一个表格,方便你对照:
| 类型 | 自由度 | 典型用途 | 注意事项 |
|---|---|---|---|
| revolute | 1 旋转 | 肩关节、肘关节 | 必须设置 limit |
| continuous | 1 旋转 | 车轮、无限旋转关节 | 不需要 limit |
| prismatic | 1 平移 | 线性滑轨、伸缩臂 | 必须设置 limit |
| fixed | 0 | 固定连接、传感器支架 | 不需要 limit |
| floating | 6 | 自由漂浮基座(无人机) | ROS 2 中支持更好 |
| planar | 3 | 平面移动(AGV 简化) | 较少使用 |
关节的 origin 定义了子连杆相对于父连杆的初始位置和姿态。axis 定义了运动轴的方向。对于 revolute 关节,轴的方向就是旋转轴;对于 prismatic 关节,轴的方向就是平移方向。
举个例子,人形机器人的髋关节通常是 revolute 类型,轴指向 Z 方向(左右旋转)或者 Y 方向(前后摆动)。写的时候一定要想清楚坐标系方向,不然机器人走路姿势会很奇怪。
4.4 惯性参数设置:理论与实操
惯性参数是 URDF 里最让人头疼的部分。理论上,对于一个均匀密度的长方体,惯性张量有公式可以算。但实际中,你的连杆可能是异形件,或者是从 CAD 导出的 mesh。
我推荐两种做法:
- 用 CAD 软件算:SolidWorks、Fusion 360 都能自动计算惯性张量。导出 URDF 时直接带上。
- 用近似几何体估算:把复杂零件近似成几个基本几何体的组合,分别算惯性再叠加。
下面是一个均匀密度圆柱体的惯性张量计算公式(圆柱轴线沿 Z 轴):
ixx = iyy = (1/12) * m * (3 * r^2 + h^2)
izz = (1/2) * m * r^2
ixy = ixz = iyz = 0
其中 m 是质量,r 是半径,h 是高度。如果你懒得算,网上有现成的惯性计算器,搜 "moment of inertia calculator" 就能找到。
避坑指南:我曾经给一个六轴机械臂写 URDF,五个关节的惯性参数都是估算的,跑仿真看起来没问题。结果一做力矩控制,第三个关节的力矩曲线全是毛刺。查了两天才发现是惯性张量里 ixy 设成了 0.01,但实际应该是 0。这种非对角项会让动力学方程多出耦合项,控制器根本扛不住。
4.5 本章知识体系
下面这张图帮你理清 URDF 建模的核心脉络:
4.6 实操建议:从零搭建一个 URDF
如果你刚开始写 URDF,我建议按这个顺序来:
- 先画草图:在纸上画出机器人的连杆和关节拓扑,标出每个关节的类型和运动轴方向。
- 写固定关节的骨架:先用 fixed 关节把所有连杆串起来,验证 visual 和 collision 的几何体是否正确。
- 替换活动关节:把 fixed 改成 revolute 或 prismatic,加上 limit 和 axis。
- 补惯性参数:最后再填 inertial 块。用 CAD 算或者用公式估,别空着。
- 用 check_urdf 验证:ROS 自带的
check_urdf工具能帮你检查语法错误和结构问题。
小技巧:在终端运行 urdf_to_graphiz 可以把 URDF 转成一张拓扑图,一眼就能看出关节父子关系对不对。我每次写完都会跑一下这个命令,比盯着 XML 看快多了。
URDF 是机器人仿真的地基。地基没打好,后面做运动学、动力学、控制都会出问题。花点时间把模型写扎实,后面能省你十倍的时间。