Skip to main content
Home/Guides/ROS 2 Tutorial for Beginners
💻 TutorialROS 2 HumbleUpdated June 2026

ROS 2 Tutorial for Beginners 2026 — Complete Getting Started Guide

ROS 2 (Robot Operating System 2) is the foundation of modern robotics. This guide takes you from zero to your first working robot program — covering installation, core concepts, and real code you can run today.

20 min readUbuntu 22.04 + ROS 2 HumblePython focus
What You'll Learn
Install ROS 2 Humble on Ubuntu 22.04
Understand nodes, topics, services, and actions
Write your first Python publisher & subscriber
Use ros2 CLI tools to inspect and debug
Create a ROS 2 package with colcon
Launch multiple nodes with a launch file
Understand TF2 coordinate transforms
Know what Nav2, SLAM Toolbox, and RViz2 are for

Prerequisites

🐍
Python basics
Comfortable with classes, functions, and imports. No robotics experience needed.
🖥️
Linux comfort
Can use terminal, sudo, and text editor. Know cd, ls, mkdir.
💻
Ubuntu 22.04
Native install, VM, or WSL2 on Windows. At least 20GB disk space.

Step 1 — Install ROS 2 Humble

01
Install Ubuntu 22.04 LTS

ROS 2 Humble runs best on Ubuntu 22.04 (Jammy Jellyfish). If you're on Windows, install WSL2 with Ubuntu 22.04, or use a VM. macOS users can use Docker (see note).

💡 Windows users: run `wsl --install -d Ubuntu-22.04` in PowerShell as Administrator.
02
Set locale and add ROS 2 repo

Configure your system locale and add the official ROS 2 apt repository.

# Set UTF-8 locale
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8

# Add ROS 2 GPG key and repo
sudo apt install software-properties-common curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key   -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture)   signed-by=/usr/share/keyrings/ros-archive-keyring.gpg]   http://packages.ros.org/ros2/ubuntu   $(. /etc/os-release && echo $UBUNTU_CODENAME) main"   | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
03
Install ROS 2 Humble Desktop

The 'desktop' meta-package includes RViz2, demo nodes, and all core libraries. Use 'ros-base' for headless robots.

sudo apt update && sudo apt upgrade -y
sudo apt install ros-humble-desktop -y
sudo apt install python3-rosdep python3-colcon-common-extensions -y

# Initialize rosdep
sudo rosdep init
rosdep update
04
Source setup and test

Add the ROS 2 setup script to your .bashrc so it loads in every terminal, then verify with the talker/listener demo.

# Add to ~/.bashrc (run once)
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
source ~/.bashrc

# Test: open 2 terminals and run:
# Terminal 1:
ros2 run demo_nodes_cpp talker

# Terminal 2:
ros2 run demo_nodes_py listener
# You should see: [INFO] I heard: [Hello World: N]

Step 2 — Core Concepts

ROS 2 has six core communication primitives. Understanding them unlocks everything else.

Nodes

A node is a single executable process that performs a specific task. A robot system is made of many nodes communicating with each other.

Mental model: Think of nodes like microservices — small, single-purpose, communicating via well-defined interfaces.
# List running nodes
ros2 node list

# Get info about a node
ros2 node info /talker
📡
Topics

Topics implement a publish/subscribe pattern. Nodes publish messages to a topic; any number of nodes can subscribe to receive them.

Mental model: Topics are asynchronous and many-to-many. Use them for continuous data streams like sensor readings.
# List active topics
ros2 topic list

# Echo messages on a topic
ros2 topic echo /chatter

# Publish manually
ros2 topic pub /chatter std_msgs/msg/String   '{"data": "Hello from terminal"}'
🔄
Services

Services implement request/response. One node calls a service; the server node processes and returns a response synchronously.

Mental model: Services are synchronous and one-to-one. Use them for actions with a definite result: reset, query, configure.
# List services
ros2 service list

# Call a service
ros2 service call /add_two_ints   example_interfaces/srv/AddTwoInts   "{a: 5, b: 3}"
# Response: sum: 8
🎯
Actions

