2. URDF机器人建模基础:link与joint的定义、坐标系与惯性参数、可视化检查URDF模型

各位同学,欢迎来到第二章。这一章我们聊聊URDF建模。

说实话,URDF是ROS机器人建模的基石。你想想看,没有模型,MoveIt怎么规划运动?Gazebo怎么仿真物理?所以这一章,咱们得把基础打扎实了。

2.1 什么是URDF?为什么需要它?

URDF全称是Unified Robot Description Format,统一机器人描述格式。说白了,就是用XML文件描述你的机器人长什么样、关节怎么动、重心在哪。

我个人习惯把URDF比作机器人的「身份证」。它告诉ROS系统:

  • 你有几个身体部件(link)
  • 它们之间怎么连接(joint)
  • 每个部件有多重、惯性多大
  • 视觉上长什么样(mesh或几何体)

我在项目中遇到过最坑的事,就是同事把URDF里的惯性参数写错了。结果Gazebo仿真时机器人直接「起飞」了——嗯,物理引擎算出来的加速度完全不对。所以惯性参数这事,咱们后面得重点讲。

2.2 link的定义:机器人的「骨头」

link就是机器人的刚体部件。一个机械臂的每个臂杆、一个移动机器人的底盘,都是link。

一个典型的link包含以下几部分:

<link name="arm_link1">
  <visual>
    <geometry>
      <box size="0.1 0.05 0.3"/>
    </geometry>
    <origin xyz="0 0 0.15" rpy="0 0 0"/>
    <material name="blue">
      <color rgba="0 0 1 1"/>
    </material>
  </visual>
  <collision>
    <geometry>
      <box size="0.1 0.05 0.3"/>
    </geometry>
    <origin xyz="0 0 0.15" rpy="0 0 0"/>
  </collision>
  <inertial>
    <mass value="1.5"/>
    <inertia ixx="0.01" ixy="0" ixz="0"
             iyy="0.01" iyz="0"
             izz="0.005"/>
  </inertial>
</link>

这里有三块核心内容:

  • visual:视觉显示用的几何体,Gazebo和Rviz里能看到的样子
  • collision:碰撞检测用的几何体,可以比visual简单一些,节省计算
  • inertial:惯性参数,质量+惯性张量,Gazebo物理仿真必须
我的小技巧: collision几何体尽量用简单的形状(box、cylinder、sphere),别用复杂的mesh。我曾经把一个齿轮的STL文件直接当collision用,结果碰撞检测慢得像蜗牛爬。后来换成圆柱体,速度提升了10倍。

2.3 joint的定义:机器人的「关节」

joint连接两个link,定义了它们之间的相对运动关系。joint的类型决定了自由度:

类型 说明 自由度 典型应用
revolute 旋转关节,有限角度 1(旋转) 机械臂肘关节
continuous 连续旋转关节 1(旋转) 车轮
prismatic 平移关节 1(平移) 滑轨、升降台
fixed 固定连接 0 传感器支架
floating 6自由度浮动 6 移动机器人基座
planar 平面运动 3(x,y,偏航) AGV小车

来看一个典型的revolute关节定义:

<joint name="joint1" type="revolute">
  <parent link="base_link"/>
  <child link="arm_link1"/>
  <origin xyz="0 0 0.1" rpy="0 0 0"/>
  <axis xyz="0 0 1"/>
  <limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
  <dynamics damping="0.1" friction="0.01"/>
</joint>

这里要注意几个关键点:

  • parent和child:关节从父link指向子link,坐标系变换也是这个方向
  • origin:关节原点在父link坐标系中的位置和姿态
  • axis:旋转轴或平移方向,在子link坐标系中定义
  • limit:关节限位,MoveIt规划时会严格遵守
  • dynamics:阻尼和摩擦,Gazebo仿真用
我曾经踩过的坑: 有一次我把axis定义错了方向。本想让关节绕Z轴转,结果写成了绕X轴。在Rviz里看模型时完全没发现问题,但一跑运动学就全乱套了。所以写完URDF一定要做可视化检查!

2.4 坐标系与变换:TF树的基础

URDF里每个link都有自己的坐标系。joint的origin定义了子link坐标系相对于父link坐标系的变换。

我习惯这样理解:

  • 每个link的坐标系原点,默认在它的几何中心
  • joint的origin,就是子link坐标系原点在父link坐标系中的位置
  • 所有link通过joint串联起来,就形成了一棵TF树

举个例子,一个两连杆机械臂的TF树是这样的:

world → base_link → joint1 → link1 → joint2 → link2 → tool0

每个joint就是一个变换节点。MoveIt做运动学计算时,就是沿着这棵树从根节点遍历到末端。

核心原则: 坐标系定义要一致。我建议所有link都遵循右手定则,Z轴向上。这样后续做运动学、动力学都会省心很多。

2.5 惯性参数:物理仿真的灵魂

惯性参数是Gazebo仿真里最容易出错的地方。很多初学者直接忽略,结果仿真一跑就崩。

惯性张量是一个3x3的矩阵:

<inertial>
  <mass value="2.0"/>
  <inertia ixx="0.012" ixy="0.0" ixz="0.0"
           iyy="0.012" iyz="0.0"
           izz="0.005"/>
</inertial>

对于简单几何体,可以用公式计算:

几何体 ixx iyy izz
长方体 (a×b×c) m(b²+c²)/12 m(a²+c²)/12 m(a²+b²)/12
圆柱 (半径r,高h) m(3r²+h²)/12 m(3r²+h²)/12 mr²/2
球体 (半径r) 2mr²/5 2mr²/5 2mr²/5
我的经验: 如果实在不知道怎么算,可以用SolidWorks或Fusion 360导出URDF,它们会自动计算惯性参数。但要注意,导出的参数单位是kg·m²,别和ROS里的单位搞混了。

2.6 可视化检查:用Rviz验证模型

写完URDF,第一件事就是可视化检查。别直接丢进Gazebo,否则出了问题都不知道是模型的事还是物理引擎的事。

检查步骤很简单:

  1. 启动Rviz:rviz2
  2. 添加RobotModel显示插件
  3. 加载你的URDF文件
  4. 检查每个link的位置、朝向是否正确
  5. 拖动joint,看运动是否顺畅

我一般会检查这几个点:

  • 所有link是否都在正确的位置,没有「飞出去」的
  • 关节旋转方向是否符合预期
  • 碰撞几何体是否包裹住了视觉几何体
  • 坐标系箭头(在Rviz里可以显示)是否指向正确方向
注意: Rviz里显示正常,不代表Gazebo里也能正常。因为Gazebo还依赖惯性参数和碰撞属性。所以Rviz检查只是第一步,后面还要在Gazebo里做物理仿真验证。

2.7 本章知识体系

下面这张图总结了URDF建模的核心逻辑,我画成了流程图,方便你理解:

URDF机器人建模核心流程 定义机器人结构 定义link(刚体部件) 定义joint(关节连接) visual(视觉几何体) collision(碰撞几何体) inertial(质量+惯性张量) parent/child(父子关系) origin(坐标系变换) axis/limit(运动轴与限位) 可视化检查(Rviz) ✅ 模型就绪,进入仿真

这张图把URDF建模的流程串起来了。从定义结构开始,分两条线走——link和joint,最后汇聚到可视化检查。每一步都不可或缺。

好了,这一章的内容就到这。URDF建模看似简单,但细节很多。我建议你动手写一个简单的两连杆模型,然后加载到Rviz里看看效果。只有亲手做过,才能真正理解link和joint的关系。

可可精品资料库