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