3、XML基础:XML语法规则、标签与属性、注释与命名空间
URDF 文件,说白了就是一个 XML 文件。你想想看,机器人模型里那么多连杆、关节、传感器,总得有个规矩把它们组织起来吧?XML 就是这套规矩。我刚开始学 URDF 时,以为直接写标签就行,结果解析器报了一堆错——嗯,从那以后我老老实实把 XML 语法啃了一遍。
这一章,咱们就把 XML 的核心规则捋清楚。不扯虚的,全是你在写 URDF 时一定会碰到的内容。
3.1 XML 语法规则:严格但简单
XML 的语法规则不多,但每条都是硬性的。写错了,解析器直接罢工。
| 规则 | 说明 | 常见错误 |
|---|---|---|
| 必须有根元素 | 整个文件只有一个顶层标签,所有内容包在里面 | 写了两个并列的 <robot> |
| 标签必须闭合 | 有开就有闭,自闭合标签用 /> |
<link> 忘了写 </link> |
| 大小写敏感 | <Link> 和 <link> 是两个东西 |
URDF 标准全是小写,大写会报错 |
| 属性值必须加引号 | 双引号或单引号都行,但不能省略 | name=link1 漏了引号 |
| 标签嵌套要正确 | 先开的后闭,不能交叉 | <a><b></a></b> |
核心原则:XML 是「格式即语义」的语言。格式错了,内容再对也没用。我在项目中见过有人把 <inertial> 写成 <Inertial>,Gazebo 直接不认——排查了半小时才发现是大小写问题。
3.2 标签与属性:URDF 的骨架和血肉
标签(Tag)定义「有什么东西」,属性(Attribute)定义「这个东西长什么样」。举个例子:
<link name="base_link">
<visual>
<geometry>
<box size="0.2 0.3 0.1"/>
</geometry>
</visual>
</link>
这里 <link> 是标签,name="base_link" 是属性。<box> 是自闭合标签,它的 size 属性用三个数字表示长宽高。
我个人习惯把属性用在「标识」和「简单数值」上。比如:
- 标识类属性:
name、type—— 给元素起名字、定类型 - 数值类属性:
size、xyz、rpy—— 直接填数字 - 引用类属性:
parent、child—— 关联其他元素
我的经验:属性值尽量用双引号,这是 ROS 社区的主流写法。单引号虽然合法,但混用容易看花眼。另外,属性名不要自己发明——URDF 规定好的属性名就那么几个,写错了解析器不会帮你纠错,只会默默忽略。
3.3 注释:给自己和队友留条路
XML 注释的写法是 <!-- 注释内容 -->。注意,注释不能嵌套,也不能出现在标签内部。
<!-- 这是底盘连杆,材质为铝合金 -->
<link name="base_link">
<!-- 视觉模型暂时用 box 占位,后续替换为 STL 文件 -->
<visual>
<geometry>
<box size="0.2 0.3 0.1"/>
</geometry>
</visual>
</link>
我曾经在一个协作项目里吃过亏:队友把注释写在 <link> 标签内部但没闭合好,结果整个文件解析失败。排查时发现注释里有个 -- 连字符,直接截断了注释范围。
避坑指南:注释内容里不要出现连续的 --(双减号),这是 XML 的保留标记。另外,注释不要用来「临时禁用」大段代码——用注释块包住标签虽然能生效,但嵌套注释会直接报错。我建议用编辑器自带的折叠功能或版本控制来管理临时改动。
3.4 命名空间:URDF 里用得少,但得懂
命名空间(Namespace)是 XML 用来解决「同名标签冲突」的机制。比如 <link> 在 URDF 里是连杆,在 XHTML 里可能是超链接——如果两个文件合并,解析器就懵了。
命名空间的写法是 xmlns:前缀="URI"。URDF 文件里最常见的命名空间是 xmlns:xacro,用于引入 Xacro 宏预处理功能:
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="my_robot">
<xacro:include filename="common_macros.xacro"/>
<link name="base_link"/>
</robot>
这里的 xacro 就是前缀,后面用 xacro:include 表示「这个标签来自 xacro 命名空间」。没有前缀的标签(比如 <link>)属于默认命名空间。
| 命名空间前缀 | 用途 | 示例 |
|---|---|---|
xacro |
宏定义、文件包含、数学运算 | <xacro:property name="pi" value="3.14159"/> |
gazebo |
Gazebo 仿真专用配置 | <gazebo reference="base_link"> |
controller |
ROS 控制器配置(较少直接写在 URDF 里) | <controller:gazebo_ros_controller/> |
注意:命名空间的 URI 只是一个唯一标识符,不一定要能访问。ROS 社区习惯用 http://... 格式,但解析器不会真的去联网下载什么。你完全可以把 URI 理解成一个「身份证号」——只要不重复就行。
3.5 知识结构总览
下面这张图把本章的核心知识点串起来了。你可以把它当作写 URDF 时的「语法速查卡」。
3.6 实战:写一个符合规范的 URDF 片段
光说不练假把式。咱们把这一章的知识点揉进一个完整的 URDF 片段里:
<?xml version="1.0" encoding="utf-8"?>
<!-- 这是一个符合 XML 规范的 URDF 文件片段 -->
<robot name="demo_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!-- 底盘连杆:使用 box 几何体 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0"/>
</visual>
</link>
<!-- 左轮连杆:使用 cylinder 几何体 -->
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.02"/>
</geometry>
</visual>
</link>
<!-- 关节:连接底盘和左轮 -->
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="-0.15 -0.2 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</robot>
检查清单:
- ✅ 根标签
<robot>只有一个 - ✅ 所有标签都正确闭合(
<box/>用了自闭合) - ✅ 属性值都加了双引号
- ✅ 标签名全小写(
link、joint、visual) - ✅ 注释写清楚了每个模块的用途
- ✅ 命名空间声明在根标签上
嗯,到这里 XML 基础就差不多了。你可能会觉得这些规则有点琐碎,但相信我——写 URDF 时 90% 的报错都来自这些「小地方」。养成好习惯,后面会省很多事。