23 #include "rclcpp/executor.hpp"
24 #include "rclcpp/macros.hpp"
25 #include "rclcpp/visibility_control.hpp"
32 namespace cbg_executor
35 struct RegisteredEntityCache;
37 struct GlobalWeakExecutableCache;
60 size_t number_of_threads = 0,
61 std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
69 const rclcpp::CallbackGroup::SharedPtr & group_ptr,
70 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
71 bool notify =
true)
override;
74 std::vector<rclcpp::CallbackGroup::WeakPtr>
78 std::vector<rclcpp::CallbackGroup::WeakPtr>
82 std::vector<rclcpp::CallbackGroup::WeakPtr>
88 const rclcpp::CallbackGroup::SharedPtr & group_ptr,
89 bool notify =
true)
override;
94 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
95 bool notify =
true)
override;
103 add_node(
const std::shared_ptr<rclcpp::Node> & node_ptr,
bool notify =
true)
override;
108 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
109 bool notify =
true)
override;
117 remove_node(
const std::shared_ptr<rclcpp::Node> & node_ptr,
bool notify =
true)
override;
120 void add_callback_group_only(
const rclcpp::CallbackGroup::SharedPtr & group_ptr);
140 spin(
const std::function<
void(
const std::exception &)> & exception_handler);
144 spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1))
override;
148 spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0))
override;
155 std::chrono::nanoseconds max_duration,
156 bool recollect_if_no_work_available);
160 spin_all(std::chrono::nanoseconds max_duration)
override;
173 get_number_of_threads()
const;
181 template<
typename FutureT,
typename TimeRepT =
int64_t,
typename TimeT = std::milli>
183 spin_until_future_complete(
184 const FutureT & future,
185 std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
192 std::future_status status = future.wait_for(std::chrono::seconds(0));
193 if (status == std::future_status::ready) {
194 return FutureReturnCode::SUCCESS;
197 auto end_time = std::chrono::steady_clock::now();
198 std::chrono::nanoseconds timeout_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
200 if (timeout_ns > std::chrono::nanoseconds::zero()) {
201 end_time += timeout_ns;
203 std::chrono::nanoseconds timeout_left = timeout_ns;
205 if (spinning.exchange(
true)) {
206 throw std::runtime_error(
"spin_until_future_complete() called while already spinning");
208 RCPPUTILS_SCOPE_EXIT(this->spinning.store(
false); );
209 while (
rclcpp::ok(this->context_) && spinning.load()) {
211 spin_once_internal(timeout_left);
214 status = future.wait_for(std::chrono::seconds(0));
215 if (status == std::future_status::ready) {
216 return FutureReturnCode::SUCCESS;
219 if (timeout_ns < std::chrono::nanoseconds::zero()) {
223 auto now = std::chrono::steady_clock::now();
224 if (now >= end_time) {
225 return FutureReturnCode::TIMEOUT;
228 timeout_left = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - now);
232 return FutureReturnCode::INTERRUPTED;
244 run(
size_t this_thread_number,
bool block_initially);
249 size_t this_thread_number,
250 const std::function<
void(
const std::exception &)> & exception_handler);
258 std::unique_ptr<cbg_executor::CBGScheduler> scheduler;
268 CallbackGroup::WeakPtr callback_group;
270 std::unique_ptr<cbg_executor::RegisteredEntityCache> registered_entities;
282 const std::chrono::time_point<std::chrono::steady_clock> & stop_time);
284 void unregister_event_callbacks(
const rclcpp::CallbackGroup::SharedPtr & cbg)
const;
287 void remove_all_nodes_and_callback_groups();
289 void sync_callback_groups();
295 void trigger_callback_group_sync();
298 void spin_once_internal(std::chrono::nanoseconds timeout);
302 std::mutex added_callback_groups_mutex_;
303 std::vector<rclcpp::CallbackGroup::WeakPtr> added_callback_groups;
305 std::mutex added_nodes_mutex_;
306 std::vector<node_interfaces::NodeBaseInterface::WeakPtr> added_nodes;
308 std::mutex callback_groups_mutex;
310 std::vector<CallbackGroupData> callback_groups;
312 size_t number_of_threads_;
314 std::chrono::nanoseconds next_exec_timeout_;
316 std::atomic_bool needs_callback_group_resync =
false;
319 std::atomic_bool spinning;
322 bool in_shutdown =
false;
325 std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
328 std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
334 std::shared_ptr<rclcpp::Context> context_;
336 std::unique_ptr<cbg_executor::TimerManager> timer_manager;
340 std::unique_ptr<cbg_executor::GlobalWeakExecutableCache> global_executable_cache;
343 std::unique_ptr<cbg_executor::GlobalWeakExecutableCache> nodes_executable_cache;
Coordinate the order and timing of available communication tasks.
static RCLCPP_PUBLIC void execute_timer(const rclcpp::TimerBase::SharedPtr &timer, const std::shared_ptr< void > &data_ptr)
Run timer executable.
static RCLCPP_PUBLIC void execute_client(const rclcpp::ClientBase::SharedPtr &client)
Run service client executable.
static RCLCPP_PUBLIC void execute_service(const rclcpp::ServiceBase::SharedPtr &service)
Run service server executable.
static RCLCPP_PUBLIC void execute_subscription(const rclcpp::SubscriptionBase::SharedPtr &subscription)
Run subscription executable.
Node is the single point of entry for creating publishers and subscribers.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups() override
Get callback groups that belong to executor.
RCLCPP_PUBLIC void spin_once(std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1)) override
Collect work once and execute the next available work, optionally within a duration.
RCLCPP_PUBLIC void spin(const std::function< void(const std::exception &)> &exception_handler)
RCLCPP_PUBLIC void add_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Add a callback group to an executor.
RCLCPP_PUBLIC void spin_some(std::chrono::nanoseconds max_duration=std::chrono::nanoseconds(0)) override
Collect work once and execute all available work, optionally within a max duration.
RCLCPP_PUBLIC void add_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Add a node to the executor.
bool execute_previous_ready_executables_until(const std::chrono::time_point< std::chrono::steady_clock > &stop_time)
RCLCPP_PUBLIC EventsCBGExecutor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions(), size_t number_of_threads=0, std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
RCLCPP_PUBLIC void spin_all(std::chrono::nanoseconds max_duration) override
Collect and execute work repeatedly within a duration or until no more work is available.
RCLCPP_PUBLIC void remove_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true) override
Remove a node from the executor.
RCLCPP_PUBLIC bool collect_and_execute_ready_events(std::chrono::nanoseconds max_duration, bool recollect_if_no_work_available)
RCLCPP_PUBLIC void cancel() override
Cancel any running spin* function, causing it to return.
RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups() override
Get callback groups that belong to 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 spin() override
RCLCPP_PUBLIC void remove_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, bool notify=true) override
Remove a callback group from the executor.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
RCLCPP_PUBLIC bool ok(const rclcpp::Context::SharedPtr &context=rclcpp::contexts::get_global_default_context())
Check rclcpp's status.
FutureReturnCode
Return codes to be used with spin_until_future_complete.
Options to be passed to the executor constructor.