Tutorialbeginner

Getting Started with ROS 2: Your First Robot Application

By Robotocist Team··3 min read·45 minutes to complete

Prerequisites

  • Basic Python knowledge
  • Ubuntu 24.04 LTS (or WSL2 on Windows)
  • Command line familiarity
ROS 2 JazzyPython 3Ubuntu 24.04

ROS 2 (Robot Operating System 2) is the de facto standard framework for building robot applications. In this tutorial, you'll go from zero to running your first ROS 2 nodes.

What You'll Learn

By the end of this tutorial, you will:

  • Install ROS 2 Jazzy on Ubuntu 24.04
  • Understand ROS 2 core concepts (nodes, topics, messages)
  • Create a workspace and package
  • Build a publisher and subscriber in Python
  • Run and test your first ROS 2 application

Prerequisites

Before starting, make sure you have:

  • Ubuntu 24.04 LTS (native or via WSL2 on Windows)
  • Python 3.10+ installed
  • Basic command line familiarity

Step 1: Install ROS 2 Jazzy

First, set up the ROS 2 apt repository:

# Set locale
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
 
# Add ROS 2 GPG key
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo apt update && sudo apt install curl -y
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
 
# Add repository to sources list
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
 
# Install ROS 2 Jazzy
sudo apt update
sudo apt install ros-jazzy-desktop -y

Source the ROS 2 setup file:

source /opt/ros/jazzy/setup.bash
# Add to your .bashrc for persistence
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc

Step 2: Understand Core Concepts

ROS 2 is built around a few key concepts:

  • Nodes: Independent processes that perform computation
  • Topics: Named buses for nodes to exchange messages
  • Messages: Typed data structures sent over topics
  • Publishers: Nodes that send messages to a topic
  • Subscribers: Nodes that receive messages from a topic

Think of it like a chat system: publishers post messages to channels (topics), and subscribers listen to those channels.

Step 3: Create Your Workspace

# Create workspace directory
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
 
# Create a Python package
ros2 pkg create --build-type ament_python my_first_robot \
  --dependencies rclpy std_msgs

This creates a package called my_first_robot with dependencies on rclpy (ROS 2 Python client) and std_msgs (standard message types).

Step 4: Write the Publisher

Create the publisher node at ~/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):
    """A simple publisher that sends robot status messages."""
 
    def __init__(self):
        super().__init__("robot_publisher")
        self.publisher_ = self.create_publisher(String, "robot_status", 10)
        timer_period = 1.0  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.count = 0
 
    def timer_callback(self):
        msg = String()
        msg.data = f"Robot status update #{self.count}: All systems operational"
        self.publisher_.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()
 
 
if __name__ == "__main__":
    main()

Step 5: Write the Subscriber

Create the subscriber at ~/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):
    """A simple subscriber that listens for robot status messages."""
 
    def __init__(self):
        super().__init__("robot_subscriber")
        self.subscription = self.create_subscription(
            String, "robot_status", self.listener_callback, 10
        )
 
    def listener_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()
 
 
if __name__ == "__main__":
    main()

Step 6: Configure and Build

Update setup.py in your package to register the entry points:

entry_points={
    "console_scripts": [
        "publisher = my_first_robot.publisher:main",
        "subscriber = my_first_robot.subscriber:main",
    ],
},

Build and source:

cd ~/ros2_ws
colcon build --packages-select my_first_robot
source install/setup.bash

Step 7: Run Your Application

Open two terminals. In the first:

ros2 run my_first_robot publisher

In the second:

ros2 run my_first_robot subscriber

You should see the publisher sending messages and the subscriber receiving them in real-time!

Next Steps

Now that you have the basics down, explore:

  • Services: Request-response communication pattern
  • Actions: Long-running tasks with feedback
  • Launch files: Start multiple nodes at once
  • TF2: Coordinate frame transforms
  • URDF: Robot description format

ROS 2 is a vast ecosystem, and this tutorial just scratches the surface. In our next tutorial, we'll build a simulated robot using Gazebo and control it with ROS 2.

ros2roboticstutorialpythonbeginner
Share:𝕏inY