15 #ifndef RCLCPP__EXECUTOR_HPP_
16 #define RCLCPP__EXECUTOR_HPP_
32 #include "rcpputils/scope_exit.hpp"
34 #include "rclcpp/context.hpp"
35 #include "rclcpp/contexts/default_context.hpp"
36 #include "rclcpp/guard_condition.hpp"
37 #include "rclcpp/executor_options.hpp"
38 #include "rclcpp/future_return_code.hpp"
39 #include "rclcpp/memory_strategies.hpp"
40 #include "rclcpp/memory_strategy.hpp"
41 #include "rclcpp/node_interfaces/node_base_interface.hpp"
42 #include "rclcpp/utilities.hpp"
43 #include "rclcpp/visibility_control.hpp"
48 typedef std::map<rclcpp::CallbackGroup::WeakPtr,
49 rclcpp::node_interfaces::NodeBaseInterface::WeakPtr,
50 std::owner_less<rclcpp::CallbackGroup::WeakPtr>> WeakCallbackGroupsToNodesMap;
68 RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(
Executor)
106 rclcpp::CallbackGroup::SharedPtr group_ptr,
107 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
123 virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
137 virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
152 virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
177 rclcpp::CallbackGroup::SharedPtr group_ptr,
201 add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify =
true);
209 add_node(std::shared_ptr<rclcpp::Node> node_ptr,
bool notify =
true);
229 remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
bool notify =
true);
237 remove_node(std::shared_ptr<rclcpp::Node> node_ptr,
bool notify =
true);
246 template<
typename RepT =
int64_t,
typename T = std::milli>
249 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
250 std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
252 return spin_node_once_nanoseconds(
254 std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
259 template<
typename NodeT = rclcpp::Node,
typename RepT =
int64_t,
typename T = std::milli>
262 std::shared_ptr<NodeT> node,
263 std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
265 return spin_node_once_nanoseconds(
266 node->get_node_base_interface(),
267 std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
277 spin_node_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node);
297 spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0));
316 spin_all(std::chrono::nanoseconds max_duration);
320 spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
332 template<
typename FutureT,
typename TimeRepT =
int64_t,
typename TimeT = std::milli>
335 const FutureT & future,
336 std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
343 std::future_status status = future.wait_for(std::chrono::seconds(0));
344 if (status == std::future_status::ready) {
345 return FutureReturnCode::SUCCESS;
348 auto end_time = std::chrono::steady_clock::now();
349 std::chrono::nanoseconds timeout_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(
351 if (timeout_ns > std::chrono::nanoseconds::zero()) {
352 end_time += timeout_ns;
354 std::chrono::nanoseconds timeout_left = timeout_ns;
357 throw std::runtime_error(
"spin_until_future_complete() called while already spinning");
359 RCPPUTILS_SCOPE_EXIT(this->
spinning.store(
false); );
362 spin_once_impl(timeout_left);
365 status = future.wait_for(std::chrono::seconds(0));
366 if (status == std::future_status::ready) {
367 return FutureReturnCode::SUCCESS;
370 if (timeout_ns < std::chrono::nanoseconds::zero()) {
374 auto now = std::chrono::steady_clock::now();
375 if (now >= end_time) {
376 return FutureReturnCode::TIMEOUT;
379 timeout_left = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - now);
383 return FutureReturnCode::INTERRUPTED;
418 spin_node_once_nanoseconds(
419 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
420 std::chrono::nanoseconds timeout);
424 spin_some_impl(std::chrono::nanoseconds max_duration,
bool exhaustive);
438 execute_subscription(
439 rclcpp::SubscriptionBase::SharedPtr subscription);
443 execute_timer(rclcpp::TimerBase::SharedPtr timer);
447 execute_service(rclcpp::ServiceBase::SharedPtr service);
451 execute_client(rclcpp::ClientBase::SharedPtr client);
458 wait_for_work(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
461 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr
463 const WeakCallbackGroupsToNodesMap & weak_groups_to_nodes,
464 rclcpp::CallbackGroup::SharedPtr group);
475 const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
476 const WeakCallbackGroupsToNodesMap & weak_groups_to_nodes)
const;
479 rclcpp::CallbackGroup::SharedPtr
480 get_group_by_timer(rclcpp::TimerBase::SharedPtr timer);
489 rclcpp::CallbackGroup::SharedPtr group_ptr,
490 rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
491 WeakCallbackGroupsToNodesMap & weak_groups_to_nodes,
492 bool notify =
true) RCPPUTILS_TSA_REQUIRES(mutex_);
502 WeakCallbackGroupsToNodesMap & weak_groups_to_nodes,
503 bool notify = true) RCPPUTILS_TSA_REQUIRES(mutex_);
511 get_next_ready_executable_from_map(
513 const WeakCallbackGroupsToNodesMap & weak_groups_to_nodes);
519 std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
548 mutable std::mutex mutex_;
551 memory_strategy::MemoryStrategy::SharedPtr
561 spin_once_impl(std::chrono::nanoseconds timeout);
566 WeakCallbackGroupsToGuardConditionsMap;
569 WeakCallbackGroupsToGuardConditionsMap
573 WeakCallbackGroupsToNodesMap
577 WeakCallbackGroupsToNodesMap
581 WeakCallbackGroupsToNodesMap
585 std::list<
rclcpp::node_interfaces::NodeBaseInterface::WeakPtr>
Context which encapsulates shared state between nodes and other similar entities.
Coordinate the order and timing of available communication tasks.
RCLCPP_PUBLIC void spin_node_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node)
Add a node, complete all immediately available work, and remove the node.
rcl_wait_set_t wait_set_
Wait set for managing entities that the rmw layer waits on.
RCLCPP_PUBLIC void set_memory_strategy(memory_strategy::MemoryStrategy::SharedPtr memory_strategy)
Support dynamic switching of the memory strategy.
virtual RCLCPP_PUBLIC ~Executor()
Default destructor.
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups()
Get callback groups that belong to executor.
virtual RCLCPP_PUBLIC void remove_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr, bool notify=true)
Remove a callback group from the executor.
FutureReturnCode spin_until_future_complete(const FutureT &future, std::chrono::duration< TimeRepT, TimeT > timeout=std::chrono::duration< TimeRepT, TimeT >(-1))
Spin (blocking) until the future is complete, it times out waiting, or rclcpp is interrupted.
virtual RCLCPP_PUBLIC void add_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr, rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true)
Add a callback group to an executor.
RCLCPP_PUBLIC void wait_for_work(std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
virtual RCLCPP_PUBLIC void remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true)
Remove a node from the executor.
RCLCPP_PUBLIC Executor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions())
Default constructor.
virtual RCLCPP_PUBLIC void spin_some(std::chrono::nanoseconds max_duration=std::chrono::nanoseconds(0))
Collect work once and execute all available work, optionally within a duration.
RCLCPP_PUBLIC void cancel()
Cancel any running spin* function, causing it to return.
WeakCallbackGroupsToGuardConditionsMap weak_groups_to_guard_conditions_ RCPPUTILS_TSA_GUARDED_BY(mutex_)
maps callback groups to guard conditions
RCLCPP_PUBLIC bool is_spinning()
Returns true if the executor is currently spinning.
void spin_node_once(std::shared_ptr< NodeT > node, std::chrono::duration< RepT, T > timeout=std::chrono::duration< RepT, T >(-1))
Convenience function which takes Node and forwards NodeBaseInterface.
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_automatically_added_callback_groups_from_nodes()
Get callback groups that belong to executor.
rclcpp::GuardCondition interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
rclcpp::OnShutdownCallbackHandle shutdown_callback_handle_
shutdown callback handle registered to Context
virtual RCLCPP_PUBLIC void add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true)
Add a node to the executor.
RCLCPP_PUBLIC void execute_any_executable(AnyExecutable &any_exec)
Find the next available executable and do the work associated with it.
virtual RCLCPP_PUBLIC void add_callback_group_to_map(rclcpp::CallbackGroup::SharedPtr group_ptr, rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, WeakCallbackGroupsToNodesMap &weak_groups_to_nodes, bool notify=true) RCPPUTILS_TSA_REQUIRES(mutex_)
Add a callback group to an executor.
virtual RCLCPP_PUBLIC void add_callback_groups_from_nodes_associated_to_executor() RCPPUTILS_TSA_REQUIRES(mutex_)
Add all callback groups that can be automatically added from associated nodes.
virtual void spin()=0
Do work periodically as it becomes available to us. Blocking call, may block indefinitely.
virtual RCLCPP_PUBLIC void remove_callback_group_from_map(rclcpp::CallbackGroup::SharedPtr group_ptr, WeakCallbackGroupsToNodesMap &weak_groups_to_nodes, bool notify=true) RCPPUTILS_TSA_REQUIRES(mutex_)
Remove a callback group from the executor.
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups()
Get callback groups that belong to executor.
RCLCPP_PUBLIC bool has_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, const WeakCallbackGroupsToNodesMap &weak_groups_to_nodes) const
Return true if the node has been added to this executor.
virtual RCLCPP_PUBLIC void spin_all(std::chrono::nanoseconds max_duration)
Collect and execute work repeatedly within a duration or until no more work is available.
void spin_node_once(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node, std::chrono::duration< RepT, T > timeout=std::chrono::duration< RepT, T >(-1))
Add a node to executor, execute the next available unit of work, and remove the node.
memory_strategy::MemoryStrategy::SharedPtr memory_strategy_ RCPPUTILS_TSA_PT_GUARDED_BY(mutex_)
The memory strategy: an interface for handling user-defined memory allocation strategies.
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin and to cancel blocking spins.
A condition that can be waited on in a single wait set and asynchronously triggered.
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
FutureReturnCode
Return codes to be used with spin_until_future_complete.
RCLCPP_PUBLIC bool ok(rclcpp::Context::SharedPtr context=nullptr)
Check rclcpp's status.
Container for subscription's, guard condition's, etc to be waited on.
Options to be passed to the executor constructor.
RCL_PUBLIC RCL_WARN_UNUSED rcl_wait_set_t rcl_get_zero_initialized_wait_set(void)
Return a rcl_wait_set_t struct with members set to NULL.