3、机械臂URDF模型解析:URDF语法、link与joint定义、在Rviz中可视化。
URDF,全称是 Unified Robot Description Format。说白了,它就是ROS世界里描述机器人长什么样的标准语言。你想想看,要让机械臂在Rviz里动起来,总得告诉系统它有几个关节、几根连杆、长什么形状吧?URDF就是干这个的。
我个人习惯,每次开始一个新机械臂项目,第一件事就是先把URDF搭起来。哪怕后面要改,也得先有个骨架。今天我们就来拆解这个骨架。
3.1 URDF的语法基础:XML标签
URDF本质上是XML文件。所以它的语法就是标签套标签。根标签是 <robot>,里面再放 <link> 和 <joint>。
一个最简单的URDF骨架长这样:
<robot name="my_arm">
<link name="base_link">
<visual>
<geometry>
<box size="0.2 0.2 0.1"/>
</geometry>
</visual>
</link>
<joint name="joint_1" type="revolute">
<parent link="base_link"/>
<child link="link_1"/>
<origin xyz="0 0 0.1" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
</joint>
</robot>
嗯,这里要注意:<robot> 标签的 name 属性不能乱写,它会在后续的命名空间里出现。我见过有人把名字写成带空格的,结果编译直接报错。
3.2 link:机械臂的每一块骨头
每个 <link> 代表一个刚体部件。比如底座、大臂、小臂、末端执行器。每个link里可以定义三部分:视觉(visual)、碰撞(collision)、惯性(inertial)。
| 子标签 | 作用 | 是否必须 |
|---|---|---|
<visual> |
定义显示用的几何形状和颜色 | 推荐有 |
<collision> |
定义碰撞检测用的几何体 | 推荐有 |
<inertial> |
定义质量、质心、惯性张量 | 仿真必须 |
我在项目中遇到过一个问题:visual和collision用了不同的几何体,结果Rviz里看着没撞上,但Gazebo里机械臂直接穿模了。后来我学乖了,除非有特殊优化需求,否则visual和collision用同一套几何体。
几何体支持三种基本形状:
<box>:长方体,用size指定长宽高<cylinder>:圆柱体,用radius和length<sphere>:球体,用radius<mesh>:导入STL或DAE文件,最常用
3.3 joint:关节的定义与类型
joint把两个link连接起来。每个joint必须指定parent和child。方向是从parent指向child。
ROS2支持6种关节类型,但机械臂常用的就下面几种:
| 类型 | 说明 | 自由度 | 机械臂场景 |
|---|---|---|---|
revolute |
旋转关节,有角度限制 | 1 | 肩关节、肘关节 |
continuous |
无限旋转关节 | 1 | 末端旋转 |
prismatic |
平移关节 | 1 | 伸缩臂 |
fixed |
固定连接 | 0 | 传感器安装座 |
定义joint时,<origin> 和 <axis> 是最容易出错的。origin定义的是child link相对于parent link的位姿。axis定义旋转轴或平移方向。
<joint name="shoulder_pan" type="revolute">
<parent link="base_link"/>
<child link="shoulder_link"/>
<origin xyz="0 0 0.15" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="100" velocity="1.0"/>
</joint>
3.4 坐标系与变换树
URDF里每个link都有一个自己的坐标系。joint的origin定义了子link坐标系相对于父link坐标系的变换。这些变换串起来,就形成了TF树。
为什么这个重要?因为Rviz里显示机械臂,靠的就是TF树。如果某个joint的origin写错了,整个机械臂的位姿都会乱掉。
我个人习惯,在写URDF之前,先在纸上画一遍坐标系。标出每个joint的原点位置和旋转轴方向。画清楚了再写代码,基本不会出错。
3.5 在Rviz中可视化
URDF写好了,怎么验证?直接扔进Rviz看。
步骤很简单:
- 启动Rviz:
rviz2 - 添加RobotModel显示插件
- 在Description话题里填入你的URDF内容
但更推荐的做法是用 robot_state_publisher 节点。它会自动读取URDF并发布TF和关节状态。
# 启动robot_state_publisher
ros2 run robot_state_publisher robot_state_publisher --ros-args -p robot_description:=<你的urdf文件路径>
然后在Rviz里添加RobotModel,把Description话题设为 /robot_description。这时候你应该能看到机械臂的模型了。
check_urdf 工具可以快速验证:check_urdf your_robot.urdf。
3.6 本章知识体系
下面这张图总结了URDF的核心结构:
3.7 常见错误与避坑指南
写URDF的时候,有几个坑我几乎每次都会遇到:
- 标签大小写:URDF标签名全是小写,
<Link>不行,必须是<link> - joint的parent和child写反:这会导致TF树断裂,Rviz里模型散架
- 缺少limit标签:revolute和prismatic关节必须加limit,否则报错
- mesh路径错误:用相对路径时,要确保启动节点的工作目录正确
好了,URDF的基础就这些。你写的时候,记住一句话:link是骨头,joint是关节,origin是位置,axis是方向。把这四个东西搞清楚了,机械臂的模型就搭起来了。