Blog

ROS (Robot Operating System): What It Is and How to Start with ROS 2

ROS (Robot Operating System) is not an operating system. It is an open-source set of libraries, tools and conventions for writing robot software as many small programs that talk to each other. You write ROS programs mainly in C++ or Python. If you start today, learn ROS 2: the old ROS 1 reached end of life with Noetic on May 31, 2025, so older tutorials (including the earlier version of this post) that use roscore, catkin and rospy no longer apply.

What ROS gives you

A robot needs code for sensors, motors, localization, planning and a user interface. ROS lets you write each as a separate node and connect them, instead of one giant program. It also supplies ready-made pieces you would not want to write yourself:

  • message definitions for common data (images, laser scans, poses, velocity commands);
  • command-line tools to inspect and debug a running system (ros2 topic, ros2 node, ros2 bag for recording data);
  • visualization (RViz) and the Gazebo simulator, so you can test without hardware;
  • large packages for navigation (Nav2), arm motion planning (MoveIt) and more, built by the community.

The main client libraries are rclcpp for C++ and rclpy for Python. Python is faster to write and fine for learning and high-level logic. C++ is common where timing and performance matter. So the answer to “what programming language does ROS use” is: both, and the nodes can be in different languages in the same robot.

ROS 1 or ROS 2?

Use ROS 2. ROS 1 is no longer maintained: its last release, Noetic, ended support on May 31, 2025. ROS 2 replaced the central roscore master with a decentralized discovery system on top of DDS, supports Windows and Linux, and is the version all current tutorials and new packages target.

ROS 2 releases come out every May. As of October 2026 (check docs.ros.org/en/rolling/Releases.html for the current list):

Distribution Type Main Ubuntu target Supported until
Lyrical Luth (May 2026) LTS 26.04 May 2031
Kilted Kaiju (May 2025) Non-LTS 24.04 December 2026
Jazzy Jalisco (May 2024) LTS 24.04 May 2029
Humble Hawksbill (May 2022) LTS 22.04 May 2027

Pick an LTS release that matches your Ubuntu version. On Ubuntu 24.04, that is Jazzy; on 26.04, Lyrical. The commands below use Jazzy; for another distribution replace jazzy with its name (for example lyrical) and follow that distribution’s page on docs.ros.org. Use the installation page for your distribution to confirm the latest steps, because the package source setup has changed over the years.

Install ROS 2 Jazzy on Ubuntu 24.04

These are the deb-package steps from the official Jazzy documentation. First make sure the locale is UTF-8 and the universe repository is enabled:

sudo apt update && sudo apt install locales
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

sudo apt install software-properties-common
sudo add-apt-repository universe

Then add the ROS 2 apt source and install the desktop bundle (ROS, RViz, demos and tutorials):

sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb

sudo apt update
sudo apt upgrade
sudo apt install ros-jazzy-desktop

In every new terminal, load the environment (or add the line to ~/.bashrc):

source /opt/ros/jazzy/setup.bash

Check it with two terminals: ros2 run demo_nodes_cpp talker in one and ros2 run demo_nodes_py listener in the other. The listener should print the messages the C++ talker publishes, which shows C++ and Python nodes working together. No Ubuntu machine? The official docs also describe installing on Windows, and Docker images exist for ROS releases.

The core concepts

  • Node: one process that does one job, such as reading a lidar or driving the wheels.
  • Topic: a named channel with publish/subscribe semantics. A node publishes messages to /chatter; any number of nodes can subscribe. Use topics for continuous streams like sensor data.
  • Message: the typed data on a topic, for example std_msgs/msg/String or geometry_msgs/msg/Twist.
  • Service: request and reply between two nodes, for short one-off questions such as “reset the map”.
  • Action: a long-running goal with feedback and the ability to cancel, such as “navigate to this point”.
  • Parameter: a configurable value of a node, such as a speed limit, which you can change without editing code.

There is no master process in ROS 2. Nodes find each other automatically, so you do not run anything like roscore first.

