انتقل إلى المحتوى
العودة إلى الرؤى

How to Set Up ROS 2: A Practical Guide

TL;DR

Mohammed Cherifi
نُشر
6 دقائق للقراءة

TL;DR

  • Install ROS 2 Jazzy on Ubuntu 24.04 with sudo apt install ros-jazzy-desktop
  • Core concepts: nodes (processes), topics (pub/sub), services (RPC), actions (long-running tasks)
  • Write a Python/C++ publisher/subscriber in 5 minutes
  • Use ros2 launch for multi-node orchestration
  • Debug with rqt, ros2 bag, and rviz2

## 1. Installing ROS 2 (Jazzy) on Ubuntu

Prerequisites

Step 1: Set up locale and repositories

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

Step 2: Add ROS 2 repository

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

Step 3: Install ROS 2 Jazzy

# Desktop install (recommended): ROS, RViz, demos, tutorials
sudo apt install ros-jazzy-desktop

# Base install (minimal): just ROS and command-line tools
# sudo apt install ros-jazzy-ros-base

# Development tools (optional)
sudo apt install ros-dev-tools

Step 4: Set up environment

# Source ROS 2 setup file (add to ~/.bashrc for persistence)
source /opt/ros/jazzy/setup.bash

# Verify installation
ros2 --version
# Expected output: ros2 version 26.0.0 (or higher)

Gotchas:

  • If ros2 --version fails, ensure /opt/ros/jazzy/setup.bash is sourced.
  • For Python packages, install python3-colcon-common-extensions if missing.

## 2. Nodes, Topics, Services, and Actions

Core Concepts

ConceptDescription<a href="/services/physical-ai-robotics">physical ai</a> Stack Mapping
NodeA process that performs computation (e.g., sensor driver, planner).COMPUTE
TopicAsynchronous pub/sub communication (e.g., /scan for LiDAR data).CONNECT
ServiceSynchronous request/response (e.g., /reset_pose for localization).REASON
ActionLong-running task with feedback (e.g., /navigate_to_pose for navigation).ACT

CLI Commands

# List nodes
ros2 node list

# List topics
ros2 topic list

# Echo a topic
ros2 topic echo /scan

# Call a service
ros2 service call /reset_pose std_srvs/srv/Empty

# List actions
ros2 action list

## 3. Writing Your First Publisher/Subscriber

Python Example

Publisher (publisher.py)

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class MinimalPublisher(Node):
    def __init__(self):
        super().__init__('minimal_publisher')
        self.publisher_ = self.create_publisher(String, 'topic', 10)
        timer_period = 0.5  # seconds
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0

    def timer_callback(self):
        msg = String()
        msg.data = f'Hello ROS 2: {self.i}'
        self.publisher_.publish(msg)
        self.get_logger().info(f'Publishing: "{msg.data}"')
        self.i += 1

def main(args=None):
    rclpy.init(args=args)
    minimal_publisher = MinimalPublisher()
    rclpy.spin(minimal_publisher)
    minimal_publisher.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Subscriber (subscriber.py)

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class MinimalSubscriber(Node):
    def __init__(self):
        super().__init__('minimal_subscriber')
        self.subscription = self.create_subscription(
            String,
            'topic',
            self.listener_callback,
            10)
        self.subscription  # prevent unused variable warning

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

def main(args=None):
    rclpy.init(args=args)
    minimal_subscriber = MinimalSubscriber()
    rclpy.spin(minimal_subscriber)
    minimal_subscriber.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Run the Example

# Terminal 1: Run publisher
python3 publisher.py

# Terminal 2: Run subscriber
python3 subscriber.py

# Expected output (Terminal 2):
# [INFO] [minimal_subscriber]: I heard: "Hello ROS 2: 0"
# [INFO] [minimal_subscriber]: I heard: "Hello ROS 2: 1"

C++ Example

Publisher (publisher.cpp)

#include <chrono>
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"

using namespace std::chrono_literals;

class MinimalPublisher : public rclcpp::Node {
public:
  MinimalPublisher() : Node("minimal_publisher"), count_(0) {
    publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
    timer_ = this->create_wall_timer(
      500ms, std::bind(&MinimalPublisher::timer_callback, this));
  }

private:
  void timer_callback() {
    auto message = std_msgs::msg::String();
    message.data = "Hello ROS 2: " + std::to_string(count_++);
    RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
    publisher_->publish(message);
  }
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
  size_t count_;
};

int main(int argc, char * argv[]) {
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalPublisher>());
  rclcpp::shutdown();
  return 0;
}

Build and Run

# Create a workspace
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake cpp_pubsub

# Replace the generated src/cpp_pubsub/src/publisher_member_function.cpp with the code above
# Build
cd ~/ros2_ws
colcon build --packages-select cpp_pubsub

# Source the workspace
source install/setup.bash

# Run publisher
ros2 run cpp_pubsub talker

## 4. Launch Files and Parameters

