ros2-ecosystem-packages
Skill2 starsChanged 54 days agoMITView on GitHub
Use when deciding which existing ROS 2 package already solves a need (control, navigation, manipulation, SLAM, sensor fusion, simulation bridging, recording, visualization, diagnostics, teleoperation, microcontroller bridging) before writing custom code — a curated reference to the 20 most important ROS 2 packages, what each does, when to reach for it, install commands, and pointers to the other skills in this plugin that go deeper.
In this repository5 other files it gives its agents.
- embedded-ros-bridgeSkill
- nav2-moveit2-configSkill
- ros2-controlSkill
- ros2-workspaceSkill
- urdf-xacro-builderSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Before writing a custom node for a capability listed below, use the maintained upstream package instead.
- Very specific: line 59
Always pass an explicit timeout to lookup_transform — an un-bounded lookup that never resolves (a missing publisher, a broken TF tree) …
- Very specific: line 61
Use rclpy.time.Time() (i.e.
- Very specific: line 87
Always include /tf_static alongside /tf when recording anything you'll want to visualize later — static transforms are published once …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
ROS 2 Ecosystem: The 20 Packages to Reach For First
Before writing a custom node for a capability listed below, use the maintained upstream
package instead. Reinventing TF broadcasting, SLAM, a diff-drive controller, or a bag recorder
is wasted effort and a common source of subtle bugs (frame timing, QoS mismatches, coordinate
convention errors) that these packages have already had years of real-world use to fix. Install
commands below use the binary APT packages (ros-<distro>-<package>, distro = humble or
jazzy); prefer these over building from source unless you need an unreleased fix.
Quick reference
| # | Package | Purpose | Reach for it when... |
| 1 | rclcpp / rclpy | Core C++/Python client libraries | Writing any ROS 2 node — see [[ros2-workspace]]. |
| 2 | tf2 (tf2_ros, tf2_geometry_msgs) | Coordinate frame transforms over time | You need to know where one frame is relative to another, now or in the past. |
| 3 | robot_state_publisher | Publishes TF from a URDF + joint states | You have a URDF and need /tf for every link, not just the base. |
| 4 | joint_state_publisher / _gui | Publishes/edits /joint_states | Visualizing or manually testing a URDF without real hardware. |
| 5 | xacro | Macro-expands .xacro into .urdf | Any non-trivial robot description — see [[urdf-xacro-builder]]. |
| 6 | launch / launch_ros | Declarative multi-node bringup | Starting more than one node together with shared arguments. |
| 7 | ros2_control + ros2_controllers | Real-time hardware abstraction + standard controllers | You need a diff-drive, joint-trajectory, or effort controller instead of hand-rolled PID nodes — see [[ros2-control]]. |
| 8 | navigation2 (Nav2) | Autonomous mobile robot navigation stack | Path planning, obstacle avoidance, costmaps — see [[nav2-moveit2-config]]. |
| 9 | moveit2 | Motion planning for manipulators | Arm/gripper trajectory planning, collision-aware IK — see [[nav2-moveit2-config]]. |
| 10 | slam_toolbox | 2D SLAM (mapping + localization) | Building a map from a lidar with no prior map, online or offline. |
| 11 | robot_localization | EKF/UKF sensor fusion | Fusing wheel odometry + IMU (+ GPS) into one continuous odom/map estimate. |
| 12 | behaviortree.cpp (behaviortree_cpp) | Behavior tree execution engine | Sequencing recoverable, composable robot behaviors — Nav2's BT navigator is built on it. |
| 13 | rosbag2 | Record/replay topic data | Capturing sensor/log data for offline debugging or dataset collection. |
| 14 | rviz2 | 3D visualization | Inspecting TF, sensor data, costmaps, or planned trajectories visually. |
| 15 | rqt (rqt_graph, rqt_console, rqt_plot) | GUI debugging tool suite | Visualizing the node/topic graph, tailing logs, or plotting a signal live. |
| 16 | ros_gz (ros_gz_bridge, ros_gz_sim, gz_ros2_control) | ROS 2 ⟷ Gazebo Sim bridge | Simulating a robot in Gazebo and bridging its topics/clock into ROS 2 — see [[urdf-xacro-builder]]. |
| 17 | image_transport + cv_bridge | Efficient image topics + OpenCV interop | Publishing/subscribing camera images, especially compressed, or converting to/from cv::Mat. |
| 18 | diagnostic_updater + diagnostic_aggregator | Standardized system health reporting | Reporting node/hardware health in a way rqt_robot_monitor//diagnostics consumers expect. |
| 19 | teleop_twist_keyboard + joy | Manual teleoperation | Driving a robot by keyboard or gamepad for a smoke test, no custom teleop node needed. |
| 20 | micro-ROS (micro_ros_setup, rclc, micro-ROS Agent) | ROS 2 client stack for microcontrollers | Bridging an STM32/ESP32 into the ROS 2 graph — see [[embedded-ros-bridge]]. |
Also worth knowing, just past the top 20: rosbridge_suite / foxglove_bridge (WebSocket
bridges for browser-based tooling like Foxglove Studio), plotjuggler (standalone bag/live
signal plotting), ros2_socketcan (a ready-made SocketCAN ⟷ ROS 2 bridge node, an alternative
to hand-writing the CAN bridge shown in [[embedded-ros-bridge]]).
Deeper notes on the highest-leverage / most-misused packages
tf2 — coordinate transforms
from tf2_ros import Buffer, TransformListener
from rclpy.duration import Duration
self._tf_buffer = Buffer()
self._tf_listener = TransformListener(self._tf_buffer, self)
transform = self._tf_buffer.lookup_transform(
'base_link', 'laser_frame', rclpy.time.Time(), timeout=Duration(seconds=0.2))- Always pass an explicit
timeouttolookup_transform— an un-bounded lookup that never resolves (a missing publisher, a broken TF tree) hangs the calling thread indefinitely. - Use
rclpy.time.Time()(i.e. "latest available") for most control-loop lookups; only request a specific past stamp when you genuinely need to transform a timestamped sensor reading. - A
LookupException/ExtrapolationExceptionalmost always means a broken or incomplete TF tree (a missingrobot_state_publisher, a static transform never published) — fix the tree, don't catch-and-ignore the exception.
slam_toolbox vs robot_localization — don't confuse the two
slam_toolboxanswers "where am I, and what does the map look like?" from lidar scan matching. It publishesmap -> odom.robot_localizationanswers "what's my best continuous pose estimate from these sensors?" by fusing odometry/IMU/GPS. It typically publishesodom -> base_link(and can publishmap -> odomtoo if configured as the global fusion node, but don't run two nodes both publishing the same TF edge).- A common misconfiguration is running both
slam_toolboxandrobot_localizationeach trying to publishmap -> odom— pick exactly one authority per TF edge.
rosbag2 — record only what you need
ros2 bag record /scan /tf /tf_static /odom -o my_test_run
ros2 bag play my_test_run- Explicitly list topics rather than
-a(all) on a real robot — recording high-rate raw camera/lidar topics unbounded will fill disk and can starve I/O for other processes. - Always include
/tf_staticalongside/tfwhen recording anything you'll want to visualize later — static transforms are published once (transient-local) and are easy to miss if the recorder started after they were published, unless the topic is explicitly subscribed.
image_transport + cv_bridge — don't publish raw images if you can help it
from cv_bridge import CvBridge
bridge = CvBridge()
ros_image = bridge.cv2_to_imgmsg(cv_frame, encoding='bgr8')- Publish through
image_transport(which offerscompressed,theora, etc. transports automatically) rather than rawsensor_msgs/Imageon bandwidth-constrained links (Wi-Fi to a base station, a slow serial-tunneled connection). - Match the
encodingstring (bgr8,mono8,rgb8, ...) to what the array actually contains — a mismatched encoding is a common source of a visually "wrong colors" but otherwise functioning image pipeline.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

