rclcpp  master
C++ ROS Client Library API
timer.hpp
Go to the documentation of this file.
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__TIMER_HPP_
16 #define RCLCPP__TIMER_HPP_
17 
18 #include <chrono>
19 #include <functional>
20 #include <memory>
21 #include <sstream>
22 #include <thread>
23 #include <type_traits>
24 #include <utility>
25 
26 #include "rclcpp/clock.hpp"
27 #include "rclcpp/context.hpp"
29 #include "rclcpp/macros.hpp"
30 #include "rclcpp/rate.hpp"
31 #include "rclcpp/utilities.hpp"
33 #include "tracetools/tracetools.h"
34 #include "tracetools/utils.hpp"
35 
36 #include "rcl/error_handling.h"
37 #include "rcl/timer.h"
38 
39 #include "rmw/error_handling.h"
40 #include "rmw/rmw.h"
41 
42 namespace rclcpp
43 {
44 
45 class TimerBase
46 {
47 public:
49 
51  explicit TimerBase(
52  Clock::SharedPtr clock,
55 
57  ~TimerBase();
58 
60  void
61  cancel();
62 
64 
70  bool
71  is_canceled();
72 
74  void
75  reset();
76 
78  virtual void
79  execute_callback() = 0;
80 
84 
86 
90 
92 
93  virtual bool is_steady() = 0;
94 
96 
102  bool is_ready();
103 
104 protected:
107 };
108 
109 
112 
114 template<
115  typename FunctorT,
116  typename std::enable_if<
119  >::type * = nullptr
120 >
121 class GenericTimer : public TimerBase
122 {
123 public:
125 
126 
127 
132  explicit GenericTimer(
133  Clock::SharedPtr clock, std::chrono::nanoseconds period, FunctorT && callback,
134  rclcpp::Context::SharedPtr context
135  )
136  : TimerBase(clock, period, context), callback_(std::forward<FunctorT>(callback))
137  {
138  TRACEPOINT(
139  rclcpp_timer_callback_added,
140  (const void *)get_timer_handle().get(),
141  (const void *)&callback_);
142  TRACEPOINT(
143  rclcpp_callback_register,
144  (const void *)&callback_,
145  get_symbol(callback_));
146  }
147 
149  virtual ~GenericTimer()
150  {
151  // Stop the timer from running.
152  cancel();
153  }
154 
155  void
156  execute_callback() override
157  {
159  if (ret == RCL_RET_TIMER_CANCELED) {
160  return;
161  }
162  if (ret != RCL_RET_OK) {
163  throw std::runtime_error("Failed to notify timer that callback occurred");
164  }
165  TRACEPOINT(callback_start, (const void *)&callback_, false);
166  execute_callback_delegate<>();
167  TRACEPOINT(callback_end, (const void *)&callback_);
168  }
169 
170  // void specialization
171  template<
172  typename CallbackT = FunctorT,
173  typename std::enable_if<
175  >::type * = nullptr
176  >
177  void
179  {
180  callback_();
181  }
182 
183  template<
184  typename CallbackT = FunctorT,
185  typename std::enable_if<
187  >::type * = nullptr
188  >
189  void
191  {
192  callback_(*this);
193  }
194 
195  bool
196  is_steady() override
197  {
198  return clock_->get_clock_type() == RCL_STEADY_TIME;
199  }
200 
201 protected:
203 
204  FunctorT callback_;
205 };
206 
207 template<
208  typename FunctorT,
209  typename std::enable_if<
210  rclcpp::function_traits::same_arguments<FunctorT, VoidCallbackType>::value ||
211  rclcpp::function_traits::same_arguments<FunctorT, TimerCallbackType>::value
212  >::type * = nullptr
213 >
214 class WallTimer : public GenericTimer<FunctorT>
215 {
216 public:
218 
220  std::chrono::nanoseconds period,
221  FunctorT && callback,
222  rclcpp::Context::SharedPtr context)
223  : GenericTimer<FunctorT>(
224  std::make_shared<Clock>(RCL_STEADY_TIME), period, std::move(callback), context)
225  {}
226 
227 protected:
229 };
230 
231 } // namespace rclcpp
232 
233 #endif // RCLCPP__TIMER_HPP_
virtual void execute_callback()=0
#define RCLCPP_DISABLE_COPY(...)
Definition: macros.hpp:26
Clock::SharedPtr clock_
Definition: timer.hpp:105
rmw_ret_t rcl_ret_t
Definition: timer.hpp:214
bool is_ready()
Check if the timer is ready to trigger the callback.
Context which encapsulates shared state between nodes and other similar entities. ...
Definition: context.hpp:53
#define RCL_RET_TIMER_CANCELED
std::chrono::nanoseconds time_until_trigger()
Check how long the timer has until its next scheduled callback.
void execute_callback_delegate()
Definition: timer.hpp:178
This header provides the get_node_base_interface() template function.
Definition: allocator_common.hpp:24
virtual ~GenericTimer()
Default destructor.
Definition: timer.hpp:149
Generic timer. Periodically executes a user-specified callback.
Definition: timer.hpp:121
#define RCL_RET_OK
rcl_ret_t rcl_timer_call(rcl_timer_t *timer)
virtual bool is_steady()=0
Is the clock steady (i.e. is the time between ticks constant?)
#define RCLCPP_SMART_PTR_DEFINITIONS(...)
Definition: macros.hpp:36
RCL_STEADY_TIME
Definition: function_traits.hpp:161
TimerBase(Clock::SharedPtr clock, std::chrono::nanoseconds period, rclcpp::Context::SharedPtr context)
std::shared_ptr< const rcl_timer_t > get_timer_handle()
Definition: clock.hpp:51
#define RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(...)
Definition: macros.hpp:51
bool is_steady() override
Is the clock steady (i.e. is the time between ticks constant?)
Definition: timer.hpp:196
T get(T... args)
#define RCLCPP_PUBLIC
Definition: visibility_control.hpp:50
Set the data type used in the intra-process buffer as std::shared_ptr<MessageT>
void execute_callback() override
Definition: timer.hpp:156
std::shared_ptr< rcl_timer_t > timer_handle_
Definition: timer.hpp:106
Definition: timer.hpp:45
bool is_canceled()
Return the timer cancellation state.