TecnoMate logo
Back to Blog
Guide

ROS 2 on Raspberry Pi: Getting Started with Robot Operating System

7 June 2026
9 min read
ROS 2 on Raspberry Pi: Getting Started with Robot Operating System

Robot Operating System (ROS) has revolutionized the way we build and deploy robotic systems. While ROS 1 was groundbreaking, ROS 2 brings significant improvements with real-time capabilities, better security, and enhanced developer experience. When combined with the affordability and versatility of Raspberry Pi, you get a powerful platform perfect for learning, prototyping, and even building production-ready robots right from your dorm room or workshop.

This comprehensive guide will walk you through everything you need to know about setting up ROS 2 on Raspberry Pi, with practical examples and troubleshooting tips specifically tailored for Indian engineering students and DIY electronics enthusiasts.

Prerequisites: What You'll Need

Prerequisites: What You'll Need

Before diving into ROS 2 on Raspberry Pi, let's gather all the necessary components. Most of these are readily available at TecnoMate stores across major Indian cities and can be ordered online with delivery within 2-3 days.

ComponentSpecificationPrice (₹)Availability
Raspberry Pi 4B4GB RAM, WiFi/BT2,600All TecnoMate stores
MicroSD Card32GB Class 10250Available online
Power Supply5V 3A Official450In stock
USB Hub7-port powered550Limited stock
Breadboard830-point180In stock
Jumper Wires40-pin male-to-female120In stock
LED Pack10mm RGB90In stock
Push ButtonsTactile momentary50In stock
L298N Motor DriverDual H-bridge220In stock
2x DC Motors6V geared180In stock
Chassis Kit2WD acrylic350Available online

Additional Software Requirements:

  • Raspberry Pi OS (latest version with 64-bit support)
  • Stable Internet Connection
  • ~64GB free storage (for ROS 2 installation and projects)
  • Git client for version control

Setting Up Your Raspberry Pi for ROS 2

Setting Up Your Raspberry Pi for ROS 2

Step 1: Install Raspberry Pi OS

First, flash the latest Raspberry Pi OS (64-bit version) onto your microSD card using the Raspberry Pi Imager. This is crucial as ROS 2 requires a 64-bit system for optimal performance.

CodeTecnoMate
# Check your current OS version and architecture
uname -a

If you see armv7l instead of aarch64, you're running the 32-bit version and need to reinstall with the 64-bit option.

Step 2: Update System Packages

Connect your Raspberry Pi to the internet and update all system packages:

CodeTecnoMate
sudo apt update
sudo apt upgrade -y

Step 3: Install ROS 2 Foxy Fitzroy (Recommended for Beginners)

ROS 2 Foxy Fitzroy is the latest Long-Term Support (LTS) release and provides the best stability for learning and development.

CodeTecnoMate
# Add ROS 2 apt repository
sudo apt install curl gnupg -y
curl -sSL https://raw.githubusercontent.com/ros2/ros2/master/ros.key -o /usr/share/keyrings/ros2-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros2-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null

# Update and install ROS 2 Foxy
sudo apt update
sudo apt install ros-foxy-desktop -y

Step 4: Configure Environment Variables

Add ROS 2 to your shell profile:

CodeTecnoMate
echo "source /opt/ros/foxy/setup.bash" >> ~/.bashrc
source ~/.bashrc

Verify the installation:

CodeTecnoMate
ros2 --version

You should see output indicating ROS 2 Foxy Fitzroy.

Your First ROS 2 Node: A Blinking LED

Your First ROS 2 Node: A Blinking LED

Let's create a simple ROS 2 node that controls an LED connected to GPIO pin 18. This will help you understand the basic concepts of ROS 2 nodes, publishers, and subscribers.

Hardware Setup

  • Connect LED anode (long leg) to GPIO pin 18 via a 220Ω resistor
  • Connect LED cathode (short leg) to GND

Creating the Node

CodeTecnoMate
# Create a ROS 2 package
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python blinker_pkg --dependencies rclpy std_msgs

# Navigate to the package directory
cd blinker_pkg

Python Node Code

Create a file blinker_pkg/blinker_pkg/blink_node.py:

CodeTecnoMate
#!/usr/bin/env python3

import rclpy
from rclpy.node import Node
from std_msgs.msg import Bool
import time
from gpiozero import LED

class BlinkerNode(Node):
    def __init__(self):
        super().__init__('blinker_node')
        self.publisher = self.create_publisher(Bool, '/led_command', 10)
        self.timer = self.create_timer(1.0, self.publish_led_command)
        self.led = LED(18)  # GPIO pin 18
        self.counter = 0

    def publish_led_command(self):
        self.counter += 1
        
        if self.counter % 2 == 0:
            self.led.on()
            msg = Bool()
            msg.data = True
        else:
            self.led.off()
            msg = Bool()
            msg.data = False
            
        self.publisher.publish(msg)
        self.get_logger().info(f'LED {"ON" if msg.data else "OFF"}')

def main(args=None):
    rclpy.init(args=args)
    node = BlinkerNode()
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Launch File

Create blinker_pkg/blinker_pkg/launch/blinker.launch.py:

CodeTecnoMate
#!/usr/bin/env python3

from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='blinker_pkg',
            executable='blink_node',
            name='blinker_node',
            output='screen'
        )
    ])

Making Files Executable and Building

CodeTecnoMate
# Make files executable
chmod +x blinker_pkg/blinker_pkg/blink_node.py
chmod +x blinker_pkg/blinker_pkg/launch/blinker.launch.py

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

Running Your First Node

