第2章:机器人模型URDF基础:编写简单的差速驱动机器人URDF模型

做机器人仿真,第一步就是得有个“身体”。

URDF,全称是Unified Robot Description Format。说白了,就是用一个XML文件,把你的机器人长什么样、关节怎么动、传感器装在哪,统统告诉Gazebo。我个人习惯,每次新建项目,第一件事就是把这个骨架搭好。

核心知识点:URDF由(刚体部件)和(连接关系)组成。一个差速驱动底盘,至少需要:底盘、左轮、右轮、一个转向架(caster wheel),再加一个激光雷达。

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差速底盘结构。你看一眼,心里就有谱了。

差速驱动机器人URDF结构图 base_link (底盘) 圆柱体 半径0.20m 高0.15m left_wheel 连续旋转关节 right_wheel 连续旋转关节 caster_wheel 固定关节 laser_link 固定关节 连续关节 连续关节 固定关节

2.6 完整模型整合

把上面所有部件拼在一起,就是一个完整的URDF文件。我习惯把每个link和joint按顺序写,底盘在最上面,然后是轮子、万向轮、传感器。这样结构清晰,后期改参数也方便。

避坑指南:我曾经把轮子的origin坐标算反了,结果左轮和右轮位置互换,机器人一启动就原地转圈。检查了半小时才发现是Y轴符号写反了。所以,写坐标时一定要画个草图,确认正方向。

差速驱动模型的关键参数就三个:轮距(左右轮间距)、轮径、底盘离地高度。这三个值决定了机器人的运动学特性。轮距越大,转向越稳但越迟钝;轮径越大,速度越快但扭矩越小。具体怎么选,得看你实际的应用场景。

好了,模型写好了。下一步就是把它丢进Gazebo里,看看能不能动起来。

可可精品资料库