Fixposition SDK 0.0.0-heads/main-0-gfaec355
Collection of c++ libraries and apps for use with Fixposition products
Loading...
Searching...
No Matches
time.hpp
Go to the documentation of this file.
1/**
2 * \verbatim
3 * ___ ___
4 * \ \ / /
5 * \ \/ / Copyright (c) Fixposition AG (www.fixposition.com) and contributors
6 * / /\ \ License: see the LICENSE file
7 * /__/ \__\
8 *
9 * Parts copyright (c) 2008, Willow Garage, Inc., see time.cpp and the LICENSE file for details
10 * Written by flipflip (https://github.com/phkehl)
11 * \endverbatim
12 *
13 * @file
14 * @brief Fixposition SDK: Time utilities
15 *
16 * @page FPSDK_COMMON_TIME Time utilities
17 *
18 * **API**: fpsdk_common/time.hpp and fpsdk::common::time
19 *
20 */
21#ifndef __FPSDK_COMMON_TIME_HPP__
22#define __FPSDK_COMMON_TIME_HPP__
23
24/* LIBC/STL */
25#include <chrono>
26#include <cstdint>
27#include <ctime>
28#include <string>
29
30/* EXTERNAL */
31
32/* PACKAGE */
33
34namespace fpsdk {
35namespace common {
36/**
37 * @brief Time utilities
38 */
39namespace time {
40/* ****************************************************************************************************************** */
41
42/**
43 * @brief Constants
44 * @{
45 */
46
47// clang-format off
48static constexpr int SEC_IN_MIN_I = 60; //!< Number of seconds in a minute (integer)
49static constexpr int SEC_IN_HOUR_I = 60 * SEC_IN_MIN_I; //!< Number of seconds in an hour (integer)
50static constexpr int SEC_IN_DAY_I = 24 * SEC_IN_HOUR_I; //!< Number of seconds in a day (integer)
51static constexpr int SEC_IN_WEEK_I = 7 * SEC_IN_DAY_I; //!< Number of seconds in a week (integer)
52static constexpr double SEC_IN_MIN_D = static_cast<double>(SEC_IN_MIN_I); //!< Number of seconds in a minute (double)
53static constexpr double SEC_IN_HOUR_D = static_cast<double>(SEC_IN_HOUR_I); //!< Number of seconds in an hour (double)
54static constexpr double SEC_IN_DAY_D = static_cast<double>(SEC_IN_DAY_I); //!< Number of seconds in a day (double)
55static constexpr double SEC_IN_WEEK_D = static_cast<double>(SEC_IN_WEEK_I); //!< Number of seconds in a week (double)
56//clang-format on
57
58///@}
59
60// ---------------------------------------------------------------------------------------------------------------------
61
62/**
63 * @brief Get milliseconds [ms], monotonic time
64 *
65 * @returns the number of milliseconds
66 */
67uint64_t GetMillis();
68
69/**
70 * @brief Get seconds [s], monotonic time
71 *
72 * @returns the number of seconds
73 */
74double GetSecs();
75
76// ---------------------------------------------------------------------------------------------------------------------
77
78class Duration; // forward declaration
79
80/**
81 * @brief Helper to measure wallclock time
82 */
83class TicToc
84{
85 public:
86 /**
87 * @brief Constructor
88 *
89 * This also starts the measurements, like Tic().
90 */
92
93 /**
94 * @brief (Re-)start measurement
95 */
96 void Tic();
97
98 /**
99 * @brief Get elapsed wallclock time
100 *
101 * @param[in] reset Reset (restart) measurements
102 *
103 * @returns the elapsed time since object constructed resp. last call to Tic()
104 */
105 Duration Toc(const bool reset = false);
106
107 private:
108 std::chrono::time_point<std::chrono::steady_clock> t0_;
109};
110
111// ---------------------------------------------------------------------------------------------------------------------
112
113/**
114 * @brief Minimal ros::Time() / rplcpp::Time implementation (that doesn't throw)
115 */
117{
118 RosTime();
119 /**
120 * @brief Constructor
121 *
122 * @param[in] sec Time value seconds
123 * @param[in] nsec Time value nanoseconds
124 */
125 RosTime(const uint32_t sec, const uint32_t nsec);
126
127 /**
128 * @brief Convert to seconds
129 *
130 * @returns the time value (time since epoch) in [s]
131 */
132 double ToSec() const;
133
134 /**
135 * @brief Check if time is zero (invalid, unset)
136 *
137 * @returns true if time is zero (invalid, unset)
138 */
139 bool IsZero() const;
140
141 uint32_t sec_; //!< Seconds part of time
142 uint32_t nsec_; //!< Nanoseconds part of time (*should* be in range 0-999999999)
143
144 bool operator==(const RosTime& rhs) const; //!< Equal
145};
146
147// ---------------------------------------------------------------------------------------------------------------------
148
149/**
150 * @brief Time duration
151 *
152 * This is similar (and binary compatible) to ros::Duration and rpclpp::Duration. While some of the constructors and
153 * operators can throw, it also provides non-throwing methods to manipulate the duration.
154 */
156{
157 public:
158 // -----------------------------------------------------------------------------------------------------------------
159 /**
160 * @name Make Duration object
161 *
162 * @note These throw std::runtime_error if the values are out of range.
163 * @{
164 */
165
166 /**
167 * @brief Constructor, zero duration
168 */
170
171 /**
172 * @brief Make Duration from seconds and nanoseconds
173 *
174 * @param[in] sec Duration value seconds
175 * @param[in] nsec Duration value nanoseconds
176 */
177 static Duration FromSecNSec(const int32_t sec, const int32_t nsec);
178
179 /**
180 * @brief Make Duration from nanoseconds
181 *
182 * @param[in] nsec Duration value nanoseconds
183 */
184 static Duration FromNSec(const int64_t nsec);
185
186 /**
187 * @brief Make Duration from seconds
188 *
189 * @param[in] sec Duration value seconds
190 */
191 static Duration FromSec(const double sec);
192
193 ///@}
194 // -----------------------------------------------------------------------------------------------------------------
195 /**
196 * @name Set duration
197 *
198 * These do not throw and instead return true/false.
199 * @{
200 */
201
202 /**
203 * @brief Set duration from seconds and nanoseconds
204 *
205 * @param[in] sec Duration value seconds
206 * @param[in] nsec Duration value nanoseconds
207 *
208 * @returns true if successful (values in range), false otherwise (bad values)
209 */
210 bool SetSecNSec(const int32_t sec, const int32_t nsec);
211
212 /**
213 * @brief Set duration from nanoseconds
214 *
215 * @param[in] nsec Duration value nanoseconds
216 *
217 * @returns true if successful (sec value in range), false otherwise (bad sec value)
218 */
219 bool SetNSec(const int64_t nsec);
220
221 /**
222 * @brief Set duration from seconds
223 *
224 * @param[in] sec Duration value seconds
225 *
226 * @returns true if successful (sec value in range), false otherwise (bad sec value)
227 */
228 bool SetSec(const double sec);
229
230 ///@}
231 // -----------------------------------------------------------------------------------------------------------------
232 /**
233 * @name Get duration
234 * @{
235 */
236
237 /**
238 * @brief Get duration as nanoseconds
239 *
240 * @returns the duration as nanoseconds
241 */
242 int64_t GetNSec() const;
243
244 /**
245 * @brief Get duration as seconds
246 *
247 * @param[in] prec Round the seconds to this many fractional digits (0-9)
248 *
249 * @returns the duration as seconds
250 */
251 double GetSec(const int prec = 9) const;
252
253 /**
254 * @brief Get duration as std::chrono::milliseconds
255 *
256 * @returns the duration as std::chrono::milliseconds
257 */
258 std::chrono::milliseconds GetChronoMilli() const;
259
260 /**
261 * @brief Get duration as std::chrono::nanoseconds
262 *
263 * @returns the duration as std::chrono::nanoseconds
264 */
265 std::chrono::nanoseconds GetChronoNano() const;
266
267 ///@}
268 // -----------------------------------------------------------------------------------------------------------------
269 /**
270 * @name Misc
271 * @{
272 */
273
274 /**
275 * @brief Check if duration is zero
276 *
277 * @returns true if duration is exactly zero
278 */
279 bool IsZero() const;
280
281 /**
282 * @brief Stringify duration, for debugging
283 *
284 * @param[in] prec Number of fractional digits for the seconds (0-9)
285 *
286 * @returns The stringified duration ("HH:MM:SS.SSS", resp. "DDd HH:MM:SS.SSS" if duration > 1d)
287 */
288 std::string Stringify(const int prec = 3) const;
289
290 /**
291 * @brief Sleep for the duration (if > 0)
292 */
293 void Sleep() const;
294
295 ///@}
296 // -----------------------------------------------------------------------------------------------------------------
297 /**
298 * @name Arithmetic methods
299 *
300 * These do not throw and instead return true/false.
301 * @{
302 */
303
304 /**
305 * @brief Add duration to duration
306 *
307 * @param[in] dur Duration to add
308 *
309 * @returns true if successful (dur value in range), false otherwise (bad sec value)
310 */
311 bool AddDur(const Duration& dur);
312
313 /**
314 * @brief Add nanoseconds to duration
315 *
316 * @param[in] nsec Nanoseconds to add
317 *
318 * @returns true if successful (sec value in range), false otherwise (bad sec value)
319 */
320 bool AddNSec(const int64_t nsec);
321
322 /**
323 * @brief Add seconds to duration
324 *
325 * @param[in] sec Seconds to add
326 *
327 * @returns true if successful (sec value in range), false otherwise (bad sec value)
328 */
329 bool AddSec(const double sec);
330
331 /**
332 * @brief Substract duration from duration
333 *
334 * @param[in] dur Duration to substract
335 *
336 * @returns true if successful (dur value in range), false otherwise (bad sec value)
337 */
338 bool SubDur(const Duration& dur);
339
340 /**
341 * @brief Substract nanoseconds from duration
342 *
343 * @param[in] nsec Nanoseconds to substract
344 *
345 * @returns true if successful (sec value in range), false otherwise (bad sec value)
346 */
347 bool SubNSec(const int64_t nsec);
348
349 /**
350 * @brief Substract seconds from duration
351 *
352 * @param[in] sec Seconds to substract
353 *
354 * @returns true if successful (sec value in range), false otherwise (bad sec value)
355 */
356 bool SubSec(const double sec);
357
358 /**
359 * @brief Scale (multiply) duration
360 *
361 * @param[in] sec Scale factor
362 *
363 * @returns true if successful (scale value in range), false otherwise (bad scale value)
364 */
365 bool Scale(const double sec);
366
367 ///@}
368 // -----------------------------------------------------------------------------------------------------------------
369 /**
370 * @name Arithmetic operators
371 *
372 * @note These throw std::runtime_error if the values are out of range.
373 * @{
374 */
375
376 Duration operator+(const Duration& rhs) const; //!< Sum duration and duration
377 Duration operator+(const int64_t nsec) const; //!< Sum duration and nanoseconds
378 Duration operator+(const double sec) const; //!< Sum duration and seconds
379 Duration& operator+=(const Duration& rhs); //!< Add duration to duration
380 Duration& operator+=(const int64_t nsec); //!< Add nanoseconds to durationn
381 Duration& operator+=(const double sec); //!< Add seconds to duration
382 Duration operator-(const Duration& rhs) const; //!< Subtract duration and duration
383 Duration operator-(const int64_t nsec) const; //!< Subtract duration and nanoseconds
384 Duration operator-(const double sec) const; //!< Subtract duration and seconds
385 Duration& operator-=(const Duration& rhs); //!< Subtract duration from duration
386 Duration& operator-=(const int64_t nsec); //!< Subtract nanoseconds from duration
387 Duration& operator-=(const double sec); //!< Subtract seconds from durationn
388 Duration operator-() const; //!< Reverse sign
389 Duration operator*(double scale) const; //!< Multiply (scale) duration
390 Duration& operator*=(double scale); //!< Multiply (scale) duration
391
392 ///@}
393 // -----------------------------------------------------------------------------------------------------------------
394 /**
395 * @name Logic operators
396 * @{
397 */
398
399 bool operator==(const Duration& rhs) const; //!< Equal
400 bool operator!=(const Duration& rhs) const; //!< Not equal
401 bool operator>(const Duration& rhs) const; //!< Greater than
402 bool operator<(const Duration& rhs) const; //!< Smaller than
403 bool operator>=(const Duration& rhs) const; //!< Greater or equal than
404 bool operator<=(const Duration& rhs) const; //!< Smaller or equal than
405
406 ///@}
407 // -----------------------------------------------------------------------------------------------------------------
408
409 // Storage deliberately public
410 int32_t sec_; //!< Seconds part of duration
411 int32_t nsec_; //!< Nanoseconds part of duration (*should* be in range 0-999999999)
412
413 ///@
414};
415
416// ---------------------------------------------------------------------------------------------------------------------
417
418/**
419 * @brief GNSS atomic time representation: week number (wno) and time of week (tow) used by GPS, Galileo and BeiDou
420 */
421struct WnoTow {
422 /**
423 * @brief GNSS time system
424 */
425 enum class Sys {
426 GPS, //!< GPS (also: SBAS, QZSS)
427 GAL, //!< Galileo system time (GST)
428 BDS, //!< BeiDou time
429 };
430
431 /**
432 * @brief Constructor
433 *
434 * @param[in] sys GNSS
435 */
436 WnoTow(const Sys sys = Sys::GPS);
437
438 /**
439 * @brief Constructor
440 *
441 * @param[in] wno Week number [-] (>= 0)
442 * @param[in] tow Time of week [s] (0.0-603'799.999..)
443 * @param[in] sys GNSS
444 */
445 WnoTow(const int wno, const double tow, const Sys sys = Sys::GPS);
446
447 // clang-format off
448 int wno_ = 0; //!< Week number [-] (>= 0)
449 double tow_ = 0.0; //!< Time of week [s] (0.0-603'799.999..)
450 Sys sys_; //!< Time system
451 // clang-format on
452
453 /**
454 * @brief Stringify time system (for debugging)
455 *
456 * @returns a string identifying the time system
457 */
458 const char* SysStr() const;
459};
460
461/**
462 * @brief GLONASS time
463 */
465{
466 GloTime() = default; //!< Ctor
467
468 /**
469 * @brief Constructor
470 * @param[in] N4 Four-year interval, 1=1996..1999, 2=2000..2003, ..., valid range: 1-...
471 * @param[in] Nt Day in four-year interval, valid range: 1-1461
472 * @param[in] TOD Time of day (in Москва time zone) [s]
473 */
474 GloTime(const int N4, const int Nt, const double TOD);
475
476 // clang-format off
477 int N4_ = 0; //!< Four-year interval, 1=1996..1999, 2=2000..2003, ..., valid range: 1-...
478 int Nt_ = 0; //!< Day in four-year interval, valid range: 1-1461
479 double TOD_ = 0.0; //!< Time of day (in Москва time zone) [s]
480 // clang-format on
481};
482
483/**
484 * @brief UTC time representation
485 */
487{
488 UtcTime() = default; //!< Ctor
489 /**
490
491 * @brief Constructor
492 *
493 * @param[in] year Year
494 * @param[in] month Month (1-12)
495 * @param[in] day Day (1-31)
496 * @param[in] hour Hour (0-23)
497 * @param[in] min Minute (0-59)
498 * @param[in] sec Second (0-60)
499 */
500 UtcTime(const int year, const int month, const int day, const int hour, const int min, const double sec);
501
502 // clang-format off
503 int year_ = 0; //!< Year
504 int month_ = 0; //!< Month (1-12)
505 int day_ = 0; //!< Day (1-31)
506 int hour_ = 0; //!< Hour (0-23)
507 int min_ = 0; //!< Minute (0-59)
508 double sec_ = 0.0; //!< Second (0-60)
509 // clang-format on
510};
511
512// clang-format off
513/**
514 * @brief Time
515 *
516 * This class implements conversion from and to different time systems and time artithmetics. Internally it uses an
517 * *atomic* time in seconds and nanoseconds since 1970 as its representation of time. Conversion from and to UTC time or
518 * POSIX time are available. No timezones or local time are supported (use the ctime API for that).
519 *
520 * Some of the constructors and operators can throw. Non-throwing methods to manipulate the time are provided as well.
521 *
522 * This time object can represent the time from T_MIN to T_MAX, which is (the old) 32bit POSIX time. Note that for the
523 * different GNSS times you will get negative week numbers (GPS, Galileo, BeiDou) or a negative offset "M4" value
524 * (GLONASS) for timestamps before the beginning of respective timescales.
525 *
526 * ---1970-------------1980-------1996-1999----2006--------------------2106---//--fuuuuuture----> time
527 *
528 * 1970-01-01 00:00:00.0 UTC |<----- std::time_t ---------------------------------------------------//----->|
529 * |<----- ros::Time/rclcpp::Time----------------------------------->|
530 * 1980-01-06 00:00:00.0 UTC |<---- GPS time---------------------------------------//----->
531 * 1996-01-01 00:00:00.0 UTC(SU) |<---- GLONASS time -----------------------//----->
532 * 1999-08-21 23:59:47.0 UTC |<---- Galileo time ------------------//----->
533 * 2006-01-01 00:00:00.0 UTC |<---- BeiDou time -----------//----->
534 *
535 * |<======================= Time object ===========================>|
536 * T_MIN T_MAX
537 * 1970-01-01 00:00:0.0 UTC 2106-02-06 06:28:16.0 UTC (approximately!)
538 *
539 * Some notes:
540 *
541 * - "Strict" POSIX time is used for the methods marked with "POSIX". This time has a discontinuity and/or ambiguity
542 * at/during leapsecond events. It does not use the "Mills" or NTP style of handling these periods and is therefore,
543 * for those timestamps, likely not compatible with the system time (CLOCK_REALTIME) of a typical Linux system. See
544 * references below.
545 * - The from/to UTC calculations are not fully correct for times before 1972.
546 * - FromClockTai() and SetClockTai() likely will not give the expected result unless your system (Linux kernel) is
547 * configured for the correct leapsecond.
548 * - The precision of all integer getters, setters and operators should be [ns] in all cases
549 * - The precision of all double getters, setters and operators should be [ns] in most cases
550 * - The internal representation of time (the sec_ value) is atomic, but it is not CLOCK_TAI (which already "has" 10
551 * leapseconds at sec_ = 0).
552 *
553 * Some references:
554 *
555 * - https://en.wikipedia.org/wiki/Unix_time
556 * - https://en.wikipedia.org/wiki/Atomic_clock
557 * - https://en.wikipedia.org/wiki/Coordinated_Universal_Time
558 * - https://docs.ntpsec.org/latest/leapsmear.html
559 * - https://www.eecis.udel.edu/~mills/leap.html
560 * - https://manpages.org/adjtimex/2
561 *
562 */
563// clang-format on
564class Time
565{
566 public:
567 // -----------------------------------------------------------------------------------------------------------------
568 /**
569 * @name Make Time object
570 *
571 * @note These throw std::runtime_error if the time (the arguments) is out of range
572 * @{
573 */
574
575 /**
576 * @brief Constructor, empty (invalid) time
577 */
579
580 /**
581 * @brief Time from seconds and nanoseconds (atomic)
582 *
583 * @param[in] sec Time value seconds
584 * @param[in] nsec Time value nanoseconds
585 *
586 * @returns the Time object
587 */
588 static Time FromSecNSec(const uint32_t sec, const uint32_t nsec);
589
590 /**
591 * @brief Time from nanoseconds (atomic)
592 *
593 * @param[in] nsec Time value nanoseconds (> 0)
594 *
595 * @returns the Time object
596 */
597 static Time FromNSec(const uint64_t nsec);
598
599 /**
600 * @brief From seconds (atomic)
601 *
602 * @param[in] sec Time value seconds (> 0.0)
603 *
604 * @returns the Time object
605 */
606 static Time FromSec(const double sec);
607
608 /**
609 * @brief From POSIX time (POSIX)
610 *
611 * @note See comments in the class description regarding POSIX time!
612 *
613 * @param[in] posix Time value seconds (> 0)
614 *
615 * @returns the Time object
616 */
617 static Time FromPosix(const std::time_t posix);
618
619 /**
620 * @brief From ROS time (POSIX)
621 *
622 * @note See comments in the class description regarding POSIX time!
623 *
624 * @param[in] rostime Time value
625 *
626 * @returns the Time object
627 */
628 static Time FromRosTime(const RosTime& rostime);
629
630 /**
631 * @brief From GNSS time (atomic)
632 *
633 * @param[in] wnotow GNSS time
634 *
635 * @returns the Time object
636 */
637 static Time FromWnoTow(const WnoTow& wnotow);
638
639 /**
640 * @brief From GLONASS time (UTC + 3h)
641 *
642 * @param[in] glotime GLONASS time
643 *
644 * @returns the Time object
645 */
646 static Time FromGloTime(const GloTime& glotime);
647
648 /**
649 * @brief From UTC time (UTC)
650 *
651 * @param[in] utctime UTC time
652 *
653 * @returns the Time object
654 */
655 static Time FromUtcTime(const UtcTime& utctime);
656
657 /**
658 * @brief From TAI time (CLOCK_TAI)
659 *
660 * @returns true if successful, false otherwise (bad time)
661 */
662 static Time FromTai(const time_t tai);
663
664 /**
665 * @brief From system clock current (now) system time (CLOCK_REALTIME)
666 *
667 * @returns the Time object
668 */
670
671#ifdef CLOCK_TAI
672 /**
673 * @brief From system clock current (now) atomic time (CLOCK_TAI)
674 *
675 * @note This will only produce the right result if your system is configured accordingly (which is unlikely). See
676 * comments in the Time class description.
677 *
678 * @returns the Time object
679 */
680 static Time FromClockTai();
681#endif
682
683 ///@}
684 // -----------------------------------------------------------------------------------------------------------------
685 /**
686 * @name Set time
687 *
688 * These do not throw and instead return true/false.
689 * @{
690 */
691
692 /**
693 * @brief Set time from seconds and nanoseconds (atomic)
694 *
695 * @param[in] sec Time value seconds
696 * @param[in] nsec Time value nanoseconds
697 *
698 * @returns true if successful, false otherwise (bad time)
699 */
700 bool SetSecNSec(const uint32_t sec, const uint32_t nsec);
701
702 /**
703 * @brief Set time from nanoseconds (atomic)
704 *
705 * @param[in] nsec Time value nanoseconds (> 0)
706 *
707 * @returns true if successful, false otherwise (bad time)
708 */
709 bool SetNSec(const uint64_t nsec);
710
711 /**
712 * @brief Set time from seconds (atomic)
713 *
714 * @param[in] sec Time value seconds (> 0.0)
715 *
716 * @returns true if successful, false otherwise (bad time)
717 */
718 bool SetSec(const double sec);
719
720 /**
721 * @brief Set time from POSIX time (POSIX)
722 *
723 * @note See comments in the class description regarding POSIX time!
724 *
725 * @param[in] posix The POSIX time
726 *
727 * @returns true if successful, false otherwise (bad time)
728 */
729 bool SetPosix(const time_t posix);
730
731 /**
732 * @brief Set time from ROS time (POSIX)
733 *
734 * @note See comments in the class description regarding POSIX time!
735 *
736 * @param[in] rostime Time value
737 *
738 * @returns true if successful, false otherwise (bad time)
739 */
740 bool SetRosTime(const RosTime& rostime);
741
742 /**
743 * @brief Set time from GNSS (GPS, Galileo, BeiDou) time (atomic)
744 *
745 * @param[in] wnotow GNSS time
746 *
747 * @returns true if successful, false otherwise (bad time)
748 */
749 bool SetWnoTow(const WnoTow& wnotow);
750
751 /**
752 * @brief Set time from GLONASS time (UTC + 3h)
753 *
754 * @param[in] glotime GLONASS time
755 *
756 * @returns true if successful, false otherwise (bad time)
757 */
758 bool SetGloTime(const GloTime& glotime);
759
760 /**
761 * @brief Set time from UTC time (UTC)
762 *
763 * @param[in] utctime UTC time
764 *
765 * @returns true if successful, false otherwise (bad time)
766 */
767 bool SetUtcTime(const UtcTime& utctime);
768
769 /**
770 * @brief Set time from TAI time (CLOCK_TAI)
771 *
772 * @param[in] tai The TAI time
773 *
774 * @returns true if successful, false otherwise (bad time)
775 */
776 bool SetTai(const time_t tai);
777
778 /**
779 * @brief Set time from system clock current (now) system time (CLOCK_REALTIME)
780 *
781 * @returns true if successful, false otherwise (bad time)
782 */
784
785#ifdef CLOCK_TAI
786 /**
787 * @brief Set time from system clock current (now) TAI time (CLOCK_TAI)
788 *
789 * @note This will only produce the right result if your system is configured accordingly (which is unlikely). See
790 * comments in the Time class description.
791 *
792 * @returns the Time object
793 */
794
795 bool SetClockTai();
796#endif
797
798 ///@}
799 // -----------------------------------------------------------------------------------------------------------------
800 /**
801 * @name Get time
802 * @{
803 */
804
805 /**
806 * @brief Get time as nanoseconds (atomic)
807 *
808 * @returns the time as nanoseconds
809 */
810 uint64_t GetNSec() const;
811
812 /**
813 * @brief Get time as seconds (atomic)
814 *
815 * @param[in] prec Round the seconds to this many fractional digits (0-9)
816 *
817 * @returns the time as seconds
818 */
819 double GetSec(const int prec = 9) const;
820
821 /**
822 * @brief Get time as POSIX time (POSIX)
823 *
824 * @note See comments in the class description regarding POSIX time!
825 *
826 * @returns the POSIX time, truncated (rounded down, sub-seconds ignored)
827 */
828 time_t GetPosix() const;
829
830 /**
831 * @brief Get time as ROS time (POSIX)
832 *
833 * @note See comments in the class description regarding POSIX time!
834 *
835 * @returns the time
836 */
838
839 /**
840 * @brief Get time as GNSS (GPS, Galileo, BeiDou) time (atomic)
841 *
842 * @note For times before the respective GNSS epoch the result is not usable (e.g. negative week numbers).
843 *
844 * @param[in] sys GNSS
845 * @param[in] prec Round the seconds to this many fractional digits (0-9)
846 *
847 * @returns the GNSS time for the selected GNSS
848 */
849 WnoTow GetWnoTow(const WnoTow::Sys sys = WnoTow::Sys::GPS, const int prec = 9) const;
850
851 /**
852 * @brief Get time as GLONASS time (UTC + 3h)
853 *
854 * @param[in] prec Round the seconds to this many fractional digits (0-9)
855 *
856 * @returns the GLONASS time
857 */
858 GloTime GetGloTime(const int prec = 9) const;
859
860 /**
861 * @brief Get time as UTC time (UTC)
862 *
863 * @param[in] prec Round the seconds to this many fractional digits (0-9)
864 *
865 * @returns the UTC time
866 */
867 UtcTime GetUtcTime(const int prec = 9) const;
868
869 /**
870 * @brief Get day of year
871 *
872 * @param[in] prec Round to this many fractional digits (0-12)
873 *
874 * @returns the day of the year
875 */
876 double GetDayOfYear(const int prec = 12) const;
877
878 /**
879 * @brief Get time as TAI time (CLOCK_TAI)
880 *
881 * @returns the TAI time, truncated (rounded down, sub-seconds ignored)
882 */
883 time_t GetTai() const;
884
885 /**
886 * @brief Get time as std::chrono::duration (milliseconds since epoch) (POSIX)
887 *
888 * @note See comments in the class description regarding POSIX time!
889 *
890 * @returns the time as std::chrono::milliseconds
891 */
892 std::chrono::milliseconds GetChronoMilli() const;
893
894 /**
895 * @brief Get time as std::chrono::nanoseconds (nanoseconds since epoch) (POSIX)
896 *
897 * @note See comments in the class description regarding POSIX time!
898 *
899 * @returns the time as std::chrono::nanoseconds
900 */
901 std::chrono::nanoseconds GetChronoNano() const;
902
903 ///@}
904 // -----------------------------------------------------------------------------------------------------------------
905 /**
906 * @name Misc
907 * @{
908 */
909
910 /**
911 * @brief Check if time is zero (invalid)
912 *
913 * @returns true if time is exactly zero
914 */
915 bool IsZero() const;
916
917 ///@}
918 // -----------------------------------------------------------------------------------------------------------------
919 /**
920 * @name Arithmetic methods
921 *
922 * These do not throw and instead return true/false.
923 * @{
924 */
925
926 /**
927 * @brief Add duration to time
928 *
929 * @param[in] dur Duration to add
930 *
931 * @returns true if successful (dur value in range), false otherwise (bad sec value)
932 */
933 bool AddDur(const Duration& dur);
934
935 /**
936 * @brief Add seconds to time
937 *
938 * @param[in] sec Seconds to add
939 *
940 * @returns true if successful (sec value in range), false otherwise (bad sec value)
941 */
942 bool AddSec(const double sec);
943
944 /**
945 * @brief Add nanoseconds to time
946 *
947 * @param[in] nsec Nanoseconds to add
948 *
949 * @returns true if successful (sec value in range), false otherwise (bad sec value)
950 */
951 bool AddNSec(const int64_t nsec);
952
953 /**
954 * @brief Substract duration from time
955 *
956 * @param[in] dur Duration to substract
957 *
958 * @returns true if successful (dur value in range), false otherwise (bad sec value)
959 */
960 bool SubDur(const Duration& dur);
961
962 /**
963 * @brief Substract nanoseconds from time
964 *
965 * @param[in] nsec Nanoseconds to substract
966 *
967 * @returns true if successful (sec value in range), false otherwise (bad sec value)
968 */
969 bool SubNSec(const int64_t nsec);
970
971 /**
972 * @brief Substract seconds from time
973 *
974 * @param[in] sec Seconds to substract
975 *
976 * @returns true if successful (sec value in range), false otherwise (bad sec value)
977 */
978 bool SubSec(const double sec);
979
980 /**
981 * @brief Calculate difference between times
982 *
983 * @param[in] other The other time
984 * @param[out] diff The difference to the other time (time - other)
985 *
986 * @returns true if the times and the difference are within range, false otherwise
987 */
988 bool Diff(const Time& other, Duration& diff) const;
989
990 ///@}
991 // -----------------------------------------------------------------------------------------------------------------
992 /**
993 * @name Arithmetic operators
994 *
995 * @note These throw std::runtime_error if the arguments (the time) are out of range.
996 * @{
997 */
998
999 Time operator+(const Duration& rhs) const; //!< Sum time and duration
1000 Time operator+(const int64_t nsec) const; //!< Sum time and nanoseconds
1001 Time operator+(const double sec) const; //!< Sum time and seconds
1002 Time& operator+=(const Duration& rhs); //!< Add duration to time
1003 Time& operator+=(const int64_t nsec); //!< Add nanoseconds to time
1004 Time& operator+=(const double sec); //!< Add seconds to time
1005 Time operator-(const Duration& rhs) const; //!< Subtract time and duration
1006 Time operator-(const int64_t nsec) const; //!< Subtract time and nanoseconds
1007 Time operator-(const double sec) const; //!< Subtract time and seconds
1008 Time& operator-=(const Duration& rhs); //!< Subtract duration from time
1009 Time& operator-=(const int64_t nsec); //!< Subtract nanoseconds from time
1010 Time& operator-=(const double sec); //!< Subtract seconds from time
1011 Duration operator-(const Time& rhs) const; //!< Subtract time and time
1012
1013 ///@}
1014 // -----------------------------------------------------------------------------------------------------------------
1015 /**
1016 * @name Logic operators
1017 * @{
1018 */
1019
1020 bool operator==(const Time& rhs) const; //!< Equal
1021 bool operator!=(const Time& rhs) const; //!< Not equal
1022 bool operator>(const Time& rhs) const; //!< Greater than
1023 bool operator<(const Time& rhs) const; //!< Smaller than
1024 bool operator>=(const Time& rhs) const; //!< Greater or equal than
1025 bool operator<=(const Time& rhs) const; //!< Smaller or equal than
1026
1027 ///@}
1028 // -----------------------------------------------------------------------------------------------------------------
1029 /**
1030 * @name Stringification
1031 *
1032 * See also fpsdk::common::string::Strftime().
1033 *
1034 * @{
1035 */
1036
1037 /**
1038 * @brief Stringify as GNSS time (atomic)
1039 *
1040 * @param[in] sys The desired GNSS time system
1041 * @param[in] prec Number of fractional digits for the seconds (0-9)
1042 *
1043 * @returns a string with formatted week-number and time-of-week ("wwww:tttttt.ttt")
1044 */
1045 std::string StrWnoTow(const WnoTow::Sys sys = WnoTow::Sys::GPS, const int prec = 3) const;
1046
1047 /**
1048 * @brief Stringify as year, month, day, hour, minute and second time (UTC)
1049 *
1050 * @param[in] prec Number of fractional digits for the seconds (0-9)
1051 *
1052 * @returns a string with formatted UTC time ("yyyy-mm-dd hh:mm:ss.sss")
1053 */
1054 std::string StrUtcTime(const int prec = 3) const;
1055
1056 /**
1057 * @brief Stringify as ISO 8601 time (UTC)
1058 *
1059 * @param[in] prec Number of fractional digits for the seconds (0-9)
1060 *
1061 * @returns a string with formatted UTC time ("yyyyddmmThhmmssZ")
1062 */
1063 std::string StrIsoTime(const int prec = 0) const;
1064
1065 ///@}
1066 // -----------------------------------------------------------------------------------------------------------------
1067 /**
1068 * @name Leapseconds
1069 *
1070 * @{
1071 */
1072
1073 /**
1074 * @brief Set or change current leapseconds
1075 *
1076 * This extends the build-in leapseconds table with the current value. The given value is assumed to be the
1077 * leapseconds value (TAI - UTC) that is valid from the object's time (truncated to integer seconds). The object's
1078 * time must be past (later than) and the value must be greater or equal than the information in the latest entry in
1079 * the built-in table.
1080 *
1081 * The built-in table and the "current leapseconds" information are global per process. Setting or changing the
1082 * current leapseconds value affects all existing and future Time objects immediately.
1083 *
1084 * For example, the latest entry in the built-in table may be 2017-01-01 00:00:00 UTC with TAI-UTC = 37. So it could
1085 * be updated with a time of 2035-06-01 00:00:00 UTC and a value of 38.
1086 *
1087 * The idea is to use this in real-time applications where an upcoming leapseconds event can be learned from on-line
1088 * data, such as GNSS navigation data. Calling this method at and appropriate time with appropriate arguments is up
1089 * to the application. For example, if multiple future leapseconds events are known, the right event must be
1090 * "activated" at the right time.
1091 *
1092 * @param[in] value The current leapseconds value
1093 *
1094 * @returns true if the objects time and the leapseconds value were acceptable and set, false otherwise
1095 */
1096 bool SetCurrentLeapseconds(const int value) const;
1097
1098 ///@}
1099 // -----------------------------------------------------------------------------------------------------------------
1100
1101 static const Time MIN; //!< Minimum representable time
1102 static const Time MAX; //!< Maximum representable time
1103 static const Time ZERO; //!< Zero (invalid, uninitialised) time
1104
1105 // Storage deliberately public
1106 uint32_t sec_; //!< Seconds part of time (atomic seconds since 1970-01-01 00:00:00 UTC)
1107 uint32_t nsec_; //!< Nanoseconds part of time (*should* be in range 0-999999999)
1108};
1109
1110/* ****************************************************************************************************************** */
1111} // namespace time
1112} // namespace common
1113} // namespace fpsdk
1114#endif // __FPSDK_COMMON_TIME_HPP__
Duration & operator+=(const int64_t nsec)
Add nanoseconds to durationn.
bool operator!=(const Duration &rhs) const
Not equal.
bool AddNSec(const int64_t nsec)
Add nanoseconds to duration.
Duration & operator+=(const double sec)
Add seconds to duration.
bool SetSecNSec(const int32_t sec, const int32_t nsec)
Set duration from seconds and nanoseconds.
Duration operator+(const double sec) const
Sum duration and seconds.
Duration operator*(double scale) const
Multiply (scale) duration.
Duration & operator-=(const int64_t nsec)
Subtract nanoseconds from duration.
static Duration FromSecNSec(const int32_t sec, const int32_t nsec)
Make Duration from seconds and nanoseconds.
int32_t sec_
Seconds part of duration.
Definition time.hpp:410
static Duration FromNSec(const int64_t nsec)
Make Duration from nanoseconds.
bool IsZero() const
Check if duration is zero.
Duration operator-(const Duration &rhs) const
Subtract duration and duration.
bool SubDur(const Duration &dur)
Substract duration from duration.
bool operator<=(const Duration &rhs) const
Smaller or equal than.
void Sleep() const
Sleep for the duration (if > 0)
Duration()
Constructor, zero duration.
Duration & operator*=(double scale)
Multiply (scale) duration.
Duration & operator-=(const Duration &rhs)
Subtract duration from duration.
std::chrono::nanoseconds GetChronoNano() const
Get duration as std::chrono::nanoseconds.
bool SetSec(const double sec)
Set duration from seconds.
std::chrono::milliseconds GetChronoMilli() const
Get duration as std::chrono::milliseconds.
double GetSec(const int prec=9) const
Get duration as seconds.
Duration operator-(const double sec) const
Subtract duration and seconds.
bool AddDur(const Duration &dur)
Add duration to duration.
int64_t GetNSec() const
Get duration as nanoseconds.
bool SubSec(const double sec)
Substract seconds from duration.
bool operator>(const Duration &rhs) const
Greater than.
Duration operator-(const int64_t nsec) const
Subtract duration and nanoseconds.
bool AddSec(const double sec)
Add seconds to duration.
Duration & operator+=(const Duration &rhs)
Add duration to duration.
int32_t nsec_
Nanoseconds part of duration (should be in range 0-999999999)
Definition time.hpp:411
bool Scale(const double sec)
Scale (multiply) duration.
Duration operator+(const Duration &rhs) const
Sum duration and duration.
std::string Stringify(const int prec=3) const
Stringify duration, for debugging.
Duration operator+(const int64_t nsec) const
Sum duration and nanoseconds.
bool SetNSec(const int64_t nsec)
Set duration from nanoseconds.
Duration operator-() const
Reverse sign.
bool SubNSec(const int64_t nsec)
Substract nanoseconds from duration.
static Duration FromSec(const double sec)
Make Duration from seconds.
bool operator==(const Duration &rhs) const
Equal.
Duration & operator-=(const double sec)
Subtract seconds from durationn.
bool operator>=(const Duration &rhs) const
Greater or equal than.
bool operator<(const Duration &rhs) const
Smaller than.
Helper to measure wallclock time.
Definition time.hpp:84
Duration Toc(const bool reset=false)
Get elapsed wallclock time.
void Tic()
(Re-)start measurement
UtcTime GetUtcTime(const int prec=9) const
Get time as UTC time (UTC)
bool SetTai(const time_t tai)
Set time from TAI time (CLOCK_TAI)
double GetDayOfYear(const int prec=12) const
Get day of year.
Time operator-(const Duration &rhs) const
Subtract time and duration.
bool SetUtcTime(const UtcTime &utctime)
Set time from UTC time (UTC)
std::string StrUtcTime(const int prec=3) const
Stringify as year, month, day, hour, minute and second time (UTC)
Time & operator+=(const int64_t nsec)
Add nanoseconds to time.
static Time FromSec(const double sec)
From seconds (atomic)
bool SetClockRealtime()
Set time from system clock current (now) system time (CLOCK_REALTIME)
Time operator+(const Duration &rhs) const
Sum time and duration.
time_t GetPosix() const
Get time as POSIX time (POSIX)
Time & operator+=(const double sec)
Add seconds to time.
bool operator<=(const Time &rhs) const
Smaller or equal than.
static Time FromTai(const time_t tai)
From TAI time (CLOCK_TAI)
static const Time MIN
Minimum representable time.
Definition time.hpp:1101
GloTime GetGloTime(const int prec=9) const
Get time as GLONASS time (UTC + 3h)
static Time FromNSec(const uint64_t nsec)
Time from nanoseconds (atomic)
static const Time ZERO
Zero (invalid, uninitialised) time.
Definition time.hpp:1103
RosTime GetRosTime() const
Get time as ROS time (POSIX)
std::string StrWnoTow(const WnoTow::Sys sys=WnoTow::Sys::GPS, const int prec=3) const
Stringify as GNSS time (atomic)
static Time FromRosTime(const RosTime &rostime)
From ROS time (POSIX)
uint32_t nsec_
Nanoseconds part of time (should be in range 0-999999999)
Definition time.hpp:1107
static Time FromPosix(const std::time_t posix)
From POSIX time (POSIX)
std::chrono::milliseconds GetChronoMilli() const
Get time as std::chrono::duration (milliseconds since epoch) (POSIX)
Time()
Constructor, empty (invalid) time.
bool SetCurrentLeapseconds(const int value) const
Set or change current leapseconds.
bool SetSec(const double sec)
Set time from seconds (atomic)
bool IsZero() const
Check if time is zero (invalid)
Time & operator-=(const int64_t nsec)
Subtract nanoseconds from time.
std::chrono::nanoseconds GetChronoNano() const
Get time as std::chrono::nanoseconds (nanoseconds since epoch) (POSIX)
bool SetGloTime(const GloTime &glotime)
Set time from GLONASS time (UTC + 3h)
bool SubDur(const Duration &dur)
Substract duration from time.
bool SetPosix(const time_t posix)
Set time from POSIX time (POSIX)
Duration operator-(const Time &rhs) const
Subtract time and time.
bool operator>(const Time &rhs) const
Greater than.
Time & operator-=(const Duration &rhs)
Subtract duration from time.
uint32_t sec_
Seconds part of time (atomic seconds since 1970-01-01 00:00:00 UTC)
Definition time.hpp:1106
static Time FromUtcTime(const UtcTime &utctime)
From UTC time (UTC)
static Time FromGloTime(const GloTime &glotime)
From GLONASS time (UTC + 3h)
bool SubSec(const double sec)
Substract seconds from time.
Time operator+(const int64_t nsec) const
Sum time and nanoseconds.
bool AddSec(const double sec)
Add seconds to time.
time_t GetTai() const
Get time as TAI time (CLOCK_TAI)
bool AddNSec(const int64_t nsec)
Add nanoseconds to time.
bool SubNSec(const int64_t nsec)
Substract nanoseconds from time.
bool operator<(const Time &rhs) const
Smaller than.
static Time FromSecNSec(const uint32_t sec, const uint32_t nsec)
Time from seconds and nanoseconds (atomic)
bool Diff(const Time &other, Duration &diff) const
Calculate difference between times.
bool SetSecNSec(const uint32_t sec, const uint32_t nsec)
Set time from seconds and nanoseconds (atomic)
Time & operator-=(const double sec)
Subtract seconds from time.
uint64_t GetNSec() const
Get time as nanoseconds (atomic)
static Time FromWnoTow(const WnoTow &wnotow)
From GNSS time (atomic)
Time operator-(const double sec) const
Subtract time and seconds.
static Time FromClockRealtime()
From system clock current (now) system time (CLOCK_REALTIME)
Time & operator+=(const Duration &rhs)
Add duration to time.
bool SetRosTime(const RosTime &rostime)
Set time from ROS time (POSIX)
bool AddDur(const Duration &dur)
Add duration to time.
bool operator==(const Time &rhs) const
Equal.
static const Time MAX
Maximum representable time.
Definition time.hpp:1102
bool operator>=(const Time &rhs) const
Greater or equal than.
bool SetNSec(const uint64_t nsec)
Set time from nanoseconds (atomic)
Time operator-(const int64_t nsec) const
Subtract time and nanoseconds.
bool SetWnoTow(const WnoTow &wnotow)
Set time from GNSS (GPS, Galileo, BeiDou) time (atomic)
bool operator!=(const Time &rhs) const
Not equal.
double GetSec(const int prec=9) const
Get time as seconds (atomic)
WnoTow GetWnoTow(const WnoTow::Sys sys=WnoTow::Sys::GPS, const int prec=9) const
Get time as GNSS (GPS, Galileo, BeiDou) time (atomic)
std::string StrIsoTime(const int prec=0) const
Stringify as ISO 8601 time (UTC)
Time operator+(const double sec) const
Sum time and seconds.
static constexpr int SEC_IN_MIN_I
Constants.
Definition time.hpp:48
static constexpr double SEC_IN_MIN_D
Number of seconds in a minute (double)
Definition time.hpp:52
static constexpr int SEC_IN_WEEK_I
Number of seconds in a week (integer)
Definition time.hpp:51
static constexpr double SEC_IN_WEEK_D
Number of seconds in a week (double)
Definition time.hpp:55
uint64_t GetMillis()
Get milliseconds [ms], monotonic time.
static constexpr int SEC_IN_DAY_I
Number of seconds in a day (integer)
Definition time.hpp:50
static constexpr double SEC_IN_HOUR_D
Number of seconds in an hour (double)
Definition time.hpp:53
static constexpr double SEC_IN_DAY_D
Number of seconds in a day (double)
Definition time.hpp:54
double GetSecs()
Get seconds [s], monotonic time.
static constexpr int SEC_IN_HOUR_I
Number of seconds in an hour (integer)
Definition time.hpp:49
Fixposition SDK.
GloTime(const int N4, const int Nt, const double TOD)
Constructor.
int Nt_
Day in four-year interval, valid range: 1-1461.
Definition time.hpp:478
double TOD_
Time of day (in Москва time zone) [s].
Definition time.hpp:479
int N4_
Four-year interval, 1=1996..1999, 2=2000..2003, ..., valid range: 1-...
Definition time.hpp:477
Minimal ros::Time() / rplcpp::Time implementation (that doesn't throw)
Definition time.hpp:117
bool operator==(const RosTime &rhs) const
Equal.
RosTime(const uint32_t sec, const uint32_t nsec)
Constructor.
uint32_t nsec_
Nanoseconds part of time (should be in range 0-999999999)
Definition time.hpp:142
uint32_t sec_
Seconds part of time.
Definition time.hpp:141
double ToSec() const
Convert to seconds.
bool IsZero() const
Check if time is zero (invalid, unset)
UTC time representation.
Definition time.hpp:487
double sec_
Second (0-60)
Definition time.hpp:508
int min_
Minute (0-59)
Definition time.hpp:507
int month_
Month (1-12)
Definition time.hpp:504
UtcTime(const int year, const int month, const int day, const int hour, const int min, const double sec)
Constructor.
GNSS atomic time representation: week number (wno) and time of week (tow) used by GPS,...
Definition time.hpp:421
Sys sys_
Time system.
Definition time.hpp:450
double tow_
Time of week [s] (0.0-603'799.999..)
Definition time.hpp:449
int wno_
Week number [-] (>= 0)
Definition time.hpp:448
Sys
GNSS time system.
Definition time.hpp:425
@ GPS
GPS (also: SBAS, QZSS)
@ GAL
Galileo system time (GST)
WnoTow(const Sys sys=Sys::GPS)
Constructor.
WnoTow(const int wno, const double tow, const Sys sys=Sys::GPS)
Constructor.
const char * SysStr() const
Stringify time system (for debugging)