RoboticsROS 2 tutorial

ROS 2 Tutorial for Beginners Build a Small Robot Graph

Learn ROS 2 with a practical beginner workflow covering installation, nodes, topics, services, parameters, launch files, bags, TF and Gazebo.

By TechniaHQRobot8 min read
A TurtleBot3 Burger mobile robot
A TurtleBot3 Burger mobile robot. Image credit Xeru the first · CC BY-SA 4.0

Introduction

ROS 2 is a middleware ecosystem for building robot software from separate processes that exchange typed messages. A camera driver can publish images, a localization node can publish a pose and a controller can consume velocity commands without every component living in one program. The architecture is useful, but beginners often memorize commands without understanding the graph they create.

This tutorial uses ROS 2 Jazzy on Ubuntu 24.04 because Jazzy is a long-term support distribution. The worked exercise creates a Python package and publisher, then reads its messages from the command line. Later sections explain services, actions, parameters, transforms and recording. Commands should be copied from the official installation guide for your operating system because repositories and keys can change. The examples below begin after ROS 2 is installed and the environment has been sourced.

Key findings

  • A ROS 2 node is a process participant with publishers, subscribers, services, actions, parameters and timers.
  • Topics carry streams such as images, joint states and odometry.
  • Services handle short request-response operations; actions handle longer goals with feedback and cancellation.
  • Quality of Service settings affect delivery behavior and must match the data type and network.
  • TF2 records the timed coordinate-frame relationships that let sensor data and robot geometry agree.
  • Rosbags preserve messages for debugging, regression testing and offline analysis.

ROS 2 communication concepts

Choose the primitive by the interaction, not by convenience.

ConceptUseExampleCommon beginner error
TopicContinuous or event streamLaser scan, image, odometry, joint stateUsing a reliable profile for high-rate sensor data without considering loss or latency
ServiceQuick request and responseReset odometry, request a map saveUsing a service for a long operation that blocks the caller
ActionLong task with feedback and cancellationNavigate to pose, execute trajectoryIgnoring cancel and recovery behavior
ParameterRuntime configuration owned by a nodeFrame name, threshold, control rateTreating parameters as a global database
TF2Timed transforms between coordinate framesmap to odom to base_link to cameraPublishing inconsistent parents or stale timestamps
RosbagRecorded topic trafficReplay a sensor run after a failureRecording without noting software version and robot configuration

Verify the installation and environment

Open a new terminal and source the distribution setup file before running ROS commands. A missing source step is the most common reason ros2 is not found or a newly built package is invisible. Add the source command to the shell startup file only after confirming the correct distribution path.

Run the built-in talker and listener in separate terminals. The talker publishes strings and the listener subscribes. This small test confirms that the command-line tools, middleware and environment work before custom code is introduced.

Source ROS 2 Jazzy
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_cpp talker
Start the listener in another terminal
source /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_py listener

Inspect the ROS graph

While the demo runs, list nodes and topics. Use ros2 node info to see the publishers, subscriptions, services and actions attached to a node. Use ros2 topic info with the verbose flag to inspect message type and Quality of Service. The graph is the fastest way to understand an unfamiliar robot.

Echo a topic only when the message rate is manageable. High-bandwidth images or point clouds can flood the terminal. For those, inspect frequency, bandwidth or a small field, and use RViz or a dedicated visualization tool.

Graph inspection commands
ros2 node list
ros2 topic list -t
ros2 node info /talker
ros2 topic info /chatter --verbose
ros2 topic hz /chatter

Create a Python package

Create a workspace with a src directory, then generate an ament_python package. The package metadata declares dependencies and entry points. Keep one responsibility per node while learning. A sensor simulator that publishes temperature should not also contain navigation logic.

After editing, build with colcon from the workspace root. Source the workspace install file in each terminal. The overlay lets ROS find the package on top of the base distribution.

Create and build a workspace
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python beginner_robot --dependencies rclpy std_msgs
cd ~/ros2_ws
colcon build --symlink-install
source install/setup.bash

Write and inspect a Python publisher

Save the example below as ~/ros2_ws/src/beginner_robot/beginner_robot/temperature_publisher.py. It sends a Float32 message once per second on /lab/temperature_c. The values are generated in software and do not come from a temperature sensor.

Use std_msgs for this small exercise. A hardware temperature sensor can use sensor_msgs/Temperature to carry a timestamp and variance alongside the measurement. Check existing message definitions before creating a custom one.

Minimal Python publisher
import rclpy
from rclpy.node import Node
from std_msgs.msg import Float32

class TemperaturePublisher(Node):
    def __init__(self):
        super().__init__('temperature_publisher')
        self.publisher = self.create_publisher(Float32, '/lab/temperature_c', 10)
        self.timer = self.create_timer(1.0, self.publish_value)
        self.value = 21.0

    def publish_value(self):
        message = Float32()
        message.data = self.value
        self.publisher.publish(message)
        self.value += 0.1

def main():
    rclpy.init()
    node = TemperaturePublisher()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

Register the executable and read its messages

Open ~/ros2_ws/src/beginner_robot/setup.py. Add the entry shown below inside its existing entry_points field. Keep the other setup arguments. The entry maps the executable name temperature_publisher to the main function in the new Python module.

Build the package after saving both files. Run the publisher in the first terminal, then open a second terminal and source the same workspace before running ros2 topic echo. You should receive one temperature message per second, starting near 21.0 and rising by 0.1. Float32 rounding may add small decimal differences. Stop the commands with Ctrl+C.

