3、机器人建模基础:URDF模型结构、连杆与关节定义、惯性参数设置
说到机器人仿真,第一步就是把物理世界的机器人「搬」进电脑里。这个「搬」的过程,就是建模。
在ROS生态里,URDF(Unified Robot Description Format)是的主流。它用XML描述机器人的运动学与动力学属性。说白了,就是告诉仿真器:你的机器人长什么样、关节怎么动、每个部件有多重。
我个人习惯,拿到一个新机器人,第一件事就是打开它的URDF文件。这比看任何文档都直观。
核心要点:URDF不是画图工具,它是机器人的「身份证」。仿真器靠它理解你的机器人。
3.1 URDF文件结构:一棵树
URDF的结构其实很简单——一棵树。根节点是robot,下面挂link(连杆)和joint(关节)。
你想想看,人形机器人从躯干出发,分出左臂、右臂、头部、双腿。每个分支又继续分下去。这就是典型的树形结构。
<robot name="my_humanoid">
<link name="base_link">
<!-- 躯干 -->
</link>
<joint name="neck_joint" type="revolute">
<parent link="base_link"/>
<child link="head_link"/>
</joint>
<link name="head_link">
<!-- 头部 -->
</link>
</robot>
注意,每个关节必须指定parent和child。这决定了运动学传递的方向。我在项目中遇到过有人把父子关系搞反,结果仿真时手臂从肩膀飞出去了……嗯,检查了半天。
3.2 连杆(link)定义:不只是几何
一个link包含三部分:视觉(visual)、碰撞(collision)、惯性(inertial)。
| 子元素 | 作用 | 是否必须 |
|---|---|---|
visual |
显示用的几何形状和材质 | 否(但建议有) |
collision |
物理碰撞检测用的形状 | 是 |
inertial |
质量、质心、惯性张量 | 是 |
这里有个坑:visual和collision可以不一样。比如你为了显示美观,用精细的STL网格;但碰撞检测为了性能,用简单的圆柱或盒子。我曾经为了省事,直接把视觉模型当碰撞模型用,结果仿真跑起来卡成PPT……
我的建议:碰撞模型尽量用基本几何体(box、cylinder、sphere)。复杂网格会让碰撞检测变慢,尤其人形机器人关节多,性能影响很明显。
3.3 关节(joint)定义:运动的灵魂
关节决定了两个连杆之间的相对运动。URDF支持6种关节类型:
- revolute:旋转关节,有角度限制。比如肘关节、膝关节。
- continuous:连续旋转关节,无限制。比如车轮。
- prismatic:平移关节,有位移限制。比如伸缩臂。
- fixed:固定关节,两个连杆焊死。比如躯干和骨盆之间。
- floating:6自由度浮动关节。一般用于基座与世界的连接。
- planar:平面运动关节,2平移+1旋转。
人形机器人最常用的是revolute。每个关节还需要定义origin(相对父连杆的位姿)、axis(旋转轴)、limit(运动范围)。
<joint name="right_elbow" type="revolute">
<parent link="right_upper_arm"/>
<child link="right_forearm"/>
<origin xyz="0 0 -0.3" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
<limit lower="-1.57" upper="0" effort="30" velocity="3.14"/>
</joint>
注意limit里的effort和velocity。很多人只填角度范围,忽略了力矩和速度限制。结果仿真时关节能输出无限大的力,机器人直接「自爆」了……
警告:关节的effort和velocity必须根据实际电机参数填写。否则仿真结果完全不可信。我曾经吃过这个亏,仿真里跑得好好的,真机上一动就过热保护。
3.4 惯性参数设置:最容易出错的地方
惯性参数包括质量(mass)、质心(origin)、惯性张量(inertia)。这是URDF里最容易被忽略、也最容易出错的部分。
为什么重要?因为动力学仿真全靠惯性参数算加速度。你设错了,仿真里的机器人就像在月球上跳舞——轻飘飘的,完全不对。
惯性张量是一个3x3矩阵,描述物体绕各轴旋转的惯性。URDF里只需要填对角线元素ixx、iyy、izz和交叉项ixy、ixz、iyz。
<inertial>
<mass value="2.5"/>
<origin xyz="0 0 -0.05" rpy="0 0 0"/>
<inertia ixx="0.03" ixy="0" ixz="0"
iyy="0.03" iyz="0"
izz="0.01"/>
</inertial>
这里有个技巧:对于简单几何体,可以用公式估算惯性张量。比如圆柱绕中心轴的惯性是0.5 * m * r^2。但对于复杂形状,最好用CAD软件导出。
避坑指南:我曾经直接用默认值ixx="0.01" iyy="0.01" izz="0.01",结果仿真时机器人走路像踩棉花。后来用SolidWorks导出了真实惯性参数,才恢复正常。记住:惯性张量不是随便填的。
3.5 知识体系总览
下面这张图总结了URDF建模的核心结构。你可以把它当作检查清单:
3.6 实战建议:从零开始建URDF
如果你要自己写URDF,我建议按这个顺序来:
- 先画运动学树:用纸笔画出所有连杆和关节的层级关系。
- 定义关节:确定每个关节的类型、轴方向、运动范围。
- 添加碰撞模型:用简单几何体包裹每个连杆。
- 填写惯性参数:从CAD导出或估算,不要用默认值。
- 添加视觉模型:最后再美化显示效果。
- 用check_urdf验证:ROS自带工具,能检查语法错误和结构问题。
小技巧:用urdf_to_graphiz可以生成运动学树的可视化图。我每次改完URDF都会跑一遍,看看树结构对不对。有一次发现多了一个悬空的link,就是靠这个工具抓出来的。
URDF建模看似基础,但它是整个仿真流程的基石。模型建得准,后面的仿真才有意义。别嫌麻烦,花时间把URDF调好,后面能省你十倍的时间。