第1章:机器人模型与URDF——统一机器人描述格式基础

大家好,我是你们的讲师。今天咱们来聊聊机器人建模这件事。

做机器人开发,第一步是什么?我个人觉得,不是写代码,不是调参数,而是先把你的机器人“描述清楚”。你想想看,如果你连自己的机器人长什么样、有几个关节、轮子多大都说不清楚,那后面的导航、避障、抓取,根本无从谈起。

URDF,全称是Unified Robot Description Format,翻译过来就是“统一机器人描述格式”。说白了,它就是一套用XML语言写的“机器人身份证”。

1.1 URDF到底能描述什么?

URDF能描述的东西,其实比你想象的多。我刚开始接触的时候,以为它就是个3D模型文件,后来才发现,它承载的信息远不止外观。

  • 运动学结构:机器人由哪些刚体(link)组成,它们之间怎么连接(joint)
  • 几何尺寸:每个部件的长宽高、半径、偏移量
  • 惯性参数:质量、质心、转动惯量——这个在动力学仿真里特别重要
  • 碰撞模型:用于碰撞检测的简化几何体,通常比视觉模型更粗糙
  • 视觉模型:你在Rviz里看到的那个“好看”的机器人

核心要点:URDF本质上是一个树形结构。从“base_link”(基座)开始,通过关节连接各个连杆,形成一棵完整的运动学树。

1.2 底盘URDF建模——从轮子开始

咱们先拿一个差速底盘举例。我记得第一次给学生讲这个的时候,有人问:“老师,底盘不就是四个轮子加一个板子吗?”嗯,从外观上看确实是这样,但URDF里你得把每个部件拆开。

来看一个最简单的两轮差速底盘URDF片段:

<robot name="my_robot">
  <!-- 底盘主体 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.4 0.3 0.1"/>
      </geometry>
      <material name="blue">
        <color rgba="0 0 1 1"/>
      </material>
    </visual>
    <collision>
      <geometry>
        <box size="0.4 0.3 0.1"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="2.0"/>
      <inertia ixx="0.01" ixy="0" ixz="0"
               iyy="0.01" iyz="0"
               izz="0.02"/>
    </inertial>
  </link>

  <!-- 左轮 -->
  <link name="left_wheel">
    <visual>
      <geometry>
        <cylinder radius="0.05" length="0.04"/>
      </geometry>
      <material name="gray"/>
    </visual>
  </link>

  <joint name="left_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="left_wheel"/>
    <origin xyz="-0.15 0.15 0" rpy="0 0 0"/>
    <axis xyz="0 1 0"/>
  </joint>
</robot>

这里有几个坑,我当年踩过:

  • 关节类型别搞错:轮子用continuous(连续旋转关节),机械臂关节用revolute(有限角度旋转),别混用
  • 坐标系方向:axis xyz="0 1 0"表示绕Y轴旋转,这个得跟你的实际电机安装方向一致
  • 碰撞模型别太精细:我曾经把一个机械臂的碰撞模型做得跟视觉模型一样精细,结果碰撞检测慢得要命。后来学乖了,碰撞模型用圆柱体或长方体代替

我的小技巧:写URDF的时候,先用简单的几何体(box、cylinder、sphere)把机器人搭出来,确认运动学没问题了,再替换成复杂的mesh文件。这样调试效率高很多。

1.3 机械臂URDF建模——关节与连杆的“父子关系”

机械臂的URDF,说白了就是一堆连杆和关节串在一起。我习惯从基座开始,一层一层往上写。

来看一个6轴机械臂的关节定义示例:

<joint name="joint1" type="revolute">
  <parent link="base_link"/>
  <child link="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"/>
</joint>

<joint name="joint2" type="revolute">
  <parent link="link1"/>
  <child link="link2"/>
  <origin xyz="0 0 0.3" rpy="0 1.57 0"/>
  <axis xyz="0 1 0"/>
  <limit lower="-2.09" upper="2.09" effort="8" velocity="1.0"/>
</joint>

这里要注意几个点:

  • origin里的rpy(翻滚角、俯仰角、偏航角)定义了子连杆相对于父连杆的旋转偏移。joint2的rpy="0 1.57 0"表示绕Y轴转了90度,这样第二个关节的轴线就变成水平方向了
  • limit里的lower和upper是关节限位,单位是弧度。我见过有人把限位设成-180 180,结果单位搞错了,应该是-3.14 3.14

曾经踩过的坑:有一次我写机械臂URDF,忘了给关节加limit标签,结果仿真的时候机械臂直接“飞”起来了——关节没有限位,电机一直转。从那以后,我每个关节都会仔细检查限位参数。

1.4 在Rviz2中可视化——验证你的模型

URDF写完了,怎么知道对不对?Rviz2就是最好的验证工具。

启动步骤很简单:

# 安装必要工具
sudo apt install ros-humble-urdf-tutorial

# 启动Rviz2并加载URDF
ros2 launch urdf_tutorial display.launch.py model:=/path/to/your_robot.urdf

在Rviz2里,你可以:

  • 用RobotModel插件显示机器人模型
  • 用TF插件查看坐标系变换
  • 用JointStatePublisher手动拖动关节,看看运动学对不对

我个人习惯,每次修改URDF后,都会在Rviz2里转一圈。看看关节方向对不对,连杆位置有没有偏移。这比直接跑导航程序再发现问题,效率高太多了。

1.5 本章知识体系总览

下面这张图,是我自己总结的URDF知识结构。你可以把它当成一个“检查清单”,写URDF的时候对照着看,不容易漏东西。

URDF机器人建模知识体系 URDF机器人描述 运动学结构 几何与惯性 视觉与碰撞 关节与限位 link(连杆) mass / inertia mesh / geometry limit / axis joint(关节) origin / rpy 碰撞简化 连续/有限旋转 验证工具:Rviz2 + RobotModel + TF 检查运动学树、坐标系、关节限位

这张图把URDF的核心要素都串起来了。你写模型的时候,就照着这个结构来,基本不会出错。

1.6 一些实用建议

最后,分享几个我这些年积累的经验:

  • 命名规范很重要:link和joint的名字要有意义,别用link1、link2这种。我习惯用base_link、shoulder_link、elbow_link这种,一看就知道是哪个部件
  • 单位统一:URDF里长度单位是米,角度单位是弧度。别混用,否则模型会变形
  • 版本控制:URDF文件建议用Git管理。我每次修改都会commit一次,方便回溯
  • 从简单到复杂:先写底盘,验证通过后再加机械臂。别一口气写完整个机器人,出了问题很难排查

一个小工具推荐:check_urdf命令可以帮你检查URDF语法错误。我每次写完都会跑一遍,能省不少调试时间。

好了,这一章的内容就到这里。URDF是机器人开发的基础,看似简单,但细节很多。你动手写一遍,遇到问题再回来翻翻,慢慢就熟练了。

可可精品资料库