4. 机器人URDF模型构建:URDF语法、link与joint定义、xacro优化、可视化检查
好,咱们进入正题。URDF,全称是Unified Robot Description Format,说白了就是机器人的「身份证」。你要让MoveIt认识你的机器人,首先得给它一张清晰的「证件照」——也就是URDF模型。我刚开始接触ROS那会儿,觉得这玩意儿不就是个XML嘛,随便写写就行。结果第一次加载模型,机器人直接在地上劈叉……嗯,从那以后我再也不敢小看URDF了。
核心要点:URDF定义了机器人的运动学树(Kinematic Tree),包括刚体(link)和关节(joint)。MoveIt依赖它来做运动规划、碰撞检测和可视化。
4.1 URDF语法基础
URDF本质上是一个XML文件。它的根元素是<robot>,里面包含两种核心元素:<link>和<joint>。你可以把link想象成机器人的骨头,joint就是连接骨头的关节。
4.1.1 link的定义
一个link至少需要定义视觉(visual)、碰撞(collision)和惯性(inertial)三部分。我见过不少新手只写visual,结果仿真时物理引擎直接报错。为什么?因为没有惯性参数,机器人就像一团空气。
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0"/>
<material name="blue">
<color rgba="0 0 1 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<origin xyz="0 0 0" rpy="0 0 0"/>
</collision>
<inertial>
<mass value="2.0"/>
<inertia ixx="0.01" ixy="0" ixz="0"
iyy="0.01" iyz="0"
izz="0.02"/>
</inertial>
</link>
个人经验:惯性矩阵的计算,我建议直接用SolidWorks或Fusion 360导出。手算?别折腾了,我试过一次,算出来的数值和实际差了一个数量级,仿真时机器人抖得像筛糠。
4.1.2 joint的定义
joint定义了link之间的相对运动关系。常见的类型有:fixed(固定)、revolute(旋转)、prismatic(平移)、continuous(连续旋转)。
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="arm_link1"/>
<origin xyz="0 0 0.1" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="10" velocity="1.0"/>
</joint>
这里要注意<origin>和<axis>。origin定义了子link相对于父link的位姿,axis定义了旋转轴。我曾经犯过一个低级错误:把旋转轴写成了xyz="1 0 0",结果机械臂只能左右摆,不能上下抬——你想想看,这还怎么抓东西?
4.2 xacro优化:告别重复劳动
写纯URDF?对于简单机器人还行。但如果你要做一个六轴机械臂,每个link写一遍,每个joint写一遍,光复制粘贴就能让你崩溃。这时候就需要xacro(XML Macros)出场了。
xacro说白了就是给URDF加了个「宏」功能。你可以定义变量、写循环、做数学运算。我个人习惯把所有可变的参数(比如长度、质量、颜色)都抽成xacro属性,这样改参数时只需要改一处。
<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="my_robot">
<xacro:property name="arm_length" value="0.5"/>
<xacro:property name="arm_mass" value="1.5"/>
<xacro:macro name="arm_link" params="name length mass color">
<link name="${name}">
<visual>
<geometry>
<cylinder length="${length}" radius="0.05"/>
</geometry>
<material name="${color}">
<color rgba="0 0 1 1"/>
</material>
</visual>
<inertial>
<mass value="${mass}"/>
<!-- 惯性矩计算省略 -->
</inertial>
</link>
</xacro:macro>
<xacro:arm_link name="arm_1" length="${arm_length}" mass="${arm_mass}" color="red"/>
<xacro:arm_link name="arm_2" length="0.3" mass="1.0" color="blue"/>
</robot>
避坑指南:我曾经在xacro里用了一个未定义的变量,结果模型加载时直接报错,查了半天才发现是拼写错误。建议每次修改xacro后,先用check_urdf命令验证一下。
4.3 可视化检查:眼见为实
模型写完了,怎么知道对不对?别急着跑MoveIt,先用可视化工具看一眼。我推荐两个工具:rviz和urdf_to_graphiz。
4.3.1 使用rviz检查
启动一个空的rviz,添加RobotModel显示插件,然后加载你的URDF文件。如果模型显示正常,恭喜你,至少语法没问题。如果模型缺胳膊少腿,多半是joint的origin定义错了。
4.3.2 使用urdf_to_graphiz生成树状图
这个工具能把URDF转换成一张图,直观展示机器人的运动学树结构。命令很简单:
urdf_to_graphiz my_robot.urdf
它会生成一个PDF文件,里面是树状图。我每次写完新模型都会跑一下这个命令,看看父子关系对不对。有一次我发现一个joint的parent和child写反了,机器人变成了「头朝下」——还好提前发现了。
4.4 本章知识体系
下面这张图总结了URDF模型构建的核心逻辑,你可以把它当作一个快速参考:
4.5 常见问题与调试技巧
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 模型加载后显示不全 | joint的origin定义错误,导致link位置偏移 | 检查<origin>的xyz和rpy值,确保子link在正确位置 |
| 关节无法转动 | joint类型写成了fixed,或者limit设置不合理 | 确认type为revolute或continuous,检查limit的lower/upper范围 |
| 物理仿真时机器人抖动 | 惯性参数缺失或数值不合理 | 补充<inertial>部分,使用CAD工具导出准确数值 |
| xacro文件解析失败 | 变量未定义或宏调用参数不匹配 | 使用xacro --check-order检查宏调用顺序 |
调试小技巧:我习惯在终端里用rosrun tf view_frames查看TF树。如果TF树和你的预期不一致,那肯定是joint的parent/child关系写错了。这个命令能帮你快速定位问题。
好了,URDF模型构建这部分就讲到这里。记住一句话:模型是MoveIt的基石,基础打牢了,后面的导航和规划才能跑得稳。下一节我们会把模型加载到MoveIt中,开始真正的运动规划配置。