3、第一个URDF文件:创建最简单的机器人模型
好了,到了真正动手写代码的时候了。前面两章我们聊了URDF是什么、为什么用它,现在直接上干货——创建一个最简单的机器人模型。
我个人习惯,学任何新东西都是从最小可行模型开始。你想想看,如果连一个底盘都定义不好,后面加轮子、加传感器只会越搞越乱。所以这一章,我们就只做一件事:用URDF描述一个底盘。
3.1 URDF文件的基本骨架:<robot>标签
每个URDF文件,最外层必须有一个 <robot> 标签。它就像房子的地基,所有零件都装在里面。
<?xml version="1.0" encoding="utf-8"?>
<robot name="my_first_robot">
<!-- 这里放 link 和 joint -->
</robot>
注意几个细节:
- name属性是必须的,给机器人取个名字。我一般用项目代号或功能描述,比如
simple_chassis。 - XML声明可以省略,但建议加上。尤其是中文注释多的时候,指定
encoding="utf-8"能避免乱码。 - 注释用
<!-- -->,和HTML一样。我在项目里习惯在文件头部写版本号和修改日期。
3.2 定义底盘:<link>标签的核心用法
<link> 描述的是机器人身上的一个刚体部件。底盘、轮子、手臂连杆,都是link。每个link可以包含三个子部分:
| 子标签 | 作用 | 是否必须 |
|---|---|---|
<inertial> |
质量、惯性矩阵 | 仿真时必须 |
<visual> |
可视化外观(形状、颜色) | 建议有 |
<collision> |
碰撞检测用的简化形状 | 仿真时必须 |
对于第一个模型,我们只加 <visual>,先让它在Rviz里能显示出来。
3.3 写一个完整的底盘URDF
下面这个例子,定义了一个长0.6米、宽0.4米、高0.2米的矩形底盘。说白了就是一个盒子。
<?xml version="1.0" encoding="utf-8"?>
<robot name="simple_chassis">
<link name="base_link">
<visual>
<geometry>
<box size="0.6 0.4 0.2"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0"/>
<material name="blue">
<color rgba="0 0 1 1"/>
</material>
</visual>
</link>
</robot>
拆开来看:
link name="base_link"—— 底盘的名字。ROS里习惯把机器人的主体叫base_link,这是约定俗成的根坐标系。<geometry>—— 几何形状。这里用<box>,三个数字分别对应长、宽、高(单位:米)。<origin>—— 位置和姿态。xyz是相对link坐标系的偏移,rpy是绕固定轴的旋转(roll、pitch、yaw)。这里全零,表示几何中心就在link原点。<material>—— 外观材质。颜色用RGBA四通道,值范围0~1。0 0 1 1就是不透明的纯蓝色。
<origin> 的xyz偏移是相对于link自身的坐标系。如果你想让底盘中心在地面以上0.1米,可以写 xyz="0 0 0.1"。我在做AGV小车时,经常用这个偏移来调整底盘离地高度。
3.4 形状不止盒子:cylinder和sphere
除了盒子,URDF还支持圆柱体和球体。下面这个表总结了三种基本形状的写法:
| 形状 | 标签 | 参数 | 示例 |
|---|---|---|---|
| 盒子 | <box> |
size="长 宽 高" | size="0.6 0.4 0.2" |
| 圆柱体 | <cylinder> |
radius="半径" length="高度" | radius="0.15" length="0.1" |
| 球体 | <sphere> |
radius="半径" | radius="0.2" |
举个例子,如果你想把底盘做成一个圆柱体(像某些扫地机器人那样):
<link name="base_link">
<visual>
<geometry>
<cylinder radius="0.3" length="0.15"/>
</geometry>
<origin xyz="0 0 0.075" rpy="0 0 0"/>
<material name="gray">
<color rgba="0.5 0.5 0.5 1"/>
</material>
</visual>
</link>
注意这里 origin 的z轴设成了 0.075(高度的一半),目的是让圆柱体的底面刚好落在z=0平面上。嗯,这个细节很容易忘,我第一次写的时候就没加,结果底盘悬在半空中……
3.5 本章知识结构图
下面这张图帮你理清URDF文件的基本结构:
3.6 验证你的URDF文件
写完了怎么知道对不对?ROS提供了一个命令行工具:check_urdf。
# 安装工具(如果还没装)
sudo apt install liburdfdom-tools
# 检查URDF文件
check_urdf simple_chassis.urdf
如果一切正常,你会看到类似这样的输出:
robot name is: simple_chassis
---------- Successfully Parsed XML ---------------
root link: base_link has 1 child(ren)
child(1): base_link
ERROR: No root link found,说明你的URDF里没有定义任何link。或者link的name属性写错了。我曾经犯过一个低级错误——把 name 写成了 Name,XML是大小写敏感的,排查了十分钟才发现。
3.7 在Rviz里看一眼
光看文字不过瘾,我们把它显示出来。用 urdf_to_graphiz 可以生成结构图,但更直观的是用Rviz:
# 启动Rviz并加载URDF
ros2 run urdf_tutorial display.launch.py model:=`pwd`/simple_chassis.urdf
如果你是ROS1用户,命令稍有不同:
roslaunch urdf_tutorial display.launch model:=`pwd`/simple_chassis.urdf
Rviz窗口里应该出现一个蓝色的盒子或圆柱体。你可以用鼠标旋转视角,从各个方向观察它。
3.8 本章小结
这一章我们做了三件事:
- 学会了URDF文件的基本骨架:
<robot>标签 - 用
<link>定义了一个底盘,包含<visual>和几何形状 - 掌握了三种基本形状(box、cylinder、sphere)的写法
别看内容少,这是整个机器人建模的起点。后面的所有关节、传感器、传动系统,都是在这个底盘上长出来的。把这个基础打牢,后面会顺很多。