Skip to main content

Chapter 4: ROS 2 Fundamentals

Introduction

Robot Operating System 2 (ROS 2) represents a fundamental evolution in robotics middleware, addressing the limitations of ROS 1 while maintaining its core philosophy of code reuse in robotics. ROS 2 is built from the ground up for real-world applications, featuring real-time capabilities, security, and support for multi-robot systems. This chapter introduces the fundamental concepts and architecture of ROS 2, providing the foundation for building complex robotic systems.

ROS 2 is not an operating system but a middleware framework that provides services like hardware abstraction, device drivers, libraries, visualizers, message-passing, package management, and more.

4.1 ROS 2 Architecture Overview

4.1.1 Evolution from ROS 1 to ROS 2

ROS 2 addresses critical limitations in ROS 1 while introducing significant architectural improvements:

Diagram: ROS 1 vs ROS 2 Architecture

ROS 1 Architecture                    ROS 2 Architecture
┌─────────────────────────┐         ┌─────────────────────────┐
│ ROS Master              │         │ DDS (Data Distribution) │
│ (Centralized)           │         │ (Decentralized)         │
│    ↕    ↕    ↕          │         │    ↕    ↕    ↕          │
┌───────┬───────┬───────┐   →    ┌───────┬───────┬───────┐
│ Node A│ Node B│ Node C│       │ Node A│ Node B│ Node C│
└───────┴───────┴───────┘       └───────┴───────┴───────┘
                                │    ↕    ↕    ↕          │
                                └─────────────────────────┘
                                   Discovery, Communication
                                   Security, Real-time

4.1.2 Key Architectural Improvements

Decentralized Communication

  • No single point of failure
  • Dynamic node discovery
  • Native support for multi-robot systems

Real-time Capabilities

  • Real-time transport support
  • Deterministic scheduling
  • Bounded latency communication

Security

  • Authentication and authorization
  • Encrypted communication
  • Access control mechanisms

Cross-platform Support

  • Windows, macOS, Linux support
  • Embedded system deployment
  • Real-time operating systems

4.1.3 DDS-based Communication

ROS 2 uses Data Distribution Service (DDS) as its underlying communication middleware:

Diagram: DDS Communication Architecture

┌─────────────────────────────────────────────────────────────┐
│                        DDS Domain                           │
│                                                             │
│  ┌─────────────┐   Publisher   ┌─────────────┐            │
│  │   Node A    │ ──────────→   │   Node B    │            │
│  │             │               │             │            │
│  │ Publisher   │               │ Subscriber  │            │
│  │ Subscriber  │               │ Publisher   │            │
│  └─────────────┘ ←─────────── └─────────────┘            │
│         │                            │                    │
│         ↕                            ↕                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              DDS Infrastructure                     │   │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐             │   │
│  │  │ RTPS    │  │ Discovery│  │Security │             │   │
│  │  │ Protocol│  │ Service  │  │ Service  │             │   │
│  │  └─────────┘  └─────────┘  └─────────┘             │   │
│  └─────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────┘

4.2 Core ROS 2 Concepts

4.2.1 Nodes

Nodes are the fundamental units of computation in ROS 2:

Node Definition A node is a process that performs computation and communicates with other nodes:

Example: Basic ROS 2 Node in C++


class MinimalNode : public rclcpp::Node {
public:
    MinimalNode() : Node("minimal_node") {
        // Initialize node
        RCLCPP_INFO(this->get_logger(), "Minimal node has been started");

        // Create a timer for periodic work
        timer_ = this->create_wall_timer(
            std::chrono::milliseconds(500),
            std::bind(&MinimalNode::timer_callback, this));
    }

private:
    void timer_callback() {
        RCLCPP_INFO(this->get_logger(), "Hello from minimal node!");
    }

    rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char** argv) {
    rclcpp::init(argc, argv);

    auto node = std::make_shared<MinimalNode>();

    rclcpp::spin(node);

    rclcpp::shutdown();
    return 0;
}

