2、URDF基础语法(上):XML基础回顾、robot标签、link标签详解、visual与geometry属性、简单连杆建模

各位同学,欢迎来到URDF建模的第一站。说实话,URDF本身并不复杂,它本质上就是一个描述机器人结构的XML文件。但很多初学者上来就栽在语法细节上,比如标签没闭合、单位搞错、坐标系乱套——这些坑我当年都踩过。

今天这一节,我们先打好基础。把XML的底子过一遍,然后重点吃透robot和link这两个核心标签。你想想看,一个机器人再复杂,也是由一个个连杆(link)和关节(joint)拼起来的。连杆就是机器人的“骨头”,关节就是“筋”。今天我们先搞定“骨头”。

本节核心目标:掌握URDF中link标签的完整写法,能独立创建一个带可视化几何体的简单连杆模型。

2.1 XML基础回顾——别小看这门“格式课”

URDF是XML的一种方言。所以,如果你对XML不熟,写URDF时会很痛苦。我记得刚带项目时,有个同事花了一整天排查一个URDF报错,最后发现只是<link>标签少了个斜杠——这种低级错误,浪费了多少时间。

XML的几个硬规矩,我帮你列出来:

  • 标签必须闭合:<link>...</link>,或者自闭合<geometry />。少一个斜杠都不行。
  • 属性值必须加引号:不管是双引号还是单引号,总之不能裸写。<link name="base_link">,写成name=base_link直接报错。
  • 大小写敏感:<Link>和<link>是两个东西。URDF规定所有标签都是小写。
  • 层级嵌套要正确:父标签完全包裹子标签,不能交叉。

我的小习惯:写URDF之前,先在VS Code里装好XML插件,它会自动帮你检查闭合和缩进。这能省掉至少一半的排错时间。

来看一个最简单的XML片段,感受一下:

<?xml version="1.0"?>
<robot name="my_first_robot">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.2" radius="0.1" />
      </geometry>
    </visual>
  </link>
</robot>

这段代码定义了一个叫my_first_robot的机器人,它只有一个连杆base_link,形状是个圆柱体。嗯,这就是URDF的“最小可行模型”。

2.2 robot标签——一切从这里开始

<robot>是URDF文件的根标签。整个机器人描述都包在里面。它只有一个必填属性:name。

属性 类型 必填 说明
name string 是 机器人的名称,用于标识,不能重复

写法很简单:

<robot name="my_robot">
  <!-- 这里放 link 和 joint -->
</robot>

一个URDF文件里只能有一个<robot>标签。如果你想把多个机器人放在同一个文件里?不行,得分开写。我在项目中一般是一个机器人一个URDF文件,命名规范是机器人名.urdf。

2.3 link标签详解——机器人的每一块“骨头”

<link>描述的是机器人中的一个刚性连杆。它不能变形,不能弯曲。每个link都有一个name属性,在整个机器人中必须唯一。

一个完整的link包含以下几个子元素:

子标签 必填 作用
<visual> 否 可视化外观,用于显示和仿真
<collision> 否 碰撞检测模型,用于物理引擎
<inertial> 否 惯性参数,用于动力学计算

你可能会问:三个都是可选的,那link能不能空着?能。但空link在Rviz里看不见,在Gazebo里也没物理效果。说白了,就是个占位符。我建议至少把<visual>写上,不然调试时什么都看不到,很抓狂。

曾经踩过的坑:有一次我写了一个link,只配了visual没配collision,结果Gazebo里机器人直接穿透地面掉下去了。因为碰撞模型默认不存在,物理引擎认为这个连杆“没有实体”。所以做仿真时,visual和collision最好都配。

2.4 visual与geometry属性——让连杆“看得见”

<visual>标签负责定义连杆长什么样。它下面有三个主要子标签:

  • <geometry>:几何形状(必填)
  • <origin>:相对link坐标系的偏移(可选,默认零偏移)
  • <material>:材质颜色(可选,默认白色)

其中<geometry>是最核心的。URDF支持四种基本几何体:

几何体 标签 关键属性
长方体 <box> size="长 宽 高"
圆柱体 <cylinder> length 和 radius
球体 <sphere> radius
网格文件 <mesh> filename(指向STL或DAE文件)

来看几个例子:

<!-- 一个长方体连杆,长0.5米,宽0.3米,高0.1米 -->
<link name="base_plate">
  <visual>
    <geometry>
      <box size="0.5 0.3 0.1" />
    </geometry>
  </visual>
</link>

<!-- 一个圆柱体连杆,半径0.05米,长度0.2米 -->
<link name="shaft">
  <visual>
    <geometry>
      <cylinder radius="0.05" length="0.2" />
    </geometry>
  </visual>
</link>

<!-- 一个球体连杆,半径0.1米 -->
<link name="joint_ball">
  <visual>
    <geometry>
      <sphere radius="0.1" />
    </geometry>
  </visual>
</link>

关于单位:URDF默认使用米、千克、秒(MKS)单位制。所有长度都是米,角度是弧度。我见过有人把毫米当米写,结果模型在Rviz里小得像蚂蚁。记住:1米=1000毫米,别搞混。

2.5 简单连杆建模——动手写第一个URDF

理论说完了,我们来实战。下面我带你创建一个完整的URDF文件,里面只有一个连杆——一个红色的圆柱体。

步骤很简单:

  1. 创建文件simple_link.urdf
  2. 写入<robot>根标签
  3. 添加一个<link>,命名为base_link
  4. 在<visual>里定义圆柱体几何
  5. 加上<material>设置颜色为红色

完整代码如下:

<?xml version="1.0"?>
<robot name="simple_robot">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.3" radius="0.1" />
      </geometry>
      <origin xyz="0 0 0" rpy="0 0 0" />
      <material name="red">
        <color rgba="1 0 0 1" />
      </material>
    </visual>
  </link>
</robot>

这里解释一下<origin>:xyz是相对link坐标系的平移,rpy是绕固定轴的旋转(roll、pitch、yaw,单位弧度)。默认都是0,表示几何体中心与link坐标系原点重合。

<material>里的color属性是RGBA格式,四个值范围0~1。红色是1 0 0 1,绿色是0 1 0 1,蓝色是0 0 1 1,最后一个1表示完全不透明。

验证方法:写完URDF后,用ROS自带的check_urdf工具检查语法。在终端运行:check_urdf simple_link.urdf。如果输出没有报错,说明语法正确。然后用urdf_to_graphiz可以生成结构图。

2.6 知识结构总览

下面这张SVG图帮你把今天的内容串起来。从根标签robot开始,到link,再到visual和geometry,层级关系一目了然。

URDF基础语法知识结构 <robot name="..."> <link name="..."> <visual> <collision> <inertial> <geometry> <origin> <material> <box size="..." /> <cylinder ... /> <sphere ... /> <mesh ... /> 核心:每个link至少配visual,仿真场景建议同时配collision和inertial

从这张图你可以看到,link是URDF的骨架节点,visual负责“长相”,geometry决定“形状”。今天我们先掌握这一条线,下一节会继续深入collision和inertial,以及最重要的joint——把骨头连起来。

课后练习:自己动手写一个URDF文件,包含两个link:一个长方体底座(0.4x0.3x0.1米,灰色),一个圆柱体立柱(半径0.05米,长度0.25米,蓝色)。用check_urdf验证,然后在Rviz里加载看看效果。