第三章:URDF与机器人建模

说到机器人建模,URDF 是绕不开的第一道坎。我最早接触它的时候,觉得不就是个 XML 文件嘛,写起来应该不难。结果第一次在 Rviz 里看到自己的机器人像个散架的积木,那感觉,嗯,记忆犹新。

URDF 的全称是 Unified Robot Description Format,统一机器人描述格式。说白了,它就是用来告诉 ROS:你的机器人长什么样,关节在哪,能怎么动。今天我们就把它彻底讲透。

URDF 文件结构详解

一个标准的 URDF 文件,核心就两个东西:link 和 joint。link 是刚体部件,joint 是连接它们的关节。我习惯把 link 想象成骨头,joint 想象成关节,这样好理解。

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"/>
    <material name="blue">
      <color rgba="0 0 1 1"/>
    </material>
  </visual>
  <collision>
    <geometry>
      <box size="0.4 0.3 0.1"/>
    </geometry>
    <origin xyz="0 0 0" rpy="0 0 0"/>
  </collision>
  <inertial>
    <mass value="2.0"/>
    <inertia ixx="0.01" ixy="0" ixz="0"
              iyy="0.01" iyz="0"
              izz="0.01"/>
  </inertial>
</link>

这里有个坑,我刚开始做项目时经常忽略 <collision> 和 <inertial>。结果在 Gazebo 里仿真,机器人要么直接穿透地面,要么物理行为完全不对。记住,visual 只是给人看的,collision 和 inertial 才是给物理引擎用的。

joint 的定义

joint 决定了两个 link 之间的运动关系。常用的关节类型有:

类型 说明 自由度
revolute 旋转关节,有限角度 1
continuous 连续旋转关节,无角度限制 1
prismatic 平移关节 1
fixed 固定连接,不能动 0

写 joint 的时候,<parent> 和 <child> 的层级关系一定要理清楚。我曾经把 parent 和 child 搞反了,结果整个机械臂的运动学链全乱了,排查了半天才发现是这里的问题。

<joint name="shoulder_joint" type="revolute">
  <parent link="base_link"/>
  <child link="shoulder_link"/>
  <origin xyz="0 0 0.1" rpy="0 0 0"/>
  <axis xyz="0 0 1"/>
  <limit lower="-1.57" upper="1.57" effort="10" velocity="1.0"/>
</joint>

你想想看,<origin> 定义的是 joint 相对于 parent link 的位置,<axis> 定义的是旋转轴。这两个参数写错了,机器人动起来就会像喝醉了酒一样。

使用 SolidWorks 导出 URDF

手写 URDF 对于简单模型还行,但遇到复杂的机械臂,比如六轴协作机器人,手写就太痛苦了。这时候就需要用 SolidWorks 的 URDF 导出插件。

我个人习惯的流程是这样的:

  1. 在 SolidWorks 里建好装配体,每个零件作为一个独立的 part
  2. 定义好配合关系,确保关节的运动副正确
  3. 安装 sw2urdf 插件,这个插件是 ROS 社区开发的
  4. 运行导出向导,逐个指定每个 joint 的类型和轴方向

小技巧:导出前,把每个零件的坐标系原点对齐到关节旋转中心。这样导出的 URDF 里 <origin> 参数会更干净,后期调试省很多事。

导出完成后,你会得到一个文件夹,里面包含 URDF 文件、meshes 文件夹(存放 STL 文件)、以及一个 launch 文件。我建议你打开 URDF 文件检查一下,特别是 <inertial> 部分的数值。SolidWorks 导出的惯性参数有时候会偏大,需要手动调整。

注意:SolidWorks 导出的 URDF 默认使用 STL 格式的网格文件。STL 文件比较大,会影响加载速度。我一般会用 meshlab 或者 Blender 把网格简化一下,在不影响外观的前提下减少面数。

在 Rviz 中可视化机器人模型

模型建好了,怎么验证对不对?Rviz 就是最好的工具。你只需要一个 launch 文件,把 robot_description 参数加载到参数服务器,然后启动 Rviz 就行。

<launch>
  <param name="robot_description" 
         textfile="$(find my_robot_description)/urdf/my_robot.urdf"/>
  
  <node name="robot_state_publisher" 
        pkg="robot_state_publisher" 
        type="robot_state_publisher"/>
  
  <node name="rviz" pkg="rviz" type="rviz" 
        args="-d $(find my_robot_description)/config/display.rviz"/>
</launch>

启动后,在 Rviz 里添加 RobotModel 显示插件,你应该就能看到自己的机器人了。如果模型显示不出来,最常见的原因是:

  • URDF 文件路径不对,robot_description 没加载成功
  • mesh 文件路径是相对路径,但 Rviz 找不到
  • joint 的 parent 和 child 命名有拼写错误

我记得有一次,模型死活显示不出来,折腾了两个小时。最后发现是 URDF 文件里一个 link 的名字多了一个空格。这种低级错误,排查起来真的很崩溃。

为了让模型动起来,你还需要发布 joint states。可以用 joint_state_publisher 这个节点,它会弹出一个 GUI 滑块,让你手动拖动每个关节。或者用 joint_state_publisher_gui,效果一样但界面更友好。

核心要点:URDF 建模的本质是建立一棵树状的 kinematics chain。每个 joint 连接两个 link,从 base_link 开始,一直延伸到末端执行器。这棵树的结构决定了机器人的运动学行为。

下面这张图展示了 URDF 建模的核心逻辑,从 SolidWorks 模型到 Rviz 可视化的完整链路:

URDF 建模与可视化流程 SolidWorks 建模 装配体 + 配合关系 sw2urdf 导出 生成 URDF + meshes URDF 文件 link + joint 定义 视觉/碰撞/惯性 robot_description 加载到 ROS 参数服务器 state_publisher 发布 TF + joint states Rviz 可视化 显示 + 调试模型 核心:URDF 是一棵 kinematics tree,从 base_link 到 end_effector link = 骨头 | joint = 关节 | 树状结构决定运动学

最后说一句,URDF 建模这件事,看起来简单,但真正做好需要耐心。我见过太多人一上来就想写复杂的模型,结果被各种小问题折磨得放弃。我的建议是:从最简单的两连杆开始,先在 Rviz 里跑通,再逐步增加复杂度。这样每一步都能验证,出了问题也知道从哪里排查。

嗯,URDF 的内容就讲到这里。记住,模型是仿真的基础,基础打牢了,后面的运动学、轨迹规划才能顺利进行。

可可精品资料库