本节摘要:Gazebo 二十多年稳定可依赖的设计承诺有三条:物理引擎可替换(抽象层隔离)、一切交互走消息与插件(不锁死单一框架)、仿真与实机共用同一套控制代码(连续体契约)。理解这三条,就能预判哪些需求"架构天然支持"、哪些是"逆着架构游泳"。
1.2 节的断代史容易给人"什么都会变"的印象。但有几条设计决策从 Classic 到 gz-sim 基本没动摇过,它们才是使用者的长期资产:
承诺一:物理引擎是插件,不是地基。 ODE、Bullet、DART、Simbody 通过统一的 Physics 抽象接入,SDF 里一行切换:
<physics name="dart_physics" type="dart"> <max_step_size>0.001</max_step_size> </physics>
含义:你的世界文件不绑死任何一个求解器。ODE 老而稳、DART 对关节链精度更好、Bullet 处理大量碰撞体有优势——切换成本是一个字符串,而不是重写模型。第 3 章 3.1 会拆这个抽象层的内部结构。
承诺二:组件之间只通过消息和插件对话。 gz-sim 里物理、渲染、传感器、用户控制流是独立的系统,靠 gz-transport 主题交换数据。这带来一个直接推论:你写的控制节点不需要链接 Gazebo 的任何库,只要订阅 /clock、发布速度指令就能开车。ROS 集成靠桥(ros_gz_bridge)而不是靠植入,就是这个哲学的体现。
承诺三:仿真-实机连续体。 同一个 ros2_control 控制器配置,hardware_interface 一端指向 gz-sim-system 插件就是仿真,指向真实串口就是实机。控制器代码零改动。这条契约的成立条件是:延迟、带宽、噪声这些"实机税"必须在仿真侧被显式建模——否则连续体名存实亡(第 5 章 5.3 专门对这笔账)。

这套分层不是装饰,它直接回答日常选型问题:
<physics type="dart">。这是承诺一兑现的场景。💡 关键直觉:判断一个 Gazebo 需求是否"顺架构",看它落在分层的哪一层、那一层的承诺是否覆盖它。覆盖则成本低到一行配置;不覆盖则任何 hack 都是在为下次重构埋雷。
某团队为了图省事,在 Classic 里直接调用 Gazebo 内部 C++ API 读取物理引擎的碰撞明细(绕过消息接口)。三年后迁移 gz-sim,这部分代码全部作废——因为内部 API 恰恰是分层契约明确"不承诺稳定"的部分。重写花了两个月。教训:契约边界内的慢是假慢,契约边界外的快是假快。
连续体契约最有说服力的证据是可以贴出来的配置差异——一个差速底盘的 ros2_control 文件,切到仿真与切到实机各自只动"硬件插件"一处,控制器参数、单位、关节名分毫不动:
<!-- 仿真侧:硬件接口指向 gz-sim 提供的仿真系统插件 --> <hardware> <plugin>gz_ros2_control/GazeboSimSystem</plugin> </hardware> <joint name="left_wheel_joint"> <command_interface name="velocity"/> <state_interface name="velocity"/> <state_interface name="position"/> </joint>
<!-- 实机侧:只换插件名与串口参数,控制器代码与 URDF 完全不变 --> <hardware> <plugin>diffdrive_hardware/DiffDriveHardware</plugin> <param name="serial_port">/dev/ttyUSB0</param> <param name="baud_rate">115200</param> </hardware> <joint name="left_wheel_joint"> <command_interface name="velocity"/> <state_interface name="velocity"/> <state_interface name="position"/> </joint>
两段配置的关节声明逐行相同,这正是"连续体"三个字的含金量:上层控制器在仿真里收敛出的增益,拿到实机上至少是一个合法的初值,而不是从零重调。工程上把这个差异管理成一条 CI 流水线——同一份控制器配置在仿真世界跑回归、在硬件在环(HIL)台架跑冒烟,两个环境共用同一份参数文件与测试用例。连续体契约的真正收益不是"少写代码",而是让虚实两侧的测试资产可以互相继承:仿真里积累的边界用例直接成为实机验收清单的第一稿,反之实机上暴露的问题(如执行器死区)可以回到仿真里复现成固定的回归场景。
<physics type> 能解决的事别写两千行 hack;引擎层没有的账(流体、柔性),用联合仿真补,别硬等。第 1 章到此收束。第 2 章进入机器内部:一帧仿真从物理步进到传感器更新,各系统如何在同一个仿真时钟下排队对齐——那是排障时最值钱的一章。