Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions rclcpp_components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ add_executable(
)
target_link_libraries(component_container_event PRIVATE component_manager rclcpp::rclcpp)

add_executable(
component_container_cbg
src/component_container_cbg.cpp
)
target_link_libraries(component_container_cbg PRIVATE component_manager rclcpp::rclcpp)

set(node_main_template_install_dir "share/${PROJECT_NAME}")
install(FILES
src/node_main.cpp.in
Expand Down
42 changes: 42 additions & 0 deletions rclcpp_components/src/component_container_cbg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2026 Open Source Robotics Foundation, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>

#include "rclcpp/utilities.hpp"
#include "rclcpp/executors/events_cbg_executor/events_cbg_executor.hpp"

#include "rclcpp_components/component_manager.hpp"

int main(int argc, char * argv[])
{
/// Component container with an events executor.
rclcpp::init(argc, argv);
rclcpp::executors::EventsCBGExecutor::SharedPtr exec = nullptr;

auto node = std::make_shared<rclcpp_components::ComponentManager>();

if (node->has_parameter("thread_num")) {
const auto thread_num = node->get_parameter("thread_num").as_int();
exec = std::make_shared<rclcpp::executors::EventsCBGExecutor>(
rclcpp::ExecutorOptions{}, thread_num);
} else {
exec = std::make_shared<rclcpp::executors::EventsCBGExecutor>();
}
node->set_executor(exec);
exec->add_node(node);
exec->spin();

return 0;
}
64 changes: 49 additions & 15 deletions rclcpp_components/src/component_container_isolated.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,75 @@
// limitations under the License.

#include <memory>
#include <vector>
#include <string>
#include <vector>

#include "rclcpp/executors/single_threaded_executor.hpp"
#include "rclcpp/executors/multi_threaded_executor.hpp"
#include "rclcpp/experimental/executors/events_executor/events_executor.hpp"
#include "rclcpp/executors/events_cbg_executor/events_cbg_executor.hpp"
#include "rclcpp/utilities.hpp"

#include "rclcpp_components/component_manager_isolated.hpp"

int main(int argc, char * argv[])
{
/// Component container with dedicated single-threaded executors for each components.
/// Component container with dedicated executor for each component
rclcpp::init(argc, argv);

// parse arguments
bool use_multi_threaded_executor{false};
// valid entries: --executor-type single-threaded, --executor-type multi-threaded, --executor-type events
std::vector<std::string> args = rclcpp::remove_ros_arguments(argc, argv);
for (auto & arg : args) {
if (arg == std::string("--use_multi_threaded_executor")) {
use_multi_threaded_executor = true;
rclcpp::Node::SharedPtr node;

std::string executor_type = "single-threaded"; // default
for (size_t i = 0; i < args.size(); ++i) {
if (args[i] == "--executor-type") {
if (i + 1 < args.size()) {
executor_type = args[i + 1];
break;
}
} else if (args[i] == "--use_multi_threaded_executor") { // backward compatibility
RCLCPP_WARN(node->get_logger(),
"--use_multi_threaded_executor is deprecated, use --executor-type multi-threaded instead.");
executor_type = "multi-threaded";
}
}

// create executor and component manager
auto exec = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
rclcpp::Node::SharedPtr node;
if (use_multi_threaded_executor) {
using ComponentManagerIsolated =
rclcpp_components::ComponentManagerIsolated<rclcpp::executors::MultiThreadedExecutor>;
std::shared_ptr<rclcpp::Executor> exec;
if (executor_type == "events") {
using executor = rclcpp::experimental::executors::EventsExecutor;
using ComponentManagerIsolated = rclcpp_components::ComponentManagerIsolated<executor>;
exec = std::make_shared<executor>();
Comment on lines +53 to +56
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I don't think anything in the experimental namespace should be officially supported in a thing like this. Especially knowing that this is going to be depreciated in short order with the new one

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably we can say EventExecutor is now graduated phase as official for next turtle-M release from the incubation experimental phase?

node = std::make_shared<ComponentManagerIsolated>(exec);
} else {
using ComponentManagerIsolated =
rclcpp_components::ComponentManagerIsolated<rclcpp::executors::SingleThreadedExecutor>;
} else if (executor_type == "cbg-single-threaded") {
using executor = rclcpp::executors::EventsCBGExecutor;
using ComponentManagerIsolated = rclcpp_components::ComponentManagerIsolated<executor>;
exec = std::make_shared<executor>(rclcpp::ExecutorOptions(), 1);
node = std::make_shared<ComponentManagerIsolated>(exec);
} else if (executor_type == "cbg-multi-threaded") {
using executor = rclcpp::executors::EventsCBGExecutor;
using ComponentManagerIsolated = rclcpp_components::ComponentManagerIsolated<executor>;
exec = std::make_shared<executor>();
node = std::make_shared<ComponentManagerIsolated>(exec);
} else if (executor_type == "multi-threaded") {
using executor = rclcpp::executors::MultiThreadedExecutor;
using ComponentManagerIsolated = rclcpp_components::ComponentManagerIsolated<executor>;
exec = std::make_shared<executor>();
node = std::make_shared<ComponentManagerIsolated>(exec);
} else if (executor_type == "single-threaded") {
using executor = rclcpp::executors::SingleThreadedExecutor;
using ComponentManagerIsolated = rclcpp_components::ComponentManagerIsolated<executor>;
exec = std::make_shared<executor>();
node = std::make_shared<ComponentManagerIsolated>(exec);
} else {
std::cerr << "Invalid executor type: " << executor_type << std::endl;
return 1;
}

exec->add_node(node);
exec->spin();

return 0;
}
}