Example: Basic ROS 2 Node in Python

from rclpy.node import Node

class MinimalNode(Node):
    def __init__(self):
        super().__init__('minimal_node')

        self.get_logger().info('Minimal node has been started')

        # Create a timer for periodic work
        self.timer = self.create_timer(0.5, self.timer_callback)

    def timer_callback(self):
        self.get_logger().info('Hello from minimal node!')

def main(args=None):
    rclpy.init(args=args)

    node = MinimalNode()

    rclpy.spin(node)

    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

Node Characteristics

  • Independent processes with their own memory space
  • Can be written in different programming languages
  • Communicate through DDS-based middleware
  • Can be distributed across multiple machines

4.2.2 Topics

Topics provide named buses for anonymous message exchange:

Diagram: Topic-based Communication

               Topic: "/robot/joint_states"
                         ↕
┌─────────────┐   Publish   ┌─────────────┐   Subscribe   ┌─────────────┐
│Joint State  │ ──────────→ │  Other      │ ←──────────── │Robot Control│
│  Publisher  │             │   Nodes     │               │   Node      │
└─────────────┘             └─────────────┘               └─────────────┘
      ↕                           ↕                           ↕
┌─────────────┐   Subscribe   ┌─────────────┐   Publish   ┌─────────────┐
│   RViz      │ ←──────────── │Motion Planner│ ──────────→ │Simulation   │
│  Visualizer │               │   Node      │             │   Node      │
└─────────────┘               └─────────────┘             └─────────────┘

Topic Properties

  • Named communication channels
  • Anonymous publish/subscribe model
  • Type-safe message passing
  • Many-to-many communication

Example: Publisher and Subscriber Example

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

class PublisherNode(Node):
    def __init__(self):
        super().__init__('publisher_node')

        # Create publisher
        self.publisher_ = self.create_publisher(
            String, 'test_topic', 10)

        # Create timer for periodic publishing
        self.timer = self.create_timer(1.0, self.publish_message)
        self.count = 0

    def publish_message(self):
        msg = String()
        msg.data = f'Hello ROS 2! Count: {self.count}'
        self.publisher_.publish(msg)
        self.count += 1
        self.get_logger().info(f'Published: {msg.data}')

class SubscriberNode(Node):
    def __init__(self):
        super().__init__('subscriber_node')

        # Create subscriber
        self.subscription = self.create_subscription(
            String, 'test_topic', self.listener_callback, 10)

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

4.2.3 Services

Services provide request-response communication for synchronous operations:

Diagram: Service Call Architecture

Client Node                    Server Node
┌─────────────┐                ┌─────────────┐
│    Call     │ Request/Response│    Service  │
│ Service     │ ──────────────→ │    Handler  │
│             │                │             │
│   Response  │ ←────────────── │   Process   │
│   Wait      │                │             │
└─────────────┘                └─────────────┘

Example: Service Example


class ServiceNode(Node):
    def __init__(self):
        super().__init__('service_node')

        # Create service
        self.service = self.create_service(
            AddTwoInts, 'add_two_ints', self.add_two_ints_callback)

        self.get_logger().info('Service ready')

    def add_two_ints_callback(self, request, response):
        response.sum = request.a + request.b
        self.get_logger().info(
            f'Incoming request: {request.a} + {request.b} = {response.sum}')

        return response

class ClientNode(Node):
    def __init__(self):
        super().__init__('client_node')

        # Create client
        self.client = self.create_client(AddTwoInts, 'add_two_ints')

        # Wait for service to be available
        while not self.client.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Service not available, waiting...')

    def send_request(self, a, b):
        request = AddTwoInts.Request()
        request.a = a
        request.b = b

        future = self.client.call_async(request)
        return future

4.2.4 Actions

Actions provide long-running, preemptable, and cancelable asynchronous operations:

Diagram: Action Client/Server Architecture

