第 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,耐心等待):
sudoaptupdatesudoaptinstall-yros-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|grepros_gz4. 启动空世界
ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=empty.sdf这条命令同时做了两件事:启动 Gazebo(空世界)和启动桥接所需的 ROS 节点。桌面上会出现 Gazebo 窗口,显示一个空荡荡的世界(淡蓝色背景)。
如果窗口黑屏或渲染异常,确认容器启动时带了
LIBGL_ALWAYS_SOFTWARE=1(见第 0 章)。窗口里的世界默认是暂停状态,点窗口底部中央的播放按钮开始仿真。
新开一个终端,查看现在有哪些话题:
dockerexec-itros2_learningbashsource/opt/ros/jazzy/setup.bash ros2 topic list你会看到/clock、/world/empty/dynamic_pose/info等话题。其中:
/clock:仿真时钟。ros2 topic echo /clock可以看到clock.sec不断增长/world/empty/...:世界状态信息,例如所有实体的位姿
查看节点列表,可以看到gz_server、gz_client等 ros_gz 启动的节点:
ros2nodelist5. 往世界里放东西
Gazebo 自带一些模型。创建自己的世界文件~/my_world.sdf:
<?xml version="1.0"?><sdfversion="1.11"><worldname="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 本体未安装成功,重新执行安装命令 |
练习题
- 用
ros2 topic echo /clock观察仿真时钟,说说它和你电脑系统时间的关系。 - 在 Gazebo 窗口左侧的实体(Insert)面板中,从资源库里拖入一个模型到世界里,观察它的外观,并用
ros2 topic list看看话题有什么变化。 - 尝试无头模式运行空世界,然后用
ros2 topic list对比有窗口模式的差异。