ROS 2 rclcpp + rcl - rolling  rolling-a919a6e5
ROS 2 C++ Client Library with ROS Client Library
events_executor.hpp
1 // Copyright 2023 iRobot Corporation.
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__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__EVENTS_EXECUTOR_HPP_
16 #define RCLCPP__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__EVENTS_EXECUTOR_HPP_
17 
18 #include <atomic>
19 #include <chrono>
20 #include <memory>
21 #include <vector>
22 
23 #include "rclcpp/executor.hpp"
24 #include "rclcpp/executors/executor_entities_collection.hpp"
25 #include "rclcpp/executors/executor_entities_collector.hpp"
26 #include "rclcpp/experimental/executors/events_executor/events_executor_event_types.hpp"
27 #include "rclcpp/experimental/executors/events_executor/events_queue.hpp"
28 #include "rclcpp/experimental/executors/events_executor/simple_events_queue.hpp"
29 #include "rclcpp/experimental/timers_manager.hpp"
30 #include "rclcpp/node.hpp"
31 
32 namespace rclcpp
33 {
34 namespace experimental
35 {
36 namespace executors
37 {
38 
40 
61 {
62 public:
63  RCLCPP_SMART_PTR_DEFINITIONS(EventsExecutor)
64 
65 
72  RCLCPP_PUBLIC
74  rclcpp::experimental::executors::EventsQueue::UniquePtr events_queue = std::make_unique<
76  bool execute_timers_separate_thread = false,
78 
80  RCLCPP_PUBLIC
81  virtual ~EventsExecutor();
82 
84 
89  RCLCPP_PUBLIC
90  void
91  spin() override;
92 
94 
107  RCLCPP_PUBLIC
108  void
109  spin_some(std::chrono::nanoseconds max_duration = std::chrono::nanoseconds(0)) override;
110 
112 
125  RCLCPP_PUBLIC
126  void
127  spin_all(std::chrono::nanoseconds max_duration) override;
128 
129 protected:
131  RCLCPP_PUBLIC
132  void
133  spin_once_impl(std::chrono::nanoseconds timeout) override;
134 
136  RCLCPP_PUBLIC
137  void
138  spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive);
139 
141  RCLCPP_PUBLIC
142  void
143  handle_updated_entities(bool notify) override;
144 
145 private:
146  RCLCPP_DISABLE_COPY(EventsExecutor)
147 
148 
149  void
150  execute_event(const ExecutorEvent & event);
151 
153  void
154  setup_notify_waitable();
155 
157  void
158  refresh_current_collection(const rclcpp::executors::ExecutorEntitiesCollection & new_collection);
159 
161  std::function<void(size_t)>
162  create_entity_callback(void * entity_key, ExecutorEventType type);
163 
165  std::function<void(size_t, int)>
166  create_waitable_callback(const rclcpp::Waitable * waitable_id);
167 
169  void
170  add_notify_waitable_to_collection(
172 
174  template<typename CollectionType>
175  typename CollectionType::EntitySharedPtr
176  retrieve_entity(typename CollectionType::Key entity_id, CollectionType & collection)
177  {
178  // Note: we lock the mutex because we assume that you are trying to get an element from the
179  // current collection... If there will be a use-case to retrieve elements also from other
180  // collections, we can move the mutex back to the calling codes.
181  std::lock_guard<std::mutex> guard(mutex_);
182 
183  // Check if the entity_id is in the collection
184  auto it = collection.find(entity_id);
185  if (it == collection.end()) {
186  return nullptr;
187  }
188 
189  // Check if the entity associated with the entity_id is valid
190  // and remove it from the collection if it isn't
191  auto entity = it->second.entity.lock();
192  if (!entity) {
193  collection.erase(it);
194  }
195 
196  // Return the retrieved entity (this can be a nullptr if the entity was not valid)
197  return entity;
198  }
199 
201  rclcpp::experimental::executors::EventsQueue::UniquePtr events_queue_;
202 
204  std::shared_ptr<rclcpp::experimental::TimersManager> timers_manager_;
205 };
206 
207 } // namespace executors
208 } // namespace experimental
209 } // namespace rclcpp
210 
211 #endif // RCLCPP__EXPERIMENTAL__EXECUTORS__EVENTS_EXECUTOR__EVENTS_EXECUTOR_HPP_
Coordinate the order and timing of available communication tasks.
Definition: executor.hpp:65
RCLCPP_PUBLIC void spin_once_impl(std::chrono::nanoseconds timeout) override
Internal implementation of spin_once.
RCLCPP_PUBLIC void spin() override
Events executor implementation of spin.
virtual RCLCPP_PUBLIC ~EventsExecutor()
Default destructor.
RCLCPP_PUBLIC void spin_some_impl(std::chrono::nanoseconds max_duration, bool exhaustive)
Internal implementation of spin_some.
RCLCPP_PUBLIC EventsExecutor(rclcpp::experimental::executors::EventsQueue::UniquePtr events_queue=std::make_unique< rclcpp::experimental::executors::SimpleEventsQueue >(), bool execute_timers_separate_thread=false, const rclcpp::ExecutorOptions &options=rclcpp::ExecutorOptions())
Default constructor. See the default constructor for Executor.
RCLCPP_PUBLIC void spin_all(std::chrono::nanoseconds max_duration) override
Events executor implementation of spin all.
RCLCPP_PUBLIC void handle_updated_entities(bool notify) override
Collect entities from callback groups and refresh the current collection with them.
RCLCPP_PUBLIC void spin_some(std::chrono::nanoseconds max_duration=std::chrono::nanoseconds(0)) override
Events executor implementation of spin some.
This class implements an EventsQueue as a simple wrapper around a std::queue. It does not perform any...
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.
Options to be passed to the executor constructor.
Represent the total set of entities for a single executor.