15 #include "rclcpp/executors/static_single_threaded_executor.hpp"
22 #include "rcpputils/scope_exit.hpp"
27 StaticSingleThreadedExecutor::StaticSingleThreadedExecutor(
31 entities_collector_ = std::make_shared<StaticExecutorEntitiesCollector>();
36 if (entities_collector_->is_init()) {
37 entities_collector_->fini();
45 throw std::runtime_error(
"spin() called while already spinning");
47 RCPPUTILS_SCOPE_EXIT(this->
spinning.store(
false); );
51 entities_collector_->init(&
wait_set_, memory_strategy_);
55 entities_collector_->refresh_wait_set();
64 if (std::chrono::nanoseconds(0) == max_duration) {
65 max_duration = std::chrono::nanoseconds::max();
68 return this->spin_some_impl(max_duration,
false);
74 if (max_duration < std::chrono::nanoseconds(0)) {
75 throw std::invalid_argument(
"max_duration must be greater than or equal to 0");
77 return this->spin_some_impl(max_duration,
true);
81 StaticSingleThreadedExecutor::spin_some_impl(std::chrono::nanoseconds max_duration,
bool exhaustive)
84 if (!entities_collector_->is_init()) {
85 entities_collector_->init(&
wait_set_, memory_strategy_);
88 auto start = std::chrono::steady_clock::now();
89 auto max_duration_not_elapsed = [max_duration, start]() {
90 if (std::chrono::nanoseconds(0) == max_duration) {
93 }
else if (std::chrono::steady_clock::now() - start < max_duration) {
102 throw std::runtime_error(
"spin_some() called while already spinning");
104 RCPPUTILS_SCOPE_EXIT(this->
spinning.store(
false); );
108 entities_collector_->refresh_wait_set(std::chrono::milliseconds::zero());
111 if (!work_available || !exhaustive) {
118 StaticSingleThreadedExecutor::spin_once_impl(std::chrono::nanoseconds timeout)
121 if (!entities_collector_->is_init()) {
122 entities_collector_->init(&
wait_set_, memory_strategy_);
127 entities_collector_->refresh_wait_set(timeout);
135 rclcpp::CallbackGroup::SharedPtr group_ptr,
136 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
139 bool is_new_node = entities_collector_->add_callback_group(group_ptr, node_ptr);
140 if (is_new_node && notify) {
148 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify)
150 bool is_new_node = entities_collector_->add_node(node_ptr);
151 if (is_new_node && notify) {
160 this->
add_node(node_ptr->get_node_base_interface(), notify);
165 rclcpp::CallbackGroup::SharedPtr group_ptr,
bool notify)
167 bool node_removed = entities_collector_->remove_callback_group(group_ptr);
169 if (node_removed && notify) {
176 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify)
178 bool node_removed = entities_collector_->remove_node(node_ptr);
180 throw std::runtime_error(
"Node needs to be associated with this executor.");
188 std::vector<rclcpp::CallbackGroup::WeakPtr>
191 return entities_collector_->get_all_callback_groups();
194 std::vector<rclcpp::CallbackGroup::WeakPtr>
197 return entities_collector_->get_manually_added_callback_groups();
200 std::vector<rclcpp::CallbackGroup::WeakPtr>
203 return entities_collector_->get_automatically_added_callback_groups_from_nodes();
209 this->
remove_node(node_ptr->get_node_base_interface(), notify);
215 bool any_ready_executable =
false;
219 if (i < entities_collector_->get_number_of_subscriptions()) {
221 execute_subscription(entities_collector_->get_subscription(i));
225 any_ready_executable =
true;
231 if (i < entities_collector_->get_number_of_timers()) {
232 if (
wait_set_.
timers[i] && entities_collector_->get_timer(i)->is_ready()) {
233 auto timer = entities_collector_->get_timer(i);
235 execute_timer(std::move(timer));
239 any_ready_executable =
true;
245 if (i < entities_collector_->get_number_of_services()) {
247 execute_service(entities_collector_->get_service(i));
251 any_ready_executable =
true;
257 if (i < entities_collector_->get_number_of_clients()) {
259 execute_client(entities_collector_->get_client(i));
263 any_ready_executable =
true;
268 for (
size_t i = 0; i < entities_collector_->get_number_of_waitables(); ++i) {
269 auto waitable = entities_collector_->get_waitable(i);
271 auto data = waitable->take_data();
272 waitable->execute(data);
276 any_ready_executable =
true;
279 return any_ready_executable;
Coordinate the order and timing of available communication tasks.
rcl_wait_set_t wait_set_
Wait set for managing entities that the rmw layer waits on.
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
rclcpp::GuardCondition interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin and to cancel blocking spins.
RCLCPP_PUBLIC void trigger()
Notify the wait set waiting on this condition, if any, that the condition had been met.
Static executor implementation.
RCLCPP_PUBLIC void spin_some(std::chrono::nanoseconds max_duration=std::chrono::nanoseconds(0)) override
Static executor implementation of spin some.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC void spin() override
Static executor implementation of spin.
RCLCPP_PUBLIC void add_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr, rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true) override
Add a callback group to an executor.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups() override
Get callback groups that belong to executor.
virtual RCLCPP_PUBLIC ~StaticSingleThreadedExecutor()
Default destrcutor.
RCLCPP_PUBLIC void spin_all(std::chrono::nanoseconds max_duration) override
Static executor implementation of spin all.
RCLCPP_PUBLIC void remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true) override
Remove a node from the executor.
RCLCPP_PUBLIC bool execute_ready_executables(bool spin_once=false)
Executes ready executables from wait set.
RCLCPP_PUBLIC void add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true) override
Add a node to the executor.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_automatically_added_callback_groups_from_nodes() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC void remove_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr, bool notify=true) override
Remove callback group from the executor.
This class contains subscriptionbase, timerbase, etc. which can be used to run callbacks.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC bool ok(rclcpp::Context::SharedPtr context=nullptr)
Check rclcpp's status.
const rcl_timer_t ** timers
Storage for timer pointers.
size_t size_of_timers
Number of timers.
size_t size_of_subscriptions
Number of subscriptions.
const rcl_service_t ** services
Storage for service pointers.
const rcl_client_t ** clients
Storage for client pointers.
const rcl_subscription_t ** subscriptions
Storage for subscription pointers.
size_t size_of_clients
Number of clients.
size_t size_of_services
Number of services.
Options to be passed to the executor constructor.