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.
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 exercises create a Python package, publish a simple sensor value, subscribe to it, expose a service, set a parameter, record a bag and inspect transforms. 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.
| Concept | Use | Example | Common beginner error |
|---|---|---|---|
| Topic | Continuous or event stream | Laser scan, image, odometry, joint state | Using a reliable profile for high-rate sensor data without considering loss or latency |
| Service | Quick request and response | Reset odometry, request a map save | Using a service for a long operation that blocks the caller |
| Action | Long task with feedback and cancellation | Navigate to pose, execute trajectory | Ignoring cancel and recovery behavior |
| Parameter | Runtime configuration owned by a node | Frame name, threshold, control rate | Treating parameters as a global database |
| TF2 | Timed transforms between coordinate frames | map to odom to base_link to camera | Publishing inconsistent parents or stale timestamps |
| Rosbag | Recorded topic traffic | Replay a sensor run after a failure | Recording 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 /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_cpp talkersource /opt/ros/jazzy/setup.bash
ros2 run demo_nodes_py listenerInspect 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.
ros2 node list
ros2 topic list -t
ros2 node info /talker
ros2 topic info /chatter --verbose
ros2 topic hz /chatterCreate 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.
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.bashWrite a publisher and subscriber
A publisher creates a typed topic and sends messages at a defined rate. A subscriber registers a callback that receives each compatible message. Use explicit units in topic names or message definitions when ambiguity is possible. A number called speed is incomplete without linear or angular meaning and units.
Start with std_msgs for learning, then move to domain messages such as sensor_msgs, geometry_msgs and nav_msgs. Avoid inventing custom messages until the existing interfaces are checked. Standard messages improve tool compatibility.
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()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. Do not use a parameter to send high-rate commands.
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 -tLaunch 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.
ros2 run beginner_robot temperature_publisher --ros-args -r /lab/temperature_c:=/robot1/temperature_cTF2 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.
ros2 run tf2_tools view_frames
ros2 run tf2_ros tf2_echo base_link camera_linkRecord 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.
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
TechniaHQRobot checked official product pages, documentation, standards and public technical material on July 15, 2026. Prices and availability can change by country, tax, shipping, software plan, support contract and configuration.
Manufacturer performance figures remain manufacturer-reported unless an independent test is identified. Missing specifications are left undisclosed rather than estimated.
- ROS 2 Jazzy documentation — Open Robotics · Accessed July 15, 2026
- ROS 2 Tutorials — Open Robotics · Accessed July 15, 2026
- ROS 2 Quality of Service settings — Open Robotics · Accessed July 15, 2026
- TF2 documentation — Open Robotics · Accessed July 15, 2026
- Gazebo getting started — Open Robotics · Accessed July 15, 2026