第二章:机器人URDF模型基础
URDF,全称是Unified Robot Description Format。说白了,它就是机器人的“身份证”和“骨架说明书”。没有它,MoveIt根本不知道你的机器人长什么样、胳膊往哪转。
我个人习惯,拿到一个新机器人,第一件事就是看它的URDF文件。这比看图纸还直观。你想想看,一个几百行的XML文件,就能描述一个复杂的机械臂,是不是很神奇?
URDF文件结构
URDF本质上是一个XML文件。它的根节点是<robot>,里面包含两大核心元素:<link>和<joint>。
我刚开始学的时候,总把link和joint搞混。后来我总结了一句话:link是骨头,joint是关节。骨头不会动,关节负责连接骨头并让它们动起来。
核心原则:一个完整的机器人模型,必须至少有一个base_link作为根,然后通过joint串联起所有link。
来看一个最简单的URDF骨架:
<robot name="my_robot">
<link name="base_link">
<visual>
<geometry>
<box size="0.2 0.2 0.1"/>
</geometry>
</visual>
</link>
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="arm_link"/>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
</joint>
</robot>
嗯,这里要注意:origin定义的是子link相对于父link的位置和姿态。我曾经在这里栽过跟头,坐标写反了,结果模型在RViz里直接飞出去了。
link与joint的详细定义
link:机器人的“骨头”
每个link可以包含三个部分:
- visual:可视化用的几何形状,不影响物理碰撞
- collision:碰撞检测用的形状,越简单越好
- inertial:惯性参数,包括质量、惯性矩阵
我的经验:collision几何体尽量用简单的形状(盒子、圆柱、球体)。复杂的mesh虽然好看,但会让碰撞检测变得很慢。我在做AGV项目时,把轮子的collision从mesh改成了圆柱体,性能提升了3倍。
joint:机器人的“关节”
joint的类型决定了机器人的运动方式:
| 类型 | 说明 | 自由度 |
|---|---|---|
| revolute | 旋转关节,有角度限制 | 1 |
| continuous | 连续旋转关节,无限制 | 1 |
| prismatic | 平移关节 | 1 |
| fixed | 固定连接,不能动 | 0 |
| floating | 6自由度浮动关节 | 6 |
为什么会有fixed关节?说白了,有些零件虽然物理上是分开的,但为了建模方便,我们把它拆成两个link,然后用fixed关节焊死。我在做协作机器人时,把末端执行器拆成了三个link,用fixed关节连接,这样更换夹爪时只需要改一个link就行。
坐标系与变换
URDF里最让人头疼的就是坐标系。每个link都有自己的坐标系,joint的origin定义了父子link之间的变换关系。
记住这个原则:子link的坐标系原点,是在父link坐标系下描述的。
举个例子:
<joint name="shoulder" type="revolute">
<parent link="base_link"/>
<child link="upper_arm"/>
<origin xyz="0 0 0.3" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
</joint>
这表示:upper_arm的坐标系原点,在base_link坐标系下是(0, 0, 0.3)的位置。旋转顺序是RPY(Roll-Pitch-Yaw),也就是绕X、Y、Z轴依次旋转。
避坑指南:我曾经在定义关节时,把rpy写成了0 0 90(度),但URDF里用的是弧度!结果模型在RViz里歪了90度,找了半天才发现是单位问题。记住:URDF里角度一律用弧度。
使用SolidWorks导出URDF
手动写URDF太累了,尤其是复杂机器人。我推荐用SolidWorks的SW2URDF插件。流程很简单:
- 在SolidWorks里建好装配体
- 安装SW2URDF插件
- 为每个零件定义坐标系和关节轴
- 导出URDF和mesh文件
导出后你会得到:一个.urdf文件,一个meshes文件夹(里面是STL文件),以及一个launch文件夹。
嗯,这里有个坑:SW2URDF导出的坐标系可能不符合ROS的惯例(Z轴向上)。我一般会在导出后手动检查一下origin的数值,尤其是rpy部分。
在RViz中可视化模型
有了URDF,我们就能在RViz里看到机器人了。用display.launch文件启动:
<launch>
<param name="robot_description" textfile="$(find my_robot)/urdf/my_robot.urdf"/>
<node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"/>
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher"/>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find my_robot)/config/display.rviz"/>
</launch>
启动后,你会看到:
- 机器人模型显示在RViz中
- 可以通过滑动条调节关节角度
- 坐标系显示为红绿蓝三色箭头
如果模型显示不出来,八成是robot_description参数没加载成功。用rosparam get /robot_description检查一下。
调试技巧:在RViz里添加TF显示,可以看到每个link的坐标系。如果某个link的坐标系位置不对,那肯定是joint的origin定义错了。我排查URDF问题时,90%的情况都是靠看TF坐标系找到的。
知识体系结构图
下面这张图总结了URDF的核心知识脉络,我建议你保存下来,写URDF时对照着看:
这张图把URDF的核心知识点串起来了。你写URDF时,从上到下、从左到右过一遍,基本不会漏掉什么。
好了,URDF的基础就这些。说白了,它就是一套描述机器人“骨头”和“关节”的规则。掌握了这些,你就能让机器人在RViz里动起来了。