Action Client                    Action Server
┌─────────────┐                ┌─────────────┐
│   Send      │    Goal       │    Accept   │
│   Goal      │ ──────────────→ │   Goal      │
│             │                │             │
│   Receive   │ Feedback       │    Send     │
│  Feedback   │ ←────────────── │  Feedback   │
│             │                │             │
│   Receive   │   Result       │    Send     │
│   Result    │ ←────────────── │   Result    │
└─────────────┘                └─────────────┘
     ↕   ↕
Preempt/Cancel

Example: Action Server Example

from action_msgs.msg import GoalStatus
from rclpy.action import ActionServer
from my_interface.action import Fibonacci

class ActionServerNode(Node):
    def __init__(self):
        super().__init__('action_server_node')

        # Create action server
        self.action_server = ActionServer(
            self, Fibonacci, 'fibonacci',
            self.execute_callback)

    def execute_callback(self, goal_handle):
        self.get_logger().info('Executing goal...')

        feedback_msg = Fibonacci.Feedback()
        feedback_msg.partial_sequence = [0, 1]

        # Execute long-running task
        for i in range(1, goal_handle.request.order):
            # Check for cancellation
            if goal_handle.is_cancel_requested:
                goal_handle.canceled()
                return Fibonacci.Result()

            # Compute next Fibonacci number
            next_num = feedback_msg.partial_sequence[-1] + \
                      feedback_msg.partial_sequence[-2]
            feedback_msg.partial_sequence.append(next_num)

            # Send feedback
            goal_handle.publish_feedback(feedback_msg)

            # Simulate work
            self.get_clock().sleep_for(0.5)

        goal_handle.succeed()

        result = Fibonacci.Result()
        result.sequence = feedback_msg.partial_sequence
        return result

4.3 Quality of Service (QoS) Policies

4.3.1 QoS Overview

QoS policies control how data is exchanged between nodes, enabling fine-tuned control over reliability, durability, and latency:

Diagram: QoS Policy Impact

     Publisher                         Subscriber
┌───────────────────┐            ┌───────────────────┐
│    QoS Settings   │            │    QoS Settings   │
│  ┌─────────────┐  │            │  ┌─────────────┐  │
│  │ Reliability │  │            │  │ Reliability │  │
│  └─────────────┘  │            │  └─────────────┘  │
│  ┌─────────────┐  │            │  ┌─────────────┐  │
│  │ Durability  │  │            │  │ Durability  │  │
│  └─────────────┘  │            │  └─────────────┘  │
│  ┌─────────────┐  │            │  ┌─────────────┐  │
│  │ Deadline    │  │            │  │ Deadline    │  │
│  └─────────────┘  │            │  └─────────────┘  │
│  ┌─────────────┐  │            │  ┌─────────────┐  │
│  │ Lifespan    │  │            │  │ Lifespan    │  │
│  └─────────────┘  │            │  └─────────────┘  │
└───────────────────┘            └───────────────────┘
         ↕                                 ↕
               Communication Channel
         ↕                                 ↕
    ┌─────────────────────────────────┐
    │        DDS Middleware           │
    │  Policy Negotiation & Enforcement│
    └─────────────────────────────────┘

4.3.2 Key QoS Policies

Reliability

  • BEST_EFFORT: Messages may be lost
  • RELIABLE: Guaranteed delivery (when possible)

Durability

  • VOLATILE: Only current subscribers receive messages
  • TRANSIENT_LOCAL: Late-joining subscribers receive last message

Deadline

  • Maximum time between consecutive messages

Lifespan

  • Maximum time a message is considered valid

Example: QoS Configuration


# Custom QoS profile for sensor data
sensor_qos = QoSProfile(
    depth=10,
    reliability=QoSReliabilityPolicy.BEST_EFFORT,  # Allow some loss
    durability=QoSDurabilityPolicy.VOLATILE,       # Only new data
)

# QoS for control commands
control_qos = QoSProfile(
    depth=10,
    reliability=QoSReliabilityPolicy.RELIABLE,     # Must arrive
    durability=QoSDurabilityPolicy.TRANSIENT_LOCAL, # Keep last state
)

