第2章:机器人模型URDF基础:编写简单的差速驱动机器人URDF模型
做机器人仿真,第一步就是得有个“身体”。
URDF,全称是Unified Robot Description Format。说白了,就是用一个XML文件,把你的机器人长什么样、关节怎么动、传感器装在哪,统统告诉Gazebo。我个人习惯,每次新建项目,第一件事就是把这个骨架搭好。
核心知识点:URDF由(刚体部件)和
2.1 底盘:机器人的“腰”
底盘是整个机器人的基座。所有东西都长在它上面。
我一般用一个扁圆柱体来表示底盘。为什么是圆柱?因为仿真里碰撞检测简单,而且差速转向时不容易卡住。你想想看,方形的底盘在转弯时,边角很容易和障碍物“打架”。
<link name="base_link">
<visual>
<geometry>
<cylinder length="0.15" radius="0.20"/>
</geometry>
<material name="blue">
<color rgba="0.2 0.2 0.8 1.0"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.15" radius="0.20"/>
</geometry>
</collision>
<inertial>
<mass value="2.0"/>
<inertia ixx="0.01" ixy="0.0" ixz="0.0"
iyy="0.01" iyz="0.0"
izz="0.02"/>
</inertial>
</link>
我的小技巧:惯性矩阵(inertia)很多人随便填。我在项目中吃过亏——填太小,机器人一加速就翻;填太大,转向反应迟钝。对于0.2m半径、2kg的底盘,ixx和iyy给0.01,izz给0.02,基本够用。
2.2 轮子:驱动力的来源
差速驱动,顾名思义,左右轮独立驱动。转向靠速度差。
轮子需要两个:左轮和右轮。它们通过旋转关节(continuous joint)连到底盘上。注意,轮子的位置要对称,否则机器人会跑偏。
<link name="left_wheel">
<visual>
<geometry>
<cylinder length="0.04" radius="0.05"/>
</geometry>
<material name="black">
<color rgba="0.1 0.1 0.1 1.0"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.04" radius="0.05"/>
</geometry>
</collision>
<inertial>
<mass value="0.2"/>
<inertia ixx="0.0001" ixy="0.0" ixz="0.0"
iyy="0.0001" iyz="0.0"
izz="0.0002"/>
</inertial>
</link>
<joint name="left_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="left_wheel"/>
<origin xyz="-0.10 0.15 -0.05" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
这里有个坑:axis xyz="0 1 0"表示轮子绕Y轴旋转。为什么?因为轮子立起来时,它的圆柱轴线是Y方向。我曾经把轴线设成X轴,结果轮子在地上“横着滚”,那画面……嗯,不提了。
2.3 万向轮:防止“狗啃泥”
差速底盘只有两个驱动轮,不稳定的。必须加一个或两个万向轮(caster wheel)做支撑。
万向轮用固定关节(fixed joint)连到底盘上,不需要旋转。它就是个“小跟班”,跟着底盘到处跑。
<link name="caster_wheel">
<visual>
<geometry>
<sphere radius="0.02"/>
</geometry>
<material name="grey">
<color rgba="0.5 0.5 0.5 1.0"/>
</material>
</visual>
<collision>
<geometry>
<sphere radius="0.02"/>
</geometry>
</collision>
</link>
<joint name="caster_joint" type="fixed">
<parent link="base_link"/>
<child link="caster_wheel"/>
<origin xyz="0.15 0.0 -0.07" rpy="0 0 0"/>
</joint>
注意:万向轮的位置要放在底盘前方或后方,不能和驱动轮在同一横截面上。否则机器人会像跷跷板一样前后摇晃。我刚开始做时,把万向轮放在两个驱动轮中间,结果仿真一开始就“点头”,调试了半天才发现是重心问题。
2.4 激光雷达:机器人的“眼睛”
避障靠什么?激光雷达。在URDF里,它就是一个传感器link,装在底盘顶部。
我习惯用圆柱体表示雷达的外壳,然后通过Gazebo插件给它加上激光扫描功能。这里先只做外观模型。
<link name="laser_link">
<visual>
<geometry>
<cylinder length="0.03" radius="0.04"/>
</geometry>
<material name="red">
<color rgba="0.8 0.2 0.2 1.0"/>
</material>
</visual>
<collision>
<geometry>
<cylinder length="0.03" radius="0.04"/>
</geometry>
</collision>
</link>
<joint name="laser_joint" type="fixed">
<parent link="base_link"/>
<child link="laser_link"/>
<origin xyz="0.0 0.0 0.10" rpy="0 0 0"/>
</joint>
雷达装在底盘正上方,高度0.1米。这样它就能360度扫描周围环境,没有遮挡。
2.5 知识体系总览
下面这张图,是我自己总结的URDF差速底盘结构。你看一眼,心里就有谱了。
2.6 完整模型整合
把上面所有部件拼在一起,就是一个完整的URDF文件。我习惯把每个link和joint按顺序写,底盘在最上面,然后是轮子、万向轮、传感器。这样结构清晰,后期改参数也方便。
避坑指南:我曾经把轮子的origin坐标算反了,结果左轮和右轮位置互换,机器人一启动就原地转圈。检查了半小时才发现是Y轴符号写反了。所以,写坐标时一定要画个草图,确认正方向。
差速驱动模型的关键参数就三个:轮距(左右轮间距)、轮径、底盘离地高度。这三个值决定了机器人的运动学特性。轮距越大,转向越稳但越迟钝;轮径越大,速度越快但扭矩越小。具体怎么选,得看你实际的应用场景。
好了,模型写好了。下一步就是把它丢进Gazebo里,看看能不能动起来。