欢迎进入机器人建模的世界!这是 ROS 中最直观、最有趣的部分。
URDF (Unified Robot Description Format) 是 ROS 中的标准格式,用来描述机器人的外观(它长什么样)、物理属性(它有多重)以及运动学结构(它的关节怎么动)。
简单来说:如果 C++ 节点是机器人的大脑,那么 URDF 就是机器人的身体。
一、 核心概念:URDF 的“积木”理论
URDF 本质上是一个 XML 文件。构建一个机器人模型,其实就是搭积木。只有两种积木:
- Link (连杆/部件):
- 机器人的刚体部分。
- 比如:车体底盘、轮子、雷达、机械臂的大臂。
- 属性:Visual (外观,给人看的)、Collision (碰撞体积,物理引擎算的)、Inertial (质量/惯性,算物理运动用的)。
- Joint (关节):
- 连接两个 Link 的部件。
- 比如:连接轮子和底盘的轴、连接机械臂的舵机。
- 属性:Type (旋转、滑动、固定)、Origin (安装位置)。
核心规则:这就构成了一棵树(Tree)。
- Parent Link (父部件) -> Joint (关节) -> Child Link (子部件)。
二、 实战:编写第一个机器人模型
我们将建立一个非常简单的模型:一个方块形状的底盘,上面顶着一个圆柱形的雷达。
1. 准备工作
创建一个存放描述文件的包(通常以 _description 结尾):
cd ~/catkin_ws/src
catkin_create_pkg my_robot_description urdf xacro
cd my_robot_description
mkdir urdf
mkdir launch
2. 编写 URDF 文件
在 urdf 目录下新建文件 simple_robot.urdf。
<?xml version="1.0"?>
<robot name="my_first_robot"><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 0.8 1"/> </material></visual></link><link name="laser_link"><visual><geometry><cylinder length="0.1" radius="0.05"/></geometry><origin xyz="0 0 0" rpy="0 0 0"/><material name="white"><color rgba="1 1 1 1"/></material></visual></link><joint name="base_to_laser_joint" type="fixed"><parent link="base_link"/><child link="laser_link"/><origin xyz="0 0 0.15" rpy="0 0 0"/></joint></robot>
三、 怎么看?(使用 Launch 文件启动)
光有 URDF 是不够的,我们需要通过 Launch 文件把模型加载到 Parameter Server,并启动 RViz。
在 launch 目录下新建 display.launch:
<launch><param name="robot_description" textfile="$(find my_robot_description)/urdf/simple_robot.urdf" /><node name="joint_state_publisher_gui" pkg="joint_state_publisher_gui" type="joint_state_publisher_gui" /><node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" /><node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_robot_description)/urdf.rviz" required="true" />
</launch>
四、 运行与调试
- 运行:
cd ~/catkin_ws
catkin_make
source devel/setup.bash
roslaunch my_robot_description display.launch
- 在 RViz 中配置:
- RViz 打开可能是空的。
- Fixed Frame: 设置为
base_link。 - 点击左下角 Add -> 找到 RobotModel -> Add。
- 成功现象:你应该能看到一个蓝色的方块,顶着一个白色的圆柱体。
- 理解 TF 的作用:
- 还记得我们上一节学的 TF 吗?
robot_state_publisher节点读取了你的 URDF,发现base_link和laser_link之间有一个fixed关节,偏移是z=0.15。- 于是它自动向系统广播:
base_link->laser_link的 TF 变换。你不需要手写 TF 广播代码了!
五、 URDF 的进阶细节
1. 关节类型 (Joint Types)
我们在例子中用了 fixed,但机器人是会动的。常用类型如下:
- fixed: 固定不动的(如雷达安装座)。
- continuous: 连续旋转的(如轮子)。
- revolute: 有角度限制的旋转(如机械臂的肘关节,比如 -90度 到 90度)。
- prismatic: 直线滑动的(如升降台)。
2. 物理属性 (Inertial)
如果你只是在 RViz 里看,不需要这个。但如果你想在 Gazebo 仿真器里让它受重力影响掉下来,或者做碰撞检测,必须加 <collision> 和 <inertial>。
<link name="base_link"><visual> ... </visual><collision><geometry><box size="0.6 0.4 0.2"/></geometry></collision><inertial><mass value="10.0"/> <inertia ixx="1.0" ixy="0.0" ... /></inertial>
</link>
六、 痛点与解决方案:Xacro
如果你写过复杂的机器人,你会发现 URDF 有个大问题:重复代码太多。
比如一个四轮小车,四个轮子的代码几乎一模一样,只是位置不同。如果用纯 URDF,你得复制粘贴四遍。
解决方案:Xacro (XML Macros)
它是 URDF 的“升级版”,支持变量、宏(函数)和数学计算。
- URDF 写法:
<cylinder radius="0.05" ... />(写死) - Xacro 写法:
<xacro:property name="wheel_radius" value="0.05" />
<cylinder radius="${wheel_radius}" ... />
总结建议:
初学者先写纯 URDF 理解结构(Link/Joint)。一旦你觉得复制粘贴很烦,立刻去学 Xacro。
下一步建议:
你已经做出了一个静态的机器人模型。
- 想让它动起来吗? 我们可以修改 URDF,给轮子加上
continuous关节,并用 GUI 控制它转动。 - 想精简代码吗? 我可以教你如何把刚才的 URDF 改写成 Xacro 格式,使用宏来定义轮子。
你倾向于哪个?