ROS 2 rclcpp + rcl - jazzy  jazzy
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 
301  RCLCPP_PUBLIC
302  virtual void
303  spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0));
304 
306 
309  RCLCPP_PUBLIC
310  virtual void
312  rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
313  std::chrono::nanoseconds max_duration);
314 
316  RCLCPP_PUBLIC
317  virtual void
318  spin_node_all(std::shared_ptr<rclcpp::Node> node, std::chrono::nanoseconds max_duration);
319 
321 
335  RCLCPP_PUBLIC
336  virtual void
337  spin_all(std::chrono::nanoseconds max_duration);
338 
339 
341 
349  RCLCPP_PUBLIC
350  virtual void
351  spin_once(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
352 
354 
363  template<typename FutureT, typename TimeRepT = int64_t, typename TimeT = std::milli>
366  const FutureT & future,
367  std::chrono::duration<TimeRepT, TimeT> timeout = std::chrono::duration<TimeRepT, TimeT>(-1))
368  {
370  std::chrono::duration_cast<std::chrono::nanoseconds>(timeout),
371  [&future](std::chrono::nanoseconds wait_time) {
372  return future.wait_for(wait_time);
373  }
374  );
375  }
376 
378 
382  RCLCPP_PUBLIC
383  virtual void
384  cancel();
385 
387 
391  RCLCPP_PUBLIC
392  bool
393  is_spinning();
394 
395 protected:
397 
402  explicit Executor(const std::shared_ptr<rclcpp::Context> & context);
403 
405 
412  RCLCPP_PUBLIC
413  void
415  rclcpp::node_interfaces::NodeBaseInterface::SharedPtr node,
416  std::chrono::nanoseconds timeout);
417 
419 
429  RCLCPP_PUBLIC
430  virtual FutureReturnCode
432  std::chrono::nanoseconds timeout,
433  const std::function<std::future_status(std::chrono::nanoseconds wait_time)> & wait_for_future);
434 
436 
444  RCLCPP_PUBLIC
445  void
446  spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive);
447 
449 
454  RCLCPP_PUBLIC
455  void
457 
459 
463  RCLCPP_PUBLIC
464  static void
466  rclcpp::SubscriptionBase::SharedPtr subscription);
467 
469 
473  RCLCPP_PUBLIC
474  static void
475  execute_timer(rclcpp::TimerBase::SharedPtr timer, const std::shared_ptr<void> & data_ptr);
476 
478 
482  RCLCPP_PUBLIC
483  static void
484  execute_service(rclcpp::ServiceBase::SharedPtr service);
485 
487 
491  RCLCPP_PUBLIC
492  static void
493  execute_client(rclcpp::ClientBase::SharedPtr client);
494 
496  RCLCPP_PUBLIC
497  void
499 
501 
507  RCLCPP_PUBLIC
508  void
509  wait_for_work(std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
510 
512 
517  RCLCPP_PUBLIC
518  bool
519  get_next_ready_executable(AnyExecutable & any_executable);
520 
522 
532  RCLCPP_PUBLIC
533  bool
535  AnyExecutable & any_executable,
536  std::chrono::nanoseconds timeout = std::chrono::nanoseconds(-1));
537 
539 
544  void
545  trigger_entity_recollect(bool notify);
546 
548  std::atomic_bool spinning;
549 
551  std::shared_ptr<rclcpp::GuardCondition> interrupt_guard_condition_;
552 
554  std::shared_ptr<rclcpp::GuardCondition> shutdown_guard_condition_;
555 
556  mutable std::mutex mutex_;
557 
559  std::shared_ptr<rclcpp::Context> context_;
560 
561  RCLCPP_DISABLE_COPY(Executor)
562 
563  RCLCPP_PUBLIC
564  virtual void
565  spin_once_impl(std::chrono::nanoseconds timeout);
566 
568 
574  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> notify_waitable_;
575 
576  std::atomic_bool entities_need_rebuild_;
577 
580 
583  std::optional<rclcpp::WaitResult<rclcpp::WaitSet>> wait_result_ RCPPUTILS_TSA_GUARDED_BY(mutex_);
584 
587  mutex_);
588 
590  std::shared_ptr<rclcpp::executors::ExecutorNotifyWaitable> current_notify_waitable_
592 
595 
597  std::unique_ptr<ExecutorImplementation> impl_;
598 };
599 
600 } // namespace rclcpp
601 
602 #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:308
std::shared_ptr< rclcpp::GuardCondition > interrupt_guard_condition_
Guard condition for signaling the rmw layer to wake up for special events.
Definition: executor.hpp:551
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:244
virtual RCLCPP_PUBLIC ~Executor()
Default destructor.
Definition: executor.cpp:92
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_manually_added_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:156
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:202
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:365
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:170
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:742
static RCLCPP_PUBLIC void execute_service(rclcpp::ServiceBase::SharedPtr service)
Run service server executable.
Definition: executor.cpp:650
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:224
RCLCPP_PUBLIC Executor(const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions())
Default constructor.
Definition: executor.cpp:61
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:327
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:914
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:446
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:321
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:456
RCLCPP_PUBLIC bool is_spinning()
Returns true if the executor is currently spinning.
Definition: executor.cpp:934
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
RCLCPP_PUBLIC bool get_next_ready_executable(AnyExecutable &any_executable)
Check for executable in ready state and populate union structure.
Definition: executor.cpp:791
std::shared_ptr< rclcpp::Context > context_
The context associated with this executor.
Definition: executor.hpp:559
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:644
void trigger_entity_recollect(bool notify)
This function triggers a recollect of all entities that are registered to the executor.
Definition: executor.cpp:134
static RCLCPP_PUBLIC void execute_subscription(rclcpp::SubscriptionBase::SharedPtr subscription)
Run subscription executable.
Definition: executor.cpp:543
RCLCPP_PUBLIC void collect_entities()
Gather all of the waitable entities from associated nodes and callback groups.
Definition: executor.cpp:674
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:163
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:255
rclcpp::OnShutdownCallbackHandle shutdown_callback_handle_
shutdown callback handle registered to Context
Definition: executor.hpp:594
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:188
RCLCPP_PUBLIC void execute_any_executable(AnyExecutable &any_exec)
Find the next available executable and do the work associated with it.
Definition: executor.cpp:468
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:574
virtual RCLCPP_PUBLIC std::vector< rclcpp::CallbackGroup::WeakPtr > get_all_callback_groups()
Get callback groups that belong to executor.
Definition: executor.cpp:149
static RCLCPP_PUBLIC void execute_client(rclcpp::ClientBase::SharedPtr client)
Run service client executable.
Definition: executor.cpp:662
rclcpp::executors::ExecutorEntitiesCollector collector_
Collector used to associate executable entities from nodes and guard conditions.
Definition: executor.hpp:579
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:342
std::unique_ptr< ExecutorImplementation > impl_
Pointer to implementation.
Definition: executor.hpp:597
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:351
std::shared_ptr< rclcpp::GuardCondition > shutdown_guard_condition_
Guard condition for signaling the rmw layer to wake up for system shutdown.
Definition: executor.hpp:554
std::atomic_bool spinning
Spinning state, used to prevent multi threaded calls to spin and to cancel blocking spins.
Definition: executor.hpp:548
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.