第 6 章 Gazebo 仿真入门

学习目标

  • 理解 Gazebo 是什么、能仿真什么
  • 明白 SDF/URDF、物理引擎、传感器仿真的基本概念
  • 安装 Gazebo Harmonic 并启动一个空世界
  • 通过 ros_gz 桥接观察 ROS 与仿真之间的数据流动

1. Gazebo 是什么

Gazebo 是一个机器人仿真器:在虚拟世界里模拟机器人、环境和物理规律。与 turtlesim 这种“示意图”不同,Gazebo 会认真计算:

  • 物理引擎:重力、碰撞、摩擦力,机器人会真实地倒下、被撞开
  • 传感器仿真:激光雷达、相机、IMU 可以输出接近真实的数据
  • 机器人模型:从 URDF/SDF 描述的关节、连杆构成,关节可以驱动

在真机测试之前先在 Gazebo 里验证,成本低、零风险,是机器人开发的标配流程。

ROS 2 Jazzy 官方配套的是 Gazebo Harmonic(新版 Gazebo,旧版叫 Gazebo Classic,两者不兼容,本教程全部使用 Harmonic)。

2. 核心概念

概念 说明
世界(World) 仿真的整个场景,用 SDF 文件描述:地面、光照、物体、模型
模型(Model) 世界里的物体,可以是机器人、墙、桌子
SDF 描述场景和模型的 XML 格式,Gazebo 的原生格式
URDF 描述机器人结构的 XML 格式(连杆/关节),Gazebo 也能导入
实体(Entity) 世界中的每个物体(模型、灯光、传感器……)
插件/系统(System) 让模型“活”起来的功能模块,如驱动插件、传感器插件
仿真时间 仿真器自己的时钟,与真实时间不同步,由 /clock 话题发布

Gazebo 与 ROS 的关系

Gazebo 本身不依赖 ROS,两者通过 ros_gz 桥接连接:

┌───────────┐   话题/服务    ┌───────────┐
│  ROS 2    │◄──────────────►│  Gazebo   │
│  节点们    │   ros_gz_bridge │  仿真世界  │
└───────────┘                └───────────┘

例如:

  • 你的 ROS 节点向 /cmd_vel 发布速度 → 桥接转发 → Gazebo 里的机器人前进
  • Gazebo 里传感器生成激光数据 → 桥接转发 → ROS 里 /scan 话题收到数据

3. 安装 Gazebo Harmonic

在容器里安装(约 1 GB,耐心等待):

sudo apt update
sudo apt install -y ros-jazzy-ros-gz ros-jazzy-ros-gz-sim-demos

说明:

  • ros-jazzy-ros-gz:ros_gz 元包,包含桥接(ros_gz_bridge)、仿真启动器(ros_gz_sim)和 Gazebo Harmonic 本体
  • ros-jazzy-ros-gz-sim-demos:官方演示,下一章会用

验证安装:

ros2 pkg list | grep ros_gz

4. 启动空世界

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=empty.sdf

这条命令同时做了两件事:启动 Gazebo(空世界)和启动桥接所需的 ROS 节点。桌面上会出现 Gazebo 窗口,显示一个空荡荡的世界(淡蓝色背景)。

如果窗口黑屏或渲染异常,确认容器启动时带了 LIBGL_ALWAYS_SOFTWARE=1(见第 0 章)。窗口里的世界默认是暂停状态,点窗口底部中央的播放按钮开始仿真。

新开一个终端,查看现在有哪些话题:

docker exec -it ros2_learning bash
source /opt/ros/jazzy/setup.bash
ros2 topic list

你会看到 /clock/world/empty/dynamic_pose/info 等话题。其中:

  • /clock:仿真时钟。ros2 topic echo /clock 可以看到 clock.sec 不断增长
  • /world/empty/...:世界状态信息,例如所有实体的位姿

查看节点列表,可以看到 gz_servergz_client 等 ros_gz 启动的节点:

ros2 node list

5. 往世界里放东西

Gazebo 自带一些模型。创建自己的世界文件 ~/my_world.sdf

<?xml version="1.0"?>
<sdf version="1.11">
  <world name="my_world">
    <include>
      <uri>model://sun</uri>
    </include>
    <include>
      <uri>model://ground_plane</uri>
    </include>
  </world>
</sdf>

启动这个世界(首次会联网下载模型,耐心等待):

cd ~
ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=-r\ my_world.sdf

-r 表示启动后立刻运行(不暂停)。这次世界里有了地面和阳光,接下来就可以往里面放机器人了——这正是下一章的内容。

6. 无头模式(可选)

如果只是想跑仿真不想看窗口(例如服务器上),可以加 -s 无头运行:

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=-s\ empty.sdf

常见问题

现象 原因与解决办法
Gazebo 窗口黑屏/空白 确认 LIBGL_ALWAYS_SOFTWARE=1 已设置;VcXsrv 正常运行
package 'ros_gz_sim' not found 未安装 ros-jazzy-ros-gz,或新终端没 source(source /opt/ros/jazzy/setup.bash
模型下载失败 model:// 模型首次需要联网从 Gazebo 资源库下载;网络受限时可先改用 empty.sdf
世界静止不动 仿真处于暂停状态,点 Gazebo 窗口底部的播放按钮
gz: command not found Gazebo 本体未安装成功,重新执行安装命令

练习题

  1. ros2 topic echo /clock 观察仿真时钟,说说它和你电脑系统时间的关系。
  2. 在 Gazebo 窗口左侧的实体(Insert)面板中,从资源库里拖入一个模型到世界里,观察它的外观,并用 ros2 topic list 看看话题有什么变化。
  3. 尝试无头模式运行空世界,然后用 ros2 topic list 对比有窗口模式的差异。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