ROS/ROS2

ROS (Robot Operating System) is not an operating system — it is publish/subscribe middleware plus a huge ecosystem of tools and packages that has become the lingua franca of robotics software. For SLAM, ROS solves the unglamorous but essential plumbing: getting sensor data from drivers to your algorithm, keeping coordinate frames straight, recording datasets, and visualising results.

Core concepts you need:

ROS 1 vs ROS 2: ROS 1 (final release: Noetic) reached end of life; new development targets ROS 2, which replaces the custom transport with DDS, adds quality-of-service controls (crucial for lossy wireless links and high-rate sensors), supports real-time-friendly executors, works natively on multiple platforms, and drops the single-master architecture. The concepts above carry over almost unchanged; APIs are rclcpp (C++) and rclpy (Python).

For SLAM specifically, the practical workflow is: write your algorithm as a library that knows nothing about ROS, then add a thin ROS wrapper node that subscribes to sensor topics, feeds your library, and publishes odometry, the TF correction, and visualisation markers. This keeps the algorithm testable and portable — the pattern used by ORB-SLAM3, VINS-Fusion, RTAB-Map and most open-source systems that offer ROS support.

A minimal ROS 2 wrapper in Python shows the shape of every SLAM node:

import rclpy
from rclpy.node import Node
from rclpy.qos import qos_profile_sensor_data
from sensor_msgs.msg import Image, Imu
from nav_msgs.msg import Odometry

class SlamNode(Node):
    def __init__(self):
        super().__init__('my_slam')
        self.create_subscription(Image, '/camera/image_raw',
                                 self.on_image, qos_profile_sensor_data)
        self.create_subscription(Imu, '/imu/data',
                                 self.on_imu, qos_profile_sensor_data)
        self.odom_pub = self.create_publisher(Odometry, '/odom', 10)

    def on_imu(self, msg):   self.slam.feed_imu(msg)      # buffer at high rate
    def on_image(self, msg): self.odom_pub.publish(
                                 to_odom_msg(self.slam.track(msg)))

rclpy.init(); rclpy.spin(SlamNode())

Day-to-day commands worth memorising: ros2 bag record -a / ros2 bag play <bag>, ros2 topic hz <topic> (is data actually arriving, at what rate?), ros2 topic echo, ros2 run tf2_tools view_frames (dump the TF tree), and ros2 node info <node> for wiring checks. For multi-sensor input, message_filters provides approximate-time synchronisers to pair images with depth or IMU batches.

Common pitfalls

Why it matters for SLAM

Nearly every robot you will deploy on speaks ROS: sensor data arrives as ROS topics, extrinsics live in TF, and downstream consumers (navigation, planning) expect nav_msgs/Odometry and a map frame. Being able to wrap a SLAM system into a ROS 2 node, replay bags, and debug with RViz is a baseline skill for both research and industry robotics work.

Hands-on