4. Gazebo基础操作:世界文件、模型加载与仿真控制

Gazebo 仿真器,说白了就是一个“虚拟实验室”。你不需要买昂贵的机器人硬件,也不用担心撞坏墙壁。但很多人一上来就拖模型、点按钮,结果仿真跑起来乱七八糟。嗯,这章我们就从最基础的世界文件讲起,把地基打牢。

4.1 世界文件(.world)的结构

世界文件是 Gazebo 的“剧本”。它告诉仿真器:场景里有什么、光照怎么打、物理引擎用哪套。我个人习惯把 .world 文件看作一个 XML 格式的配置文件,核心结构如下:

<?xml version="1.0" ?>
<sdf version="1.6">
  <world name="my_world">
    <!-- 光照设置 -->
    <include>
      <uri>model://sun</uri>
    </include>

    <!-- 地面 -->
    <include>
      <uri>model://ground_plane</uri>
    </include>

    <!-- 物理引擎参数 -->
    <physics type="ode">
      <real_time_update_rate>1000</real_time_update_rate>
      <max_step_size>0.001</max_step_size>
    </physics>

    <!-- 加载机器人模型 -->
    <include>
      <uri>model://my_robot</uri>
      <pose>0 0 0.1 0 0 0</pose>
    </include>
  </world>
</sdf>

这里有几个关键点:

  • <world>:根标签,name 属性唯一标识这个场景。
  • <include>:引用模型库里的模型,比如 sun、ground_plane。
  • <physics>:物理引擎配置。type 可以是 ode、bullet、simbody。我一般用 ode,稳定。
  • <pose>:模型初始位置和姿态,格式是 x y z roll pitch yaw。
小技巧: 如果你想让地面带点纹理,可以在 ground_plane 的 model.config 里修改。不过大多数时候默认就够用了。

4.2 模型加载的两种方式

加载模型有两种路子:一种是从 Gazebo 模型库拉,另一种是自己写 SDF 文件。我刚开始学的时候,总想自己手写模型,结果折腾半天还不如直接用现成的。

4.2.1 从模型库加载

Gazebo 自带一个在线模型库,里面有很多常见物体。你只需要在 .world 文件里写:

<include>
  <uri>model://cafe_table</uri>
  <pose>1.0 0.5 0.0 0 0 0</pose>
</include>

第一次运行时会自动下载。不过网络不好的话,可能会卡住。我曾经在客户现场演示时,就因为网络问题等了五分钟……嗯,后来我学乖了,提前把常用模型缓存到本地。

4.2.2 自定义 SDF 模型

如果你需要特殊形状的物体,比如一个带传感器的支架,那就得自己写 SDF 了。举个例子:

<model name="my_sensor_mount">
  <static>true</static>
  <link name="base">
    <collision name="collision">
      <geometry>
        <box>
          <size>0.2 0.2 0.5</size>
        </box>
      </geometry>
    </collision>
    <visual name="visual">
      <geometry>
        <box>
          <size>0.2 0.2 0.5</size>
        </box>
      </geometry>
    </visual>
  </link>
</model>

注意 <static>true</static> 表示这个物体是固定的,不会被物理引擎推动。做环境障碍物时常用。

4.3 GUI 界面使用

Gazebo 的 GUI 界面其实挺直观的。左边是模型列表,中间是 3D 视图,下面是时间控制条。但有几个隐藏功能你可能不知道:

  • 右键拖拽:旋转视角。中键滚轮缩放。
  • Shift + 左键:选中模型后可以拖拽移动。
  • Ctrl + R:重置仿真。
  • 左侧面板的“World”选项卡:可以实时修改重力、风速等参数。
避坑指南: 我曾经在调试时,不小心把重力改成了 0,结果所有模型都飘起来了……找了半天才发现是 GUI 里误操作。所以,重要参数最好在 .world 文件里写死,别在 GUI 里乱改。

4.4 仿真时间控制

仿真时间控制是很多人容易忽略的点。Gazebo 有两种时间模式:

模式 说明 适用场景
实时模式(Real Time) 仿真时间与真实时间同步 与真实硬件联调
非实时模式(Non-Real Time) 仿真时间可以比真实时间快或慢 批量测试、加速仿真

在 GUI 底部的时间控制条上,你可以看到三个数字:

  • Real Time:实际经过的时间。
  • Sim Time:仿真世界里的时间。
  • Factor:Sim Time / Real Time 的比值。如果 Factor 小于 1,说明仿真跑得比真实世界慢。

为什么会这样?因为物理计算太复杂,CPU 跟不上。我遇到过一种情况:机器人明明走了 10 秒,但仿真时间只过了 3 秒。这时候 ROS 里的定时器就会出问题。解决办法是降低物理更新频率,或者简化模型。

注意: 如果你用 ROS 2 的 /clock 话题同步时间,一定要确保 Gazebo 的仿真时间发布正确。否则控制算法会乱套。

4.5 本章知识体系

下面这张图帮你理清本章的核心逻辑:

Gazebo 基础操作 世界文件 (.world) 光照 & 地面 物理引擎配置 模型加载 模型库加载 自定义 SDF GUI 界面操作 视角控制 模型拖拽 仿真时间控制 实时模式 非实时模式

这张图把本章四个核心模块串起来了。世界文件是基础,模型加载是内容,GUI 是交互方式,时间控制是运行保障。你想想看,这四个点搞明白了,Gazebo 的基本操作也就拿下了。

总结一下: 世界文件是仿真的“剧本”,模型加载是“演员”,GUI 是“导演监视器”,时间控制是“播放速度”。把这四样玩转,你就能在 Gazebo 里搭建出任何想要的仿真场景。