agentsclimarketplace

Ros2 sim skill

Skill BaraaLazkani/ros2-sim-skill

Expert ROS2 Jazzy + Gazebo Harmonic (gz sim 8) robot simulation: design, build, run, verify, and analyze simulations end to end. Covers colcon workspaces, URDF/xacro authoring, SolidWorks-to-URDF export, SDF worlds, ros_gz bridge config, launch files, headless/GUI simulation, diff-drive and Ackermann mobile robots, manipulator arms (ros2_control, MoveIt 2), sensors (lidar, camera, depth, ultrasonic, IMU, GPS), RViz sensor visualization, teleop, Nav2, SLAM, rosbag recording and analysis. Enforces: interview first, search existing packages before writing code, reuse existing worlds, verify every build/launch with evidence, always ship an RViz config showing every sensor. Use for ANY task mentioning ROS, ROS2, Jazzy, Gazebo, gz sim, Ignition, URDF, xacro, SDF, RViz, colcon, tf, ros2_control, MoveIt, Nav2, SLAM, teleop, or rosbag — creating/spawning/simulating robots, adding sensors, bridging topics, writing launch files, or debugging colcon builds and Gazebo launches.From its SKILL.md

Install
npx -y skills add BaraaLazkani/ros2-sim-skill

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

19.0 KB, ~4.9k tokens by cl100k_base, as published. Nobody here has run it

ROS2 Simulation Skill

