diff --git a/cie_config_msgs/CMakeLists.txt b/cie_config_msgs/CMakeLists.txt
index 2cd6a5c..6ff3bd8 100644
--- a/cie_config_msgs/CMakeLists.txt
+++ b/cie_config_msgs/CMakeLists.txt
@@ -20,6 +20,9 @@ if(BUILD_TESTING)
ament_lint_auto_find_test_dependencies()
endif()
-rosidl_generate_interfaces(${PROJECT_NAME} "msg/CallbackGroupInfo.msg")
+rosidl_generate_interfaces(${PROJECT_NAME}
+ "msg/CallbackGroupInfo.msg"
+ "msg/NonRosThreadInfo.msg"
+)
ament_package()
diff --git a/cie_config_msgs/msg/NonRosThreadInfo.msg b/cie_config_msgs/msg/NonRosThreadInfo.msg
new file mode 100644
index 0000000..4005f8b
--- /dev/null
+++ b/cie_config_msgs/msg/NonRosThreadInfo.msg
@@ -0,0 +1,2 @@
+string thread_name
+int64 thread_id
diff --git a/cie_sample_application/CMakeLists.txt b/cie_sample_application/CMakeLists.txt
index 771b0b3..d8b2787 100644
--- a/cie_sample_application/CMakeLists.txt
+++ b/cie_sample_application/CMakeLists.txt
@@ -11,6 +11,7 @@ find_package(rclcpp_components REQUIRED)
find_package(std_msgs REQUIRED)
find_package(callback_isolated_executor REQUIRED)
+find_package(cie_thread_configurator REQUIRED)
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
@@ -26,15 +27,19 @@ endif()
include_directories(include)
add_library(sample_node SHARED src/sample_node.cpp)
-ament_target_dependencies(sample_node rclcpp rclcpp_components std_msgs)
+ament_target_dependencies(sample_node rclcpp rclcpp_components std_msgs cie_thread_configurator)
rclcpp_components_register_nodes(sample_node "SampleNode")
add_executable(sample_node_main src/sample_node_main.cpp)
target_link_libraries(sample_node_main sample_node)
ament_target_dependencies(sample_node_main rclcpp callback_isolated_executor)
+add_executable(sample_non_ros_process src/sample_non_ros_process.cpp)
+ament_target_dependencies(sample_non_ros_process cie_thread_configurator)
+
install(TARGETS
sample_node_main
+ sample_non_ros_process
DESTINATION lib/${PROJECT_NAME}
)
diff --git a/cie_sample_application/README.md b/cie_sample_application/README.md
index 700d65c..69be156 100644
--- a/cie_sample_application/README.md
+++ b/cie_sample_application/README.md
@@ -17,3 +17,10 @@ Or, load the node to the exsiting component container.
$ ros2 run callback_isolated_executor component_container_callback_isolated --ros-args --remap __node:=sample_container
$ ros2 launch cie_sample_application load_sample_node.launch.xml
```
+
+## Standalone Non-ROS Process
+```bash
+$ ros2 run cie_sample_application sample_non_ros_process
+```
+
+This demonstrates using `spawn_cie_thread` in a standalone process without any ROS2 node.
diff --git a/cie_sample_application/include/cie_sample_application/sample_node.hpp b/cie_sample_application/include/cie_sample_application/sample_node.hpp
index 709f139..741f175 100644
--- a/cie_sample_application/include/cie_sample_application/sample_node.hpp
+++ b/cie_sample_application/include/cie_sample_application/sample_node.hpp
@@ -7,11 +7,13 @@ class SampleNode : public rclcpp::Node {
public:
explicit SampleNode(
const rclcpp::NodeOptions &options = rclcpp::NodeOptions());
+ ~SampleNode();
private:
void timer_callback();
void timer_callback2();
void subscription_callback(const std_msgs::msg::Int32::SharedPtr msg);
+ void non_ros_thread_func(int value);
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::TimerBase::SharedPtr timer2_;
@@ -26,4 +28,6 @@ class SampleNode : public rclcpp::Node {
size_t count_;
size_t count2_;
+
+ std::thread non_ros_thread_;
};
diff --git a/cie_sample_application/package.xml b/cie_sample_application/package.xml
index 026e5da..fb2b800 100644
--- a/cie_sample_application/package.xml
+++ b/cie_sample_application/package.xml
@@ -24,6 +24,7 @@
std_msgs
callback_isolated_executor
+ cie_thread_configurator
ament_cmake
diff --git a/cie_sample_application/src/sample_node.cpp b/cie_sample_application/src/sample_node.cpp
index 27744be..ad9fab2 100644
--- a/cie_sample_application/src/sample_node.cpp
+++ b/cie_sample_application/src/sample_node.cpp
@@ -3,6 +3,7 @@
#include
#include "cie_sample_application/sample_node.hpp"
+#include "cie_thread_configurator/cie_thread_configurator.hpp"
#include "rclcpp_components/register_node_macro.hpp"
using namespace std::chrono_literals;
@@ -31,6 +32,15 @@ SampleNode::SampleNode(const rclcpp::NodeOptions &options)
std::bind(&SampleNode::subscription_callback, this,
std::placeholders::_1),
sub_options);
+
+ non_ros_thread_ = cie_thread_configurator::spawn_cie_thread(
+ "sample_non_ros_thread", &SampleNode::non_ros_thread_func, this, 42);
+}
+
+SampleNode::~SampleNode() {
+ if (non_ros_thread_.joinable()) {
+ non_ros_thread_.join();
+ }
}
void SampleNode::timer_callback() {
@@ -61,4 +71,13 @@ void SampleNode::subscription_callback(
msg->data);
}
+void SampleNode::non_ros_thread_func(int value) {
+ long tid = syscall(SYS_gettid);
+ for (int i = 0; i < 5; ++i) {
+ std::this_thread::sleep_for(2s);
+ RCLCPP_INFO(this->get_logger(), "Test thread running (tid=%ld), value: %d",
+ tid, value);
+ }
+}
+
RCLCPP_COMPONENTS_REGISTER_NODE(SampleNode)
diff --git a/cie_sample_application/src/sample_non_ros_process.cpp b/cie_sample_application/src/sample_non_ros_process.cpp
new file mode 100644
index 0000000..4398748
--- /dev/null
+++ b/cie_sample_application/src/sample_non_ros_process.cpp
@@ -0,0 +1,12 @@
+#include
+
+#include "cie_thread_configurator/cie_thread_configurator.hpp"
+
+void worker_function() { std::cout << "Worker thread running" << std::endl; }
+
+int main(int /*argc*/, char ** /*argv*/) {
+ auto thread = cie_thread_configurator::spawn_cie_thread("standalone_worker",
+ worker_function);
+ thread.join();
+ return 0;
+}
diff --git a/cie_thread_configurator/README.md b/cie_thread_configurator/README.md
index 4a61ee9..fd04bf9 100644
--- a/cie_thread_configurator/README.md
+++ b/cie_thread_configurator/README.md
@@ -6,7 +6,7 @@ For instructions on how to use this tool, please refer to https://github.com/tie
## YAML Configuration File Format
For each ROS 2 application, prepare a single YAML configuration file.
The format of the YAML configuration file is as follows.
-There is a top-level entry called `callback_groups`, under which there are arrays representing each callback group.
+There are two top-level entries: `callback_groups` for ROS 2 callback groups, and `non_ros_threads` for non-ROS worker threads.
The IDs for the callback groups are automatically generated by this tool according to the rules described in the next section.
```yaml
@@ -25,6 +25,13 @@ callback_groups:
policy: SCHED_FIFO
priority: 50
+non_ros_threads:
+ - id: zzzzz
+ affinity:
+ - 4
+ policy: SCHED_OTHER
+ priority: 0
+
...
```
@@ -133,3 +140,24 @@ Timers with the same period cannot be distinguished from each other, so if diffe
For `rclcpp::Waitable`, no distinction is made between instances.
Note: Future updates may exclude `rclcpp::Waitable` from being included in the CallbackGroup ID.
+
+## Non-ROS Worker Thread Management
+
+The `spawn_cie_thread` function enables thread scheduling management for non-ROS2 worker threads. Threads created with this function automatically publish their information to the `cie_thread_configurator` without requiring a ROS node.
+
+### Usage
+
+```cpp
+#include "cie_thread_configurator/cie_thread_configurator.hpp"
+
+// Spawn a managed worker thread
+auto thread = cie_thread_configurator::spawn_cie_thread(
+ "worker_thread_name", // Unique thread name (used as ID in YAML)
+ worker_function, // Thread function
+ arg1, arg2, ... // Optional arguments
+);
+
+thread.join();
+```
+
+The thread name specified as the first argument must match the `id` field in the `non_ros_threads` section of the YAML configuration file. This allows the thread's scheduling policy, priority, and CPU affinity to be configured through the same YAML file used for ROS 2 callback groups.
diff --git a/cie_thread_configurator/include/cie_thread_configurator/cie_thread_configurator.hpp b/cie_thread_configurator/include/cie_thread_configurator/cie_thread_configurator.hpp
index 730e5f5..84d9927 100644
--- a/cie_thread_configurator/include/cie_thread_configurator/cie_thread_configurator.hpp
+++ b/cie_thread_configurator/include/cie_thread_configurator/cie_thread_configurator.hpp
@@ -4,8 +4,10 @@
#include