本节摘要:Gazebo 从 2002 年南加州大学的 Player 项目起步,经历 Gazebo Classic 十一年长青、2018 年断代重构为 Ignition、2022 年更名回 Gazebo(gz-sim)三次大转弯。每次重构都在还一类旧账:渲染架构债、进程隔离债、命名混乱债。本节给出时间线、版本对照表与 2026 年的选型决策要点。
Gazebo 的历史不是平滑升级,而是三次"推倒重来"。理解这一点很重要:网上大量教程、问答、代码片段混杂着三个不兼容时代的写法,初学者最大的时间黑洞不是学不会,而是把 Classic 的答案抄进 gz-sim 的工程里。

三个时代各自的核心特征:
gazebo_ros 插件生态爆发,DARPA Robotics Challenge 让它成为行业标准。代价是渲染用 OGRE1、仿真服务器单进程大杂烩,云端无头部署与多仿真并行越来越吃力。| 维度 | Gazebo Classic 11 | Ignition Fortress | gz-sim Harmonic/Ionic |
|---|---|---|---|
| 推荐搭配 | ROS 1 Noetic / ROS 2 Galactic 前 | ROS 2 Humble | ROS 2 Humble/Jazzy 起 |
| 渲染 | OGRE 1.x | ogre1 / ogre2 可选 | ogre2 为主 |
| 通信 | gazebo_ros 插件内嵌 | gz-transport + ros_gz_bridge | 同左,生态更全 |
| 多物理引擎 | ODE/Bullet/DART/Simbody | 同左(插件式) | 同左 |
| 维护状态 | 2025-01 EOL | 过渡版 | 当前主线 |
⚠️ 常见坑:搜索"gz gazebo tutorial"得到的答案可能横跨三个时代。判断技巧:命令以
gz开头且世界文件用<plugin filename="gz-sim-..."的是新架构;命令gazebo+gazebo_ros插件是 Classic;出现<sdf version="1.6">多半是 Classic 时代文件,新架构建议升到 1.9+。
Classic 的债具体在哪?一个例子:GUI、物理、脚本在同一个进程里跑,GUI 掉帧会拖慢物理步进;云端 CI 想跑无头仿真,还得装一整套 X11 依赖。Ignition 的解法是进程级隔离——仿真服务器(gz sim -s)与图形客户端(gz sim -g)分离,渲染只在需要传感器的服务器上按需加载(详见第 2 章 2.1)。这不是功能升级,而是架构层的还债,代价是 API 全面不兼容、社区内容断层——这也是为什么迁移期的学习成本特别高。
断代最疼的地方是"同一个差速控制器,两个时代写法完全不同"。对照着看一遍迁移量最小的真实案例——给世界注入一个自定义地面摩擦补丁。Classic 时代用 ROS 服务调物理引擎参数,新架构用 gz-transport 话题直接改世界:
<!-- Classic 时代:靠 gazebo_ros 插件搭桥,插件名与库绑定 --> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <updateRate>30</updateRate> <leftJoint>left_wheel_joint</leftJoint> <rightJoint>right_wheel_joint</rightJoint> <wheelSeparation>0.34</wheelSeparation> <wheelDiameter>0.30</wheelDiameter> </plugin>
<!-- 新架构:gz-sim 系统插件,参数名与单位有差异,行为等价 --> <plugin filename="gz-sim-diff-drive-system" name="gz::sim::systems::DiffDrive"> <left_joint>left_wheel_joint</left_joint> <right_joint>right_wheel_joint</right_joint> <wheel_separation>0.34</wheel_separation> <wheel_radius>0.15</wheel_radius> <odom_publish_frequency>30</odom_publish_frequency> </plugin>
两个片段的差异浓缩了整个断代史:插件文件名从 libgazebo_ros_* 变成 gz-sim-*-system,参数从驼峰改蛇形,轮直径换成了轮半径——最后这项最容易漏改,迁移后的机器人速度会整整差一倍。下面这段脚本用来在存量工程里批量定位所有待迁移点:
# 统计仓库里的 Classic 指纹:旧插件、旧命令、旧 SDF 版本 grep -rEo "libgazebo_ros[a-z_]*\.so" models worlds | sort | uniq -c grep -rE "gazebo_ros(_pkgs|_plugins)" launch package.xml | wc -l grep -rl 'sdf version="1\.[0-6]"' . | wc -l # 需要升级的低版本 SDF 文件数
三项输出构成迁移工作量清单:第一行给出要替换的插件种类数,第二行给出依赖清单改动范围,第三行数出需要过一遍 SDF 升级校验的文件。一个中型机器人仓库的典型读数是十几种插件、两处依赖、上百个 SDF 文件——据此排一个两周的迁移窗口比凭感觉估"大概几天"靠谱得多。这也是版本史的现实价值:历史不是背景知识,是迁移预算的计算依据。
下一节回答:贯穿这些版本变化、始终没变的设计哲学是什么——它决定了你能在 Gazebo 身上依赖哪些长期承诺。