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建模的核心结构。你可以把它当作检查清单:

URDF 建模核心结构 robot(根) link(连杆) joint(关节) visual(视觉) collision(碰撞) inertial(惯性) origin(位姿) axis(旋转轴) limit(限制) mass(质量) origin(质心) inertia(张量) 💡 关键原则:树形结构,每个 joint 连接一个 parent link 和一个 child link 惯性参数必须真实,否则动力学仿真不可信 每个 link 必须包含 collision + inertial 每个 joint 必须指定 parent/child

3.6 实战建议:从零开始建URDF

如果你要自己写URDF,我建议按这个顺序来:

  1. 先画运动学树:用纸笔画出所有连杆和关节的层级关系。
  2. 定义关节:确定每个关节的类型、轴方向、运动范围。
  3. 添加碰撞模型:用简单几何体包裹每个连杆。
  4. 填写惯性参数:从CAD导出或估算,不要用默认值。
  5. 添加视觉模型:最后再美化显示效果。
  6. 用check_urdf验证:ROS自带工具,能检查语法错误和结构问题。

小技巧:用urdf_to_graphiz可以生成运动学树的可视化图。我每次改完URDF都会跑一遍,看看树结构对不对。有一次发现多了一个悬空的link,就是靠这个工具抓出来的。

URDF建模看似基础,但它是整个仿真流程的基石。模型建得准,后面的仿真才有意义。别嫌麻烦,花时间把URDF调好,后面能省你十倍的时间。