Hardware Academy
Robotics

ROS 2 and the robotics stack

Nodes, topics, services, actions, TF and how robotics teams are organized.

Day 10 · 45 min

After this lesson

  • You can explain ROS 2 nodes, topics, services, actions and QoS.
  • You can sketch a node graph for the course robot.
  • You can present the robot as a portfolio project.

How professional robots are wired together in software

What ROS 2 is

ROS 2 (Robot Operating System 2) is not an operating system. It is middleware plus a toolbox: you split a robot's software into nodes, each with one job, and they talk over a publish-subscribe bus built on DDS. A long-term-support release ships every two years in May; Humble Hawksbill (2022) is supported to 2027 and Jazzy Jalisco (2024, on Ubuntu 24.04) to 2029. Nodes are written in C++ with rclcpp or Python with rclpy and driven from the ros2 command line.

Topics, services, actions, parameters and launch files

  • Topics: named, typed, many-to-many streams for continuous data. /cmd_vel carries geometry_msgs/msg/Twist (linear.x in m/s, angular.z in rad/s); /scan carries sensor_msgs/msg/LaserScan.
  • Services: request and response, like a function call across the network, for short operations such as enabling the motors.
  • Actions: long-running goals with feedback and cancellation, built from topics and services. Nav2's NavigateToPose streams the distance remaining and can be cancelled when a person steps in front.
  • Parameters: typed per-node settings such as wheel_base: 0.12, loaded from YAML at launch or changed live with ros2 param set.
  • Launch files: Python, XML or YAML files that start a set of nodes with their parameters, remappings and namespaces, so one command brings up the whole robot.

DDS and quality of service

Underneath, the RMW layer maps ROS 2 onto a DDS implementation: eProsima Fast DDS by default, or Eclipse Cyclone DDS; Zenoh is a newer non-DDS option. Discovery is automatic over UDP multicast, and ROS_DOMAIN_ID keeps two robots on one network apart. Every endpoint carries a QoS profile: reliability (RELIABLE retransmits lost samples, BEST_EFFORT does not), durability (VOLATILE, or TRANSIENT_LOCAL, which replays the last messages to late joiners and is used for maps), history depth (KEEP_LAST 10), plus deadline and liveliness. Publishers offer, subscribers request, and a connection forms only when the offer satisfies the request. Camera and lidar drivers usually publish with the sensor-data profile, BEST_EFFORT with depth 5, so a subscriber left on the RELIABLE default receives nothing, with one warning as the only clue.

TF, URDF, RViz and bags

TF2 keeps a time-stamped tree of coordinate frames. By REP 105 the chain is map → odom → base_link: odometry publishes odom → base_link (smooth, drifts), localization publishes map → odom (corrects drift, may jump), and robot_state_publisher reads the URDF to publish base_link → sensor frames. Any node can then ask where the sonar was in the map frame at 12.304 s and get an interpolated answer. RViz2 draws it all live: robot model, frames, scans, maps, planned paths. ros2 bag record captures topics to MCAP files so a field failure can be replayed at your desk.

The big packages

  • Nav2: AMCL localization, costmaps that inflate obstacles, global planners (NavFn, Smac), local controllers (DWB, Regulated Pure Pursuit, MPPI) and recovery behaviors, orchestrated by behavior trees.
  • MoveIt 2: motion planning for arms: inverse kinematics, collision checking, OMPL planners and trajectory execution.
  • ros2_control: a hardware abstraction with standard controllers such as diff_drive_controller.
  • micro-ROS: ROS 2 on microcontrollers such as the ESP32 over XRCE-DDS, with an agent on a computer that bridges serial or Wi-Fi into the graph. That is how the course robot would publish /odom and obey /cmd_vel.

How robotics teams are organized

Robotics companies usually split work into perception, localization and mapping, planning and controls, manipulation, embedded firmware, electrical, mechanical, simulation and test, and infrastructure for fleets, logs and CI. Startups hire generalists who cover several of these; larger companies such as Boston Dynamics, Amazon Robotics or Agility Robotics hire specialists. Firmware and controls meet at the motor driver, perception and planning meet at the costmap, and everyone meets in the logs.

Presenting the robot as a portfolio project

A reviewer gives a project about two minutes, so lead with a 60 to 90 second video of the robot finishing a lap with telemetry overlaid. Then a README with a block diagram, the bill of materials and cost, the schematic or KiCad board, the firmware and simulator code, and measured results: "a UMBmark square test cut return error from 41 cm to 6 cm", "bulk capacitance cut the 5 V dip from 1.1 V to 0.08 V". Add a section on what went wrong; it is the part interviewers ask about.

Roles and interview expectations