Actions extend services with feedback during execution and the ability to cancel. Perfect for long-running tasks like navigation.

Mental model: Use actions for tasks that take >1 second, provide progress, and may need cancellation: navigate, pick, scan.
# List action servers
ros2 action list

# Send a Fibonacci action goal
ros2 action send_goal /fibonacci   action_tutorials_interfaces/action/Fibonacci   "{order: 10}" --feedback
⚙️
Parameters

Parameters let you configure node behavior at runtime without recompiling. They're stored per-node and type-safe.

Mental model: Set initial parameters in launch files with YAML. Change them at runtime without restarting.
# List parameters for a node
ros2 param list /my_node

# Get a parameter value
ros2 param get /my_node robot_name

# Set a parameter at runtime
ros2 param set /my_node max_speed 1.5
🚀
Launch Files

Launch files start multiple nodes with parameters in one command. Written in Python (ROS 2) for full programmability.

Mental model: ros2 launch my_robot my_robot_launch.py starts everything at once — no need to open multiple terminals.
# my_robot_launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_robot',
            executable='robot_controller',
            parameters=[{'max_speed': 1.0}]
        ),
        Node(
            package='my_robot',
            executable='lidar_processor',
        ),
    ])

Step 3 — Write Your First Node

Build a complete publisher/subscriber pair in Python. Copy and paste each block — it will run.

1
Create a workspace and package
# Create workspace
mkdir -p ~/ros2_ws/src && cd ~/ros2_ws/src

# Create a Python package
ros2 pkg create --build-type ament_python --node-name my_node my_first_robot

# Build
cd ~/ros2_ws && colcon build
source install/setup.bash
2
Write a publisher node
# ~/ros2_ws/src/my_first_robot/my_first_robot/publisher.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class RobotPublisher(Node):
    def __init__(self):
        super().__init__('robot_publisher')
        self.pub = self.create_publisher(String, 'robot_status', 10)
        self.timer = self.create_timer(1.0, self.timer_callback)
        self.count = 0

    def timer_callback(self):
        msg = String()
        msg.data = f'Robot status: cycle {self.count}'
        self.pub.publish(msg)
        self.get_logger().info(f'Publishing: {msg.data}')
        self.count += 1

def main(args=None):
    rclpy.init(args=args)
    node = RobotPublisher()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()
3
Write a subscriber node
# ~/ros2_ws/src/my_first_robot/my_first_robot/subscriber.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class RobotSubscriber(Node):
    def __init__(self):
        super().__init__('robot_subscriber')
        self.sub = self.create_subscription(
            String, 'robot_status', self.callback, 10)

    def callback(self, msg):
        self.get_logger().info(f'Received: {msg.data}')

def main(args=None):
    rclpy.init(args=args)
    node = RobotSubscriber()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()
4
Register nodes and build
# In setup.py, add entry_points:
entry_points={
    'console_scripts': [
        'publisher = my_first_robot.publisher:main',
        'subscriber = my_first_robot.subscriber:main',
    ],
},

# Rebuild and run
cd ~/ros2_ws && colcon build --symlink-install
source install/setup.bash

# Terminal 1:
ros2 run my_first_robot publisher

# Terminal 2:
ros2 run my_first_robot subscriber

Common Errors & Fixes

Package 'X' not found
Fix: Run: sudo apt install ros-humble-X (replace underscores with dashes, e.g., ros-humble-nav2-bringup)
ros2: command not found
Fix: You forgot to source: run `source /opt/ros/humble/setup.bash` or add it to ~/.bashrc
colcon build fails with 'No module named ...'
Fix: Run `rosdep install --from-paths src -y` in your workspace root to install Python dependencies
Topics not showing / nodes can't communicate
Fix: Check ROS_DOMAIN_ID — both nodes must use the same value. `export ROS_DOMAIN_ID=0` in all terminals
Can't echo topic / empty topic list
Fix: Make sure the publisher is running. Check with `ros2 node list` — the publisher node must appear
QoS incompatibility warning
Fix: Publisher and subscriber QoS profiles must match. Use the same reliability policy (RELIABLE or BEST_EFFORT)

