isolated_async_timer.h
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2018, University of Luxembourg
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of University of Luxembourg nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * Author: Maciej Zurad
36  *********************************************************************/
44 #ifndef ROBOT_ACTIVITY_ISOLATED_ASYNC_TIMER_H
45 #define ROBOT_ACTIVITY_ISOLATED_ASYNC_TIMER_H
46 
47 #include <atomic>
48 
49 #include <ros/ros.h>
50 #include <ros/console.h>
51 #include <ros/callback_queue.h>
52 
53 namespace robot_activity
54 {
55 
63 {
64 public:
65  typedef std::function<void(void)> LambdaCallback;
66 
71  IsolatedAsyncTimer() = delete;
72 
88  IsolatedAsyncTimer(const ros::NodeHandle& node_handle,
89  const IsolatedAsyncTimer::LambdaCallback& callback,
90  const float& frequency,
91  bool stoppable = true,
92  bool autostart = true,
93  bool oneshot = false)
94  : IsolatedAsyncTimer(node_handle,
95  to_timer_callback(callback),
96  frequency,
97  stoppable,
98  autostart,
99  oneshot) { }
100 
118  const ros::TimerCallback& callback,
119  const float& frequency,
120  bool stoppable = true,
121  bool autostart = true,
122  bool oneshot = false)
123  : node_handle_(node_handle),
124  timer_ops_(),
125  callback_queue_(),
126  stoppable_(stoppable),
127  paused_(true)
128  {
129  callback_ = wrapTimerCallback(callback);
130 
131  frequency_ = frequency;
132  period_ = ros::Duration(1.0 / frequency);
133 
137  timer_ops_.oneshot = oneshot;
138  timer_ops_.autostart = autostart;
139 
140  timer_ = std::make_shared<ros::Timer>();
142 
143  spinner_ = std::make_shared<ros::AsyncSpinner>(1, &callback_queue_);
144  spinner_->start();
145  }
146 
151  {
152  ROS_DEBUG("IsolatedAsyncTimer destructor");
153  }
154 
158  void start()
159  {
160  timer_->start();
161  }
162 
166  void stop()
167  {
168  if (stoppable_)
169  timer_->stop();
170  }
171 
175  void pause()
176  {
177  paused_ = true;
178  }
179 
183  void resume()
184  {
185  paused_ = false;
186  }
187 
191  bool isValid()
192  {
193  return timer_->isValid();
194  }
195 
206  void setRate(const float& frequency, bool reset = true)
207  {
208  frequency_ = frequency;
209  period_ = ros::Duration(1.0 / frequency);
210  timer_->setPeriod(period_, reset);
211  }
212 
220  const IsolatedAsyncTimer::LambdaCallback& callback)
221  {
222  return [callback](const ros::TimerEvent & event)
223  {
224  callback();
225  };
226  }
227 
228 private:
238  {
239  return [ = ](const ros::TimerEvent & ev)
240  {
241  if (stoppable_ == false || paused_ == false)
242  {
243  auto last_loop_duration = ev.profile.last_duration.toSec();
244  if (ev.last_real.toSec() != 0 && last_loop_duration > period_.toSec())
245  {
246  auto lag = last_loop_duration - period_.toSec();
248  "Missed it's desired rate of " << frequency_ <<
249  " [Hz], the loop actually took " << last_loop_duration
250  << " [s], which is " << lag << " [s] longer");
251  }
252  callback(ev);
253  }
254  };
255  }
256 
261 
265  float frequency_;
266 
271 
276 
281 
286 
287 
291  std::shared_ptr<ros::Timer> timer_;
292 
297  std::shared_ptr<ros::AsyncSpinner> spinner_;
298 
302  std::atomic<bool> stoppable_;
303 
307  std::atomic<bool> paused_;
308 };
309 
310 } // namespace robot_activity
311 
312 #endif // ROBOT_ACTIVITY_ISOLATED_ASYNC_TIMER_H
std::atomic< bool > paused_
Atomic bool that determines whether timer is paused or not.
ros::TimerOptions timer_ops_
Timer options needed for.
ros::TimerCallback wrapTimerCallback(const ros::TimerCallback &callback) const
Wraps a ros::TimerCallback with additional functionality.
float frequency_
Frequency in Hz of the timer.
IsolatedAsyncTimer(const ros::NodeHandle &node_handle, const ros::TimerCallback &callback, const float &frequency, bool stoppable=true, bool autostart=true, bool oneshot=false)
Constructor.
#define ROS_WARN_STREAM_THROTTLE(period, args)
bool isValid()
Returns true if timer is valid.
boost::function< void(const TimerEvent &)> TimerCallback
std::function< void(void)> LambdaCallback
IsolatedAsyncTimer()=delete
Default destructor is deleted.
CallbackQueueInterface * callback_queue
std::shared_ptr< ros::AsyncSpinner > spinner_
Shared pointer to the actual ros::AsyncSpiner that serves the callback queue in the background...
IsolatedAsyncTimer(const ros::NodeHandle &node_handle, const IsolatedAsyncTimer::LambdaCallback &callback, const float &frequency, bool stoppable=true, bool autostart=true, bool oneshot=false)
Constructor.
ros::NodeHandle node_handle_
Node handle used to create the actual ros::Timer.
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
TimerCallback callback
ros::TimerCallback callback_
Actual ros::TimerCallback used in the timer.
std::atomic< bool > stoppable_
Atomic bool that determines whether timer is stoppable or not.
ros::Duration period_
Duration between consecutive callback executions.
std::shared_ptr< ros::Timer > timer_
Shared pointer to the actual ros::Timer object.
ros::CallbackQueue callback_queue_
Seperate callback queue for the timer.
void stop()
Stops the timer if set to stoppable.
void setRate(const float &frequency, bool reset=true)
Sets a new rate to the timer.
#define ROS_DEBUG(...)
static ros::TimerCallback to_timer_callback(const IsolatedAsyncTimer::LambdaCallback &callback)
Converts a Lambda callback to valid ros::TimerCallback.


robot_activity
Author(s): Maciej ZURAD
autogenerated on Thu Jun 6 2019 19:32:17