3、让机器人动起来:URDF模型导入、配置差速驱动插件、使用键盘控制小车

好,到了这一章,咱们终于要让机器人真正跑起来了。

前面几章我们把环境搭好,把模型建好,但说白了,那都是静态的。一个不会动的机器人,跟个雕塑没啥区别。我刚开始学Gazebo的时候,最兴奋的时刻就是第一次看到小车在仿真里动起来——虽然只是原地转了个圈,但那种成就感,嗯,至今还记得。

3.1 URDF模型导入Gazebo

URDF(Unified Robot Description Format)是ROS里描述机器人最常用的格式。它用XML写,定义了机器人的连杆、关节、外观和碰撞属性。

我个人习惯把URDF文件放在功能包的urdf/目录下。比如我们的小车,结构很简单:一个底盘、四个轮子。

核心要点:URDF里必须包含<gazebo>标签,否则Gazebo不认识你的模型。很多新手会漏掉这一步。

来看一个简化版的底盘URDF示例:

<robot name="my_car">
  <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>
  </link>

  <!-- 轮子部分省略 -->

  <gazebo>
    <plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
      ...
    </plugin>
  </gazebo>
</robot>

注意看,<collision>和<visual>我通常建议分开写。视觉可以花哨点,但碰撞体尽量用简单几何体——这能大幅提升仿真性能。我在项目里见过有人把碰撞体做得跟艺术品一样精细,结果仿真卡成PPT,何必呢?

3.2 配置差速驱动插件

差速驱动,说白了就是靠左右轮速度差来控制转向。你想想看,坦克、扫地机器人,都是这个原理。

Gazebo里实现差速驱动,靠的是插件机制。我们用的是libgazebo_ros_diff_drive.so这个插件。

配置参数有点多,我列个表方便你对照:

参数名 说明 我的建议值
left_joint 左轮旋转关节名称 left_wheel_joint
right_joint 右轮旋转关节名称 right_wheel_joint
wheel_separation 左右轮间距(米) 0.34
wheel_diameter 轮子直径(米) 0.1
command_topic 接收速度指令的话题 /cmd_vel
odometry_topic 发布里程计的话题 /odom

小技巧:wheel_separation这个值一定要量准。我曾经因为写错了一位小数,小车在仿真里一直画圈圈,查了半天才发现是轮距设窄了5毫米。

完整的插件配置大概长这样:

<gazebo>
  <plugin name="diff_drive_controller" filename="libgazebo_ros_diff_drive.so">
    <ros>
      <namespace>/my_car</namespace>
    </ros>
    <left_joint>left_wheel_joint</left_joint>
    <right_joint>right_wheel_joint</right_joint>
    <wheel_separation>0.34</wheel_separation>
    <wheel_diameter>0.1</wheel_diameter>
    <max_wheel_torque>20</max_wheel_torque>
    <max_wheel_acceleration>1.0</max_wheel_acceleration>
    <command_topic>/cmd_vel</command_topic>
    <odometry_topic>/odom</odometry_topic>
    <odometry_frame>odom</odometry_frame>
    <robot_base_frame>base_link</robot_base_frame>
  </plugin>
</gazebo>

这里有个坑:max_wheel_torque和max_wheel_acceleration别设太大。设太大,小车启动时会像被踹了一脚,直接飞出去。我刚开始就吃过这个亏,小车一启动就翻了个跟头,把我笑坏了。

3.3 使用键盘控制小车

插件配好了,怎么控制呢?最直接的方式就是用键盘。

ROS里有个现成的包叫teleop_twist_keyboard,装好就能用。

安装命令:

sudo apt install ros-noetic-teleop-twist-keyboard

启动方式:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

然后你就能在终端里看到提示:按i前进,,后退,j左转,l右转。按k停车。

注意:键盘控制节点默认发布到/cmd_vel话题。如果你的机器人命名空间不同,记得用__ns:=/my_car参数重映射。

为什么会这样?因为teleop_twist_keyboard默认话题是/cmd_vel,而我们的差速驱动插件监听的就是这个。只要话题对上,数据就能流通。

我个人习惯在启动时加上_speed:=0.5参数,把默认速度调低一点。0.5米/秒的速度,在仿真里既能看到效果,又不会失控。

3.4 本章知识体系

下面这张图,帮你理清整个流程:

让机器人动起来:核心流程 URDF模型导入 定义连杆、关节 视觉+碰撞属性 差速驱动插件 配置轮距/轮径 订阅/cmd_vel 键盘控制 teleop_twist_keyboard 发布速度指令 关键数据流: 键盘输入 → /cmd_vel话题 → 差速驱动插件 → 轮子关节速度 插件内部计算:左轮速度 = (v - w*L/2)/r,右轮速度 = (v + w*L/2)/r 其中 v 是线速度,w 是角速度,L 是轮距,r 是轮子半径 —— 理解了这个公式,你就掌握了差速驱动的灵魂

嗯,到这里,你的小车应该能在Gazebo里跑起来了。如果按下键盘没反应,别急,先检查三件事:

  1. URDF里的<gazebo>插件段有没有写对?
  2. 话题名是不是/cmd_vel?
  3. Gazebo仿真有没有暂停?按空格键可以切换暂停/运行。

避坑指南:我曾经在项目里遇到一个诡异问题——键盘控制没反应,但rostopic echo /cmd_vel能看到数据。查了两小时,发现是URDF里轮子的<joint>类型写成了fixed,轮子根本转不了。所以,<joint type="continuous">这个细节,千万别写错。

好了,去试试吧。看着自己写的小车在仿真里灵活穿梭,那种感觉,比打游戏通关还爽。

可可精品资料库