ROS 2 CLI Quick Reference

Essential Commands
# Node management
ros2 node list                         # list all running nodes
ros2 node info /node_name              # show node details

# Topics
ros2 topic list                        # list all topics
ros2 topic echo /topic_name            # print messages
ros2 topic hz /topic_name              # check publish rate
ros2 topic pub /topic std_msgs/msg/String '{"data":"hi"}' -1

# Services
ros2 service list                      # list all services
ros2 service call /service example_interfaces/srv/AddTwoInts "{a: 1, b: 2}"

# Parameters
ros2 param list /node_name             # list params
ros2 param get /node_name param        # get value
ros2 param set /node_name param value  # set value
ros2 param dump /node_name             # dump all to YAML

# Packages
ros2 pkg list                          # list installed packages
ros2 pkg prefix my_package             # find package path

# Build (in workspace root)
colcon build                           # build all packages
colcon build --packages-select my_pkg  # build one package
colcon build --symlink-install         # dev mode (no rebuild for Python)

# Launch
ros2 launch my_package my_launch.py   # run a launch file

What to Learn Next

🗺️
TF2 — Transform Trees

Learn how ROS 2 tracks coordinate frames for every part of your robot (base_link → wheel → camera → world).

ros2 run tf2_tools view_frames
📦
URDF — Robot Description

Define your robot's physical structure in URDF XML. Visualize it in RViz2 with the robot_state_publisher.

ros2 launch urdf_tutorial display.launch.py
👁️
RViz2 — Visualization

The standard robotics visualization tool. Add laser scan, camera, TF, and marker displays to debug your robot.

ros2 run rviz2 rviz2
🤖
Gazebo / Isaac Sim

Simulate your robot in a physics engine. Test Nav2, SLAM, and manipulation before touching real hardware.

ros2 launch gazebo_ros gazebo.launch.py
🧭
Nav2 — Autonomous Navigation

The standard ROS 2 navigation stack. Handles path planning, obstacle avoidance, and goal execution.

ros2 launch nav2_bringup navigation_launch.py
🗺️
SLAM Toolbox

Simultaneous Localization and Mapping. Build a map while your robot navigates an unknown environment.

ros2 launch slam_toolbox online_async_launch.py

Beginner → Expert: 6-Month Path

M1
Month 1: ROS 2 Fundamentals
Install & configure ROS 2 HumbleNodes, topics, services, actionsWrite 5+ pub/sub pairscolcon build workflow
M2
Month 2: Robot Modeling
URDF robot descriptionTF2 coordinate framesRViz2 visualizationrobot_state_publisher
M3
Month 3: Simulation
Gazebo Classic or Ignition FortressImport URDF into GazeboGazebo plugins (lidar, camera, diff drive)Nav2 in simulation
M4
Month 4: Perception
OpenCV with ROS 2Camera calibrationPoint cloud processingObject detection with YOLO ROS
M5
Month 5: Navigation
slam_toolbox for mappingNav2 path planningCustom costmap pluginsBehavior Trees (BT Navigator)
M6
Month 6: Real Hardware
Motor controller integrationSensor drivers (LiDAR, IMU)Safety and watchdog nodesDeploy on Raspberry Pi / Jetson

Best Free Resources

Official ROS 2 Docs
https://docs.ros.org/en/humble/
docs.ros.org — the authoritative reference. Start with Tutorials section.
The Construct ROS 2 Course
https://app.theconstruct.ai/
Browser-based ROS environment, no local install. Best for getting started quickly.
Articulated Robotics (YouTube)
https://www.youtube.com/@ArticulatedRobotics
Josh Newans builds a real robot from scratch with ROS 2. Best video series available.
Robotics Back-End
https://roboticsbackend.com/
In-depth tutorials on specific ROS 2 concepts with working code examples.
GitHub: ros2/examples
https://github.com/ros2/examples
Official ROS 2 Python and C++ code examples — copy and adapt.
r/ROS subreddit
https://www.reddit.com/r/ROS/
Active community. Search before posting — most beginner questions are answered.