[具身智能-117]:统一机器人描述格式( Unified Robot Description Format)ROS2 URDF 描述机器人没有血肉的运动骨架!
在 ROS 2 中,URDF (Unified Robot Description Format)是用来描述机器人“长什么样”以及“怎么动”的标准格式。
你可以把它理解为机器人的“数字孪生说明书”。它告诉 ROS 2 你的机器人由哪些零件组成(连杆),零件之间怎么连接(关节),以及它们的物理属性(质量、形状、颜色)。
以下是关于 ROS 2 URDF 的核心知识体系,涵盖从概念到实战的全过程。
1. URDF 的核心概念
URDF 文件本质上是一个XML 文件(后缀名为.urdf)。它通过两个最核心的标签来构建机器人:
- Link (连杆):机器人的“零件”。
- 描述零件的外观(Visual):在 RViz2 中长什么样(颜色、形状)。
- 描述零件的碰撞(Collision):用于物理碰撞检测的简化形状。
- 描述零件的惯性(Inertial):质量、重心,用于动力学仿真。
- Joint (关节):零件之间的“连接关系”。
- 定义两个 Link 的相对位置。
- 定义运动类型(旋转、滑动、固定)。
- 定义运动限制(最大角度、最大速度)。
2. 代码实战:构建一个简单的机器人
让我们通过一个具体的例子来看 URDF 的结构。假设我们要描述一个带有底盘和轮子的简单移动机器人。
核心代码片段解析
Link (定义底盘):
xml
<link name="base_link"> <visual> <origin xyz="0 0 0" rpy="0 0 0"/> <!-- 位置偏移和旋转 --> <geometry> <cylinder length="0.16" radius="0.20"/> <!-- 几何形状:圆柱体 --> </geometry> <material name="yellow"> <color rgba="1 0.4 0 1"/> <!-- 颜色:黄色 (R G B A) --> </material> </visual> </link>Joint (定义轮子连接):
xml
<joint name="left_wheel_joint" type="continuous"> <origin xyz="0 0.19 -0.05" rpy="0 0 0"/> <!-- 轮子相对于底盘的偏移 --> <parent link="base_link"/> <!-- 父连杆:底盘 --> <child link="left_wheel_link"/> <!-- 子连杆:左轮 --> <axis xyz="0 1 0"/> <!-- 旋转轴:绕Y轴旋转 --> <!-- continuous 类型表示可以无限旋转,不需要 limit 标签 --> </joint>完整示例文件 (robot.urdf)
xml
<?xml version="1.0"?> <robot name="my_first_robot"> <!-- 1. 定义底盘 --> <link name="base_link"> <visual> <geometry> <cylinder length="0.16" radius="0.20"/> </geometry> <material name="yellow"> <color rgba="1 0.4 0 1"/> </material> </visual> </link> <!-- 2. 定义左轮 --> <link name="left_wheel_link"> <visual> <geometry> <cylinder length="0.05" radius="0.05"/> </geometry> <material name="white"> <color rgba="1 1 1 1"/> </material> </visual> </link> <!-- 3. 连接底盘和左轮 --> <joint name="left_wheel_joint" type="continuous"> <origin xyz="0 0.19 -0.05" rpy="0 0 0"/> <parent link="base_link"/> <child link="left_wheel_link"/> <axis xyz="0 1 0"/> </joint> </robot>3. 如何在 ROS 2 中可视化 URDF
写好 URDF 文件后,你需要让它在 RViz2 中显示出来。这通常需要编写一个 Launch 文件来启动相关节点。
步骤 A: 创建 Launch 文件 (display.launch.py)
这个脚本的作用是启动RViz2,并加载你的URDF文件内容。
python
from launch import LaunchDescription from launch_ros.actions import Node from ament_index_python.packages import get_package_share_directory import os def generate_launch_description(): # 获取功能包路径 pkg_path = get_package_share_directory('your_package_name') urdf_path = os.path.join(pkg_path, 'urdf', 'robot.urdf') # 读取 URDF 文件内容 with open(urdf_path, 'r') as infp: robot_desc = infp.read() return LaunchDescription([ # 1. 启动机器人状态发布器 (发布 TF 变换) Node( package='robot_state_publisher', executable='robot_state_publisher', parameters=[{'robot_description': robot_desc}] ), # 2. 启动关节状态发布器 (用于手动拖动关节测试) Node( package='joint_state_publisher_gui', executable='joint_state_publisher_gui' ), # 3. 启动 RViz2 Node( package='rviz2', executable='rviz2', arguments=['-d', os.path.join(pkg_path, 'rviz', 'urdf.rviz')] ) ])步骤 B: 运行并查看
- 编译工作空间:
colcon build - 加载环境:
source install/setup.bash - 启动:
ros2 launch your_package_name display.launch.py
此时,你应该能在RViz2中看到你的黄色底盘和白色轮子。
4. URDF 的局限性与进阶 (Xacro)
虽然 URDF 是基础,但它有两个主要缺点:
- 无法参数化:如果你想修改轮子半径,必须手动去 XML 里改数字,不能复用。
- 文件冗长:复杂的机器人(如机械臂)URDF 文件会非常长,难以维护。
解决方案:Xacro (XML Macros)
Xacro 是 URDF 的“升级版”,它允许你使用变量、常量和宏来编写 URDF。
- URDF 写法:
<cylinder length="0.16" radius="0.20"/> - Xacro 写法:xml
<xacro:property name="wheel_radius" value="0.05" /> <cylinder length="0.05" radius="${wheel_radius}"/>
建议:在实际项目中,我们通常编写.xacro文件,然后在 Launch 文件中通过xacro命令将其转换为 URDF 供 ROS 2 使用。
5. 总结:关键标签速查表
表格
| 标签 | 作用 | 关键属性/子标签 |
|---|---|---|
<robot> | 根节点,定义机器人名称 | name="my_robot" |
<link> | 定义刚体零件 | name="link_name" |
<visual> | 外观显示 (给人看) | <geometry>,<material>,<origin> |
<collision> | 碰撞检测 (给计算机算) | 通常比 visual 形状更简单 (如用盒子代替复杂模型) |
<inertial> | 物理属性 (质量/重心) | <mass>,<inertia>(仿真必须) |
<joint> | 定义连接关系 | type="fixed/continuous/revolute/prismatic" |
<parent>/<child> | 定义父子连接 | 必须有,且不能形成闭环 |
<axis> | 运动轴向 | xyz="0 0 1"(绕Z轴) |
<limit> | 运动限制 | lower,upper,velocity,effort(除 continuous/fixed 外必填) |
掌握 URDF 是 ROS 2 机器人开发的必经之路,它是后续进行运动学计算、导航仿真和 MoveIt 规划的基础。