Entry point inside setup.py
entry_points={
    'console_scripts': [
        'temperature_publisher = beginner_robot.temperature_publisher:main',
    ],
},
Build and run in the first terminal
source /opt/ros/jazzy/setup.bash
cd ~/ros2_ws
colcon build --symlink-install --packages-select beginner_robot
source install/setup.bash
ros2 run beginner_robot temperature_publisher
Read messages in a second terminal
source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash
ros2 topic echo /lab/temperature_c std_msgs/msg/Float32

Services, actions and parameters

Use a service for an operation that should finish quickly, such as clearing a counter. Use an action when the operation can take seconds or minutes and needs feedback, cancellation or a final result. Navigation and manipulation goals are action-shaped problems because the robot may be interrupted or fail partway.

Parameters let a node expose configuration such as publish rate, threshold or frame name. Declare parameters with defaults, validate ranges and log the applied value. The publisher above does not declare publish_rate. Replace /your_node below with a node that declares that parameter before trying these commands.

Inspect and set parameters
ros2 param list
ros2 param get /your_node publish_rate
ros2 param set /your_node publish_rate 5.0
ros2 service list -t
ros2 action list -t

Launch files and namespaces

A launch file starts a set of nodes with parameters, remappings and namespaces. It replaces a sequence of manual terminal commands and makes a system repeatable. Give nodes stable names and use namespaces when multiple robots or sensors expose the same interfaces.

Remapping changes an interface name without editing the node. This is useful when a generic controller expects cmd_vel but the robot exposes a namespaced command topic. Document remaps because invisible name changes can make debugging difficult.

Run with a topic remap
ros2 run beginner_robot temperature_publisher --ros-args -r /lab/temperature_c:=/robot1/temperature_c

TF2 and robot coordinate frames

A mobile robot usually has map, odom and base_link frames. Sensors attach below the base through fixed transforms. The map frame can jump when global localization corrects the pose. The odom frame should remain locally continuous. The base_link frame moves with the robot.

Incorrect transforms can make a valid laser scan appear to rotate around the wrong point. Check frame names, parent-child relationships, timestamps and units. Use RViz to visualize axes and the TF tree. Static transforms describe rigid mounting; dynamic transforms describe motion.

Inspect transforms
ros2 run tf2_tools view_frames
ros2 run tf2_ros tf2_echo base_link camera_link

Record and replay a rosbag

Record the topics required to reproduce a failure sensor input, commands, odometry, transforms and system state. A bag without the software version, parameter file and robot configuration is incomplete evidence. Store a short README beside important recordings.

Replay allows a perception or state-estimation node to process the same input repeatedly. It does not reproduce actuator timing, network load or every clock interaction. Use bag-based regression tests for data pipelines and separate hardware-in-the-loop tests for motion.

Record and replay
ros2 bag record /scan /odom /tf /tf_static /cmd_vel
ros2 bag info <bag_directory>
ros2 bag play <bag_directory>

Move from turtlesim to Gazebo and a real robot

Turtlesim is useful for graph concepts. Gazebo adds a physical world, robot model, sensors and plugins. Begin with an official example rather than importing a complicated robot. Confirm that joint names, frames and control interfaces are consistent before adding navigation.

On hardware, start with wheels or joints lifted, low velocity limits and an accessible emergency stop. Verify command sign, encoder direction and stop behavior. A simulation that moves correctly cannot prove the wiring and motor controller are safe.

Limitations and missing information

  • Installation commands can change; the official ROS 2 guide is the source of truth.
  • Jazzy, Kilted and Rolling have different support windows and package availability.
  • ROS 2 is not a hard real-time guarantee by itself.
  • Simulation does not reproduce every hardware, network and timing failure.
  • Quality of Service mismatches can make compatible message types appear disconnected.

Conclusion

A beginner understands ROS 2 when they can draw the graph, name the message types, explain the coordinate frames and reproduce a failure from recorded data. Build a small publisher and subscriber, add configuration and launch, inspect TF2, record a bag and then move the same architecture into Gazebo and low-energy hardware.

Frequently asked questions

Which ROS 2 distribution should a beginner use in 2026?

ROS 2 Jazzy is a strong default on Ubuntu 24.04 because it is a long-term support release. Use the distribution required by the robot or course when compatibility matters.

Should I learn ROS 1 before ROS 2?

No for a new project. Learn ROS 2 directly unless you must maintain a ROS 1 system.

Is ROS 2 a programming language?

No. It is middleware, libraries, tools and conventions used from languages such as C++ and Python.

What is the difference between a topic and a service?

A topic carries a stream without a direct response. A service handles a short request and response. Use an action for long tasks that need feedback or cancellation.

Can ROS 2 control a real robot safely?

It can be part of a safe system, but safety also depends on hardware limits, motor controllers, emergency stops, risk assessment, real-time behavior and validated failure handling.

Sources and methodology

The Python example and package instructions were reviewed on 11 October 2026 against the ROS 2 documentation source. The publisher uses generated temperature values for a software exercise.

The publisher and setup.py entry-point snippet passed Python syntax checks. ROS 2 was unavailable in the review environment, so this review does not report a live publisher/subscriber run or a hardware test.

Share this article

Share the current TechniaHQRobot article page.

Continue reading

Open the latest robotics reporting, Physical AI analysis and hardware notes.

Browse robotics news
Article by @techniahqrobot