CodeTecnoMate
# Terminal 1: Launch the node
ros2 launch blinker_pkg blinker.launch.py

# Terminal 2: Monitor the topic
ros2 topic echo /led_command

You should see the LED blinking and messages appearing in the topic monitor!

Advanced Tips for Better Performance

TipDescriptionExpected Impact
Use 64-bit OSEssential for ROS 2 performance40-50% faster node execution
Disable unnecessary servicesImprove system resourcesBetter real-time response
Use SSD instead of SD cardFaster I/O operationsReduced latency for sensor data
Configure real-time kernelBetter determinismImproved timing accuracy
Limit CPU frequencyStability under loadPrevents thermal throttling

Disabling Unnecessary Services

CodeTecnoMate
# Disable GUI services to save resources
sudo systemctl disable --now lightdm.service
sudo systemctl disable --now bluetooth.service
sudo systemctl disable --now avahi-daemon.service

# Enable headless mode
sudo raspi-config nonint do_boot_behaviour headless

Real-Time Kernel Configuration

For better real-time performance, consider installing the PREEMPT_RT kernel:

CodeTecnoMate
# Add RT kernel repository
sudo add-apt-repository ppa:beineri/opt-qt-5.12.1-focal
sudo apt update
sudo apt install linux-image-rt-amd64

# Reboot and select RT kernel from GRUB

Common Mistakes and How to Avoid Them

MistakeConsequenceSolution
Using 32-bit OSInstallation failuresAlways use 64-bit Raspberry Pi OS
Insufficient powerRandom crashesUse official 3A power supply
Not sourcing setup.bashCommand not found errorsAdd to ~/.bashrc or source manually
Running as rootSecurity vulnerabilitiesUse 'ros2 run' without sudo
Memory leaksSystem becomes unresponsiveUse proper node lifecycle management

Fixing Memory Leaks

Implement proper cleanup in Python nodes:

CodeTecnoMate
def node_shutdown_hook(node):
    print("Node shutting down...")
    # Clean up resources here
    node.destroy_node()

def main(args=None):
    rclpy.init(args=args)
    node = BlinkerNode()
    rclpy.spin(node)
    
    # Add shutdown hook
    node.destroy_node()
    rclpy.shutdown()

Building a Simple Autonomous Robot

Building a Simple Autonomous Robot

Now that you're comfortable with basic ROS 2 concepts, let's build a simple line-following robot using your Raspberry Pi and components from TecnoMate.

Hardware Assembly

  1. Mount Raspberry Pi on the chassis using the mounting holes
  2. Connect DC motors to L298N driver module
  3. Attach the L298N to the robot chassis
  4. Connect the IR sensor array to GPIO pins 7 and 11
  5. Power the system using a 7.4V LiPo battery

Line Following Node

Create a new package line_follower_pkg:

CodeTecnoMate
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_python line_follower_pkg --dependencies rclpy sensor_msgs geometry_msgs

Add the following Python code line_follower_pkg/line_follower_pkg/line_follower.py:

CodeTecnoMate
#!/usr/bin/env python3

import rclpy
from rclpy.node import Node
import RPi.GPIO as GPIO
import time
from geometry_msgs.msg import Twist

class LineFollowerNode(Node):
    def __init__(self):
        super().__init__('line_follower_node')
        
        # GPIO setup
        GPIO.setmode(GPIO.BCM)
        self.left_sensor = 7
        self.right_sensor = 11
        GPIO.setup(self.left_sensor, GPIO.IN)
        GPIO.setup(self.right_sensor, GPIO.IN)
        
        # Publisher for motor commands
        self.cmd_vel_pub = self.create_publisher(Twist, '/cmd_vel', 10)
        self.twist_msg = Twist()
        
        # PID parameters
        self.Kp = 2.0
        self.Ki = 0.0
        self.Kd = 0.1
        
        self.error_integral = 0
        self.last_error = 0
        
        timer_period = 0.1  # 10 Hz control frequency
        self.timer = self.create_timer(timer_period, self.line_follow)

    def line_follow(self):
        left_value = GPIO.input(self.left_sensor)
        right_value = GPIO.input(self.right_sensor)
        
        # Simple threshold-based line following
        if left_value == 0 and right_value == 1:
            # Line on left sensor
            self.twist_msg.angular.z = -0.5
            self.twist_msg.linear.x = 0.3
        elif left_value == 1 and right_value == 0:
            # Line on right sensor
            self.twist_msg.angular.z = 0.5
            self.twist_msg.linear.x = 0.3
        elif left_value == 0 and right_value == 0:
            # Line lost or junction
            self.twist_msg.angular.z = 0
            self.twist_msg.linear.x = -0.1
        else:
            # No line detected
            self.twist_msg.angular.z = 0
            self.twist_msg.linear.x = 0
            
        self.cmd_vel_pub.publish(self.twist_msg)
        
    def cleanup(self):
        GPIO.cleanup()

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

if __name__ == '__main__':
    main()

Testing Your Robot

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

# Run RViz for visualization
ros2 run rviz2 rviz2 -d $(find-ros-2-package -d rviz/default_viewpoints.rviz) &

# In another terminal, run the line follower
ros2 run line_follower_pkg line_follower.py

Frequently Asked Questions

Yes, ROS 2 can run on Raspberry Pi 3, but you'll need to use ROS 2 Humble (latest) and limit expectations for complex applications. The Pi 4B is highly recommended for serious robotics projects due to its better performance and memory.

Tags
gettingtutorialtecnomateelectronicsdiystartedraspberryrobotros

Ready to start building?

Explore our collection of DIY kits and components. All project components mentioned in this blog are available in our store.

Browse All Projects