NimbRo ROS Soccer Package
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ros_timing.h
1 // Utilities for timing events and actions using the ROS time
2 // File: ros_timing.h
3 // Author: Philipp Allgeuer <pallgeuer@ais.uni-bonn.de>
4 
5 // Ensure header is only included once
6 #ifndef ROS_TIMING_H
7 #define ROS_TIMING_H
8 
9 // Includes
10 #include <cstddef>
11 #include <ros/time.h>
12 #include <ros/service_client.h>
13 
14 // Nimbro utilities namespace
15 namespace nimbro_utils
16 {
28  {
29  public:
30  // Constructors
31  RosTimeMarker() : markerTime(0), iHaveMarker(false) {}
32 
33  // Timing functions
34  void unsetMarker() { iHaveMarker = false; }
35  void setMarker()
36  {
37  // Record the current ROS time
38  markerTime = ros::Time::now();
39  iHaveMarker = true;
40  }
41  bool haveMarker() const { return iHaveMarker; }
42  double getElapsed() const { return (iHaveMarker ? (ros::Time::now() - markerTime).toSec() : -1.0); }
43  bool hasElapsed(double duration) const { return !iHaveMarker || (iHaveMarker && ((ros::Time::now() - markerTime).toSec() >= duration)); }
44 
45  private:
46  // Internal variables
47  ros::Time markerTime;
48  bool iHaveMarker;
49  };
50 
64  {
65  public:
67  explicit RosTimeTracker(std::size_t N) : N(N)
68  {
69  // Make sure we have room for at least one marker
70  if(N < 1) N = 1;
71 
72  // Allocate memory for the marker and flag arrays
73  markerTime = new ros::Time[N];
74  iHaveMarker = new bool[N];
75 
76  // Initialise the arrays explicitly
77  for(std::size_t i = 0;i < N;i++)
78  {
79  markerTime[i].fromSec(0);
80  iHaveMarker[i] = false;
81  }
82  }
83 
85  virtual ~RosTimeTracker()
86  {
87  // Delete the allocated memory
88  delete[] markerTime;
89  delete[] iHaveMarker;
90  }
91 
92  // Timing functions (in all these functions m is the index of the marker, valid values are 0 -> N-1)
94  void unsetMarker(std::size_t m)
95  {
96  // Forget the required marker
97  if(m < N) iHaveMarker[m] = false;
98  }
100  void setMarker(std::size_t m)
101  {
102  // Record the current ROS time in the appropriate marker
103  if(m < N)
104  {
105  markerTime[m] = ros::Time::now();
106  iHaveMarker[m] = true;
107  }
108  }
110  bool haveMarker(std::size_t m) const { return (m < N ? iHaveMarker[m] : false); }
112  double getElapsed(std::size_t m) const
113  {
114  // Return the elapsed time since marker m was set
115  if(m < N) return (iHaveMarker[m] ? (ros::Time::now() - markerTime[m]).toSec() : -1.0);
116  else return -1.0;
117  }
119  bool hasElapsed(std::size_t m, double duration) const
120  {
121  // Return whether the given duration has elapsed since marker m was set
122  if(m < N) return !iHaveMarker[m] || (iHaveMarker[m] && ((ros::Time::now() - markerTime[m]).toSec() >= duration));
123  else return false;
124  }
125 
126  private:
127  // Internal variables
128  ros::Time* markerTime;
129  bool* iHaveMarker;
130  std::size_t N;
131  };
132 
169  template <class T>
171  {
172  public:
179  RosServiceCaller(double reissueDelay, double failRetryDelay)
180  : failRetryDelay(failRetryDelay)
181  , reissueDelay(reissueDelay)
182  {}
183 
184  // Service client set function
185  void setServiceClient(const ros::ServiceClient& SC) { m_srv = SC; }
186 
187  // Service call functions
189  bool callService() { return callService(data); }
191  bool callService(T& srv_data)
192  {
193  // Declare variables
194  bool ret = false;
195 
196  // Decide whether to call the service or not (don't want to spam the service by calling it every time!)
197  if(lastGoodCall.hasElapsed(reissueDelay) && lastBadCall.hasElapsed(failRetryDelay))
198  {
199  ret = m_srv.call<T>(srv_data); // If setServiceClient() hasn't been called (i.e. m_srv is invalid) then this returns false
200  if(ret) lastGoodCall.setMarker();
201  else lastBadCall.setMarker();
202  }
203 
204  // Return whether the service call was carried out AND was successful
205  return ret;
206  }
207 
208  public:
209  // Variables
210  T data;
211 
212  private:
213  // Internal variables
214  const double failRetryDelay;
215  const double reissueDelay;
216  ros::ServiceClient m_srv;
217  RosTimeMarker lastGoodCall;
218  RosTimeMarker lastBadCall;
219  };
220 }
221 
222 #endif /* ROS_TIMING_H */
223 // EOF
bool callService()
Call the required service with the request data stored in the data class member.
Definition: ros_timing.h:189
bool callService(T &srv_data)
Call the required service with the request data stored in srv_data.
Definition: ros_timing.h:191
RosTimeTracker(std::size_t N)
Default constructor.
Definition: ros_timing.h:67
double getElapsed() const
Returns the current elapsed time since the marker was set (returns -1.0 if no marker has been set - c...
Definition: ros_timing.h:42
bool hasElapsed(double duration) const
Returns whether a certain time duration has elapsed since the time marker was set (returns true if no...
Definition: ros_timing.h:43
void setMarker()
Set the time marker to the current ROS time (future calls to getElapsed() and hasElapsed() will be ev...
Definition: ros_timing.h:35
Class that facilitates the timing of multiple durations using ROS-time.
Definition: ros_timing.h:63
Provides basic functionality for controlling calls to ROS services.
Definition: ros_timing.h:170
void unsetMarker()
Forget any time marker that may have been set previously.
Definition: ros_timing.h:34
Class that facilitates the timing of durations using ROS-time.
Definition: ros_timing.h:27
void setMarker(std::size_t m)
Set the m-th time marker to the current ROS time (future calls to getElapsed(m) and hasElapsed(m...
Definition: ros_timing.h:100
T data
Request variable (can choose to use this instead of providing your own in the calling scope of callSe...
Definition: ros_timing.h:210
virtual ~RosTimeTracker()
Object destructor.
Definition: ros_timing.h:85
void unsetMarker(std::size_t m)
Forget the m-th time marker if one is currently set.
Definition: ros_timing.h:94
double getElapsed(std::size_t m) const
Returns the current elapsed time since the m-th marker was set (returns -1.0 if the m-th marker is no...
Definition: ros_timing.h:112
bool haveMarker(std::size_t m) const
Returns whether the m-th marker is currently set.
Definition: ros_timing.h:110
RosServiceCaller(double reissueDelay, double failRetryDelay)
Default constructor.
Definition: ros_timing.h:179
void setServiceClient(const ros::ServiceClient &SC)
Set function for the ROS ServiceClient used by this RosServiceCaller
Definition: ros_timing.h:185
RosTimeMarker()
Default constructor.
Definition: ros_timing.h:31
bool hasElapsed(std::size_t m, double duration) const
Returns whether a certain time duration has elapsed since the m-th time marker was set (returns true ...
Definition: ros_timing.h:119
bool haveMarker() const
Returns whether a marker is currently set.
Definition: ros_timing.h:41