source: rrlib_util/tTime.h @ 84:f328970a6b47

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

Merged with changes from RRLab

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