第1章:机器人模型与URDF——统一机器人描述格式基础
大家好,我是你们的讲师。今天咱们来聊聊机器人建模这件事。
做机器人开发,第一步是什么?我个人觉得,不是写代码,不是调参数,而是先把你的机器人“描述清楚”。你想想看,如果你连自己的机器人长什么样、有几个关节、轮子多大都说不清楚,那后面的导航、避障、抓取,根本无从谈起。
URDF,全称是Unified Robot Description Format,翻译过来就是“统一机器人描述格式”。说白了,它就是一套用XML语言写的“机器人身份证”。
1.1 URDF到底能描述什么?
URDF能描述的东西,其实比你想象的多。我刚开始接触的时候,以为它就是个3D模型文件,后来才发现,它承载的信息远不止外观。
- 运动学结构:机器人由哪些刚体(link)组成,它们之间怎么连接(joint)
- 几何尺寸:每个部件的长宽高、半径、偏移量
- 惯性参数:质量、质心、转动惯量——这个在动力学仿真里特别重要
- 碰撞模型:用于碰撞检测的简化几何体,通常比视觉模型更粗糙
- 视觉模型:你在Rviz里看到的那个“好看”的机器人
核心要点:URDF本质上是一个树形结构。从“base_link”(基座)开始,通过关节连接各个连杆,形成一棵完整的运动学树。
1.2 底盘URDF建模——从轮子开始
咱们先拿一个差速底盘举例。我记得第一次给学生讲这个的时候,有人问:“老师,底盘不就是四个轮子加一个板子吗?”嗯,从外观上看确实是这样,但URDF里你得把每个部件拆开。
来看一个最简单的两轮差速底盘URDF片段:
<robot name="my_robot">
<!-- 底盘主体 -->
<link name="base_link">
<visual>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
<material name="blue">
<color rgba="0 0 1 1"/>
</material>
</visual>
<collision>
<geometry>
<box size="0.4 0.3 0.1"/>
</geometry>
</collision>
<inertial>
<mass value="2.0"/>
<inertia ixx="0.01" ixy="0" ixz="0"
iyy="0.01" iyz="0"
izz="0.02"/>
</inertial>
</link>
<!-- 左轮 -->
<link name="left_wheel">
<visual>
<geometry>
<cylinder radius="0.05" length="0.04"/>
</geometry>
<material name="gray"/>
</visual>
</link>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="-0.15 0.15 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</robot>
这里有几个坑,我当年踩过:
- 关节类型别搞错:轮子用
continuous(连续旋转关节),机械臂关节用revolute(有限角度旋转),别混用 - 坐标系方向:
axis xyz="0 1 0"表示绕Y轴旋转,这个得跟你的实际电机安装方向一致 - 碰撞模型别太精细:我曾经把一个机械臂的碰撞模型做得跟视觉模型一样精细,结果碰撞检测慢得要命。后来学乖了,碰撞模型用圆柱体或长方体代替
我的小技巧:写URDF的时候,先用简单的几何体(box、cylinder、sphere)把机器人搭出来,确认运动学没问题了,再替换成复杂的mesh文件。这样调试效率高很多。
1.3 机械臂URDF建模——关节与连杆的“父子关系”
机械臂的URDF,说白了就是一堆连杆和关节串在一起。我习惯从基座开始,一层一层往上写。
来看一个6轴机械臂的关节定义示例:
<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="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>
<joint name="joint2" type="revolute">
<parent link="link1"/>
<child link="link2"/>
<origin xyz="0 0 0.3" rpy="0 1.57 0"/>
<axis xyz="0 1 0"/>
<limit lower="-2.09" upper="2.09" effort="8" velocity="1.0"/>
</joint>
这里要注意几个点:
origin里的rpy(翻滚角、俯仰角、偏航角)定义了子连杆相对于父连杆的旋转偏移。joint2的rpy="0 1.57 0"表示绕Y轴转了90度,这样第二个关节的轴线就变成水平方向了limit里的lower和upper是关节限位,单位是弧度。我见过有人把限位设成-180 180,结果单位搞错了,应该是-3.14 3.14
曾经踩过的坑:有一次我写机械臂URDF,忘了给关节加limit标签,结果仿真的时候机械臂直接“飞”起来了——关节没有限位,电机一直转。从那以后,我每个关节都会仔细检查限位参数。
1.4 在Rviz2中可视化——验证你的模型
URDF写完了,怎么知道对不对?Rviz2就是最好的验证工具。
启动步骤很简单:
# 安装必要工具
sudo apt install ros-humble-urdf-tutorial
# 启动Rviz2并加载URDF
ros2 launch urdf_tutorial display.launch.py model:=/path/to/your_robot.urdf
在Rviz2里,你可以:
- 用RobotModel插件显示机器人模型
- 用TF插件查看坐标系变换
- 用JointStatePublisher手动拖动关节,看看运动学对不对
我个人习惯,每次修改URDF后,都会在Rviz2里转一圈。看看关节方向对不对,连杆位置有没有偏移。这比直接跑导航程序再发现问题,效率高太多了。
1.5 本章知识体系总览
下面这张图,是我自己总结的URDF知识结构。你可以把它当成一个“检查清单”,写URDF的时候对照着看,不容易漏东西。
这张图把URDF的核心要素都串起来了。你写模型的时候,就照着这个结构来,基本不会出错。
1.6 一些实用建议
最后,分享几个我这些年积累的经验:
- 命名规范很重要:link和joint的名字要有意义,别用
link1、link2这种。我习惯用base_link、shoulder_link、elbow_link这种,一看就知道是哪个部件 - 单位统一:URDF里长度单位是米,角度单位是弧度。别混用,否则模型会变形
- 版本控制:URDF文件建议用Git管理。我每次修改都会commit一次,方便回溯
- 从简单到复杂:先写底盘,验证通过后再加机械臂。别一口气写完整个机器人,出了问题很难排查
一个小工具推荐:check_urdf命令可以帮你检查URDF语法错误。我每次写完都会跑一遍,能省不少调试时间。
好了,这一章的内容就到这里。URDF是机器人开发的基础,看似简单,但细节很多。你动手写一遍,遇到问题再回来翻翻,慢慢就熟练了。
可可精品资料库