ROS 2 rclcpp + rcl - rolling  rolling-b14af74a
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 <list>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 #include <string>
28 #include <vector>
29 
30 #include "rcl/guard_condition.h"
31 #include "rcl/wait.h"
32 #include "rclcpp/executors/executor_notify_waitable.hpp"
33 #include "rcpputils/scope_exit.hpp"
34 
35 #include "rclcpp/context.hpp"
36 #include "rclcpp/contexts/default_context.hpp"
37 #include "rclcpp/guard_condition.hpp"
38 #include "rclcpp/executor_options.hpp"
39 #include "rclcpp/executors/executor_entities_collection.hpp"
40 #include "rclcpp/executors/executor_entities_collector.hpp"
41 #include "rclcpp/future_return_code.hpp"
42 #include "rclcpp/node_interfaces/node_base_interface.hpp"
43 #include "rclcpp/utilities.hpp"
44 #include "rclcpp/visibility_control.hpp"
45 #include "rclcpp/wait_set.hpp"
46 
47 namespace rclcpp
48 {
49 
50 // Forward declaration is used in convenience method signature.
51 class Node;
52 class ExecutorImplementation;
53 
55 
64 class Executor
65 {
66 public:
67  RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(Executor)
68 
69 
73  RCLCPP_PUBLIC
74  explicit Executor(const rclcpp::ExecutorOptions & options = rclcpp::ExecutorOptions());
75 
77  RCLCPP_PUBLIC
78  virtual ~Executor();
79 
81  // It is up to the implementation of Executor to implement spin.
82  virtual void
83  spin() = 0;
84 
86 
102  RCLCPP_PUBLIC
103  virtual void
105  rclcpp::CallbackGroup::SharedPtr group_ptr,
106  rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr,
107  bool notify = true);
108 
110 
121  RCLCPP_PUBLIC
122  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
124 
126 
135  RCLCPP_PUBLIC
136  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
138 
140 
150  RCLCPP_PUBLIC
151  virtual std::vector<rclcpp::CallbackGroup::WeakPtr>
153 
155 
173  RCLCPP_PUBLIC
174  virtual void
176  rclcpp::CallbackGroup::SharedPtr group_ptr,
177  bool notify = true);
178 
180 
198  RCLCPP_PUBLIC
199  virtual void
200  add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify = true);
201 
203 
206  RCLCPP_PUBLIC
207  virtual void
208  add_node(std::shared_ptr<rclcpp::Node> node_ptr, bool notify = true);
209 
211 
226  RCLCPP_PUBLIC
227  virtual void
228  remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify = true);
229 
231 
234  RCLCPP_PUBLIC
235  virtual void
236  remove_node(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  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  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(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node);
277 
279  RCLCPP_PUBLIC
280  virtual void
281  spin_node_some(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  rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
325  std::chrono::nanoseconds max_duration);
326 
328  RCLCPP_PUBLIC
329  virtual void
330  spin_node_all(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  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  rclcpp::SubscriptionBase::SharedPtr subscription);
482 
484 
488  RCLCPP_PUBLIC
489  static void
490  execute_timer(rclcpp::TimerBase::SharedPtr timer, const std::shared_ptr<void> & data_ptr);
491 
493 
497  RCLCPP_PUBLIC
498  static void
499  execute_service(rclcpp::ServiceBase::SharedPtr service);
500 
502 
506  RCLCPP_PUBLIC
507  static void
508  execute_client(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  std::atomic_bool spinning;
565 
567  std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
568 
570  std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
571 
572  mutable std::mutex mutex_;
573 
575  std::shared_ptr<rclcpp::Context> context_;
576 
577  RCLCPP_DISABLE_COPY(Executor)
578 
579  RCLCPP_PUBLIC
580  virtual void
581  spin_once_impl(std::chrono::nanoseconds timeout);
582 
584 
590  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> notify_waitable_;
591 
592  std::atomic_bool entities_need_rebuild_;
593 
596 
599  std::optional<rclcpp::WaitResult<rclcpp::WaitSet>> wait_result_ RCPPUTILS_TSA_GUARDED_BY(mutex_);
600 
603  mutex_);
604 
606  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> current_notify_waitable_
608 
611 
613  std::unique_ptr<ExecutorImplementation> impl_;
614 };
615 
616 } // namespace rclcpp
617 
618 #endif // RCLCPP__EXECUTOR_HPP_
Coordinate the order and timing of available communication tasks.
Definition: executor.hpp:65
virtual RCLCPP_PUBLIC void spin_node_some(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node)
Add a node, complete all immediately available work, and remove the node.
Definition: executor.cpp:314
std::shared_ptr< rclcpp::GuardCondition > interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
Definition: executor.hpp:567
RCLCPP_PUBLIC void spin_node_once_nanoseconds(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:250
virtual RCLCPP_PUBLIC ~Executor()
Default destructor.
Definition: executor.cpp:94
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:158
virtual RCLCPP_PUBLIC void remove_callback_group(rclcpp::CallbackGroup::SharedPtr group_ptr, bool notify=true)
Remove a callback group from the executor.
Definition: executor.cpp:208
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.
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.
Definition: executor.cpp:172
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:749
static RCLCPP_PUBLIC void execute_service(rclcpp::ServiceBase::SharedPtr service)
Run service server executable.
Definition: executor.cpp:657
virtual RCLCPP_PUBLIC void remove_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true)
Remove a node from the executor.
Definition: executor.cpp:230
RCLCPP_PUBLIC Executor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions())
Default constructor.
Definition: executor.cpp:63
virtual RCLCPP_PUBLIC void spin_node_all(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:333
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:904
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:452
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:327
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:462
RCLCPP_PUBLIC bool is_spinning()
Returns true if the executor is currently spinning.
Definition: executor.cpp:924
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.
Definition: executor.hpp:260
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:136
RCLCPP_PUBLIC bool get_next_ready_executable(AnyExecutable &any_executable)
Check for executable in ready state and populate union structure.
Definition: executor.cpp:781
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
Definition: executor.hpp:575
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.
static RCLCPP_PUBLIC void execute_timer(rclcpp::TimerBase::SharedPtr timer, const std::shared_ptr< void > &data_ptr)
Run timer executable.
Definition: executor.cpp:651
static RCLCPP_PUBLIC void execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription)
Run subscription executable.
Definition: executor.cpp:549
RCLCPP_PUBLIC void collect_entities()
Gather all of the waitable entities from associated nodes and callback groups.
Definition: executor.cpp:681
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:165
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:261
rclcpp::OnShutdownCallbackHandle shutdown_callback_handle_
shutdown callback handle registered to Context
Definition: executor.hpp:610
virtual RCLCPP_PUBLIC void add_node(rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node_ptr, bool notify=true)
Add a node to the executor.
Definition: executor.cpp:189
RCLCPP_PUBLIC void execute_any_executable(AnyExecutable &any_exec)
Find the next available executable and do the work associated with it.
Definition: executor.cpp:474
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:590
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:151
static RCLCPP_PUBLIC void execute_client(rclcpp::ClientBase::SharedPtr client)
Run service client executable.
Definition: executor.cpp:669
rclcpp::executors::ExecutorEntitiesCollector collector_
Collector used to associate executable entities from nodes and guard conditions.
Definition: executor.hpp:595
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:348
std::unique_ptr< ExecutorImplementation > impl_
Pointer to implementation.
Definition: executor.hpp:613
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.
Definition: executor.hpp:247
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:357
std::shared_ptr< rclcpp::GuardCondition > shutdown_guard_condition_
Guard condition for signaling the rmw layer to wake up for system shutdown.
Definition: executor.hpp:570
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin and to cancel blocking spins.
Definition: executor.hpp:564
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.