ROS2 Architecture and Core Tools
This article provides in-depth technical notes on the ROS2 system architecture and key software stacks. For ROS history and basic installation, see the ROS section in Simulation Platforms.
ROS2 System Architecture
Communication Middleware: DDS
The core design decision of ROS2 is adopting DDS (Data Distribution Service) as the communication middleware. DDS is a real-time data distribution standard defined by the OMG organization, with the following features:
| Feature | Description |
|---|---|
| Decentralized | No Master node required; automatic discovery via Simple Discovery Protocol (SDP) |
| QoS Policies | Configurable reliability (Reliable/Best-Effort), durability (Transient Local/Volatile), history depth, etc. |
| Real-time | Supports deterministic latency, suitable for hard real-time scenarios |
| Security | DDS-Security plugin supports authentication, access control, and data encryption |
Common DDS implementations:
| DDS Implementation | Maintainer | Features | Recommended Scenario |
|---|---|---|---|
| Cyclone DDS | Eclipse Foundation | Default in ROS2 Humble, stable | General development |
| Fast DDS | eProsima | Most feature-complete, formerly the default | Full DDS feature set needed |
| Connext DDS | RTI | Commercial, high certification level | Industrial/military deployment |
| Zenoh | Eclipse (experimental) | Not DDS, but ROS2 adaptation in progress | Cross-network/cloud-edge collaboration |
ROS2 Node Communication Patterns
graph TB
subgraph Node_A["Node A (Perception)"]
PA[Publisher<br/>/camera/image]
CA[Client<br/>/detect_object]
end
subgraph Node_B["Node B (Planning)"]
SB[Subscriber<br/>/camera/image]
SRV[Service Server<br/>/detect_object]
AC[Action Client<br/>/navigate_to]
end
subgraph Node_C["Node C (Navigation)"]
AS[Action Server<br/>/navigate_to]
PC[Publisher<br/>/cmd_vel]
end
subgraph Node_D["Node D (Chassis)"]
SD[Subscriber<br/>/cmd_vel]
end
PA -- "Topic (async)" --> SB
CA -- "Service (sync request-response)" --> SRV
AC -- "Action (async + feedback)" --> AS
PC -- "Topic" --> SD
style Node_A fill:#e1f5fe
style Node_B fill:#fff3e0
style Node_C fill:#e8f5e9
style Node_D fill:#fce4ec
Four Communication Patterns in Detail
1. Topic: Asynchronous publish-subscribe, one-to-many
# Publisher
self.pub = self.create_publisher(Twist, '/cmd_vel', 10)
msg = Twist()
msg.linear.x = 0.5
self.pub.publish(msg)
# Subscriber
self.sub = self.create_subscription(Twist, '/cmd_vel', self.callback, 10)
2. Service: Synchronous request-response, one-to-one
# Service Server
self.srv = self.create_service(SetBool, '/enable_motor', self.handle)
# Service Client
self.cli = self.create_client(SetBool, '/enable_motor')
future = self.cli.call_async(request)
3. Action: Asynchronous + feedback + cancellable, suitable for long-running tasks
# Action Server
self._action_server = ActionServer(
self, NavigateToPose, 'navigate_to_pose', self.execute_callback)
# Send feedback in the execute callback
feedback_msg.distance_remaining = distance
goal_handle.publish_feedback(feedback_msg)
4. Parameter: Dynamic node parameter configuration
ros2 param set /my_node max_speed 1.5
ros2 param get /my_node max_speed
QoS Configuration Policies
QoS policies are critical for robot systems; incorrect configuration can cause topics to fail to communicate:
| QoS Policy | Sensor Data Recommended | Control Command Recommended | Map Data Recommended |
|---|---|---|---|
| Reliability | Best Effort | Reliable | Reliable |
| Durability | Volatile | Volatile | Transient Local |
| History Depth | 1-5 | 1 | 1 |
| Deadline | 33ms (30Hz) | 10ms (100Hz) | N/A |
Key Packages
ros2_control: Hardware Abstraction Layer
ros2_control is the hardware abstraction framework for ROS2, decoupling hardware interfaces from control algorithms.
Core Components:
- Controller Manager: Daemon for loading/unloading/switching controllers
- Hardware Interface: Abstracts hardware into Command/State interfaces
- Controllers: Receive commands and output control signals
Hardware Interface Types:
| Interface Type | Semantics | Example |
|---|---|---|
hardware_interface::HI_POSITION |
Position command | Joint angle (rad) |
hardware_interface::HI_VELOCITY |
Velocity command | Joint angular velocity (rad/s) |
hardware_interface::HI_EFFORT |
Force/torque command | Joint torque (Nm) |
Common Controllers:
controller_manager:
ros__parameters:
update_rate: 500 # Hz
joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster
arm_controller:
type: joint_trajectory_controller/JointTrajectoryController
gripper_controller:
type: position_controllers/GripperActionController
Custom Hardware Interface Example:
class MyRobotHardware : public hardware_interface::SystemInterface {
CallbackReturn on_activate(const rclcpp_lifecycle::State &) override {
// Initialize serial/CAN communication
serial_port_.open("/dev/ttyUSB0", 115200);
return CallbackReturn::SUCCESS;
}
hardware_interface::return_type read(
const rclcpp::Time &, const rclcpp::Duration &) override {
// Read joint states from encoders
for (size_t i = 0; i < num_joints_; i++) {
hw_states_position_[i] = serial_port_.read_encoder(i);
hw_states_velocity_[i] = serial_port_.read_velocity(i);
}
return hardware_interface::return_type::OK;
}
hardware_interface::return_type write(
const rclcpp::Time &, const rclcpp::Duration &) override {
// Send commands to motors
for (size_t i = 0; i < num_joints_; i++) {
serial_port_.send_command(i, hw_commands_position_[i]);
}
return hardware_interface::return_type::OK;
}
};
MoveIt 2: Motion Planning Framework
MoveIt 2 is the most widely used motion planning framework for robot arms in ROS2, providing a complete pipeline from path planning to trajectory execution.
Core Modules:
| Module | Function | Key Algorithms |
|---|---|---|
| Motion Planning | Path planning | OMPL (RRT, PRM, BIT*), Pilz Industrial Planner |
| Kinematics | Forward/inverse kinematics | KDL, TRAC-IK, IKFast (analytical solutions) |
| Collision Checking | Collision detection | FCL (Flexible Collision Library) |
| Servo | Real-time Cartesian control | Incremental IK, supports joystick/keyboard |
| MoveIt Task Constructor | Multi-stage tasks | Cascaded planning of subtasks |
OMPL Planner Selection Guide:
| Planner | Features | Suitable Scenarios |
|---|---|---|
| RRTConnect | Bidirectional RRT, fast | General purpose (default) |
| RRT* | Asymptotically optimal | High-quality paths needed |
| PRM* | Pre-built roadmap | Repeated planning in same space |
| BIT* | Batch-informed sampling optimal | Optimal planning in high-dimensional spaces |
| CHOMP | Optimization-based | Smooth trajectories |
MoveIt Servo is suitable for teleoperation and visual servoing, receiving incremental commands at 100-1000Hz:
# Send Cartesian incremental commands
twist_msg = TwistStamped()
twist_msg.header.frame_id = "tool0"
twist_msg.twist.linear.x = 0.01 # 10mm/cycle
twist_msg.twist.angular.z = 0.05 # rad/cycle
servo_twist_pub.publish(twist_msg)
For more on motion planning theory, see Motion Planning.
Nav2: Autonomous Navigation Stack
Nav2 is the navigation framework for ROS2, primarily used for autonomous navigation of mobile robots.
Architecture Layers:
| Layer | Component | Function |
|---|---|---|
| Perception | Costmap 2D | Multi-layer costmap (static layer, obstacle layer, inflation layer) |
| Global Planning | Planner Server | Generate global paths |
| Local Control | Controller Server | Path tracking, obstacle avoidance |
| Behavior | Behavior Server | Recovery behaviors (spin, backup, wait) |
| Navigation Management | BT Navigator | Behavior tree coordinating the entire navigation flow |
Global Planner Comparison:
| Planner | Algorithm | Features | Suitable Scenarios |
|---|---|---|---|
| NavFn | Dijkstra/A* | Classic, stable | General navigation |
| SMAC 2D | A* variant | More heuristics | 2D map navigation |
| SMAC Hybrid-A* | Hybrid A* | Considers kinematic constraints | Ackermann steering vehicles |
| SMAC Lattice | State lattice | Custom motion primitives | Non-standard motion models |
| Theta* | Theta* | Any-angle paths | Smooth paths needed |
Local Controller Comparison:
| Controller | Algorithm | Features | Suitable Scenarios |
|---|---|---|---|
| DWB | Dynamic Window | Classic, stable | Differential/omnidirectional mobile bases |
| RPP | Regulated Pure Pursuit | Curvature regulation | Outdoor/high-speed scenarios |
| MPPI | Model Predictive Path Integral | GPU-accelerated, learnable costs | Complex terrain, optimal control needed |
| Rotation Shim | In-place rotation preprocessing | Used with other controllers | Narrow corridor startup |
# Nav2 parameter configuration example
controller_server:
ros__parameters:
controller_frequency: 20.0
FollowPath:
plugin: "dwb_core::DWBLocalPlanner"
max_vel_x: 0.5
max_vel_theta: 1.0
critics: ["RotateToGoal", "Oscillation", "ObstacleFootprint", "PathAlign", "PathDist", "GoalDist"]
For more SLAM-related content, see SLAM.
Micro-ROS: Embedded ROS2
Micro-ROS brings ROS2 communication capabilities to the microcontroller (MCU) level, based on micro-XRCE-DDS.
Supported Hardware Platforms:
| Platform | Chip Example | RTOS | Features |
|---|---|---|---|
| ESP32 | ESP32-S3 | FreeRTOS | Low cost, built-in WiFi |
| STM32 | STM32F4/F7/H7 | FreeRTOS/Zephyr | Industrial-grade, rich peripherals |
| Teensy | Teensy 4.1 (Cortex-M7) | FreeRTOS | High performance, Arduino compatible |
| Raspberry Pi Pico | RP2040 | FreeRTOS | Ultra-low cost |
Typical Applications: Making IMUs, encoders, and motor drivers directly participate in ROS2 communication as nodes.
// Micro-ROS on ESP32: Publish IMU data
rcl_publisher_t imu_publisher;
sensor_msgs__msg__Imu imu_msg;
void timer_callback(rcl_timer_t * timer, int64_t last_call_time) {
read_mpu6050(&imu_msg);
rcl_publish(&imu_publisher, &imu_msg, NULL);
}
Agent Mode: The MCU connects to the micro-ROS Agent running on the host via serial/WiFi/USB. The Agent bridges data to the full DDS network.
# Start micro-ROS Agent
ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0 -b 115200
Common CLI Tools
# Node management
ros2 node list
ros2 node info /my_node
# Topic debugging
ros2 topic list
ros2 topic echo /cmd_vel
ros2 topic hz /camera/image_raw # Check publish frequency
ros2 topic bw /pointcloud # Check bandwidth
# Service calls
ros2 service call /set_mode std_srvs/srv/SetBool "{data: true}"
# Action monitoring
ros2 action list
ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose "{...}"
# TF debugging
ros2 run tf2_tools view_frames # Generate TF tree PDF
ros2 run tf2_ros tf2_echo base_link camera_link
# Launch files
ros2 launch my_package my_launch.py
# Record and playback
ros2 bag record -a -o my_bag
ros2 bag play my_bag
Development Best Practices
- Use Launch files to manage nodes: Avoid manually starting nodes one by one
- Leverage QoS configuration: Use Best Effort for sensors, Reliable for control commands
- Lifecycle nodes: Use managed nodes to control node lifecycle (unconfigured -> inactive -> active)
- Composition: Load multiple nodes into the same process to reduce serialization overhead
- Use colcon to build:
colcon build --symlink-installsupports Python hot-reloading
Related Resources
- ROS2 Official Documentation
- ros2_control Documentation
- MoveIt 2 Documentation
- Nav2 Documentation
- Related notes: Motion Planning | SLAM | Development Toolchain