4、构建差速底盘:设计并搭建一个两轮差速机器人底盘模型

好,咱们进入正题。差速底盘,说白了就是靠两个轮子转速差来控制方向和速度。你想想看,坦克怎么转弯?一边履带停转,另一边转,车身就拐过去了。机器人差速底盘也是这个道理。

我个人习惯把底盘设计分成三块来考虑:机械结构、运动学模型、URDF建模。咱们一个一个来拆解。

4.1 差速底盘的运动学原理

先搞明白数学关系。差速底盘有两个驱动轮,通常还有一个万向轮做支撑。两个轮子独立驱动,通过转速差实现转向。

核心公式其实就两个:

v = (v_right + v_left) / 2
ω = (v_right - v_left) / d

其中:

  • v — 机器人线速度(m/s)
  • ω — 机器人角速度(rad/s)
  • v_left、v_right — 左右轮线速度
  • d — 左右轮间距(轮距)

嗯,这里要注意:轮距d是影响转弯半径的关键参数。我在项目中遇到过,有人把轮距量错了5毫米,结果机器人走直线都画弧线,排查了半天。

关键结论:

  • v_left = v_right → 直线前进/后退
  • v_left = -v_right → 原地旋转(零半径转弯)
  • v_left ≠ v_right → 弧线运动

4.2 设计底盘参数

咱们要搭一个教学用的差速底盘,参数我建议这样定:

参数 数值 说明
轮距 d 0.4 m 左右轮中心距离
车轮半径 r 0.1 m 驱动轮尺寸
车身长 0.5 m 底盘长度
车身宽 0.3 m 底盘宽度
离地间隙 0.05 m 底盘最低点距地面

为什么选这些值?说白了,0.4米的轮距在室内跑比较灵活,转弯半径小。0.1米的轮子大小适中,过门槛、过线缆都还行。

个人经验:轮距和轮径的比例最好在3:1到5:1之间。比例太小,机器人容易侧翻;比例太大,转弯笨重。我曾经做过一个比例2:1的底盘,一转弯就翘轮子,后来老老实实改回来了。

4.3 URDF模型搭建

好,理论讲完了,咱们动手写URDF。Gazebo里用URDF描述机器人,说白了就是一堆link和joint拼起来。

先看整体结构图:

差速底盘URDF结构图 base_link 车身底盘 left_wheel right_wheel caster_wheel left_joint right_joint caster_joint link(刚体) joint(关节)

结构很清晰:一个车身,两个驱动轮,一个万向轮。驱动轮用连续旋转关节,万向轮用固定关节。

4.4 编写URDF代码

来,直接上代码。我习惯把每个link和joint分开写,清晰好维护。

<?xml version="1.0"?>
<robot name="diff_drive_robot">

  <!-- 车身 -->
  <link name="base_link">
    <visual>
      <geometry>
        <box size="0.5 0.3 0.1"/>
      </geometry>
      <material name="blue">
        <color rgba="0.2 0.5 0.8 1.0"/>
      </material>
    </visual>
    <collision>
      <geometry>
        <box size="0.5 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.1" length="0.05"/>
      </geometry>
      <material name="black">
        <color rgba="0.2 0.2 0.2 1.0"/>
      </material>
    </visual>
    <collision>
      <geometry>
        <cylinder radius="0.1" length="0.05"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="0.5"/>
      <inertia ixx="0.001" ixy="0" ixz="0"
               iyy="0.001" iyz="0"
               izz="0.001"/>
    </inertial>
  </link>

  <!-- 左轮关节 -->
  <joint name="left_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="left_wheel"/>
    <origin xyz="-0.15 0.2 0" rpy="0 1.5708 0"/>
    <axis xyz="0 0 1"/>
  </joint>

  <!-- 右驱动轮 -->
  <link name="right_wheel">
    <visual>
      <geometry>
        <cylinder radius="0.1" length="0.05"/>
      </geometry>
      <material name="black">
        <color rgba="0.2 0.2 0.2 1.0"/>
      </material>
    </visual>
    <collision>
      <geometry>
        <cylinder radius="0.1" length="0.05"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="0.5"/>
      <inertia ixx="0.001" ixy="0" ixz="0"
               iyy="0.001" iyz="0"
               izz="0.001"/>
    </inertial>
  </link>

  <!-- 右轮关节 -->
  <joint name="right_wheel_joint" type="continuous">
    <parent link="base_link"/>
    <child link="right_wheel"/>
    <origin xyz="-0.15 -0.2 0" rpy="0 1.5708 0"/>
    <axis xyz="0 0 1"/>
  </joint>

  <!-- 万向轮 -->
  <link name="caster_wheel">
    <visual>
      <geometry>
        <sphere radius="0.03"/>
      </geometry>
      <material name="gray">
        <color rgba="0.5 0.5 0.5 1.0"/>
      </material>
    </visual>
    <collision>
      <geometry>
        <sphere radius="0.03"/>
      </geometry>
    </collision>
    <inertial>
      <mass value="0.1"/>
      <inertia ixx="0.0001" ixy="0" ixz="0"
               iyy="0.0001" iyz="0"
               izz="0.0001"/>
    </inertial>
  </link>

  <!-- 万向轮关节 -->
  <joint name="caster_wheel_joint" type="fixed">
    <parent link="base_link"/>
    <child link="caster_wheel"/>
    <origin xyz="0.2 0 -0.05" rpy="0 0 0"/>
  </joint>

</robot>

注意:origin中的xyz坐标是相对于父link的。左轮在y正方向,右轮在y负方向,这样才对称。我曾经见过有人把两个轮子放在同一侧,结果机器人原地打转——嗯,这种低级错误我也犯过。

4.5 几个关键细节

写URDF时,有几个坑我得提醒你:

  1. 轮子朝向:圆柱体默认轴是z轴,但轮子要绕y轴转。所以rpy里要旋转90度,把圆柱横过来。
  2. 碰撞模型:一定要加collision,不然Gazebo里没有物理碰撞,轮子会陷进地面。
  3. 惯性参数:别偷懒不写inertial。Gazebo没有惯性数据会报错,或者仿真跑起来怪怪的。
  4. 万向轮位置:放在车身前方或后方,离地间隙要略小于驱动轮,保证三点支撑稳定。

避坑指南:我曾经在项目里忘了给万向轮加碰撞模型,结果机器人一跑起来就翘头,像要翻跟头似的。排查了半天才发现是万向轮直接穿透了地面,没有支撑力。加上collision后,一切正常。

4.6 验证模型

写完后怎么验证?我一般三步走:

  1. 用check_urdf命令检查语法:check_urdf my_robot.urdf
  2. 用urdf_to_graphiz生成结构图,看看关节关系对不对
  3. 直接丢进Gazebo,看轮子是否着地,转动是否正常

嗯,到这里,一个完整的差速底盘模型就搭好了。你想想看,其实核心就三个部分:运动学公式、参数设计、URDF描述。搞懂了这些,后面加传感器、加控制器就水到渠成了。

可可精品资料库