Design, build, run, verify, and analyze ROS2 Jazzy + Gazebo Harmonic (gz sim 8) robot simulations. This is a router: it holds doctrine, workflows, and selection tables, and points at references/*.md for depth, scripts/* for execution, and assets/* for copy-and-adapt starting files.

The Five Laws

  1. Interview before building. Use AskUserQuestion per the bank below before writing a line of URDF or launch code for a new simulation.
  2. Search for existing packages before writing code. Run scripts/pkg_search.sh <keyword> first — ROS2 Jazzy already ships teleop, SLAM, nav, EKF, and controller packages for almost everything.
  3. Reuse existing worlds before authoring new ones. Check the world catalog below before writing a single <model> tag.
  4. Never claim success without evidence. A clean colcon build exit code and printed logs are not proof a simulation works — run scripts/sim_verify.py and report its output.
  5. Every simulation ships an RViz config displaying every sensor. No exceptions, not even for "just testing" — see references/rviz-sensor-viz.md.

Environment Facts (verify on your machine)

FactDetail
ROS2 distroJazzy, /opt/ros/jazzy
Simulatorgz sim 8.x (Harmonic)
Commonly installednav2, slam_toolbox, teleop_twist_keyboard/teleop_twist_joy, ros2_control + gz_ros2_control, rosbag2 (sqlite3 + mcap), rqt_plot, robot_localization — verify with env_check.sh since apt install sets vary
May not be installedMoveIt (check for moveit* under /opt/ros/jazzy/share, or run env_check.sh --require moveit before promising a MoveIt-based workflow), plotjuggler, twist_mux — none of these are pulled in by a base ros-jazzy-desktop install
GZ_SIM_RESOURCE_PATHUnset in a bare shell on a standard apt install. Only becomes populated once your shell rc file (sourcing jazzy + your workspace overlay) has run. Don't rely on it — launch files must append their own model/world paths explicitly (AppendEnvironmentVariable, see references/launch-patterns.md). This holds for any Jazzy apt install, not just this one.
GZ_SIM_SYSTEM_PLUGIN_PATHMust include /opt/ros/jazzy/opt/gz_sim_vendor/lib/gz-sim-8/plugins or gz plugins (DiffDrive, sensors, ros2_control bridge) fail to load silently. This path pattern is standard for any Jazzy apt install.
Workspace<your_workspace>/src (conventionally ~/ros2_ws/src) — check what packages already exist there before scaffolding anything new; run scripts/pkg_search.sh per Law 2.
Shell stateClaude's Bash tool does not persist shell state between calls — every ros2/gz/colcon command must source /opt/ros/jazzy/setup.bash && source ~/ros2_ws/install/setup.bash && (adjust the workspace path) in the same command. This is a Claude Code harness behavior, true on any machine.

Run bash <skill_path>/scripts/env_check.sh at the start of any session that will build or launch anything. It reports install status, both env vars above, workspace overlay build state, and stale gz sim processes — this is how you turn the table above from "typical" into "verified for your machine."

Interview First (mandatory for new simulations)

Use AskUserQuestion before scaffolding a new simulation. Skip questions the user already answered in their request; never skip the sensor question — it drives Law 5.

QuestionOptions
Robot typediff-drive / Ackermann (check the workspace for an existing *_description package to reuse or mirror first — Law 2) / manipulator arm / other
Sensors (multiSelect)lidar / camera / depth camera / ultrasonic / IMU / GPS / none
Worldexisting (list from the catalog below) / minimal flat / custom description
Goalteleop drive-around / SLAM + mapping / nav2 autonomous nav / arm motion / sensor data collection / algorithm testing
Control preference (only if relevant)quick gz plugin (DiffDrive/AckermannSteering) vs full ros2_control

Workflow: New Simulation From Scratch

  1. bash scripts/env_check.sh — confirm the environment is sane.
  2. Interview (above).
  3. bash scripts/pkg_search.sh <capability> for every capability the interview surfaced (teleop, slam, nav, ekf, ...) — Law 2.
  4. Scaffold workspace/packages — references/workspace-packaging.md.
  5. Author URDF/xacro from assets/urdf/* macros — references/urdf-authoring.md.
  6. bash scripts/urdf_check.sh <robot>.urdf.xacro — model gate.
  7. Pick a world from the catalog below, or author one if nothing fits — references/sdf-worlds.md.
  8. Write the bridge yaml from assets/config/bridge_template.yamlreferences/ros-gz-bridge.md.
  9. Write the launch file from assets/launch/sim.launch.py.templatereferences/launch-patterns.md.
  10. python3 scripts/gen_rviz_config.py --output <robot>.rviz ... — Law 5.
  11. colcon build (never inside src/), source the overlay, launch headless first (-s), run scripts/sim_verify.py.
  12. Fix loop on any failed gate — references/self-correction.md, escalate to references/troubleshooting.md after 3 failed attempts on the same gate. Only then launch GUI + RViz for the user and report with evidence.

Workflow: Modify an Existing Simulation

Read the existing xacro/launch/bridge files first — don't guess their structure. A modular xacro split (base.xacro/wheels.xacro/ <drive_type>_drive.xacro/sensors.xacro) is a proven pattern worth mirroring if the workspace already uses it. Adding a sensor = one xacro macro (assets/urdf/sensor_*.xacro) + one bridge yaml entry + one RViz display flag + re-run sim_verify.py. Changing worlds = update the launch file's world argument and re-check GZ_SIM_RESOURCE_PATH handling, not a rewrite. Always re-run the verify gate after any change — Law 4 doesn't get suspended for "small" edits.

Workflow: Run & Verify

Modegz_argsWhen
Headless (server only)-r -sAlways run this first — verification, evals, CI-style checks
Full (server + GUI)-rOnce headless is verified, for the user to watch
GUI-only (attach to running server)-gAttaching a viewer to a server already launched headless

Launch via the package's gz_sim.launch.py-style entry point with run_in_background: true, capture its log, then verify:

python3 <skill_path>/scripts/sim_verify.py \
  --topics /scan:5 /odom:10 /clock:10 \
  --tf odom:base_link \
  --model <robot_name> \
  --move-test /cmd_vel

Clean up stale servers before relaunching (pgrep -f 'gz sim' / pkill -f 'gz sim' — a new sim can silently attach to an old server and produce misleading "it works" evidence). The final report to the user must include an evidence block: the exact commands run and their captured output (build exit code, sim_verify.py table, RViz display manifest) — not a prose claim.

Workflow: Analyze Results

ros2 bag record (explicit topics or -a, mcap or sqlite3 storage) → python3 scripts/bag_plot.py <bag_dir> --xy /odom ... --output traj.png or --stats for min/max/mean/hz → rqt_plot for live GUI sessions. Full recipes, ground-truth-pose bridging for accuracy metrics, and storage hygiene in references/bag-analysis.md.

Workflow: SolidWorks → URDF

The user's SolidWorks assembly lives on their Windows machine — Claude guides step by step, the user drives the export, then hands the exported folder back for the Jazzy conversion (package.xml format 3, xacro conversion, mesh unit/path fixes, adding gz sensor tags and drive plugins, none of which the exporter provides). Full walkthrough: references/solidworks-export.md.

Selection Tables

World catalog

WorldPathGood for
default (ros_gz_sim demo)/opt/ros/jazzy/share/ros_gz_sim_demos/worlds/default.sdfFastest empty smoke test
vehicle (ros_gz_sim demo)/opt/ros/jazzy/share/ros_gz_sim_demos/worlds/vehicle.sdfReference for wheeled-vehicle plugin wiring
warehouse (nav2 tb4)/opt/ros/jazzy/share/nav2_minimal_tb4_sim/worlds/warehouse.sdfLarge-scale nav2 benchmarking
depot (nav2 tb4)/opt/ros/jazzy/share/nav2_minimal_tb4_sim/worlds/depot.sdfSecond nav2 reference scenario
minimal_flatassets/worlds/minimal_flat.sdfStarting point for authoring a genuinely new world

These ship with any Jazzy install that has ros_gz_sim_demos / nav2_minimal_tb4_sim installed, plus minimal_flat which ships with this skill. Your own workspace almost certainly has more worlds worth cataloging here — see "Example: cataloging your own worlds" in references/sdf-worlds.md for how to fold them in and validate reused worlds with gz sdf -k.

Full annotated catalog (sizes, obstacle detail, Fuel models, gz sdf -k validation): references/sdf-worlds.md.

Task → existing package

TaskPackageStatus (verify with env_check.sh)
Keyboard/joystick teleopteleop_twist_keyboard / teleop_twist_joyTypically installed
SLAMslam_toolboxTypically installed
Autonomous navigationnav2_bringupTypically installed
Mobile/arm controlros2_control + gz_ros2_controlTypically installed
Sensor fusion / EKFrobot_localizationTypically installed
Bag recording/replayrosbag2 (sqlite3 + mcap)Typically installed
Arm motion planningMoveIt 2Often not installed by defaultsudo apt install ros-jazzy-moveit ros-jazzy-moveit-setup-assistant ros-jazzy-moveit-resources (present as a command, don't run unasked)
Live plottingrqt_plot / scripts/bag_plot.pyplotjuggler often not installed
cmd_vel multiplexingtwist_muxOften not installed by defaultsudo apt install ros-jazzy-twist-mux

Full capability cheat table (~25 rows) and the search-first decision flow: references/package-discovery.md.

Drive approach: gz plugin vs ros2_control

ApproachUse when
gz DiffDrive / AckermannSteering system pluginQuick demo, no ROS controller deps needed, odom TF straight from gz
ros2_control (diff_drive_controller / JTC)nav2-grade tunable odometry, controller lifecycle management, required for arms

Full parameter tables and the Jazzy diff_drive_controller TwistStamped gotcha: references/ros2-control-mobile.md.

Sensor → SDF type → gz topic → bridge → RViz display

SensorSDF <sensor type=...>gz topic patternROS type ← gz type (bridge)RViz display
2D lidargpu_lidar/world/<w>/model/<r>/link/<l>/sensor/<s>/scansensor_msgs/msg/LaserScangz.msgs.LaserScanLaserScan (Best Effort)
3D lidargpu_lidar.../scan/pointssensor_msgs/msg/PointCloud2gz.msgs.PointCloudPackedPointCloud2 (Best Effort)
Camera (RGB)camera.../imagesensor_msgs/msg/Imagegz.msgs.ImageImage (raw transport)
Camera info(paired with camera).../camera_infosensor_msgs/msg/CameraInfogz.msgs.CameraInfopaired with Image, not standalone
Ultrasonicgpu_lidar (narrow-FOV, assets/urdf/sensor_ultrasonic.xacro).../scansensor_msgs/msg/Rangegz.msgs.LaserScanRange (cone alpha ~0.5)
IMUimu.../imusensor_msgs/msg/Imugz.msgs.IMUImu class — may not be registered on your machine (rviz_imu_plugin is not installed by default; check with env_check.sh, install with sudo apt install ros-jazzy-rviz-imu-plugin). gen_rviz_config.py still emits the display + a warning; RViz shows "class not found" for that one display only if it's missing, everything else is unaffected. Use rqt_plot on /imu/orientation.* as the working fallback until installed.
GPSnavsat.../navsatsensor_msgs/msg/NavSatFixgz.msgs.NavSatno dedicated display; log/echo

Full type-mapping table (clock, cmd_vel, odom, joints, tf, magnetometer, joy) and debug recipes: references/ros-gz-bridge.md. Full display recipes and QoS pitfalls: references/rviz-sensor-viz.md.

Scripts

ScriptInvocationWhen to run
env_check.shbash <skill_path>/scripts/env_check.sh [--json] [--require moveit,nav2,...] [--ws PATH]Start of every session that will build or launch; before promising anything that might not be installed
pkg_search.shbash <skill_path>/scripts/pkg_search.sh [--ws PATH] <keyword> [keyword2 ...]Before writing any node/launch logic for a capability — Law 2
urdf_check.shbash <skill_path>/scripts/urdf_check.sh <file.urdf.xacro> [--xacro-args 'k:=v ...'] [--ws PATH]Before every Gazebo attempt — the model gate
sim_verify.pypython3 <skill_path>/scripts/sim_verify.py [--ws PATH] [--topics T:hz ...] [--tf p:c ...] [--model NAME] [--move-test /cmd_vel] [--level MODEL[:max_rad]] [--timeout N] [--json]After every launch, before claiming anything works — Law 4. --level checks resting roll/pitch (default max 0.05 rad) — run it once after every first spawn
gen_rviz_config.pypython3 <skill_path>/scripts/gen_rviz_config.py --output out.rviz [--fixed-frame F] [--laser T]... [--pointcloud T]... [--image T]... [--camera-info T]... [--range T]... [--imu T]... [--map T] [--path T] [--markers T] [--no-robot-model] [--no-tf]Before delivering any simulation — Law 5. Never hand-write .rviz YAML
bag_plot.pypython3 <skill_path>/scripts/bag_plot.py <bag_dir> [--list] [--topic T --field F.path]... [--xy T fx fy] [--stats] --output out.pngAnalysis workflow — trajectory plots, field-vs-time plots, stats

All scripts self-source /opt/ros/jazzy/setup.bash (+ workspace overlay via --ws, default ~/ros2_ws), support --help, and are safe to run read-only except where noted.

Reference Guides (load as needed)

TopicFileWhen to Read
Package discoveryreferences/package-discovery.mdBefore writing any custom node/logic — Law 2 doctrine + capability table
Workspace & packagingreferences/workspace-packaging.mdCreating a package, writing CMakeLists/package.xml, deciding new-vs-existing workspace
URDF/xacro authoringreferences/urdf-authoring.mdAny link/joint/inertia/sensor/drive-plugin work — the deepest reference
SolidWorks → URDFreferences/solidworks-export.mdUser has a SolidWorks assembly to bring in
SDF world authoring & reusereferences/sdf-worlds.mdPicking or authoring a world — Law 3
ros_gz bridgereferences/ros-gz-bridge.mdWiring or debugging any Gazebo↔ROS topic bridge — the type-mapping bible
Launch patternsreferences/launch-patterns.mdWriting/fixing a sim launch file, managing background gz/ros2 processes
Mobile base controlreferences/ros2-control-mobile.mdDiff-drive/Ackermann drive plugin vs ros2_control decision + wiring
Manipulators & MoveItreferences/manipulators-moveit.mdSimulating an arm — two-tier strategy since MoveIt often isn't installed by default
Nav2 + SLAMreferences/nav2-slam.mdMapping or autonomous navigation on a custom sim robot
RViz sensor visualizationreferences/rviz-sensor-viz.mdMUST READ before delivering any simulation — Law 5 enforcement
Self-correctionreferences/self-correction.mdMUST READ before claiming anything works — the evidence loop and stage gates
Bag analysisreferences/bag-analysis.mdRecording, replaying, plotting, or computing metrics from a run
Troubleshootingreferences/troubleshooting.mdA gate has failed the same way 3 times — symptom-indexed fixes, the escalation target

Critical Rules & Common Mistakes

  • Every ros2/gz/colcon Bash call must re-source in the same command — shell state doesn't persist: source /opt/ros/jazzy/setup.bash && source ~/ros2_ws/install/setup.bash && <cmd>.
  • Never colcon build from inside src/ — build from the workspace root.
  • Pass use_sim_time:=true to every node in a simulation launch, including rviz2 — otherwise expect TF extrapolation errors.
  • Always bridge /clock (rosgraph_msgs/msg/Clockgz.msgs.Clock) — it is a prerequisite for use_sim_time working at all.
  • Spawn with a small -z 0.1 offset to avoid ground-plane collision jitter at t=0.
  • GZ_SIM_RESOURCE_PATH is unset in a bare shell — launch files must append their own package share paths (AppendEnvironmentVariable), never assume it's inherited from the interactive shell.
  • Kill stale gz sim servers (pkill -f 'gz sim') before relaunching — a new launch can silently attach to an old server and produce misleading "it works" evidence.
  • Build xacro Command substitutions as ParameterValue(Command(['xacro ', path, ...]), value_type=str) — omitting value_type=str is a common silent robot_state_publisher failure.
  • Don't reinvent teleop, nav, SLAM, or EKF fusion — Law 2 exists because Jazzy already ships working, tested packages for all of them.
  • visualization_msgs/Marker(Array) is not bridgeable — publish markers directly from a ROS-side node, never add a marker bridge entry.
  • MoveIt is frequently not installed by default — check with env_check.sh --require moveit before promising a MoveIt-based workflow; default to the ros2_control JTC tier for arms unless the user explicitly wants MoveIt and accepts the install.
  • diff_drive_controller in Jazzy expects TwistStamped by default — remap/adapt teleop output (stamped:=true) accordingly.
  • Missing gz-sim-sensors-system (ogre2) or gz-sim-imu-system world plugins is the #1 cause of "sensor topic never publishes" — check the world file, not the robot's sensor tag, first.
  • Diff-drive bases get casters front AND rear — the support polygon must contain the center of mass, and two wheels on one axle alone don't constrain pitch. After first spawn, verify the robot rests level (roll/pitch ≈ 0, see references/self-correction.md) before trusting any sensor data — a tilted rest tilts every sensor frame with it.

What ships with it: 39 files

3425.9 KB alongside SKILL.md, 6 of them executable

.claude-plugin/

docs/

scripts/

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.