# Create publisher with custom QoS
publisher = node.create_publisher(
    String, 'control_topic',
    qos_profile=control_qos)

4.3.3 Common QoS Profiles

ROS 2 provides predefined QoS profiles:

Diagram: Common QoS Profiles

SENSOR_DATA Profile
├── Reliability: BEST_EFFORT
├── Durability: VOLATILE
├── Deadline: (disabled)
└── Lifespan: (disabled)
Use Cases: Camera images, LiDAR scans

DEFAULT Profile
├── Reliability: RELIABLE
├── Durability: VOLATILE
├── Deadline: (disabled)
└── Lifespan: (disabled)
Use Cases: General communication

PARAMETERS Profile
├── Reliability: RELIABLE
├── Durability: TRANSIENT_LOCAL
├── Deadline: (disabled)
└── Lifespan: (disabled)
Use Cases: Parameter updates

SERVICES Profile
├── Reliability: RELIABLE
├── Durability: VOLATILE
├── Deadline: (disabled)
└── Lifespan: (disabled)
Use Cases: Service calls

4.4 ROS 2 Workspace and Packages

4.4.1 Workspace Structure

A ROS 2 workspace organizes packages and builds them efficiently:

Diagram: ROS 2 Workspace Structure

ros2_ws/                          # Workspace root
├── src/                          # Source packages
│   ├── package_1/                # Package directory
│   │   ├── include/              # Header files
│   │   ├── src/                  # Source files
│   │   ├── launch/               # Launch files
│   │   ├── config/               # Configuration files
│   │   ├── CMakeLists.txt        # CMake configuration
│   │   └── package.xml          # Package metadata
│   └── package_2/
├── build/                        # Build artifacts
├── install/                      # Install files
├── log/                          # Build logs
└── devel/                        # Development files

4.4.2 Creating a Package

Example: Creating a ROS 2 Package

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

# Create package with dependencies
ros2 pkg create --build-type ament_cmake \
    --dependencies rclcpp std_msgs \
    my_robot_package

# Create Python package
ros2 pkg create --build-type ament_python \
    --dependencies rclpy std_msgs \
    my_python_package

# Navigate to workspace
cd ~/ros2_ws

# Build the workspace
colcon build --packages-select my_robot_package

# Source the workspace
source install/setup.bash

4.4.3 Package Configuration

CMakeLists.txt for C++ packages

cmake_minimum_required(VERSION 3.8)
project(my_robot_package)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# Find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

# Add executable
add_executable(my_node src/my_node.cpp)

# Target specific includes and libraries
ament_target_dependencies(my_node rclcpp std_msgs)

# Install targets
install(TARGETS my_node
  DESTINATION lib/${PROJECT_NAME}
)

ament_package()

package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>my_robot_package</name>
  <version>0.0.0</version>
  <description>Example ROS 2 package</description>
  <maintainer email="developer@example.com">Developer</maintainer>
  <license>Apache-2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>rclcpp</depend>
  <depend>std_msgs</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>
</CodeBlock>

## 4.5 Launch System

### 4.5.1 Launch Files

Launch files coordinate multiple nodes and configure their behavior:

**Example: Python Launch File**

