This repository provides experimental real-time extensions for ROS 2.
It extends the ROS 2 Client Libraries with real-time–oriented capabilities, such as configurable thread attributes and scheduling behavior, while abstracting RTOS-specific thread APIs behind a common interface.
The work in this repository is based on the concept proposed in REP-2017.
Originally, real-time–related functionality was planned as an extension to core ROS 2 packages (e.g., rcl, rclcpp).
Community discussions, including feedback from the PTC, concluded that such functionality would be difficult to maintain within the core.
As a result, these capabilities are provided as a separate package set, allowing independent evolution while keeping the ROS 2 core lightweight.
The repository provides experimental real-time extensions for ROS 2, with a focus on thread configuration, scheduling control, and RTOS portability.
- External YAML-based real-time configuration is supported.
- Thread attributes can be applied to Executors at runtime.
- POSIX is used as the initial reference backend.
rcl_realtimebased on rcl/rcl- Introcudes a dedicated context for real-time configuration.
- Provides APIs for loading and accessing real-time settings (e.g., thread attributes).
rcl_realtime_yaml_param_parserbased on rcl/rcl_yaml_param_parser- Implements a YAML-based configuration parser for real-time settings.
- Designed to decouple configuration formats from core logic.
rcutils_realtimebased on rcutils- Introduces common data structures for representing thread attributes (priority, affinity, scheduling policy, etc.).
rclcpp_realtimebased on rclcpp/rclcpp (reference implementation)- Provides a thread-based Executor capable of applying real-time configuration.
- Extends execution behavior based on the real-time context added to
rcl. - Serves as a demonstration and validation implementation, not a drop-in replacement for all Executors.
rcpputils_realtimebased on rcpputils- Implements an abstraction layer over OS-specific thread APIs.
- Currently supports POSIX-based APIs only.
- Improve documentation
- Add API documentation
- Document configuration usage
- Executor-based configuration
- YAML-based configuration
-
rosparam-based configuration
- Provide sample programs and usage examples
- Expand test coverage
- Add additional API tests
- Verify interoperability between
rclandrclcppAPIs
- Add git history for copied files and improve traceability
- Extend backend support to additional platforms and RTOS environments (e.g., Windows, macOS, QNX, VxWorks, eMCOS POSIX, Zephyr)
- Replace
std::thread,std::mutex, andstd::condition_variablewith implementations that expose and utilizenative_handle - Apply and validate real-time configurations for ROS message communication mechanisms
- Compare implementation details and performance with existing publicly available executors
This section introduces an example of modifying the official ROS 2 tutorial
Writing a simple publisher and subscriber (C++).
Note
This example demonstrates the "YAML-based configuration" described in the TODO list. Thread attributes are applied to existing ROS 2 nodes by specifying configurations via a YAML file and executing the nodes with a newly developed executor.
First, clone this repository into the same workspace.
Next, add rclcpp_realtime alongside rclcpp in package.xml and CMakeLists.txt.
package.xml
<depend>rclcpp</depend>
+<depend>rclcpp_realtime</depend>CMakeLists.txt
find_package(rclcpp REQUIRED)
+find_package(rclcpp_realtime REQUIRED)-ament_target_dependencies(talker rclcpp std_msgs)
+ament_target_dependencies(talker rclcpp rclcpp_realtime std_msgs)Then modify the C++ source code as follows.
publisher_lambda_function.cpp
#include "rclcpp/rclcpp.hpp"
+#include "rclcpp_realtime/node.hpp"
+#include "rclcpp_realtime/utilities.hpp"
+#include "rclcpp_realtime/sched_param_executor.hpp"
#include "std_msgs/msg/string.hpp"-class MinimalPublisher : public rclcpp::Node
+class MinimalPublisher : public rclcpp_realtime::Nodeint main(int argc, char * argv[])
{
- rclcpp::init(argc, argv);
- rclcpp::spin(std::make_shared<MinimalPublisher>());
- rclcpp::shutdown();
+ rclcpp_realtime::init(argc, argv);
+ auto node = std::make_shared<MinimalPublisher>();
+ auto options = rclcpp_realtime::SchedParamExecutorOptions();
+ rclcpp_realtime::SchedParamSingleThreadedExecutor executor(options);
+ executor.add_node(node);
+ executor.spin();
+ rclcpp_realtime::shutdown();
return 0;
}After building the workspace and applying the environment variables, run the node.
ros2 run cpp_pubsub talkerFrom another terminal, check the thread attributes.
$ ps -eLo pid,tid,class,rtprio,ni,pri,psr,comm | grep talker
2149 2149 TS - 0 19 8 talker
2149 2150 TS - 0 19 16 talker-ust
2149 2151 TS - 0 19 3 talker-ust
2149 2152 TS - 0 19 18 talker
2149 2153 TS - 0 19 5 talker
2149 2163 TS - 0 19 3 talkerNext, define the following YAML file in your workspace.
- priority: 10
tag: RCLCPP_EXECUTOR_SINGLE_THREADED
core_affinity: []
scheduling_policy: RRSet the environment variable and run the same command again.
export ROS_THREAD_ATTRS_FILE=<YAML_CONFIG_FILE_PATH>
ros2 run cpp_pubsub talkerYou can now confirm that thread attributes have been applied to the threads running within ROS.
$ ps -eLo pid,tid,class,rtprio,ni,pri,psr,comm | grep talker
3962 3962 TS - 0 19 7 talker
3962 3963 TS - 0 19 10 talker-ust
3962 3964 TS - 0 19 19 talker-ust
3962 3965 TS - 0 19 20 talker
3962 3966 TS - 0 19 11 talker
3962 3976 TS - 0 19 19 talker
3962 3977 RR 10 - 50 20 talkerThis work was supported by the New Energy and Industrial Technology Development Organization (NEDO), Japan, under commissioned research project JPNP25016.