source: rrlib_util/tTime.h @ 80:f8014ca4bc2b

Last change on this file since 80:f8014ca4bc2b was 80:f8014ca4bc2b, checked in by Tobias Föhst <foehst@…>, 7 years ago

Updated file info

File size: 11.8 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 2
10// of the License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/util/tTime.h
23 *
24 * \author  Jens Wettach
25 *
26 * \date    2011-01-04
27 *
28 * \brief
29 *
30 */
31//----------------------------------------------------------------------
32#ifndef _util_tTime_h_
33#define _util_tTime_h_
34
35#include <sys/time.h>
36#include <iostream>
37
38namespace rrlib
39{
40
41#ifdef _LIB_RRLIB_SERIALIZATION_PRESENT_
42namespace serialization
43{
44class tInputStream;
45class tOutputStream;
46}
47#endif
48
49namespace util
50{
51//! Repesents times (absolutes and differences)
52/*! Use this class whenever you want to deal with times,
53  as it provides a number of operators and functions.
54 */
55class  tTime
56{
57public:
58
59  //! standard constructor, creates a null-time
60  tTime()
61  {
62    tv_sec = 0;
63    tv_usec = 0;
64  };
65
66
67  //! constructor, takes a timeval for creation
68  tTime(const tTime & t)
69  {
70    tv_sec = t.tv_sec;
71    tv_usec = t.tv_usec;
72  }
73
74  //! constructor, takes a timeval for creation
75  tTime(timeval t)
76  {
77    tv_sec = t.tv_sec;
78    tv_usec = t.tv_usec;
79  }
80
81  //! constructor that gets a time in seconds plus microseconds
82  tTime(long sec, long usec)
83  {
84    tv_sec = sec;
85    tv_usec = usec;
86    NormalizeTime();
87  }
88
89  //! This static function returns a tTime that contains the current System-time
90  static inline tTime Now()
91  {
92    timeval ntime;
93    gettimeofday(&ntime, 0);
94    return tTime(ntime);
95  }
96
97  /*! Returns the time of the current thread (time elapsed since start
98    of thread. It exists only for internal MCA usage. You do not need
99    to call it directly. */
100  static inline tTime TaskTime()
101  {
102# if (CLOCKS_PER_SEC == 1000000)
103
104    return tTime(0, clock());
105# else
106
107    return tTime(0, clock() * (1000000 / CLOCKS_PER_SEC));
108# endif
109
110  }
111
112  /*! Returns a time that is calculated by tTime::Now()+tTime(0,usec)
113   */
114  static inline tTime FutureUSec(long usec)
115  {
116    tTime ntime(0, usec);
117    //FromUSec(usec);
118    ntime += tTime::Now();
119    return ntime;
120  }
121
122  /*! Returns a time that is calculated by
123    tTime::Now()+tTime.FromMSec(msec)
124  */
125  static inline tTime FutureMSec(long msec)
126  {
127    tTime ntime(0, msec * 1000);
128    //FromMSec(msec);
129    ntime += tTime::Now();
130    return ntime;
131  }
132
133  /*! Returns a time that is calculated by tTime::Now()+tTime(sec,0)
134   */
135  static inline tTime FutureSec(long sec)
136  {
137    tTime ntime(sec, 0);
138    //FromSec(sec);
139    ntime += tTime::Now();
140    return ntime;
141  }
142
143  /*! Sets tTime to zero. Return value is tTime itself. */
144  inline tTime FromZero()
145  {
146    tv_usec = 0;
147    tv_sec = 0;
148    return *this;
149  }
150
151  /*! Sets tTime to the current  Return value is tTime itself. */
152  inline tTime FromNow()
153  {
154    *this = Now();
155    return *this;
156  }
157
158  /*! Sets tTime to the current task  Return value is tTime itself. */
159  inline tTime FromTaskTime()
160  {
161    *this = TaskTime();
162    return *this;
163  }
164
165  /*! Sets tTime to tTime(sec,0). Return value is tTime itself. */
166  inline tTime FromSec(long sec)
167  {
168    *this = tTime(sec, 0);
169    return *this;
170  }
171
172  /*! Splits msec in sec and usec and sets tTime to tTime(sec,usec). Return value is tTime itsself. */
173  inline tTime FromMSec(long msec)
174  {
175    if (msec < 0)
176      *this = tTime(msec / 1000 - 1, ((msec % 1000) + 1000) * 1000);
177    else
178      *this = tTime(msec / 1000, (msec % 1000) * 1000);
179    return *this;
180  }
181  inline tTime FromUSec(long usec)
182  {
183    if (usec < 0)
184      *this = tTime(usec / 1000000 - 1, (usec % 1000000) + 1000000);
185    else
186      *this = tTime(usec / 1000000, usec % 1000000);
187    return *this;
188  }
189
190  /*! Compares a tTime with zero. */
191  inline bool IsZero() const
192  {
193    return ((tv_usec == 0) && (tv_sec == 0));
194  }
195
196  /*! Returns tTime in nanoseconds */
197  inline long long ToNSec()const
198  {
199    return ((long long)tv_usec + (long long)tv_sec * 1000000) * 1000;
200  }
201
202  /*! Returns tTime in microseconds */
203  inline long long ToUSec()const
204  {
205    return (long long)tv_usec + (long long)tv_sec * 1000000;
206  }
207
208  /*! Returns tTime in milli seconds rounded down to an long integer.*/
209  inline long long ToMSec()const
210  {
211    return (long long)tv_usec / 1000 + (long long)tv_sec * 1000;
212  }
213
214  /*! Returns tTime in seconds rounded down to an long integer.*/
215  inline long ToSec()const
216  {
217    return tv_sec;
218  }
219
220  /*! Don't use this function: Returns the tv_sec value if timeval which is the basis of tTime */
221  inline long TvSec()const
222  {
223    return tv_sec;
224  }
225
226  /*! Don't use this function: Returns the tv_usec value if timeval which is the basis of tTime */
227  inline long TvUSec() const
228  {
229    return tv_usec;
230  }
231
232  /*! Don't use this function: Returns the tv_usec value if timeval which is the basis of tTime */
233  inline long TvNSec() const
234  {
235    return tv_usec * 1000;
236  }
237
238  /*! Don't use this function: Sets the internal tv_sec variable of timeval */
239  inline void SetTvSec(long new_tv_sec)
240  {
241    tv_sec = new_tv_sec;
242  }
243
244  /*! Don't use this function: Sets the internal tv_usec variable of timeval */
245  inline void SetTvUSec(long new_tv_usec)
246  {
247    tv_usec = new_tv_usec;
248  }
249
250  /*! Use this function if you want to express the time in hours, minutes and seconds */
251  inline int Hours()const
252  {
253    return tv_sec / 3600 % 24;
254  }
255
256  /*! Use this function if you want to express the time in hours, minutes and seconds */
257  inline int Minutes()const
258  {
259    return (tv_sec % 3600) / 60;
260  }
261
262  /*! Use this function if you want to express the time in hours, minutes and seconds */
263  inline int Seconds()const
264  {
265    return (tv_sec % 3600) % 60;
266  }
267
268  /*! Use this function if you want to get the subseconds in milliseconds (rounded) */
269  inline int MSeconds()const
270  {
271    return tv_usec / 1000;
272  }
273
274  /*! Adds two times */
275  inline tTime operator+(const tTime& b)const
276  {
277    tTime a = *this;
278    return a += b;
279  }
280
281  /*! Adds a second time */
282  inline tTime operator+=(const tTime& b)
283  {
284    tv_usec += b.tv_usec;
285    tv_sec += b.tv_sec;
286    //NormalizeTimePositive();
287    NormalizeTime();
288    return *this;
289  }
290
291  /*! Substracts the second time from the first */
292  inline tTime operator-(const tTime& b)const
293  {
294    tTime a = *this;
295    return a -= b;
296  }
297
298  /*! Substracts a second time */
299  inline tTime operator-=(const tTime& b)
300  {
301    tv_usec -= b.tv_usec;
302    tv_sec -= b.tv_sec;
303    //NormalizeTimeNegative();
304    NormalizeTime();
305    return *this;
306  }
307
308  /*! sign operator */
309  inline tTime operator-()const
310  {
311    tTime a(-tv_sec, tv_usec);
312//     a.tv_usec = tv_usec;
313//     a.tv_sec = -tv_sec;
314    return a;
315  }
316
317  /*! Multiplies the time by a factor. Uses operator*= (see below). */
318  inline tTime operator*(double factor)const
319  {
320    tTime a = *this;
321    return a *= factor;
322  }
323
324  /*! Multiplies by a factor. */
325  inline tTime operator*=(double factor)
326  {
327    tv_usec = (long)(tv_usec * factor);
328    tv_sec = (long)(tv_sec * factor);
329    NormalizeTime();
330    return *this;
331  }
332
333  /*! Compares two variables of type tTime. Returns true if they are not equal*/
334  inline bool operator!=(const tTime& b)const
335  {
336    return (tv_usec != b.tv_usec) || (tv_sec != b.tv_sec);
337  }
338
339  /*! Compares two variables of type tTime. Returns true if they are equal*/
340  inline bool operator==(const tTime& b) const
341  {
342    return (tv_usec == b.tv_usec) && (tv_sec == b.tv_sec);
343  }
344
345  /*! Compares two variables of type tTime. Returns true if the first one is earlier than the second one*/
346  inline bool operator<(const tTime& b) const
347  {
348    return (tv_sec == b.tv_sec) ? (tv_usec < b.tv_usec) : (tv_sec < b.tv_sec);
349  }
350
351  /*! Compares two variables of type tTime. Returns true if the first one is later than the second one*/
352  inline bool operator>(const tTime& b) const
353  {
354    return (tv_sec == b.tv_sec) ? (tv_usec > b.tv_usec) : (tv_sec > b.tv_sec);
355  }
356
357  /*! Compares two variables of type tTime. Returns true if the first one is erlier than or equal to the second one*/
358  inline bool operator<=(const tTime& b) const
359  {
360    return (tv_sec == b.tv_sec) ? ((tv_usec == b.tv_usec) || (tv_usec < b.tv_usec)) : (tv_sec < b.tv_sec);
361  }
362
363  /*! Compares two variables of type tTime. Returns true if the first one is later than or equal to the second one*/
364  inline bool operator>=(const tTime& b) const
365  {
366    return (tv_sec == b.tv_sec) ? ((tv_usec == b.tv_usec) || (tv_usec > b.tv_usec)) : (tv_sec > b.tv_sec);
367  }
368
369  /*! Casts this tTime object into timespec object (consists of tv_sec/tv_nsec, see h)*/
370  operator timespec()
371  {
372    timespec t = {tv_sec, 1000 * tv_usec};
373    return t;
374  }
375
376  /*! Returns a formatted string for strftime-like-usage instead of getting "(sec, usec)", which is not really readable when used as global timestamp (date) */
377  inline std::string GetString(const std::string &format_string) const
378  {
379    char buffer[64];
380    strftime(buffer, sizeof(buffer), format_string.c_str(), localtime(&tv_sec));
381    return std::string(buffer);
382  }
383
384
385  // some standard time intervals to be used for timeouts etc
386  static const tTime time_forever;
387  static const tTime time_0ms;
388  static const tTime time_1us;
389  static const tTime time_1ms;
390  static const tTime time_5ms;
391  static const tTime time_10ms;
392  static const tTime time_20ms;
393  static const tTime time_25ms;
394  static const tTime time_30ms;
395  static const tTime time_40ms;
396  static const tTime time_50ms;
397  static const tTime time_100ms;
398  static const tTime time_200ms;
399  static const tTime time_250ms;
400  static const tTime time_300ms;
401  static const tTime time_400ms;
402  static const tTime time_500ms;
403  static const tTime time_1s;
404  static const tTime time_2s;
405  static const tTime time_5s;
406  static const tTime time_10s;
407  static const tTime time_30s;
408  static const tTime time_60s;
409  static const tTime time_120s;
410  static const tTime time_180s;
411  static const tTime time_240s;
412  static const tTime time_30000s;
413  static const tTime time_1year;
414
415private:
416  long tv_sec;
417  long tv_usec;
418
419  /*! Makes sure that tv_usec lies in the interval [0; 1000000] by:
420      - converting multiples of 1000000 usec into multiples of sec
421      - transforming tv_sec and tv_usec so that the usec part is positive
422  */
423  inline void NormalizeTime()
424  {
425    // test modulo
426    tv_sec = tv_sec + tv_usec / 1000000;
427    tv_usec = tv_usec % 1000000;
428
429    // ensure that usec part is positive
430    if (tv_usec < 0)
431    {
432      tv_sec --;
433      tv_usec += 1000000;
434    }
435  }
436};
437
438//! Overloading the << operator for ostream
439/*! Outputs a time as a pair of long integer representing (seconds, microseconds).
440 */
441inline std::ostream &operator<<(std::ostream &ost, const tTime& time)
442{
443  ost << "(" << time.TvSec() << ", " << time.TvUSec() << ")";
444  return ost;
445}
446
447//! Overloading the << operator for ostream
448/*! Outputs a time as a pair of long integer representing (seconds, microseconds).
449 */
450inline std::istream &operator>>(std::istream &str, tTime &time)
451{
452  char temp;
453  long int tv_sec, tv_usec;
454  str >> temp;
455  if (temp == '(')
456  {
457    str >> tv_sec >> temp >> tv_usec >> temp;
458  }
459  else
460  {
461    str.putback(temp);
462    str >> tv_sec >> tv_usec;
463  }
464  time = tTime(tv_sec, tv_usec);
465  return str;
466}
467
468#ifdef _LIB_RRLIB_SERIALIZATION_PRESENT_
469
470serialization::tOutputStream &operator << (serialization::tOutputStream &stream, const tTime &t);
471
472serialization::tInputStream &operator >> (serialization::tInputStream &stream, tTime &t);
473
474#endif
475
476}
477}
478#endif
Note: See TracBrowser for help on using the repository browser.