Launch File Example (launch_example.py)

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='cpp_pubsub',
            executable='talker',
            name='talker_node',
            parameters=[{'use_sim_time': True}]
        ),
        Node(
            package='demo_nodes_py',
            executable='listener',
            name='listener_node'
        )
    ])

Run the Launch File

ros2 launch launch_example.py

Parameters

# List parameters
ros2 param list

# Get a parameter
ros2 param get /talker_node use_sim_time

# Set a parameter
ros2 param set /talker_node use_sim_time false

## 5. DDS, QoS, and Real-Time Considerations

QoS Profiles

ROS 2 uses Quality of Service (QoS) policies to configure communication reliability, durability, and latency.

PolicyOptionsUse Case
ReliabilityRELIABLE, BEST_EFFORTSensor data (BEST_EFFORT), commands (RELIABLE)
DurabilityVOLATILE, TRANSIENT_LOCALMap data (TRANSIENT_LOCAL), telemetry (VOLATILE)
HistoryKEEP_LAST(n), KEEP_ALLLimited buffer (KEEP_LAST), full replay (KEEP_ALL)

Example: Configuring QoS in Python

from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy

qos_profile = QoSProfile(
    reliability=ReliabilityPolicy.RELIABLE,
    history=HistoryPolicy.KEEP_LAST,
    depth=10
)

self.publisher = self.create_publisher(
    String,
    'topic',
    qos_profile
)

Real-Time Setup

  1. Use a real-time kernel:
    sudo apt install linux-image-rt-amd64
    
  2. Configure DDS for real-time:
    • Use rmw_connextdds or rmw_cyclonedds with real-time settings.
    • Example cyclonedds.xml:
      <CycloneDDS>
          <Domain>
              <General>
                  <NetworkInterfaceAddress>lo</NetworkInterfaceAddress>
                  <AllowMulticast>false</AllowMulticast>
              </General>
              <Tracing>
                  <Verbosity>warning</Verbosity>
              </Tracing>
          </Domain>
      </CycloneDDS>
      
  3. Set thread priorities:
    rclcpp::ExecutorOptions options;
    options.context = rclcpp::Context::make_shared();
    options.context->init(0, nullptr, rclcpp::InitOptions().use_real_time());
    rclcpp::executors::SingleThreadedExecutor executor(options);
    

## 6. ros2_control and Hardware Interfaces

Overview

ros2_control is a framework for real-time control of robot hardware. It separates hardware interfaces from control algorithms.

Example: URDF with ros2_control

<robot name="my_robot">
  <ros2_control name="MyRobotSystem" type="system">
    <hardware>
      <plugin>my_robot_hardware/MyRobotSystemHardware</plugin>
    </hardware>
    <joint name="joint1">
      <command_interface name="position"/>
      <state_interface name="position"/>
      <state_interface name="velocity"/>
    </joint>
  </ros2_control>
</robot>

Launch File for ros2_control

from launch import LaunchDescription
from launch_ros.actions import Node
from launch_ros.substitutions import FindPackageShare
from launch.substitutions import PathJoinSubstitution

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='controller_manager',
            executable='ros2_control_node',
            parameters=[PathJoinSubstitution([
                FindPackageShare('my_robot_description'),
                'config',
                'my_robot_controllers.yaml'
            ])]
        ),
        Node(
            package='controller_manager',
            executable='spawner',
            arguments=['joint_state_broadcaster']
        ),
        Node(
            package='controller_manager',
            executable='spawner',
            arguments=['joint_trajectory_controller']
        )
    ])

## 7. Debugging with rqt, ros2 bag, and rviz2

rqt (GUI Tools)

# Launch rqt
rqt

# Common plugins:
# - Topic Monitor (/rqt_topic)
# - Service Caller (/rqt_service_caller)
# - Node Graph (/rqt_graph)

ros2 bag (Recording/Playback)

# Record topics
ros2 bag record /scan /odom

# Play back
ros2 bag play rosbag2_2026_06_02-12_00_00

# Info
ros2 bag info rosbag2_2026_06_02-12_00_00

rviz2 (Visualization)

# Launch RViz2
rviz2

إفصاح عن الذكاء الاصطناعي: أُنشئت هذه المقالة بمساعدة الذكاء الاصطناعي ولم تخضع لمراجعة بشرية فردية. استُخدمت أدوات الذكاء الاصطناعي في البحث والصياغة والتحرير. تعامل مع التفاصيل كنقطة انطلاق وتحقّق من أي معلومة تنوي الاعتماد عليها.

المصادر

  1. https://docs.ros.org
  2. ROS 2 Jazzy requirements
مشاركة:
رؤى أسبوعية في الذكاء الاصطناعي

The AI Dispatch

من العرض التوضيحي إلى التشغيل الموثوق. احصل أسبوعياً على مذكرة قرار لمنتجات Physical AI.

يمكنك إلغاء الاشتراك في أي وقت. لا بريد مزعج، أبداً.

هل يكشف هذا عن قرار منتج؟

أحضر القرار والموعد النهائي والأدلة المتاحة. سيوجهك نموذج التواصل إلى أصغر خطوة تالية مفيدة.

ناقشوا قرار المنتج