2、XML基础回顾:XML标签与属性、XML的树形结构、URDF中的XML规范
好,咱们正式开始第二讲。在动手写URDF之前,我强烈建议先花点时间把XML的基础过一遍。你可能会想:“XML嘛,不就是一堆尖括号?” 嗯,话是这么说,但URDF对XML的用法有它自己的脾气。我在项目里见过太多因为少写一个斜杠、搞错属性位置,导致整个机器人模型加载不出来的情况。所以,这一节咱们把地基打牢。
2.1 XML标签与属性:机器人的“骨架”和“关节”
说白了,XML就是一种用纯文本描述数据结构的语言。它只有两个核心概念:标签(Tag) 和 属性(Attribute)。
- 标签:就像机器人的骨架。它定义了“这是什么”。比如
<link>表示一个连杆,<joint>表示一个关节。标签必须成对出现,有头有尾:<link>...</link>。如果标签里没有内容,可以简写为自闭合形式:<link />。 - 属性:就像骨架上的关节参数。它定义了“这个东西长什么样”。属性写在起始标签里,格式是
名字="值"。比如<joint name="shoulder_pan" type="revolute">,这里的name和type就是属性。
核心记忆点: 标签定义结构,属性定义参数。在URDF里,你几乎所有的机器人参数(尺寸、颜色、惯性、传动比)都是通过属性传递的。
举个例子,一个最简单的连杆长这样:
<link name="base_link">
<visual>
<geometry>
<box size="0.2 0.2 0.1" />
</geometry>
</visual>
</link>
你看,<link> 是标签,name="base_link" 是属性。<box> 也是标签,它的 size 属性定义了长宽高。这里有个小细节:<box /> 是自闭合的,因为它里面没有子标签了。
我的习惯: 写属性值时,我永远用双引号,不用单引号。虽然XML语法上单引号也行,但ROS的解析器在某些旧版本里对单引号支持得不好。为了避免这种莫名其妙的坑,统一用双引号最省心。
2.2 XML的树形结构:从“散装零件”到“装配体”
XML最牛的地方在于它的树形结构。你可以把标签一层层嵌套起来,形成父子关系。这跟机器人本身的层级结构天然吻合——一个关节下面挂一个连杆,连杆下面再挂子关节,子关节下面再挂子连杆……
我刚开始学的时候,总觉得这玩意儿不就是个文件夹嘛。但真正在调试一个六轴机械臂时,我才体会到树形结构的重要性。你想想看,如果所有零件都平铺在同一个层级,那修改一个末端执行器的位置,你得手动算一堆坐标变换。但有了树形结构,你只需要改父关节的参数,子零件会自动跟着动。
来看一个典型的树形结构:
<robot name="my_robot">
<link name="base"> ... </link>
<joint name="joint1" type="continuous">
<parent link="base"/>
<child link="arm1"/>
</joint>
<link name="arm1"> ... </link>
<joint name="joint2" type="revolute">
<parent link="arm1"/>
<child link="arm2"/>
</joint>
<link name="arm2"> ... </link>
</robot>
这个结构用图表示更清楚。我画了一张SVG图,帮你理解这种层级关系:
看到没?<robot> 是根,下面挂着 <link> 和 <joint>。每个 <joint> 通过 <parent> 和 <child> 标签,把两个 <link> 串起来。这就是URDF的核心逻辑——用树形结构描述运动链。
2.3 URDF中的XML规范:那些“潜规则”
XML本身很灵活,但URDF给它加了很多硬性规定。这些规定不是随便定的,而是为了让ROS的解析器能高效、无歧义地读取你的机器人模型。我整理了一个表格,把最关键的规范列出来:
| 规范项 | 具体要求 | 我曾经踩过的坑 |
|---|---|---|
| 根标签 | 必须且只能有一个 <robot> 标签,必须有 name 属性 |
有一次我忘了写 name,结果 gazebo 直接报错“robot has no name”,排查了半天 |
| 标签顺序 | 同一层级下,<link> 必须在 <joint> 之前定义 |
我习惯先写关节再写连杆,结果解析器说“找不到父连杆”,后来才改过来 |
| 属性命名 | 所有名称(name)必须唯一,不能有空格或特殊字符 | 用中文命名?想都别想,ROS 1 的解析器直接崩溃 |
| 单位制 | 长度用米(m),角度用弧度(rad),质量用千克(kg) | 有一次我把角度写成了度数,结果机械臂转得跟抽风一样 |
| 自闭合标签 | 没有子内容的标签必须自闭合,如 <box /> |
写 <box></box> 虽然语法没错,但有些旧版解析器会警告 |
特别注意: URDF 对大小写敏感!<Link> 和 <link> 是两个完全不同的标签。我见过有人把 <visual> 写成 <Visual>,结果模型加载出来是透明的。所有标签和属性名都必须小写。
另外,还有一个容易被忽略的点:注释。XML的注释是 <!-- 注释内容 -->。我建议在复杂的关节或连杆定义前加注释,方便以后自己回头看。比如:
<!-- 基座连杆,固定在桌面上 -->
<link name="base_link">
...
</link>
嗯,这些规范看起来琐碎,但真能帮你省下大把调试时间。我个人习惯是在写完URDF后,先用 check_urdf 命令跑一遍语法检查。这个工具会告诉你哪里标签没闭合、哪里属性值不对。强烈推荐。
最后总结一下:XML的标签和属性是URDF的“砖瓦”,树形结构是“蓝图”,而URDF规范就是“施工标准”。这三样东西搞明白了,后面写URDF就是水到渠成的事。