Embedded robotics interviews probe interrupts, PWM and H-bridges, encoders, PID tuning, power integrity and bring-up. Robotics software interviews probe C++ and Python, ROS 2 (QoS, TF, executors and callback groups), coordinate frames, state estimation such as Kalman filters, and planning such as A* and sampling-based planners. Expect a live or take-home exercise: A* on a grid, a PID class with anti-windup, or transforming points between frames.

TF tree for the course robot: map to odom to base_link, then wheels and sensorsmapodombase_linkleft_wheel0, 0.06, 0right_wheel0, -0.06, 0sonar_link0.07, 0, 0.08line_sensors0.05, 0, -0.015imu_link0, 0, 0.03camera_link0.06, 0, 0.12camera_opticalmap → odom: AMCL or SLAM, 10-20 Hz. Globally right, but it can jump.odom → base_link: wheel odometry or an EKF, 50 Hz. Smooth, but drifts.wheels: robot_state_publisher, from /joint_statessensors: fixed URDF joints, published once on /tf_staticoffsets in meters (x forward, y left, z up: REP 103)
TF tree for the course robot. Each frame has exactly one parent. Odometry and localization publish the top two links at runtime; the sensor offsets come from the URDF and never change.

Interactive: a node graph you can break

A ROS 2 node graph

Messages flow from the camera to the motors. Click a node or a topic for its message types, then change the detector's QoS and watch the graph break the way real ones do.

ROS 2 graph: /camera, /detector, /planner and /motor_driver nodes linked by topicsBEST_EFFORT offered → BEST_EFFORT requested/camera/camera/image_raw/detector/detections/planner/cmd_vel/motor_driverrounded = node · square = topic · dots = messages (slowed down: the real camera publishes 30 per second)
/detector subscription reliability

Click or tab to a node (rounded) or a topic (square) to see what it publishes, subscribes to and its message types.

images published 1 · delivered 0 · dropped 0 · retransmitted 0

Connected: the QoS profiles are compatible and images flow.

In practice

Practice

Sketch the node graph for your robot, then install ROS 2

Assume the ESP32 runs micro-ROS over Wi-Fi and a laptop runs everything else. List the nodes, the topics with their message types and rates, and the QoS you would choose for each. Then install ROS 2 and reproduce this lesson's QoS bug on purpose.

Worked answer: the node graph

NodeRuns onPublishesSubscribes
/robot_base (micro-ROS)ESP32/odom (nav_msgs/msg/Odometry, 20 Hz, best effort), /range (sensor_msgs/msg/Range, 16 Hz, sensor data), /battery (sensor_msgs/msg/BatteryState, 1 Hz, reliable)/cmd_vel (geometry_msgs/msg/Twist, reliable), with a 300 ms watchdog
/micro_ros_agentlaptopBridges XRCE-DDS over Wi-Fi UDP into DDSnone
/robot_state_publisherlaptop/tf_static and /robot_description (transient local)/joint_states
/odom_to_tflaptop/tf (odom → base_link)/odom
/behavior (your state machine)laptop/cmd_vel (10 Hz)/range, /odom
/teleop_twist_keyboard and rviz2laptop/cmd_vel when you drive by hand/tf, /odom, /range

The design choices to defend in an interview: the speed loops and encoder interrupts stay on the ESP32, only setpoints and state cross Wi-Fi; sensor streams are best effort because a late reading is worthless; commands are reliable and guarded by a watchdog so a dropped link stops the robot.

Install and the QoS experiment

terminalbash
# Ubuntu 24.04 with ROS 2 Jazzy (add the ROS 2 apt repository first, as in docs.ros.org)
sudo apt install ros-jazzy-desktop
source /opt/ros/jazzy/setup.bash

# macOS or Windows: run it in a container instead
docker run -it --rm osrf/ros:jazzy-desktop

# smoke test, in two terminals
ros2 run demo_nodes_cpp talker
ros2 run demo_nodes_py listener

# look at the graph and the QoS of every endpoint
ros2 node list
ros2 topic list
ros2 topic info -v /chatter

# reproduce this lesson's scenario: a QoS mismatch
ros2 topic pub /test std_msgs/msg/String "{data: hello}" --qos-reliability best_effort
ros2 topic echo /test --qos-reliability reliable     # silence, plus an incompatible-QoS warning
ros2 topic echo /test --qos-reliability best_effort  # messages arrive

Real-world scenario

Real-world scenario

The publisher works, the subscriber never hears it

A new team member writes a C++ node that subscribes to /camera/image_raw to count people in the hallway. The camera driver is clearly running: ros2 topic hz reports 30 Hz and RViz shows the live image. The new node builds, starts, logs that it has subscribed, and then its callback never fires, not once, for an entire afternoon of debugging.

