4、URDF模型基础:URDF文件结构、link与joint的定义、可视化URDF模型

各位同学,欢迎来到第四章。从这一章开始,我们就要亲手搭建机器人的“骨架”了。

URDF,全称是Unified Robot Description Format,统一机器人描述格式。说白了,它就是一套用XML语言写的“机器人说明书”。你想想看,我们要在Gazebo里仿真一个机器人,总得告诉它:你长什么样?胳膊多长?关节能怎么动?这些信息,全都写在URDF文件里。

我个人习惯把URDF比作机器人的“身份证”加“体检报告”。它既描述了你的静态结构(link),也描述了你的活动能力(joint)。没有它,Gazebo里就是一团空气。

核心要点:URDF是ROS和Gazebo世界的“通用语言”。你写的每一个link和joint,最终都会变成仿真世界里的实体。

4.1 URDF文件结构:一棵倒着长的树

URDF文件的结构,其实就是一个树形结构。根节点在最上面,然后分叉出各种枝干。我刚开始学的时候,总觉得这玩意儿很抽象,后来在项目里调试一个六轴机械臂,天天跟这棵树打交道,才彻底搞明白。

一个标准的URDF文件,最外层是<robot>标签,里面包含两部分核心内容:link(连杆)和joint(关节)。

下面这张图,是我用SVG画的URDF结构逻辑图,你看一眼就明白了:

<robot> <link> <joint> visual collision inertial parent link child link origin URDF 文件结构:树形层级关系 一个 robot 包含多个 link 和 joint link 定义外观、碰撞、惯性 joint 定义连接关系和运动方式

嗯,这里要注意:joint 必须连接两个 link,一个叫 parent(父连杆),一个叫 child(子连杆)。整个机器人就是靠这种父子关系,一层层搭起来的。

4.2 link的定义:机器人的每一块骨头

link 就是机器人的一个刚体部件。比如一个机械臂的基座、一个轮子、一个摄像头支架,都是一个 link。

每个 link 有三个核心属性需要定义:

属性 作用 必填
visual 视觉外观,决定你“看到”的样子 推荐
collision 碰撞模型,决定物理接触边界 推荐
inertial 惯性参数,决定质量、转动惯量 必须

来看一个最简单的 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>
  </collision>
  <inertial>
    <mass value="2.0"/>
    <inertia ixx="0.01" ixy="0" ixz="0" iyy="0.01" iyz="0" izz="0.01"/>
  </inertial>
</link>

这段代码定义了一个长0.4米、宽0.3米、高0.1米的蓝色盒子,质量2公斤。我在项目中遇到过一个问题:有人只写了visual,没写collision,结果仿真时机器人直接穿模到地底下去了。所以,collision 一定要写,哪怕形状跟visual一样。

小技巧:visual和collision的几何形状可以不一样。比如你为了视觉好看,用了一个复杂的mesh模型,但碰撞模型可以用一个简单的长方体代替,这样仿真计算会快很多。

4.3 joint的定义:机器人的关节

joint 定义了 link 之间的连接方式和相对运动。URDF 支持六种关节类型:

类型 说明 自由度
revolute 旋转关节,有限角度 1
continuous 连续旋转关节,无角度限制 1
prismatic 平移关节,直线运动 1
fixed 固定关节,两个link焊死 0
floating 浮动关节,6自由度 6
planar 平面关节,在平面内运动 3

最常用的是 revolute 和 fixed。来看一个旋转关节的例子:

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

这里我解释几个关键点:

  • origin:关节原点在父link坐标系中的位置和姿态。说白了,就是关节长在父link的哪个位置。
  • axis:旋转轴的方向。xyz=(0,0,1)表示绕Z轴旋转。
  • limit:关节的运动范围。lower和upper是角度限制(弧度),effort是最大力矩,velocity是最大速度。

我曾经犯过一个低级错误:把origin的rpy写成了"0 0 0",结果关节朝向完全不对,机械臂直接扭成了麻花。后来排查了半天才发现,原来是坐标系理解错了。所以,写joint之前,先在纸上画清楚坐标系,这个习惯帮我省了不少时间。

注意:joint的origin是相对于parent link的坐标系。而link内部的visual和collision的origin,是相对于link自身的坐标系。这两个别搞混了,我见过太多人在这里栽跟头。

4.4 可视化URDF模型:眼见为实

写完了URDF文件,怎么知道对不对?别急着跑Gazebo,先用ROS自带的可视化工具检查一下。

最常用的命令是 urdf_to_graphiz 和 check_urdf:

# 检查URDF语法
check_urdf my_robot.urdf

# 生成结构图
urdf_to_graphiz my_robot.urdf

check_urdf 会告诉你有没有语法错误,比如标签没闭合、属性值写错了之类的。urdf_to_graphiz 会生成一张PDF图,把机器人的树形结构画得清清楚楚。

我个人更推荐用 RViz 来可视化:

# 启动一个空的RViz
rosrun rviz rviz

# 在RViz中,添加RobotModel显示插件
# 然后在URDF参数中填入你的URDF文件路径

在RViz里,你可以旋转、缩放、查看每个link的坐标系。我记得有一次调试一个四轮小车,四个轮子的joint方向总是对不上,就是在RViz里一个一个坐标系看过去,才发现有一个轮子的axis写反了。

调试技巧:在RViz中勾选“Show Axes”,每个link都会显示自己的坐标系。红色是X轴,绿色是Y轴,蓝色是Z轴。一眼就能看出关节朝向对不对。

还有一个在线工具叫 URDF Viz(你可以在浏览器里搜到),直接把URDF代码粘贴进去,就能看到3D模型。适合快速验证,不用启动ROS环境。

4.5 一个完整的URDF示例

最后,我放一个完整的、最简单的URDF文件。这是一个两连杆的机械臂:

<?xml version="1.0"?>
<robot name="simple_arm">
  
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.1" radius="0.05"/>
      </geometry>
      <origin xyz="0 0 0" rpy="0 0 0"/>
      <material name="gray">
        <color rgba="0.5 0.5 0.5 1"/>
      </material>
    </visual>
  </link>
  
  <link name="arm_link">
    <visual>
      <geometry>
        <box size="0.02 0.02 0.3"/>
      </geometry>
      <origin xyz="0 0 0.15" rpy="0 0 0"/>
      <material name="red">
        <color rgba="1 0 0 1"/>
      </material>
    </visual>
  </link>
  
  <joint name="base_to_arm" type="revolute">
    <parent link="base_link"/>
    <child link="arm_link"/>
    <origin xyz="0 0 0.05" rpy="0 0 0"/>
    <axis xyz="0 0 1"/>
    <limit lower="-3.14" upper="3.14" effort="5" velocity="1.0"/>
  </joint>
  
</robot>

这个例子虽然简单,但五脏俱全。一个灰色的圆柱底座,上面连着一根红色的细长臂,关节可以绕Z轴旋转。你把它保存成 simple_arm.urdf,然后用 check_urdf 检查一下,再用RViz看看效果。

嗯,URDF的基础就这些。说白了,就是link加joint,一层层搭积木。下一节我们会在这个基础上,加入更多的细节,让机器人变得更真实。


可可精品资料库