rclcpp  beta1
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 
27 #include "rclcpp/macros.hpp"
28 #include "rclcpp/rate.hpp"
29 #include "rclcpp/utilities.hpp"
31 
32 #include "rcl/error_handling.h"
33 #include "rcl/timer.h"
34 
35 #include "rmw/error_handling.h"
36 #include "rmw/rmw.h"
37 
38 namespace rclcpp
39 {
40 namespace timer
41 {
42 
43 class TimerBase
44 {
45 public:
47 
49  explicit TimerBase(std::chrono::nanoseconds period);
50 
52  ~TimerBase();
53 
55  void
56  cancel();
57 
59  virtual void
60  execute_callback() = 0;
61 
63  const rcl_timer_t *
65 
67 
71 
73 
74  virtual bool is_steady() = 0;
75 
77 
83  bool is_ready();
84 
85 protected:
87 };
88 
89 
92 
94 template<
95  typename FunctorT,
96  class Clock,
97  typename std::enable_if<
100  Clock::is_steady
101  >::type * = nullptr
102 >
103 class GenericTimer : public TimerBase
104 {
105 public:
107 
108 
109 
113  GenericTimer(std::chrono::nanoseconds period, FunctorT && callback)
114  : TimerBase(period), callback_(std::forward<FunctorT>(callback))
115  {
116  }
117 
119  virtual ~GenericTimer()
120  {
121  // Stop the timer from running.
122  cancel();
124  fprintf(stderr, "Failed to clean up rcl timer handle: %s\n", rcl_get_error_string_safe());
125  }
126  }
127 
128  void
130  {
132  if (ret == RCL_RET_TIMER_CANCELED) {
133  return;
134  }
135  if (ret != RCL_RET_OK) {
136  throw std::runtime_error("Failed to notify timer that callback occurred");
137  }
138  execute_callback_delegate<>();
139  }
140 
141  // void specialization
142  template<
143  typename CallbackT = FunctorT,
144  typename std::enable_if<
146  >::type * = nullptr
147  >
148  void
150  {
151  callback_();
152  }
153 
154  template<
155  typename CallbackT = FunctorT,
156  typename std::enable_if<
158  >::type * = nullptr
159  >
160  void
162  {
163  callback_(*this);
164  }
165 
166  virtual bool
168  {
169  return Clock::is_steady;
170  }
171 
172 protected:
174 
175  FunctorT callback_;
176 };
177 
178 template<typename CallbackType>
179 using WallTimer = GenericTimer<CallbackType, std::chrono::steady_clock>;
180 
181 } // namespace timer
182 } // namespace rclcpp
183 
184 #endif // RCLCPP__TIMER_HPP_
#define RCLCPP_DISABLE_COPY(...)
Definition: macros.hpp:26
virtual void execute_callback()=0
rmw_ret_t rcl_ret_t
void execute_callback_delegate()
Definition: timer.hpp:149
#define RCL_RET_TIMER_CANCELED
Generic timer templated on the clock type. Periodically executes a user-specified callback...
Definition: timer.hpp:103
Definition: allocator_common.hpp:24
rcl_ret_t rcl_timer_fini(rcl_timer_t *timer)
Definition: timer.hpp:43
rcl_timer_t rcl_get_zero_initialized_timer(void)
rcl_ret_t rcl_timer_call(rcl_timer_t *timer)
#define RCL_RET_OK
rcl_timer_t timer_handle_
Definition: timer.hpp:86
virtual ~GenericTimer()
Default destructor.
Definition: timer.hpp:119
#define RCLCPP_SMART_PTR_DEFINITIONS(...)
Definition: macros.hpp:36
Definition: function_traits.hpp:141
#define rcl_get_error_string_safe
void execute_callback()
Definition: timer.hpp:129
#define RCLCPP_SMART_PTR_DEFINITIONS_NOT_COPYABLE(...)
Definition: macros.hpp:51
TimerBase(std::chrono::nanoseconds period)
#define RCLCPP_PUBLIC
Definition: visibility_control.hpp:50
std::chrono::nanoseconds time_until_trigger()
Check how long the timer has until its next scheduled callback.
bool is_ready()
Check if the timer is ready to trigger the callback.
virtual bool is_steady()
Is the clock steady (i.e. is the time between ticks constant?)
Definition: timer.hpp:167
virtual bool is_steady()=0
Is the clock steady (i.e. is the time between ticks constant?)
const rcl_timer_t * get_timer_handle()