Write a publisher and a subscriber in Python

This is the classic first program, written for ROS 2 with rclpy. Save it as talker.py. It publishes a string to the topic chatter twice a second:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String


class Talker(Node):
    def __init__(self):
        super().__init__('talker')
        self.publisher_ = self.create_publisher(String, 'chatter', 10)
        self.timer = self.create_timer(0.5, self.on_timer)
        self.count = 0

    def on_timer(self):
        msg = String()
        msg.data = f'hello world {self.count}'
        self.publisher_.publish(msg)
        self.get_logger().info(f'Publishing: "{msg.data}"')
        self.count += 1


def main(args=None):
    rclpy.init(args=args)
    node = Talker()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

And listener.py, which subscribes to the same topic:

import rclpy
from rclpy.node import Node
from std_msgs.msg import String


class Listener(Node):
    def __init__(self):
        super().__init__('listener')
        self.subscription = self.create_subscription(
            String, 'chatter', self.on_message, 10)

    def on_message(self, msg):
        self.get_logger().info(f'I heard: "{msg.data}"')


def main(args=None):
    rclpy.init(args=args)
    node = Listener()
    try:
        rclpy.spin(node)
    except KeyboardInterrupt:
        pass
    finally:
        node.destroy_node()
        rclpy.shutdown()


if __name__ == '__main__':
    main()

With the ROS environment sourced, run each in its own terminal:

python3 talker.py
python3 listener.py

The listener prints each message the talker sends. The number 10 in both calls is the queue size (how many messages are kept if the receiver is slow). rclpy.spin keeps the node alive and runs its callbacks. Note that the earlier-style ROS 1 code with rospy.Publisher and rospy.init_node does not work in ROS 2.

While both run, inspect the system from a third terminal:

ros2 node list
ros2 topic list
ros2 topic echo /chatter
ros2 topic info /chatter

Running scripts directly is fine to learn. For a real project you package the code. Create a workspace with a src folder, make a package with ros2 pkg create --build-type ament_python my_package, register your functions under entry_points in setup.py, then build with colcon build and load the result with source install/setup.bash. The build tool is colcon; ROS 1’s catkin_make is gone. C++ packages use ament_cmake.

Beyond the first program

  • Launch files start many nodes with parameters in one command (ros2 launch). In ROS 2 they are usually written in Python, with XML and YAML also supported.
  • tf2 tracks coordinate frames, for instance where the camera is relative to the wheels.
  • URDF describes a robot’s links and joints so it can be shown in RViz and simulated in Gazebo.
  • Nav2 and MoveIt 2 are the standard stacks for mobile robot navigation and arm motion planning.
  • ros2 bag records topics so you can replay real sensor data while you debug.

Learning path and common mistakes

  1. Install ROS 2 and finish the official “Beginner: CLI tools” and “Beginner: Client libraries” tutorials on docs.ros.org.
  2. Simulate a robot (TurtleSim first, then a Gazebo robot) before buying hardware.
  3. Use a real board or kit later, such as a Raspberry Pi based robot, once you can publish, subscribe and read logs comfortably.

Frequent problems: forgetting to source the environment in a new terminal (the commands “are not found”); mixing distributions in the same shell; using ROS 1 tutorials with ROS 2 commands; and doing slow work (loops, network calls) inside a callback, which blocks all other callbacks in that node.

Robot software leans on ordinary programming skill: data structures, state machines and search. Our post on algorithms in robotics: pathfinding and navigation shows the kind of code Nav2 runs under the hood, and a solid grounding in Python helps with rclpy. You can practice the basics with guided exercises at app.algocademy.com.

A lesson in AlgoCademy: the step to write, a picture of what it does, the line written in the editor, and the check: Step 2 passed

Before you go

Start thinking like a software engineer.

Learn to code and solve interview problems, one small, checked step at a time.

Free, no card needed. Or look around first

By continuing you agree to the Terms of Service and Privacy Policy.