gazebo
The sim half of the robium nav-vertical trial run: modern Gazebo (the gz
tools — Gazebo Classic/gazebo11 is a separate, EOL project and out of scope
everywhere in this skill) for building SDF worlds and models, attaching
sensors, bridging topics to ROS 2 via ros_gz, spawning robots, and running
headless. As of this session, Gazebo's current named releases are Jetty
(LTS, Sep 2025 – May 2031), Ionic (standard support, Sep 2024 – Dec 2026),
and Harmonic (LTS, Sep 2023 – May 2029) — verified by direct curl of
gazebosim.org/docs/all/releases/ this session, which also lists the older
Fortress LTS (Sep 2021 – May 2027) still inside its support window. Jetty is
now the newest LTS, one release past the Harmonic/Ionic line named in this
skill's description; re-verify the release list before trusting any of this
paragraph in a future session; see references/worlds-and-models.md's
sourcing note. The robium nav vertical (nav2 skill) targets ROS 2 Jazzy
Jalisco, whose paired Gazebo release is Harmonic — the ros_gz
jazzy branch ships prebuilt binaries for that pairing from
packages.ros.org, confirmed by direct fetch of the ros_gz README this
session (see References). This skill's nav-facing snippets and examples
target Jazzy + Harmonic for that reason; Ionic (paired with Kilted) is
nearing its Dec 2026 EOL, and Jetty (the newest LTS) pairs with Lyrical or
Rolling, not Jazzy — don't pick either for a new Jazzy-based project without
re-checking the table first.
When to use this skill
- Building or editing an SDF world or model, adding a sensor (lidar, camera,
IMU, contact) to a robot, wiring a
ros_gz bridge, spawning a robot into a
running simulation, or running Gazebo headless/server-only.
- The trigger phrases in the description: 'gazebo', 'gz sim', 'ros_gz',
'simulate the robot', 'add a lidar to the sim'.
- Someone mentions Gazebo Classic tutorials,
gazebo11, or the old
libgazebo_ros_* plugin names — flag that they don't apply here (Classic
is EOL) and redirect to this skill's modern gz/ros_gz equivalents.
- Cross-references — go to the sibling skill instead when the question is:
- Which simulator to use at all (Gazebo vs. Isaac Sim vs. something
else) → the
simulation skill. This skill assumes Gazebo has
already been chosen.
- Generic ROS 2 mechanics the bridge or a spawned robot's launch file rides
on (workspaces, colcon, launch files, TF2 concepts, QoS) →
ros2. This
skill's only TF content is what the ros_gz bridge or a sim plugin
itself publishes.
- Navigation behavior once sensor data is flowing (costmaps, AMCL,
behavior trees) →
nav2. This skill stops at "sensor topics are bridged
and correctly framed"; what Nav2 does with them is nav2's territory.
- Isaac Sim specifically →
isaac-sim.
- Running
gz/ros_gz inside Docker, GPU passthrough for the container,
or macOS/remote-server environment strategy → environments. This
skill's Platform gotchas section only notes where Docker changes gz's own
behavior (rendering, display), not how to set the container up.
- The whole-stack decision this feeds into →
architect (routes here).
Key directives
- Delegation posture: embed + links. SDF anatomy, sensor tags, and the
ros_gz bridge's CLI/YAML syntax live in this skill's references in depth
— no single upstream page walks through all three as one coherent unit for
a new project — but every tag, default value, and parameter table links
back to gazebosim.org, the sdformat spec, or the gazebosim/ros_gz
GitHub repo rather than being retyped from memory. See References.
- Never recommend Gazebo Classic (
gazebo11). It reached end-of-life;
its plugin names (libgazebo_ros_*), world format quirks, and tutorials do
not carry over to modern gz. If a search result or an old tutorial
mentions Classic, say so explicitly and translate to the modern
equivalent rather than silently using Classic syntax.
- Bridge every topic explicitly, via a config file, not ad-hoc CLI
bridges. A one-off
ros2 run ros_gz_bridge parameter_bridge /topic@ros_type@gz_type per topic is fine for a five-minute test, but a
real project's bridge set (clock, cmd_vel, odom, tf, every sensor) belongs
in one YAML config file passed via the config_file parameter — it's the
single reviewable place that states exactly what's bridged, in which
direction, and at what QoS, and it survives a robot rename without hunting
down scattered ros2 run invocations. See
examples/ros-gz-bridge-config.yaml and
references/ros2-bridge.md.
- Sensor rates and frames must match the real target robot, not simulator
defaults. A lidar simulated at the tutorial's default rate/FOV, or a
camera with the wrong resolution, produces a stack that "works in sim" and
then behaves differently the moment it meets real sensor data or a
downstream consumer (Nav2's costmap update rate, a perception model's
expected input size) tuned for the real hardware's datasheet. Pull the
real sensor's rate/FOV/range/frame from its datasheet before simulating it
— this is the
simulation skill's correctness-checklist territory;
this skill only supplies the SDF tags to encode whatever numbers
that check produces.
- Never write gz release numbers, EOL dates, or ROS 2/Gazebo pairings from
memory. They change with every named release (Jetty's arrival moved
Harmonic and Ionic down a rung since this skill's description was
written). Verify against
gazebosim.org/docs/all/releases/ and the
gazebosim/ros_gz README's compatibility table before repeating a claim
in a real project — every example in this skill is marked status: unverified for exactly this reason, and each reference states how its
claims were checked this session.
Quick start
1. Confirm the gz release paired with your ROS 2 distro. Check the
compatibility table in references/ros2-bridge.md (sourced from the
gazebosim/ros_gz README) before installing anything — for the Jazzy-based
nav vertical this skill targets, that's Gazebo Harmonic:
sudo apt-get install ros-jazzy-ros-gz
2. Write or copy a world. Start from
examples/diffdrive-world-snippet.sdf (a minimal differential-drive robot
with lidar and IMU sensors) and see references/worlds-and-models.md for
SDF anatomy.
3. Run it headless and bridge topics. See the two usage patterns below —
"Run a world headless" and "Bridge sensor topics to ROS 2" — using
examples/ros-gz-bridge-config.yaml as the bridge's config_file.
4. Verify data is flowing with ros2 topic echo /scan (or /imu,
/odom) before wiring anything downstream (Nav2, a perception node) to it.
Usage patterns
Run a world headless. gz sim -s -r <world>.sdf starts the simulation
server only (-s, "headless mode" — overrides -g if present) with the
simulation already playing (-r, "run simulation on start"); add
--headless-rendering (requires OGRE2, the default render engine) when the
world has camera or lidar sensors and there's no X server — see Platform
gotchas. This is the mode a CI job or a remote/cloud run should use; source
verified from the gz-sim CLI's own help text
(src/cmd/cmdsim.rb.in, fetched directly this session). See
references/worlds-and-models.md.
Spawn a robot from SDF/URDF. Launch Gazebo, then use ros_gz_sim's
create executable rather than hand-rolling a Gazebo Transport service call:
ros2 run ros_gz_sim create -world <world_name> -file <path/to/model.sdf> -name <robot_name> -x 0 -y 0 -z 0.1 for a file on disk (or a Fuel URL), or
-topic <topic> to spawn from a latched std_msgs/msg/String publisher —
the pattern for spawning a URDF that a robot_state_publisher node already
published to /robot_description. See references/worlds-and-models.md.
Bridge sensor topics to ROS 2. Pass a single YAML file to
parameter_bridge rather than one CLI arg per topic (see Key directives):
ros2 run ros_gz_bridge parameter_bridge \
--ros-args -p config_file:=examples/ros-gz-bridge-config.yaml
examples/ros-gz-bridge-config.yaml bridges /clock, /cmd_vel, /odom,
/tf, /scan, and /imu for the robot in
examples/diffdrive-world-snippet.sdf — the gz-side topic names in that
world and the gz_topic_names in the bridge config are kept in sync
deliberately; renaming one without the other silently breaks the bridge for
that topic. See references/ros2-bridge.md.
Add sensor noise. Every SDF sensor type accepts a <noise> element
(type="gaussian", with <mean>/<stddev>, plus <bias_mean>/
<bias_stddev> for slowly-varying sensor bias) — for a lidar it sits inside
<lidar> alongside <scan>/<range>, for IMU/camera it sits inside the
relevant axis/noise block. A sensor with zero noise is a common source of a
perception or localization stack that "works perfectly in sim" and then
struggles on the real sensor's actual noise floor — pull real numbers from
the target sensor's datasheet, per the sensor-rates-and-frames key directive
above. See references/sensors.md.
Platform gotchas
- GPU vs. software rendering. Camera and
gpu_lidar sensors go through
Gazebo's render engine (OGRE2 by default); with a GPU and a display, this
just works. Headless or GPU-less, use --headless-rendering (EGL-backed,
OGRE2-only) rather than trying to get X11 forwarding working for a
render-heavy sim — and if there's no GPU at all, OGRE2 falls back to
software rendering, which works but is markedly slower for camera/lidar-
heavy worlds. Source: gazebosim.org's Headless Rendering page, fetched
directly this session. See references/sensors.md.
- Running
gz in Docker. A ROS 2 + Gazebo + ros_gz stack in a
container needs the same GPU-passthrough and headless-rendering
considerations as any other GPU-using container workload — that setup
(--gpus all, the NVIDIA Container Toolkit, choosing headless vs. a
forwarded display) is the environments skill's territory, not
duplicated here; see that skill's Docker and GPU/remote guidance,
including its example ROS 2 Dockerfile, before building a gz-in-Docker
image from scratch.
- macOS status.
gz sim itself ships native Jetty binaries for macOS
via Homebrew (brew install gz-jetty, Ventura/Sonoma — verified via
direct fetch of gazebosim.org's macOS binary-install page this session),
so Gazebo alone is not Docker-only the way ROS 2 is. But the ros_gz
bridge links against ROS 2, and ROS 2 has no native macOS install (see the
ros2 skill's Platform gotchas) — so the full ROS 2 + gz + bridge stack
this skill assumes still needs Docker on a Mac dev machine, even though a
gz-only world with no ROS integration could run natively there.
Customization
- Different gz release / ROS 2 distro pairing: swap the install command
and the world/plugin filenames' implicit release assumptions (plugin
filenames like
gz-sim-diff-drive-system are stable across releases, but
package names and binary availability are not) — re-check
references/ros2-bridge.md's pairing table against the live ros_gz
README first; don't assume the Jazzy/Harmonic pairing this skill defaults
to still applies once the project moves to a different ROS 2 distro.
- Different robot / sensor set: start from
examples/diffdrive-world-snippet.sdf, keep the DiffDrive plugin's
<frame_id>/<child_frame_id> (odom/base_link) and the sensors'
<topic> names in sync with whatever bridge config you copy alongside it
— see references/worlds-and-models.md and references/sensors.md.
- Different bridge topic set: add or remove entries in
examples/ros-gz-bridge-config.yaml; each entry is independent, but a
removed gz_topic_name must also be removed (or renamed together with)
the SDF side that publishes it, per the Usage patterns note above.
References
references/worlds-and-models.md — SDF world/model/link/joint anatomy,
default world plugins, <include>/Fuel model references, the DiffDrive
plugin's parameters, and spawning with ros_gz_sim's create executable.
references/sensors.md — IMU, contact, lidar (<lidar>, the current
preferred tag over the legacy <ray> alias), and camera sensor tags, the
render-engine-backed Sensors system, and the shared <noise> element.
references/ros2-bridge.md — parameter_bridge CLI syntax, the YAML
config-file format (every field), the ROS↔gz message-type table, /clock
bridging, and frame_id/override_frame_id overrides.
examples/diffdrive-world-snippet.sdf — a minimal differential-drive
robot world with lidar and IMU sensors (status: unverified — file header
states the exact upstream sources and the deviations made).
examples/ros-gz-bridge-config.yaml — the matching bridge config for the
world above; topic names are kept in sync between the two files
deliberately (status: unverified — file header states sourcing).
- Upstream: Gazebo documentation and
Gazebo releases (both reached
via direct fetch this session), gazebosim/ros_gz
repo (bridge source and
compatibility table, fetched directly this session),
gazebosim/gz-sim (world examples
and system-plugin sources), sdformat
spec (sensor/noise element
definitions). Sibling skills:
ros2 (foundation, load alongside), nav2
(consumes this skill's bridged topics), simulation (simulator selection),
isaac-sim (GPU photorealistic alternative), environments
(Docker/GPU/remote setup), architect (routes here).
Changelog
1---2name: gazebo-23description: Modern Gazebo (gz — Harmonic/Ionic line) simulation: SDF worlds and models, sensors (lidar, camera, IMU, contact), the ros_gz bridge, spawning robots, and headless/server operation. Use when: 'gazebo', 'gz sim', 'ros_gz', 'simulate the robot', 'add a lidar to the sim', simulating mobile robots or sensors in the ROS ecosystem. Pairs with ros2 and nav2; simulator SELECTION lives in the simulation skill. Gazebo Classic (11) is EOL — this skill covers modern gz only and must never recommend Classic. Not for: Isaac Sim (isaac-sim) or non-ROS simulation.4---56# gazebo78The sim half of the robium nav-vertical trial run: modern Gazebo (the `gz`9tools — Gazebo Classic/`gazebo11` is a separate, EOL project and out of scope10everywhere in this skill) for building SDF worlds and models, attaching11sensors, bridging topics to ROS 2 via `ros_gz`, spawning robots, and running12headless. As of this session, Gazebo's current named releases are **Jetty**13(LTS, Sep 2025 – May 2031), **Ionic** (standard support, Sep 2024 – Dec 2026),14and **Harmonic** (LTS, Sep 2023 – May 2029) — verified by direct `curl` of15`gazebosim.org/docs/all/releases/` this session, which also lists the older16Fortress LTS (Sep 2021 – May 2027) still inside its support window. Jetty is17now the newest LTS, one release past the Harmonic/Ionic line named in this18skill's description; re-verify the release list before trusting any of this19paragraph in a future session; see `references/worlds-and-models.md`'s20sourcing note. The robium nav vertical (`nav2` skill) targets ROS 2 **Jazzy21Jalisco**, whose paired Gazebo release is **Harmonic** — the `ros_gz`22`jazzy` branch ships prebuilt binaries for that pairing from23packages.ros.org, confirmed by direct fetch of the `ros_gz` README this24session (see References). This skill's nav-facing snippets and examples25target Jazzy + Harmonic for that reason; Ionic (paired with Kilted) is26nearing its Dec 2026 EOL, and Jetty (the newest LTS) pairs with Lyrical or27Rolling, not Jazzy — don't pick either for a new Jazzy-based project without28re-checking the table first.2930## When to use this skill3132- Building or editing an SDF world or model, adding a sensor (lidar, camera,33 IMU, contact) to a robot, wiring a `ros_gz` bridge, spawning a robot into a34 running simulation, or running Gazebo headless/server-only.35- The trigger phrases in the description: 'gazebo', 'gz sim', 'ros_gz',36 'simulate the robot', 'add a lidar to the sim'.37- Someone mentions Gazebo Classic tutorials, `gazebo11`, or the old38 `libgazebo_ros_*` plugin names — flag that they don't apply here (Classic39 is EOL) and redirect to this skill's modern `gz`/`ros_gz` equivalents.40- Cross-references — go to the sibling skill instead when the question is:41 - **Which simulator to use at all** (Gazebo vs. Isaac Sim vs. something42 else) → the `simulation` skill. This skill assumes Gazebo has43 already been chosen.44 - Generic ROS 2 mechanics the bridge or a spawned robot's launch file rides45 on (workspaces, colcon, launch files, TF2 concepts, QoS) → `ros2`. This46 skill's only TF content is what the `ros_gz` bridge or a sim plugin47 itself publishes.48 - Navigation behavior once sensor data is flowing (costmaps, AMCL,49 behavior trees) → `nav2`. This skill stops at "sensor topics are bridged50 and correctly framed"; what Nav2 does with them is `nav2`'s territory.51 - Isaac Sim specifically → `isaac-sim`.52 - Running `gz`/`ros_gz` inside Docker, GPU passthrough for the *container*,53 or macOS/remote-server environment strategy → `environments`. This54 skill's Platform gotchas section only notes where Docker changes gz's own55 behavior (rendering, display), not how to set the container up.56 - The whole-stack decision this feeds into → `architect` (routes here).5758## Key directives5960- **Delegation posture: embed + links.** SDF anatomy, sensor tags, and the61 `ros_gz` bridge's CLI/YAML syntax live in this skill's references in depth62 — no single upstream page walks through all three as one coherent unit for63 a new project — but every tag, default value, and parameter table links64 back to `gazebosim.org`, the `sdformat` spec, or the `gazebosim/ros_gz`65 GitHub repo rather than being retyped from memory. See References.66- **Never recommend Gazebo Classic (`gazebo11`).** It reached end-of-life;67 its plugin names (`libgazebo_ros_*`), world format quirks, and tutorials do68 not carry over to modern `gz`. If a search result or an old tutorial69 mentions Classic, say so explicitly and translate to the modern70 equivalent rather than silently using Classic syntax.71- **Bridge every topic explicitly, via a config file, not ad-hoc CLI72 bridges.** A one-off `ros2 run ros_gz_bridge parameter_bridge73 /topic@ros_type@gz_type` per topic is fine for a five-minute test, but a74 real project's bridge set (clock, cmd_vel, odom, tf, every sensor) belongs75 in one YAML config file passed via the `config_file` parameter — it's the76 single reviewable place that states exactly what's bridged, in which77 direction, and at what QoS, and it survives a robot rename without hunting78 down scattered `ros2 run` invocations. See79 `examples/ros-gz-bridge-config.yaml` and80 `references/ros2-bridge.md`.81- **Sensor rates and frames must match the real target robot, not simulator82 defaults.** A lidar simulated at the tutorial's default rate/FOV, or a83 camera with the wrong resolution, produces a stack that "works in sim" and84 then behaves differently the moment it meets real sensor data or a85 downstream consumer (Nav2's costmap update rate, a perception model's86 expected input size) tuned for the real hardware's datasheet. Pull the87 real sensor's rate/FOV/range/frame from its datasheet before simulating it88 — this is the `simulation` skill's correctness-checklist territory;89 this skill only supplies the SDF tags to encode whatever numbers90 that check produces.91- **Never write gz release numbers, EOL dates, or ROS 2/Gazebo pairings from92 memory.** They change with every named release (Jetty's arrival moved93 Harmonic and Ionic down a rung since this skill's description was94 written). Verify against `gazebosim.org/docs/all/releases/` and the95 `gazebosim/ros_gz` README's compatibility table before repeating a claim96 in a real project — every example in this skill is marked `status:97 unverified` for exactly this reason, and each reference states how its98 claims were checked this session.99100## Quick start101102**1. Confirm the gz release paired with your ROS 2 distro.** Check the103compatibility table in `references/ros2-bridge.md` (sourced from the104`gazebosim/ros_gz` README) before installing anything — for the Jazzy-based105nav vertical this skill targets, that's Gazebo **Harmonic**:106107```bash108sudo apt-get install ros-jazzy-ros-gz109```110111**2. Write or copy a world.** Start from112`examples/diffdrive-world-snippet.sdf` (a minimal differential-drive robot113with lidar and IMU sensors) and see `references/worlds-and-models.md` for114SDF anatomy.115116**3. Run it headless and bridge topics.** See the two usage patterns below —117"Run a world headless" and "Bridge sensor topics to ROS 2" — using118`examples/ros-gz-bridge-config.yaml` as the bridge's `config_file`.119120**4. Verify data is flowing** with `ros2 topic echo /scan` (or `/imu`,121`/odom`) before wiring anything downstream (Nav2, a perception node) to it.122123## Usage patterns124125**Run a world headless.** `gz sim -s -r <world>.sdf` starts the simulation126server only (`-s`, "headless mode" — overrides `-g` if present) with the127simulation already playing (`-r`, "run simulation on start"); add128`--headless-rendering` (requires OGRE2, the default render engine) when the129world has camera or lidar sensors and there's no X server — see Platform130gotchas. This is the mode a CI job or a remote/cloud run should use; source131verified from the `gz-sim` CLI's own help text132(`src/cmd/cmdsim.rb.in`, fetched directly this session). See133`references/worlds-and-models.md`.134135**Spawn a robot from SDF/URDF.** Launch Gazebo, then use `ros_gz_sim`'s136`create` executable rather than hand-rolling a Gazebo Transport service call:137`ros2 run ros_gz_sim create -world <world_name> -file <path/to/model.sdf>138-name <robot_name> -x 0 -y 0 -z 0.1` for a file on disk (or a Fuel URL), or139`-topic <topic>` to spawn from a latched `std_msgs/msg/String` publisher —140the pattern for spawning a URDF that a `robot_state_publisher` node already141published to `/robot_description`. See `references/worlds-and-models.md`.142143**Bridge sensor topics to ROS 2.** Pass a single YAML file to144`parameter_bridge` rather than one CLI arg per topic (see Key directives):145146```bash147ros2 run ros_gz_bridge parameter_bridge \148 --ros-args -p config_file:=examples/ros-gz-bridge-config.yaml149```150151`examples/ros-gz-bridge-config.yaml` bridges `/clock`, `/cmd_vel`, `/odom`,152`/tf`, `/scan`, and `/imu` for the robot in153`examples/diffdrive-world-snippet.sdf` — the gz-side topic names in that154world and the `gz_topic_name`s in the bridge config are kept in sync155deliberately; renaming one without the other silently breaks the bridge for156that topic. See `references/ros2-bridge.md`.157158**Add sensor noise.** Every SDF sensor type accepts a `<noise>` element159(`type="gaussian"`, with `<mean>`/`<stddev>`, plus `<bias_mean>`/160`<bias_stddev>` for slowly-varying sensor bias) — for a lidar it sits inside161`<lidar>` alongside `<scan>`/`<range>`, for IMU/camera it sits inside the162relevant axis/noise block. A sensor with zero noise is a common source of a163perception or localization stack that "works perfectly in sim" and then164struggles on the real sensor's actual noise floor — pull real numbers from165the target sensor's datasheet, per the sensor-rates-and-frames key directive166above. See `references/sensors.md`.167168## Platform gotchas169170- **GPU vs. software rendering.** Camera and `gpu_lidar` sensors go through171 Gazebo's render engine (OGRE2 by default); with a GPU and a display, this172 just works. Headless or GPU-less, use `--headless-rendering` (EGL-backed,173 OGRE2-only) rather than trying to get X11 forwarding working for a174 render-heavy sim — and if there's no GPU at all, OGRE2 falls back to175 software rendering, which works but is markedly slower for camera/lidar-176 heavy worlds. Source: `gazebosim.org`'s Headless Rendering page, fetched177 directly this session. See `references/sensors.md`.178- **Running `gz` in Docker.** A ROS 2 + Gazebo + `ros_gz` stack in a179 container needs the same GPU-passthrough and headless-rendering180 considerations as any other GPU-using container workload — that setup181 (`--gpus all`, the NVIDIA Container Toolkit, choosing headless vs. a182 forwarded display) is the `environments` skill's territory, not183 duplicated here; see that skill's Docker and GPU/remote guidance,184 including its example ROS 2 Dockerfile, before building a gz-in-Docker185 image from scratch.186- **macOS status.** `gz sim` itself ships native Jetty binaries for macOS187 via Homebrew (`brew install gz-jetty`, Ventura/Sonoma — verified via188 direct fetch of `gazebosim.org`'s macOS binary-install page this session),189 so Gazebo alone is not Docker-only the way ROS 2 is. But the `ros_gz`190 bridge links against ROS 2, and ROS 2 has no native macOS install (see the191 `ros2` skill's Platform gotchas) — so the full ROS 2 + `gz` + bridge stack192 this skill assumes still needs Docker on a Mac dev machine, even though a193 gz-only world with no ROS integration could run natively there.194195## Customization196197- **Different gz release / ROS 2 distro pairing:** swap the install command198 and the world/plugin filenames' implicit release assumptions (plugin199 filenames like `gz-sim-diff-drive-system` are stable across releases, but200 package names and binary availability are not) — re-check201 `references/ros2-bridge.md`'s pairing table against the live `ros_gz`202 README first; don't assume the Jazzy/Harmonic pairing this skill defaults203 to still applies once the project moves to a different ROS 2 distro.204- **Different robot / sensor set:** start from205 `examples/diffdrive-world-snippet.sdf`, keep the `DiffDrive` plugin's206 `<frame_id>`/`<child_frame_id>` (`odom`/`base_link`) and the sensors'207 `<topic>` names in sync with whatever bridge config you copy alongside it208 — see `references/worlds-and-models.md` and `references/sensors.md`.209- **Different bridge topic set:** add or remove entries in210 `examples/ros-gz-bridge-config.yaml`; each entry is independent, but a211 removed `gz_topic_name` must also be removed (or renamed together with)212 the SDF side that publishes it, per the Usage patterns note above.213214## References215216- `references/worlds-and-models.md` — SDF world/model/link/joint anatomy,217 default world plugins, `<include>`/Fuel model references, the `DiffDrive`218 plugin's parameters, and spawning with `ros_gz_sim`'s `create` executable.219- `references/sensors.md` — IMU, contact, lidar (`<lidar>`, the current220 preferred tag over the legacy `<ray>` alias), and camera sensor tags, the221 render-engine-backed `Sensors` system, and the shared `<noise>` element.222- `references/ros2-bridge.md` — `parameter_bridge` CLI syntax, the YAML223 config-file format (every field), the ROS↔gz message-type table, `/clock`224 bridging, and `frame_id`/`override_frame_id` overrides.225- `examples/diffdrive-world-snippet.sdf` — a minimal differential-drive226 robot world with lidar and IMU sensors (status: unverified — file header227 states the exact upstream sources and the deviations made).228- `examples/ros-gz-bridge-config.yaml` — the matching bridge config for the229 world above; topic names are kept in sync between the two files230 deliberately (status: unverified — file header states sourcing).231- Upstream: [Gazebo documentation](https://gazebosim.org/docs/) and232 [Gazebo releases](https://gazebosim.org/docs/all/releases/) (both reached233 via direct fetch this session), [gazebosim/ros_gz234 repo](https://github.com/gazebosim/ros_gz) (bridge source and235 compatibility table, fetched directly this session),236 [gazebosim/gz-sim](https://github.com/gazebosim/gz-sim) (world examples237 and system-plugin sources), [sdformat238 spec](https://sdformat.org/spec/1.12/sensor/) (sensor/noise element239 definitions). Sibling skills: `ros2` (foundation, load alongside), `nav2`240 (consumes this skill's bridged topics), `simulation` (simulator selection),241 `isaac-sim` (GPU photorealistic alternative), `environments`242 (Docker/GPU/remote setup), `architect` (routes here).243244## Changelog245246<!-- One dated line per battle-tested change, added by skill-author hardening sessions. -->