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文件,里面只有一个连杆——一个红色的圆柱体。
步骤很简单:
- 创建文件
simple_link.urdf - 写入
<robot>根标签 - 添加一个
<link>,命名为base_link - 在
<visual>里定义圆柱体几何 - 加上
<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,层级关系一目了然。
从这张图你可以看到,link是URDF的骨架节点,visual负责“长相”,geometry决定“形状”。今天我们先掌握这一条线,下一节会继续深入collision和inertial,以及最重要的joint——把骨头连起来。
课后练习:自己动手写一个URDF文件,包含两个link:一个长方体底座(0.4x0.3x0.1米,灰色),一个圆柱体立柱(半径0.05米,长度0.25米,蓝色)。用check_urdf验证,然后在Rviz里加载看看效果。