3、URDF与机器人建模:从零编写一个简单的URDF模型
说到机器人建模,URDF(Unified Robot Description Format)是绕不开的第一道坎。说白了,它就是机器人的「身份证」——告诉系统你的机器人长什么样、关节怎么动、传感器装在哪。
我刚开始接触URDF时,觉得不就是个XML文件嘛,随便写写就行。结果第一次加载到RViz里,机械臂直接「飞」到了天上。嗯,坐标系搞反了。从那以后,我对URDF的每一个数字都格外小心。
3.1 URDF的核心结构:连杆与关节
URDF的核心就两个东西:连杆(link)和关节(joint)。你可以把连杆想象成骨头,关节就是连接骨头的韧带。
- link:描述刚体部分,包括视觉外观、碰撞模型、惯性参数
- joint:描述两个连杆之间的运动关系,包括类型、父子关系、原点偏移
一个最简单的URDF模型,至少需要一个根连杆和一个子连杆,中间用关节连接。我见过不少新手上来就写十几个连杆,结果调试时根本不知道哪里出了问题。我的建议是:从两个连杆开始,逐步增加。
3.2 从零编写一个两连杆机械臂
咱们直接上手写一个。假设我们要做一个简单的两连杆机械臂,基座固定,中间一个旋转关节,末端再连一个连杆。
<?xml version="1.0"?>
<robot name="two_link_arm">
<!-- 基座连杆 -->
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.1" radius="0.05"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0"/>
</visual>
</link>
<!-- 关节1:旋转关节 -->
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="link1"/>
<origin xyz="0 0 0.05" rpy="0 0 0"/>
<axis xyz="0 0 1"/>
<limit lower="-3.14" upper="3.14" effort="10" velocity="1"/>
</joint>
<!-- 连杆1 -->
<link name="link1">
<visual>
<geometry>
<box size="0.02 0.02 0.3"/>
</geometry>
<origin rpy="0 0 0" xyz="0 0 0.15"/>
</visual>
</link>
</robot>
这段代码里,base_link是一个圆柱体,link1是一个细长的长方体。关节joint1绕Z轴旋转,范围是-180°到180°。
3.3 坐标系:URDF的「隐形骨架」
URDF里每个连杆都有自己的坐标系。这个坐标系的原点在哪?方向怎么摆?全由<origin>标签决定。
我遇到过最坑的事:一个学生把origin的xyz写成了相对于父连杆的坐标,但rpy却忘了设置。结果机械臂在RViz里看起来是歪的。其实origin的rpy默认是0,但如果你不写,系统不会报错,只会默默给你一个「看起来不对」的模型。
记住一个原则:子连杆的坐标系原点,是相对于父连杆坐标系原点的偏移。关节的origin也是相对于父连杆的。
3.4 关节类型:选对才能动对
URDF支持六种关节类型,但常用的就三种:
| 类型 | 说明 | 典型用途 |
|---|---|---|
| revolute | 旋转关节,有限位 | 机械臂肩关节、肘关节 |
| continuous | 连续旋转,无限位 | 轮子、转台 |
| prismatic | 平移关节,有限位 | 伸缩臂、滑台 |
| fixed | 固定连接 | 传感器支架、末端工具 |
我个人的习惯是:能用fixed就别用revolute,能用revolute就别用continuous。关节类型越简单,运动学计算越稳定。曾经有个项目,为了省事把所有关节都设成continuous,结果逆解时角度飘到天上去,查了两天才发现是关节限位没设。
3.5 使用SolidWorks导出URDF的注意事项
手工写URDF适合简单模型。一旦机械臂超过3个关节,或者有复杂的曲面,我强烈建议用SolidWorks导出。
SolidWorks有个官方插件叫SW2URDF,可以自动生成URDF文件。但别以为一键导出就完事了,坑多着呢。
- 导出前没检查单位——SolidWorks默认是毫米,URDF要求米。导出后模型大1000倍,在RViz里根本看不到。
- 坐标系没对齐——SolidWorks里随便建个基准面,导出来关节轴方向全乱套。一定要在SolidWorks里把每个关节的坐标系对齐好。
- 惯性参数自动生成——插件会自动计算惯性矩阵,但如果你模型里有很多装饰性特征(比如螺丝孔、倒角),惯性参数会严重偏离实际。我建议导出后手动检查
<inertia>的值。
使用SW2URDF的正确流程:
- 在SolidWorks里把每个连杆单独建一个零件文件
- 装配体中,每个关节处建立一个坐标系,Z轴指向关节旋转方向
- 运行SW2URDF插件,按提示依次选择每个关节的坐标系
- 导出后,用
check_urdf命令验证模型完整性 - 在RViz中加载,手动旋转每个关节,确认运动方向正确
3.6 知识体系:URDF建模核心逻辑
下面这张图,是我自己总结的URDF建模流程。每次写新模型前,我都会按这个思路走一遍。
3.7 验证你的URDF模型
写完了别急着用,先跑一遍验证工具。ROS自带一个check_urdf命令,能帮你找出语法错误和结构问题。
# 检查URDF文件
check_urdf my_robot.urdf
# 如果一切正常,会输出类似:
# robot name is: two_link_arm
# ---------- Successfully Parsed XML ----------
# root link: base_link has 1 child(ren)
# child(1): link1
我每次写完URDF,都会在RViz里手动拖动每个关节,看看运动方向对不对。你想想看,如果关节转反了,后面做运动学规划全是错的。这一步省不得。