```pythonfrom launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_robot_package',
            executable='motor_controller',
            name='motor_controller',
            output='screen',
            parameters=[
                {'motor_ids': [1, 2, 3, 4]},
                {'max_speed': 10.0}
            ]
        ),
        Node(
            package='my_robot_package',
            executable='sensor_processor',
            name='sensor_processor',
            output='screen',
            remappings=[
                ('input_topic', '/raw_sensor_data'),
                ('output_topic', '/processed_data')
            ]
        ),
    ])

4.5.2 Launch Configuration

Example: Running Launch Files

ros2 launch my_robot_package my_robot_launch.py

# Launch with arguments
ros2 launch my_robot_package my_robot_launch.py \
    use_sim_time:=True \
    robot_name:=my_robot

# Include other launch files
ros2 launch my_robot_package main_launch.py \
    navigation:=true \
    perception:=false

4.6 Parameters and Configuration

4.6.1 Parameter System

ROS 2 provides a flexible parameter system for runtime configuration:

Example: Parameter Usage

from rclpy.node import Node

class ParameterNode(Node):
    def __init__(self):
        super().__init__('parameter_node')

        # Declare parameters with defaults
        self.declare_parameter('max_speed', 5.0)
        self.declare_parameter('safety_distance', 1.0)
        self.declare_parameter('use_sensors', True)

        # Get parameter values
        self.max_speed = self.get_parameter('max_speed').value
        self.safety_distance = self.get_parameter('safety_distance').value
        self.use_sensors = self.get_parameter('use_sensors').value

        # Set parameter callback
        self.add_on_set_parameters_callback(self.parameter_callback)

    def parameter_callback(self, params):
        """Handle parameter updates"""
        for param in params:
            if param.name == 'max_speed' and param.type_ == param.Type.DOUBLE:
                if param.value > 0.0 and param.value <= 20.0:
                    self.max_speed = param.value
                else:
                    return rclpy.ParameterDescriptor(
                        type_=param.Type.DOUBLE,
                        description='Maximum robot speed (0-20 m/s)')

        # Successfully updated
        return SetParametersResult(successful=True)

4.6.2 Parameter Files

YAML parameter files enable organized configuration:

Example: Parameter File (params.yaml)

  ros__parameters:
    motor_ids: [1, 2, 3, 4]
    max_speed: 10.0
    acceleration_limit: 5.0
    use_encoders: true
    safety_limits:
      max_current: 10.0
      max_temperature: 80.0

sensor_processing:
  ros__parameters:
    input_topics:
      - "/camera/image_raw"
      - "/lidar/scan"
      - "/imu/data"
    output_rate: 30.0
    filter_config:
      gaussian_kernel_size: 5
      edge_threshold: 100

Example: Loading Parameters

ros2 param load motor_controller /path/to/params.yaml

# Set individual parameters
ros2 param set /motor_controller max_speed 8.0

# List parameters
ros2 param list /motor_controller

# Get parameter value
ros2 param get /motor_controller max_speed

4.7 Real-world ROS 2 Applications

4.7.1 Mobile Robot Control

Example: Autonomous Mobile Robot

A ROS 2-based autonomous mobile robot system:

Hardware Abstraction Layer

  • Motor controller node (CAN bus interface)
  • Sensor driver nodes (LiDAR, cameras, IMU)
  • Power management node

Perception Stack

  • LiDAR processing and obstacle detection
  • Visual SLAM using camera data
  • Sensor fusion for robust localization

Planning and Control

  • Path planning using Nav2
  • Motion control with feedback
  • Safety monitoring and emergency stops

User Interface

  • Web-based control panel
  • RViz visualization
  • Remote monitoring

4.7.2 Manipulation System

Diagram: ROS 2 Manipulation Architecture

┌─────────────────────────────────────────────────────────────┐
│                     User Interface                          │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │ RViz    │  │Web UI   │  │Teleop   │  │Program  │        │
│  │Visual   │  │Control  │  │Interface│  │Interface│        │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
└─────────────────────────────────────────────────────────────┘
                              ↕
┌─────────────────────────────────────────────────────────────┐
│                    High-Level Control                        │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │Task     │  │Motion   │  │Grasp    │  │Safety   │        │
│  │Planner  │  │Planner  │  │Planner  │  │Monitor  │        │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
└─────────────────────────────────────────────────────────────┘
                              ↕
┌─────────────────────────────────────────────────────────────┐
│                    Low-Level Control                         │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │
│  │Joint    │  │Force    │  │PID      │  │Hardware │        │
│  │Control  │  │Control  │  │Control  │  │Drivers  │        │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │
└─────────────────────────────────────────────────────────────┘

4.8 Best Practices and Common Patterns

4.8.1 Node Design Patterns

Single Responsibility Principle

  • Each node performs one specific function
  • Clear interfaces between nodes
  • Modular and reusable design

Error Handling

  • Graceful degradation
  • Retry mechanisms
  • Emergency procedures

Resource Management

  • Efficient memory usage
  • Proper cleanup
  • Resource monitoring

4.8.2 Communication Patterns

Use topics for high-frequency data streaming, services for sporadic request-response communication, and actions for long-running operations with feedback.

Topic Naming Conventions

  • Use descriptive, hierarchical names
  • Follow ROS 2 naming guidelines
  • Include message type in documentation

QoS Best Practices

  • Match publisher and subscriber QoS
  • Consider network conditions
  • Balance reliability with performance

4.9 Debugging and Development Tools

4.9.1 Command Line Tools

Example: Essential ROS 2 Commands

ros2 node list                    # List running nodes
ros2 node info /node_name        # Node information
ros2 lifecycle                   # Lifecycle management

# Topic operations
ros2 topic list                   # List topics
ros2 topic echo /topic_name      # View topic messages
ros2 topic hz /topic_name        # Topic frequency
ros2 topic pub /topic_name ...   # Publish to topic

# Service operations
ros2 service list                 # List services
ros2 service call /service_name  # Call service
ros2 service type /service_name  # Service type

# Parameter operations
ros2 param list /node_name       # List parameters
ros2 param get /node_name param  # Get parameter
ros2 param set /node_name param  # Set parameter

# Action operations
ros2 action list                  # List actions
ros2 action send_goal /action_name # Send action goal

4.9.2 Visualization Tools

RViz2

  • 3D visualization
  • Plugin architecture
  • Custom displays

rqt

  • GUI framework
  • Various plugins
  • Custom interfaces

Summary

ROS 2 provides a robust foundation for building complex robotic systems with improved reliability, security, and real-time capabilities compared to ROS 1. Key concepts include decentralized communication through DDS, flexible QoS policies, and comprehensive development tools.

Key takeaways:

  • ROS 2 uses DDS for decentralized, real-time communication
  • QoS policies enable fine-tuned control over data exchange
  • Nodes, topics, services, and actions provide communication paradigms
  • Launch files coordinate multiple nodes and configurations
  • Parameter system enables runtime configuration
  • Comprehensive tooling supports development and debugging

Exercises

Exercise 4.1: Create a ROS 2 Package

Create a new ROS 2 package that implements:

  • A publisher node that publishes sensor data
  • A subscriber node that processes the data
  • A service node that provides configuration
  • Launch files to coordinate all nodes

Exercise 4.2: QoS Experiment

Implement a publisher/subscriber pair with different QoS settings:

  • Compare BEST_EFFORT vs RELIABLE reliability
  • Test VOLATILE vs TRANSIENT_LOCAL durability
  • Measure latency with different profiles
  • Analyze network behavior under load

Exercise 4.3: Multi-Node System

Design a multi-node system for a specific robot application:

  • Define node responsibilities and interfaces
  • Implement communication between nodes
  • Handle errors and failures gracefully
  • Test system performance

Exercise 4.4: Parameter Management

Create a configurable system using ROS 2 parameters:

  • Define parameter structure and defaults
  • Implement parameter callbacks
  • Create YAML configuration files
  • Test runtime parameter updates

Exercise 4.5: Action Server

Implement an action server for a long-running task:

  • Define custom action interface
  • Implement server with feedback
  • Create client with goal handling
  • Add cancellation and preemption support

Glossary Terms

  • DDS (Data Distribution Service): Middleware standard for real-time data distribution
  • Node: Process that performs computation and communicates in ROS 2
  • Topic: Named bus for anonymous message exchange
  • Service: Request-response communication pattern
  • Action: Long-running, preemptable asynchronous operations
  • QoS (Quality of Service): Policies controlling data exchange behavior
  • Launch File: Configuration file for starting multiple nodes
  • Parameter: Runtime configuration values for nodes
  • Workspace: Directory containing ROS 2 packages
  • Package: Organizational unit containing ROS 2 code and resources