Fixposition SDK 0.0.0-heads/main-0-g90a51ff
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 * Based on work 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 * \verbatim
525 * ---1970-------------1980-------1996-1999----2006--------------------2106---//--fuuuuuture----> time
526 *
527 * 1970-01-01 00:00:00.0 UTC |<----- std::time_t ---------------------------------------------------//----->|
528 * |<----- ros::Time/rclcpp::Time----------------------------------->|
529 * 1980-01-06 00:00:00.0 UTC |<---- GPS time---------------------------------------//----->
530 * 1996-01-01 00:00:00.0 UTC(SU) |<---- GLONASS time -----------------------//----->
531 * 1999-08-21 23:59:47.0 UTC |<---- Galileo time ------------------//----->
532 * 2006-01-01 00:00:00.0 UTC |<---- BeiDou time -----------//----->
533 *
534 * |<======================= Time object ===========================>|
535 * T_MIN T_MAX
536 * 1970-01-01 00:00:0.0 UTC 2106-02-06 06:28:16.0 UTC (approximately!)
537 *
538 * Some notes:
539 *
540 * - "Strict" POSIX time is used for the methods marked with "POSIX". This time has a discontinuity and/or ambiguity
541 * at/during leapsecond events. It does not use the "Mills" or NTP style of handling these periods and is therefore,
542 * for those timestamps, likely not compatible with the system time (CLOCK_REALTIME) of a typical Linux system. See
543 * references below.
544 * - The from/to UTC calculations are not fully correct for times before 1972.
545 * - FromClockTai() and SetClockTai() likely will not give the expected result unless your system (Linux kernel) is
546 * configured for the correct leapsecond.
547 * - The precision of all integer getters, setters and operators should be [ns] in all cases
548 * - The precision of all double getters, setters and operators should be [ns] in most cases
549 * - The internal representation of time (the sec_ value) is atomic, but it is not CLOCK_TAI (which already "has" 10
550 * leapseconds at sec_ = 0).
551 *
552 * Some references:
553 *
554 * - https://en.wikipedia.org/wiki/Unix_time
555 * - https://en.wikipedia.org/wiki/Atomic_clock
556 * - https://en.wikipedia.org/wiki/Coordinated_Universal_Time
557 * - https://docs.ntpsec.org/latest/leapsmear.html
558 * - https://www.eecis.udel.edu/~mills/leap.html
559 * - https://manpages.org/adjtimex/2
560 *
561 * \endverbatim
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 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 * @note These throw std::runtime_error if the values are out of range.
691 * @{
692 */
693
694 /**
695 * @brief Set time from seconds and nanoseconds (atomic)
696 *
697 * @param[in] sec Time value seconds
698 * @param[in] nsec Time value nanoseconds
699 *
700 * @returns true if successful, false otherwise (bad time)
701 */
702 bool SetSecNSec(const uint32_t sec, const uint32_t nsec);
703
704 /**
705 * @brief Set time from nanoseconds (atomic)
706 *
707 * @param[in] nsec Time value nanoseconds (> 0)
708 *
709 * @returns true if successful, false otherwise (bad time)
710 */
711 bool SetNSec(const uint64_t nsec);
712
713 /**
714 * @brief Set time from seconds (atomic)
715 *
716 * @param[in] sec Time value seconds (> 0.0)
717 *
718 * @returns true if successful, false otherwise (bad time)
719 */
720 bool SetSec(const double sec);
721
722 /**
723 * @brief Set time from POSIX time (POSIX)
724 *
725 * @note See comments in the class description regarding POSIX time!
726 *
727 * @param[in] posix The POSIX time
728 *
729 * @returns true if successful, false otherwise (bad time)
730 */
731 bool SetPosix(const time_t posix);
732
733 /**
734 * @brief Set time from ROS time (POSIX)
735 *
736 * @note See comments in the class description regarding POSIX time!
737 *
738 * @param[in] rostime Time value
739 *
740 * @returns true if successful, false otherwise (bad time)
741 */
742 bool SetRosTime(const RosTime& rostime);
743
744 /**
745 * @brief Set time from GNSS (GPS, Galileo, BeiDou) time (atomic)
746 *
747 * @param[in] wnotow GNSS time
748 *
749 * @returns true if successful, false otherwise (bad time)
750 */
751 bool SetWnoTow(const WnoTow& wnotow);
752
753 /**
754 * @brief Set time from GLONASS time (UTC + 3h)
755 *
756 * @param[in] glotime GLONASS time
757 *
758 * @returns true if successful, false otherwise (bad time)
759 */
760 bool SetGloTime(const GloTime& glotime);
761
762 /**
763 * @brief Set time from UTC time (UTC)
764 *
765 * @param[in] utctime UTC time
766 *
767 * @returns true if successful, false otherwise (bad time)
768 */
769 bool SetUtcTime(const UtcTime& utctime);
770
771 /**
772 * @brief Set time from TAI time (CLOCK_TAI)
773 *
774 * @param[in] tai The TAI time
775 *
776 * @returns true if successful, false otherwise (bad time)
777 */
778 bool SetTai(const time_t tai);
779
780 /**
781 * @brief Set time from system clock current (now) system time (CLOCK_REALTIME)
782 *
783 * @returns true if successful, false otherwise (bad time)
784 */
786
787#ifdef CLOCK_TAI
788 /**
789 * @brief Set time from system clock current (now) TAI time (CLOCK_TAI)
790 *
791 * @note This will only produce the right result if your system is configured accordingly (which is unlikely). See
792 * comments in the Time class description.
793 *
794 * @returns the Time object
795 */
796
797 bool SetClockTai();
798#endif
799
800 ///@}
801 // -----------------------------------------------------------------------------------------------------------------
802 /**
803 * @name Get time
804 * @{
805 */
806
807 /**
808 * @brief Get time as nanoseconds (atomic)
809 *
810 * @returns the time as nanoseconds
811 */
812 uint64_t GetNSec() const;
813
814 /**
815 * @brief Get time as seconds (atomic)
816 *
817 * @param[in] prec Round the seconds to this many fractional digits (0-9)
818 *
819 * @returns the time as seconds
820 */
821 double GetSec(const int prec = 9) const;
822
823 /**
824 * @brief Get time as POSIX time (POSIX)
825 *
826 * @note See comments in the class description regarding POSIX time!
827 *
828 * @returns the POSIX time, truncated (rounded down, sub-seconds ignored)
829 */
830 time_t GetPosix() const;
831
832 /**
833 * @brief Get time as ROS time (POSIX)
834 *
835 * @note See comments in the class description regarding POSIX time!
836 *
837 * @returns the time
838 */
840
841 /**
842 * @brief Get time as GNSS (GPS, Galileo, BeiDou) time (atomic)
843 *
844 * @note For times before the respective GNSS epoch the result is not usable (e.g. negative week numbers).
845 *
846 * @param[in] sys GNSS
847 * @param[in] prec Round the seconds to this many fractional digits (0-9)
848 *
849 * @returns the GNSS time for the selected GNSS
850 */
851 WnoTow GetWnoTow(const WnoTow::Sys sys = WnoTow::Sys::GPS, const int prec = 9) const;
852
853 /**
854 * @brief Get time as GLONASS time (UTC + 3h)
855 *
856 * @param[in] prec Round the seconds to this many fractional digits (0-9)
857 *
858 * @returns the GLONASS time
859 */
860 GloTime GetGloTime(const int prec = 9) const;
861
862 /**
863 * @brief Get time as UTC time (UTC)
864 *
865 * @param[in] prec Round the seconds to this many fractional digits (0-9)
866 *
867 * @returns the UTC time
868 */
869 UtcTime GetUtcTime(const int prec = 9) const;
870
871 /**
872 * @brief Get day of year
873 *
874 * @param[in] prec Round to this many fractional digits (0-12)
875 *
876 * @returns the day of the year
877 */
878 double GetDayOfYear(const int prec = 12) const;
879
880 /**
881 * @brief Get time as TAI time (CLOCK_TAI)
882 *
883 * @returns the TAI time, truncated (rounded down, sub-seconds ignored)
884 */
885 time_t GetTai() const;
886
887 /**
888 * @brief Get time as std::chrono::duration (milliseconds since epoch) (POSIX)
889 *
890 * @note See comments in the class description regarding POSIX time!
891 *
892 * @returns the time as std::chrono::milliseconds
893 */
894 std::chrono::milliseconds GetChronoMilli() const;
895
896 /**
897 * @brief Get time as std::chrono::nanoseconds (nanoseconds since epoch) (POSIX)
898 *
899 * @note See comments in the class description regarding POSIX time!
900 *
901 * @returns the time as std::chrono::nanoseconds
902 */
903 std::chrono::nanoseconds GetChronoNano() const;
904
905 ///@}
906 // -----------------------------------------------------------------------------------------------------------------
907 /**
908 * @name Misc
909 * @{
910 */
911
912 /**
913 * @brief Check if time is zero (invalid)
914 *
915 * @returns true if time is exactly zero
916 */
917 bool IsZero() const;
918
919 ///@}
920 // -----------------------------------------------------------------------------------------------------------------
921 /**
922 * @name Arithmetic methods
923 *
924 * These do not throw and instead return true/false.
925 * @{
926 */
927
928 /**
929 * @brief Add duration to time
930 *
931 * @param[in] dur Duration to add
932 *
933 * @returns true if successful (dur value in range), false otherwise (bad sec value)
934 */
935 bool AddDur(const Duration& dur);
936
937 /**
938 * @brief Add seconds to time
939 *
940 * @param[in] sec Seconds to add
941 *
942 * @returns true if successful (sec value in range), false otherwise (bad sec value)
943 */
944 bool AddSec(const double sec);
945
946 /**
947 * @brief Add nanoseconds to time
948 *
949 * @param[in] nsec Nanoseconds to add
950 *
951 * @returns true if successful (sec value in range), false otherwise (bad sec value)
952 */
953 bool AddNSec(const int64_t nsec);
954
955 /**
956 * @brief Substract duration from time
957 *
958 * @param[in] dur Duration to substract
959 *
960 * @returns true if successful (dur value in range), false otherwise (bad sec value)
961 */
962 bool SubDur(const Duration& dur);
963
964 /**
965 * @brief Substract nanoseconds from time
966 *
967 * @param[in] nsec Nanoseconds to substract
968 *
969 * @returns true if successful (sec value in range), false otherwise (bad sec value)
970 */
971 bool SubNSec(const int64_t nsec);
972
973 /**
974 * @brief Substract seconds from time
975 *
976 * @param[in] sec Seconds to substract
977 *
978 * @returns true if successful (sec value in range), false otherwise (bad sec value)
979 */
980 bool SubSec(const double sec);
981
982 /**
983 * @brief Calculate difference between times
984 *
985 * @param[in] other The other time
986 * @param[out] diff The difference to the other time (time - other)
987 *
988 * @returns true if the times and the difference are within range, false otherwise
989 */
990 bool Diff(const Time& other, Duration& diff) const;
991
992 ///@}
993 // -----------------------------------------------------------------------------------------------------------------
994 /**
995 * @name Arithmetic operators
996 *
997 * @note These throw std::runtime_error if the values are out of range.
998 * @{
999 */
1000
1001 Time operator+(const Duration& rhs) const; //!< Sum time and duration
1002 Time operator+(const int64_t nsec) const; //!< Sum time and nanoseconds
1003 Time operator+(const double sec) const; //!< Sum time and seconds
1004 Time& operator+=(const Duration& rhs); //!< Add duration to time
1005 Time& operator+=(const int64_t nsec); //!< Add nanoseconds to time
1006 Time& operator+=(const double sec); //!< Add seconds to time
1007 Time operator-(const Duration& rhs) const; //!< Subtract time and duration
1008 Time operator-(const int64_t nsec) const; //!< Subtract time and nanoseconds
1009 Time operator-(const double sec) const; //!< Subtract time and seconds
1010 Time& operator-=(const Duration& rhs); //!< Subtract duration from time
1011 Time& operator-=(const int64_t nsec); //!< Subtract nanoseconds from time
1012 Time& operator-=(const double sec); //!< Subtract seconds from time
1013 Duration operator-(const Time& rhs) const; //!< Subtract time and time
1014
1015 ///@}
1016 // -----------------------------------------------------------------------------------------------------------------
1017 /**
1018 * @name Logic operators
1019 * @{
1020 */
1021
1022 bool operator==(const Time& rhs) const; //!< Equal
1023 bool operator!=(const Time& rhs) const; //!< Not equal
1024 bool operator>(const Time& rhs) const; //!< Greater than
1025 bool operator<(const Time& rhs) const; //!< Smaller than
1026 bool operator>=(const Time& rhs) const; //!< Greater or equal than
1027 bool operator<=(const Time& rhs) const; //!< Smaller or equal than
1028
1029 ///@}
1030 // -----------------------------------------------------------------------------------------------------------------
1031 /**
1032 * @name Stringification
1033 *
1034 * See also fpsdk::common::string::Strftime().
1035 *
1036 * @{
1037 */
1038
1039 /**
1040 * @brief Stringify as GNSS time (atomic)
1041 *
1042 * @param[in] sys The desired GNSS time system
1043 * @param[in] prec Number of fractional digits for the seconds (0-9)
1044 *
1045 * @returns a string with formatted week-number and time-of-week ("wwww:tttttt.ttt")
1046 */
1047 std::string StrWnoTow(const WnoTow::Sys sys = WnoTow::Sys::GPS, const int prec = 3) const;
1048
1049 /**
1050 * @brief Stringify as year, month, day, hour, minute and second time (UTC)
1051 *
1052 * @param[in] prec Number of fractional digits for the seconds (0-9)
1053 *
1054 * @returns a string with formatted UTC time ("yyyy-mm-dd hh:mm:ss.sss")
1055 */
1056 std::string StrUtcTime(const int prec = 3) const;
1057
1058 /**
1059 * @brief Stringify as ISO 8601 time (UTC)
1060 *
1061 * @param[in] prec Number of fractional digits for the seconds (0-9)
1062 *
1063 * @returns a string with formatted UTC time ("yyyyddmmThhmmssZ")
1064 */
1065 std::string StrIsoTime(const int prec = 0) const;
1066
1067 ///@}
1068 // -----------------------------------------------------------------------------------------------------------------
1069
1070 static const Time MIN; //!< Minimum representable time
1071 static const Time MAX; //!< Maximum representable time
1072 static const Time ZERO; //!< Zero (invalid, uninitialised) time
1073
1074 // Storage deliberately public
1075 uint32_t sec_; //!< Seconds part of time (atomic seconds since 1970-01-01 00:00:00 UTC)
1076 uint32_t nsec_; //!< Nanoseconds part of time (*should* be in range 0-999999999)
1077};
1078
1079/* ****************************************************************************************************************** */
1080} // namespace time
1081} // namespace common
1082} // namespace fpsdk
1083#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:1070
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:1072
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:1076
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:1075
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:1071
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)