ROS 2 rclcpp + rcl - rolling  rolling-20536064
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 <algorithm>
19 #include <cassert>
20 #include <chrono>
21 #include <cstdlib>
22 #include <iostream>
23 #include <map>
24 #include <memory>
25 #include <mutex>
26 #include <string>
27 #include <vector>
28 
29 #include "rcl/guard_condition.h"
30 #include "rcl/wait.h"
31 #include "rclcpp/executors/executor_notify_waitable.hpp"
32 #include "rcpputils/scope_exit.hpp"
33 
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/executors/executor_entities_collection.hpp"
39 #include "rclcpp/executors/executor_entities_collector.hpp"
40 #include "rclcpp/future_return_code.hpp"
41 #include "rclcpp/node_interfaces/node_base_interface.hpp"
42 #include "rclcpp/utilities.hpp"
43 #include "rclcpp/visibility_control.hpp"
44 #include "rclcpp/wait_set.hpp"
45 
46 namespace rclcpp
47 {
48 
49 // Forward declaration is used in convenience method signature.
50 class Node;
51 class ExecutorImplementation;
52 
54 
63 class Executor
64 {
65 public:
66  RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(Executor)
67 
68 
72  RCLCPP_PUBLIC
73  explicit Executor(const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions());
74 
76  RCLCPP_PUBLIC
77  virtual ~Executor();
78 
80  // It is up to the implementation of Executor to implement spin.
81  virtual void
82  spin() = 0;
83 
85 
101  RCLCPP_PUBLIC
102  virtual void
104  const rclcpp::CallbackGroup::SharedPtr & group_ptr,
105  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
106  bool notify = true);
107 
109 
120  RCLCPP_PUBLIC
121  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
123 
125 
134  RCLCPP_PUBLIC
135  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
137 
139 
149  RCLCPP_PUBLIC
150  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
152 
154 
172  RCLCPP_PUBLIC
173  virtual void
175  const rclcpp::CallbackGroup::SharedPtr & group_ptr,
176  bool notify = true);
177 
179 
197  RCLCPP_PUBLIC
198  virtual void
199  add_node(
200  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
201  bool notify = true);
202 
204 
207  RCLCPP_PUBLIC
208  virtual void
209  add_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
210 
212 
227  RCLCPP_PUBLIC
228  virtual void
229  remove_node(
230  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node_ptr,
231  bool notify = true);
232 
234 
237  RCLCPP_PUBLIC
238  virtual void
239  remove_node(const std::shared_ptr<rclcpp::Node> & node_ptr, bool notify = true);
240 
242 
248  template<typename RepT = int64_t, typename T = std::milli>
249  void
251  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
252  std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
253  {
255  node,
256  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
257  );
258  }
259 
261  template<typename NodeT = rclcpp::Node, typename RepT = int64_t, typename T = std::milli>
262  void
264  const std::shared_ptr<NodeT> & node,
265  std::chrono::duration<RepT, T> timeout = std::chrono::duration<RepT, T>(-1))
266  {
268  node->get_node_base_interface(),
269  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout)
270  );
271  }
272 
274 
277  RCLCPP_PUBLIC
278  virtual void
279  spin_node_some(const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node);
280 
282  RCLCPP_PUBLIC
283  virtual void
284  spin_node_some(const std::shared_ptr<rclcpp::Node> & node);
285 
287 
316  RCLCPP_PUBLIC
317  virtual void
318  spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0));
319 
321 
324  RCLCPP_PUBLIC
325  virtual void
327  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
328  std::chrono::nanoseconds max_duration);
329 
331  RCLCPP_PUBLIC
332  virtual void
333  spin_node_all(const std::shared_ptr<rclcpp::Node> & node, std::chrono::nanoseconds max_duration);
334 
336 
350  RCLCPP_PUBLIC
351  virtual void
352  spin_all(std::chrono::nanoseconds max_duration);
353 
354 
356 
364  RCLCPP_PUBLIC
365  virtual void
366  spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
367 
369 
381  template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::milli>
384  const FutureT & future,
385  std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
386  {
388  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout),
389  [&future](std::chrono::nanoseconds wait_time) {
390  return future.wait_for(wait_time);
391  }
392  );
393  }
394 
396 
400  RCLCPP_PUBLIC
401  virtual void
402  cancel();
403 
405 
409  RCLCPP_PUBLIC
410  bool
411  is_spinning();
412 
413 protected:
415 
420  explicit Executor(const std::shared_ptr<rclcpp::Context> & context);
421 
423 
430  RCLCPP_PUBLIC
431  void
433  const rclcpp::node_interfaces::NodeBaseInterface::SharedPtr & node,
434  std::chrono::nanoseconds timeout);
435 
437 
447  RCLCPP_PUBLIC
448  virtual FutureReturnCode
450  std::chrono::nanoseconds timeout,
451  const std::function<std::future_status(std::chrono::nanoseconds wait_time)> & wait_for_future);
452 
454 
462  RCLCPP_PUBLIC
463  void
464  spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive);
465 
467 
472  RCLCPP_PUBLIC
473  void
475 
477 
481  RCLCPP_PUBLIC
482  static void
484  const rclcpp::SubscriptionBase::SharedPtr & subscription);
485 
487 
491  RCLCPP_PUBLIC
492  static void
493  execute_timer(const rclcpp::TimerBase::SharedPtr & timer, const std::shared_ptr<void> & data_ptr);
494 
496 
500  RCLCPP_PUBLIC
501  static void
502  execute_service(const rclcpp::ServiceBase::SharedPtr & service);
503 
505 
509  RCLCPP_PUBLIC
510  static void
511  execute_client(const rclcpp::ClientBase::SharedPtr & client);
512 
514  RCLCPP_PUBLIC
515  void
517 
519 
525  RCLCPP_PUBLIC
526  void
527  wait_for_work(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
528 
530 
535  RCLCPP_PUBLIC
536  bool
537  get_next_ready_executable(AnyExecutable & any_executable);
538 
540 
550  RCLCPP_PUBLIC
551  bool
553  AnyExecutable & any_executable,
554  std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
555 
557 
562  RCLCPP_PUBLIC
563  virtual void
564  handle_updated_entities(bool notify);
565 
567 
571  std::atomic_bool spinning;
572 
574 
578  std::atomic_bool cancel_requested_;
579 
581  std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
582 
584  std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
585 
586  mutable std::mutex mutex_;
587 
589  std::shared_ptr<rclcpp::Context> context_;
590 
591  RCLCPP_DISABLE_COPY(Executor)
592 
593  RCLCPP_PUBLIC
594  virtual void
595  spin_once_impl(std::chrono::nanoseconds timeout);
596 
598 
604  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> notify_waitable_;
605 
606  std::atomic_bool entities_need_rebuild_;
607 
610 
613  std::optional<rclcpp::WaitResult<rclcpp::WaitSet>> wait_result_ RCPPUTILS_TSA_GUARDED_BY(mutex_);
614 
617  mutex_);
618 
620  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> current_notify_waitable_
622 
625 
627  std::unique_ptr<ExecutorImplementation> impl_;
628 };
629 
630 } // namespace rclcpp
631 
632 #endif // RCLCPP__EXECUTOR_HPP_
Coordinate the order and timing of available communication tasks.
Definition: executor.hpp:64
std::shared_ptr< rclcpp::GuardCondition > interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
Definition: executor.hpp:581
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:383
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:589
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:250
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:263
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:624
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:604
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:578
rclcpp::executors::ExecutorEntitiesCollector collector_
Collector used to associate executable entities from nodes and guard conditions.
Definition: executor.hpp:609
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:627
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:584
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin.
Definition: executor.hpp:571
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.