Symptoms

  • ros2 topic list shows /camera/image_raw and ros2 topic hz reports 30 Hz
  • RViz and ros2 topic echo display the images normally
  • The new node's callback counter stays at zero, with no errors and no crashes
  • A single warning at startup says a new publisher on /camera/image_raw is offering incompatible QoS and that no messages will be received from it

Interview questions

screenExplain topics, services and actions, with an example of when you would use each.
A topic is a typed, many-to-many stream for continuous data: a lidar publishes sensor_msgs/msg/LaserScan on /scan at 10 Hz and any node can subscribe. A service is a request-response call for short operations, such as enabling the motors or resetting odometry, where the caller waits for an answer. An action is for long-running goals that need feedback and cancellation, like Nav2's NavigateToPose: you send a goal, receive the distance remaining as feedback, and can cancel it if a person steps in front. Under the hood actions are built from topics and services. Choosing wrong hurts: a 30-second navigation done as a service blocks the caller and cannot be cancelled cleanly.
screenWhat does TF do, and what are the map, odom and base_link frames?
TF keeps a time-stamped tree of coordinate frames so any node can ask where one frame was relative to another at a given time, with interpolation. By REP 105, base_link is fixed to the robot, odom is a world frame in which the robot's pose is smooth and continuous but drifts, and map is a world frame that is globally correct but can jump when localization corrects itself. Wheel odometry or an EKF publishes odom to base_link; AMCL or SLAM publishes map to odom, which absorbs the drift without making the odometry discontinuous. robot_state_publisher publishes the fixed sensor frames from the URDF. Local control uses odom because it never jumps; global planning uses map.
screenHow would you present a hobby robot in an interview so that it counts as real experience?
I would lead with a 60 to 90 second video of the robot doing its job, then walk through a block diagram and the decisions behind it, such as why the TB6612 and why a separate 5 V rail. The strongest part is measured numbers and failures: the brownout I found with a scope and fixed with a bigger buck and bulk capacitance, and how a UMBmark square test cut odometry error from 41 cm to 6 cm. I would show that I tested in simulation first and what changed on hardware. Interviewers care less about the robot's features than about how I debugged, measured and documented it.
deepA subscriber receives nothing even though the topic is publishing. How do you debug it?
First I confirm what DDS sees: ros2 topic info -v on the topic lists every publisher and subscription with its QoS, so I check that both endpoints appear and that reliability, durability and deadline are compatible; a RELIABLE subscriber never matches a BEST_EFFORT publisher. If the subscription is missing, I check names and namespaces, remappings and the exact message type. If the publisher is invisible, I check ROS_DOMAIN_ID, the RMW implementation on each machine, and whether multicast discovery is blocked by the network or a firewall, which is common on Wi-Fi and in Docker. Finally I look for an executor problem: a callback group that is never spun, or a single-threaded executor blocked by a long callback.
deepHow would you connect a microcontroller-based robot like the course robot to a ROS 2 system?
I would run micro-ROS on the ESP32: an XRCE-DDS client publishes /odom and range data and subscribes to /cmd_vel, and a micro-ROS agent on the laptop bridges it over serial or Wi-Fi UDP into the normal DDS graph. Hard real-time work, the 100 Hz wheel speed loops and encoder interrupts, stays on the microcontroller, and only setpoints and state cross the link, at 20 to 50 Hz. I would timestamp messages after syncing the clock with the agent, use best effort for high-rate sensor data and reliable for commands, and add a /cmd_vel watchdog that stops the motors if no command arrives for 300 ms. On a larger robot I would instead write a ros2_control hardware interface so the standard diff_drive_controller does the kinematics.

Quiz

1. Which communication pattern fits 'drive to the kitchen, report progress, and let me cancel'?
2. A subscription requests RELIABLE and the only publisher offers BEST_EFFORT. What happens?
3. Under REP 105, which transform does wheel odometry publish?
4. What does TRANSIENT_LOCAL durability give a subscriber that joins late?
5. What is micro-ROS?
6. For a differential-drive robot, which fields of the geometry_msgs/msg/Twist on /cmd_vel matter?
7. Which tool records topics to a file so you can replay a field failure at your desk?

References and further reading

Where the ideas in this lesson come from, and what to read next. Books are the standard texts; papers are the original sources; standards are what employers work to.

  1. Paperfree online

    Morgan Quigley et al. (2009). ROS: An Open-Source Robot Operating System. ICRA Workshop on Open Source Software.

    Read: The original ROS design.

  2. Paper

    Steven Macenski, Tully Foote, Brian Gerkey, Chris Lalancette and William Woodall (2022). Robot Operating System 2: Design, Architecture, and Uses in the Wild. Science Robotics 7(66).doi:10.1126/scirobotics.abm6074

    Read: Why ROS 2 changed the architecture and who runs it in production.