ROS 2 rclcpp + rcl - rolling  rolling-29de98cf
ROS 2 C++ Client Library with ROS Client Library
executor.hpp
1 // Copyright 2014 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef RCLCPP__EXECUTOR_HPP_
16 #define RCLCPP__EXECUTOR_HPP_
17 
18 #include <cassert>
19 #include <chrono>
20 #include <cstdlib>
21 #include <map>
22 #include <memory>
23 #include <mutex>
24 #include <string>
25 #include <vector>
26 
27 #include "rcl/guard_condition.h"
28 #include "rcl/wait.h"
29 #include "rclcpp/executors/executor_notify_waitable.hpp"
30 #include "rcpputils/scope_exit.hpp"
31 
32 #include "rclcpp/context.hpp"
33 #include "rclcpp/contexts/default_context.hpp"
34 #include "rclcpp/guard_condition.hpp"
35 #include "rclcpp/executor_options.hpp"
36 #include "rclcpp/executors/executor_entities_collection.hpp"
37 #include "rclcpp/executors/executor_entities_collector.hpp"
38 #include "rclcpp/future_return_code.hpp"
39 #include "rclcpp/node_interfaces/node_base_interface.hpp"
40 #include "rclcpp/visibility_control.hpp"
41 #include "rclcpp/wait_set.hpp"
42 
43 namespace rclcpp
44 {
45 
46 // Forward declaration is used in convenience method signature.
47 class Node;
48 class ExecutorImplementation;
49 
51 
60 class Executor
61 {
62 public:
63  RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(Executor)
64 
65 
69  RCLCPP_PUBLIC
70  explicit Executor(const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions());
71 
73  RCLCPP_PUBLIC
74  virtual ~Executor();
75 
77  // It is up to the implementation of Executor to implement spin.
78  virtual void
79  spin() = 0;
80 
82 
98  RCLCPP_PUBLIC
99  virtual void
101  const rclcpp::CallbackGroup::SharedPtr & group_ptr,
102  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
103  bool notify = true);
104 
106 
117  RCLCPP_PUBLIC
118  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
120 
122 
131  RCLCPP_PUBLIC
132  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
134 
136 
146  RCLCPP_PUBLIC
147  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
149 
151 
169  RCLCPP_PUBLIC
170  virtual void
172  const rclcpp::CallbackGroup::SharedPtr & group_ptr,
173  bool notify = true);
174 
176 
194  RCLCPP_PUBLIC
195  virtual void
196  add_node(
197  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
198  bool notify = true);
199 
201 
204  RCLCPP_PUBLIC
205  virtual void
206  add_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
207 
209 
224  RCLCPP_PUBLIC
225  virtual void
226  remove_node(
227  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
228  bool notify = true);
229 
231 
234  RCLCPP_PUBLIC
235  virtual void
236  remove_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
237 
239 
245  template<typename RepT = int64_t, typename T = std::milli>
246  void
248  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
249  std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
250  {
252  node,
253  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
254  );
255  }
256 
258  template<typename NodeT = rclcpp::Node, typename RepT = int64_t, typename T = std::milli>
259  void
261  const std::shared_ptr<NodeT> & node,
262  std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
263  {
265  node->get_node_base_interface(),
266  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
267  );
268  }
269 
271 
274  RCLCPP_PUBLIC
275  virtual void
276  spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node);
277 
279  RCLCPP_PUBLIC
280  virtual void
281  spin_node_some(const std::shared_ptr<rclcpp::Node> & node);
282 
284 
313  RCLCPP_PUBLIC
314  virtual void
315  spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0));
316 
318 
321  RCLCPP_PUBLIC
322  virtual void
324  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
325  std::chrono::nanoseconds max_duration);
326 
328  RCLCPP_PUBLIC
329  virtual void
330  spin_node_all(const std::shared_ptr<rclcpp::Node> & node, std::chrono::nanoseconds max_duration);
331 
333 
347  RCLCPP_PUBLIC
348  virtual void
349  spin_all(std::chrono::nanoseconds max_duration);
350 
351 
353 
361  RCLCPP_PUBLIC
362  virtual void
363  spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
364 
366 
378  template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::milli>
381  const FutureT & future,
382  std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
383  {
385  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout),
386  [&future](std::chrono::nanoseconds wait_time) {
387  return future.wait_for(wait_time);
388  }
389  );
390  }
391 
393 
397  RCLCPP_PUBLIC
398  virtual void
399  cancel();
400 
402 
406  RCLCPP_PUBLIC
407  bool
408  is_spinning();
409 
410 protected:
412 
417  explicit Executor(const std::shared_ptr<rclcpp::Context> & context);
418 
420 
427  RCLCPP_PUBLIC
428  void
430  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
431  std::chrono::nanoseconds timeout);
432 
434 
444  RCLCPP_PUBLIC
445  virtual FutureReturnCode
447  std::chrono::nanoseconds timeout,
448  const std::function<std::future_status(std::chrono::nanoseconds wait_time)> & wait_for_future);
449 
451 
459  RCLCPP_PUBLIC
460  void
461  spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive);
462 
464 
469  RCLCPP_PUBLIC
470  void
472 
474 
478  RCLCPP_PUBLIC
479  static void
481  const rclcpp::SubscriptionBase::SharedPtr & subscription);
482 
484 
488  RCLCPP_PUBLIC
489  static void
490  execute_timer(const rclcpp::TimerBase::SharedPtr & timer, const std::shared_ptr<void> & data_ptr);
491 
493 
497  RCLCPP_PUBLIC
498  static void
499  execute_service(const rclcpp::ServiceBase::SharedPtr & service);
500 
502 
506  RCLCPP_PUBLIC
507  static void
508  execute_client(const rclcpp::ClientBase::SharedPtr & client);
509 
511  RCLCPP_PUBLIC
512  void
514 
516 
522  RCLCPP_PUBLIC
523  void
524  wait_for_work(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
525 
527 
532  RCLCPP_PUBLIC
533  bool
534  get_next_ready_executable(AnyExecutable & any_executable);
535 
537 
547  RCLCPP_PUBLIC
548  bool
550  AnyExecutable & any_executable,
551  std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
552 
554 
559  RCLCPP_PUBLIC
560  virtual void
561  handle_updated_entities(bool notify);
562 
564 
568  std::atomic_bool spinning;
569 
571 
575  std::atomic_bool cancel_requested_;
576 
578  std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
579 
581  std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
582 
583  mutable std::mutex mutex_;
584 
586  std::shared_ptr<rclcpp::Context> context_;
587 
588  RCLCPP_DISABLE_COPY(Executor)
589 
590  RCLCPP_PUBLIC
591  virtual void
592  spin_once_impl(std::chrono::nanoseconds timeout);
593 
595 
601  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> notify_waitable_;
602 
603  std::atomic_bool entities_need_rebuild_;
604 
607 
610  std::optional<rclcpp::WaitResult<rclcpp::WaitSet>> wait_result_ RCPPUTILS_TSA_GUARDED_BY(mutex_);
611 
614  mutex_);
615 
617  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> current_notify_waitable_
619 
622 
624  std::unique_ptr<ExecutorImplementation> impl_;
625 };
626 
627 } // namespace rclcpp
628 
629 #endif // RCLCPP__EXECUTOR_HPP_
Coordinate the order and timing of available communication tasks.
Definition: executor.hpp:61
std::shared_ptr< rclcpp::GuardCondition > interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
Definition: executor.hpp:578
virtual RCLCPP_PUBLIC void spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node)
Add a node, complete all immediately available work, and remove the node.
Definition: executor.cpp:326
virtual RCLCPP_PUBLIC void spin_node_all(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node, std::chrono::nanoseconds max_duration)
Add a node, complete all immediately available work exhaustively, and remove the node.
Definition: executor.cpp:345
virtual RCLCPP_PUBLIC ~Executor()
Default destructor.
Definition: executor.cpp:96
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:160
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.
Definition: executor.hpp:380
rclcpp::WaitSet wait_set_ RCPPUTILS_TSA_GUARDED_BY(mutex_)
WaitSet to be waited on.
RCLCPP_PUBLIC void wait_for_work(std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
Block until more work becomes avilable or timeout is reached.
Definition: executor.cpp:782
RCLCPP_PUBLIC void spin_node_once_nanoseconds(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node, std::chrono::nanoseconds timeout)
Add a node to executor, execute the next available unit of work, and remove the node.
Definition: executor.cpp:256
RCLCPP_PUBLIC Executor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions())
Default constructor.
Definition: executor.cpp:64
RCLCPP_PUBLIC bool get_next_executable(AnyExecutable &any_executable, std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
Wait for executable in ready state and populate union structure.
Definition: executor.cpp:937
virtual RCLCPP_PUBLIC void spin_once(std::chrono::nanoseconds timeout=std::chrono::nanoseconds(-1))
Collect work once and execute the next available work, optionally within a duration.
Definition: executor.cpp:472
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 max duration.
Definition: executor.cpp:339
rclcpp::executors::ExecutorEntitiesCollection current_collection_ RCPPUTILS_TSA_GUARDED_BY(mutex_)
Hold the current state of the collection being waited on by the waitset.
virtual RCLCPP_PUBLIC void cancel()
Cancel any running spin* function, causing it to return.
Definition: executor.cpp:488
static RCLCPP_PUBLIC void execute_timer(const rclcpp::TimerBase::SharedPtr &timer, const std::shared_ptr< void > &data_ptr)
Run timer executable.
Definition: executor.cpp:682
RCLCPP_PUBLIC bool is_spinning()
Returns true if the executor is currently spinning.
Definition: executor.cpp:957
virtual RCLCPP_PUBLIC void handle_updated_entities(bool notify)
This function triggers a recollect of all entities that are registered to the executor.
Definition: executor.cpp:138
RCLCPP_PUBLIC bool get_next_ready_executable(AnyExecutable &any_executable)
Check for executable in ready state and populate union structure.
Definition: executor.cpp:814
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
Definition: executor.hpp:586
std::shared_ptr< rclcpp::executors::ExecutorNotifyWaitable > current_notify_waitable_ RCPPUTILS_TSA_GUARDED_BY(mutex_)
Hold the current state of the notify waitable being waited on by the waitset.
virtual RCLCPP_PUBLIC void remove_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true)
Remove a node from the executor.
Definition: executor.cpp:234
RCLCPP_PUBLIC void collect_entities()
Gather all of the waitable entities from associated nodes and callback groups.
Definition: executor.cpp:714
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_automatically_added_callback_groups_from_nodes()
Get callback groups that belong to executor.
Definition: executor.cpp:167
void spin_node_once(const 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.
Definition: executor.hpp:247
virtual RCLCPP_PUBLIC FutureReturnCode spin_until_future_complete_impl(std::chrono::nanoseconds timeout, const std::function< std::future_status(std::chrono::nanoseconds wait_time)> &wait_for_future)
Spin (blocking) until the future is complete, it times out waiting, or rclcpp is interrupted.
Definition: executor.cpp:267
void spin_node_once(const 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.
Definition: executor.hpp:260
virtual RCLCPP_PUBLIC void remove_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, bool notify=true)
Remove a callback group from the executor.
Definition: executor.cpp:212
static RCLCPP_PUBLIC void execute_client(const rclcpp::ClientBase::SharedPtr &client)
Run service client executable.
Definition: executor.cpp:702
rclcpp::OnShutdownCallbackHandle shutdown_callback_handle_
shutdown callback handle registered to Context
Definition: executor.hpp:621
static RCLCPP_PUBLIC void execute_service(const rclcpp::ServiceBase::SharedPtr &service)
Run service server executable.
Definition: executor.cpp:690
RCLCPP_PUBLIC void execute_any_executable(AnyExecutable &any_exec)
Find the next available executable and do the work associated with it.
Definition: executor.cpp:504
virtual void spin()=0
Do work periodically as it becomes available to us. Blocking call, may block indefinitely.
std::shared_ptr< rclcpp::executors::ExecutorNotifyWaitable > notify_waitable_
Waitable containing guard conditions controlling the executor flow.
Definition: executor.hpp:601
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:153
virtual RCLCPP_PUBLIC void add_callback_group(const rclcpp::CallbackGroup::SharedPtr &group_ptr, const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true)
Add a callback group to an executor.
Definition: executor.cpp:174
virtual RCLCPP_PUBLIC void add_node(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr &node_ptr, bool notify=true)
Add a node to the executor.
Definition: executor.cpp:191
std::atomic_bool cancel_requested_
Tracks a pending cancel request that has not yet been consumed by a spin.
Definition: executor.hpp:575
rclcpp::executors::ExecutorEntitiesCollector collector_
Collector used to associate executable entities from nodes and guard conditions.
Definition: executor.hpp:606
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.
Definition: executor.cpp:362
std::unique_ptr< ExecutorImplementation > impl_
Pointer to implementation.
Definition: executor.hpp:624
RCLCPP_PUBLIC void spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive)
Collect work and execute available work, optionally within a duration.
Definition: executor.cpp:371
static RCLCPP_PUBLIC void execute_subscription(const rclcpp::SubscriptionBase::SharedPtr &subscription)
Run subscription executable.
Definition: executor.cpp:579
std::shared_ptr< rclcpp::GuardCondition > shutdown_guard_condition_
Guard condition for signaling the rmw layer to wake up for system shutdown.
Definition: executor.hpp:581
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin.
Definition: executor.hpp:568
Encapsulates sets of waitable items which can be waited on as a group.
Class to monitor a set of nodes and callback groups for changes in entity membership.
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.
Options to be passed to the executor constructor.
Represent the total set of entities for a single executor.