diff --git a/rclcpp/include/rclcpp/executor.hpp b/rclcpp/include/rclcpp/executor.hpp index fcc48da055..ceba28e49f 100644 --- a/rclcpp/include/rclcpp/executor.hpp +++ b/rclcpp/include/rclcpp/executor.hpp @@ -407,6 +407,10 @@ class Executor bool is_spinning(); + RCLCPP_PUBLIC + virtual std::string + get_class_name() const = 0; + protected: /// Constructor that will not initialize any non-trivial members. /** diff --git a/rclcpp/include/rclcpp/executors/multi_threaded_executor.hpp b/rclcpp/include/rclcpp/executors/multi_threaded_executor.hpp index 119013ebfb..b130519ec6 100644 --- a/rclcpp/include/rclcpp/executors/multi_threaded_executor.hpp +++ b/rclcpp/include/rclcpp/executors/multi_threaded_executor.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -73,6 +74,10 @@ class MultiThreadedExecutor : public rclcpp::Executor size_t get_number_of_threads(); + RCLCPP_PUBLIC + std::string + get_class_name() const override; + protected: RCLCPP_PUBLIC void diff --git a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp index 9dc6dec57b..ca2b971325 100644 --- a/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp +++ b/rclcpp/include/rclcpp/executors/single_threaded_executor.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "rclcpp/executor.hpp" @@ -65,6 +66,10 @@ class SingleThreadedExecutor : public rclcpp::Executor void spin() override; + RCLCPP_PUBLIC + std::string + get_class_name() const override; + private: RCLCPP_DISABLE_COPY(SingleThreadedExecutor) }; diff --git a/rclcpp/include/rclcpp/experimental/executors/events_executor/events_executor.hpp b/rclcpp/include/rclcpp/experimental/executors/events_executor/events_executor.hpp index aede14dbc9..93b3cba4b1 100644 --- a/rclcpp/include/rclcpp/experimental/executors/events_executor/events_executor.hpp +++ b/rclcpp/include/rclcpp/experimental/executors/events_executor/events_executor.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "rclcpp/executor.hpp" @@ -126,6 +127,10 @@ class EventsExecutor : public rclcpp::Executor void spin_all(std::chrono::nanoseconds max_duration) override; + RCLCPP_PUBLIC + std::string + get_class_name() const override; + protected: /// Internal implementation of spin_once RCLCPP_PUBLIC diff --git a/rclcpp/src/rclcpp/executors/multi_threaded_executor.cpp b/rclcpp/src/rclcpp/executors/multi_threaded_executor.cpp index 378fdfb8fa..a2eb694eb3 100644 --- a/rclcpp/src/rclcpp/executors/multi_threaded_executor.cpp +++ b/rclcpp/src/rclcpp/executors/multi_threaded_executor.cpp @@ -78,6 +78,12 @@ MultiThreadedExecutor::get_number_of_threads() return number_of_threads_; } +std::string +MultiThreadedExecutor::get_class_name() const +{ + return "MultiThreadedExecutor"; +} + void MultiThreadedExecutor::run([[maybe_unused]] size_t this_thread_number) { diff --git a/rclcpp/src/rclcpp/executors/single_threaded_executor.cpp b/rclcpp/src/rclcpp/executors/single_threaded_executor.cpp index 689bbae398..b0f8507146 100644 --- a/rclcpp/src/rclcpp/executors/single_threaded_executor.cpp +++ b/rclcpp/src/rclcpp/executors/single_threaded_executor.cpp @@ -43,3 +43,9 @@ SingleThreadedExecutor::spin() } } } + +std::string +SingleThreadedExecutor::get_class_name() const +{ + return "SingleThreadedExecutor"; +} diff --git a/rclcpp/src/rclcpp/experimental/executors/events_executor/events_executor.cpp b/rclcpp/src/rclcpp/experimental/executors/events_executor/events_executor.cpp index 4a3f8f796f..07c06bb924 100644 --- a/rclcpp/src/rclcpp/experimental/executors/events_executor/events_executor.cpp +++ b/rclcpp/src/rclcpp/experimental/executors/events_executor/events_executor.cpp @@ -240,6 +240,11 @@ EventsExecutor::spin_once_impl(std::chrono::nanoseconds timeout) } } +std::string +EventsExecutor::get_class_name() const +{ + return "EventsExecutor"; +} void EventsExecutor::execute_event(const ExecutorEvent & event) diff --git a/rclcpp/test/rclcpp/executors/test_executors_callback_group_behavior.cpp b/rclcpp/test/rclcpp/executors/test_executors_callback_group_behavior.cpp index 49391cd838..21b692deac 100644 --- a/rclcpp/test/rclcpp/executors/test_executors_callback_group_behavior.cpp +++ b/rclcpp/test/rclcpp/executors/test_executors_callback_group_behavior.cpp @@ -42,6 +42,11 @@ class CustomExecutor : public rclcpp::Executor void spin() override {} + std::string get_class_name() const override + { + return "CustomExecutor"; + } + void collect() { this->collect_entities(); diff --git a/rclcpp/test/rclcpp/test_executor.cpp b/rclcpp/test/rclcpp/test_executor.cpp index 46ed2969cc..00bf71613b 100644 --- a/rclcpp/test/rclcpp/test_executor.cpp +++ b/rclcpp/test/rclcpp/test_executor.cpp @@ -47,6 +47,11 @@ class DummyExecutor : public rclcpp::Executor { } + std::string get_class_name() const override + { + return "DummyExecutor"; + } + void spin_nanoseconds(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node) { spin_node_once_nanoseconds(node, std::chrono::milliseconds(100)); diff --git a/rclcpp_components/include/rclcpp_components/component_manager.hpp b/rclcpp_components/include/rclcpp_components/component_manager.hpp index 34b2ea4d39..82d60b1951 100644 --- a/rclcpp_components/include/rclcpp_components/component_manager.hpp +++ b/rclcpp_components/include/rclcpp_components/component_manager.hpp @@ -90,6 +90,20 @@ class ComponentManager : public rclcpp::Node using ComponentResource = std::pair; /// Default constructor + /** + * Initializes the component manager. It creates the services: load node, unload node + * and list nodes. Initialize executor after construction using set_executor. + * + * \param executor the executor which will spin the node. + * \param node_name the name of the node that the data originates from. + * \param node_options additional options to control creation of the node. + */ + RCLCPP_COMPONENTS_PUBLIC + ComponentManager( + std::string node_name = "ComponentManager", + const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions()); + + /// Constructor with executor /** * Initializes the component manager. It creates the services: load node, unload node * and list nodes. @@ -100,12 +114,9 @@ class ComponentManager : public rclcpp::Node */ RCLCPP_COMPONENTS_PUBLIC ComponentManager( - std::weak_ptr executor = - std::weak_ptr(), + std::weak_ptr executor, std::string node_name = "ComponentManager", - const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions() - .start_parameter_services(false) - .start_parameter_event_publisher(false)); + const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions()); RCLCPP_COMPONENTS_PUBLIC virtual ~ComponentManager(); diff --git a/rclcpp_components/src/component_container.cpp b/rclcpp_components/src/component_container.cpp index cc5018ef3a..2de3adf4bf 100644 --- a/rclcpp_components/src/component_container.cpp +++ b/rclcpp_components/src/component_container.cpp @@ -23,8 +23,32 @@ int main(int argc, char * argv[]) { /// Component container with a single-threaded executor. rclcpp::init(argc, argv); - auto exec = std::make_shared(); - auto node = std::make_shared(exec); + + std::shared_ptr exec; + auto node = std::make_shared(); + + const auto exec_type = node->get_parameter("executor_type").as_string(); + if (exec_type == "SingleThreadedExecutor" || exec_type == "No Executor") { + // Default executor for ComponentContainer is SingleThreadedExecutor, because of + // backward compatibility. + exec = std::make_shared(); + } else if (exec_type == "MultiThreadedExecutor") { + if (node->has_parameter("thread_num")) { + const auto thread_num = node->get_parameter("thread_num").as_int(); + exec = std::make_shared( + rclcpp::ExecutorOptions{}, thread_num); + } else { + exec = std::make_shared(); + } + } else if (exec_type == "EventsExecutor") { + exec = std::make_shared(); + } else { + RCLCPP_ERROR(node->get_logger(), "Unknown executor type %s", exec_type.c_str()); + return 1; + } + + node->set_executor(exec); + exec->add_node(node); exec->spin(); diff --git a/rclcpp_components/src/component_container_event.cpp b/rclcpp_components/src/component_container_event.cpp index f693281023..361ec529b2 100644 --- a/rclcpp_components/src/component_container_event.cpp +++ b/rclcpp_components/src/component_container_event.cpp @@ -19,12 +19,22 @@ #include "rclcpp_components/component_manager.hpp" +[[deprecated("component_container_event is deprecated and will be removed " + "in the next version. Use 'ros2 run rclcpp_components " + "component_container --ros-args -p executor_type:=EventsExecutor' " + "instead.")]] int main(int argc, char * argv[]) { /// Component container with an events executor. rclcpp::init(argc, argv); auto exec = std::make_shared(); auto node = std::make_shared(exec); + + RCLCPP_WARN(node->get_logger(), + "component_container_event is depracated and will be removed " + "in the next version. use 'ros2 run rclcpp_components " + "component_container --ros-args -p executor_type:=EventsExecutor'."); + exec->add_node(node); exec->spin(); diff --git a/rclcpp_components/src/component_container_mt.cpp b/rclcpp_components/src/component_container_mt.cpp index 9675f9a7a7..2ee1decc86 100644 --- a/rclcpp_components/src/component_container_mt.cpp +++ b/rclcpp_components/src/component_container_mt.cpp @@ -19,6 +19,11 @@ #include "rclcpp_components/component_manager.hpp" +[[deprecated("component_container_event is depracated and will be removed " + "in the next version. use 'ros2 run rclcpp_components " + "component_container --ros-args -p executor_type:=" + "MultiThreadedExecutor'." +)]] int main(int argc, char * argv[]) { /// Component container with a multi-threaded executor. @@ -34,6 +39,13 @@ int main(int argc, char * argv[]) } else { node->set_executor(exec); } + + RCLCPP_WARN(node->get_logger(), + "component_container_event is depracated and will be removed " + "in the next version. use 'ros2 run rclcpp_components " + "component_container --ros-args -p executor_type:=" + "MultiThreadedExecutor'."); + exec->add_node(node); exec->spin(); diff --git a/rclcpp_components/src/component_manager.cpp b/rclcpp_components/src/component_manager.cpp index ac2df6d812..62e83ecec1 100644 --- a/rclcpp_components/src/component_manager.cpp +++ b/rclcpp_components/src/component_manager.cpp @@ -46,11 +46,9 @@ namespace rclcpp_components { ComponentManager::ComponentManager( - std::weak_ptr executor, std::string node_name, const rclcpp::NodeOptions & node_options) -: Node(std::move(node_name), node_options), - executor_(executor) +: Node(std::move(node_name), node_options) { loadNode_srv_ = create_service( "~/_container/load_node", @@ -75,6 +73,22 @@ ComponentManager::ComponentManager( this->declare_parameter( "thread_num", static_cast(std::thread::hardware_concurrency()), desc); } + + rcl_interfaces::msg::ParameterDescriptor exec_type_desc{}; + exec_type_desc.description = "Type of executor used for ComponentManager"; + exec_type_desc.type = rclcpp::PARAMETER_STRING; + // The value is changed only within set_executor. It cannot be changed externally. + exec_type_desc.read_only = true; + this->declare_parameter("executor_type", "No Executor", exec_type_desc); +} + +ComponentManager::ComponentManager( + std::weak_ptr executor, + std::string node_name, + const rclcpp::NodeOptions & node_options) +: ComponentManager::ComponentManager(node_name, node_options) +{ + this->set_executor(executor); } ComponentManager::~ComponentManager() @@ -243,6 +257,10 @@ void ComponentManager::set_executor(const std::weak_ptr executor) { executor_ = executor; + if (auto exec = executor_.lock()) { + rclcpp::Parameter exec_type("executor_type", exec->get_class_name()); + auto result = this->set_parameter(exec_type); + } } void