From 11986fc6a9b79c41a5e7cb9cad7fe5e617d4b8a8 Mon Sep 17 00:00:00 2001 From: johnk Date: Tue, 18 Oct 2022 12:14:02 -0500 Subject: [PATCH 01/16] Add NavData::clone method to leaf classes to make alterable shared_ptr copies that don't affect the original --- core/lib/NewNav/BDSD1NavAlm.hpp | 3 +++ core/lib/NewNav/BDSD1NavEph.hpp | 3 +++ core/lib/NewNav/BDSD1NavHealth.hpp | 3 +++ core/lib/NewNav/BDSD1NavISC.hpp | 3 +++ core/lib/NewNav/BDSD1NavIono.hpp | 3 +++ core/lib/NewNav/BDSD1NavTimeOffset.hpp | 3 +++ core/lib/NewNav/BDSD2NavAlm.hpp | 3 +++ core/lib/NewNav/BDSD2NavEph.hpp | 3 +++ core/lib/NewNav/BDSD2NavHealth.hpp | 3 +++ core/lib/NewNav/BDSD2NavISC.hpp | 3 +++ core/lib/NewNav/BDSD2NavIono.hpp | 3 +++ core/lib/NewNav/BDSD2NavTimeOffset.hpp | 3 +++ core/lib/NewNav/GLOCNavAlm.hpp | 3 +++ core/lib/NewNav/GLOCNavEph.hpp | 3 +++ core/lib/NewNav/GLOCNavHealth.hpp | 3 +++ core/lib/NewNav/GLOCNavIono.hpp | 3 +++ core/lib/NewNav/GLOCNavUT1TimeOffset.hpp | 3 +++ core/lib/NewNav/GLOFNavAlm.hpp | 3 +++ core/lib/NewNav/GLOFNavEph.hpp | 3 +++ core/lib/NewNav/GLOFNavHealth.hpp | 3 +++ core/lib/NewNav/GLOFNavISC.hpp | 3 +++ core/lib/NewNav/GLOFNavTimeOffset.hpp | 3 +++ core/lib/NewNav/GLOFNavUT1TimeOffset.hpp | 3 +++ core/lib/NewNav/GPSCNav2Alm.hpp | 3 +++ core/lib/NewNav/GPSCNav2Eph.hpp | 3 +++ core/lib/NewNav/GPSCNav2Health.hpp | 3 +++ core/lib/NewNav/GPSCNav2ISC.hpp | 3 +++ core/lib/NewNav/GPSCNav2Iono.hpp | 3 +++ core/lib/NewNav/GPSCNav2TimeOffset.hpp | 3 +++ core/lib/NewNav/GPSCNavAlm.hpp | 3 +++ core/lib/NewNav/GPSCNavEph.hpp | 3 +++ core/lib/NewNav/GPSCNavHealth.hpp | 3 +++ core/lib/NewNav/GPSCNavISC.hpp | 3 +++ core/lib/NewNav/GPSCNavIono.hpp | 3 +++ core/lib/NewNav/GPSCNavRedAlm.hpp | 3 +++ core/lib/NewNav/GPSCNavTimeOffset.hpp | 3 +++ core/lib/NewNav/GPSLNavAlm.hpp | 3 +++ core/lib/NewNav/GPSLNavEph.hpp | 3 +++ core/lib/NewNav/GPSLNavHealth.hpp | 3 +++ core/lib/NewNav/GPSLNavISC.hpp | 3 +++ core/lib/NewNav/GPSLNavIono.hpp | 3 +++ core/lib/NewNav/GPSLNavTimeOffset.hpp | 3 +++ core/lib/NewNav/GalFNavAlm.hpp | 3 +++ core/lib/NewNav/GalFNavEph.hpp | 3 +++ core/lib/NewNav/GalFNavHealth.hpp | 3 +++ core/lib/NewNav/GalFNavISC.hpp | 3 +++ core/lib/NewNav/GalFNavIono.hpp | 3 +++ core/lib/NewNav/GalFNavTimeOffset.hpp | 3 +++ core/lib/NewNav/GalINavAlm.hpp | 3 +++ core/lib/NewNav/GalINavEph.hpp | 3 +++ core/lib/NewNav/GalINavHealth.hpp | 3 +++ core/lib/NewNav/GalINavISC.hpp | 3 +++ core/lib/NewNav/GalINavIono.hpp | 3 +++ core/lib/NewNav/GalINavTimeOffset.hpp | 3 +++ core/lib/NewNav/NavData.hpp | 2 ++ core/lib/NewNav/OrbitDataSP3.hpp | 3 +++ core/lib/NewNav/RinexTimeOffset.hpp | 3 +++ core/tests/NewNav/BDSD1NavData_T.cpp | 2 ++ core/tests/NewNav/BDSD2NavData_T.cpp | 2 ++ core/tests/NewNav/GLOFNavData_T.cpp | 2 ++ core/tests/NewNav/GPSCNavData_T.cpp | 2 ++ core/tests/NewNav/GPSLNavData_T.cpp | 2 ++ core/tests/NewNav/InterSigCorr_T.cpp | 2 ++ core/tests/NewNav/KlobucharIonoNavData_T.cpp | 15 ++++++++++++--- core/tests/NewNav/NavDataFactoryWithStore_T.cpp | 3 +++ core/tests/NewNav/NavHealthData_T.cpp | 2 ++ core/tests/NewNav/NeQuickIonoNavData_T.cpp | 17 +++++++++++++---- core/tests/NewNav/OrbitDataKepler_T.cpp | 2 ++ core/tests/NewNav/StdNavTimeOffset_T.cpp | 2 ++ 69 files changed, 216 insertions(+), 7 deletions(-) diff --git a/core/lib/NewNav/BDSD1NavAlm.hpp b/core/lib/NewNav/BDSD1NavAlm.hpp index 730472c2d..629406afc 100644 --- a/core/lib/NewNav/BDSD1NavAlm.hpp +++ b/core/lib/NewNav/BDSD1NavAlm.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. BDSD1NavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD1NavEph.hpp b/core/lib/NewNav/BDSD1NavEph.hpp index 260aca0b5..dd1ccfd82 100644 --- a/core/lib/NewNav/BDSD1NavEph.hpp +++ b/core/lib/NewNav/BDSD1NavEph.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. BDSD1NavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD1NavHealth.hpp b/core/lib/NewNav/BDSD1NavHealth.hpp index 9905167f0..8dc8f1ea2 100644 --- a/core/lib/NewNav/BDSD1NavHealth.hpp +++ b/core/lib/NewNav/BDSD1NavHealth.hpp @@ -73,6 +73,9 @@ namespace gnsstk /// Initialize to unhealthy using a value typically not seen in health. BDSD1NavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD1NavISC.hpp b/core/lib/NewNav/BDSD1NavISC.hpp index a6d3cf5c1..d225af6d5 100644 --- a/core/lib/NewNav/BDSD1NavISC.hpp +++ b/core/lib/NewNav/BDSD1NavISC.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Initialize data members. BDSD1NavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/BDSD1NavIono.hpp b/core/lib/NewNav/BDSD1NavIono.hpp index f7c3a5477..ca17cc725 100644 --- a/core/lib/NewNav/BDSD1NavIono.hpp +++ b/core/lib/NewNav/BDSD1NavIono.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Sets the nav message type. BDSD1NavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD1NavTimeOffset.hpp b/core/lib/NewNav/BDSD1NavTimeOffset.hpp index e12c4391f..06c9009ac 100644 --- a/core/lib/NewNav/BDSD1NavTimeOffset.hpp +++ b/core/lib/NewNav/BDSD1NavTimeOffset.hpp @@ -69,6 +69,9 @@ namespace gnsstk public: /// Initialize all data to 0. BDSD1NavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Return the number of seconds prior to the effectivity * time (2/3 of a day) during which the standard delta t diff --git a/core/lib/NewNav/BDSD2NavAlm.hpp b/core/lib/NewNav/BDSD2NavAlm.hpp index 145cbe1de..c8068cded 100644 --- a/core/lib/NewNav/BDSD2NavAlm.hpp +++ b/core/lib/NewNav/BDSD2NavAlm.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. BDSD2NavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD2NavEph.hpp b/core/lib/NewNav/BDSD2NavEph.hpp index fb068c201..2462d75c2 100644 --- a/core/lib/NewNav/BDSD2NavEph.hpp +++ b/core/lib/NewNav/BDSD2NavEph.hpp @@ -59,6 +59,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. BDSD2NavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Compute the satellites position and velocity at a time. * @note This overrides the default OrbitDataKepler diff --git a/core/lib/NewNav/BDSD2NavHealth.hpp b/core/lib/NewNav/BDSD2NavHealth.hpp index 93c7f84a6..6eed69444 100644 --- a/core/lib/NewNav/BDSD2NavHealth.hpp +++ b/core/lib/NewNav/BDSD2NavHealth.hpp @@ -73,6 +73,9 @@ namespace gnsstk /// Initialize to unhealthy using a value typically not seen in health. BDSD2NavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD2NavISC.hpp b/core/lib/NewNav/BDSD2NavISC.hpp index a299ec923..028eba497 100644 --- a/core/lib/NewNav/BDSD2NavISC.hpp +++ b/core/lib/NewNav/BDSD2NavISC.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Initialize data members. BDSD2NavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/BDSD2NavIono.hpp b/core/lib/NewNav/BDSD2NavIono.hpp index 14d7a4927..4a6764f70 100644 --- a/core/lib/NewNav/BDSD2NavIono.hpp +++ b/core/lib/NewNav/BDSD2NavIono.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Sets the nav message type. BDSD2NavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/BDSD2NavTimeOffset.hpp b/core/lib/NewNav/BDSD2NavTimeOffset.hpp index 1e7f88fa0..7be9f8152 100644 --- a/core/lib/NewNav/BDSD2NavTimeOffset.hpp +++ b/core/lib/NewNav/BDSD2NavTimeOffset.hpp @@ -69,6 +69,9 @@ namespace gnsstk public: /// Initialize all data to 0. BDSD2NavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Return the number of seconds prior to the effectivity * time (2/3 of a day) during which the standard delta t diff --git a/core/lib/NewNav/GLOCNavAlm.hpp b/core/lib/NewNav/GLOCNavAlm.hpp index f0496e28c..5ef208032 100644 --- a/core/lib/NewNav/GLOCNavAlm.hpp +++ b/core/lib/NewNav/GLOCNavAlm.hpp @@ -78,6 +78,9 @@ namespace gnsstk /// Sets the nav message type, and all other data members to 0. GLOCNavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOCNavEph.hpp b/core/lib/NewNav/GLOCNavEph.hpp index 3a1dba90f..3a5489dfe 100644 --- a/core/lib/NewNav/GLOCNavEph.hpp +++ b/core/lib/NewNav/GLOCNavEph.hpp @@ -66,6 +66,9 @@ namespace gnsstk /// Sets the nav message type and all other data members to 0. GLOCNavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOCNavHealth.hpp b/core/lib/NewNav/GLOCNavHealth.hpp index b28c78bd4..daab60179 100644 --- a/core/lib/NewNav/GLOCNavHealth.hpp +++ b/core/lib/NewNav/GLOCNavHealth.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Initialize to unhealthy using a value typically not seen in health. GLOCNavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOCNavIono.hpp b/core/lib/NewNav/GLOCNavIono.hpp index ead9e698a..ee16dd7c0 100644 --- a/core/lib/NewNav/GLOCNavIono.hpp +++ b/core/lib/NewNav/GLOCNavIono.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GLOCNavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOCNavUT1TimeOffset.hpp b/core/lib/NewNav/GLOCNavUT1TimeOffset.hpp index c1f38544a..cea38d254 100644 --- a/core/lib/NewNav/GLOCNavUT1TimeOffset.hpp +++ b/core/lib/NewNav/GLOCNavUT1TimeOffset.hpp @@ -60,6 +60,9 @@ namespace gnsstk public: /// Initialize all data to 0. GLOCNavUT1TimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the contents of this object in a human-readable * format. Uses parameters for GLONASS instead of generalized. diff --git a/core/lib/NewNav/GLOFNavAlm.hpp b/core/lib/NewNav/GLOFNavAlm.hpp index f9d093a48..64052c84a 100644 --- a/core/lib/NewNav/GLOFNavAlm.hpp +++ b/core/lib/NewNav/GLOFNavAlm.hpp @@ -76,6 +76,9 @@ namespace gnsstk /// Sets the nav message type, and all other data members to 0. GLOFNavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOFNavEph.hpp b/core/lib/NewNav/GLOFNavEph.hpp index a86f4fa91..52af9f016 100644 --- a/core/lib/NewNav/GLOFNavEph.hpp +++ b/core/lib/NewNav/GLOFNavEph.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. GLOFNavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOFNavHealth.hpp b/core/lib/NewNav/GLOFNavHealth.hpp index 8690f1e61..c98daf9fa 100644 --- a/core/lib/NewNav/GLOFNavHealth.hpp +++ b/core/lib/NewNav/GLOFNavHealth.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Initialize to unhealthy using a value typically not seen in health. GLOFNavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOFNavISC.hpp b/core/lib/NewNav/GLOFNavISC.hpp index 8635f4619..a73c548bd 100644 --- a/core/lib/NewNav/GLOFNavISC.hpp +++ b/core/lib/NewNav/GLOFNavISC.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize data members. GLOFNavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOFNavTimeOffset.hpp b/core/lib/NewNav/GLOFNavTimeOffset.hpp index ce47a1b3b..277b2eada 100644 --- a/core/lib/NewNav/GLOFNavTimeOffset.hpp +++ b/core/lib/NewNav/GLOFNavTimeOffset.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize all data to 0. GLOFNavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GLOFNavUT1TimeOffset.hpp b/core/lib/NewNav/GLOFNavUT1TimeOffset.hpp index 0108776eb..d8833d23f 100644 --- a/core/lib/NewNav/GLOFNavUT1TimeOffset.hpp +++ b/core/lib/NewNav/GLOFNavUT1TimeOffset.hpp @@ -61,6 +61,9 @@ namespace gnsstk public: /// Initialize all data to 0. GLOFNavUT1TimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the contents of this object in a human-readable * format. diff --git a/core/lib/NewNav/GPSCNav2Alm.hpp b/core/lib/NewNav/GPSCNav2Alm.hpp index 6e2763c31..1208ed713 100644 --- a/core/lib/NewNav/GPSCNav2Alm.hpp +++ b/core/lib/NewNav/GPSCNav2Alm.hpp @@ -60,6 +60,9 @@ namespace gnsstk /// Sets the nav message type. GPSCNav2Alm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNav2Eph.hpp b/core/lib/NewNav/GPSCNav2Eph.hpp index 75a73c532..6c8c690c5 100644 --- a/core/lib/NewNav/GPSCNav2Eph.hpp +++ b/core/lib/NewNav/GPSCNav2Eph.hpp @@ -62,6 +62,9 @@ namespace gnsstk /// Sets the nav message type and all other data members to 0. GPSCNav2Eph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNav2Health.hpp b/core/lib/NewNav/GPSCNav2Health.hpp index 6ee100837..06e76df77 100644 --- a/core/lib/NewNav/GPSCNav2Health.hpp +++ b/core/lib/NewNav/GPSCNav2Health.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Initialize to unhealthy. GPSCNav2Health(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNav2ISC.hpp b/core/lib/NewNav/GPSCNav2ISC.hpp index 1238a3cf4..d19e949a4 100644 --- a/core/lib/NewNav/GPSCNav2ISC.hpp +++ b/core/lib/NewNav/GPSCNav2ISC.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the internal data members. GPSCNav2ISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/GPSCNav2Iono.hpp b/core/lib/NewNav/GPSCNav2Iono.hpp index 12a338730..3ff536bcc 100644 --- a/core/lib/NewNav/GPSCNav2Iono.hpp +++ b/core/lib/NewNav/GPSCNav2Iono.hpp @@ -57,6 +57,9 @@ namespace gnsstk { msgLenSec = 5.48; } + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } }; //@} diff --git a/core/lib/NewNav/GPSCNav2TimeOffset.hpp b/core/lib/NewNav/GPSCNav2TimeOffset.hpp index 4e69f8cc2..29609c543 100644 --- a/core/lib/NewNav/GPSCNav2TimeOffset.hpp +++ b/core/lib/NewNav/GPSCNav2TimeOffset.hpp @@ -64,6 +64,9 @@ namespace gnsstk public: /// Initialize all data to 0. GPSCNav2TimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavAlm.hpp b/core/lib/NewNav/GPSCNavAlm.hpp index 5f8237dd0..a9f972702 100644 --- a/core/lib/NewNav/GPSCNavAlm.hpp +++ b/core/lib/NewNav/GPSCNavAlm.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GPSCNavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavEph.hpp b/core/lib/NewNav/GPSCNavEph.hpp index 1df61c299..d38663314 100644 --- a/core/lib/NewNav/GPSCNavEph.hpp +++ b/core/lib/NewNav/GPSCNavEph.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. GPSCNavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavHealth.hpp b/core/lib/NewNav/GPSCNavHealth.hpp index 7297ca52a..9099aca6c 100644 --- a/core/lib/NewNav/GPSCNavHealth.hpp +++ b/core/lib/NewNav/GPSCNavHealth.hpp @@ -58,6 +58,9 @@ namespace gnsstk GPSCNavHealth() : health(true) {} + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavISC.hpp b/core/lib/NewNav/GPSCNavISC.hpp index 18098437d..99ddf9630 100644 --- a/core/lib/NewNav/GPSCNavISC.hpp +++ b/core/lib/NewNav/GPSCNavISC.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the internal data members. GPSCNavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/GPSCNavIono.hpp b/core/lib/NewNav/GPSCNavIono.hpp index f3e90230d..589362914 100644 --- a/core/lib/NewNav/GPSCNavIono.hpp +++ b/core/lib/NewNav/GPSCNavIono.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GPSCNavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavRedAlm.hpp b/core/lib/NewNav/GPSCNavRedAlm.hpp index 0d442e658..a3f80b693 100644 --- a/core/lib/NewNav/GPSCNavRedAlm.hpp +++ b/core/lib/NewNav/GPSCNavRedAlm.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Set data to default values. GPSCNavRedAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSCNavTimeOffset.hpp b/core/lib/NewNav/GPSCNavTimeOffset.hpp index 9575e6baa..8d286ffb1 100644 --- a/core/lib/NewNav/GPSCNavTimeOffset.hpp +++ b/core/lib/NewNav/GPSCNavTimeOffset.hpp @@ -64,6 +64,9 @@ namespace gnsstk public: /// Initialize all data to 0. GPSCNavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavAlm.hpp b/core/lib/NewNav/GPSLNavAlm.hpp index 66142f651..a631954ed 100644 --- a/core/lib/NewNav/GPSLNavAlm.hpp +++ b/core/lib/NewNav/GPSLNavAlm.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GPSLNavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavEph.hpp b/core/lib/NewNav/GPSLNavEph.hpp index b44664149..e257f9efd 100644 --- a/core/lib/NewNav/GPSLNavEph.hpp +++ b/core/lib/NewNav/GPSLNavEph.hpp @@ -61,6 +61,9 @@ namespace gnsstk /// Sets the nav message type and all other data members to 0. GPSLNavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavHealth.hpp b/core/lib/NewNav/GPSLNavHealth.hpp index 5f4c1549b..ff0a8ba8d 100644 --- a/core/lib/NewNav/GPSLNavHealth.hpp +++ b/core/lib/NewNav/GPSLNavHealth.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Initialize to unhealthy using a value typically not seen in health. GPSLNavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavISC.hpp b/core/lib/NewNav/GPSLNavISC.hpp index 588aa2160..0fa078f3c 100644 --- a/core/lib/NewNav/GPSLNavISC.hpp +++ b/core/lib/NewNav/GPSLNavISC.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize data members. GPSLNavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavIono.hpp b/core/lib/NewNav/GPSLNavIono.hpp index b13077db4..bb3ee6381 100644 --- a/core/lib/NewNav/GPSLNavIono.hpp +++ b/core/lib/NewNav/GPSLNavIono.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GPSLNavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GPSLNavTimeOffset.hpp b/core/lib/NewNav/GPSLNavTimeOffset.hpp index 2d6b9f035..6c26d62f9 100644 --- a/core/lib/NewNav/GPSLNavTimeOffset.hpp +++ b/core/lib/NewNav/GPSLNavTimeOffset.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize all data to 0. GPSLNavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalFNavAlm.hpp b/core/lib/NewNav/GalFNavAlm.hpp index 88f6d6b49..645bc5586 100644 --- a/core/lib/NewNav/GalFNavAlm.hpp +++ b/core/lib/NewNav/GalFNavAlm.hpp @@ -59,6 +59,9 @@ namespace gnsstk /// Sets the nav message type. GalFNavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalFNavEph.hpp b/core/lib/NewNav/GalFNavEph.hpp index 4cc3b9443..d690454b7 100644 --- a/core/lib/NewNav/GalFNavEph.hpp +++ b/core/lib/NewNav/GalFNavEph.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. GalFNavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalFNavHealth.hpp b/core/lib/NewNav/GalFNavHealth.hpp index 54e774165..186ec761c 100644 --- a/core/lib/NewNav/GalFNavHealth.hpp +++ b/core/lib/NewNav/GalFNavHealth.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize to unhealthy using a value typically not seen in health. GalFNavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalFNavISC.hpp b/core/lib/NewNav/GalFNavISC.hpp index 54ee34184..f304cafa4 100644 --- a/core/lib/NewNav/GalFNavISC.hpp +++ b/core/lib/NewNav/GalFNavISC.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Initialize data members. GalFNavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/GalFNavIono.hpp b/core/lib/NewNav/GalFNavIono.hpp index 30d133613..f8c4125f7 100644 --- a/core/lib/NewNav/GalFNavIono.hpp +++ b/core/lib/NewNav/GalFNavIono.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GalFNavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalFNavTimeOffset.hpp b/core/lib/NewNav/GalFNavTimeOffset.hpp index f68989f0a..f8e78a478 100644 --- a/core/lib/NewNav/GalFNavTimeOffset.hpp +++ b/core/lib/NewNav/GalFNavTimeOffset.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize all data to 0. GalFNavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalINavAlm.hpp b/core/lib/NewNav/GalINavAlm.hpp index b0fa5edca..a22e66768 100644 --- a/core/lib/NewNav/GalINavAlm.hpp +++ b/core/lib/NewNav/GalINavAlm.hpp @@ -59,6 +59,9 @@ namespace gnsstk /// Sets the nav message type. GalINavAlm(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalINavEph.hpp b/core/lib/NewNav/GalINavEph.hpp index 3007ea1d8..948688467 100644 --- a/core/lib/NewNav/GalINavEph.hpp +++ b/core/lib/NewNav/GalINavEph.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Sets the nav message type and all other data members to 0. GalINavEph(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalINavHealth.hpp b/core/lib/NewNav/GalINavHealth.hpp index c2439da47..d3b595b1b 100644 --- a/core/lib/NewNav/GalINavHealth.hpp +++ b/core/lib/NewNav/GalINavHealth.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize to unhealthy using a value typically not seen in health. GalINavHealth(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalINavISC.hpp b/core/lib/NewNav/GalINavISC.hpp index c0c7de276..f77b7fc71 100644 --- a/core/lib/NewNav/GalINavISC.hpp +++ b/core/lib/NewNav/GalINavISC.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Initialize data members. GalINavISC(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Print the actual corrections provided by this object in a * human-readable format. Typically called by dump(). diff --git a/core/lib/NewNav/GalINavIono.hpp b/core/lib/NewNav/GalINavIono.hpp index 5a00f167a..a8af25477 100644 --- a/core/lib/NewNav/GalINavIono.hpp +++ b/core/lib/NewNav/GalINavIono.hpp @@ -52,6 +52,9 @@ namespace gnsstk public: /// Sets the nav message type. GalINavIono(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/GalINavTimeOffset.hpp b/core/lib/NewNav/GalINavTimeOffset.hpp index 89b833353..b709b34e1 100644 --- a/core/lib/NewNav/GalINavTimeOffset.hpp +++ b/core/lib/NewNav/GalINavTimeOffset.hpp @@ -55,6 +55,9 @@ namespace gnsstk public: /// Initialize all data to 0. GalINavTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. diff --git a/core/lib/NewNav/NavData.hpp b/core/lib/NewNav/NavData.hpp index b37df22e1..d57090fef 100644 --- a/core/lib/NewNav/NavData.hpp +++ b/core/lib/NewNav/NavData.hpp @@ -92,6 +92,8 @@ namespace gnsstk GNSSTK_EXPORT static const std::string dumpTimeFmtBrief; /// Initialize internal data fields. NavData(); + /// Create a deep copy of this object, whatever it truly is. + virtual NavDataPtr clone() const = 0; /** Checks the contents of this message against known * validity rules as defined in the appropriate ICD. * @return true if this message is valid according to ICD criteria. diff --git a/core/lib/NewNav/OrbitDataSP3.hpp b/core/lib/NewNav/OrbitDataSP3.hpp index b5f7f7e4d..ace101604 100644 --- a/core/lib/NewNav/OrbitDataSP3.hpp +++ b/core/lib/NewNav/OrbitDataSP3.hpp @@ -53,6 +53,9 @@ namespace gnsstk public: /// Set the vector sizes and initialize everything to 0. OrbitDataSP3(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Copy only the position, velocity and acceleration data. * @param[in] right The OrbitDataSP3 to copy XV data from. diff --git a/core/lib/NewNav/RinexTimeOffset.hpp b/core/lib/NewNav/RinexTimeOffset.hpp index 4dc69803d..09b87f55a 100644 --- a/core/lib/NewNav/RinexTimeOffset.hpp +++ b/core/lib/NewNav/RinexTimeOffset.hpp @@ -54,6 +54,9 @@ namespace gnsstk public: /// Initialize all data to 0. RinexTimeOffset(); + /// Create a deep copy of this object. + NavDataPtr clone() const override + { return std::make_shared(*this); } /** Construct from a pre-existing TimeSystemCorrection object * and leap seconds. diff --git a/core/tests/NewNav/BDSD1NavData_T.cpp b/core/tests/NewNav/BDSD1NavData_T.cpp index a5b236ed0..b96954e6a 100644 --- a/core/tests/NewNav/BDSD1NavData_T.cpp +++ b/core/tests/NewNav/BDSD1NavData_T.cpp @@ -45,6 +45,8 @@ class TestClass : public gnsstk::BDSD1NavData public: gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::BEGINNING_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/BDSD2NavData_T.cpp b/core/tests/NewNav/BDSD2NavData_T.cpp index 33d4d5860..b383a554d 100644 --- a/core/tests/NewNav/BDSD2NavData_T.cpp +++ b/core/tests/NewNav/BDSD2NavData_T.cpp @@ -45,6 +45,8 @@ class TestClass : public gnsstk::BDSD2NavData public: gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::BEGINNING_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/GLOFNavData_T.cpp b/core/tests/NewNav/GLOFNavData_T.cpp index 4c3fb8779..93aa9d0b2 100644 --- a/core/tests/NewNav/GLOFNavData_T.cpp +++ b/core/tests/NewNav/GLOFNavData_T.cpp @@ -63,6 +63,8 @@ class TestClass : public gnsstk::GLOFNavData bool getXvt(const gnsstk::CommonTime& t, gnsstk::Xvt& xvt, const gnsstk::ObsID& oid = gnsstk::ObsID()) override { return false; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/GPSCNavData_T.cpp b/core/tests/NewNav/GPSCNavData_T.cpp index f81a16edc..e122caf64 100644 --- a/core/tests/NewNav/GPSCNavData_T.cpp +++ b/core/tests/NewNav/GPSCNavData_T.cpp @@ -45,6 +45,8 @@ class TestClass : public gnsstk::GPSCNavData public: gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::BEGINNING_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/GPSLNavData_T.cpp b/core/tests/NewNav/GPSLNavData_T.cpp index c24a4f242..f5ff5a7b7 100644 --- a/core/tests/NewNav/GPSLNavData_T.cpp +++ b/core/tests/NewNav/GPSLNavData_T.cpp @@ -45,6 +45,8 @@ class TestClass : public gnsstk::GPSLNavData public: gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::BEGINNING_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/InterSigCorr_T.cpp b/core/tests/NewNav/InterSigCorr_T.cpp index 5998290f2..ee4b55407 100644 --- a/core/tests/NewNav/InterSigCorr_T.cpp +++ b/core/tests/NewNav/InterSigCorr_T.cpp @@ -63,6 +63,8 @@ class TestClass : public gnsstk::InterSigCorr { return validOids.empty(); } bool validate() const override { return true; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/KlobucharIonoNavData_T.cpp b/core/tests/NewNav/KlobucharIonoNavData_T.cpp index 11e087d9c..9a74d35d2 100644 --- a/core/tests/NewNav/KlobucharIonoNavData_T.cpp +++ b/core/tests/NewNav/KlobucharIonoNavData_T.cpp @@ -50,6 +50,15 @@ namespace gnsstk } } +/// non-abstract class under test +class TestClass : public gnsstk::KlobucharIonoNavData +{ +public: + TestClass() = default; + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } +}; + class KlobucharIonoNavData_T { public: @@ -64,7 +73,7 @@ unsigned KlobucharIonoNavData_T :: constructorTest() { TUDEF("KlobucharIonoNavData", "KlobucharIonoNavData"); - gnsstk::KlobucharIonoNavData uut; + TestClass uut; TUASSERTE(gnsstk::NavMessageType, gnsstk::NavMessageType::Iono, uut.signal.messageType); TUASSERTFE(0.0, uut.alpha[0]); @@ -83,7 +92,7 @@ unsigned KlobucharIonoNavData_T :: getIonoCorrTest() { TUDEF("KlobucharIonoNavData", "getIonoCorr"); - gnsstk::KlobucharIonoNavData uut; + TestClass uut; gnsstk::CommonTime when = gnsstk::GPSWeekSecond(2100,135.0); gnsstk::Position rx, sv; rx.setECEF(-1575232.0141,-4707872.2332, 3993198.4383); @@ -108,7 +117,7 @@ unsigned KlobucharIonoNavData_T :: rolloverTest() { TUDEF("KlobucharIonoNavData", "getIonoCorr(day rollover)"); - gnsstk::KlobucharIonoNavData uut; + TestClass uut; gnsstk::CommonTime when = gnsstk::CivilTime(2020, 10, 1, 23, 30, 0.0); gnsstk::Position rx, sv; rx.setECEF(-740290.055522, -5457071.691343, 3207245.635068); diff --git a/core/tests/NewNav/NavDataFactoryWithStore_T.cpp b/core/tests/NewNav/NavDataFactoryWithStore_T.cpp index 39e5014e2..a5ecd2f11 100644 --- a/core/tests/NewNav/NavDataFactoryWithStore_T.cpp +++ b/core/tests/NewNav/NavDataFactoryWithStore_T.cpp @@ -89,6 +89,9 @@ class FakeODK : public gnsstk::OrbitDataKepler public: FakeODK() {} + /// Create a deep copy of this object. + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } bool validate() const override { return true; } bool getXvt(const gnsstk::CommonTime& when, gnsstk::Xvt& xvt, diff --git a/core/tests/NewNav/NavHealthData_T.cpp b/core/tests/NewNav/NavHealthData_T.cpp index dd2bb5757..7d721be09 100644 --- a/core/tests/NewNav/NavHealthData_T.cpp +++ b/core/tests/NewNav/NavHealthData_T.cpp @@ -50,6 +50,8 @@ class TestClass : public gnsstk::NavHealthData { return false; } gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::END_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; diff --git a/core/tests/NewNav/NeQuickIonoNavData_T.cpp b/core/tests/NewNav/NeQuickIonoNavData_T.cpp index e333b38aa..d11be1fb4 100644 --- a/core/tests/NewNav/NeQuickIonoNavData_T.cpp +++ b/core/tests/NewNav/NeQuickIonoNavData_T.cpp @@ -60,6 +60,15 @@ gnsstk::CivilTime convertTime(double hour, int month) /// Use this "ellipsoid" (sphere) for all testing gnsstk::GalileoIonoEllipsoid galEll; +/// non-abstract class under test +class TestClass : public gnsstk::NeQuickIonoNavData +{ +public: + TestClass() = default; + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } +}; + class NeQuickIonoNavData_T { public: @@ -667,7 +676,7 @@ unsigned NeQuickIonoNavData_T :: constructorTest() { TUDEF("NeQuickIonoNavData", "NeQuickIonoNavData()"); - gnsstk::NeQuickIonoNavData uut; + TestClass uut; TUASSERTFE(0.0, uut.ai[0]); TUASSERTFE(0.0, uut.ai[1]); TUASSERTFE(0.0, uut.ai[2]); @@ -685,7 +694,7 @@ getEffIonoLevelTest() { TUDEF("NeQuickIonoNavData", "getEffIonoLevel"); unsigned numTests = sizeof(testDataAz)/sizeof(testDataAz[0]); - gnsstk::NeQuickIonoNavData uut; + TestClass uut; for (unsigned testNum = 0; testNum < numTests; testNum++) { const TestDataAz& td(testDataAz[testNum]); @@ -848,7 +857,7 @@ getTECTest() using namespace std; TUDEF("NeQuickIonoNavData::ModelParameters", "getTEC"); unsigned numTests = sizeof(testDataTEC)/sizeof(testDataTEC[0]); - gnsstk::NeQuickIonoNavData uut; + TestClass uut; /// E layer maximum density height in km. constexpr double hmE = 120.0; //eq.78 for (unsigned testNum = 0; testNum < numTests; testNum++) @@ -889,7 +898,7 @@ getIonoCorrTest() using namespace std; TUDEF("NeQuickIonoNavData::ModelParameters", "getIonoCorr"); unsigned numTests = sizeof(testDataTEC)/sizeof(testDataTEC[0]); - gnsstk::NeQuickIonoNavData uut; + TestClass uut; /// E layer maximum density height in km. constexpr double hmE = 120.0; //eq.78 gnsstk::CarrierBand band; diff --git a/core/tests/NewNav/OrbitDataKepler_T.cpp b/core/tests/NewNav/OrbitDataKepler_T.cpp index dfa61b58e..a16e35ade 100644 --- a/core/tests/NewNav/OrbitDataKepler_T.cpp +++ b/core/tests/NewNav/OrbitDataKepler_T.cpp @@ -60,6 +60,8 @@ class TestClass : public gnsstk::OrbitDataKepler { return true; } gnsstk::CommonTime getUserTime() const override { return gnsstk::CommonTime::BEGINNING_OF_TIME; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } bool getXvt(const gnsstk::CommonTime& when, gnsstk::Xvt& xvt, const gnsstk::ObsID& oid = gnsstk::ObsID()) override { GNSSTK_THROW(gnsstk::Exception("Not implemented")); } diff --git a/core/tests/NewNav/StdNavTimeOffset_T.cpp b/core/tests/NewNav/StdNavTimeOffset_T.cpp index 6d8f09a3b..e0aa9e53e 100644 --- a/core/tests/NewNav/StdNavTimeOffset_T.cpp +++ b/core/tests/NewNav/StdNavTimeOffset_T.cpp @@ -57,6 +57,8 @@ class TestClass : public gnsstk::StdNavTimeOffset public: bool validate() const override { return true; } + gnsstk::NavDataPtr clone() const override + { return std::make_shared(*this); } }; class StdNavTimeOffset_T From bb2e17aea176029ba49925df312a54cb99ea8484 Mon Sep 17 00:00:00 2001 From: Dan Wright Date: Tue, 15 Nov 2022 16:50:49 -0600 Subject: [PATCH 02/16] Ci clean build --- build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build.sh b/build.sh index 9b4cda771..b4db18cac 100755 --- a/build.sh +++ b/build.sh @@ -169,8 +169,20 @@ if [ -f "$LOG" ]; then fi if [ $clean ]; then + + case `uname` in + Linux) + echo "Uninstalling using install_manifest.txt if it exists..." + find $build_root -name "install_manifest.txt" -exec cat {} \; | xargs rm -fv + ;; + *) + echo "Not running make uninstall on non-Linux systems" + ;; + esac + rm -rf "$build_root"/* log "Cleaned out $build_root ..." + fi if ((verbose>0)); then From ceac0ed2934b6bfbea79e7e2f34ab1609fc672bd Mon Sep 17 00:00:00 2001 From: Dan Wright Date: Tue, 22 Nov 2022 09:51:01 -0600 Subject: [PATCH 03/16] Deprecated debian 9 --- .gitlab-ci.yml | 123 ++----------------------------------------------- 1 file changed, 4 insertions(+), 119 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ec2d543d4..a23d5ba91 100755 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -108,7 +108,7 @@ static_analysis: extends: .normal_build tags: - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild + image: $DOCKER_REGISTRY/sgl/debian-10:pkgbuild script: - ./lint_test.sh # Allow failures here to prevent blocking the rest of the pipeline. @@ -195,7 +195,7 @@ generate_documentation: extends: .normal_build tags: - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild + image: $DOCKER_REGISTRY/sgl/debian-10:pkgbuild script: # Install GraphViz - sudo apt-get install -y graphviz @@ -208,24 +208,6 @@ generate_documentation: - docs/ expire_in: 4 days -build_debian_9: - stage: build - needs: [] - extends: .normal_build - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - mkdir -p build - - cd build - - export gnsstk=`pwd`/install - - cmake -DPYTHON_INSTALL_PREFIX=$gnsstk -DCMAKE_INSTALL_PREFIX=install $CMAKE_ARG_DEFAULT - - make all -j 4 - artifacts: - paths: - - build/ - expire_in: 4 days - build_debian_10: stage: build needs: [] @@ -535,26 +517,6 @@ build_windows_vs2019: # Test Stage # Runs all tests of GNSSTK for each platform -test_debian_9: - stage: test - needs: [build_debian_9] - extends: .normal_build - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - cd build - - ctest -j 4 - - touch $CI_PROJECT_DIR/success - artifacts: - when: on_failure - paths: - - build/Testing/Temporary/ - - build/swig/ - expire_in: 4 days - dependencies: - - build_debian_9 - test_debian_10: stage: test needs: [build_debian_10] @@ -786,25 +748,6 @@ test_windows_vs2019_dll: # User_Install Stage # Tests user install of Gnsstk on each platform, saves artifacts for downstream builds. -user_install_debian_9: - stage: install - needs: [build_debian_9] - extends: .big_build - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - cd build - - export gnsstk=`pwd`/install - - cmake -DPYTHON_INSTALL_PREFIX=$gnsstk -DCMAKE_INSTALL_PREFIX=$gnsstk -DPYTHON_USER_INSTALL=ON ../ - - make install -j 4 - artifacts: - paths: - - build/install - expire_in: 4 days - dependencies: - - build_debian_9 - user_install_debian_10: stage: install needs: [build_debian_10] @@ -972,21 +915,6 @@ user_install_windows_vs2019_dll: # System Stage # Tests install of Gnsstk on each platform, saves artifacts for downstream builds. -system_install_debian_9: - stage: install - needs: [build_debian_9] - extends: .big_build - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - cd build - - export gnsstk=/usr/local - - cmake -DPYTHON_INSTALL_PREFIX=$gnsstk -DCMAKE_INSTALL_PREFIX=$gnsstk ../ - - sudo make install -j 4 - dependencies: - - build_debian_9 - system_install_redhat_8: stage: install needs: [build_redhat_8] @@ -1004,32 +932,6 @@ system_install_redhat_8: # Package Stage # Tests packaging of Gnsstk on all platforms - -package_debian_9: - stage: package - needs: [] - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - rm -rf ../*.deb .gitmodules - # Mark the debian log so that this package is a backport. - # Use the most recent Maintainer as current maintainer. - - export DEBEMAIL=$(dpkg-parsechangelog -S Maintainer) - - dch --bpo "No Changes" - - dpkg-buildpackage --build-profiles=pkg_python,debug_package -us -uc -d --changes-option="-DDistribution=stretch-sgl" - - mkdir debs - - mv ../*.deb debs - - mv ../*.changes debs - - mv ../*.dsc debs - - mv ../*.git ../*.gitshallow debs - - mv ../*.buildinfo debs - artifacts: - paths: - - debs/ - dependencies: - - build_debian_9 - package_debian_10: stage: package needs: [] @@ -1225,22 +1127,6 @@ package_windows_vs2019_dll: # Deploy Stage # Tests install of Gnsstk package on each platform, saves artifacts for downstream builds. - -deploy_debian_9: - stage: deploy - needs: [package_debian_9] - extends: .big_build - tags: - - docker-executor - image: $DOCKER_REGISTRY/sgl/debian-9:pkgbuild - script: - - cd debs - - sudo apt-get -y install ./*.deb - - python3 -c "import gnsstk" - - df_diff -h - dependencies: - - package_debian_9 - deploy_debian_10: stage: deploy needs: [package_debian_10] @@ -1308,9 +1194,8 @@ deploy_redhat_py36: push_artifacts: extends: .push_selected_artifacts variables: - DEB_9_PACKAGES: "debs/*bpo9*.deb" DEB_10_PACKAGES: "debs/*bpo10*.deb" DEB_11_PACKAGES: "debs/*bpo11*.deb" stage: push - needs: [package_conda, package_debian_9, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] - dependencies: [package_conda, package_debian_9, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] \ No newline at end of file + needs: [package_conda, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] + dependencies: [package_conda, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] \ No newline at end of file From 1323e215eee19340a4bc93bba44074bb53b3aaaa Mon Sep 17 00:00:00 2001 From: John Knutson Date: Mon, 28 Nov 2022 12:22:56 -0600 Subject: [PATCH 04/16] Update SWIG cmake rules now that we're no longer supporting cmake version 2 --- swig/CMakeLists.txt | 97 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/swig/CMakeLists.txt b/swig/CMakeLists.txt index 9b09a80b4..13dbb8d8f 100644 --- a/swig/CMakeLists.txt +++ b/swig/CMakeLists.txt @@ -3,6 +3,14 @@ #---------------------------------------- cmake_minimum_required( VERSION 3.7.2 ) +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + # UseSWIG target_name_policy + cmake_policy(SET CMP0078 OLD) +endif() +if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14.0") + # UseSWIG module_name_policy + cmake_policy(SET CMP0086 NEW) +endif() include( make_copy_targets.cmake ) find_package( SWIG REQUIRED ) @@ -94,119 +102,170 @@ set( CLOCKMODEL_MODULE "ClockModel" ) set(SWIG_MODULE_${CLOCKMODEL_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(ClockModel/ClockModel.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${CLOCKMODEL_MODULE} python ClockModel/ClockModel.i ) +swig_add_library( ${CLOCKMODEL_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES ClockModel/ClockModel.i ) swig_link_libraries( ${CLOCKMODEL_MODULE} gnsstk ) set( CODEGEN_MODULE "CodeGen" ) set(SWIG_MODULE_${CODEGEN_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(CodeGen/CodeGen.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${CODEGEN_MODULE} python CodeGen/CodeGen.i ) +swig_add_library( ${CODEGEN_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES CodeGen/CodeGen.i ) swig_link_libraries( ${CODEGEN_MODULE} gnsstk ) set( FILEDIRPROC_MODULE "FileDirProc" ) set(SWIG_MODULE_${FILEDIRPROC_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(FileDirProc/FileDirProc.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${FILEDIRPROC_MODULE} python FileDirProc/FileDirProc.i ) +swig_add_library( ${FILEDIRPROC_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES FileDirProc/FileDirProc.i ) swig_link_libraries( ${FILEDIRPROC_MODULE} gnsstk ) set( FILEHANDLING_MODULE "FileHandling" ) set(SWIG_MODULE_${FILEHANDLING_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(FileHandling/FileHandling.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${FILEHANDLING_MODULE} python FileHandling/FileHandling.i ) +swig_add_library( ${FILEHANDLING_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES FileHandling/FileHandling.i ) swig_link_libraries( ${FILEHANDLING_MODULE} gnsstk ) set( GEOMATICS_MODULE "Geomatics" ) set(SWIG_MODULE_${GEOMATICS_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(Geomatics/Geomatics.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${GEOMATICS_MODULE} python Geomatics/Geomatics.i ) +swig_add_library( ${GEOMATICS_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES Geomatics/Geomatics.i ) swig_link_libraries( ${GEOMATICS_MODULE} gnsstk ) set( GNSSCORE_MODULE "GNSSCore" ) set(SWIG_MODULE_${GNSSCORE_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(GNSSCore/GNSSCore.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${GNSSCORE_MODULE} python GNSSCore/GNSSCore.i ) +swig_add_library( ${GNSSCORE_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES GNSSCore/GNSSCore.i ) swig_link_libraries( ${GNSSCORE_MODULE} gnsstk ) set( GNSSEPH_MODULE "GNSSEph" ) set(SWIG_MODULE_${GNSSEPH_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(GNSSEph/GNSSEph.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${GNSSEPH_MODULE} python GNSSEph/GNSSEph.i ) +swig_add_library( ${GNSSEPH_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES GNSSEph/GNSSEph.i ) swig_link_libraries( ${GNSSEPH_MODULE} gnsstk ) set( MATH_MODULE "Math" ) set(SWIG_MODULE_${MATH_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(Math/Math.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${MATH_MODULE} python Math/Math.i ) +swig_add_library( ${MATH_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES Math/Math.i ) swig_link_libraries( ${MATH_MODULE} gnsstk ) set( NAVFILTER_MODULE "NavFilter" ) set(SWIG_MODULE_${NAVFILTER_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(NavFilter/NavFilter.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${NAVFILTER_MODULE} python NavFilter/NavFilter.i ) +swig_add_library( ${NAVFILTER_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES NavFilter/NavFilter.i ) swig_link_libraries( ${NAVFILTER_MODULE} gnsstk ) set( NEWNAV_MODULE "NewNav" ) set(SWIG_MODULE_${NEWNAV_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(NewNav/NewNav.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${NEWNAV_MODULE} python NewNav/NewNav.i ) +swig_add_library( ${NEWNAV_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES NewNav/NewNav.i ) swig_link_libraries( ${NEWNAV_MODULE} gnsstk ) set( ORD_MODULE "ORD" ) set(SWIG_MODULE_${ORD_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(ORD/ORD.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${ORD_MODULE} python ORD/ORD.i ) +swig_add_library( ${ORD_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES ORD/ORD.i ) swig_link_libraries( ${ORD_MODULE} gnsstk ) set( POSSOL_MODULE "PosSol" ) set(SWIG_MODULE_${POSSOL_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(PosSol/PosSol.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${POSSOL_MODULE} python PosSol/PosSol.i ) +swig_add_library( ${POSSOL_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES PosSol/PosSol.i ) swig_link_libraries( ${POSSOL_MODULE} gnsstk ) set( REFTIME_MODULE "RefTime" ) set(SWIG_MODULE_${REFTIME_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(RefTime/RefTime.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${REFTIME_MODULE} python RefTime/RefTime.i ) +swig_add_library( ${REFTIME_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES RefTime/RefTime.i ) swig_link_libraries( ${REFTIME_MODULE} gnsstk ) set( RXIO_MODULE "Rxio" ) set(SWIG_MODULE_${RXIO_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(Rxio/Rxio.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${RXIO_MODULE} python Rxio/Rxio.i ) +swig_add_library( ${RXIO_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES Rxio/Rxio.i ) swig_link_libraries( ${RXIO_MODULE} gnsstk ) set( TIMEHANDLING_MODULE "TimeHandling" ) set(SWIG_MODULE_${TIMEHANDLING_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(TimeHandling/TimeHandling.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${TIMEHANDLING_MODULE} python TimeHandling/TimeHandling.i ) +swig_add_library( ${TIMEHANDLING_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES TimeHandling/TimeHandling.i ) swig_link_libraries( ${TIMEHANDLING_MODULE} gnsstk ) set( UTILITIES_MODULE "Utilities" ) set(SWIG_MODULE_${UTILITIES_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(Utilities/Utilities.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${UTILITIES_MODULE} python Utilities/Utilities.i ) +swig_add_library( ${UTILITIES_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES Utilities/Utilities.i ) swig_link_libraries( ${UTILITIES_MODULE} gnsstk ) set( SWIG_MODULE "gnsstk" ) set(SWIG_MODULE_${SWIG_MODULE}_EXTRA_FLAGS ${TK_EXTRA_FLAGS}) set_source_files_properties(gnsstk.i PROPERTIES CPLUSPLUS ON USE_SWIG_DEPENDENCIES TRUE) -swig_add_module( ${SWIG_MODULE} python gnsstk.i ) +swig_add_library( ${SWIG_MODULE} + TYPE MODULE + LANGUAGE python + SOURCES gnsstk.i ) swig_link_libraries( ${SWIG_MODULE} gnsstk ) # Install the gnsstk module into the package file tree @@ -226,7 +285,7 @@ set( CMAKE_SWIG_OUTDIR ${MODULE_PATH}/${SWIG_MODULE} ) #---------------------------------------- add_custom_target(swig-make-directory ALL COMMAND ${CMAKE_COMMAND} -E make_directory ${MODULE_PATH}/gnsstk) -add_dependencies("_${SWIG_MODULE}" swig-make-directory) +add_dependencies("${SWIG_MODULE}" swig-make-directory) add_custom_command( TARGET "_${CLOCKMODEL_MODULE}" POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "$" ${CMAKE_SWIG_OUTDIR} ) add_custom_command( TARGET "_${CLOCKMODEL_MODULE}" POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CLOCKMODEL_MODULE}.py" ${CMAKE_SWIG_OUTDIR} ) @@ -345,7 +404,7 @@ if( PIP_WHEEL_SWITCH ) add_custom_target(swig-make-wheel ALL COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} bdist_wheel WORKING_DIRECTORY ${MODULE_PATH} - DEPENDS "_${SWIG_MODULE}") + DEPENDS "${SWIG_MODULE}") endif() From a4e7670fdc7a73298d21e74e5a2d1c6e40da845a Mon Sep 17 00:00:00 2001 From: John Knutson Date: Tue, 29 Nov 2022 13:54:31 -0600 Subject: [PATCH 05/16] Add signal details to nav dump methods --- core/lib/NewNav/BDSD1NavEph.cpp | 3 +- core/lib/NewNav/BDSD1NavHealth.cpp | 13 +++---- core/lib/NewNav/BDSD2NavEph.cpp | 3 +- core/lib/NewNav/BDSD2NavHealth.cpp | 13 +++---- core/lib/NewNav/GLOFNavAlm.cpp | 6 ++-- core/lib/NewNav/GLOFNavEph.cpp | 6 ++-- core/lib/NewNav/GLOFNavHealth.cpp | 13 +++---- core/lib/NewNav/GLOFNavUT1TimeOffset.cpp | 15 +++------ core/lib/NewNav/GPSCNav2Health.cpp | 40 +++++++++++++++++++--- core/lib/NewNav/GPSCNavHealth.cpp | 13 +++---- core/lib/NewNav/GPSLNavHealth.cpp | 13 +++---- core/lib/NewNav/GalFNavEph.cpp | 2 ++ core/lib/NewNav/GalFNavHealth.cpp | 13 +++---- core/lib/NewNav/GalINavHealth.cpp | 13 +++---- core/lib/NewNav/InterSigCorr.cpp | 13 +++---- core/lib/NewNav/KlobucharIonoNavData.cpp | 12 ++----- core/lib/NewNav/NavData.cpp | 41 +++++++++++++++++++++++ core/lib/NewNav/NavData.hpp | 3 ++ core/lib/NewNav/NeQuickIonoNavData.cpp | 12 ++----- core/lib/NewNav/OrbitDataKepler.cpp | 20 +---------- core/lib/NewNav/PNBGalFNavDataFactory.cpp | 5 +-- core/lib/NewNav/PNBGalINavDataFactory.cpp | 7 ++-- core/lib/NewNav/StdNavTimeOffset.cpp | 14 +++----- data | 2 +- 24 files changed, 147 insertions(+), 148 deletions(-) diff --git a/core/lib/NewNav/BDSD1NavEph.cpp b/core/lib/NewNav/BDSD1NavEph.cpp index c1786b100..f8220c24b 100644 --- a/core/lib/NewNav/BDSD1NavEph.cpp +++ b/core/lib/NewNav/BDSD1NavEph.cpp @@ -119,7 +119,8 @@ namespace gnsstk << "URA index : " << setw(6) << (unsigned)uraIndex << endl << "URA (nominal) : " << setw(6) << fixed << SV_ACCURACY_GPS_NOMINAL_INDEX[uraIndex] << " m" << endl - << endl + << "Health : " << setw(9) + << gnsstk::StringUtils::asString(health) << endl << "Tgd1 : " << setw(13) << setprecision(6) << scientific << tgd1 << " sec" << endl << "Tgd2 : " << setw(13) << setprecision(6) diff --git a/core/lib/NewNav/BDSD1NavHealth.cpp b/core/lib/NewNav/BDSD1NavHealth.cpp index 5d9e415ee..091739bbf 100644 --- a/core/lib/NewNav/BDSD1NavHealth.cpp +++ b/core/lib/NewNav/BDSD1NavHealth.cpp @@ -103,15 +103,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/BDSD2NavEph.cpp b/core/lib/NewNav/BDSD2NavEph.cpp index 0e314a3fc..b860a8b8e 100644 --- a/core/lib/NewNav/BDSD2NavEph.cpp +++ b/core/lib/NewNav/BDSD2NavEph.cpp @@ -351,7 +351,8 @@ namespace gnsstk << "URA index : " << setw(6) << (unsigned)uraIndex << endl << "URA (nominal) : " << setw(6) << fixed << SV_ACCURACY_GPS_NOMINAL_INDEX[uraIndex] << " m" << endl - << endl + << "Health : " << setw(9) + << gnsstk::StringUtils::asString(health) << endl << "Tgd1 : " << setw(13) << setprecision(6) << scientific << tgd1 << " sec" << endl << "Tgd2 : " << setw(13) << setprecision(6) diff --git a/core/lib/NewNav/BDSD2NavHealth.cpp b/core/lib/NewNav/BDSD2NavHealth.cpp index 2ffa913fc..ef43b602e 100644 --- a/core/lib/NewNav/BDSD2NavHealth.cpp +++ b/core/lib/NewNav/BDSD2NavHealth.cpp @@ -103,15 +103,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/GLOFNavAlm.cpp b/core/lib/NewNav/GLOFNavAlm.cpp index 69db2c149..b8080a362 100644 --- a/core/lib/NewNav/GLOFNavAlm.cpp +++ b/core/lib/NewNav/GLOFNavAlm.cpp @@ -133,8 +133,10 @@ namespace gnsstk s << "**************************************************************" << endl - << " GLONASS ORB/CLK (NON-IMMEDIATE) PARAMETERS for GLONASS Slot " - << signal.sat.id << endl; + << " GLONASS ORB/CLK (NON-IMMEDIATE) PARAMETERS" + << endl + << endl + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) diff --git a/core/lib/NewNav/GLOFNavEph.cpp b/core/lib/NewNav/GLOFNavEph.cpp index 9152b3e4b..6064642b7 100644 --- a/core/lib/NewNav/GLOFNavEph.cpp +++ b/core/lib/NewNav/GLOFNavEph.cpp @@ -210,8 +210,10 @@ namespace gnsstk s << "****************************************************************" << "************" << endl - << "GLONASS ORB/CLK (IMMEDIATE) PARAMETERS" << endl << endl - << "SAT : " << signal.sat << endl << endl; + << "GLONASS ORB/CLK (IMMEDIATE) PARAMETERS" + << endl + << endl + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) diff --git a/core/lib/NewNav/GLOFNavHealth.cpp b/core/lib/NewNav/GLOFNavHealth.cpp index 4ec8b9175..af16ed78f 100644 --- a/core/lib/NewNav/GLOFNavHealth.cpp +++ b/core/lib/NewNav/GLOFNavHealth.cpp @@ -91,15 +91,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/GLOFNavUT1TimeOffset.cpp b/core/lib/NewNav/GLOFNavUT1TimeOffset.cpp index 44474a481..0409ce05a 100644 --- a/core/lib/NewNav/GLOFNavUT1TimeOffset.cpp +++ b/core/lib/NewNav/GLOFNavUT1TimeOffset.cpp @@ -81,16 +81,11 @@ namespace gnsstk } s << "****************************************************************" << "************" << endl - << "Time System Offset" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - - s << endl << endl + << "Time System Offset" + << endl + << endl + << getSignalString() << endl + << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl << "Transmit: " << getDumpTime(dl, timeStamp) diff --git a/core/lib/NewNav/GPSCNav2Health.cpp b/core/lib/NewNav/GPSCNav2Health.cpp index 23e1d98b4..1624e219f 100644 --- a/core/lib/NewNav/GPSCNav2Health.cpp +++ b/core/lib/NewNav/GPSCNav2Health.cpp @@ -53,13 +53,43 @@ namespace gnsstk void GPSCNav2Health :: dump(std::ostream& s, DumpDetail dl) const { - NavData::dump(s,dl); - if (dl == DumpDetail::OneLine) + const ios::fmtflags oldFlags = s.flags(); + s.setf(ios::fixed, ios::floatfield); + s.setf(ios::right, ios::adjustfield); + s.setf(ios::uppercase); + s.precision(0); + s.fill(' '); + switch (dl) { - return; + case DumpDetail::OneLine: + NavData::dump(s,dl); + break; + case DumpDetail::Brief: + NavData::dump(s,dl); + s << "health = " << hex << (unsigned)health << dec << " " + << StringUtils::asString(getHealth()) << endl; + break; + case DumpDetail::Full: + // "header" + s << "*************************************************************" + << "***************" << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl + << " TIMES OF INTEREST" + << endl << endl + << " " << getDumpTimeHdr(dl) << endl + << "Transmit: " << getDumpTime(dl, timeStamp) << endl + << endl + << " HEALTH DATA" << endl + << "Bits 0x" << hex << setw(1) << setfill('0') + << (unsigned)health << endl + << "Status " << StringUtils::asString(getHealth()) + << endl; + break; } - s << "health = " << health << " " - << StringUtils::asString(getHealth()) << endl; + s.flags(oldFlags); } diff --git a/core/lib/NewNav/GPSCNavHealth.cpp b/core/lib/NewNav/GPSCNavHealth.cpp index 621e9f2b2..009124881 100644 --- a/core/lib/NewNav/GPSCNavHealth.cpp +++ b/core/lib/NewNav/GPSCNavHealth.cpp @@ -74,15 +74,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/GPSLNavHealth.cpp b/core/lib/NewNav/GPSLNavHealth.cpp index 609d3c35c..e4046d014 100644 --- a/core/lib/NewNav/GPSLNavHealth.cpp +++ b/core/lib/NewNav/GPSLNavHealth.cpp @@ -73,15 +73,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/GalFNavEph.cpp b/core/lib/NewNav/GalFNavEph.cpp index d46907da4..8b167bfa8 100644 --- a/core/lib/NewNav/GalFNavEph.cpp +++ b/core/lib/NewNav/GalFNavEph.cpp @@ -142,6 +142,8 @@ namespace gnsstk << "E5a_HS : " << setw(9) << static_cast(hsE5a) << " (" << gnsstk::StringUtils::asString(hsE5a) << ")" << endl << "SISA : " << setw(9) << (unsigned)sisaIndex << endl + << "Health : " << setw(9) + << gnsstk::StringUtils::asString(health) << endl << setprecision(6) << "Bgd(E1-E5a) : " << setw(13) << bgdE5aE1 << " sec" << endl; s.flags(oldFlags); diff --git a/core/lib/NewNav/GalFNavHealth.cpp b/core/lib/NewNav/GalFNavHealth.cpp index 405733d41..46bc0b250 100644 --- a/core/lib/NewNav/GalFNavHealth.cpp +++ b/core/lib/NewNav/GalFNavHealth.cpp @@ -88,15 +88,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/GalINavHealth.cpp b/core/lib/NewNav/GalINavHealth.cpp index 0fa3495cc..208fda985 100644 --- a/core/lib/NewNav/GalINavHealth.cpp +++ b/core/lib/NewNav/GalINavHealth.cpp @@ -87,15 +87,10 @@ namespace gnsstk // "header" s << "*************************************************************" << "***************" << endl - << "Satellite Health" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl + << "Satellite Health" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl diff --git a/core/lib/NewNav/InterSigCorr.cpp b/core/lib/NewNav/InterSigCorr.cpp index 3d1416ad7..c1ad5f9f0 100644 --- a/core/lib/NewNav/InterSigCorr.cpp +++ b/core/lib/NewNav/InterSigCorr.cpp @@ -65,15 +65,10 @@ namespace gnsstk // "header" s << "****************************************************************" << "************" << endl - << "Inter-signal Corrections" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl; + << "Inter-signal Corrections" + << endl + << endl + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) diff --git a/core/lib/NewNav/KlobucharIonoNavData.cpp b/core/lib/NewNav/KlobucharIonoNavData.cpp index 4cd3eef4a..f0dfd18ef 100644 --- a/core/lib/NewNav/KlobucharIonoNavData.cpp +++ b/core/lib/NewNav/KlobucharIonoNavData.cpp @@ -67,14 +67,7 @@ namespace gnsstk << "Ionospheric correction data" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl; + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) @@ -88,8 +81,7 @@ namespace gnsstk s.precision(0); s.fill(' '); - s << endl - << " TIMES OF INTEREST" + s << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl << "Transmit: " << getDumpTime(dl, timeStamp) << endl; diff --git a/core/lib/NewNav/NavData.cpp b/core/lib/NewNav/NavData.cpp index dcfb3f41b..f69d16f46 100644 --- a/core/lib/NewNav/NavData.cpp +++ b/core/lib/NewNav/NavData.cpp @@ -82,6 +82,47 @@ namespace gnsstk } + std::string NavData :: + getSignalString() const + { + using namespace std; + ostringstream s; + s << "PRN : " << setw(2) << signal.sat;; + string svn; + if (getSVN(signal.sat, timeStamp, svn)) + { + s << " / " << "SVN : " << setw(2) << svn; + } + if (signal.messageType == NavMessageType::Almanac) + { + // for almanacs, print the transmitting satellite as well. + s << endl + << "XMIT: " << setw(2) << signal.xmitSat; + if (getSVN(signal.xmitSat, timeStamp, svn)) + { + s << " / " << "SVN : " << setw(2) << svn; + } + } + s << endl; + // All the obs data is derived from the transmitting + // satellite so it makes sense to list it underneath the XMIT + // tag. + if (!signal.obs.freqOffsWild) + { + s << "FREQ: " << signal.obs.freqOffs << endl; + } + s << "CODE: " << gnsstk::StringUtils::asString(signal.nav) + << " " << gnsstk::StringUtils::asString(signal.obs.band) + << " " << gnsstk::StringUtils::asString(signal.obs.code) << endl; + if (signal.obs.xmitAnt != gnsstk::XmitAnt::Any) + { + s << "ANT : " << gnsstk::StringUtils::asString(signal.obs.xmitAnt) + << endl; + } + return s.str(); + } + + std::string NavData :: getDumpTimeHdr(DumpDetail dl) const { diff --git a/core/lib/NewNav/NavData.hpp b/core/lib/NewNav/NavData.hpp index d57090fef..ed2681a40 100644 --- a/core/lib/NewNav/NavData.hpp +++ b/core/lib/NewNav/NavData.hpp @@ -154,6 +154,9 @@ namespace gnsstk return ((satMetaDataStore != nullptr) && satMetaDataStore->getSVN(sat,when,svn)); } + /** Return lines of text containing the sufficient + * specification of the current nav message signal. */ + std::string getSignalString() const; /** Return an appropriate header label for the time format in dump(). * @param[in] dl The detail level for the time string to be dumped. * @return A string labeling the columns of the time format diff --git a/core/lib/NewNav/NeQuickIonoNavData.cpp b/core/lib/NewNav/NeQuickIonoNavData.cpp index 3536217a7..0b3849420 100644 --- a/core/lib/NewNav/NeQuickIonoNavData.cpp +++ b/core/lib/NewNav/NeQuickIonoNavData.cpp @@ -139,14 +139,7 @@ namespace gnsstk << "Ionospheric correction data" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - s << endl << endl; + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) @@ -160,8 +153,7 @@ namespace gnsstk s.precision(0); s.fill(' '); - s << endl - << " TIMES OF INTEREST" + s << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl << "Transmit: " << getDumpTime(dl, timeStamp) << endl; diff --git a/core/lib/NewNav/OrbitDataKepler.cpp b/core/lib/NewNav/OrbitDataKepler.cpp index e09287ce5..bda7aaf85 100644 --- a/core/lib/NewNav/OrbitDataKepler.cpp +++ b/core/lib/NewNav/OrbitDataKepler.cpp @@ -76,25 +76,7 @@ namespace gnsstk // - " << getNameLong(); << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - if (signal.messageType == NavMessageType::Almanac) - { - // for almanacs, print the transmitting satellite as well. - s << endl - << "XMIT: " << setw(2) << signal.xmitSat << " / " - << "SVN : " << setw(2); - if (getSVN(signal.xmitSat, timeStamp, svn)) - { - s << svn; - } - } - s << endl << endl; + << getSignalString() << endl; // the rest is full details, so just return if Full is not asked for. if (dl != DumpDetail::Full) diff --git a/core/lib/NewNav/PNBGalFNavDataFactory.cpp b/core/lib/NewNav/PNBGalFNavDataFactory.cpp index f3cea93c5..854702f7c 100644 --- a/core/lib/NewNav/PNBGalFNavDataFactory.cpp +++ b/core/lib/NewNav/PNBGalFNavDataFactory.cpp @@ -121,10 +121,11 @@ namespace gnsstk NavSatelliteID key(navIn->getsatSys().id, navIn->getsatSys(), navIn->getobsID(), navIn->getNavID()); if (!PNBNavDataFactory::processEph && !PNBNavDataFactory::processHea && + !PNBNavDataFactory::processIono && !PNBNavDataFactory::processISC && !PNBNavDataFactory::processTim) { - // User doesn't want ephemerides or health so don't do any - // processing. + // User doesn't want any of the messages we're capable of + // decoding, so don't do any processing. return true; } if (ephAcc.find(key) == ephAcc.end()) diff --git a/core/lib/NewNav/PNBGalINavDataFactory.cpp b/core/lib/NewNav/PNBGalINavDataFactory.cpp index d9281bf97..55bcc86af 100644 --- a/core/lib/NewNav/PNBGalINavDataFactory.cpp +++ b/core/lib/NewNav/PNBGalINavDataFactory.cpp @@ -126,10 +126,11 @@ namespace gnsstk { NavSatelliteID key(navIn->getsatSys().id, navIn->getsatSys(), navIn->getobsID(), navIn->getNavID()); - if (!PNBNavDataFactory::processEph && !PNBNavDataFactory::processHea) + if (!PNBNavDataFactory::processEph && !PNBNavDataFactory::processHea && + !PNBNavDataFactory::processIono && !PNBNavDataFactory::processISC) { - // User doesn't want ephemerides or health so don't do any - // processing. + // User doesn't want any of the messages we're capable of + // decoding, so don't do any processing. return true; } if (ephAcc.find(key) == ephAcc.end()) diff --git a/core/lib/NewNav/StdNavTimeOffset.cpp b/core/lib/NewNav/StdNavTimeOffset.cpp index 48fe874c8..8c128f51e 100644 --- a/core/lib/NewNav/StdNavTimeOffset.cpp +++ b/core/lib/NewNav/StdNavTimeOffset.cpp @@ -113,16 +113,10 @@ namespace gnsstk } s << "****************************************************************" << "************" << endl - << "Time System Offset" << endl << endl - << "PRN : " << setw(2) << signal.sat << " / " - << "SVN : " << setw(2); - std::string svn; - if (getSVN(signal.sat, timeStamp, svn)) - { - s << svn; - } - - s << endl << endl + << "Time System Offset" + << endl + << endl + << getSignalString() << endl << " TIMES OF INTEREST" << endl << endl << " " << getDumpTimeHdr(dl) << endl << "Transmit: " << getDumpTime(dl, timeStamp) diff --git a/data b/data index 2d851ff6a..432a0eb92 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 2d851ff6a036b431aaef2eac3f1be7d0258914a4 +Subproject commit 432a0eb9206bb9e28ea82cb77d0b878006406bfe From 2d83909f978aaaf43b5e3b5b9f89628a8d49f6d5 Mon Sep 17 00:00:00 2001 From: Sarah Magliocca Date: Sun, 4 Dec 2022 20:48:29 -0600 Subject: [PATCH 06/16] Updating the GNSSTk build scripts for visual studio 2019 --- BuildGNSSTkWindows.sh | 2 +- BuildGNSSTkWindowsRelativeInstall.sh | 2 +- README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/BuildGNSSTkWindows.sh b/BuildGNSSTkWindows.sh index 27194ffb9..107e328a7 100755 --- a/BuildGNSSTkWindows.sh +++ b/BuildGNSSTkWindows.sh @@ -1,6 +1,6 @@ # run in projects/gnsstk cd build -cmake -DBUILD_EXT=true -DCMAKE_INSTALL_PREFIX=$HOMEDRIVE$HOMEPATH/.local/gnsstkDiffProc -G"Visual Studio 14 2015 Win64" ../ +cmake -DBUILD_EXT=true -DCMAKE_INSTALL_PREFIX=$HOMEDRIVE$HOMEPATH/.local/gnsstkDiffProc -G"Visual Studio 16 2019" -A x64 ../ cmake --build . --config release --target install cd .. diff --git a/BuildGNSSTkWindowsRelativeInstall.sh b/BuildGNSSTkWindowsRelativeInstall.sh index cb9f07f4a..8f3bf112c 100755 --- a/BuildGNSSTkWindowsRelativeInstall.sh +++ b/BuildGNSSTkWindowsRelativeInstall.sh @@ -1,6 +1,6 @@ # run in projects/gnsstk cd build -cmake -DBUILD_EXT=true -DCMAKE_INSTALL_PREFIX=../install -G"Visual Studio 14 2015 Win64" ../ +cmake -DBUILD_EXT=true -DCMAKE_INSTALL_PREFIX=../install -G"Visual Studio 16 2019" -A x64 ../ cmake --build . --config release --target install cd .. diff --git a/README.md b/README.md index 47c56de28..aca3ed36c 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ To build and install the python bindings, you have two options: Testing: -------- -See the TESTING.txt for details. +See the TESTING.md for details. Help & Docs: From 4681ddaae93902a5f9da0397362e4b0f0a568142 Mon Sep 17 00:00:00 2001 From: John Knutson Date: Tue, 6 Dec 2022 15:01:50 -0600 Subject: [PATCH 07/16] Helmert transform/reference frames refactor --- core/lib/FileHandling/SP3/SP3Data.cpp | 2 +- core/lib/FileHandling/SP3/SP3Header.cpp | 8 + core/lib/GNSSCore/Angle.hpp | 2 +- core/lib/GNSSCore/AngleReduced.hpp | 2 +- core/lib/GNSSCore/AngleType.hpp | 2 +- core/lib/GNSSCore/EllipsoidModel.hpp | 2 +- core/lib/GNSSCore/GNSSconstants.hpp | 8 +- core/lib/GNSSCore/GPSEllipsoid.hpp | 2 +- core/lib/GNSSCore/HelmertTransformer.cpp | 265 +++++++++ core/lib/GNSSCore/HelmertTransformer.hpp | 176 ++++++ core/lib/GNSSCore/PZ90Ellipsoid.hpp | 2 +- core/lib/GNSSCore/Position.cpp | 12 +- core/lib/GNSSCore/Position.hpp | 28 +- core/lib/GNSSCore/RefFrame.cpp | 178 +++++++ core/lib/GNSSCore/RefFrame.hpp | 135 +++++ core/lib/GNSSCore/RefFrameRlz.cpp | 239 +++++++++ core/lib/GNSSCore/RefFrameRlz.hpp | 108 ++++ .../GNSSCore/RefFrameSys.cpp} | 68 ++- core/lib/GNSSCore/RefFrameSys.hpp | 77 +++ core/lib/GNSSCore/TransformLibrary.cpp | 245 +++++++++ core/lib/GNSSCore/TransformLibrary.hpp | 215 ++++++++ core/lib/GNSSCore/Transformer.hpp | 173 ++++++ core/lib/GNSSCore/Xvt.cpp | 2 +- core/lib/GNSSCore/Xvt.hpp | 6 +- core/lib/GNSSEph/BrcKeplerOrbit.cpp | 2 +- core/lib/GNSSEph/GloEphemeris.cpp | 503 ------------------ core/lib/GNSSEph/GloEphemeris.hpp | 271 ---------- core/lib/NewNav/BDSD1NavData.cpp | 2 +- core/lib/NewNav/BDSD2NavData.cpp | 2 +- core/lib/NewNav/BDSD2NavEph.cpp | 3 +- core/lib/NewNav/GLOCNavAlm.hpp | 5 +- core/lib/NewNav/GLOCNavAlmCorrected.hpp | 4 +- core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp | 2 +- core/lib/NewNav/GLOCNavEph.cpp | 4 +- core/lib/NewNav/GLOFNavAlm.cpp | 2 +- core/lib/NewNav/GLOFNavEph.cpp | 4 +- core/lib/NewNav/GalFNavAlm.cpp | 2 +- core/lib/NewNav/GalFNavEph.cpp | 2 +- core/lib/NewNav/GalINavAlm.cpp | 2 +- core/lib/NewNav/GalINavEph.cpp | 2 +- core/lib/NewNav/OrbitDataKepler.cpp | 6 +- core/lib/NewNav/OrbitDataKepler.hpp | 5 +- core/lib/NewNav/OrbitDataSP3.cpp | 2 +- core/lib/NewNav/OrbitDataSP3.hpp | 2 +- core/lib/NewNav/SP3NavDataFactory.cpp | 7 +- core/lib/RefTime/HelmertTransform.cpp | 10 +- core/lib/RefTime/HelmertTransform.hpp | 13 +- core/lib/RefTime/ReferenceFrame.hpp | 4 +- core/tests/GNSSCore/CMakeLists.txt | 28 + core/tests/GNSSCore/HelmertTransformer_T.cpp | 358 +++++++++++++ core/tests/GNSSCore/RefFrameRlz_T.cpp | 204 +++++++ core/tests/GNSSCore/RefFrameSys_T.cpp | 90 ++++ core/tests/GNSSCore/TransformLibrary_T.cpp | 377 +++++++++++++ core/tests/NewNav/BDSD1NavAlm_T.cpp | 3 +- core/tests/NewNav/BDSD1NavEph_T.cpp | 3 +- core/tests/NewNav/BDSD2NavAlm_T.cpp | 3 +- core/tests/NewNav/BDSD2NavEph_T.cpp | 3 +- core/tests/NewNav/GLOCNavAlm_T.cpp | 7 +- core/tests/NewNav/GLOFNavAlm_T.cpp | 3 +- core/tests/NewNav/GLOFNavEph_T.cpp | 5 +- core/tests/NewNav/GPSCNav2Alm_T.cpp | 3 +- core/tests/NewNav/GPSCNav2Eph_T.cpp | 3 +- core/tests/NewNav/GPSCNavAlm_T.cpp | 3 +- core/tests/NewNav/GPSCNavEph_T.cpp | 3 +- core/tests/NewNav/GPSLNavAlm_T.cpp | 3 +- core/tests/NewNav/GPSLNavEph_T.cpp | 3 +- core/tests/NewNav/GalFNavAlm_T.cpp | 3 +- core/tests/NewNav/GalFNavEph_T.cpp | 3 +- core/tests/NewNav/GalINavAlm_T.cpp | 3 +- core/tests/NewNav/GalINavEph_T.cpp | 3 +- core/tests/NewNav/SP3NavDataFactory_T.cpp | 58 +- core/tests/RefTime/HelmertTransform_T.cpp | 35 +- swig/GNSSCore/GNSSCore.i | 30 +- swig/GNSSEph/GNSSEph.i | 2 - swig/NewNav/NewNav.i | 3 + swig/gnsstk_swig.hpp | 7 +- swig/gnsstk_swig.i | 7 +- swig/tests/test_misc.py | 6 +- 78 files changed, 3128 insertions(+), 952 deletions(-) create mode 100644 core/lib/GNSSCore/HelmertTransformer.cpp create mode 100644 core/lib/GNSSCore/HelmertTransformer.hpp create mode 100644 core/lib/GNSSCore/RefFrame.cpp create mode 100644 core/lib/GNSSCore/RefFrame.hpp create mode 100644 core/lib/GNSSCore/RefFrameRlz.cpp create mode 100644 core/lib/GNSSCore/RefFrameRlz.hpp rename core/{tests/RefTime/HelmertTransform_T.hpp => lib/GNSSCore/RefFrameSys.cpp} (63%) create mode 100644 core/lib/GNSSCore/RefFrameSys.hpp create mode 100644 core/lib/GNSSCore/TransformLibrary.cpp create mode 100644 core/lib/GNSSCore/TransformLibrary.hpp create mode 100644 core/lib/GNSSCore/Transformer.hpp delete mode 100644 core/lib/GNSSEph/GloEphemeris.cpp delete mode 100644 core/lib/GNSSEph/GloEphemeris.hpp create mode 100644 core/tests/GNSSCore/HelmertTransformer_T.cpp create mode 100644 core/tests/GNSSCore/RefFrameRlz_T.cpp create mode 100644 core/tests/GNSSCore/RefFrameSys_T.cpp create mode 100644 core/tests/GNSSCore/TransformLibrary_T.cpp diff --git a/core/lib/FileHandling/SP3/SP3Data.cpp b/core/lib/FileHandling/SP3/SP3Data.cpp index 30e0b6ea1..398038ec7 100644 --- a/core/lib/FileHandling/SP3/SP3Data.cpp +++ b/core/lib/FileHandling/SP3/SP3Data.cpp @@ -77,7 +77,7 @@ namespace gnsstk // TimeSystem for this stream TimeSystem timeSystem; - timeSystem = gnsstk::StringUtils::asTimeSystem(strm.header.timeSystemString()); + timeSystem = strm.header.timeSystem; // loop until an error occurs, or until the entire record (which may consist // of two lines) is read. diff --git a/core/lib/FileHandling/SP3/SP3Header.cpp b/core/lib/FileHandling/SP3/SP3Header.cpp index fe03885da..3089f45d1 100644 --- a/core/lib/FileHandling/SP3/SP3Header.cpp +++ b/core/lib/FileHandling/SP3/SP3Header.cpp @@ -237,6 +237,14 @@ namespace gnsstk GNSSTK_THROW(e); } } + else if (version == SP3a) + { + // standard for SP3a says "All times referred to in this + // document are GPS times". + timeSystem = gnsstk::TimeSystem::GPS; + } + // make sure header time is in the right time system + time.setTimeSystem(timeSystem); strm.formattedGetLine(line); lineCount++; diff --git a/core/lib/GNSSCore/Angle.hpp b/core/lib/GNSSCore/Angle.hpp index 03c9d9b15..0db40d2b3 100644 --- a/core/lib/GNSSCore/Angle.hpp +++ b/core/lib/GNSSCore/Angle.hpp @@ -43,7 +43,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ /** Wrap data for an angle, including the angle in degrees, diff --git a/core/lib/GNSSCore/AngleReduced.hpp b/core/lib/GNSSCore/AngleReduced.hpp index 9d8513a0a..b7d0f45ee 100644 --- a/core/lib/GNSSCore/AngleReduced.hpp +++ b/core/lib/GNSSCore/AngleReduced.hpp @@ -47,7 +47,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ /** Wrap data for just the sine and cosine of an angle. diff --git a/core/lib/GNSSCore/AngleType.hpp b/core/lib/GNSSCore/AngleType.hpp index e9741d50d..33c366380 100644 --- a/core/lib/GNSSCore/AngleType.hpp +++ b/core/lib/GNSSCore/AngleType.hpp @@ -44,7 +44,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ /** Because the angle can be initialized via a variety of diff --git a/core/lib/GNSSCore/EllipsoidModel.hpp b/core/lib/GNSSCore/EllipsoidModel.hpp index bfb6f13f3..b4659277a 100644 --- a/core/lib/GNSSCore/EllipsoidModel.hpp +++ b/core/lib/GNSSCore/EllipsoidModel.hpp @@ -46,7 +46,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ /** diff --git a/core/lib/GNSSCore/GNSSconstants.hpp b/core/lib/GNSSCore/GNSSconstants.hpp index 5757d98bd..774f3051d 100644 --- a/core/lib/GNSSCore/GNSSconstants.hpp +++ b/core/lib/GNSSCore/GNSSconstants.hpp @@ -51,7 +51,7 @@ namespace gnsstk { /** - * @ingroup Geodetic + * @ingroup geodeticgroup * @name GNSS Constants * Time constants are in TimeConstants.hpp */ @@ -76,6 +76,12 @@ namespace gnsstk static const double DEG_TO_RAD = 1.7453292519943e-2; /// Conversion Factor from radians to degrees (units: degrees) static const double RAD_TO_DEG = 57.295779513082; + /// degrees per milliarcsecond (1e-3/3600.) + static const double DEG_PER_MAS = 2.77777777777e-7; + /// radians per milliarcsecond + static const double RAD_PER_MAS = 4.84813681e-9; + /// parts per billion + static const double PPB = 1.e-9; // ---------------- GPS -------------------------------------- /// Hz, GPS Oscillator or chip frequency diff --git a/core/lib/GNSSCore/GPSEllipsoid.hpp b/core/lib/GNSSCore/GPSEllipsoid.hpp index d7e13d211..b384664fe 100644 --- a/core/lib/GNSSCore/GPSEllipsoid.hpp +++ b/core/lib/GNSSCore/GPSEllipsoid.hpp @@ -49,7 +49,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ /** diff --git a/core/lib/GNSSCore/HelmertTransformer.cpp b/core/lib/GNSSCore/HelmertTransformer.cpp new file mode 100644 index 000000000..a2e03b71d --- /dev/null +++ b/core/lib/GNSSCore/HelmertTransformer.cpp @@ -0,0 +1,265 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "HelmertTransformer.hpp" + +namespace gnsstk +{ + HelmertTransformer :: + HelmertTransformer() + : scale(std::numeric_limits::quiet_NaN()), + description("Undefined") + { + // rotation, translation and the RefFrame objects we just use + // their default constructors. + } + + + HelmertTransformer :: + HelmertTransformer(const RefFrame& from, const RefFrame& to, + double irx, double iry, double irz, + double itx, double ity, double itz, + double sc, const std::string& desc, + const CommonTime& refEpoch) + : description(desc), + scale(sc) + { + if ((from.getRealization() == RefFrameRlz::Unknown) || + (to.getRealization() == RefFrameRlz::Unknown)) + { + InvalidRequest e("Invalid Helmert transformation with Unknown frame"); + GNSSTK_THROW(e); + } + + fromFrame = from; + toFrame = to; + epoch = refEpoch; + + double rx = irx*DEG_TO_RAD; + double ry = iry*DEG_TO_RAD; + double rz = irz*DEG_TO_RAD; + + // check that rotation angles are small; + // sin x ~ x at 0.244 radians = 13.9 deg + if ((::fabs(rx) > 1.e-3) || (::fabs(ry) > 1.e-3) || (::fabs(rz) > 1.e-3)) + { + InvalidRequest e("Invalid Helmert transformation : " + "small angle approximation."); + GNSSTK_THROW(e); + } + + /** @note small angle approximation is used. */ + /** @note by construction, transpose(rotation) == inverse(rotation) + * (given small angle approximation). */ + rotation = Matrix(3,3,0.0); + rotation(0,0) = 1.0; + rotation(0,1) = -rz; + rotation(0,2) = ry; + + rotation(1,0) = rz; + rotation(1,1) = 1.0; + rotation(1,2) = -rx; + + rotation(2,0) = -ry; + rotation(2,1) = rx; + rotation(2,2) = 1.0; + + // translation vector + translation = Vector(3); + translation(0) = itx; + translation(1) = ity; + translation(2) = itz; + } + + + bool HelmertTransformer :: + transform(const Position& fromPos, Position& toPos) + const noexcept + { + if ((fromPos.getReferenceFrame() == fromFrame) && + (toPos.getReferenceFrame() == toFrame)) + { + // transform + toPos = fromPos; + toPos.transformTo(Position::Cartesian); + Vector vec(3),res(3); + vec(0) = toPos[0]; + vec(1) = toPos[1]; + vec(2) = toPos[2]; + res = rotation*vec + scale*vec + translation; + toPos[0] = res(0); + toPos[1] = res(1); + toPos[2] = res(2); + toPos.setReferenceFrame(toFrame); + return true; + } + else if ((fromPos.getReferenceFrame() == toFrame) && + (toPos.getReferenceFrame() == fromFrame)) + { + // inverse transform + toPos = fromPos; + toPos.transformTo(Position::Cartesian); + Vector vec(3),res(3); + vec(0) = toPos[0]; + vec(1) = toPos[1]; + vec(2) = toPos[2]; + res = transpose(rotation) * (vec - scale*vec - translation); + toPos[0] = res(0); + toPos[1] = res(1); + toPos[2] = res(2); + toPos.setReferenceFrame(fromFrame); + return true; + } + return false; + } + + + bool HelmertTransformer :: + transform(const Xvt& fromPos, Xvt& toPos) + const noexcept + { + Position pos(fromPos.x, Position::Cartesian), res; + pos.setReferenceFrame(fromPos.frame); + res.setReferenceFrame(toPos.frame); + if (!transform(pos, res)) + { + return false; + } + toPos = fromPos; + toPos.x[0] = res[0]; + toPos.x[1] = res[1]; + toPos.x[2] = res[2]; + toPos.frame = res.getReferenceFrame(); + return true; + } + + + bool HelmertTransformer :: + transform(const Vector& fromPos, + const RefFrame& srcFrame, + Vector& toPos) + const noexcept + { + Position pos(fromPos[0],fromPos[1],fromPos[2],Position::Cartesian), res; + pos.setReferenceFrame(srcFrame); + if (srcFrame == fromFrame) + { + res.setReferenceFrame(toFrame); + } + else if (srcFrame == toFrame) + { + res.setReferenceFrame(fromFrame); + } + else + { + return false; + } + if (!transform(pos, res)) + { + return false; + } + toPos = Vector(3); + toPos[0] = res[0]; + toPos[1] = res[1]; + toPos[2] = res[2]; + return true; + } + + + bool HelmertTransformer :: + transform(const Triple& fromPos, + const RefFrame& srcFrame, + Triple& toPos) + const noexcept + { + Position pos(fromPos, Position::Cartesian), res; + pos.setReferenceFrame(srcFrame); + if (srcFrame == fromFrame) + { + res.setReferenceFrame(toFrame); + } + else if (srcFrame == toFrame) + { + res.setReferenceFrame(fromFrame); + } + else + { + return false; + } + if (!transform(pos, res)) + { + return false; + } + toPos[0] = res[0]; + toPos[1] = res[1]; + toPos[2] = res[2]; + return true; + } + + + bool HelmertTransformer :: + transform(double fx, double fy, double fz, + const RefFrame& srcFrame, + double& tx, double& ty, double& tz) + const noexcept + { + Position pos(fx,fy,fz,Position::Cartesian), res; + pos.setReferenceFrame(srcFrame); + if (srcFrame == fromFrame) + { + res.setReferenceFrame(toFrame); + } + else if (srcFrame == toFrame) + { + res.setReferenceFrame(fromFrame); + } + else + { + return false; + } + if (!transform(pos, res)) + { + return false; + } + tx = res.X(); + ty = res.Y(); + tz = res.Z(); + return true; + } + +} // namespace gnsstk diff --git a/core/lib/GNSSCore/HelmertTransformer.hpp b/core/lib/GNSSCore/HelmertTransformer.hpp new file mode 100644 index 000000000..db923c5ee --- /dev/null +++ b/core/lib/GNSSCore/HelmertTransformer.hpp @@ -0,0 +1,176 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_HELMERTTRANSFORMER_HPP +#define GNSSTK_HELMERTTRANSFORMER_HPP + +#include "Transformer.hpp" +#include "Matrix.hpp" + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /** Provide a class for transforming positions between datums + * using the Helmert 7-parameter transform. */ + class HelmertTransformer : public Transformer + { + public: + /// Initialize everything to invalid values. + HelmertTransformer(); + + /** Explicit constructor, from the 7 parameters. + * All the inputs are unchanged. + * + * This constructor and class are for data to be used with + * the transformation of the either of the two following + * forms (view via doxygen). + * + * @warning If the transformation parameters + * use the transposed version of the rotation matrix + * (i.e. the signs on the rotation angles are reversed from + * what is shown below), make sure to flip the sign on the + * irx,iry,irz parameters to the constructor. + * + * \f[ + * \left[ {\begin{array}{c} X_{tgt} \\ + * Y_{tgt} \\ + * Z_{tgt} \\ + * \end{array} } + * \right] = \left[ {\begin{array}{c} T_x \\ + * T_y \\ + * T_z \\ + * \end{array} } + * \right] + (1 + S_c) \left[ {\begin{array}{ccc} 1 & R_z & -R_y \\ + * -R_z & 1 & R_x \\ + * R_y & -R_x & 1 \\ + * \end{array} } + * \right] + * \left[ {\begin{array}{c} X_{src} \\ + * Y_{src} \\ + * Z_{src} \\ + * \end{array} } + * \right] + * \f] + * + * \f[ + * \left[ {\begin{array}{c} X_{tgt} \\ + * Y_{tgt} \\ + * Z_{tgt} \\ + * \end{array} } + * \right] = \left[ {\begin{array}{c} X_{src} \\ + * Y_{src} \\ + * Z_{src} \\ + * \end{array} } + * \right] + \left[ {\begin{array}{c} T_x \\ + * T_y \\ + * T_z \\ + * \end{array} } + * \right] + \left[ {\begin{array}{ccc} S_c & R_z & -R_y \\ + * -R_z & S_c & R_x \\ + * R_y & -R_x & S_c \\ + * \end{array} } + * \right] \left[ {\begin{array}{c} X_{src} \\ + * Y_{src} \\ + * Z_{src} \\ + * \end{array} } + * \right] + * \f] + * + * @param[in] from Transform takes "from" -> "to" + * @param[in] to Transform takes "from" -> "to" + * @param[in] irx X axis rotation angle in degrees + * @param[in] iry Y axis rotation angle in degrees + * @param[in] irz Z axis rotation angle in degrees + * @param[in] itx X axis translation in meters + * @param[in] ity Y axis translation in meters + * @param[in] itz Z axis translation in meters + * @param[in] sc scale factor (dimensionless) + * @param[in] desc description of the transform, should include + * @param[in] refEpoch time when transform became applicable + * (default=BOT) reference frames and an indication of the + * source (e.g. literature citation). + * @throw InvalidRequest if the transform is invalid. */ + HelmertTransformer(const RefFrame& from, const RefFrame& to, + double irx, double iry, double irz, + double itx, double ity, double itz, + double sc, const std::string& desc, + const CommonTime& refEpoch); + /// @copydoc Transformer::transform(const Position&,Position&) + bool transform(const Position& fromPos, Position& toPos) + const noexcept override; + /// @copydoc Transformer::transform(const Xvt&,Xvt&) + bool transform(const Xvt& fromPos, Xvt& toPos) + const noexcept override; + /// @copydoc Transformer::transform(const Vector&,const RefFrame&,Vector&) + bool transform(const Vector& fromPos, + const RefFrame& srcFrame, + Vector& toPos) + const noexcept override; + /// @copydoc Transformer::transform(const Triple&,const RefFrame&,Triple&) + bool transform(const Triple& fromPos, + const RefFrame& srcFrame, + Triple& toPos) + const noexcept override; + /// @copydoc Transformer::transform(double,double,double,const RefFrame&,double&,double&,double&) + bool transform(double fx, double fy, double fz, + const RefFrame& srcFrame, + double& tx, double& ty, double& tz) + const noexcept override; + + /** An arbitrary string describing the transform. It should + * include the source. */ + std::string description; + + protected: + /** The matrix that applies a rotation to move from fromFrame + * to toFrame. */ + Matrix rotation; + /** The matrix that applies a translation to move from + * fromFrame to toFrame. */ + Vector translation; + /// Scale factor. Dimensionless. 0 = no scale. + double scale; + }; // class HelmertTransformer + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_HELMERTTRANSFORMER_HPP diff --git a/core/lib/GNSSCore/PZ90Ellipsoid.hpp b/core/lib/GNSSCore/PZ90Ellipsoid.hpp index ee79e6944..3f0e8646c 100644 --- a/core/lib/GNSSCore/PZ90Ellipsoid.hpp +++ b/core/lib/GNSSCore/PZ90Ellipsoid.hpp @@ -48,7 +48,7 @@ namespace gnsstk { - /// @ingroup Geodetic + /// @ingroup geodeticgroup //@{ class PZ90Ellipsoid : public EllipsoidModel diff --git a/core/lib/GNSSCore/Position.cpp b/core/lib/GNSSCore/Position.cpp index fde9d426e..fad37dd2d 100644 --- a/core/lib/GNSSCore/Position.cpp +++ b/core/lib/GNSSCore/Position.cpp @@ -101,7 +101,7 @@ namespace gnsstk const double& c, Position::CoordinateSystem s, const EllipsoidModel *ell, - ReferenceFrame frame) + const RefFrame& frame) { try { initialize(a,b,c,s,ell,frame); @@ -114,7 +114,7 @@ namespace gnsstk Position::Position(const double ABC[3], CoordinateSystem s, const EllipsoidModel *ell, - ReferenceFrame frame) + const RefFrame& frame) { double a=ABC[0]; double b=ABC[1]; @@ -130,7 +130,7 @@ namespace gnsstk Position::Position(const Triple& ABC, CoordinateSystem s, const EllipsoidModel *ell, - ReferenceFrame frame) + const RefFrame& frame) { double a=ABC[0]; double b=ABC[1]; @@ -343,7 +343,7 @@ namespace gnsstk // system if that is required. // - const ReferenceFrame& Position::getReferenceFrame() const + const RefFrame& Position::getReferenceFrame() const noexcept { return refFrame; @@ -464,7 +464,7 @@ namespace gnsstk // ----------- Part 8: member functions: set ----------------------------- // - void Position::setReferenceFrame(const ReferenceFrame& frame) + void Position::setReferenceFrame(const RefFrame& frame) noexcept { refFrame = frame; @@ -1703,7 +1703,7 @@ namespace gnsstk const double c, Position::CoordinateSystem s, const EllipsoidModel *ell, - ReferenceFrame frame) + const RefFrame& frame) { double bb(b); if(s == Geodetic || s==Geocentric) diff --git a/core/lib/GNSSCore/Position.hpp b/core/lib/GNSSCore/Position.hpp index 90e10606f..f071abbb5 100644 --- a/core/lib/GNSSCore/Position.hpp +++ b/core/lib/GNSSCore/Position.hpp @@ -43,16 +43,13 @@ #include "StringUtils.hpp" #include "Triple.hpp" #include "EllipsoidModel.hpp" -#include "ReferenceFrame.hpp" +#include "RefFrame.hpp" #include "Xvt.hpp" #include "Angle.hpp" #include "gnsstk_export.h" namespace gnsstk { - /// @ingroup Geodetic - //@{ - // forward declarations class Position; /** @@ -60,6 +57,9 @@ namespace gnsstk */ double range(const Position& A, const Position& B); + /// @ingroup geodeticgroup + //@{ + /** * A position representation class for common 3D geographic * position formats, including geodetic (geodetic latitude, @@ -209,7 +209,7 @@ namespace gnsstk const double& c, CoordinateSystem s = Cartesian, const EllipsoidModel *ell = nullptr, - ReferenceFrame frame = ReferenceFrame::Unknown); + const RefFrame& frame = RefFrame()); /** * Explicit constructor. Coordinate system may be specified @@ -224,7 +224,7 @@ namespace gnsstk Position(const double ABC[3], CoordinateSystem s = Cartesian, const EllipsoidModel *ell = nullptr, - ReferenceFrame frame = ReferenceFrame::Unknown); + const RefFrame& frame = RefFrame()); /** * Explicit constructor. Coordinate system may be specified @@ -239,7 +239,7 @@ namespace gnsstk Position(const Triple& ABC, CoordinateSystem s = Cartesian, const EllipsoidModel *ell = nullptr, - ReferenceFrame frame = ReferenceFrame::Unknown); + const RefFrame& frame = RefFrame()); /** * Explicit constructor from Xvt. The coordinate system is Cartesian, @@ -398,8 +398,8 @@ namespace gnsstk // coordinate systems. // - /// return coordinate ReferenceFrame - const ReferenceFrame& getReferenceFrame() const + /// return coordinate RefFrame + const RefFrame& getReferenceFrame() const noexcept; /// return X coordinate (meters) @@ -509,10 +509,10 @@ namespace gnsstk // ----------- Part 8: member functions: set ------------------------ // /** - * Set the ReferenceFrame that this position is in. - * @param frame The ReferenceFrame to set to. + * Set the RefFrame that this position is in. + * @param frame The RefFrame to set to. */ - void setReferenceFrame(const ReferenceFrame& frame) + void setReferenceFrame(const RefFrame& frame) noexcept; /** @@ -1043,7 +1043,7 @@ namespace gnsstk const double c, CoordinateSystem s = Cartesian, const EllipsoidModel *ell = nullptr, - ReferenceFrame frame = ReferenceFrame::Unknown); + const RefFrame& frame = RefFrame()); /* Values of the coordinates, defined for each system as follows; * Cartesian : X,Y,Z in meters @@ -1070,7 +1070,7 @@ namespace gnsstk /// tolerance used in comparisons double tolerance; - ReferenceFrame refFrame; + RefFrame refFrame; }; // end class Position diff --git a/core/lib/GNSSCore/RefFrame.cpp b/core/lib/GNSSCore/RefFrame.cpp new file mode 100644 index 000000000..9b28b53da --- /dev/null +++ b/core/lib/GNSSCore/RefFrame.cpp @@ -0,0 +1,178 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "RefFrame.hpp" +#include "StringUtils.hpp" + +namespace gnsstk +{ + RefFrame :: + RefFrame() + : system(RefFrameSys::Unknown), + realization(RefFrameRlz::Unknown) + { + } + + + RefFrame :: + RefFrame(RefFrameRlz rlz) + : realization(rlz), + system(getRefFrameSys(rlz)) + { + } + + + RefFrame :: + RefFrame(RefFrameSys sys, const gnsstk::CommonTime& when) + : system(sys), + realization(getRefFrameRlz(sys,when)) + { + } + + + RefFrame :: + RefFrame(const std::string& str, const gnsstk::CommonTime& when) + { + realization = StringUtils::asRefFrameRlz(str); + if (realization != gnsstk::RefFrameRlz::Unknown) + { + system = getRefFrameSys(realization); + } + else + { + // try again but treat str as a system rather than a realization + system = StringUtils::asRefFrameSys(str); + realization = getRefFrameRlz(system, when); + } + } + + + bool RefFrame :: + operator<(const RefFrame& right) const noexcept + { + if (system < right.system) return true; + if (right.system < system) return false; + if (realization < right.realization) return true; + return false; + } + + + bool RefFrame :: + operator==(ReferenceFrame orf) const noexcept + { + // Only compare the reference frame SYSTEMS because that's + // how it's being used in HelmertTransform. + return (((orf == ReferenceFrame::Unknown) && + (system == RefFrameSys::Unknown)) || + ((orf == ReferenceFrame::WGS84) && + (system == RefFrameSys::WGS84)) || + ((orf == ReferenceFrame::ITRF) && + (system == RefFrameSys::ITRF)) || + ((orf == ReferenceFrame::PZ90) && + (system == RefFrameSys::PZ90)) || + ((orf == ReferenceFrame::CGCS2000) && + (system == RefFrameSys::CGCS2000))); + } + + + RefFrame :: + RefFrame(ReferenceFrame orf, const gnsstk::CommonTime& when) + { + switch (orf) + { + case ReferenceFrame::WGS84: + *this = RefFrame(RefFrameSys::WGS84, when); + break; + case ReferenceFrame::WGS84G730: + *this = RefFrame(RefFrameRlz::WGS84G730); + break; + case ReferenceFrame::WGS84G873: + *this = RefFrame(RefFrameRlz::WGS84G873); + break; + case ReferenceFrame::WGS84G1150: + *this = RefFrame(RefFrameRlz::WGS84G1150); + break; + case ReferenceFrame::WGS84G1674: + *this = RefFrame(RefFrameRlz::WGS84G1674); + break; + case ReferenceFrame::WGS84G1762: + *this = RefFrame(RefFrameRlz::WGS84G1762); + break; + case ReferenceFrame::ITRF: + *this = RefFrame(RefFrameSys::ITRF, when); + break; + case ReferenceFrame::ITRF94: + *this = RefFrame(RefFrameRlz::ITRF94); + break; + case ReferenceFrame::ITRF96: + *this = RefFrame(RefFrameRlz::ITRF96); + break; + case ReferenceFrame::ITRF97: + *this = RefFrame(RefFrameRlz::ITRF97); + break; + case ReferenceFrame::ITRF2000: + *this = RefFrame(RefFrameRlz::ITRF2000); + break; + case ReferenceFrame::ITRF2005: + *this = RefFrame(RefFrameRlz::ITRF2005); + break; + case ReferenceFrame::ITRF2008: + *this = RefFrame(RefFrameRlz::ITRF2008); + break; + case ReferenceFrame::ITRF2014: + *this = RefFrame(RefFrameRlz::ITRF2014); + break; + case ReferenceFrame::PZ90: + *this = RefFrame(RefFrameSys::PZ90, when); + break; + case ReferenceFrame::PZ90KGS: + *this = RefFrame(RefFrameRlz::PZ90KGS); + break; + case ReferenceFrame::CGCS2000: + *this = RefFrame(RefFrameSys::CGCS2000, when); + break; + default: + { + InvalidParameter exc("Invalid ReferenceFrame " + + StringUtils::asString((int)orf)); + GNSSTK_THROW(exc); + break; + } + } + } +} // namespace gnsstk diff --git a/core/lib/GNSSCore/RefFrame.hpp b/core/lib/GNSSCore/RefFrame.hpp new file mode 100644 index 000000000..df3534584 --- /dev/null +++ b/core/lib/GNSSCore/RefFrame.hpp @@ -0,0 +1,135 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_REFFRAME_HPP +#define GNSSTK_REFFRAME_HPP + +#include "RefFrameSys.hpp" +#include "RefFrameRlz.hpp" +#include "ReferenceFrame.hpp" // deprecated + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /** Class for keeping track of specific reference frame system + * and realization pairs. */ + class RefFrame + { + public: + /// Set both system and realization to Unknown. + RefFrame(); + /** Construct a RefFrame from a RefFrameRlz. The system is + * set from an assumption based on the specified realization. + * @see getRefFrameSys(). + * @post system and realization are set. + * @param[in] rlz The reference frame realization being used. */ + RefFrame(RefFrameRlz rlz); + /** Construct a RefFrame from a RefFrameSys and a time stamp. + * The realization is set based on the time of publication. + * @see getRefFrameRlz(). + * @post system and realization are set. + * @param[in] sys The reference frame system being used. + * @param[in] when The timestamp when the reference frame + * system was being used, maps to a realization. */ + RefFrame(RefFrameSys sys, const gnsstk::CommonTime& when); + /** Construct from a string representation of a realization + * (e.g. from an SP3 file header). + * @post system and realization are set. + * @param[in] str The string representation of the ref frame + * realization + * @param[in] when The time the reference frame is being + * used. If \a str is insufficient on its own to translate + * to a realization, str will be treated as a system and an + * attempt will be made to convert the system + when to a + * realization. */ + RefFrame(const std::string& str, const gnsstk::CommonTime& when); + /// Compare this with right. + bool operator==(const RefFrame& right) const noexcept + { return (system == right.system) && (realization == right.realization); } + /// Compare this with right. + bool operator!=(const RefFrame& right) const noexcept + { return (system != right.system) || (realization != right.realization); } + /// Ordering for maps etc. + bool operator<(const RefFrame& right) const noexcept; + /// Return the reference frame system represented by this object. + RefFrameSys getSystem() const noexcept + { return system; } + /// Return the reference frame realization represented by this object. + RefFrameRlz getRealization() const noexcept + { return realization; } + + /** @deprecated This is a temporary implementation to maintain + * some usability of the original HelmertTransform class and + * will be removed in the future. */ + bool operator==(ReferenceFrame orf) const noexcept; + /** @deprecated This is a temporary implementation to maintain + * some usability of the original HelmertTransform class and + * will be removed in the future. */ + RefFrame(ReferenceFrame orf, const gnsstk::CommonTime& when); + private: + /// The reference frame system this object represents. + RefFrameSys system; + /// The reference frame realization this object represents. + RefFrameRlz realization; + + friend std::ostream& operator<<(std::ostream& s, const RefFrame& rf); + }; + + + /// A little something to use for TransformerMap. + using RefFramePair = std::pair; + + + /** Stream output operator for RefFrame, obviously. + * @param[in,out] s The stream to write to. + * @param[in] rf The RefFrame object to write. + * @return the reference s, after writing. */ + inline std::ostream& operator<<(std::ostream& s, const RefFrame& rf) + { + // just print the realization, it should be enough. + s << gnsstk::StringUtils::asString(rf.realization); + return s; + } + + //@} + +} + +#endif // GNSSTK_REFFRAME_HPP diff --git a/core/lib/GNSSCore/RefFrameRlz.cpp b/core/lib/GNSSCore/RefFrameRlz.cpp new file mode 100644 index 000000000..2489d415b --- /dev/null +++ b/core/lib/GNSSCore/RefFrameRlz.cpp @@ -0,0 +1,239 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "RefFrameRlz.hpp" +#include "YDSTime.hpp" +#include "GPSWeekSecond.hpp" +#include "BasicTimeSystemConverter.hpp" + +using namespace std; + +namespace gnsstk +{ + RefFrameSys getRefFrameSys(RefFrameRlz rlz) + noexcept + { + switch (rlz) + { + case RefFrameRlz::Unknown: return RefFrameSys::Unknown; + case RefFrameRlz::WGS84G0: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G730: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G873: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G1150: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G1674: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G1762: return RefFrameSys::WGS84; + case RefFrameRlz::WGS84G2139: return RefFrameSys::WGS84; + case RefFrameRlz::ITRF94: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF96: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF97: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF2000: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF2005: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF2008: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF2014: return RefFrameSys::ITRF; + case RefFrameRlz::ITRF2020: return RefFrameSys::ITRF; + case RefFrameRlz::PZ90Y2007: return RefFrameSys::PZ90; + case RefFrameRlz::PZ90KGS: return RefFrameSys::PZ90; + case RefFrameRlz::CGCS2000Y2008: return RefFrameSys::CGCS2000; + default: return RefFrameSys::Unknown; + } + } + + + RefFrameRlz getRefFrameRlz(RefFrameSys sys, const CommonTime& when) + { + CommonTime whenUTC(when); + if (whenUTC.getTimeSystem() != TimeSystem::UTC) + { + BasicTimeSystemConverter btsc; + // time isn't in UTC, do a rough (1s precision) conversion + if (!whenUTC.changeTimeSystem(TimeSystem::UTC, &btsc)) + { + // Can't convert for whatever reason, change it to Any + // and hope for the best. This will usually be okay as + // the supported time systems are generally only a few + // seconds apart, except for GLO. + whenUTC.setTimeSystem(TimeSystem::Any); + } + } + switch (sys) + { + case RefFrameSys::WGS84: + /** @todo fix these dates up, I wasn't able to quickly + * find actual publication dates. */ + if (whenUTC >= GPSWeekSecond(2139, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G2139; + } + else if (whenUTC >= GPSWeekSecond(1762, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G1762; + } + else if (whenUTC >= GPSWeekSecond(1674, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G1674; + } + else if (whenUTC >= GPSWeekSecond(1150, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G1150; + } + else if (whenUTC >= GPSWeekSecond(873, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G873; + } + else if (whenUTC >= GPSWeekSecond(730, 0, TimeSystem::UTC)) + { + return RefFrameRlz::WGS84G730; + } + else + { + return RefFrameRlz::WGS84G0; + } + case RefFrameSys::ITRF: + /** @todo fix these dates up, I wasn't able to quickly + * find actual publication dates. */ + if (whenUTC >= YDSTime(2020, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF2020; + } + else if (whenUTC >= YDSTime(2014, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF2014; + } + else if (whenUTC >= YDSTime(2008, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF2008; + } + else if (whenUTC >= YDSTime(2005, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF2005; + } + else if (whenUTC >= YDSTime(2000, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF2000; + } + else if (whenUTC >= YDSTime(1997, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF97; + } + else if (whenUTC >= YDSTime(1996, 1, 0, TimeSystem::UTC)) + { + return RefFrameRlz::ITRF96; + } + else + { + return RefFrameRlz::ITRF94; + } + case RefFrameSys::PZ90: + if (whenUTC >= YDSTime(2007,263,61200.0,TimeSystem::UTC)) + { + return RefFrameRlz::PZ90Y2007; + } + else + { + return RefFrameRlz::PZ90KGS; + } + break; + case RefFrameSys::CGCS2000: + // only one realization so far + return RefFrameRlz::CGCS2000Y2008; + default: + return RefFrameRlz::Unknown; + } + } + + namespace StringUtils + { + std::string asString(RefFrameRlz e) + noexcept + { + switch (e) + { + case RefFrameRlz::Unknown: return "Unknown"; + case RefFrameRlz::WGS84G0: return "WGS84(G0)"; + case RefFrameRlz::WGS84G730: return "WGS84(G730)"; + case RefFrameRlz::WGS84G873: return "WGS84(G873)"; + case RefFrameRlz::WGS84G1150: return "WGS84(G1150)"; + case RefFrameRlz::WGS84G1674: return "WGS84(G1674)"; + case RefFrameRlz::WGS84G1762: return "WGS84(G1762)"; + case RefFrameRlz::WGS84G2139: return "WGS84(G2139)"; + case RefFrameRlz::ITRF94: return "ITRF(1994)"; + case RefFrameRlz::ITRF96: return "ITRF(1996)"; + case RefFrameRlz::ITRF97: return "ITRF(1997)"; + case RefFrameRlz::ITRF2000: return "ITRF(2000)"; + case RefFrameRlz::ITRF2005: return "ITRF(2005)"; + case RefFrameRlz::ITRF2008: return "ITRF(2008)"; + case RefFrameRlz::ITRF2014: return "ITRF(2014)"; + case RefFrameRlz::ITRF2020: return "ITRF(2020)"; + case RefFrameRlz::PZ90Y2007: return "PZ90(2007)"; + case RefFrameRlz::PZ90KGS: return "PZ90KGS"; + case RefFrameRlz::CGCS2000Y2008: return "CGCS2000(2008)"; + default: return "???"; + } + } + + + RefFrameRlz asRefFrameRlz(const std::string& s) + noexcept + { + if (s == "Unknown") return RefFrameRlz::Unknown; + if (s == "WGS84(G0)") return RefFrameRlz::WGS84G0; + if (s == "WGS84(G730)") return RefFrameRlz::WGS84G730; + if (s == "WGS84(G873)") return RefFrameRlz::WGS84G873; + if (s == "WGS84(G1150)") return RefFrameRlz::WGS84G1150; + if (s == "WGS84(G1674)") return RefFrameRlz::WGS84G1674; + if (s == "WGS84(G1762)") return RefFrameRlz::WGS84G1762; + if (s == "WGS84(G2139)") return RefFrameRlz::WGS84G2139; + if (s == "ITRF(1994)") return RefFrameRlz::ITRF94; + if (s == "ITRF(1996)") return RefFrameRlz::ITRF96; + if (s == "ITRF(1997)") return RefFrameRlz::ITRF97; + if (s == "ITRF(2000)") return RefFrameRlz::ITRF2000; + if (s == "ITRF(2005)") return RefFrameRlz::ITRF2005; + if (s == "ITRF(2008)") return RefFrameRlz::ITRF2008; + if (s == "ITRF(2014)") return RefFrameRlz::ITRF2014; + if (s == "ITRF(2020)") return RefFrameRlz::ITRF2020; + if (s == "PZ90(2007)") return RefFrameRlz::PZ90Y2007; + if (s == "PZ90KGS") return RefFrameRlz::PZ90KGS; + if (s == "CGCS2000(2008)") return RefFrameRlz::CGCS2000Y2008; + // strings as they (probably) appear in SP3 + if (s == "ITR94") return RefFrameRlz::ITRF94; + if (s == "ITR96") return RefFrameRlz::ITRF96; + if (s == "ITR97") return RefFrameRlz::ITRF97; + return RefFrameRlz::Unknown; + } + } // namespace StringUtils +} // end namespace diff --git a/core/lib/GNSSCore/RefFrameRlz.hpp b/core/lib/GNSSCore/RefFrameRlz.hpp new file mode 100644 index 000000000..dc27f9f14 --- /dev/null +++ b/core/lib/GNSSCore/RefFrameRlz.hpp @@ -0,0 +1,108 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_REFRAMERLZ_HPP +#define GNSSTK_REFRAMERLZ_HPP + +#include "RefFrameSys.hpp" +#include "CommonTime.hpp" + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /// Reference frame realizations. For general systems, see RefFrameSys. + enum class RefFrameRlz + { + Unknown, ///< Unknown system or uninitialized value. + WGS84G0, ///< WGS84, the original 1987 version. + WGS84G730, ///< WGS84, GPS week 730 version + WGS84G873, ///< WGS84, GPS week 873 version + WGS84G1150, ///< WGS84, GPS week 1150 version + WGS84G1674, ///< WGS84, GPS week 1674 version + WGS84G1762, ///< WGS84, GPS week 1762 version + WGS84G2139, ///< WGS84, GPS week 2139 version + ITRF94, ///< ITRF, 1994 version + ITRF96, ///< ITRF, 1996 version + ITRF97, ///< ITRF, 1997 version + ITRF2000, ///< ITRF, 2000 version + ITRF2005, ///< ITRF, 2005 version + ITRF2008, ///< ITRF, 2008 version + ITRF2014, ///< ITRF, 2014 version + ITRF2020, ///< ITRF, 2020 version + PZ90Y2007, ///< PZ90 (GLONASS), 2007 version + PZ90KGS, ///< PZ90 the "original" + CGCS2000Y2008, ///< CGCS200 (BDS) + Last ///< Used to verify that all items are described at compile time + }; + + /** Define an iterator so C++11 can do things like + * for (RefFrameRlz i : RefFrameRlzIterator()) */ + typedef EnumIterator RefFrameRlzIterator; + + /** Return the system for a given reference frame realization. + * @param[in] rlz The reference frame realization whose system + * is requested. + * @return the matching RefFrameSys (or Unknown if for some + * reason there isn't one). */ + RefFrameSys getRefFrameSys(RefFrameRlz rlz) noexcept; + + /** Return the realization for a given reference frame system and time. + * @param[in] sys The reference frame system whose realization + * is requested. + * @param[in] when The time at which the reference frame realization + * would have been in use. Expected to be in UTC time system. + * @throw InvalidRequest if when is not in UTC. + * @return the matching RefFrameRlz (or Unknown if for some + * reason there isn't one). */ + RefFrameRlz getRefFrameRlz(RefFrameSys sys, const CommonTime& when); + + namespace StringUtils + { + /// Convert a RefFrameRlz to a whitespace-free string name. + std::string asString(RefFrameRlz e) noexcept; + /// Convert a string name to an RefFrameRlz + RefFrameRlz asRefFrameRlz(const std::string& s) noexcept; + } + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_REFRAMERLZ_HPP diff --git a/core/tests/RefTime/HelmertTransform_T.hpp b/core/lib/GNSSCore/RefFrameSys.cpp similarity index 63% rename from core/tests/RefTime/HelmertTransform_T.hpp rename to core/lib/GNSSCore/RefFrameSys.cpp index 8359c20d6..b81e458a5 100644 --- a/core/tests/RefTime/HelmertTransform_T.hpp +++ b/core/lib/GNSSCore/RefFrameSys.cpp @@ -36,46 +36,38 @@ // //============================================================================== -#ifndef X_HELMERT_TRANSFORM_HPP -#define X_HELMERT_TRANSFORM_HPP +#include "RefFrameSys.hpp" -#include -#include -#include "HelmertTransform.hpp" -#include "ReferenceFrame.hpp" -#include "Position.hpp" -#include "Xvt.hpp" -#include "Triple.hpp" -#include "Vector.hpp" +using namespace std; - -class HelmertTransform_T : public CPPUNIT_NS :: TestFixture +namespace gnsstk { - CPPUNIT_TEST_SUITE (HelmertTransform_T); - CPPUNIT_TEST (positionTransformTest); - CPPUNIT_TEST (xtTransformTest); - CPPUNIT_TEST (xvtTransformTest); - CPPUNIT_TEST (triplePosTransformTest); - CPPUNIT_TEST (tripleVelTransformTest); - CPPUNIT_TEST (vectorPosTransformTest); - CPPUNIT_TEST (vectorVelTransformTest); - CPPUNIT_TEST_SUITE_END (); - - public: - void setUp(); - void tearDown() { }; - - protected: - void positionTransformTest(); - void xtTransformTest(); - void xvtTransformTest(); - void triplePosTransformTest(); - void tripleVelTransformTest(); - void vectorPosTransformTest(); - void vectorVelTransformTest(); - - private: + namespace StringUtils + { + std::string asString(RefFrameSys e) + noexcept + { + switch (e) + { + case RefFrameSys::Unknown: return "Unknown"; + case RefFrameSys::WGS84: return "WGS84"; + case RefFrameSys::ITRF: return "ITRF"; + case RefFrameSys::PZ90: return "PZ90"; + case RefFrameSys::CGCS2000: return "CGCS2000"; + default: return "???"; + } + } -}; -#endif + RefFrameSys asRefFrameSys(const std::string& s) + noexcept + { + if (s == "Unknown") return RefFrameSys::Unknown; + if (s == "WGS84") return RefFrameSys::WGS84; + if (s == "ITRF") return RefFrameSys::ITRF; + if (s == "PZ90") return RefFrameSys::PZ90; + if (s == "CGCS2000") return RefFrameSys::CGCS2000; + return RefFrameSys::Unknown; + } + } +} // end namespace diff --git a/core/lib/GNSSCore/RefFrameSys.hpp b/core/lib/GNSSCore/RefFrameSys.hpp new file mode 100644 index 000000000..1a6f6879e --- /dev/null +++ b/core/lib/GNSSCore/RefFrameSys.hpp @@ -0,0 +1,77 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_REFRAMESYS_HPP +#define GNSSTK_REFRAMESYS_HPP + +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /// Reference frame systems. For specific realizations, see RefFrameRlz. + enum class RefFrameSys + { + Unknown, ///< Unknown system or uninitialized value. + WGS84, ///< The reference frame used by GPS. + ITRF, ///< The reference frame used by Galileo. + PZ90, ///< The reference frame used by Glonass. + CGCS2000, ///< The reference frame used by BeiDou. + Last ///< Used to verify that all items are described at compile time + }; + + /** Define an iterator so C++11 can do things like + * for (RefFrameSys i : RefFrameSysIterator()) */ + typedef EnumIterator RefFrameSysIterator; + + namespace StringUtils + { + /// Convert a RefFrameSys to a whitespace-free string name. + std::string asString(RefFrameSys e) noexcept; + /// Convert a string name to an RefFrameSys + RefFrameSys asRefFrameSys(const std::string& s) noexcept; + } + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_REFRAMESYS_HPP diff --git a/core/lib/GNSSCore/TransformLibrary.cpp b/core/lib/GNSSCore/TransformLibrary.cpp new file mode 100644 index 000000000..f45ae7a52 --- /dev/null +++ b/core/lib/GNSSCore/TransformLibrary.cpp @@ -0,0 +1,245 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TransformLibrary.hpp" +#include "GNSSconstants.hpp" +#include "HelmertTransformer.hpp" +#include "YDSTime.hpp" + +namespace gnsstk +{ + TransformLibrary :: + TransformLibrary() + { + TimeSystem ts = TimeSystem::UTC; + const CommonTime PZ90Epoch(YDSTime(2007,263,61200.0,ts)); + + addTransform(std::make_shared( + RefFrame(RefFrameSys::WGS84, YDSTime(2001,305,0,ts)), + RefFrame(RefFrameSys::ITRF, YDSTime(2001,305,0,ts)), + 0, 0, 0, 0.0, 0.0, 0.0, 0, + "WGS84 to ITRF identity transform, a default value\n" + " (\"...since 1997, the WGS84 GPS broadcast ...\n" + " is consistent with the ITRS at better than 5-cm" + " level.\"\n" + " Boucher & Altamimi 2001)", + YDSTime(1997,1,0.0,ts))); + + // PZ90 WGS84 + addTransform(std::make_shared( + RefFrame(RefFrameSys::PZ90, YDSTime(2001,305,0,ts)), + RefFrame(RefFrameSys::WGS84, YDSTime(2001,305,0,ts)), + -19*DEG_PER_MAS, -4*DEG_PER_MAS, 353*DEG_PER_MAS, + 0.07, 0.0, -0.77, + -3*PPB, + "PZ90 to WGS84, determined by IGEX-98, reference\n" + " \"ITRS, PZ-90 and WGS 84: current realizations\n" + " and the related transformation parameters,\"\n" + " Journal Geodesy (2001), 75:613, by Boucher and" + " Altamimi.\n" + " Use before 20 Sept 2007 17:00 UTC (ICD-2008 v5.1" + " table 3.2).", + YDSTime(-4713,1,0.0,ts))); + + /** @note This transformation, as the others, was copied from + * an earlier implementation in HelmertTransform.cpp. I have + * been unable to track down the source, and the target + * reference frame and rotation parameters are somewhat + * dubious. The target reference frame does not match the + * description, and the Z rotation parameter is the opposite + * sign of two other references I found for similar + * transformations. + addTransform(std::make_shared( + RefFrame(RefFrameRlz::PZ90Y2007), + RefFrame(RefFrameRlz::WGS84G1150), + 0, 0, 0, -0.36, 0.08, 0.18, 0, + "PZ90.02 to ITRF2000, from Sergey Revnivykh, GLONASS PNT\n" + " Information Analysis Center, 47th CGSIC Meeting" + " and ION\n" + " GNSS 2007, Fort Worth, Texas, implemented by" + " GLONASS\n" + " 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).", + PZ90Epoch)); + */ + + // PZ90 ITRF + addTransform(std::make_shared( + RefFrame(RefFrameRlz::PZ90KGS), + RefFrame(RefFrameRlz::ITRF2000), /// @todo correct? + -19*DEG_PER_MAS, -4*DEG_PER_MAS, 353*DEG_PER_MAS, + 0.07, 0.0, -0.77, + -3*PPB, + "PZ90 to ITRF(WGS84), determined by IGEX-98, reference\n" + " \"ITRS, PZ-90 and WGS 84: current realizations\n" + " and the related transformation parameters,\"\n" + " Journal Geodesy (2001), 75:613, by Boucher and" + " Altamimi.\n" + " Use before 20 Sept 2007 17:00 UTC (ICD-2008 v5.1" + " table 3.2).", + YDSTime(-4713,1,0.0,ts))); + + /* see the note above. + addTransform(std::make_shared( + RefFrame(RefFrameRlz::PZ90Y2007), + RefFrame(RefFrameRlz::ITRF2000), + 0, 0, 0, -0.36, 0.08, 0.18, 0, + "PZ90.02 to ITRF2000, from Sergey Revnivykh, GLONASS PNT\n" + " Information Analysis Center, 47th CGSIC Meeting" + " and ION\n" + " GNSS 2007, Fort Worth, Texas, implemented by" + " GLONASS\n" + " 20 Sept 2007 17:00 UTC (ICD-2008 v5.1 table 3.2).", + PZ90Epoch)); + */ + } + + + void TransformLibrary :: + addTransform(const TransformerPtr& ptr) + { + // Insert the Transformer into the map with keys representing + // both forward and reverse transformations. + RefFramePair keyFwd(ptr->getFromFrame(), ptr->getToFrame()); + RefFramePair keyBwd(ptr->getToFrame(), ptr->getFromFrame()); + transformers[keyFwd][ptr->getEpoch()] = ptr; + transformers[keyBwd][ptr->getEpoch()] = ptr; + } + + + bool TransformLibrary :: + getTransform(const RefFrame& fromFrame, const RefFrame& toFrame, + TransformerPtr& ptr, const CommonTime& when) + const + { + // All Transformers should have been added for both forward + // and reverse direction so no need to search for both here. + RefFramePair key(fromFrame, toFrame); + const auto& p = transformers.find(key); + if (p != transformers.end()) + { + const auto& t = p->second.upper_bound(when); + const auto& pt = std::prev(t); + if (pt == p->second.end()) + { + return false; + } + ptr = pt->second; + return true; + } + return false; + } + + + bool TransformLibrary :: + transform(const Position& fromPos, Position& toPos, const CommonTime& when) + const noexcept + { + TransformerPtr xform; + if (!getTransform(fromPos.getReferenceFrame(), toPos.getReferenceFrame(), + xform, when)) + { + return false; + } + return xform->transform(fromPos, toPos); + } + + + bool TransformLibrary :: + transform(const Xvt& fromPos, Xvt& toPos, const CommonTime& when) + const noexcept + { + TransformerPtr xform; + if (!getTransform(fromPos.frame, toPos.frame, xform, when)) + { + return false; + } + return xform->transform(fromPos, toPos); + } + + + bool TransformLibrary :: + transform(const Vector& fromPos, + const RefFrame& srcFrame, + Vector& toPos, + const RefFrame& tgtFrame, + const CommonTime& when) + const noexcept + { + TransformerPtr xform; + if (!getTransform(srcFrame, tgtFrame, xform, when)) + { + return false; + } + return xform->transform(fromPos, srcFrame, toPos); + } + + + bool TransformLibrary :: + transform(const Triple& fromPos, + const RefFrame& srcFrame, + Triple& toPos, + const RefFrame& tgtFrame, + const CommonTime& when) + const noexcept + { + TransformerPtr xform; + if (!getTransform(srcFrame, tgtFrame, xform, when)) + { + return false; + } + return xform->transform(fromPos, srcFrame, toPos); + } + + + bool TransformLibrary :: + transform(double fx, double fy, double fz, + const RefFrame& srcFrame, + double& tx, double& ty, double& tz, + const RefFrame& tgtFrame, + const CommonTime& when) + const noexcept + { + TransformerPtr xform; + if (!getTransform(srcFrame, tgtFrame, xform, when)) + { + return false; + } + return xform->transform(fx, fy, fz, srcFrame, tx, ty, tz); + } + +} // namespace gnsstk diff --git a/core/lib/GNSSCore/TransformLibrary.hpp b/core/lib/GNSSCore/TransformLibrary.hpp new file mode 100644 index 000000000..ea33c347f --- /dev/null +++ b/core/lib/GNSSCore/TransformLibrary.hpp @@ -0,0 +1,215 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_TRANSFORM_LIBRARY +#define GNSSTK_TRANSFORM_LIBRARY + +#include "Transformer.hpp" + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /** This class provides storage and access to datum + * transformations. Recommended use is to create one instance + * of this class and either use the transformation data that is + * loaded by default and/or add additional transformation data. + * Then call the appropriate transform method for each + * coordinate transformation. + * + * Call the clear() method on \a transformers to empty the + * default transformation data if desired. + * + * Typical usage would be something like: + * @code + * TransformLibrary xflib; + * ... + * CommonTime ct = ...; + * ObsID oid = ...; + * Xvt xvt, xvtITRF; + * eph.getXvt(ct, xvt, oid); + * xvtITRF.frame = RefFrame(RefFrameRlz::ITRF2020); + * if (xflib.transform(xvt, xvtITRF, ct)) + * { + * cout << "success!" << endl; + * } + * @endcode + */ + class TransformLibrary + { + public: + /// Fill the library with a default set of transformation parameters. + TransformLibrary(); + + /** Add a new Transformer to the library. + * @param[in] ptr The Transformer to be added. + * @post transformers contains ptr with keys in forward and reverse. */ + void addTransform(const TransformerPtr& ptr); + + /** Get the Transformer in \a transformers that matches the requested + * parameters. + * @param[in] fromFrame The RefFrame being converted from. + * @param[in] toFrame The RefFrame being converted to. + * @param[out] ptr The Transformer that matches, if true is returned. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true if a match was found. */ + bool getTransform(const RefFrame& fromFrame, const RefFrame& toFrame, + TransformerPtr& ptr, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const; + + /** Convert a position from the reference frame in fromPos to + * that in toPos. + * @pre RefFrame must be set in both fromPos and toPos. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toPos reference frame realization are + * set in toPos. + * @param[in] fromPos The Position to be converted. + * @param[in,out] toPos The Position to store the converted position. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true on success, false on failure (typically if + * the Position RefFrame objects don't match the ones in + * this Transformer). */ + bool transform(const Position& fromPos, Position& toPos, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const noexcept; + + /** Convert a position from the reference frame in fromPos to + * that in toPos. + * @pre RefFrame must be set in both fromPos and toPos. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toPos reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Xvt whose position is to be converted. + * @param[in,out] toPos The Xvt to store the converted position. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true on success, false on failure (typically if + * the Xvt RefFrame objects don't match the ones in + * this Transformer). */ + bool transform(const Xvt& fromPos, Xvt& toPos, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const noexcept; + + /** Convert a position in fromPos from the reference frame in + * srcFrame to that in tgtFrame. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Vector whose position is to be converted. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] toPos The Vector to store the converted position. + * @param[in] tgtFrame The RefFrame to convert to. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + bool transform(const Vector& fromPos, + const RefFrame& srcFrame, + Vector& toPos, + const RefFrame& tgtFrame, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const noexcept; + + /** Convert a position in fromPos from the reference frame in + * srcFrame to that in tgtFrame. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Vector whose position is to be converted. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] toPos The Vector to store the converted position. + * @param[in] tgtFrame The RefFrame to convert to. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + bool transform(const Triple& fromPos, + const RefFrame& srcFrame, + Triple& toPos, + const RefFrame& tgtFrame, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const noexcept; + + /** Convert 3 doubles from the reference frame in srcFrame to + * that in tgtFrame. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fx ECEF x coordinate in meters in srcFrame. + * @param[in] fy ECEF y coordinate in meters in srcFrame. + * @param[in] fz ECEF z coordinate in meters in srcFrame. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] tx ECEF x coordinate in meters in srcFrame. + * @param[out] ty ECEF y coordinate in meters in srcFrame. + * @param[out] tz ECEF z coordinate in meters in srcFrame. + * @param[in] tgtFrame The RefFrame to convert to. + * @param[in] when The time of interest for the + * transformation. This does not affect the RefFrame, it + * is only used when multiple transformation parameter sets + * are available over a span of time. Default = most recent. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + bool transform(double fx, double fy, double fz, + const RefFrame& srcFrame, + double& tx, double& ty, double& tz, + const RefFrame& tgtFrame, + const CommonTime& when = gnsstk::CommonTime::END_OF_TIME) + const noexcept; + + TransformerMap transformers; ///< More than meets the eye + }; // class TransformLibrary + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_TRANSFORM_LIBRARY diff --git a/core/lib/GNSSCore/Transformer.hpp b/core/lib/GNSSCore/Transformer.hpp new file mode 100644 index 000000000..d242fb46d --- /dev/null +++ b/core/lib/GNSSCore/Transformer.hpp @@ -0,0 +1,173 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef GNSSTK_TRANSFORMER_HPP +#define GNSSTK_TRANSFORMER_HPP + +#include +#include +#include "Position.hpp" +#include "Xvt.hpp" +#include "Vector.hpp" +#include "RefFrame.hpp" +#include "CommonTime.hpp" + +namespace gnsstk +{ + /// @ingroup geodeticgroup + //@{ + + /** Provide an abstract base class for tools that can transform + * between coordinate systems, e.g. HelmertTransformer. */ + class Transformer + { + public: + // Initialize start and end time to min and max values. + Transformer() + : epoch(gnsstk::CommonTime::BEGINNING_OF_TIME) + {} + + /** Convert a position from the reference frame in fromPos to + * that in toPos. + * @pre RefFrame must be set in both fromPos and toPos. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toPos reference frame realization are + * set in toPos. + * @param[in] fromPos The Position to be converted. + * @param[in,out] toPos The Position to store the converted position. + * @return true on success, false on failure (typically if + * the Position RefFrame objects don't match the ones in + * this Transformer). */ + virtual bool transform(const Position& fromPos, Position& toPos) + const noexcept = 0; + + /** Convert a position from the reference frame in fromPos to + * that in toPos. + * @pre RefFrame must be set in both fromPos and toPos. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toPos reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Xvt whose position is to be converted. + * @param[in,out] toPos The Xvt to store the converted position. + * @return true on success, false on failure (typically if + * the Xvt RefFrame objects don't match the ones in + * this Transformer). */ + virtual bool transform(const Xvt& fromPos, Xvt& toPos) + const noexcept = 0; + + /** Convert a position from the reference frame in fromPos to + * that in toPos. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Vector whose position is to be converted. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] toPos The Vector to store the converted position. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + virtual bool transform(const Vector& fromPos, + const RefFrame& srcFrame, + Vector& toPos) + const noexcept = 0; + + /** Convert a position in fromPos from the reference frame in + * srcFrame to that in tgtFrame. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fromPos The Vector whose position is to be converted. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] toPos The Vector to store the converted position. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + virtual bool transform(const Triple& fromPos, + const RefFrame& srcFrame, + Triple& toPos) + const noexcept = 0; + + /** Convert 3 doubles from the reference frame in srcFrame to + * that in tgtFrame. + * @pre Coordinates must be set in fromPos. + * @post Coordinates in toFrame reference frame realization are + * set in toPos. Velocity and clock offset are unaffected. + * @param[in] fx ECEF x coordinate in meters in srcFrame. + * @param[in] fy ECEF y coordinate in meters in srcFrame. + * @param[in] fz ECEF z coordinate in meters in srcFrame. + * @param[in] srcFrame The RefFrame of the coordinates in fromPos. + * @param[out] tx ECEF x coordinate in meters in srcFrame. + * @param[out] ty ECEF y coordinate in meters in srcFrame. + * @param[out] tz ECEF z coordinate in meters in srcFrame. + * @return true on success, false on failure (typically if + * srcFrame doesn't match fromFrame). */ + virtual bool transform(double fx, double fy, double fz, + const RefFrame& srcFrame, + double& tx, double& ty, double& tz) + const noexcept = 0; + + /// Return the RefFrame this Transformer will convert from. + const RefFrame& getFromFrame() const noexcept + { return fromFrame; } + /// Return the RefFrame this Transformer will convert to. + const RefFrame& getToFrame() const noexcept + { return toFrame; } + /** Return the first time this Transformer is applicable. + * This is not the reference frame publication date. This is + * to allow the use of transformation sources that use the + * same reference frame realizations, but the transformation + * parameters change over time. */ + const CommonTime& getEpoch() const noexcept + { return epoch; } + + protected: + RefFrame fromFrame; ///< The reference frame we can transform from. + RefFrame toFrame; ///< The reference frame we can transform to. + CommonTime epoch; ///< When this Transformer was first applicable. + }; // class Transformer + + /// Shared pointer to Transformer object. + using TransformerPtr = std::shared_ptr; + /// Transformers may change over time while maintaining the same RefFrames + using TransformerHist = std::map; + /// Container of transformers for management. + using TransformerMap = std::map; + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_TRANSFORMER_HPP diff --git a/core/lib/GNSSCore/Xvt.cpp b/core/lib/GNSSCore/Xvt.cpp index a9091ba2d..76169c572 100644 --- a/core/lib/GNSSCore/Xvt.cpp +++ b/core/lib/GNSSCore/Xvt.cpp @@ -55,7 +55,7 @@ namespace gnsstk << ", clk drift:" << xvt.clkdrift << ", relcorr:" << xvt.relcorr << ", health:" << xvt.health - << ", frame:" << gnsstk::StringUtils::asString(xvt.frame); + << ", frame:" << xvt.frame; return os; } diff --git a/core/lib/GNSSCore/Xvt.hpp b/core/lib/GNSSCore/Xvt.hpp index b38f873ef..9a666953b 100644 --- a/core/lib/GNSSCore/Xvt.hpp +++ b/core/lib/GNSSCore/Xvt.hpp @@ -47,7 +47,7 @@ #include #include "Triple.hpp" #include "EllipsoidModel.hpp" -#include "ReferenceFrame.hpp" +#include "RefFrame.hpp" #include "GNSSconstants.hpp" namespace gnsstk @@ -100,7 +100,7 @@ namespace gnsstk /// Default constructor Xvt() : x(0.,0.,0.), v(0.,0.,0.), clkbias(0.), clkdrift(0.), - relcorr(0.), frame(ReferenceFrame::Unknown), + relcorr(0.), health(Uninitialized) {}; @@ -153,7 +153,7 @@ namespace gnsstk double clkbias; ///< Sat clock correction in seconds double clkdrift; ///< satellite clock drift in seconds/second double relcorr; ///< relativity correction (standard 2R.V/c^2 term), seconds - ReferenceFrame frame; ///< reference frame of this data + RefFrame frame; ///< reference frame of this data HealthStatus health; ///< Health status of satellite at ref time. }; // end class Xvt diff --git a/core/lib/GNSSEph/BrcKeplerOrbit.cpp b/core/lib/GNSSEph/BrcKeplerOrbit.cpp index 06f0dcc0a..378e39c36 100644 --- a/core/lib/GNSSEph/BrcKeplerOrbit.cpp +++ b/core/lib/GNSSEph/BrcKeplerOrbit.cpp @@ -364,7 +364,7 @@ namespace gnsstk // Compute clock corrections sv.relcorr = svRelativity(t); // This appears to be only a string for naming - sv.frame = ReferenceFrame::WGS84; + sv.frame = RefFrame(RefFrameSys::WGS84, t); // Compute true anomaly q = SQRT( 1.0e0 - lecc*lecc); diff --git a/core/lib/GNSSEph/GloEphemeris.cpp b/core/lib/GNSSEph/GloEphemeris.cpp deleted file mode 100644 index a379b26c7..000000000 --- a/core/lib/GNSSEph/GloEphemeris.cpp +++ /dev/null @@ -1,503 +0,0 @@ -//============================================================================== -// -// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. -// -// The GNSSTk is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 3.0 of the License, or -// any later version. -// -// The GNSSTk is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GNSSTk; if not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -// -// This software was developed by Applied Research Laboratories at the -// University of Texas at Austin. -// Copyright 2004-2022, The Board of Regents of The University of Texas System -// -//============================================================================== - -//============================================================================== -// -// This software was developed by Applied Research Laboratories at the -// University of Texas at Austin, under contract to an agency or agencies -// within the U.S. Department of Defense. The U.S. Government retains all -// rights to use, duplicate, distribute, disclose, or release this software. -// -// Pursuant to DoD Directive 523024 -// -// DISTRIBUTION STATEMENT A: This software has been approved for public -// release, distribution is unlimited. -// -//============================================================================== - -/// @file GloEphemeris.cpp -/// Ephemeris data for GLONASS. - -#include -#include "GloEphemeris.hpp" -#include "TimeString.hpp" - -namespace gnsstk -{ - - - /* Compute satellite position & velocity at the given time - * using this ephemeris. - * - * @throw InvalidRequest if required data has not been stored. - */ - Xvt GloEphemeris::svXvt(const CommonTime& epoch) const - { - - // Check that the given epoch is within the available time limits. - // We have to add a margin of 15 minutes (900 seconds). - if ( epoch < (ephTime - 900.0) || - epoch >= (ephTime + 900.0) ) - { - InvalidRequest e( "Requested time is out of ephemeris data" ); - GNSSTK_THROW(e); - } - - Xvt retVal = svXvtOverrideFit(epoch); - return retVal; - } - - Xvt GloEphemeris::svXvtOverrideFit(const CommonTime& epoch) const - { - // Values to be returned will be stored here - Xvt sv; - - // If the exact epoch is found, let's return the values - if ( epoch == ephTime ) // exact match for epoch - { - - sv.x[0] = x[0]*1.e3; // m - sv.x[1] = x[1]*1.e3; // m - sv.x[2] = x[2]*1.e3; // m - sv.v[0] = v[0]*1.e3; // m/sec - sv.v[1] = v[1]*1.e3; // m/sec - sv.v[2] = v[2]*1.e3; // m/sec - - // In the GLONASS system, 'clkbias' already includes the - // relativistic correction, therefore we must substract the late - // from the former. - sv.relcorr = sv.computeRelativityCorrection(); - sv.clkbias = clkbias + clkdrift * (epoch - ephTime) - sv.relcorr; - sv.clkdrift = clkdrift; - sv.frame = ReferenceFrame::PZ90; - - // We are done, let's return - return sv; - - } - - // Get the data out of the GloRecord structure - double px( x[0] ); // X coordinate (km) - double vx( v[0] ); // X velocity (km/s) - double ax( a[0] ); // X acceleration (km/s^2) - double py( x[1] ); // Y coordinate - double vy( v[1] ); // Y velocity - double ay( a[1] ); // Y acceleration - double pz( x[2] ); // Z coordinate - double vz( v[2] ); // Z velocity - double az( a[2] ); // Z acceleration - - // We will need some PZ-90 ellipsoid parameters - PZ90Ellipsoid pz90; - double we( pz90.angVelocity() ); - - // Get sidereal time at Greenwich at 0 hours UT - double gst( getSidTime( ephTime ) ); - double s0( gst*PI/12.0 ); - YDSTime ytime( ephTime ); - double numSeconds( ytime.sod ); - double s( s0 + we*numSeconds ); - double cs( std::cos(s) ); - double ss( std::sin(s) ); - - // Initial state matrix - Vector initialState(6), accel(3), dxt1(6), dxt2(6), dxt3(6), - dxt4(6), tempRes(6); - - // Get the reference state out of GloEphemeris object data. Values - // must be rotated from PZ-90 to an absolute coordinate system - // Initial x coordinate (m) - initialState(0) = (px*cs - py*ss); - // Initial y coordinate - initialState(2) = (px*ss + py*cs); - // Initial z coordinate - initialState(4) = pz; - - // Initial x velocity (m/s) - initialState(1) = (vx*cs - vy*ss - we*initialState(2) ); - // Initial y velocity - initialState(3) = (vx*ss + vy*cs + we*initialState(0) ); - // Initial z velocity - initialState(5) = vz; - - - // Integrate satellite state to desired epoch using the given step - double rkStep( step ); - - if ( (epoch - ephTime) < 0.0 ) rkStep = step*(-1.0); - CommonTime workEpoch( ephTime ); - - double tolerance( 1e-9 ); - bool done( false ); - while (!done) - { - - // If we are about to overstep, change the stepsize appropriately - // to hit our target final time. - if( rkStep > 0.0 ) - { - if( (workEpoch + rkStep) > epoch ) - rkStep = (epoch - workEpoch); - } - else - { - if ( (workEpoch + rkStep) < epoch ) - rkStep = (epoch - workEpoch); - } - - numSeconds += rkStep; - s = s0 + we*( numSeconds ); - cs = std::cos(s); - ss = std::sin(s); - - // Accelerations are computed once per iteration - accel(0) = ax*cs - ay*ss; - accel(1) = ax*ss + ay*cs; - accel(2) = az; - - dxt1 = derivative( initialState, accel ); - for( int j = 0; j < 6; ++j ) - tempRes(j) = initialState(j) + rkStep*dxt1(j)/2.0; - - dxt2 = derivative( tempRes, accel ); - for( int j = 0; j < 6; ++j ) - tempRes(j) = initialState(j) + rkStep*dxt2(j)/2.0; - - dxt3 = derivative( tempRes, accel ); - for( int j = 0; j < 6; ++j ) - tempRes(j) = initialState(j) + rkStep*dxt3(j); - - dxt4 = derivative( tempRes, accel ); - for( int j = 0; j < 6; ++j ) - initialState(j) = initialState(j) + rkStep * ( dxt1(j) - + 2.0 * ( dxt2(j) + dxt3(j) ) + dxt4(j) ) / 6.0; - - - // If we are within tolerance of the target time, we are done. - workEpoch += rkStep; - if ( std::fabs(epoch - workEpoch ) < tolerance ) - done = true; - - } // End of 'while (!done)...' - - - px = initialState(0); - py = initialState(2); - pz = initialState(4); - vx = initialState(1); - vy = initialState(3); - vz = initialState(5); - - sv.x[0] = 1000.0*( px*cs + py*ss ); // X coordinate - sv.x[1] = 1000.0*(-px*ss + py*cs); // Y coordinate - sv.x[2] = 1000.0*pz; // Z coordinate - sv.v[0] = 1000.0*( vx*cs + vy*ss + we*(sv.x[1]/1000.0) ); // X velocity - sv.v[1] = 1000.0*(-vx*ss + vy*cs - we*(sv.x[0]/1000.0) ); // Y velocity - sv.v[2] = 1000.0*vz; // Z velocity - - // In the GLONASS system, 'clkbias' already includes the relativistic - // correction, therefore we must substract the late from the former. - sv.relcorr = sv.computeRelativityCorrection(); - sv.clkbias = clkbias + clkdrift * (epoch - ephTime) - sv.relcorr; - sv.clkdrift = clkdrift; - sv.frame = ReferenceFrame::PZ90; - - // We are done, let's return - return sv; - - - } // End of method 'GloEphemeris::svXvt(const CommonTime& t)' - - - // Get the epoch time for this ephemeris - CommonTime GloEphemeris::getEphemerisEpoch() const - { - - // First, let's check if there is valid data - if(!valid) - { - InvalidRequest exc("getEphemerisEpoch(): No valid data stored."); - GNSSTK_THROW(exc); - } - - return ephTime; - - } // End of method 'GloEphemeris::getEphemerisEpoch()' - - - // This function returns the PRN ID of the SV. - short GloEphemeris::getPRNID() const - { - - // First, let's check if there is valid data - if(!valid) - { - InvalidRequest exc("getPRNID(): No valid data stored."); - GNSSTK_THROW(exc); - } - - return PRNID; - - } // End of method 'GloEphemeris::getPRNID()' - - - /* Compute the satellite clock bias (sec) at the given time - * - * @param epoch Epoch to compute satellite clock bias. - * - * @throw InvalidRequest if required data has not been stored. - */ - double GloEphemeris::svClockBias(const CommonTime& epoch) const - { - - // First, let's check if there is valid data - if(!valid) - { - InvalidRequest exc("svClockBias(): No valid data stored."); - GNSSTK_THROW(exc); - } - - // Auxiliar object - Xvt sv; - sv.x = x; - sv.v = v; - - // In the GLONASS system, 'clkbias' already includes the relativistic - // correction, therefore we must substract the late from the former. - sv.relcorr = sv.computeRelativityCorrection(); - sv.clkbias = clkbias + clkdrift * (epoch - ephTime) - sv.relcorr; - - return sv.clkbias; - - } // End of method 'GloEphemeris::svClockBias(const CommonTime& epoch)' - - - /* Compute the satellite clock drift (sec/sec) at the given time - * - * @param epoch Epoch to compute satellite clock drift. - * - * @throw InvalidRequest if required data has not been stored. - */ - double GloEphemeris::svClockDrift(const CommonTime& epoch) const - { - - // First, let's check if there is valid data - if(!valid) - { - InvalidRequest exc("svClockDrift(): No valid data stored."); - GNSSTK_THROW(exc); - } - - return clkdrift; - - } // End of method 'GloEphemeris::svClockDrift(const CommonTime& epoch)' - - - - - // Output the contents of this ephemeris to the given stream as a single line. - void GloEphemeris::dump(std::ostream& s) const - noexcept - { - - s << "Sys:" << satSys << ", PRN:" << PRNID - << ", Epoch:" << ephTime << ", pos:" << x - << ", vel:" << v << ", acc:" << a - << ", TauN:" << clkbias << ", GammaN:" << clkdrift - << ", MFTime:" << MFtime<< ", health:" << health - << ", freqNum:" << freqNum << ", ageOfInfo:" << ageOfInfo; - - } // End of method 'GloEphemeris::dump(std::ostream& s)' - - void GloEphemeris::prettyDump(std::ostream& s) const - { - s << "**********************************************" << std::endl; - s << "Slot ID " << std::setw(12) << PRNID << std::endl; - s << "Epoch Time " << printTime(ephTime,"%03j, %02m/%02d/%02y %02H:%02M:%02S") - << std::endl; - s << "MFTime " << std::setw(12) << MFtime << " sec of Week" << std::endl; - s << "Health " << std::setw(12) << health << std::endl; - s << "Freq. Offset" << std::setw(12) << freqNum << std::endl; - s << "Age of Info " << std::setw(12) << ageOfInfo << " days" << std::endl; - - s << "Position " << std::setw(12) << x << "m" << std::endl; - s << "Velocity " << std::setw(12) << v << "m/sec" << std::endl; - s << "Acceleration" << std::setw(12) << a << "m/sec**2" << std::endl; - s << "TauN " << std::setw(12) << clkbias << "units" << std::endl; - s << "GammaN " << std::setw(12) << clkdrift << "units" << std::endl; - } - - void GloEphemeris::terseDump(std::ostream& s) const - { - s << " " << std::setw(2) << PRNID << " "; - s << printTime(ephTime,"%03j, %02m/%02d/%02y %02H:%02M:%02S") << " "; - s << std::setw(6) << MFtime << " "; - s << std::setw(5) << health << " "; - s << std::setw(2) << freqNum << std::endl; - } - - void GloEphemeris::terseHeader(std::ostream& s) const - { - s << " Epoch time Msg Time Freq." << std::endl; - s << "Slot DOY mm/dd/yy HH:MM:SS (SOW) Health Offset" << std::endl; - } - - // Set the parameters for this ephemeris object. - GloEphemeris& GloEphemeris::setRecord( std::string svSys, - short prn, - const CommonTime& epoch, - Triple pos, - Triple vel, - Triple acc, - double tau, - double gamma, - long mftime, - short h, - short freqnum, - double age, - double rkStep ) - { - satSys = svSys; - PRNID = prn; - ephTime = epoch; - x = pos; - v = vel; - a = acc; - clkbias = tau; - clkdrift = gamma; - MFtime = mftime; - health = h; - freqNum = freqnum; - ageOfInfo = age; - - step = rkStep; - - // Set this object as valid - valid = true; - - return *this; - - } // End of method 'GloEphemeris::setRecord()' - - - // Compute true sidereal time (in hours) at Greenwich at 0 hours UT. - double GloEphemeris::getSidTime( const CommonTime& time ) const - { - - // The following algorithm is based on the paper: - // Aoki, S., Guinot,B., Kaplan, G. H., Kinoshita, H., McCarthy, D. D. - // and P.K. Seidelmann. 'The New Definition of Universal Time'. - // Astronomy and Astrophysics, 105, 359-361, 1982. - - // Get the Julian Day at 0 hours UT (jd) - YDSTime ytime( time ); - double year( static_cast(ytime.year) ); - int doy( ytime.doy ); - int temp( static_cast(floor(365.25 * (year - 1.0))) + doy ); - - double jd( static_cast(temp)+ 1721409.5 ); - - // Compute the Julian centuries (36525 days) - double jc( (jd - 2451545.0)/36525.0 ); - - // Compute the sidereal time, in seconds - double sid( 24110.54841 + jc * ( 8640184.812866 - + jc * ( 0.093104 - jc * 0.0000062 ) ) ); - - sid = sid / 3600.0; - sid = fmod(sid, 24.0); - if( sid < 0.0 ) sid = sid + 24.0; - - return sid; - - }; // End of method 'GloEphemeris::getSidTime()' - - - // Function implementing the derivative of GLONASS orbital model. - Vector GloEphemeris::derivative( const Vector& inState, - const Vector& accel ) - const - { - - // We will need some important PZ90 ellipsoid values - PZ90Ellipsoid pz90; - const double j20( pz90.j20() ); - const double mu( pz90.gm_km() ); - const double ae( pz90.a_km() ); - - // Let's start getting the current satellite position and velocity - double x( inState(0) ); // X coordinate - //double vx( inState(1) ); // X velocity - double y( inState(2) ); // Y coordinate - //double vy( inState(3) ); // Y velocity - double z( inState(4) ); // Z coordinate - //double vz( inState(5) ); // Z velocity - - double r2( x*x + y*y + z*z ); - double r( std::sqrt(r2) ); - double xmu( mu/r2 ); - double rho( ae/r ); - double xr( x/r ); - double yr( y/r ); - double zr( z/r ); - double zr2( zr*zr ); - double k1(j20*xmu*1.5*rho*rho); - double cm( k1*(1.0-5.0*zr2) ); - double cmz( k1*(3.0-5.0*zr2) ); - double k2(cm-xmu); - - double gloAx( k2*xr + accel(0) ); - double gloAy( k2*yr + accel(1) ); - double gloAz( (cmz-xmu)*zr + accel(2) ); - - Vector dxt(6, 0.0); - - // Let's insert data related to X coordinates - dxt(0) = inState(1); // Set X' = Vx - dxt(1) = gloAx; // Set Vx' = gloAx - - // Let's insert data related to Y coordinates - dxt(2) = inState(3); // Set Y' = Vy - dxt(3) = gloAy; // Set Vy' = gloAy - - // Let's insert data related to Z coordinates - dxt(4) = inState(5); // Set Z' = Vz - dxt(5) = gloAz; // Set Vz' = gloAz - - return dxt; - - } // End of method 'GloEphemeris::derivative()' - - - // Output the contents of this ephemeris to the given stream. - std::ostream& operator<<( std::ostream& s, const GloEphemeris& glo ) - { - - glo.dump(s); - return s; - - } // End of 'std::ostream& operator<<()' - - -} // End of namespace gnsstk diff --git a/core/lib/GNSSEph/GloEphemeris.hpp b/core/lib/GNSSEph/GloEphemeris.hpp deleted file mode 100644 index 7060a59a3..000000000 --- a/core/lib/GNSSEph/GloEphemeris.hpp +++ /dev/null @@ -1,271 +0,0 @@ -//============================================================================== -// -// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. -// -// The GNSSTk is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published -// by the Free Software Foundation; either version 3.0 of the License, or -// any later version. -// -// The GNSSTk is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with GNSSTk; if not, write to the Free Software Foundation, -// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA -// -// This software was developed by Applied Research Laboratories at the -// University of Texas at Austin. -// Copyright 2004-2022, The Board of Regents of The University of Texas System -// -//============================================================================== - -//============================================================================== -// -// This software was developed by Applied Research Laboratories at the -// University of Texas at Austin, under contract to an agency or agencies -// within the U.S. Department of Defense. The U.S. Government retains all -// rights to use, duplicate, distribute, disclose, or release this software. -// -// Pursuant to DoD Directive 523024 -// -// DISTRIBUTION STATEMENT A: This software has been approved for public -// release, distribution is unlimited. -// -//============================================================================== - -/// @file GloEphemeris.hpp -/// Ephemeris data for GLONASS. - -#ifndef GNSSTK_GLOEPHEMERIS_HPP -#define GNSSTK_GLOEPHEMERIS_HPP - -#include -#include "Triple.hpp" -#include "Xvt.hpp" -#include "CommonTime.hpp" -#include "PZ90Ellipsoid.hpp" -#include "Vector.hpp" -#include "YDSTime.hpp" - -namespace gnsstk -{ - - /// @ingroup GNSSEph - //@{ - - /** - * Ephemeris information for a single GLONASS satellite. This class - * encapsulates the ephemeris navigation message and provides functions - * to handle the ephemerides. - */ - class GloEphemeris : public Xvt - { - public: - - /// Default constructor - GloEphemeris() - : valid(false), step(1.0) - {}; - - - /// Destructor. - virtual ~GloEphemeris() {}; - - - /// Query the presence of data in this object. - bool isValid(short subframe) const - { return valid; }; - - - /** Compute satellite position & velocity at the given time - * using this ephemeris data. - * - * @param epoch Epoch to compute position and velocity. - * - * @throw InvalidRequest if required data has not been stored. - */ - Xvt svXvt(const CommonTime& epoch) const; - - /** Compute satellite position & velocity at the given time - * using this ephemeris data. HOWEVER, DO NOT check whether - * the requested time is in the fit interval for this data set. - * - * THIS IS ONLY INTENDED FOR SPECIAL TEST PURPOSES. GENERAL - * USE IS STRONGLY DISCOURAGED. - * - * @param epoch Epoch to compute position and velocity. - * - */ - Xvt svXvtOverrideFit(const CommonTime& epoch) const; - - /** Get the epoch time for this ephemeris - * @throw InvalidRequest - */ - CommonTime getEphemerisEpoch() const; - - - /** Get the epoch time for this ephemeris - * @throw InvalidRequest - */ - CommonTime getEpochTime() const - { return getEphemerisEpoch(); }; - - - /** This functions returns the GNSS type (satellite system code) */ - std::string getSatSys() const - noexcept - { return satSys; }; - - - /** This function returns the PRN ID of the SV. - * @throw InvalidRequest - */ - short getPRNID() const; - - - /** Compute the satellite clock bias (sec) at the given time - * - * @param epoch Epoch to compute satellite clock bias. - * - * @throw InvalidRequest if required data has not been stored. - */ - double svClockBias(const CommonTime& epoch) const; - - - /** Compute the satellite clock drift (sec/sec) at the given time - * - * @param t Epoch to compute satellite clock drift. - * - * @throw InvalidRequest if required data has not been stored. - */ - double svClockDrift(const CommonTime& t) const; - - - /// Get integration step for Runge-Kutta algorithm. - double getIntegrationStep() const - { return step; }; - - - /** Set integration step for Runge-Kutta algorithm. - * - * @param rkStep Runge-Kutta integration step in seconds. - */ - GloEphemeris& setIntegrationStep( double rkStep ) - { step = rkStep; return (*this); }; - - - /// Get the acceleration vector. - Triple getAcc() const - noexcept - { return a; } - - - /// Get the TauN parameter. - double getTauN() const - noexcept - { return clkbias; } - - - /// Get the GammaN parameter. - double getGammaN() const - noexcept - { return clkdrift; } - - - /// Get the MFTime parameter. - long getMFtime() const - noexcept - { return MFtime; } - - - /// Get the health value parameter. - short getHealth() const - noexcept - { return health; } - - - /// Get the frequency number. - short getfreqNum() const - noexcept - { return freqNum; } - - - /// Get the age of the information. - double getAgeOfInfo() const - noexcept - { return ageOfInfo; } - - - /// Output the contents of this ephemeris to the given stream. - void dump(std::ostream& s = std::cout) const - noexcept; - - void prettyDump(std::ostream& s) const; - void terseDump(std::ostream& s) const; - void terseHeader(std::ostream& s) const; - - /// Set the parameters for this ephemeris object. - GloEphemeris& setRecord( std::string svSys, - short prn, - const CommonTime& epoch, - Triple pos, - Triple vel, - Triple acc, - double clkbias, - double clkdrift, - long mftime, - short h, - short freqnum, - double ageofinfo, - double rkStep = 1.0 ); - - - protected: - - - std::string satSys; ///< GNSS (satellite system) - short PRNID; ///< SV PRN ID - CommonTime ephTime; ///< Epoch for this ephemeris - Triple a; ///< SV acceleration (x,y,z), Earth-fixed [meters] - long MFtime; ///< Message frame time [sec of UTC week] - short health; ///< SV health - short freqNum; ///< Frequency (channel) number (-7..+12) - double ageOfInfo; ///< Age of oper. information [days] - - - private: - - - /// Flag indicating that this object has valid data. - bool valid; - - - /// Integration step for Runge-Kutta algorithm (1 second by default) - double step; - - - /// Compute true sidereal time (in hours) at Greenwich at 0 hours UT. - double getSidTime( const CommonTime& time ) const; - - - /// Function implementing the derivative of GLONASS orbital model. - Vector derivative( const Vector& inState, - const Vector& accel ) const; - - - - - /// Output the contents of this ephemeris to the given stream. - friend std::ostream& operator<<( std::ostream& s, - const GloEphemeris& glo ); - - }; // End of class 'GloEphemeris' - - //@} - -} // End of namespace gnsstk - -#endif // GNSSTK_GLOEPHEMERIS_HPP diff --git a/core/lib/NewNav/BDSD1NavData.cpp b/core/lib/NewNav/BDSD1NavData.cpp index ba359d1dc..336b95fdf 100644 --- a/core/lib/NewNav/BDSD1NavData.cpp +++ b/core/lib/NewNav/BDSD1NavData.cpp @@ -49,7 +49,7 @@ namespace gnsstk sow(0) { weekFmt = "%4D(%4e)"; - frame = ReferenceFrame::CGCS2000; + frame = RefFrameSys::CGCS2000; } diff --git a/core/lib/NewNav/BDSD2NavData.cpp b/core/lib/NewNav/BDSD2NavData.cpp index 82357bf06..4a8eb7719 100644 --- a/core/lib/NewNav/BDSD2NavData.cpp +++ b/core/lib/NewNav/BDSD2NavData.cpp @@ -48,7 +48,7 @@ namespace gnsstk sow(0) { weekFmt = "%4D(%4e)"; - frame = ReferenceFrame::CGCS2000; + frame = RefFrameSys::CGCS2000; } diff --git a/core/lib/NewNav/BDSD2NavEph.cpp b/core/lib/NewNav/BDSD2NavEph.cpp index b860a8b8e..971b68166 100644 --- a/core/lib/NewNav/BDSD2NavEph.cpp +++ b/core/lib/NewNav/BDSD2NavEph.cpp @@ -129,8 +129,7 @@ namespace gnsstk xvt.relcorr = svRelativity(when); xvt.clkbias = svClockBias(when); xvt.clkdrift = svClockDrift(when); - // This appears to be only a string for naming - xvt.frame = ReferenceFrame::CGCS2000; + xvt.frame = RefFrame(frame, when); // Compute true anomaly q = SQRT( 1.0e0 - lecc*lecc); diff --git a/core/lib/NewNav/GLOCNavAlm.hpp b/core/lib/NewNav/GLOCNavAlm.hpp index 5ef208032..df2e21d42 100644 --- a/core/lib/NewNav/GLOCNavAlm.hpp +++ b/core/lib/NewNav/GLOCNavAlm.hpp @@ -287,8 +287,9 @@ namespace gnsstk * @pre r must be set * @pre lambda must be set * @pre u must be set - * @pre i must be set */ - inline Xvt getXvt(); + * @pre i must be set + * @param[in] toi The time at which the Xvt is being computed. */ + inline Xvt getXvt(const gnsstk::CommonTime& toi); private: double E; ///< Eccentric anomaly double epsilon; ///< epsilon prime, eccentricity. diff --git a/core/lib/NewNav/GLOCNavAlmCorrected.hpp b/core/lib/NewNav/GLOCNavAlmCorrected.hpp index a54fe8193..f879ec7a9 100644 --- a/core/lib/NewNav/GLOCNavAlmCorrected.hpp +++ b/core/lib/NewNav/GLOCNavAlmCorrected.hpp @@ -68,7 +68,7 @@ namespace gnsstk inline Xvt GLOCNavAlm::Corrected :: - getXvt() + getXvt(const gnsstk::CommonTime& toi) { Xvt rv; double xterm = cos(lambda)*cos(u) - sin(lambda)*sin(u)*cos(i); @@ -91,7 +91,7 @@ namespace gnsstk rv.v[0] *= 1000.0; rv.v[1] *= 1000.0; rv.v[2] *= 1000.0; - rv.frame = ReferenceFrame::PZ90; + rv.frame = RefFrame(RefFrameSys::PZ90, toi); // clock bias and drift are not available (?). rv.relcorr = rv.computeRelativityCorrection(); return rv; diff --git a/core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp b/core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp index c6ae675ea..8a1503917 100644 --- a/core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp +++ b/core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp @@ -62,7 +62,7 @@ namespace gnsstk k1.setData(B, L1, uncorrected); k2.setData(B, L, uncorrected); corrected.setData(L, uncorrected, k1, k2); - return corrected.getXvt(); + return corrected.getXvt(toi); } diff --git a/core/lib/NewNav/GLOCNavEph.cpp b/core/lib/NewNav/GLOCNavEph.cpp index 5e40ba4aa..c3dec0a0c 100644 --- a/core/lib/NewNav/GLOCNavEph.cpp +++ b/core/lib/NewNav/GLOCNavEph.cpp @@ -102,7 +102,7 @@ namespace gnsstk // Added negation here to match the SP3 sign xvt.clkbias = -(clkBias + freqBias * (when - Toe) - xvt.relcorr); xvt.clkdrift = freqBias; - xvt.frame = ReferenceFrame::PZ90; + xvt.frame = RefFrame(RefFrameSys::PZ90, when); xvt.health = toXvtHealth(header.health); return true; } @@ -186,7 +186,7 @@ namespace gnsstk // Added negation here to match the SP3 sign xvt.clkbias = -(clkBias + freqBias * (when - Toe) - xvt.relcorr); xvt.clkdrift = freqBias; - xvt.frame = ReferenceFrame::PZ90; + xvt.frame = RefFrame(RefFrameSys::PZ90, when); xvt.health = toXvtHealth(header.health); return true; } diff --git a/core/lib/NewNav/GLOFNavAlm.cpp b/core/lib/NewNav/GLOFNavAlm.cpp index b8080a362..79bc94184 100644 --- a/core/lib/NewNav/GLOFNavAlm.cpp +++ b/core/lib/NewNav/GLOFNavAlm.cpp @@ -579,7 +579,7 @@ namespace gnsstk xvt.v[0] *= 1000.0; xvt.v[1] *= 1000.0; xvt.v[2] *= 1000.0; - xvt.frame = ReferenceFrame::PZ90; + xvt.frame = RefFrame(RefFrameSys::PZ90, when); // clock bias and drift are not available (?). xvt.relcorr = xvt.computeRelativityCorrection(); return true; diff --git a/core/lib/NewNav/GLOFNavEph.cpp b/core/lib/NewNav/GLOFNavEph.cpp index 6064642b7..4d00f15c2 100644 --- a/core/lib/NewNav/GLOFNavEph.cpp +++ b/core/lib/NewNav/GLOFNavEph.cpp @@ -95,7 +95,7 @@ namespace gnsstk // Added negation here to match the SP3 sign xvt.clkbias = -(clkBias + freqBias * (when - Toe) - xvt.relcorr); xvt.clkdrift = freqBias; - xvt.frame = ReferenceFrame::PZ90; + xvt.frame = RefFrame(RefFrameSys::PZ90, when); xvt.health = toXvtHealth(health); return true; } @@ -167,7 +167,7 @@ namespace gnsstk // Added negation here to match the SP3 sign xvt.clkbias = -(clkBias + freqBias * (when - Toe) - xvt.relcorr); xvt.clkdrift = freqBias; - xvt.frame = ReferenceFrame::PZ90; + xvt.frame = RefFrame(RefFrameSys::PZ90, when); xvt.health = toXvtHealth(health); return true; } diff --git a/core/lib/NewNav/GalFNavAlm.cpp b/core/lib/NewNav/GalFNavAlm.cpp index 2dc4e98e1..0820018b1 100644 --- a/core/lib/NewNav/GalFNavAlm.cpp +++ b/core/lib/NewNav/GalFNavAlm.cpp @@ -61,7 +61,7 @@ namespace gnsstk // Galileo F/NAV nominal page transmit time is 10 seconds per // OS-SIS-ICD figure 14. msgLenSec = 10.0; - frame = ReferenceFrame::ITRF; + frame = RefFrameSys::ITRF; } diff --git a/core/lib/NewNav/GalFNavEph.cpp b/core/lib/NewNav/GalFNavEph.cpp index 8b167bfa8..5f1edccb9 100644 --- a/core/lib/NewNav/GalFNavEph.cpp +++ b/core/lib/NewNav/GalFNavEph.cpp @@ -60,7 +60,7 @@ namespace gnsstk signal.messageType = NavMessageType::Ephemeris; weekFmt = "%4L(%4l)"; msgLenSec = 10.0; - frame = ReferenceFrame::ITRF; + frame = RefFrameSys::ITRF; } diff --git a/core/lib/NewNav/GalINavAlm.cpp b/core/lib/NewNav/GalINavAlm.cpp index ee8d090b0..39400915f 100644 --- a/core/lib/NewNav/GalINavAlm.cpp +++ b/core/lib/NewNav/GalINavAlm.cpp @@ -63,7 +63,7 @@ namespace gnsstk // instead as there is no guarantee that the two word types // making up this almanac are consecutive. msgLenSec = 2.0; - frame = ReferenceFrame::ITRF; + frame = RefFrameSys::ITRF; } diff --git a/core/lib/NewNav/GalINavEph.cpp b/core/lib/NewNav/GalINavEph.cpp index 2a4b49a3d..6b957bf10 100644 --- a/core/lib/NewNav/GalINavEph.cpp +++ b/core/lib/NewNav/GalINavEph.cpp @@ -64,7 +64,7 @@ namespace gnsstk // instead as there is no guarantee that the two word types // making up this ephemeris are consecutive. msgLenSec = 2.0; - frame = ReferenceFrame::ITRF; + frame = RefFrameSys::ITRF; } diff --git a/core/lib/NewNav/OrbitDataKepler.cpp b/core/lib/NewNav/OrbitDataKepler.cpp index bda7aaf85..f62556a4f 100644 --- a/core/lib/NewNav/OrbitDataKepler.cpp +++ b/core/lib/NewNav/OrbitDataKepler.cpp @@ -52,7 +52,7 @@ namespace gnsstk dn(0.0), dndot(0.0), ecc(0.0), A(0.0), Ahalf(0.0), Adot(0.0), OMEGA0(0.0), i0(0.0), w(0.0), OMEGAdot(0.0), idot(0.0), af0(0.0), af1(0.0), af2(0.0), health(SVHealth::Unknown), - frame(ReferenceFrame::WGS84) + frame(RefFrameSys::WGS84) { } @@ -225,8 +225,7 @@ namespace gnsstk xvt.relcorr = svRelativity(when, ell); xvt.clkbias = svClockBias(when); xvt.clkdrift = svClockDrift(when); - // This appears to be only a string for naming - xvt.frame = ReferenceFrame::WGS84; + xvt.frame = RefFrame(frame, when); // Compute true anomaly q = SQRT( 1.0e0 - lecc*lecc); @@ -307,7 +306,6 @@ namespace gnsstk xvt.v[1] = vyef; xvt.v[2] = vzef; xvt.health = toXvtHealth(health); - xvt.frame = frame; return true; } diff --git a/core/lib/NewNav/OrbitDataKepler.hpp b/core/lib/NewNav/OrbitDataKepler.hpp index 7fb77e2e1..c2a5e6c73 100644 --- a/core/lib/NewNav/OrbitDataKepler.hpp +++ b/core/lib/NewNav/OrbitDataKepler.hpp @@ -196,7 +196,10 @@ namespace gnsstk double af1; ///< SV clock drift (sec/sec) double af2; ///< SV clock drift rate (sec/sec**2) - ReferenceFrame frame;///< Reference frame of produced Xvt data. + /** Reference frame system of produced Xvt data. This is + * used in combination with the Xvt time to properly set the + * Xvt RefFrame. */ + RefFrameSys frame; }; //@} diff --git a/core/lib/NewNav/OrbitDataSP3.cpp b/core/lib/NewNav/OrbitDataSP3.cpp index b188429cc..2a9513fd8 100644 --- a/core/lib/NewNav/OrbitDataSP3.cpp +++ b/core/lib/NewNav/OrbitDataSP3.cpp @@ -48,7 +48,7 @@ namespace gnsstk vel(0.0, 0.0, 0.0), velSig(0.0, 0.0, 0.0), acc(0.0, 0.0, 0.0), accSig(0.0, 0.0, 0.0), clkBias(0.0), biasSig(0.0), clkDrift(0.0), driftSig(0.0), - clkDrRate(0.0), drRateSig(0.0), frame(ReferenceFrame::Unknown) + clkDrRate(0.0), drRateSig(0.0) { signal.messageType = NavMessageType::Ephemeris; } diff --git a/core/lib/NewNav/OrbitDataSP3.hpp b/core/lib/NewNav/OrbitDataSP3.hpp index ace101604..5425c7d75 100644 --- a/core/lib/NewNav/OrbitDataSP3.hpp +++ b/core/lib/NewNav/OrbitDataSP3.hpp @@ -102,7 +102,7 @@ namespace gnsstk /// Copy of SP3Header::coordSystem since it might not translate. std::string coordSystem; /// Translation of coordSystem into an enum, if possible. - ReferenceFrame frame; + RefFrame frame; }; //@} diff --git a/core/lib/NewNav/SP3NavDataFactory.cpp b/core/lib/NewNav/SP3NavDataFactory.cpp index d1beab0ee..4da74cd1c 100644 --- a/core/lib/NewNav/SP3NavDataFactory.cpp +++ b/core/lib/NewNav/SP3NavDataFactory.cpp @@ -566,6 +566,7 @@ namespace gnsstk process(const std::string& filename, NavDataFactoryCallback& cb) { + DEBUGTRACE_FUNCTION(); bool rv = true; bool processEph = (procNavTypes.count(NavMessageType::Ephemeris) > 0); bool processClk = (procNavTypes.count(NavMessageType::Clock) > 0); @@ -890,8 +891,10 @@ namespace gnsstk break; } gps->coordSystem = head.coordSystem; - gps->frame = gnsstk::StringUtils::asReferenceFrame( - gps->coordSystem); + DEBUGTRACE("setting reference frame using time " + << gnsstk::printTime(head.time,dts) << " " + << StringUtils::asString(head.timeSystem)); + gps->frame = RefFrame(gps->coordSystem, head.time); return true; } diff --git a/core/lib/RefTime/HelmertTransform.cpp b/core/lib/RefTime/HelmertTransform.cpp index e8eb801ee..99a31a33d 100644 --- a/core/lib/RefTime/HelmertTransform.cpp +++ b/core/lib/RefTime/HelmertTransform.cpp @@ -163,7 +163,7 @@ namespace gnsstk result[0] = res(0); result[1] = res(1); result[2] = res(2); - result.setReferenceFrame(toFrame); + result.setReferenceFrame(RefFrame(toFrame, epoch)); } else if (pos.getReferenceFrame() == toFrame) { @@ -178,7 +178,7 @@ namespace gnsstk result[0] = res(0); result[1] = res(1); result[2] = res(2); - result.setReferenceFrame(fromFrame); + result.setReferenceFrame(RefFrame(fromFrame, epoch)); } else { @@ -202,7 +202,7 @@ namespace gnsstk try { Position pos(vec[0],vec[1],vec[2],Position::Cartesian), res; - pos.setReferenceFrame(frame); + pos.setReferenceFrame(RefFrame(frame, epoch)); transform(pos, res); result = Vector(3); result[0] = res.X(); @@ -222,7 +222,7 @@ namespace gnsstk try { Position pos(vec, Position::Cartesian), res; - pos.setReferenceFrame(frame); + pos.setReferenceFrame(RefFrame(frame, epoch)); transform(pos, res); result[0] = res[0]; result[1] = res[1]; @@ -264,7 +264,7 @@ namespace gnsstk try { Position pos(x,y,z,Position::Cartesian), res; - pos.setReferenceFrame(frame); + pos.setReferenceFrame(RefFrame(frame, epoch)); transform(pos, res); rx = res.X(); ry = res.Y(); diff --git a/core/lib/RefTime/HelmertTransform.hpp b/core/lib/RefTime/HelmertTransform.hpp index 429663b07..9eb838030 100644 --- a/core/lib/RefTime/HelmertTransform.hpp +++ b/core/lib/RefTime/HelmertTransform.hpp @@ -57,7 +57,9 @@ namespace gnsstk * transformations between reference frames (i.e. ECEF position * coordinates). A Helmert tranformation is defined by 7 * parameters: a rotation(3), a translation(3) and scale - * factor(1). */ + * factor(1). + * @deprecated This enum is deprecated as of Dec 2022 and should + * not be used. Use TransformLibrary or HelmertTransformer instead. */ class HelmertTransform { public: @@ -241,15 +243,6 @@ namespace gnsstk }; // end class HelmertTransform - /// degrees per milliarcsecond (1e-3/3600.) - static const double DEG_PER_MAS = 2.77777777777e-7; - - /// radians per milliarcsecond - static const double RAD_PER_MAS = 4.84813681e-9; - - /// parts per billion - static const double PPB = 1.e-9; - } // end namespace gnsstk #endif diff --git a/core/lib/RefTime/ReferenceFrame.hpp b/core/lib/RefTime/ReferenceFrame.hpp index e5e571cd3..a6f564d7f 100644 --- a/core/lib/RefTime/ReferenceFrame.hpp +++ b/core/lib/RefTime/ReferenceFrame.hpp @@ -46,7 +46,9 @@ namespace gnsstk { - /// ECEF reference systems or frames. + /** ECEF reference systems or frames. + * @deprecated This enum is deprecated as of Dec 2022 and should + * not be used. Use RefFrame instead. */ enum class ReferenceFrame { // add new frames BEFORE count, then add to diff --git a/core/tests/GNSSCore/CMakeLists.txt b/core/tests/GNSSCore/CMakeLists.txt index 88af3336c..65f3f79ab 100644 --- a/core/tests/GNSSCore/CMakeLists.txt +++ b/core/tests/GNSSCore/CMakeLists.txt @@ -23,6 +23,7 @@ add_test(NAME GNSSCore_ObsIDInitializer COMMAND $) +set_property(TEST GNSSCore_Position PROPERTY LABELS Geodetic) add_executable(TropModel_T TropModel_T.cpp) target_link_libraries(TropModel_T gnsstk) @@ -35,6 +36,7 @@ add_test(NAME GNSSCore_WxObsMap COMMAND $) add_executable(Xvt_T Xvt_T.cpp) target_link_libraries(Xvt_T gnsstk) add_test(NAME GNSSCore_Xvt COMMAND $) +set_property(TEST GNSSCore_Xvt PROPERTY LABELS Geodetic) ############################################################################### add_executable(Tropdump Tropdump.cpp) @@ -164,10 +166,12 @@ add_test(NAME GNSSCore_SatMetaDataStore COMMAND $) +set_property(TEST GNSSCore_RinexObsID PROPERTY LABELS FileHandling) add_executable(RinexSatID_T RinexSatID_T.cpp) target_link_libraries(RinexSatID_T gnsstk) add_test(NAME GNSSCore_RinexSatID COMMAND $) +set_property(TEST GNSSCore_RinexSatID PROPERTY LABELS FileHandling) add_executable(SatID_T SatID_T.cpp) target_link_libraries(SatID_T gnsstk) @@ -184,14 +188,38 @@ add_test(NAME GNSSCore_FreqConv COMMAND $) add_executable(AngleReduced_T AngleReduced_T.cpp) target_link_libraries(AngleReduced_T gnsstk) add_test(NAME GNSSCore_AngleReduced COMMAND $) +set_property(TEST GNSSCore_AngleReduced PROPERTY LABELS Geodetic) add_executable(Angle_T Angle_T.cpp) target_link_libraries(Angle_T gnsstk) add_test(NAME GNSSCore_Angle COMMAND $) +set_property(TEST GNSSCore_Angle PROPERTY LABELS Geodetic) add_executable(AngleType_T AngleType_T.cpp) target_link_libraries(AngleType_T gnsstk) add_test(NAME GNSSCore_AngleType COMMAND $) +set_property(TEST GNSSCore_AngleType PROPERTY LABELS Geodetic) + +add_executable(RefFrameSys_T RefFrameSys_T.cpp) +target_link_libraries(RefFrameSys_T gnsstk) +add_test(NAME GNSSCore_RefFrameSys COMMAND $) +set_property(TEST GNSSCore_RefFrameSys PROPERTY LABELS Geodetic) + +add_executable(RefFrameRlz_T RefFrameRlz_T.cpp) +target_link_libraries(RefFrameRlz_T gnsstk) +add_test(NAME GNSSCore_RefFrameRlz COMMAND $) +set_property(TEST GNSSCore_RefFrameRlz PROPERTY LABELS Geodetic) + +add_executable(TransformLibrary_T TransformLibrary_T.cpp) +target_link_libraries(TransformLibrary_T gnsstk) +add_test(NAME GNSSCore_TransformLibrary COMMAND $) +set_property(TEST GNSSCore_TransformLibrary PROPERTY LABELS Geodetic) + +add_executable(HelmertTransformer_T HelmertTransformer_T.cpp) +target_link_libraries(HelmertTransformer_T gnsstk) +add_test(NAME GNSSCore_HelmertTransformer COMMAND $) +set_property(TEST GNSSCore_HelmertTransformer PROPERTY LABELS Geodetic) + ############################################################################### ############################################################################### diff --git a/core/tests/GNSSCore/HelmertTransformer_T.cpp b/core/tests/GNSSCore/HelmertTransformer_T.cpp new file mode 100644 index 000000000..3afb0dfa0 --- /dev/null +++ b/core/tests/GNSSCore/HelmertTransformer_T.cpp @@ -0,0 +1,358 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "HelmertTransformer.hpp" +#include "YDSTime.hpp" + +/// Gain access to protected data. +class TestClass : public gnsstk::HelmertTransformer +{ +public: + using gnsstk::HelmertTransformer::HelmertTransformer; + double getrx() const { return rotation(2,1); } + double getry() const { return rotation(0,2); } + double getrz() const { return rotation(1,0); } + double gettx() const { return translation(0); } + double getty() const { return translation(1); } + double gettz() const { return translation(2); } + double getscale() const { return scale; } + std::string getdescription() const { return description; } +}; + + +class HelmertTransformer_T +{ +public: + HelmertTransformer_T(); + unsigned constructorTest(); + unsigned transformPositionTest(); + unsigned transformVectorTest(); + unsigned transformTripleTest(); + unsigned transformXvtTest(); + unsigned transformdoubleTest(); + + gnsstk::RefFrame initialRF; + gnsstk::RefFrame finalRF; + gnsstk::HelmertTransformer uut1, uut2; + /// initial positions and transformed positions + std::vector p1, x1, p2, x2; +}; + + +HelmertTransformer_T :: +HelmertTransformer_T() + : initialRF(gnsstk::RefFrameSys::WGS84, + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)), + finalRF(gnsstk::RefFrameSys::CGCS2000, + gnsstk::YDSTime(1994,1,0,gnsstk::TimeSystem::UTC)), + uut1(initialRF, finalRF, 0, 0, 0, 10, 10, 10, 1, "hi there", + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)), + // https://d28rz98at9flks.cloudfront.net/71433/71433.pdf + uut2(initialRF, finalRF, -24.1665*gnsstk::DEG_PER_MAS, + -20.9515*gnsstk::DEG_PER_MAS, -21.3961*gnsstk::DEG_PER_MAS, + -42.7e-3, -17.06e-3, 28.81e-3, 11.474*gnsstk::PPB, "step 2", + gnsstk::YDSTime(1994, 1, 0,gnsstk::TimeSystem::UTC)), + p1({150, 150, 150}), + x1({310, 310, 310}), // 100% scale, 10m translation + p2({-4052052.3678, 4212836.0411, -2545105.1089}), + x2({-4052051.7615, 4212836.1945, -2545106.0145}) +{ +} + + +unsigned HelmertTransformer_T :: +constructorTest() +{ + TUDEF("HelmertTransformer", "HelmertTransformer"); + TestClass uut1; + gnsstk::RefFrame exp; + TUASSERTE(gnsstk::RefFrame, exp, uut1.getFromFrame()); + TUASSERTE(gnsstk::RefFrame, exp, uut1.getToFrame()); + TUASSERTE(int, 1, std::isnan(uut1.getscale())); + + TestClass uut2(gnsstk::RefFrame(gnsstk::RefFrameRlz::PZ90Y2007), + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + 1e-4, 2e-4, 3e-4, 4, 5, 6, 7, "hi there", + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::PZ90Y2007), + uut2.getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + uut2.getToFrame()); + TUASSERTFE(1e-4*gnsstk::DEG_TO_RAD, uut2.getrx()); + TUASSERTFE(2e-4*gnsstk::DEG_TO_RAD, uut2.getry()); + TUASSERTFE(3e-4*gnsstk::DEG_TO_RAD, uut2.getrz()); + TUASSERTFE(4, uut2.gettx()); + TUASSERTFE(5, uut2.getty()); + TUASSERTFE(6, uut2.gettz()); + TUASSERTFE(7, uut2.getscale()); + TUASSERTE(std::string, "hi there", uut2.getdescription()); + TUASSERTE(gnsstk::CommonTime, + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC), + uut2.getEpoch()); + TURETURN(); +} + + +unsigned HelmertTransformer_T :: +transformPositionTest() +{ + TUDEF("HelmertTransformer", "transform(Position)"); + + gnsstk::Position pos1(&p1[0], gnsstk::Position::Cartesian, nullptr, + initialRF); + gnsstk::Position exp1(&x1[0], gnsstk::Position::Cartesian, nullptr, + finalRF); + gnsstk::Position out1; + out1.setReferenceFrame(finalRF); + TUASSERTE(bool, true, uut1.transform(pos1, out1)); + TUASSERTFE(exp1.getX(), out1.getX()); + TUASSERTFE(exp1.getY(), out1.getY()); + TUASSERTFE(exp1.getZ(), out1.getZ()); + + gnsstk::Position pos2(&p2[0], gnsstk::Position::Cartesian, nullptr, + initialRF); + gnsstk::Position exp2(&x2[0], gnsstk::Position::Cartesian, nullptr, finalRF); + gnsstk::Position out2; + out2.setReferenceFrame(finalRF); + // forward transform + TUASSERTE(bool, true, uut2.transform(pos2, out2)); + TUASSERTFEPS(exp2.getX(), out2.getX(), 1e-4); + TUASSERTFEPS(exp2.getY(), out2.getY(), 1e-4); + TUASSERTFEPS(exp2.getZ(), out2.getZ(), 1e-4); + // reverse transform + out2.setReferenceFrame(initialRF); + TUASSERTE(bool, true, uut2.transform(exp2, out2)); + TUASSERTFEPS(pos2.getX(), out2.getX(), 1e-4); + TUASSERTFEPS(pos2.getY(), out2.getY(), 1e-4); + TUASSERTFEPS(pos2.getZ(), out2.getZ(), 1e-4); + + TURETURN(); +} + + +unsigned HelmertTransformer_T :: +transformVectorTest() +{ + TUDEF("HelmertTransformer", "transform(Vector)"); + + gnsstk::Vector pos1({p1[0], p1[1], p1[2]}); + gnsstk::Vector exp1({x1[0], x1[1], x1[2]}); + gnsstk::Vector out1; + TUASSERTE(bool, true, uut1.transform(pos1, initialRF, out1)); + TUASSERTFE(exp1[0], out1[0]); + TUASSERTFE(exp1[1], out1[1]); + TUASSERTFE(exp1[2], out1[2]); + + gnsstk::Vector pos2({p2[0], p2[1], p2[2]}); + gnsstk::Vector exp2({x2[0], x2[1], x2[2]}); + gnsstk::Vector out2; + // forward transform + TUASSERTE(bool, true, uut2.transform(pos2, initialRF, out2)); + TUASSERTFEPS(exp2[0], out2[0], 1e-4); + TUASSERTFEPS(exp2[1], out2[1], 1e-4); + TUASSERTFEPS(exp2[2], out2[2], 1e-4); + // reverse transform + TUASSERTE(bool, true, uut2.transform(exp2, finalRF, out2)); + TUASSERTFEPS(pos2[0], out2[0], 1e-4); + TUASSERTFEPS(pos2[1], out2[1], 1e-4); + TUASSERTFEPS(pos2[2], out2[2], 1e-4); + + TURETURN(); +} + + +unsigned HelmertTransformer_T :: +transformTripleTest() +{ + TUDEF("HelmertTransformer", "transform(Triple)"); + + gnsstk::Triple pos1({p1[0], p1[1], p1[2]}); + gnsstk::Triple exp1({x1[0], x1[1], x1[2]}); + gnsstk::Triple out1; + TUASSERTE(bool, true, uut1.transform(pos1, initialRF, out1)); + TUASSERTFE(exp1[0], out1[0]); + TUASSERTFE(exp1[1], out1[1]); + TUASSERTFE(exp1[2], out1[2]); + + gnsstk::Triple pos2({p2[0], p2[1], p2[2]}); + gnsstk::Triple exp2({x2[0], x2[1], x2[2]}); + gnsstk::Triple out2; + // forward transform + TUASSERTE(bool, true, uut2.transform(pos2, initialRF, out2)); + TUASSERTFEPS(exp2[0], out2[0], 1e-4); + TUASSERTFEPS(exp2[1], out2[1], 1e-4); + TUASSERTFEPS(exp2[2], out2[2], 1e-4); + // reverse transform + TUASSERTE(bool, true, uut2.transform(exp2, finalRF, out2)); + TUASSERTFEPS(pos2[0], out2[0], 1e-4); + TUASSERTFEPS(pos2[1], out2[1], 1e-4); + TUASSERTFEPS(pos2[2], out2[2], 1e-4); + + TURETURN(); +} + + +unsigned HelmertTransformer_T :: +transformXvtTest() +{ + TUDEF("HelmertTransformer", "transform(Xvt)"); + + gnsstk::Xvt pos1, exp1, out1; + pos1.x = gnsstk::Triple({p1[0], p1[1], p1[2]}); + pos1.v = gnsstk::Triple({1, 2, 3}); + pos1.clkbias = 4; + pos1.clkdrift = 5; + pos1.relcorr = 6; + pos1.frame = initialRF; + pos1.health = gnsstk::Xvt::Degraded; + out1.frame = finalRF; + exp1.x = gnsstk::Triple({x1[0], x1[1], x1[2]}); + exp1.v = gnsstk::Triple({1, 2, 3}); + exp1.clkbias = 4; + exp1.clkdrift = 5; + exp1.relcorr = 6; + exp1.frame = finalRF; + exp1.health = gnsstk::Xvt::Degraded; + TUASSERTE(bool, true, uut1.transform(pos1, out1)); + TUASSERTFE(exp1.x[0], out1.x[0]); + TUASSERTFE(exp1.x[1], out1.x[1]); + TUASSERTFE(exp1.x[2], out1.x[2]); + TUASSERTFE(exp1.v[0], out1.v[0]); + TUASSERTFE(exp1.v[1], out1.v[1]); + TUASSERTFE(exp1.v[2], out1.v[2]); + TUASSERTFE(exp1.clkbias, out1.clkbias); + TUASSERTFE(exp1.clkdrift, out1.clkdrift); + TUASSERTFE(exp1.relcorr, out1.relcorr); + TUASSERTE(gnsstk::RefFrame, exp1.frame, out1.frame); + TUASSERTE(gnsstk::Xvt::HealthStatus, exp1.health, out1.health); + + gnsstk::Xvt pos2, exp2, out2; + pos2.x = gnsstk::Triple({p2[0], p2[1], p2[2]}); + pos2.v = gnsstk::Triple({1, 2, 3}); + pos2.clkbias = 4; + pos2.clkdrift = 5; + pos2.relcorr = 6; + pos2.frame = initialRF; + pos2.health = gnsstk::Xvt::Degraded; + out2.frame = finalRF; + exp2.x = gnsstk::Triple({x2[0], x2[1], x2[2]}); + exp2.v = gnsstk::Triple({1, 2, 3}); + exp2.clkbias = 4; + exp2.clkdrift = 5; + exp2.relcorr = 6; + exp2.frame = finalRF; + exp2.health = gnsstk::Xvt::Degraded; + // forward transform + TUASSERTE(bool, true, uut2.transform(pos2, out2)); + TUASSERTFEPS(exp2.x[0], out2.x[0], 1e-4); + TUASSERTFEPS(exp2.x[1], out2.x[1], 1e-4); + TUASSERTFEPS(exp2.x[2], out2.x[2], 1e-4); + TUASSERTFEPS(exp2.v[0], out2.v[0], 1e-4); + TUASSERTFEPS(exp2.v[1], out2.v[1], 1e-4); + TUASSERTFEPS(exp2.v[2], out2.v[2], 1e-4); + TUASSERTFE(exp2.clkbias, out2.clkbias); + TUASSERTFE(exp2.clkdrift, out2.clkdrift); + TUASSERTFE(exp2.relcorr, out2.relcorr); + TUASSERTE(gnsstk::RefFrame, exp2.frame, out2.frame); + TUASSERTE(gnsstk::Xvt::HealthStatus, exp2.health, out2.health); + // reverse transform + out2.frame = initialRF; + TUASSERTE(bool, true, uut2.transform(exp2, out2)); + TUASSERTFEPS(pos2.x[0], out2.x[0], 1e-4); + TUASSERTFEPS(pos2.x[1], out2.x[1], 1e-4); + TUASSERTFEPS(pos2.x[2], out2.x[2], 1e-4); + TUASSERTFEPS(pos2.v[0], out2.v[0], 1e-4); + TUASSERTFEPS(pos2.v[1], out2.v[1], 1e-4); + TUASSERTFEPS(pos2.v[2], out2.v[2], 1e-4); + TUASSERTFE(pos2.clkbias, out2.clkbias); + TUASSERTFE(pos2.clkdrift, out2.clkdrift); + TUASSERTFE(pos2.relcorr, out2.relcorr); + TUASSERTE(gnsstk::RefFrame, pos2.frame, out2.frame); + TUASSERTE(gnsstk::Xvt::HealthStatus, pos2.health, out2.health); + + TURETURN(); +} + + +unsigned HelmertTransformer_T :: +transformdoubleTest() +{ + TUDEF("HelmertTransformer", "transform(double)"); + + double out1x, out1y, out1z; + TUASSERTE(bool, true, uut1.transform(p1[0], p1[1], p1[2], initialRF, out1x, out1y, out1z)); + TUASSERTFE(x1[0], out1x); + TUASSERTFE(x1[1], out1y); + TUASSERTFE(x1[2], out1z); + + double out2x, out2y, out2z; + // forward transform + TUASSERTE(bool, true, uut2.transform(p2[0], p2[1], p2[2], initialRF, out2x, out2y, out2z)); + TUASSERTFEPS(x2[0], out2x, 1e-4); + TUASSERTFEPS(x2[1], out2y, 1e-4); + TUASSERTFEPS(x2[2], out2z, 1e-4); + // reverse transform + TUASSERTE(bool, true, uut2.transform(x2[0], x2[1], x2[2], finalRF, out2x, out2y, out2z)); + TUASSERTFEPS(p2[0], out2x, 1e-4); + TUASSERTFEPS(p2[1], out2y, 1e-4); + TUASSERTFEPS(p2[2], out2z, 1e-4); + + TURETURN(); +} + + +int main() +{ + HelmertTransformer_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.transformPositionTest(); + errorTotal += testClass.transformVectorTest(); + errorTotal += testClass.transformTripleTest(); + errorTotal += testClass.transformXvtTest(); + errorTotal += testClass.transformdoubleTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/RefFrameRlz_T.cpp b/core/tests/GNSSCore/RefFrameRlz_T.cpp new file mode 100644 index 000000000..ae4bcb2da --- /dev/null +++ b/core/tests/GNSSCore/RefFrameRlz_T.cpp @@ -0,0 +1,204 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include +#include "RefFrameRlz.hpp" +#include "GPSWeekSecond.hpp" +#include "YDSTime.hpp" +#include "TestUtil.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, gnsstk::RefFrameRlz e) + { + s << StringUtils::asString(e) << "(" << (int)e << ")"; + return s; + } + std::ostream& operator<<(std::ostream& s, gnsstk::RefFrameSys e) + { + s << StringUtils::asString(e) << "(" << (int)e << ")"; + return s; + } +} + + +class RefFrameRlz_T +{ +public: + unsigned convertTest(); + unsigned getRefFrameSysTest(); + unsigned getRefFrameRlzTest(); +}; + + +unsigned RefFrameRlz_T :: +convertTest() +{ + TUDEF("RefFrameRlz", "asString"); + // This effectively tests RefFrameRlzIterator, and asRefFrameRlz + // all at once. + for (gnsstk::RefFrameRlz e : gnsstk::RefFrameRlzIterator()) + { + TUCSM("asString"); + std::string s(gnsstk::StringUtils::asString(e)); + TUASSERT(!s.empty()); + TUASSERT(s != "???"); + TUCSM("asRefFrameRlz"); + gnsstk::RefFrameRlz e2 = gnsstk::StringUtils::asRefFrameRlz(s); + TUASSERTE(gnsstk::RefFrameRlz, e, e2); + } + TURETURN(); +} + + +unsigned RefFrameRlz_T :: +getRefFrameSysTest() +{ + TUDEF("RefFrameRlz", "getRefFrameSys"); + // make sure they all have a valid system + for (gnsstk::RefFrameRlz i : gnsstk::RefFrameRlzIterator()) + { + if (i == gnsstk::RefFrameRlz::Unknown) + { + TUASSERTE(gnsstk::RefFrameSys, gnsstk::RefFrameSys::Unknown, + getRefFrameSys(i)); + } + else + { + TUASSERT(getRefFrameSys(i) != gnsstk::RefFrameSys::Unknown); + } + } + // Now test the ones we know about (which could get added to, + // which is why we test the above separately). + for (gnsstk::RefFrameRlz i : gnsstk::EnumIterator()) + { + TUASSERTE(gnsstk::RefFrameSys, gnsstk::RefFrameSys::WGS84, + getRefFrameSys(i)); + } + for (gnsstk::RefFrameRlz i : gnsstk::EnumIterator()) + { + TUASSERTE(gnsstk::RefFrameSys, gnsstk::RefFrameSys::ITRF, + getRefFrameSys(i)); + } + for (gnsstk::RefFrameRlz i : gnsstk::EnumIterator()) + { + TUASSERTE(gnsstk::RefFrameSys, gnsstk::RefFrameSys::PZ90, + getRefFrameSys(i)); + } + for (gnsstk::RefFrameRlz i : gnsstk::EnumIterator()) + { + TUASSERTE(gnsstk::RefFrameSys, gnsstk::RefFrameSys::CGCS2000, + getRefFrameSys(i)); + } + TURETURN(); +} + + +unsigned RefFrameRlz_T :: +getRefFrameRlzTest() +{ + TUDEF("RefFrameRlz", "getRefFrameRlzTest"); + typedef std::pair InpPair; + typedef std::map ExpMap; + gnsstk::TimeSystem ts(gnsstk::TimeSystem::UTC); // short alias. + ExpMap inOutMap + {{InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(0,0,ts)), + gnsstk::RefFrameRlz::WGS84G0}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(730,0,ts)), + gnsstk::RefFrameRlz::WGS84G730}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(873,0,ts)), + gnsstk::RefFrameRlz::WGS84G873}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(1150,0,ts)), + gnsstk::RefFrameRlz::WGS84G1150}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(1674,0,ts)), + gnsstk::RefFrameRlz::WGS84G1674}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(1762,0,ts)), + gnsstk::RefFrameRlz::WGS84G1762}, + {InpPair(gnsstk::RefFrameSys::WGS84,gnsstk::GPSWeekSecond(2139,0,ts)), + gnsstk::RefFrameRlz::WGS84G2139}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(1994,1,0,ts)), + gnsstk::RefFrameRlz::ITRF94}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(1996,1,0,ts)), + gnsstk::RefFrameRlz::ITRF96}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(1997,1,0,ts)), + gnsstk::RefFrameRlz::ITRF97}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(2000,1,0,ts)), + gnsstk::RefFrameRlz::ITRF2000}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(2005,1,0,ts)), + gnsstk::RefFrameRlz::ITRF2005}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(2008,1,0,ts)), + gnsstk::RefFrameRlz::ITRF2008}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(2014,1,0,ts)), + gnsstk::RefFrameRlz::ITRF2014}, + {InpPair(gnsstk::RefFrameSys::ITRF,gnsstk::YDSTime(2020,1,0,ts)), + gnsstk::RefFrameRlz::ITRF2020}, + {InpPair(gnsstk::RefFrameSys::PZ90,gnsstk::YDSTime(2006,1,0,ts)), + gnsstk::RefFrameRlz::PZ90KGS}, + {InpPair(gnsstk::RefFrameSys::PZ90,gnsstk::YDSTime(2007,263,61200,ts)), + gnsstk::RefFrameRlz::PZ90Y2007}, + {InpPair(gnsstk::RefFrameSys::CGCS2000,gnsstk::YDSTime(2022,364,0,ts)), + gnsstk::RefFrameRlz::CGCS2000Y2008}, + }; + + for (const auto& emi : inOutMap) + { + TUASSERTE(gnsstk::RefFrameRlz, emi.second, + gnsstk::getRefFrameRlz(emi.first.first, emi.first.second)); + } + TURETURN(); +} + + +int main() +{ + RefFrameRlz_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.convertTest(); + errorTotal += testClass.getRefFrameSysTest(); + errorTotal += testClass.getRefFrameRlzTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/RefFrameSys_T.cpp b/core/tests/GNSSCore/RefFrameSys_T.cpp new file mode 100644 index 000000000..342fcf41e --- /dev/null +++ b/core/tests/GNSSCore/RefFrameSys_T.cpp @@ -0,0 +1,90 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "RefFrameSys.hpp" +#include "TestUtil.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, gnsstk::RefFrameSys e) + { + s << StringUtils::asString(e) << "(" << (int)e << ")"; + return s; + } +} + + +class RefFrameSys_T +{ +public: + unsigned convertTest(); +}; + + +unsigned RefFrameSys_T :: +convertTest() +{ + TUDEF("RefFrameSys", "asString"); + // This effectively tests RefFrameSysIterator, asString and + // asRefFrameSys all at once. + for (gnsstk::RefFrameSys e : gnsstk::RefFrameSysIterator()) + { + TUCSM("asString"); + std::string s(gnsstk::StringUtils::asString(e)); + TUASSERT(!s.empty()); + TUASSERT(s != "???"); + TUCSM("asRefFrameSys"); + gnsstk::RefFrameSys e2 = gnsstk::StringUtils::asRefFrameSys(s); + TUASSERTE(gnsstk::RefFrameSys, e, e2); + } + TURETURN(); +} + + +int main() +{ + RefFrameSys_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.convertTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/TransformLibrary_T.cpp b/core/tests/GNSSCore/TransformLibrary_T.cpp new file mode 100644 index 000000000..ada9ae1de --- /dev/null +++ b/core/tests/GNSSCore/TransformLibrary_T.cpp @@ -0,0 +1,377 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "TransformLibrary.hpp" +#include "HelmertTransformer.hpp" +#include "YDSTime.hpp" +#include "TimeString.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, const Transformer& t) + { + s << "Transformer " << StringUtils::asString(t.getFromFrame()) << " -> " + << StringUtils::asString(t.getToFrame()) << " : " + << printTime(t.getEpoch(), "%Y/%03j/%05s") << std::endl; + return s; + } +} + + +/// Something to put into a TransformLibrary without any overhead. +class FakeTransformer : public gnsstk::Transformer +{ +public: + FakeTransformer(gnsstk::RefFrameRlz fromRlz, gnsstk::RefFrameRlz toRlz) + { + fromFrame = gnsstk::RefFrame(fromRlz); + toFrame = gnsstk::RefFrame(toRlz); + } + FakeTransformer(gnsstk::RefFrameRlz fromRlz, gnsstk::RefFrameRlz toRlz, + const gnsstk::CommonTime& start) + { + fromFrame = gnsstk::RefFrame(fromRlz); + toFrame = gnsstk::RefFrame(toRlz); + epoch = start; + } + bool transform(const gnsstk::Position& fromPos, gnsstk::Position& toPos) + const noexcept override + { return false; } + bool transform(const gnsstk::Xvt& fromPos, gnsstk::Xvt& toPos) + const noexcept override + { return false; } + bool transform(const gnsstk::Vector& fromPos, + const gnsstk::RefFrame& srcFrame, + gnsstk::Vector& toPos) + const noexcept override + { return false; } + bool transform(const gnsstk::Triple& fromPos, + const gnsstk::RefFrame& srcFrame, + gnsstk::Triple& toPos) + const noexcept override + { return false; } + bool transform(double fx, double fy, double fz, + const gnsstk::RefFrame& srcFrame, + double& tx, double& ty, double& tz) + const noexcept override + { return false; } +}; + +class TransformLibrary_T +{ +public: + TransformLibrary_T(); + unsigned constructorTest(); + unsigned getTransformTest(); + unsigned transformPositionTest(); + unsigned transformVectorTest(); + unsigned transformTripleTest(); + unsigned transformXvtTest(); + unsigned transformdoubleTest(); + + gnsstk::YDSTime refTime1; + gnsstk::RefFrame initialRF; + gnsstk::RefFrame finalRF; + std::shared_ptr xf1; + /// initial positions and transformed positions + std::vector p1, x1; +}; + + +TransformLibrary_T :: +TransformLibrary_T() + : refTime1(2020,123,456,gnsstk::TimeSystem::UTC), + initialRF(gnsstk::RefFrameSys::WGS84, refTime1), + finalRF(gnsstk::RefFrameSys::CGCS2000, refTime1), + p1({150, 150, 150}), + x1({310, 310, 310}), // 100% scale, 10m translation + xf1(std::make_shared( + initialRF, finalRF, 0, 0, 0, 10, 10, 10, 1, "hi there", + refTime1)) +{ +} + + +unsigned TransformLibrary_T :: +constructorTest() +{ + TUDEF("TransformLibrary", "TransformLibrary"); + gnsstk::TransformLibrary uut; + TUASSERTE(bool, false, uut.transformers.empty()); + TURETURN(); +} + + +unsigned TransformLibrary_T :: +getTransformTest() +{ + TUDEF("TransformLibrary", "getTransform"); + gnsstk::TransformLibrary uut; + gnsstk::TransformerPtr optimus; + gnsstk::TimeSystem ts(gnsstk::TimeSystem::UTC); + uut.transformers.clear(); + TUCATCH(uut.addTransform(std::make_shared( + gnsstk::RefFrameRlz::WGS84G1150, + gnsstk::RefFrameRlz::PZ90KGS))); + TUCATCH(uut.addTransform(std::make_shared( + gnsstk::RefFrameRlz::WGS84G1150, + gnsstk::RefFrameRlz::ITRF2000))); + TUCATCH(uut.addTransform(std::make_shared( + gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + gnsstk::YDSTime(2020,5,0,ts)))); + TUCATCH(uut.addTransform(std::make_shared( + gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + gnsstk::YDSTime(2020,15,0,ts)))); + TUCATCH(uut.addTransform(std::make_shared( + gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + gnsstk::YDSTime(2020,95,0,ts)))); + // forward transformation search test + TUASSERTE(bool, true, + uut.getTransform(gnsstk::RefFrameRlz::WGS84G1150, + gnsstk::RefFrameRlz::ITRF2000, + optimus)); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + optimus->getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF2000), + optimus->getToFrame()); + // transformation unavailable test + TUASSERTE(bool, false, + uut.getTransform(gnsstk::RefFrameRlz::WGS84G1150, + gnsstk::RefFrameRlz::ITRF2020, + optimus)); + // reverse transformation search test + TUASSERTE(bool, true, + uut.getTransform(gnsstk::RefFrameRlz::ITRF2000, + gnsstk::RefFrameRlz::WGS84G1150, + optimus)); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + optimus->getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF2000), + optimus->getToFrame()); + // time history search test (too early) + TUASSERTE(bool, false, + uut.getTransform(gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + optimus, + gnsstk::YDSTime(1,1,0,ts))); + // time history search test (spot on) + TUASSERTE(bool, true, + uut.getTransform(gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + optimus, + gnsstk::YDSTime(2020,5,0,ts))); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF2020), + optimus->getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::PZ90Y2007), + optimus->getToFrame()); + TUASSERTE(gnsstk::CommonTime, gnsstk::YDSTime(2020,5,0,ts), + optimus->getEpoch()); + // time history search test (in between) + TUASSERTE(bool, true, + uut.getTransform(gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + optimus, + gnsstk::YDSTime(2020,7,0,ts))); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF2020), + optimus->getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::PZ90Y2007), + optimus->getToFrame()); + TUASSERTE(gnsstk::CommonTime, gnsstk::YDSTime(2020,5,0,ts), + optimus->getEpoch()); + // time history search test (late) + TUASSERTE(bool, true, + uut.getTransform(gnsstk::RefFrameRlz::ITRF2020, + gnsstk::RefFrameRlz::PZ90Y2007, + optimus, + gnsstk::YDSTime(2029,1,0,ts))); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF2020), + optimus->getFromFrame()); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::PZ90Y2007), + optimus->getToFrame()); + TUASSERTE(gnsstk::CommonTime, gnsstk::YDSTime(2020,95,0,ts), + optimus->getEpoch()); + TURETURN(); +} + + +unsigned TransformLibrary_T :: +transformPositionTest() +{ + TUDEF("TransformLibrary", "transform(Position)"); + gnsstk::TransformLibrary uut; + uut.transformers.clear(); + TUCATCH(uut.addTransform(xf1)); + gnsstk::Position pos1(&p1[0], gnsstk::Position::Cartesian, nullptr, + initialRF); + gnsstk::Position exp1(&x1[0], gnsstk::Position::Cartesian, nullptr, + finalRF); + gnsstk::Position out1; + out1.setReferenceFrame(finalRF); + TUASSERTE(bool, true, uut.transform(pos1, out1, refTime1)); + TUASSERTFE(exp1.getX(), out1.getX()); + TUASSERTFE(exp1.getY(), out1.getY()); + TUASSERTFE(exp1.getZ(), out1.getZ()); + + TURETURN(); +} + +unsigned TransformLibrary_T :: +transformVectorTest() +{ + TUDEF("TransformLibrary", "transform(Vector)"); + gnsstk::TransformLibrary uut; + uut.transformers.clear(); + TUCATCH(uut.addTransform(xf1)); + gnsstk::Vector pos1({p1[0], p1[1], p1[2]}); + gnsstk::Vector exp1({x1[0], x1[1], x1[2]}); + gnsstk::Vector out1; + TUASSERTE(bool, true, uut.transform(pos1,initialRF,out1,finalRF,refTime1)); + TUASSERTFE(exp1[0], out1[0]); + TUASSERTFE(exp1[1], out1[1]); + TUASSERTFE(exp1[2], out1[2]); + TURETURN(); +} + + +unsigned TransformLibrary_T :: +transformTripleTest() +{ + TUDEF("TransformLibrary", "transform(Triple)"); + gnsstk::TransformLibrary uut; + uut.transformers.clear(); + TUCATCH(uut.addTransform(xf1)); + gnsstk::Triple pos1({p1[0], p1[1], p1[2]}); + gnsstk::Triple exp1({x1[0], x1[1], x1[2]}); + gnsstk::Triple out1; + TUASSERTE(bool, true, uut.transform(pos1,initialRF,out1,finalRF,refTime1)); + TUASSERTFE(exp1[0], out1[0]); + TUASSERTFE(exp1[1], out1[1]); + TUASSERTFE(exp1[2], out1[2]); + TURETURN(); +} + + +unsigned TransformLibrary_T :: +transformXvtTest() +{ + TUDEF("TransformLibrary", "transform(Xvt)"); + gnsstk::TransformLibrary uut; + uut.transformers.clear(); + TUCATCH(uut.addTransform(xf1)); + gnsstk::Xvt pos1, exp1, out1; + pos1.x = gnsstk::Triple({p1[0], p1[1], p1[2]}); + pos1.v = gnsstk::Triple({1, 2, 3}); + pos1.clkbias = 4; + pos1.clkdrift = 5; + pos1.relcorr = 6; + pos1.frame = initialRF; + pos1.health = gnsstk::Xvt::Degraded; + out1.frame = finalRF; + exp1.x = gnsstk::Triple({x1[0], x1[1], x1[2]}); + exp1.v = gnsstk::Triple({1, 2, 3}); + exp1.clkbias = 4; + exp1.clkdrift = 5; + exp1.relcorr = 6; + exp1.frame = finalRF; + exp1.health = gnsstk::Xvt::Degraded; + TUASSERTE(bool, true, uut.transform(pos1, out1)); + TUASSERTFE(exp1.x[0], out1.x[0]); + TUASSERTFE(exp1.x[1], out1.x[1]); + TUASSERTFE(exp1.x[2], out1.x[2]); + TUASSERTFE(exp1.v[0], out1.v[0]); + TUASSERTFE(exp1.v[1], out1.v[1]); + TUASSERTFE(exp1.v[2], out1.v[2]); + TUASSERTFE(exp1.clkbias, out1.clkbias); + TUASSERTFE(exp1.clkdrift, out1.clkdrift); + TUASSERTFE(exp1.relcorr, out1.relcorr); + TUASSERTE(gnsstk::RefFrame, exp1.frame, out1.frame); + TUASSERTE(gnsstk::Xvt::HealthStatus, exp1.health, out1.health); + TURETURN(); +} + + +unsigned TransformLibrary_T :: +transformdoubleTest() +{ + TUDEF("TransformLibrary", "transform(double)"); + gnsstk::TransformLibrary uut; + uut.transformers.clear(); + TUCATCH(uut.addTransform(xf1)); + double out1x, out1y, out1z; + TUASSERTE(bool, true, uut.transform(p1[0], p1[1], p1[2], initialRF, + out1x, out1y, out1z, finalRF, refTime1)); + TUASSERTFE(x1[0], out1x); + TUASSERTFE(x1[1], out1y); + TUASSERTFE(x1[2], out1z); + TURETURN(); +} + + +int main() +{ + TransformLibrary_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.getTransformTest(); + errorTotal += testClass.transformPositionTest(); + errorTotal += testClass.transformVectorTest(); + errorTotal += testClass.transformTripleTest(); + errorTotal += testClass.transformXvtTest(); + errorTotal += testClass.transformdoubleTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} + diff --git a/core/tests/NewNav/BDSD1NavAlm_T.cpp b/core/tests/NewNav/BDSD1NavAlm_T.cpp index 61931a14c..78cf5bd33 100644 --- a/core/tests/NewNav/BDSD1NavAlm_T.cpp +++ b/core/tests/NewNav/BDSD1NavAlm_T.cpp @@ -113,6 +113,7 @@ getXvtTest() TUDEF("BDSD1NavAlm", "getXvt"); gnsstk::BDSD1NavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::CGCS2000Y2008); uut.xmitTime = gnsstk::BDSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::BDSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::BDT); @@ -120,7 +121,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::BDT); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::CGCS2000,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/BDSD1NavEph_T.cpp b/core/tests/NewNav/BDSD1NavEph_T.cpp index 8d5599429..26f198f87 100644 --- a/core/tests/NewNav/BDSD1NavEph_T.cpp +++ b/core/tests/NewNav/BDSD1NavEph_T.cpp @@ -168,6 +168,7 @@ getXvtTest() TUDEF("BDSD1NavEph", "getXvt"); gnsstk::BDSD1NavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::CGCS2000Y2008); uut.xmitTime = gnsstk::BDSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::BDSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::BDT); @@ -175,7 +176,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::BDT); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::CGCS2000,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/BDSD2NavAlm_T.cpp b/core/tests/NewNav/BDSD2NavAlm_T.cpp index f1524d949..f08fe36aa 100644 --- a/core/tests/NewNav/BDSD2NavAlm_T.cpp +++ b/core/tests/NewNav/BDSD2NavAlm_T.cpp @@ -113,6 +113,7 @@ getXvtTest() TUDEF("BDSD2NavAlm", "getXvt"); gnsstk::BDSD2NavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::CGCS2000Y2008); uut.xmitTime = gnsstk::BDSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::BDSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::BDT); @@ -120,7 +121,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::BDT); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::CGCS2000,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/BDSD2NavEph_T.cpp b/core/tests/NewNav/BDSD2NavEph_T.cpp index d7435e0e2..093c23106 100644 --- a/core/tests/NewNav/BDSD2NavEph_T.cpp +++ b/core/tests/NewNav/BDSD2NavEph_T.cpp @@ -155,6 +155,7 @@ getXvtTest() TUDEF("BDSD2NavEph", "getXvt"); gnsstk::BDSD2NavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::CGCS2000Y2008); uut.xmitTime = gnsstk::BDSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::BDSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::BDT); @@ -162,7 +163,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::BDT); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::CGCS2000,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GLOCNavAlm_T.cpp b/core/tests/NewNav/GLOCNavAlm_T.cpp index e77cfdeac..bdbc9c6b2 100644 --- a/core/tests/NewNav/GLOCNavAlm_T.cpp +++ b/core/tests/NewNav/GLOCNavAlm_T.cpp @@ -342,6 +342,7 @@ getXvtTest() uut.deltaT = DeltaTA; uut.deltaTdot = DeltaTdotA; uut.Toa = gnsstk::GLONASSTime(0, NA, uut.tLambda, gnsstk::TimeSystem::GLO); + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::PZ90KGS); gnsstk::Xvt xvt; TUASSERTE(bool, true, uut.getXvt(toi, xvt)); @@ -360,7 +361,7 @@ getXvtTest() TUASSERTFESMRT(clkbiasExpected, xvt.clkbias); TUASSERTFESMRT(clkdriftExpected, xvt.clkdrift); TUASSERTFESMRT(relcorrExpected, xvt.relcorr); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::PZ90,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TUASSERTFESMRT(DeltatprExpected, uut.math.Deltatpr); TUASSERTE(int, WExpected, uut.math.W); @@ -565,7 +566,9 @@ CorrectedTest() TUASSERTFESMRT(vrExpected, uut.vr); TUCSM("setData(vu)"); TUASSERTFESMRT(vuExpected, uut.vu); - gnsstk::Xvt got = uut.getXvt(); + // time is only used to figure out the ref frame + gnsstk::CivilTime dummy(2023,1,1,0,0,0,gnsstk::TimeSystem::UTC); + gnsstk::Xvt got = uut.getXvt(dummy); TUCSM("getXvt(x)"); TUASSERTFESMRT(xExpected, got.x[0]); TUCSM("getXvt(y)"); diff --git a/core/tests/NewNav/GLOFNavAlm_T.cpp b/core/tests/NewNav/GLOFNavAlm_T.cpp index 5b42b4c83..13ddff72a 100644 --- a/core/tests/NewNav/GLOFNavAlm_T.cpp +++ b/core/tests/NewNav/GLOFNavAlm_T.cpp @@ -118,6 +118,7 @@ getXvtTest() uut.eccnA = 0.001482010; uut.omeganA = 0.440277100 * gnsstk::PI; uut.Toa = gnsstk::YDSTime(2001, 249, uut.tLambdanA, gnsstk::TimeSystem::GLO); + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::PZ90KGS); // Normally called by fixFit, but we don't care about the fit // interval for this test. @@ -136,7 +137,7 @@ getXvtTest() TUASSERTFE(0, xvt.clkbias); TUASSERTFE(0, xvt.clkdrift); TUASSERTFE(1.5097189886318696151e-09, xvt.relcorr); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::PZ90,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); #if 0 // This is more code that was used to track down what was going // on with getXvt. Specifically it first helped me confirm that diff --git a/core/tests/NewNav/GLOFNavEph_T.cpp b/core/tests/NewNav/GLOFNavEph_T.cpp index 902f8ed9a..c6abf771a 100644 --- a/core/tests/NewNav/GLOFNavEph_T.cpp +++ b/core/tests/NewNav/GLOFNavEph_T.cpp @@ -122,6 +122,7 @@ getXvtTest() TUDEF("GLOFNavEph", "getXvt()"); gnsstk::GLOFNavEph uut; gnsstk::Xvt xvt, exp1, exp2; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::PZ90KGS); // This data was probably originally obtained by setting uut to // values obtained from the broadcast data and running it // through the now deprecated GloEphemeris class, but that @@ -172,7 +173,7 @@ getXvtTest() TUASSERTFE(exp1.clkbias, xvt.clkbias); TUASSERTFE(exp1.clkdrift, xvt.clkdrift); TUASSERTFE(exp1.relcorr, xvt.relcorr); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::PZ90,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); // same ephemeris, orbit 306 seconds in the future of Toe TUASSERTE(bool, true, uut.getXvt(uut.Toe + 306, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, @@ -185,7 +186,7 @@ getXvtTest() TUASSERTFE(exp2.clkbias, xvt.clkbias); TUASSERTFE(exp2.clkdrift, xvt.clkdrift); TUASSERTFE(exp2.relcorr, xvt.relcorr); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::PZ90,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSCNav2Alm_T.cpp b/core/tests/NewNav/GPSCNav2Alm_T.cpp index f1a7d9270..48c62d71e 100644 --- a/core/tests/NewNav/GPSCNav2Alm_T.cpp +++ b/core/tests/NewNav/GPSCNav2Alm_T.cpp @@ -120,6 +120,7 @@ getXvtTest() TUDEF("GPSCNav2Alm", "getXvt"); gnsstk::GPSCNav2Alm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -127,7 +128,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSCNav2Eph_T.cpp b/core/tests/NewNav/GPSCNav2Eph_T.cpp index 3c08098f3..d0658eed6 100644 --- a/core/tests/NewNav/GPSCNav2Eph_T.cpp +++ b/core/tests/NewNav/GPSCNav2Eph_T.cpp @@ -140,6 +140,7 @@ getXvtTest() TUDEF("GPSCNav2Eph", "getXvt"); gnsstk::GPSCNav2Eph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -147,7 +148,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSCNavAlm_T.cpp b/core/tests/NewNav/GPSCNavAlm_T.cpp index abc17c941..d13146dbf 100644 --- a/core/tests/NewNav/GPSCNavAlm_T.cpp +++ b/core/tests/NewNav/GPSCNavAlm_T.cpp @@ -127,6 +127,7 @@ getXvtTest() TUDEF("GPSCNavAlm", "getXvt"); gnsstk::GPSCNavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -134,7 +135,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSCNavEph_T.cpp b/core/tests/NewNav/GPSCNavEph_T.cpp index a1869e24f..14aabdb26 100644 --- a/core/tests/NewNav/GPSCNavEph_T.cpp +++ b/core/tests/NewNav/GPSCNavEph_T.cpp @@ -167,6 +167,7 @@ getXvtTest() TUDEF("GPSCNavEph", "getXvt"); gnsstk::GPSCNavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -174,7 +175,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSLNavAlm_T.cpp b/core/tests/NewNav/GPSLNavAlm_T.cpp index 231d76626..f05da3e2f 100644 --- a/core/tests/NewNav/GPSLNavAlm_T.cpp +++ b/core/tests/NewNav/GPSLNavAlm_T.cpp @@ -111,6 +111,7 @@ getXvtTest() TUDEF("GPSLNavAlm", "getXvt"); gnsstk::GPSLNavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -118,7 +119,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GPSLNavEph_T.cpp b/core/tests/NewNav/GPSLNavEph_T.cpp index 9fc5e23aa..f5557aade 100644 --- a/core/tests/NewNav/GPSLNavEph_T.cpp +++ b/core/tests/NewNav/GPSLNavEph_T.cpp @@ -176,6 +176,7 @@ getXvtTest() TUDEF("GPSLNavEph", "getXvt"); gnsstk::GPSLNavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::WGS84G1762); uut.xmitTime = gnsstk::GPSWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GPSWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GPS); @@ -183,7 +184,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GPS); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::WGS84,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GalFNavAlm_T.cpp b/core/tests/NewNav/GalFNavAlm_T.cpp index a636d57ba..031201e67 100644 --- a/core/tests/NewNav/GalFNavAlm_T.cpp +++ b/core/tests/NewNav/GalFNavAlm_T.cpp @@ -156,6 +156,7 @@ getXvtTest() TUDEF("GalFNavAlm", "getXvt"); gnsstk::GalFNavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::ITRF2014); uut.xmitTime = gnsstk::GALWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GALWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GAL); @@ -163,7 +164,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GAL); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::ITRF,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GalFNavEph_T.cpp b/core/tests/NewNav/GalFNavEph_T.cpp index 57fa35598..0d887d774 100644 --- a/core/tests/NewNav/GalFNavEph_T.cpp +++ b/core/tests/NewNav/GalFNavEph_T.cpp @@ -143,6 +143,7 @@ getXvtTest() TUDEF("GalFNavEph", "getXvt"); gnsstk::GalFNavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::ITRF2014); uut.xmitTime = gnsstk::GALWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GALWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GAL); @@ -150,7 +151,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GAL); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::ITRF,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GalINavAlm_T.cpp b/core/tests/NewNav/GalINavAlm_T.cpp index a5fc2e8a5..080398fd2 100644 --- a/core/tests/NewNav/GalINavAlm_T.cpp +++ b/core/tests/NewNav/GalINavAlm_T.cpp @@ -185,6 +185,7 @@ getXvtTest() TUDEF("GalINavAlm", "getXvt"); gnsstk::GalINavAlm uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::ITRF2014); uut.xmitTime = gnsstk::GALWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GALWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GAL); @@ -192,7 +193,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GAL); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::ITRF,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/GalINavEph_T.cpp b/core/tests/NewNav/GalINavEph_T.cpp index cc90b6689..ffc39ad09 100644 --- a/core/tests/NewNav/GalINavEph_T.cpp +++ b/core/tests/NewNav/GalINavEph_T.cpp @@ -141,6 +141,7 @@ getXvtTest() TUDEF("GalINavEph", "getXvt"); gnsstk::GalINavEph uut; gnsstk::Xvt xvt; + gnsstk::RefFrame expRF(gnsstk::RefFrameRlz::ITRF2014); uut.xmitTime = gnsstk::GALWeekSecond(1854, .720000000000e+04); uut.Toe = gnsstk::GALWeekSecond(1854, .143840000000e+05); uut.Toc = gnsstk::CivilTime(2015,7,19,3,59,44.0,gnsstk::TimeSystem::GAL); @@ -148,7 +149,7 @@ getXvtTest() gnsstk::CivilTime civ(2015,7,19,2,0,35.0,gnsstk::TimeSystem::GAL); TUASSERT(uut.getXvt(civ, xvt)); TUASSERTE(gnsstk::Xvt::HealthStatus, gnsstk::Xvt::Healthy, xvt.health); - TUASSERTE(gnsstk::ReferenceFrame,gnsstk::ReferenceFrame::ITRF,xvt.frame); + TUASSERTE(gnsstk::RefFrame,expRF,xvt.frame); TURETURN(); } diff --git a/core/tests/NewNav/SP3NavDataFactory_T.cpp b/core/tests/NewNav/SP3NavDataFactory_T.cpp index 0d4cd10d5..a7c4d7666 100644 --- a/core/tests/NewNav/SP3NavDataFactory_T.cpp +++ b/core/tests/NewNav/SP3NavDataFactory_T.cpp @@ -268,7 +268,8 @@ findExactTest() TUASSERTFEPS(-28974.934472, uut->vel[2], 0.000001); TUASSERTFEPS(-2.52832e-5, uut->clkDrift, 0.0000000001); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G873), + uut->frame); // test find with a different carrier/ranging code TUASSERT(fact.find(nmid1b, ct1, nd1, gnsstk::SVHealth::Any, @@ -300,7 +301,8 @@ findExactTest() TUASSERTFEPS(-28974.934472, uut->vel[2], 0.000001); TUASSERTFEPS(-2.52832e-5, uut->clkDrift, 0.0000000001); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G873), + uut->frame); // test find with exact epoch at end of file gnsstk::CivilTime civ2(2001, 7, 22, 0, 45, 0, gnsstk::TimeSystem::GPS); @@ -340,7 +342,8 @@ findExactTest() TUASSERTFEPS( 20382.028718, uut->vel[2], 0.000001); TUASSERTFEPS( 8.499e-7, uut->clkDrift, 0.0000000001); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G873), + uut->frame); // test find with exact epoch in the middle of file gnsstk::CivilTime civ3(2001, 7, 22, 0, 30, 0, gnsstk::TimeSystem::GPS); @@ -380,7 +383,8 @@ findExactTest() TUASSERTFEPS( -29243.893155, uut->vel[2], 0.000001); TUASSERTFEPS( 2.133e-7, uut->clkDrift, 0.0000000001); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G873), + uut->frame); // Test using data where velocity is missing and must be interpolated. // This test makes sure we're getting velocity data when there @@ -425,7 +429,8 @@ findExactTest() TUASSERTFE(-12599.181107279617208, uut->vel[2]); TUASSERTFE(8.4786249559075835378e-05, uut->clkDrift); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); TURETURN(); } @@ -499,7 +504,8 @@ findInterpTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); TURETURN(); } @@ -565,7 +571,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // Just after start - can't interpolate ct = gnsstk::CivilTime(1997,4,6,0,0,2,gnsstk::TimeSystem::GPS); TUASSERT(!fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -603,7 +610,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // Still not enough data to interpolate ct = gnsstk::CivilTime(1997,4,6,0,15,2,gnsstk::TimeSystem::GPS); TUASSERT(!fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -641,7 +649,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // Still not enough data to interpolate ct = gnsstk::CivilTime(1997,4,6,0,30,2,gnsstk::TimeSystem::GPS); TUASSERT(!fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -684,7 +693,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // now we can interpolate ct = gnsstk::CivilTime(1997,4,6,1,0,2,gnsstk::TimeSystem::GPS); TUASSERT(fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -716,7 +726,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // interpolating near the end of the data set ct = gnsstk::CivilTime(1997,4,6,22,30,2,gnsstk::TimeSystem::GPS); TUASSERT(fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -748,7 +759,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // The last time we can interpolate ct = gnsstk::CivilTime(1997,4,6,22,45,0,gnsstk::TimeSystem::GPS); TUASSERT(fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -780,7 +792,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); // no longer able to interpolate ct = gnsstk::CivilTime(1997,4,6,22,45,2,gnsstk::TimeSystem::GPS); TUASSERT(!fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -819,7 +832,8 @@ findEdgeTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "ITR94", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::ITRF94,uut->frame); + TUASSERTE(gnsstk::RefFrame, gnsstk::RefFrame(gnsstk::RefFrameRlz::ITRF94), + uut->frame); TURETURN(); } @@ -873,7 +887,9 @@ sp3cPVTest() TUASSERTFE(1.3259000000000000871e-06, uut->clkDrift); TUASSERTFE(1.0175328004541179996e-07, uut->driftSig); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + uut->frame); /// @note drift rate value not confirmed by SP3EphemerisStore TUASSERTFE(-2.1102292768909279853e-13, uut->clkDrRate); TUASSERTFE(1.130592000504575508e-10, uut->drRateSig); @@ -908,7 +924,9 @@ sp3cPVTest() TUASSERTFE(-2.5152847174005956486e-13, uut->clkDrRate); TUASSERTFE(1.1085932582988582625e-10, uut->drRateSig); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + uut->frame); TURETURN(); } @@ -963,7 +981,9 @@ sp3cPTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + uut->frame); // interpolated match ct = gnsstk::CivilTime(2011,10,9,2,1,3,gnsstk::TimeSystem::GPS); TUASSERT(fact.find(nmid1, ct, nd, gnsstk::SVHealth::Any, @@ -996,7 +1016,9 @@ sp3cPTest() TUASSERTFE(0, uut->clkDrRate); TUASSERTFE(0, uut->drRateSig); TUASSERTE(std::string, "WGS84", uut->coordSystem); - TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, uut->frame); + TUASSERTE(gnsstk::RefFrame, + gnsstk::RefFrame(gnsstk::RefFrameRlz::WGS84G1150), + uut->frame); TURETURN(); } diff --git a/core/tests/RefTime/HelmertTransform_T.cpp b/core/tests/RefTime/HelmertTransform_T.cpp index 66570410b..813e18106 100644 --- a/core/tests/RefTime/HelmertTransform_T.cpp +++ b/core/tests/RefTime/HelmertTransform_T.cpp @@ -68,6 +68,8 @@ class HelmertTransform_T gnsstk::ReferenceFrame initialRF; gnsstk::ReferenceFrame finalRF; + gnsstk::RefFrame initRF; + gnsstk::RefFrame finRF; gnsstk::HelmertTransform uut1, uut2; /// initial positions and transformed positions std::vector p1, x1, p2, x2; @@ -77,14 +79,16 @@ class HelmertTransform_T HelmertTransform_T :: HelmertTransform_T() : initialRF(gnsstk::ReferenceFrame::WGS84), + initRF(initialRF,gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)), finalRF(gnsstk::ReferenceFrame::CGCS2000), + finRF(finalRF, gnsstk::YDSTime(1994,1,0,gnsstk::TimeSystem::UTC)), uut1(initialRF, finalRF, 0, 0, 0, 10, 10, 10, 1, "hi there", - gnsstk::YDSTime(2020,123,456)), + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)), // https://d28rz98at9flks.cloudfront.net/71433/71433.pdf uut2(initialRF, finalRF, -24.1665*gnsstk::DEG_PER_MAS, -20.9515*gnsstk::DEG_PER_MAS, -21.3961*gnsstk::DEG_PER_MAS, -42.7e-3, -17.06e-3, 28.81e-3, 11.474*gnsstk::PPB, "step 2", - gnsstk::YDSTime(1994, 1, 0)), + gnsstk::YDSTime(1994, 1, 0,gnsstk::TimeSystem::UTC)), p1({150, 150, 150}), x1({310, 310, 310}), // 100% scale, 10m translation p2({-4052052.3678, 4212836.0411, -2545105.1089}), @@ -112,7 +116,7 @@ constructorTest() TestClass uut2(gnsstk::ReferenceFrame::PZ90, gnsstk::ReferenceFrame::WGS84, 1e-4, 2e-4, 3e-4, 4, 5, 6, 7, "hi there", - gnsstk::YDSTime(2020,123,456)); + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC)); TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::PZ90, uut2.getFromFrame()); TUASSERTE(gnsstk::ReferenceFrame, gnsstk::ReferenceFrame::WGS84, @@ -125,7 +129,8 @@ constructorTest() TUASSERTFE(6, uut2.gettz()); TUASSERTFE(7, uut2.getscale()); TUASSERTE(std::string, "hi there", uut2.getdescription()); - TUASSERTE(gnsstk::CommonTime, gnsstk::YDSTime(2020,123,456), + TUASSERTE(gnsstk::CommonTime, + gnsstk::YDSTime(2020,123,456,gnsstk::TimeSystem::UTC), uut2.getEpoch()); TURETURN(); } @@ -137,9 +142,9 @@ transformPositionTest() TUDEF("HelmertTransform", "transform(Position)"); gnsstk::Position pos1(&p1[0], gnsstk::Position::Cartesian, nullptr, - initialRF); + initRF); gnsstk::Position exp1(&x1[0], gnsstk::Position::Cartesian, nullptr, - finalRF); + finRF); gnsstk::Position out1; TUCATCH(uut1.transform(pos1, out1)); TUASSERTFE(exp1.getX(), out1.getX()); @@ -147,8 +152,8 @@ transformPositionTest() TUASSERTFE(exp1.getZ(), out1.getZ()); gnsstk::Position pos2(&p2[0], gnsstk::Position::Cartesian, nullptr, - initialRF); - gnsstk::Position exp2(&x2[0], gnsstk::Position::Cartesian, nullptr, finalRF); + initRF); + gnsstk::Position exp2(&x2[0], gnsstk::Position::Cartesian, nullptr, finRF); gnsstk::Position out2; // forward transform TUCATCH(uut2.transform(pos2, out2)); @@ -238,14 +243,14 @@ transformXvtTest() pos1.clkbias = 4; pos1.clkdrift = 5; pos1.relcorr = 6; - pos1.frame = initialRF; + pos1.frame = initRF; pos1.health = gnsstk::Xvt::Degraded; exp1.x = gnsstk::Triple({x1[0], x1[1], x1[2]}); exp1.v = gnsstk::Triple({1, 2, 3}); exp1.clkbias = 4; exp1.clkdrift = 5; exp1.relcorr = 6; - exp1.frame = finalRF; + exp1.frame = finRF; exp1.health = gnsstk::Xvt::Degraded; TUCATCH(uut1.transform(pos1, out1)); TUASSERTFE(exp1.x[0], out1.x[0]); @@ -257,7 +262,7 @@ transformXvtTest() TUASSERTFE(exp1.clkbias, out1.clkbias); TUASSERTFE(exp1.clkdrift, out1.clkdrift); TUASSERTFE(exp1.relcorr, out1.relcorr); - TUASSERTE(gnsstk::ReferenceFrame, exp1.frame, out1.frame); + TUASSERTE(gnsstk::RefFrame, exp1.frame, out1.frame); TUASSERTE(gnsstk::Xvt::HealthStatus, exp1.health, out1.health); gnsstk::Xvt pos2, exp2, out2; @@ -266,14 +271,14 @@ transformXvtTest() pos2.clkbias = 4; pos2.clkdrift = 5; pos2.relcorr = 6; - pos2.frame = initialRF; + pos2.frame = gnsstk::RefFrame(gnsstk::RefFrameSys::WGS84, uut2.getEpoch()); pos2.health = gnsstk::Xvt::Degraded; exp2.x = gnsstk::Triple({x2[0], x2[1], x2[2]}); exp2.v = gnsstk::Triple({1, 2, 3}); exp2.clkbias = 4; exp2.clkdrift = 5; exp2.relcorr = 6; - exp2.frame = finalRF; + exp2.frame = finRF; exp2.health = gnsstk::Xvt::Degraded; // forward transform TUCATCH(uut2.transform(pos2, out2)); @@ -286,7 +291,7 @@ transformXvtTest() TUASSERTFE(exp2.clkbias, out2.clkbias); TUASSERTFE(exp2.clkdrift, out2.clkdrift); TUASSERTFE(exp2.relcorr, out2.relcorr); - TUASSERTE(gnsstk::ReferenceFrame, exp2.frame, out2.frame); + TUASSERTE(gnsstk::RefFrame, exp2.frame, out2.frame); TUASSERTE(gnsstk::Xvt::HealthStatus, exp2.health, out2.health); // reverse transform TUCATCH(uut2.transform(exp2, out2)); @@ -299,7 +304,7 @@ transformXvtTest() TUASSERTFE(pos2.clkbias, out2.clkbias); TUASSERTFE(pos2.clkdrift, out2.clkdrift); TUASSERTFE(pos2.relcorr, out2.relcorr); - TUASSERTE(gnsstk::ReferenceFrame, pos2.frame, out2.frame); + TUASSERTE(gnsstk::RefFrame, pos2.frame, out2.frame); TUASSERTE(gnsstk::Xvt::HealthStatus, pos2.health, out2.health); TURETURN(); diff --git a/swig/GNSSCore/GNSSCore.i b/swig/GNSSCore/GNSSCore.i index 458b35dab..21b71761c 100644 --- a/swig/GNSSCore/GNSSCore.i +++ b/swig/GNSSCore/GNSSCore.i @@ -31,6 +31,7 @@ from __future__ import absolute_import %include "typemaps.i" %include "exception.i" %include "carrays.i" +%include "std_shared_ptr.i" // ============================================================= // Section 2: Macros @@ -59,12 +60,17 @@ ENUM_MAPPER(gnsstk::CarrierBand, CarrierBand, "gnsstk") ENUM_MAPPER(gnsstk::TrackingCode, TrackingCode, "gnsstk") ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") + // needs to be before RefFrameRlz.hpp at the very least. +%import "CommonTime.hpp" + %include "SatelliteSystem.hpp" %include "CarrierBand.hpp" %include "TrackingCode.hpp" %include "ObservationType.hpp" %include "AngleType.hpp" %include "XmitAnt.hpp" +%include "RefFrameSys.hpp" +%include "RefFrameRlz.hpp" %include "renameEnums.i" %pythoncode %{ @@ -74,6 +80,8 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") renameEnums('ObservationType') renameEnums('AngleType') renameEnums('XmitAnt') + renameEnums('RefFrameSys') + renameEnums('RefFrameRlz') %} %include "cleanup.i" @@ -85,6 +93,13 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %include "Exception.i" +// ============================================================= +// Section 7: C++11 shared_ptr handling +// ============================================================= + +%shared_ptr(gnsstk::Transformer) +%shared_ptr(gnsstk::HelmertTransformer) + // ============================================================= // Section 9: typemaps that must be declared before the %includes // ============================================================= @@ -99,7 +114,6 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") // I don't know why some of these require the module option and others don't, // but without it, you get warnings saying to do it. %import(module="gnsstk") "Exception.hpp" -%import "CommonTime.hpp" %import "EngNav.hpp" %import "EngAlmanac.hpp" %import "NavType.hpp" @@ -108,11 +122,14 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %import "FFData.hpp" %import "RinexObsBase.hpp" %import "RinexObsHeader.hpp" +%import "Vector.hpp" +%import "Matrix.hpp" %include "AngleType.hpp" %include "AngleReduced.hpp" %include "Angle.hpp" %include "EllipsoidModel.hpp" +%include "RefFrame.hpp" %include "CGCS2000Ellipsoid.hpp" %include "CarrierBand.hpp" %template(std_map_CarrierBand_string) std::map; @@ -141,6 +158,8 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %include "GalileoEllipsoid.hpp" %include "GalileoIonoEllipsoid.hpp" %include "GlobalTropModel.hpp" +%include "Transformer.hpp" +%include "HelmertTransformer.hpp" %feature("flatnested"); %include "IonoModel.hpp" %feature("flatnested", ""); @@ -177,6 +196,7 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %include "SatMetaDataStore.hpp" %feature("flatnested", ""); %include "SimpleTropModel.hpp" +%include "TransformLibrary.hpp" %include "convhelp.hpp" // ============================================================= @@ -206,25 +226,25 @@ for cls in enum_vec_classes: def cartesian(x=0.0, y=0.0, z=0.0, - model=None, frame=ReferenceFrame.Unknown): + model=None, frame=RefFrame()): "Returns a Position in the Cartesian coordinate system." return Position(x, y, z, Position.Cartesian, model, frame) def geodetic(latitude=0.0, longitude=0.0, height=0.0, - model=None, frame=ReferenceFrame.Unknown): + model=None, frame=RefFrame()): "Returns a Position in the Geodetic coordinate system." return Position(latitude, longitude, height, Position.Geodetic, model, frame) def spherical(theta=0.0, phi=0.0, radius=0.0, - model=None, frame=ReferenceFrame.Unknown): + model=None, frame=RefFrame()): "Returns a Position in the Spherical coordinate system." return Position(theta, phi, radius, Position.Spherical, model, frame) def geocentric(latitude=0.0, longitude=0.0, radius=0.0, - model=None, frame=ReferenceFrame.Unknown): + model=None, frame=RefFrame()): "Returns a Position in the Geocentric coordinate system." return Position(latitude, longitude, radius, Position.Geocentric, model, frame) diff --git a/swig/GNSSEph/GNSSEph.i b/swig/GNSSEph/GNSSEph.i index e3b094fc5..34a142109 100644 --- a/swig/GNSSEph/GNSSEph.i +++ b/swig/GNSSEph/GNSSEph.i @@ -89,7 +89,6 @@ from __future__ import absolute_import %include "EngAlmanac.hpp" %include "EngEphemeris.hpp" %include "EphemerisRange.hpp" -%include "GloEphemeris.hpp" %include "SP3SatID.hpp" @@ -102,7 +101,6 @@ STR_DUMP_HELPER(BrcKeplerOrbit) STR_DUMP_HELPER(EngAlmanac) STR_DUMP_HELPER(EngEphemeris) STR_DUMP_HELPER(EngNav) -STR_DUMP_HELPER(GloEphemeris) AS_STRING_HELPER(NavID) // ============================================================= diff --git a/swig/NewNav/NewNav.i b/swig/NewNav/NewNav.i index 546705e03..7894f853f 100644 --- a/swig/NewNav/NewNav.i +++ b/swig/NewNav/NewNav.i @@ -113,7 +113,10 @@ ENUM_MAPPER(gnsstk::NavMessageType, NavMessageType, "gnsstk") %import "SatID.hpp" %import "Triple.i" %import "EllipsoidModel.hpp" +%import "RefFrameSys.hpp" +%import "RefFrameRlz.hpp" %import "ReferenceFrame.hpp" +%import "RefFrame.hpp" %import "Xvt.hpp" %import "FFData.hpp" %import "CarrierBand.hpp" diff --git a/swig/gnsstk_swig.hpp b/swig/gnsstk_swig.hpp index 445f8811a..c6e25e0d2 100644 --- a/swig/gnsstk_swig.hpp +++ b/swig/gnsstk_swig.hpp @@ -18,7 +18,10 @@ #include "Vector.hpp" #include "Triple.hpp" #include "EllipsoidModel.hpp" +#include "RefFrameSys.hpp" +#include "RefFrameRlz.hpp" #include "ReferenceFrame.hpp" +#include "RefFrame.hpp" #include "DeprecatedConsts.hpp" #include "FreqConsts.hpp" #include "GNSSconstants.hpp" @@ -278,9 +281,10 @@ #include "GalINavTimeOffset.hpp" #include "GenXSequence.hpp" #include "GenericNavFilterData.hpp" -#include "GloEphemeris.hpp" #include "GlobalTropModel.hpp" #include "HelmertTransform.hpp" +#include "Transformer.hpp" +#include "HelmertTransformer.hpp" //#include "IERS1996NutationData.hpp" //#include "IERS1996UT1mUTCData.hpp" //#include "IERS2003NutationData.hpp" @@ -426,6 +430,7 @@ #include "TimeCorrection.hpp" #include "TimeNamedFileStream.hpp" #include "TimeRange.hpp" +#include "TransformLibrary.hpp" #include "VectorOperators.hpp" #include "WNJfilter.hpp" #include "WindowFilter.hpp" diff --git a/swig/gnsstk_swig.i b/swig/gnsstk_swig.i index d1ecf6086..33402da8f 100644 --- a/swig/gnsstk_swig.i +++ b/swig/gnsstk_swig.i @@ -20,7 +20,10 @@ %import(module="gnsstk") "Vector.hpp" %import(module="gnsstk") "Triple.hpp" %import(module="gnsstk") "EllipsoidModel.hpp" +%import(module="gnsstk") "RefFrameSys.hpp" +%import(module="gnsstk") "RefFrameRlz.hpp" %import(module="gnsstk") "ReferenceFrame.hpp" +%import(module="gnsstk") "RefFrame.hpp" %import(module="gnsstk") "DeprecatedConsts.hpp" %import(module="gnsstk") "FreqConsts.hpp" %import(module="gnsstk") "GNSSconstants.hpp" @@ -350,9 +353,10 @@ %import(module="gnsstk") "GalINavTimeOffset.hpp" %import(module="gnsstk") "GenXSequence.hpp" %import(module="gnsstk") "GenericNavFilterData.hpp" -%import(module="gnsstk") "GloEphemeris.hpp" %import(module="gnsstk") "GlobalTropModel.hpp" %import(module="gnsstk") "HelmertTransform.hpp" +%import(module="gnsstk") "Transformer.hpp" +%import(module="gnsstk") "HelmertTransformer.hpp" //%import(module="gnsstk") "IERS1996NutationData.hpp" //%import(module="gnsstk") "IERS1996UT1mUTCData.hpp" //%import(module="gnsstk") "IERS2003NutationData.hpp" @@ -534,6 +538,7 @@ %import(module="gnsstk") "TimeNamedFileStream.hpp" %feature("flatnested"); %import(module="gnsstk") "TimeRange.hpp" +%import(module="gnsstk") "TransformLibrary.hpp" %feature("flatnested", ""); %import(module="gnsstk") "VectorOperators.hpp" %import(module="gnsstk") "WNJfilter.hpp" diff --git a/swig/tests/test_misc.py b/swig/tests/test_misc.py index e01c26d94..41fbbb97c 100755 --- a/swig/tests/test_misc.py +++ b/swig/tests/test_misc.py @@ -230,7 +230,7 @@ def test_cartesian_geocentric(self): def test_functions(self): system = gnsstk.Position.Cartesian ell = gnsstk.PZ90Ellipsoid() - frame = gnsstk.ReferenceFrame.PZ90 + frame = gnsstk.RefFrame(gnsstk.RefFrameRlz.PZ90Y2007) p = gnsstk.Position(10000.0, 150000.0, 200000.0, system, ell, frame) q = gnsstk.Position(20000.0, 160000.0, 190000.0, system, ell, frame) self.assertAlmostEqual(1.32756277187, q.elevation(p)) @@ -243,7 +243,7 @@ def test_helpers(self): self.assertEqual(gnsstk.Position.Cartesian, p.getCoordinateSystem()) p = gnsstk.spherical(45, 60, 100000, model=gnsstk.PZ90Ellipsoid()) self.assertEqual(gnsstk.Position.Spherical, p.getCoordinateSystem()) - p = gnsstk.geodetic(frame=gnsstk.ReferenceFrame.WGS84) + p = gnsstk.geodetic(frame=gnsstk.RefFrame(gnsstk.RefFrameRlz.WGS84G0)) self.assertEqual(gnsstk.Position.Geodetic, p.getCoordinateSystem()) p = gnsstk.geocentric(latitude=60, radius=10000) self.assertEqual(gnsstk.Position.Geocentric, p.getCoordinateSystem()) @@ -387,7 +387,7 @@ def test(self): data.clkbias = 0.0001 data.clkdrift = 0.05 data.relcorr = 0.83 - data.frame = gnsstk.ReferenceFrame.WGS84 + data.frame = gnsstk.RefFrame(gnsstk.RefFrameRlz.WGS84G2139); self.assertAlmostEqual(0.0001, data.getClockBias()) expected = 1.446445072869704e-11 From 4ef67ee91373339ab227865d9e363fdf2257fed3 Mon Sep 17 00:00:00 2001 From: John Knutson Date: Fri, 9 Dec 2022 12:01:09 -0600 Subject: [PATCH 08/16] Implement group delay calculator --- .../lib/FileHandling}/MetReader.cpp | 56 +- core/lib/FileHandling/MetReader.hpp | 76 +++ core/lib/GNSSCore/BCISCorrector.cpp | 78 +++ core/lib/GNSSCore/BCISCorrector.hpp | 81 +++ core/lib/GNSSCore/BCIonoCorrector.cpp | 88 +++ core/lib/GNSSCore/BCIonoCorrector.hpp | 80 +++ core/lib/GNSSCore/CorrDupHandling.cpp | 71 +++ core/lib/GNSSCore/CorrDupHandling.hpp | 87 +++ core/lib/GNSSCore/CorrectionResult.hpp | 79 +++ core/lib/GNSSCore/CorrectionResults.cpp | 110 ++++ core/lib/GNSSCore/CorrectionResults.hpp | 85 +++ core/lib/GNSSCore/CorrectorType.cpp | 74 +++ core/lib/GNSSCore/CorrectorType.hpp | 80 +++ core/lib/GNSSCore/GlobalTropModel.hpp | 2 +- core/lib/GNSSCore/GroupPathCorr.cpp | 184 ++++++ core/lib/GNSSCore/GroupPathCorr.hpp | 179 ++++++ core/lib/GNSSCore/GroupPathCorrector.hpp | 99 ++++ core/lib/GNSSCore/IonoModel.hpp | 2 +- core/lib/GNSSCore/IonoModelStore.hpp | 2 +- core/lib/GNSSCore/TropCorrector.hpp | 267 +++++++++ core/lib/GNSSCore/TropModel.hpp | 2 +- core/lib/NewNav/InterSigCorr.hpp | 53 +- core/lib/NewNav/NavDataFactoryWithStore.cpp | 7 + core/lib/NewNav/NavLibrary.cpp | 375 +++++-------- core/lib/NewNav/NavLibrary.hpp | 72 +-- core/lib/NewNav/RinexNavDataFactory.hpp | 5 +- core/lib/PosSol/PRSolution.hpp | 3 +- core/tests/FileHandling/CMakeLists.txt | 5 + core/tests/FileHandling/MetReader_T.cpp | 114 ++++ core/tests/GNSSCore/BCISCorrector_T.cpp | 161 ++++++ core/tests/GNSSCore/BCIonoCorrector_T.cpp | 161 ++++++ core/tests/GNSSCore/CMakeLists.txt | 45 ++ core/tests/GNSSCore/CorrDupHandling_T.cpp | 90 +++ .../tests/GNSSCore/CorrectionResult_T.cpp | 45 +- core/tests/GNSSCore/CorrectionResults_T.cpp | 153 +++++ core/tests/GNSSCore/CorrectorType_T.cpp | 90 +++ core/tests/GNSSCore/GroupPathCorr_T.cpp | 530 ++++++++++++++++++ core/tests/GNSSCore/GroupPathCorrector_T.cpp | 103 ++++ core/tests/GNSSCore/TropCorrector_T.cpp | 201 +++++++ core/tests/NewNav/NavLibrary_T.cpp | 42 +- ext/lib/GNSSCore/OceanLoading.hpp | 2 +- ext/lib/GNSSCore/PoleTides.hpp | 2 +- ref/usersguide/gnsstk.bib | 2 +- swig/FileHandling/FileHandling.i | 1 + swig/GNSSCore/GNSSCore.i | 38 ++ swig/NewNav/NewNavSharedPtr.i | 2 + swig/Rxio/Rxio.i | 1 - swig/gnsstk_swig.hpp | 9 + swig/gnsstk_swig.i | 9 + swig/tests/CMakeLists.txt | 1 + swig/tests/__init__.py | 33 ++ swig/tests/test_GNSSCore.py | 333 ++++++++++- 52 files changed, 4075 insertions(+), 395 deletions(-) rename {ext/lib/Rxio => core/lib/FileHandling}/MetReader.cpp (72%) create mode 100644 core/lib/FileHandling/MetReader.hpp create mode 100644 core/lib/GNSSCore/BCISCorrector.cpp create mode 100644 core/lib/GNSSCore/BCISCorrector.hpp create mode 100644 core/lib/GNSSCore/BCIonoCorrector.cpp create mode 100644 core/lib/GNSSCore/BCIonoCorrector.hpp create mode 100644 core/lib/GNSSCore/CorrDupHandling.cpp create mode 100644 core/lib/GNSSCore/CorrDupHandling.hpp create mode 100644 core/lib/GNSSCore/CorrectionResult.hpp create mode 100644 core/lib/GNSSCore/CorrectionResults.cpp create mode 100644 core/lib/GNSSCore/CorrectionResults.hpp create mode 100644 core/lib/GNSSCore/CorrectorType.cpp create mode 100644 core/lib/GNSSCore/CorrectorType.hpp create mode 100644 core/lib/GNSSCore/GroupPathCorr.cpp create mode 100644 core/lib/GNSSCore/GroupPathCorr.hpp create mode 100644 core/lib/GNSSCore/GroupPathCorrector.hpp create mode 100644 core/lib/GNSSCore/TropCorrector.hpp create mode 100644 core/tests/FileHandling/MetReader_T.cpp create mode 100644 core/tests/GNSSCore/BCISCorrector_T.cpp create mode 100644 core/tests/GNSSCore/BCIonoCorrector_T.cpp create mode 100644 core/tests/GNSSCore/CorrDupHandling_T.cpp rename ext/lib/Rxio/MetReader.hpp => core/tests/GNSSCore/CorrectionResult_T.cpp (75%) create mode 100644 core/tests/GNSSCore/CorrectionResults_T.cpp create mode 100644 core/tests/GNSSCore/CorrectorType_T.cpp create mode 100644 core/tests/GNSSCore/GroupPathCorr_T.cpp create mode 100644 core/tests/GNSSCore/GroupPathCorrector_T.cpp create mode 100644 core/tests/GNSSCore/TropCorrector_T.cpp create mode 100644 swig/tests/__init__.py diff --git a/ext/lib/Rxio/MetReader.cpp b/core/lib/FileHandling/MetReader.cpp similarity index 72% rename from ext/lib/Rxio/MetReader.cpp rename to core/lib/FileHandling/MetReader.cpp index 7c0b82150..994104299 100644 --- a/ext/lib/Rxio/MetReader.cpp +++ b/core/lib/FileHandling/MetReader.cpp @@ -49,28 +49,46 @@ using namespace std; namespace gnsstk { - -// --------------------------------------------------------------------- -// --------------------------------------------------------------------- -void MetReader::read(const std::string& fn) -{ - RinexMetStream rms; - try { rms.open(fn.c_str(), ios::in); } - catch (...) { - cerr << "Error reading weather data from file " << fn << endl; - exit(-1); + MetReader :: + MetReader() + : verboseLevel(0) + { } - RinexMetData rmd; - while (rms >> rmd) + + MetReader :: + MetReader(const std::string& fn) + : verboseLevel(0) { - WxObservation wob( - rmd.time, - rmd.data[RinexMetHeader::TD], - rmd.data[RinexMetHeader::PR], - rmd.data[RinexMetHeader::HR]); - wx.insertObservation(wob); + if (!read(fn)) + { + FileMissingException exc("Unable to read from "+fn); + GNSSTK_THROW(exc); + } } -} // end of read() + + + bool MetReader :: + read(const std::string& fn) + { + RinexMetStream rms; + rms.open(fn.c_str(), ios::in); + if (!rms) + { + return false; + } + + RinexMetData rmd; + while (rms >> rmd) + { + WxObservation wob( + rmd.time, + rmd.data[RinexMetHeader::TD], + rmd.data[RinexMetHeader::PR], + rmd.data[RinexMetHeader::HR]); + wx.insertObservation(wob); + } + return true; + } // end of read() } diff --git a/core/lib/FileHandling/MetReader.hpp b/core/lib/FileHandling/MetReader.hpp new file mode 100644 index 000000000..49b894960 --- /dev/null +++ b/core/lib/FileHandling/MetReader.hpp @@ -0,0 +1,76 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#ifndef METREADER_HPP +#define METREADER_HPP + +#include + +#include "CommandOption.hpp" +#include "WxObsMap.hpp" + +namespace gnsstk +{ + /** Class for reading weather (meteorological) data from a RINEX + * MET file and storing it internally for look-up. */ + class MetReader + { + public: + /// Initialize internal data structures. + MetReader(); + + /** Initialize and load a RINEX MET file. + * @param[in] fn The path to the RINEX MET file. + * @throw FileMissingException if unable to open fn. */ + MetReader(const std::string& fn); + + /** Load the data from a RINEX MET file. + * @param[in] fn The path to the RINEX MET file. + * @post wx contains the valid weather data loaded from fn. + * @return false if the file can't be opened. */ + bool read(const std::string& fn); + + /** This doesn't actually do anything, but it's here for + * backwards compatibility. */ + unsigned verboseLevel; + + /// The storage for all weather data read. + gnsstk::WxObsData wx; + }; +} +#endif diff --git a/core/lib/GNSSCore/BCISCorrector.cpp b/core/lib/GNSSCore/BCISCorrector.cpp new file mode 100644 index 000000000..b590b6ab2 --- /dev/null +++ b/core/lib/GNSSCore/BCISCorrector.cpp @@ -0,0 +1,78 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#include "BCISCorrector.hpp" + +namespace gnsstk +{ + BCISCorrector :: + BCISCorrector() + { + corrType = CorrectorType::ISC; + } + + + bool BCISCorrector :: + getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + if (navLib) + { + if (navLib->getISC(sat, obs, when, corrOut)) + { + return true; + } + } + corrOut = std::numeric_limits::quiet_NaN(); + return false; + } + + + bool BCISCorrector :: + getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + Position svp(svPos.x); + return getCorr(rxPos, svp, sat, obs, when, nav, corrOut); + } +} // namespace gnsstk diff --git a/core/lib/GNSSCore/BCISCorrector.hpp b/core/lib/GNSSCore/BCISCorrector.hpp new file mode 100644 index 000000000..b1df39846 --- /dev/null +++ b/core/lib/GNSSCore/BCISCorrector.hpp @@ -0,0 +1,81 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#ifndef GNSSTK_BCISCCORRECTOR_HPP +#define GNSSTK_BCISCCORRECTOR_HPP + +#include "GroupPathCorrector.hpp" +#include "NavLibrary.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Compute group path correction due to inter-signal bias on + * the satellite, using information available from the broadcast + * navigation message. + * + * @attention The #navLib variable must be set to a valid + * object for the getCorr() methods to return successfully. */ + class BCISCorrector : public GroupPathCorrector + { + public: + /// Set the #corrType to ISC for GroupPathCorr. + BCISCorrector(); + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + + /// Pointer to the nav library from which we will get ISC data. + std::shared_ptr navLib; + }; // class BCISCorrector + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_BCISCCORRECTOR_HPP diff --git a/core/lib/GNSSCore/BCIonoCorrector.cpp b/core/lib/GNSSCore/BCIonoCorrector.cpp new file mode 100644 index 000000000..792e6ebef --- /dev/null +++ b/core/lib/GNSSCore/BCIonoCorrector.cpp @@ -0,0 +1,88 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#include "BCIonoCorrector.hpp" + +namespace gnsstk +{ + BCIonoCorrector :: + BCIonoCorrector() + { + corrType = CorrectorType::Iono; + } + + + bool BCIonoCorrector :: + getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + if (navLib) + { + if (navLib->getIonoCorr(sat.system, when, rxPos, svPos, obs.band, + corrOut, nav)) + { + return true; + } + } + corrOut = std::numeric_limits::quiet_NaN(); + return false; + } + + + bool BCIonoCorrector :: + getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + if (navLib) + { + Position svp(svPos.x); + if (navLib->getIonoCorr(sat.system, when, rxPos, svp, obs.band, + corrOut, nav)) + { + return true; + } + } + corrOut = std::numeric_limits::quiet_NaN(); + return false; + } +} // namespace gnsstk diff --git a/core/lib/GNSSCore/BCIonoCorrector.hpp b/core/lib/GNSSCore/BCIonoCorrector.hpp new file mode 100644 index 000000000..2377dbbc9 --- /dev/null +++ b/core/lib/GNSSCore/BCIonoCorrector.hpp @@ -0,0 +1,80 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#ifndef GNSSTK_BCIONOCORRECTOR_HPP +#define GNSSTK_BCIONOCORRECTOR_HPP + +#include "GroupPathCorrector.hpp" +#include "NavLibrary.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Compute ionospheric delay on the satellite signal, using + * information available from the broadcast navigation message. + * + * @attention The #navLib variable must be set to a valid + * object for the getCorr() methods to return successfully. */ + class BCIonoCorrector : public GroupPathCorrector + { + public: + /// Set the #corrType to Iono for GroupPathCorr. + BCIonoCorrector(); + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + + /// Pointer to the nav library from which we will get iono data. + std::shared_ptr navLib; + }; // class BCIonoCorrector + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_BCIONOCORRECTOR_HPP diff --git a/core/lib/GNSSCore/CorrDupHandling.cpp b/core/lib/GNSSCore/CorrDupHandling.cpp new file mode 100644 index 000000000..1e2cf7c12 --- /dev/null +++ b/core/lib/GNSSCore/CorrDupHandling.cpp @@ -0,0 +1,71 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "CorrDupHandling.hpp" + +namespace gnsstk +{ + namespace StringUtils + { + std::string asString(CorrDupHandling e) noexcept + { + switch (e) + { + case CorrDupHandling::Unknown: return "Unknown"; + case CorrDupHandling::ComputeFirst: return "ComputeFirst"; + case CorrDupHandling::ComputeLast: return "ComputeLast"; + case CorrDupHandling::UseFirst: return "UseFirst"; + default: return "???"; + } // switch (e) + } // asString(CorrDupHandling) + + + CorrDupHandling asCorrDupHandling(const std::string& s) noexcept + { + if (s == "Unknown") + return CorrDupHandling::Unknown; + if (s == "ComputeFirst") + return CorrDupHandling::ComputeFirst; + if (s == "ComputeLast") + return CorrDupHandling::ComputeLast; + if (s == "UseFirst") + return CorrDupHandling::UseFirst; + return CorrDupHandling::Unknown; + } // asCorrDupHandling(string) + } // namespace StringUtils +} // namespace gnsstk diff --git a/core/lib/GNSSCore/CorrDupHandling.hpp b/core/lib/GNSSCore/CorrDupHandling.hpp new file mode 100644 index 000000000..a35c8f3f8 --- /dev/null +++ b/core/lib/GNSSCore/CorrDupHandling.hpp @@ -0,0 +1,87 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_CORRDUPHANDLING_HPP +#define GNSSTK_CORRDUPHANDLING_HPP + +#include +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Enumeration for defining how duplicat GroupPathCorrector + * types are handled by GroupPathCorr and CorrectionResults. + * The final sum will only ever use one correction of a given + * CorrectorType, and it will depend on the order that the + * corrector objects are added to GroupPathCorr::calcs. This + * enum also will tell GroupPathCorr whether to compute the + * biases of all of the correctors in calcs, or stop computing, + * for example, ISCs once the first ISC-type corrector yields a + * valid correction. */ + enum class CorrDupHandling + { + Unknown, ///< Duplicate handling is uninitialized. + ComputeFirst, ///< Sum includes first valid correction, no duplication. + ComputeLast, ///< Sum includes last valid correction of a type. + UseFirst, ///< Sum includes first valid correction of type, all computed. + Last ///< Used to create an iterator. + }; + + /** Define an iterator so C++11 can do things like + * for (CorrDupHandling i : CorrDupHandlingIterator()) */ + typedef EnumIterator CorrDupHandlingIterator; + /// Set of message types, used by NavLibrary and NavDataFactory. + typedef std::set CorrDupHandlingSet; + + namespace StringUtils + { + /// Convert a CorrDupHandling to a whitespace-free string name. + std::string asString(CorrDupHandling e) noexcept; + /// Convert a string name to an CorrDupHandling + CorrDupHandling asCorrDupHandling(const std::string& s) noexcept; + } + + //@} + +} + +#endif // GNSSTK_CORRDUPHANDLING_HPP diff --git a/core/lib/GNSSCore/CorrectionResult.hpp b/core/lib/GNSSCore/CorrectionResult.hpp new file mode 100644 index 000000000..a7f19719e --- /dev/null +++ b/core/lib/GNSSCore/CorrectionResult.hpp @@ -0,0 +1,79 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_CORRECTIONRESULT_HPP +#define GNSSTK_CORRECTIONRESULT_HPP + +#include +#include +#include "GroupPathCorrector.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Class for containing a single computed bias from one of the + * GroupPathCorrector classes. This pairs the actual bias with + * the corrector for the purpose of tracking bias + * contributions. */ + class CorrectionResult + { + public: + /// Initialize #result to NaN and source to null. + CorrectionResult() + : result(std::numeric_limits::quiet_NaN()) + {} + /** Fully initialize the object with real values. + * @param[in] r The computed correction value. + * @param[in] s The GroupPathCorrector that computed this result. */ + CorrectionResult(double r, const GroupPathCorrectorPtr& s) + : result(r), source(s) + {} + double result; ///< Computed bias in meters. + GroupPathCorrectorPtr source; ///< Corrector that computed this bias. + }; + + /// Just an ordered list of group path correction results. + typedef std::list CorrectionResultList; + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_CORRECTIONRESULT_HPP diff --git a/core/lib/GNSSCore/CorrectionResults.cpp b/core/lib/GNSSCore/CorrectionResults.cpp new file mode 100644 index 000000000..497c7ed37 --- /dev/null +++ b/core/lib/GNSSCore/CorrectionResults.cpp @@ -0,0 +1,110 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "CorrectionResults.hpp" + +namespace gnsstk +{ + void CorrectionResults :: + addResult(const CorrectionResult& res) + { + results.push_back(res); + } + + + const CorrectionResultList& CorrectionResults :: + getResults() const + { + return results; + } + + + double CorrectionResults :: + getCorrSum(CorrDupHandling dups) const + { + double rv = 0.0; + // Collected results (intermediate stage for dealing with duplicates) + std::map coll; + for (const auto& res : results) + { + switch (dups) + { + // Computation is already done at this point, so treat + // ComputeFirst and UseFirst the same here. + case CorrDupHandling::ComputeFirst: + case CorrDupHandling::UseFirst: + if (coll.find(res.source->corrType) == coll.end()) + { + // This is the first result of this type, so add it. + coll[res.source->corrType] = res.result; + } + break; + case CorrDupHandling::ComputeLast: + // Just add the result, and it will automatically + // end up with the last result in the map. + coll[res.source->corrType] = res.result; + break; + default: + { + InvalidParameter exc("Invalid CorrDupHandling value: " + + StringUtils::asString((int)dups)); + GNSSTK_THROW(exc); + } + } + } + if (coll.empty()) + { + // no data, so return nan. + return std::numeric_limits::quiet_NaN(); + } + for (const auto& ci : coll) + { + rv += ci.second; + } + return rv; + } + + + void CorrectionResults :: + clear() + { + results.clear(); + } + +} // namespace gnsstk diff --git a/core/lib/GNSSCore/CorrectionResults.hpp b/core/lib/GNSSCore/CorrectionResults.hpp new file mode 100644 index 000000000..adc948a69 --- /dev/null +++ b/core/lib/GNSSCore/CorrectionResults.hpp @@ -0,0 +1,85 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_CORRECTIONRESULTS_HPP +#define GNSSTK_CORRECTIONRESULTS_HPP + +#include "CorrectionResult.hpp" +#include "CorrDupHandling.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Class for containing a series of computed biases from the + * GroupPathCorrector classes. */ + class CorrectionResults + { + public: + /// Declaring it explicitly so people don't complain. + CorrectionResults() = default; + /** Add a result to the ordered list. + * @param[in] res The result to be added. */ + void addResult(const CorrectionResult& res); + /// Empty the contents of #results. + void clear(); + /// Get the ordered list of #results. + const CorrectionResultList& getResults() const; + /** Get the sum of results, filtering duplicates as indicated. + * @param[in] dups How duplicates are filtered. + * * ComputeFirst means the first result of any given type + * (e.g. Iono) that is contained within #results will be + * incorporated into the final sum, while others of that + * type will not. + * * UseFirst behaves the same as ComputeFirst + * * ComputeLast means the last result of any given type + * that is contained within #results will be + * incorporated into the final sum, while others of that + * type will not. + * @return The sum of all corrections of unique types. */ + double getCorrSum(CorrDupHandling dups) const; + private: + CorrectionResultList results; ///< The computed biases. + }; + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_CORRECTIONRESULTS_HPP diff --git a/core/lib/GNSSCore/CorrectorType.cpp b/core/lib/GNSSCore/CorrectorType.cpp new file mode 100644 index 000000000..f83386376 --- /dev/null +++ b/core/lib/GNSSCore/CorrectorType.cpp @@ -0,0 +1,74 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "CorrectorType.hpp" + +namespace gnsstk +{ + namespace StringUtils + { + std::string asString(CorrectorType e) noexcept + { + switch (e) + { + case CorrectorType::Unknown: return "Unknown"; + case CorrectorType::Trop: return "Trop"; + case CorrectorType::Iono: return "Iono"; + case CorrectorType::ISC: return "ISC"; + case CorrectorType::Multipath: return "Multipath"; + default: return "???"; + } // switch (e) + } // asString(CorrectorType) + + + CorrectorType asCorrectorType(const std::string& s) noexcept + { + if (s == "Unknown") + return CorrectorType::Unknown; + if (s == "Trop") + return CorrectorType::Trop; + if (s == "Iono") + return CorrectorType::Iono; + if (s == "ISC") + return CorrectorType::ISC; + if (s == "Multipath") + return CorrectorType::Multipath; + return CorrectorType::Unknown; + } // asCorrectorType(string) + } // namespace StringUtils +} // namespace gnsstk diff --git a/core/lib/GNSSCore/CorrectorType.hpp b/core/lib/GNSSCore/CorrectorType.hpp new file mode 100644 index 000000000..51eacd663 --- /dev/null +++ b/core/lib/GNSSCore/CorrectorType.hpp @@ -0,0 +1,80 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_CORRECTORTYPE_HPP +#define GNSSTK_CORRECTORTYPE_HPP + +#include +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /// Identify different sources of pseudorange bias. + enum class CorrectorType + { + Unknown, ///< Corrector type is not known or is uninitialized. + Trop, ///< Troposphere (weather) corrector. + Iono, ///< Ionospheric corrector. + ISC, ///< Inter-signal bias corrector. + Multipath, ///< Multipath corrector. + Last ///< Used to create an iterator. + }; + + /** Define an iterator so C++11 can do things like + * for (CorrectorType i : CorrectorTypeIterator()) */ + typedef EnumIterator CorrectorTypeIterator; + /// Set of message types, used by NavLibrary and NavDataFactory. + typedef std::set CorrectorTypeSet; + + namespace StringUtils + { + /// Convert a CorrectorType to a whitespace-free string name. + std::string asString(CorrectorType e) noexcept; + /// Convert a string name to an CorrectorType + CorrectorType asCorrectorType(const std::string& s) noexcept; + } + + //@} + +} + +#endif // GNSSTK_CORRECTORTYPE_HPP diff --git a/core/lib/GNSSCore/GlobalTropModel.hpp b/core/lib/GNSSCore/GlobalTropModel.hpp index fe4fe5d7e..dc503a01d 100644 --- a/core/lib/GNSSCore/GlobalTropModel.hpp +++ b/core/lib/GNSSCore/GlobalTropModel.hpp @@ -50,7 +50,7 @@ namespace gnsstk { - /** @addtogroup GPSsolutions */ + /** @addtogroup GNSSsolutions */ //@{ /** Tropospheric model based on the Global mapping functions (GMF) diff --git a/core/lib/GNSSCore/GroupPathCorr.cpp b/core/lib/GNSSCore/GroupPathCorr.cpp new file mode 100644 index 000000000..08593226a --- /dev/null +++ b/core/lib/GNSSCore/GroupPathCorr.cpp @@ -0,0 +1,184 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#include "GroupPathCorr.hpp" +#include "BCISCorrector.hpp" +#include "BCIonoCorrector.hpp" +#include "TropCorrector.hpp" + +namespace gnsstk +{ + bool GroupPathCorr :: + init(std::shared_ptr& navLib) + { + GroupPathCorrectorPtr ec1, ec2; + ec1 = std::make_shared(); + ec2 = std::make_shared(); + BCISCorrector *isc = dynamic_cast(ec1.get()); + BCIonoCorrector *iono = dynamic_cast(ec2.get()); + isc->navLib = navLib; + iono->navLib = navLib; + calcs.push_back(ec1); + calcs.push_back(ec2); + // No error conditions. Yet. Still returning true/false so + // that we CAN indicate error conditions in the future + // without an API change. + return true; + } + + + bool GroupPathCorr :: + initGlobal(std::shared_ptr& navLib, + const std::string& rinMetFile) + { + if (!init(navLib)) + { + return false; + } + GroupPathCorrectorPtr ec3; + ec3 = std::make_shared(); + if (!rinMetFile.empty()) + { + gnsstk::GlobalTropCorrector *trop; + trop = dynamic_cast(ec3.get()); + if (!trop->loadFile(rinMetFile)) + { + return false; + } + } + calcs.push_back(ec3); + return true; + } + + + bool GroupPathCorr :: + initNB(std::shared_ptr& navLib, + const std::string& rinMetFile) + { + if (!init(navLib)) + { + return false; + } + GroupPathCorrectorPtr ec3; + ec3 = std::make_shared(); + if (!rinMetFile.empty()) + { + gnsstk::NBTropCorrector *trop; + trop = dynamic_cast(ec3.get()); + if (!trop->loadFile(rinMetFile)) + { + return false; + } + } + calcs.push_back(ec3); + return true; + } + + + bool GroupPathCorr :: + getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, CorrectionResults& corrOut, CorrDupHandling dups) + { + // We always iterate through calcs in the same direction + // regardless of the value of dups. It is a known + // compromise, so we don't have to duplicate code to use + // forward or reverse iterators. You're never going to have + // hundreds of group path correctors, as there simply aren't + // that many models in existence, so it's a reasonable choice + // for a handful of items to iterate over. + bool rv = true; + corrOut.clear(); + CorrectorTypeSet seen; + double tmp; + for (const auto& calc : calcs) + { + if ((dups == CorrDupHandling::ComputeFirst) && + (seen.count(calc->corrType) > 0)) + { + continue; + } + if (!calc->getCorr(rxPos, svPos, sat, obs, when, nav, tmp)) + { + rv = false; + } + else + { + CorrectionResult res(tmp, calc); + corrOut.addResult(res); + seen.insert(calc->corrType); + } + } + return rv; + } + + + bool GroupPathCorr :: + getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, CorrectionResults& corrOut, CorrDupHandling dups) + { + Position sp(svPos.x); + return getCorr(rxPos, sp, sat, obs, when, nav, corrOut, dups); + } + + + bool GroupPathCorr :: + getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, double& corrOut, CorrDupHandling dups) + { + CorrectionResults res; + bool rv = getCorr(rxPos, svPos, sat, obs, when, nav, res, dups); + corrOut = res.getCorrSum(dups); + return rv; + } + + + bool GroupPathCorr :: + getCorr(const Position& rxPos, const Xvt& svPos, const SatID& sat, + const ObsID& obs, const CommonTime& when, NavType nav, + double& corrOut, CorrDupHandling dups) + { + CorrectionResults res; + bool rv = getCorr(rxPos, svPos, sat, obs, when, nav, res, dups); + corrOut = res.getCorrSum(dups); + return rv; + } +} // namespace gnsstk diff --git a/core/lib/GNSSCore/GroupPathCorr.hpp b/core/lib/GNSSCore/GroupPathCorr.hpp new file mode 100644 index 000000000..ffa660d86 --- /dev/null +++ b/core/lib/GNSSCore/GroupPathCorr.hpp @@ -0,0 +1,179 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#ifndef GNSSTK_GROUPPATHCORR_HPP +#define GNSSTK_GROUPPATHCORR_HPP + +#include +#include "Position.hpp" +#include "Xvt.hpp" +#include "SatID.hpp" +#include "ObsID.hpp" +#include "CommonTime.hpp" +#include "NavID.hpp" +#include "GroupPathCorrector.hpp" +#include "CorrectionResults.hpp" +#include "NavLibrary.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Provide a class for summing a set of group path corrections. + * Use it by instantiating the GroupPathCorrector objects that + * are desired and adding them to #calcs. Then, call getCorr() + * for each observation to be corrected. + * @code + * GroupPathCorr pec; + * GroupPathCorrectorPtr iono = std::make_shared(); + * GroupPathCorrectorPtr trop = std::make_shared(); + * GroupPathCorrectorPtr isc = std::make_shared(); + * pec.calcs.push_back(iono); + * pec.calcs.push_back(trop); + * pec.calcs.push_back(isc); + * ... + * if (!pec.getCorr(rxPos, svPos, sat, obsID, when, nav, corrOut)) + * return false; + * cout << "Correction sum: " << corrOut << endl; + * @endcode + * + * You may wish to use the init(), initGlobal(), initNB() method + * or manually add GroupPathCorrector objects as noted above, or + * really you can use both. The ordering of the correctors is + * key to how the results work, but is only relevant when e.g. an + * ISC from broadcast nav data is allowed and ISC data from a + * simple text file (not currently supported, example only) is + * added. + * + * @note The Global and New Brunwswick Trop models are the most + * accurate models and are the only ones supported in this + * fashion. This keeps us from implementing a method for each + * trop model, and avoids using template dynamic unsupported by + * Python. + */ + class GroupPathCorr + { + public: + /// Declaring it explicitly so people don't complain. + GroupPathCorr() = default; + + /** Fill calcs with the default set of BCISCorrector and + * BCIonoCorrector. + * @param[in] navLib The NavLibrary for the correctors to use. + * @return true on success, false on error. */ + bool init(std::shared_ptr& navLib); + + /** Fill calcs with the default set of BCISCorrector, + * BCIonoCorrector and GlobalTropCorrector. + * @param[in] navLib The NavLibrary for the correctors to use. + * @param[in] rinMetFile A path to a RINEX MET file to read + * for trop corrections. If no path is specified (the + * variable is left blank), no data will be read and it + * will be up to the caller to do any loading of data + * later. + * @return true on success, false on error. */ + bool initGlobal(std::shared_ptr& navLib, + const std::string& rinMetFile = ""); + + /** Fill calcs with the default set of BCISCorrector, + * BCIonoCorrector and NBTropCorrector. + * @param[in] navLib The NavLibrary for the correctors to use. + * @param[in] rinMetFile A path to a RINEX MET file to read + * for trop corrections. If no path is specified (the + * variable is left blank), no data will be read. The + * NBTropModel in this case will use its own internal data + * model. + * @return true on success, false on error. */ + bool initNB(std::shared_ptr& navLib, + const std::string& rinMetFile = ""); + + /** @param[in] dups Indicate how duplicate CorrectorType + * objects will be used. + * * ComputeFirst indicates the sum should include the + * first valid correction of a given type, and no + * further computation of that type will be done after + * the first valid correction is computed. + * * ComputeLast indicates the sum should include the + * last valid correction of a given type (all + * corrections will be necessarily computed). + * * UseFirst indicates the sum should include the first + * valid correction of a given type, but the + * CorrectionResults object will include biases for + * all GroupPathCorrector objects in #calcs. + * @note A return value of false only indicates that one or + * more of the GroupPathCorrector objects in #calcs + * returned a false. There may still be usable corrections + * returned. It is up to the caller to decide whether or + * not to use a partial success. Example: Corrector 1 + * spans time t1-t2, Corrector 2 spans time t2-t3. The + * getCorr() method for Corrector 1 might return true for a + * time within the span of t1-t2 while Corrector 2 might + * not. + * @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + */ + bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, CorrectionResults& corrOut, + CorrDupHandling dups = CorrDupHandling::ComputeFirst); + /// @copydoc getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, CorrectionResults&, CorrDupHandling) + bool getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, CorrectionResults& corrOut, + CorrDupHandling dups = CorrDupHandling::ComputeFirst); + /// @copydoc getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, CorrectionResults&, CorrDupHandling) + bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, const CommonTime& when, + NavType nav, double& corrOut, + CorrDupHandling dups = CorrDupHandling::ComputeFirst); + /// @copydoc getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, CorrectionResults&, CorrDupHandling) + bool getCorr(const Position& rxPos, const Xvt& svPos, const SatID& sat, + const ObsID& obs, const CommonTime& when, NavType nav, + double& corrOut, + CorrDupHandling dups = CorrDupHandling::ComputeFirst); + + /// The list of GroupPathCorrector objects to use in the calculation. + GroupPathCorrectorList calcs; + }; // class GroupPathCorr + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_GROUPPATHCORR_HPP diff --git a/core/lib/GNSSCore/GroupPathCorrector.hpp b/core/lib/GNSSCore/GroupPathCorrector.hpp new file mode 100644 index 000000000..2af4d3720 --- /dev/null +++ b/core/lib/GNSSCore/GroupPathCorrector.hpp @@ -0,0 +1,99 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#ifndef GNSSTK_GROUPPATHCORRECTOR_HPP +#define GNSSTK_GROUPPATHCORRECTOR_HPP + +#include +#include +#include "Position.hpp" +#include "Xvt.hpp" +#include "SatID.hpp" +#include "ObsID.hpp" +#include "CommonTime.hpp" +#include "NavID.hpp" +#include "CorrectorType.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Provide an abstract base class that defines the interface + * for a series of classes that are used to compute pseudorange + * bias. Used by GroupPathCorr. */ + class GroupPathCorrector + { + public: + /// Set the #corrType to Unknown by default. + GroupPathCorrector() + : corrType(CorrectorType::Unknown) + {} + /** Get the bias in meters given the supplied state arguments. + * @param[in] rxPos The position of the GNSS receiver antenna. + * @param[in] svPos The position of the satellite with delayed signal. + * @param[in] sat The identity of the satellite with delayed signal. + * @param[in] obs The ID of the signal being un-delayed. + * @param[in] when The time of measurement. + * @param[in] nav The navigation message type of the signal. + * @param[out] corrOut The computed bias in meters. + * @return true if successful, false on error. */ + virtual bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) = 0; + /// @copydoc getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + virtual bool getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) = 0; + /// Set by child classes, indicates what type of bias is computed. + CorrectorType corrType; + }; // class GroupPathCorrector + + /// Short-hand for shared_ptr. + typedef std::shared_ptr GroupPathCorrectorPtr; + /// Short-hand for container. + typedef std::list GroupPathCorrectorList; + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_GROUPPATHCORRECTOR_HPP diff --git a/core/lib/GNSSCore/IonoModel.hpp b/core/lib/GNSSCore/IonoModel.hpp index aeb795db0..4ace59291 100644 --- a/core/lib/GNSSCore/IonoModel.hpp +++ b/core/lib/GNSSCore/IonoModel.hpp @@ -51,7 +51,7 @@ namespace gnsstk { - /// @ingroup GPSsolutions + /// @ingroup GNSSsolutions //@{ /** Simple model of the ionosphere ("Klobuchar"), specified in the GPS IS. diff --git a/core/lib/GNSSCore/IonoModelStore.hpp b/core/lib/GNSSCore/IonoModelStore.hpp index 644205b3b..2390a3885 100644 --- a/core/lib/GNSSCore/IonoModelStore.hpp +++ b/core/lib/GNSSCore/IonoModelStore.hpp @@ -52,7 +52,7 @@ namespace gnsstk { - /// @ingroup GPSsolutions + /// @ingroup GNSSsolutions //@{ /** This class defines an interface to hide how we determine diff --git a/core/lib/GNSSCore/TropCorrector.hpp b/core/lib/GNSSCore/TropCorrector.hpp new file mode 100644 index 000000000..4904c5837 --- /dev/null +++ b/core/lib/GNSSCore/TropCorrector.hpp @@ -0,0 +1,267 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + + +#ifndef GNSSTK_TROPCORRECTOR_HPP +#define GNSSTK_TROPCORRECTOR_HPP + +#include "GroupPathCorrector.hpp" +#include "SimpleTropModel.hpp" +#include "SaasTropModel.hpp" +#include "NBTropModel.hpp" +#include "GGTropModel.hpp" +#include "GGHeightTropModel.hpp" +#include "NeillTropModel.hpp" +#include "GlobalTropModel.hpp" +#include "MetReader.hpp" +#include "YDSTime.hpp" + +// forward declaration of test class +class GroupPathCorr_T; + +namespace gnsstk +{ + /// @ingroup GNSSsolutions + //@{ + + /** Provide a means for estimating the pseudorange delay due to + * tropospheric conditions. To use it, instantiate one of the + * typedefs, then call one of either setDefaultWx() or + * loadFile() (the most recently called will be used to set the + * model's weather data). At that point, the getCorr() methods + * may be used. + * @code + * gnsstk::GlobalTropCorrector trop; + * double corr; + * if (!trop.loadFile("arlm2000.15m")) + * return false; + * if (!trop.getCorr(stnPos, svPos, sat, obsID, when, nav, corr)) + * return false; + * cout << "trop delay: " << corr << " m" << endl; + * @endcode + * + * @note The NBTropModel::setWeather() approach (calling with no + * arguments so that the data may be modeled using latitude and + * time) can be used by simply not calling setDefaultWx() or + * loadFile() either one. This approach is unique to + * NBTropModel. All other models will indicate an error + * condition if no weather data is loaded. + * + * @param Model The tropospheric model class, which is expected + * to be derived from the TropModel class. Since there is a + * relatively limited number of these, there are typedefs for + * each of the existing TropModel classes. */ + template + class TropCorrector : public GroupPathCorrector + { + public: + /// Set the #corrType to Trop for GroupPathCorr. + TropCorrector(); + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) + bool getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) override; + /** Set default weather data if no time series is available + * @param[in] temp The new default temperature (degrees C). + * @param[in] pres The new default pressure (millibars). + * @param[in] hum The new default humidity (%). */ + virtual void setDefaultWx(double temp=20, double pres=1013, + double hum=50); + /// Load RINEX MET data into wxData, uses Model + virtual bool loadFile(const std::string& fn); + /// Read and store weather data for look-up (single site) + MetReader wxData; + protected: + /// Set to true if setDefaultWx was called more recently than loadFile + bool useDefault; + double defTemp; ///< Default temperature value (degrees C). + double defPres; ///< Default pressure value (millibars). + double defHum; ///< Default humidity (%). + + /** Tell the model what weather to use. + * @param[in,out] model The model whose weather data is to be set. + * @param[in] when The time of the GNSS observation. + * @post The weather data for model is set. */ + virtual void setWeather(Model& model, const CommonTime& when); + + // For testing. Tried adding a const ref accessor, but SWIG + // complained about it. This is the easier solution. + friend class ::GroupPathCorr_T; + }; // class TropCorrector + + + /// Somewhat pointless wrapper for zero trop correction model. + typedef TropCorrector ZeroTropCorrector; + /// Wrapper for the "simple" trop model. + typedef TropCorrector SimpleTropCorrector; + /// Wrapper for the Saastamoinen trop model. + typedef TropCorrector SaasTropCorrector; + /// Wrapper for the Univeristy of New Brunswick trop model. + typedef TropCorrector NBTropCorrector; + /// Wrapper for the Goad and Goodman trop model. + typedef TropCorrector GGTropCorrector; + /// Wrapper for the Goad and Goodman trop model with heights. + typedef TropCorrector GGHeightTropCorrector; + /// Wrapper for the A.E. Neill trop model. + typedef TropCorrector NeillTropCorrector; + /// Wrapper for the global trop model (Boehm et al). + typedef TropCorrector GlobalTropCorrector; + + //@} + + template + TropCorrector :: + TropCorrector() + : useDefault(false), + defTemp(std::numeric_limits::quiet_NaN()), + defPres(std::numeric_limits::quiet_NaN()), + defHum(std::numeric_limits::quiet_NaN()) + { + corrType = CorrectorType::Trop; + } + + + template + bool TropCorrector :: + getCorr(const Position& rxPos, const Position& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + Model model; + model.setReceiverHeight(rxPos.height()); + model.setReceiverLatitude(rxPos.getGeodeticLatitude()); + model.setReceiverLongitude(rxPos.getLongitude()); + model.setDayOfYear(YDSTime(when).doy); + try + { + setWeather(model, when); + corrOut = model.correction(rxPos, svPos, when); + return true; + } + catch (...) + { + corrOut = std::numeric_limits::quiet_NaN(); + return false; + } + } + + + template + bool TropCorrector :: + getCorr(const Position& rxPos, const Xvt& svPos, + const SatID& sat, const ObsID& obs, + const CommonTime& when, NavType nav, + double& corrOut) + { + Position svp(svPos.x); + return getCorr(rxPos, svp, sat, obs, when, nav, corrOut); + } + + + template + void TropCorrector :: + setDefaultWx(double temp, double pres, double hum) + { + useDefault = true; + defTemp = temp; + defPres = pres; + defHum = hum; + } + + + template + bool TropCorrector :: + loadFile(const std::string& fn) + { + useDefault = false; + wxData.read(fn); + return true; + } + + + template + void TropCorrector :: + setWeather(Model& model, const CommonTime& when) + { + if (!useDefault) + { + model.setWeather(wxData.wx.getWxObservation(when)); + } + else + { + model.setWeather(defTemp, defPres, defHum); + } + } + + + /// Template specialization for NBTropModel. + template <> + inline void TropCorrector :: + setWeather(NBTropModel& model, const CommonTime& when) + { + if (!useDefault) + { + if (wxData.wx.obs.empty()) + { + // Haven't used the default weather via + // setDefaultWx() and if loadFile was called, it was + // unsuccessful. Maybe using the New Brunswick + // special case, so try that. + model.setWeather(); + } + else + { + model.setWeather(wxData.wx.getWxObservation(when)); + } + } + else + { + model.setWeather(defTemp, defPres, defHum); + } + } + +} // namespace gnsstk + +#endif // GNSSTK_TROPCORRECTOR_HPP diff --git a/core/lib/GNSSCore/TropModel.hpp b/core/lib/GNSSCore/TropModel.hpp index 986c098ab..e6bf62efe 100644 --- a/core/lib/GNSSCore/TropModel.hpp +++ b/core/lib/GNSSCore/TropModel.hpp @@ -75,7 +75,7 @@ namespace gnsstk { - /** @addtogroup GPSsolutions */ + /** @addtogroup GNSSsolutions */ //@{ diff --git a/core/lib/NewNav/InterSigCorr.hpp b/core/lib/NewNav/InterSigCorr.hpp index 22124031e..a4bd965b2 100644 --- a/core/lib/NewNav/InterSigCorr.hpp +++ b/core/lib/NewNav/InterSigCorr.hpp @@ -47,13 +47,62 @@ namespace gnsstk /// @ingroup NavFactory //@{ + /** \page APIguide + * - \subpage iscprimer Inter-Signal Corrections: A Primer + * \page iscprimer Inter-Signal Corrections: A Primer + * + * \section iscprimerintro Introduction + * + * All GNSS signals transmitted by a satellite are referenced to + * a clock within that satellite. Each broadcast signal + * potentially also has a different electrical path that it + * follows within the satellite. The methods for accounting for + * these biases are referred to as Inter-Signal Corrections + * (ISCs). Applying an ISC to any signal other than the + * reference signal removes the electrical path group delay + * bias, relative to the reference signal, restoring that + * signal's time stamp tie to the SV clock. + * + * \section iscprimerget Getting ISC Data + * + * ISC data can be obtained from broadcast navigation messages, + * or from product files such as the daily DCB/DSB solutions + * generated by the German Space Operations Center. + * + * ISC data must be requested using a combination of the + * following information: + * 1. Originating signal identifier + * 2. Time of interest + * + * The above may be used in a call to NavLibrary::getISC() to + * obtain the desired data. These biases are always identified + * by a pair of signals, however, in the NavLibrary::getISC() + * implementation, a single ObsID representing the originating + * signal identifier may be used. In this case, the system's + * (constellation's) reference signal will be understood to be + * used as the target signal identifier. + * + * \section iscprimersign Sign Convention + * + * The following sign convention is used by InterSigCorr: + * + * \f{eqnarray*}{ + * {bias} &=& {pseudorange} - {true\ range} \\ + * {pseudorange} &=& {true\ range} + {bias} \\ + * {true\ range} &=& {pseudorange} - {bias} + * \f} + * + * This convention is the same as used in the SINEX_BIAS file + * format, and is also in common with corrections broadcast by + * most (if not all) GNSSes. + */ + /** Class representing SV-based inter-signal bias correction information. * @note All ObsIDs added to refOids or validOids should change * the "type" field to "Unknown", and all derived classes that * override the getISC methods should also make copies of the * input ObsID parameters and set the type to unknown in order - * to consistently match. - * @todo Document in detail how this is meant to be used. */ + * to consistently match. */ class InterSigCorr : public NavData { public: diff --git a/core/lib/NewNav/NavDataFactoryWithStore.cpp b/core/lib/NewNav/NavDataFactoryWithStore.cpp index df409b54e..70a71da12 100644 --- a/core/lib/NewNav/NavDataFactoryWithStore.cpp +++ b/core/lib/NewNav/NavDataFactoryWithStore.cpp @@ -1236,6 +1236,13 @@ namespace gnsstk GLOFNavData *glof; GLOCNavData *gloc; NavHealthData *hea; + // This is a kludge to handle those cases where we don't have + // a valid satellite ID, e.g. RINEX iono corrections. + if (ndp->signal.xmitSat.id == 0) + { + DEBUGTRACE("assuming health matches for missing sat ID"); + return true; + } switch (xmitHealth) { case SVHealth::Healthy: diff --git a/core/lib/NewNav/NavLibrary.cpp b/core/lib/NewNav/NavLibrary.cpp index cd1c40f16..51e1440bb 100644 --- a/core/lib/NewNav/NavLibrary.cpp +++ b/core/lib/NewNav/NavLibrary.cpp @@ -222,17 +222,18 @@ namespace gnsstk bool NavLibrary :: - getISC(const ObsID& oid, const CommonTime& when, double& corrOut) + getISC(const SatID& sat, const ObsID& oid, const CommonTime& when, + double& corrOut, SVHealth xmitHealth, NavValidityType valid, + NavSearchOrder order) { DEBUGTRACE_FUNCTION(); - std::list msgIDs(getISCNMID(oid)); + std::list msgIDs(getISCNMID(sat, oid)); if (msgIDs.empty()) return false; NavDataPtr navOut; for (const auto& nmid : msgIDs) { - if (find(nmid, when, navOut, SVHealth::Healthy, - NavValidityType::ValidOnly, NavSearchOrder::Nearest)) + if (find(nmid, when, navOut, xmitHealth, valid, order)) { InterSigCorr *isc = dynamic_cast(navOut.get()); // This if test allows getISC to fail and the loop to @@ -245,266 +246,142 @@ namespace gnsstk } - bool NavLibrary :: - getISC(const ObsID& oid1, const ObsID& oid2, const CommonTime& when, - double& corrOut) - { - DEBUGTRACE_FUNCTION(); - // This ugly mess is a special case as GPS LNAV does not have - // ISCs that apply to the iono-free combined pseudorange. - if ((oid1.band == CarrierBand::L1) && (oid2.band == CarrierBand::L2) && - ((oid1.code == TrackingCode::CA) || - (oid1.code == TrackingCode::P) || - (oid1.code == TrackingCode::Y) || - (oid1.code == TrackingCode::Ztracking) || - (oid1.code == TrackingCode::YCodeless) || - (oid1.code == TrackingCode::Semicodeless)) && - ((oid2.code == TrackingCode::P) || - (oid2.code == TrackingCode::Y) || - (oid2.code == TrackingCode::Ztracking) || - (oid2.code == TrackingCode::YCodeless) || - (oid2.code == TrackingCode::Semicodeless))) - { - corrOut = 0.0; - return true; - } - std::list msgIDs(getISCNMID(oid1,oid2)); - if (msgIDs.empty()) - return false; - NavDataPtr navOut; - for (const auto& nmid : msgIDs) - { - if (find(nmid, when, navOut, SVHealth::Healthy, - NavValidityType::ValidOnly, NavSearchOrder::Nearest)) - { - InterSigCorr *isc = dynamic_cast(navOut.get()); - // This if test allows getISC to fail and the loop to - // continue and attempt to find another match. - if (isc->getISC(oid1, oid2, corrOut)) - return true; - } - } - return false; - } - - std::list NavLibrary :: - getISCNMID(const ObsID& oid) + getISCNMID(const SatID& sat, const ObsID& oid) { DEBUGTRACE_FUNCTION(); std::list rv; - const SatID gpsAnySat(SatelliteSystem::GPS); const ObsID anyObs(ObservationType::NavMsg, CarrierBand::Any, TrackingCode::Any, XmitAnt::Any); - NavMessageID nmid( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::Unknown), - NavMessageType::ISC); - switch (oid.code) + if (sat.system == SatelliteSystem::GPS) { - case TrackingCode::CA: - if (oid.band == CarrierBand::L1) - { - nmid.nav = NavType::GPSLNAV; - rv.push_back(nmid); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL2), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL5), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - break; - case TrackingCode::P: - case TrackingCode::Y: - case TrackingCode::Ztracking: - case TrackingCode::YCodeless: - case TrackingCode::Semicodeless: - switch (oid.band) - { - case CarrierBand::L1: - case CarrierBand::L2: + const SatID gpsAnySat(SatelliteSystem::GPS); + NavMessageID nmid( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::Unknown), + NavMessageType::ISC); + switch (oid.code) + { + case TrackingCode::CA: + if (oid.band == CarrierBand::L1) + { + nmid.nav = NavType::GPSLNAV; + rv.push_back(nmid); rv.push_back( NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSLNAV), + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL2), NavMessageType::ISC)); - break; - } - break; - case TrackingCode::MD: - case TrackingCode::MDP: - case TrackingCode::MP: - case TrackingCode::MPA: - case TrackingCode::MARLD: - case TrackingCode::MARLP: - case TrackingCode::Mprime: - case TrackingCode::MprimePA: - switch (oid.band) - { - case CarrierBand::L1: - case CarrierBand::L2: rv.push_back( NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSMNAV), + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL5), NavMessageType::ISC)); - break; - } - break; - case TrackingCode::L2CM: - case TrackingCode::L2CL: - case TrackingCode::L2CML: - if (oid.band == CarrierBand::L2) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL2), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL5), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - break; - case TrackingCode::L5I: - case TrackingCode::L5Q: - case TrackingCode::L5IQ: - if (oid.band == CarrierBand::L5) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL5), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL2), - NavMessageType::ISC)); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - break; - case TrackingCode::L1CP: - case TrackingCode::L1CD: - case TrackingCode::L1CDP: - if (oid.band == CarrierBand::L1) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - break; - } - return rv; - } - - - std::list NavLibrary :: - getISCNMID(const ObsID& oid1, const ObsID& oid2) - { - DEBUGTRACE_FUNCTION(); - std::list rv; - const SatID gpsAnySat(SatelliteSystem::GPS); - const ObsID anyObs(ObservationType::NavMsg, - CarrierBand::Any, - TrackingCode::Any, - XmitAnt::Any); - if ((oid1.band == CarrierBand::L1) && - (oid1.code == TrackingCode::CA) && - (((oid2.band == CarrierBand::L5) && - ((oid2.code == TrackingCode::L5I) || - (oid2.code == TrackingCode::L5Q))) || - ((oid2.band == CarrierBand::L2) && - ((oid2.code == TrackingCode::L2CM) || - (oid2.code == TrackingCode::L2CL) || - (oid2.code == TrackingCode::L2CML))))) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL2), - NavMessageType::ISC)); - NavMessageID l5( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAVL5), - NavMessageType::ISC); - // Push the codes so they're in order preferring the same - // band, mostly because it's expected that if you're - // processing L2 you'll have L2 nav data, etc. - if (oid2.band == CarrierBand::L5) - rv.push_front(l5); - else - rv.push_back(l5); - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - else if ((oid1.band == CarrierBand::L1) && - ((oid1.code == TrackingCode::L1CP) || - (oid1.code == TrackingCode::L1CD)) && - (oid2.band == CarrierBand::L2) && - ((oid2.code == TrackingCode::L2CM) || - (oid2.code == TrackingCode::L2CL) || - (oid2.code == TrackingCode::L2CML))) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSCNAV2), - NavMessageType::ISC)); - } - else if ((oid1.band == CarrierBand::L1) && - (oid2.band == CarrierBand::L2) && - ((oid1.code == TrackingCode::MD) || - (oid1.code == TrackingCode::MDP) || - (oid1.code == TrackingCode::MP) || - (oid1.code == TrackingCode::MPA) || - (oid1.code == TrackingCode::MARLD) || - (oid1.code == TrackingCode::MARLP) || - (oid1.code == TrackingCode::Mprime) || - (oid1.code == TrackingCode::MprimePA)) && - ((oid2.code == TrackingCode::MD) || - (oid2.code == TrackingCode::MDP) || - (oid2.code == TrackingCode::MP) || - (oid2.code == TrackingCode::MPA) || - (oid2.code == TrackingCode::MARLD) || - (oid2.code == TrackingCode::MARLP) || - (oid2.code == TrackingCode::Mprime) || - (oid2.code == TrackingCode::MprimePA))) - { - rv.push_back( - NavMessageID( - NavSatelliteID(gpsAnySat, gpsAnySat, anyObs, - NavType::GPSMNAV), - NavMessageType::ISC)); - } + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAV2), + NavMessageType::ISC)); + } + break; + case TrackingCode::P: + case TrackingCode::Y: + case TrackingCode::Ztracking: + case TrackingCode::YCodeless: + case TrackingCode::Semicodeless: + switch (oid.band) + { + case CarrierBand::L1: + case CarrierBand::L2: + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSLNAV), + NavMessageType::ISC)); + break; + } + break; + case TrackingCode::MD: + case TrackingCode::MDP: + case TrackingCode::MP: + case TrackingCode::MPA: + case TrackingCode::MARLD: + case TrackingCode::MARLP: + case TrackingCode::Mprime: + case TrackingCode::MprimePA: + switch (oid.band) + { + case CarrierBand::L1: + case CarrierBand::L2: + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSMNAV), + NavMessageType::ISC)); + break; + } + break; + case TrackingCode::L2CM: + case TrackingCode::L2CL: + case TrackingCode::L2CML: + if (oid.band == CarrierBand::L2) + { + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL2), + NavMessageType::ISC)); + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL5), + NavMessageType::ISC)); + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAV2), + NavMessageType::ISC)); + } + break; + case TrackingCode::L5I: + case TrackingCode::L5Q: + case TrackingCode::L5IQ: + if (oid.band == CarrierBand::L5) + { + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL5), + NavMessageType::ISC)); + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAVL2), + NavMessageType::ISC)); + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAV2), + NavMessageType::ISC)); + } + break; + case TrackingCode::L1CP: + case TrackingCode::L1CD: + case TrackingCode::L1CDP: + if (oid.band == CarrierBand::L1) + { + rv.push_back( + NavMessageID( + NavSatelliteID(sat, gpsAnySat, anyObs, + NavType::GPSCNAV2), + NavMessageType::ISC)); + } + break; + } + } // if (sat.system == SatelliteSystem::GPS) + /// @todo Add support for other GNSSes to getISCNMID. return rv; } diff --git a/core/lib/NewNav/NavLibrary.hpp b/core/lib/NewNav/NavLibrary.hpp index 719483787..b556d0656 100644 --- a/core/lib/NewNav/NavLibrary.hpp +++ b/core/lib/NewNav/NavLibrary.hpp @@ -574,9 +574,10 @@ namespace gnsstk * whether the orbit data came from LNAV or CNAV or CNAV2. * * \li Get ionospheric correction data... - * * Sadly, this is not available in an abstract fashion at this - * time, and if this data is needed, one will have to - * process the system-specific data. + * * Use the NavLibrary::getIonoCorr() method, or use + * NavLibrary::find() while specifying NavMessageType::Iono, + * then calling the IonoNavData::getIonoCorr() method on the + * resulting match. * * \li Get satellite XVT/health/time offset (aka clock * correction) from arbitrary input... @@ -694,19 +695,6 @@ namespace gnsstk * (ephemeris or almanac), then simply use the getXvt() * method with different times. * - * @todo GLONASS probably has health information in its - * non-Keplerian ephemeris data, but SP3 does not. The GLONASS - * data have not been implemented yet in this library but at - * some point a decision will need to be made. It might make - * sense to move the health field up to the OrbitData class and - * simply set it to "Unknown" for SP3. - * - * @todo Determine if OrbitDataKepler::beginFit and - * OrbitDataKepler::endFit need to be moved up to OrbitData. - * This mostly (if not exclusively) affects GLONASS orbits and - * OrbitDataSP3. If so, NavDataLibraryWithStore needs to - * reflect this change. - * * @todo Determine if a URA in meters should be added to * OrbitDataKepler or OrbitData. * @@ -1154,54 +1142,38 @@ namespace gnsstk NavType nt = NavType::Any, int freqOffs = 0, bool freqOffsWild = true); - /** Get inter-signal corrections for the single-frequency user. + /** Get inter-signal corrections. + * @param[in] sat The satellite whose inter-signal + * corrections are to be obtained. * @param[in] oid The carrier band and tracking code of the * signal to get the correction for. * @param[in] when The time of the observation being * corrected. This time is also used to look up ISC data. * @param[out] corrOut The correction in seconds for the * given band/code. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. * @return true If band/code are valid for this object and * corrOut was set according to available data. */ - bool getISC(const ObsID& oid, const CommonTime& when, double& corrOut); - - /** Get inter-signal corrections for the dual-frequency user. - * @param[in] oid1 The carrier band/tracking code of the - * primary signal that was used to create a dual-frequency, - * iono-free combined pseudorange. - * @param[in] oid2 The carrier band/tracking code of the - * secondary signal to get the correction for. - * @param[in] when The time of the observation being - * corrected. This time is also used to look up ISC data. - * @param[out] corrOut The correction in seconds for the given - * band/code pair. - * @return true If bands/codes are valid for this object and - * corrOut was set according to available data. */ - bool getISC(const ObsID& oid1, const ObsID& oid2, const CommonTime& when, - double& corrOut); + bool getISC(const SatID& sat, const ObsID& oid, const CommonTime& when, + double& corrOut, SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User); /** Get an appropriate NavMessageID to use to perform a - * search for ISC data for a given ObsID in a - * single-frequency user case. + * search for ISC data for a given SatID and ObsID. + * @param[in] sat The satellite whose inter-signal + * corrections are to be obtained. * @param[in] oid The ObsID for which ISCs are desired. * @return A list of appropriate NavMessageID objects to use * for searching. This list will be empty if oid is not a * signal for which ISC data sources are known. */ - static std::list getISCNMID(const ObsID& oid); - - /** Get an appropriate NavMessageID to use to perform a - * search for ISC data for a given pair of ObsID in a - * dual-frequency user case. - * @param[in] oid1 The carrier band/tracking code of the - * primary signal that was used to create a dual-frequency, - * iono-free combined pseudorange. - * @param[in] oid2 The carrier band/tracking code of the - * secondary signal to get the correction for. - * @return A list of appropriate NavMessageID objects to use - * for searching. This list will be empty if oid is not a - * signal for which ISC data sources are known. */ - static std::list getISCNMID(const ObsID& oid1, - const ObsID& oid2); + static std::list getISCNMID(const SatID& sat, + const ObsID& oid); /** Search factories to find the navigation message that meets * the specified criteria. diff --git a/core/lib/NewNav/RinexNavDataFactory.hpp b/core/lib/NewNav/RinexNavDataFactory.hpp index 39d4b904a..e1ddd0291 100644 --- a/core/lib/NewNav/RinexNavDataFactory.hpp +++ b/core/lib/NewNav/RinexNavDataFactory.hpp @@ -57,10 +57,7 @@ namespace gnsstk class RinexNavDataFactory : public NavDataFactoryWithStoreFile { public: - /** Fill supportedSignals. - * @note Currently only GPS nav is supported so only that - * will be added to supportedSignals. - */ + /// Fill supportedSignals. RinexNavDataFactory(); /// Clean up. diff --git a/core/lib/PosSol/PRSolution.hpp b/core/lib/PosSol/PRSolution.hpp index 23110e06a..94d5a55b2 100644 --- a/core/lib/PosSol/PRSolution.hpp +++ b/core/lib/PosSol/PRSolution.hpp @@ -58,7 +58,8 @@ namespace gnsstk { - /** @defgroup GPSsolutions GPS solution algorithms and Tropospheric models */ + /** @defgroup GNSSsolutions GNSS solution algorithms + * Solution algorithms and Tropospheric models. */ //@{ /// Class WtdAveStats encapsulates statistics on the PR solution and residuals diff --git a/core/tests/FileHandling/CMakeLists.txt b/core/tests/FileHandling/CMakeLists.txt index 634c16d77..aa22b6233 100644 --- a/core/tests/FileHandling/CMakeLists.txt +++ b/core/tests/FileHandling/CMakeLists.txt @@ -103,3 +103,8 @@ add_executable(SEM_T SEM_T.cpp) target_link_libraries(SEM_T gnsstk) add_test(NAME FileHandling_SEM COMMAND $) set_property(TEST FileHandling_SEM PROPERTY LABELS FileHandling) + +add_executable(MetReader_T MetReader_T.cpp) +target_link_libraries(MetReader_T gnsstk) +add_test(NAME FileHandling_MetReader COMMAND $) +set_property(TEST FileHandling_MetReader PROPERTY LABELS FileHandling) diff --git a/core/tests/FileHandling/MetReader_T.cpp b/core/tests/FileHandling/MetReader_T.cpp new file mode 100644 index 000000000..e637172fd --- /dev/null +++ b/core/tests/FileHandling/MetReader_T.cpp @@ -0,0 +1,114 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "MetReader.hpp" +#include "build_config.h" +#include "TestUtil.hpp" + +using namespace std; + +class MetReader_T +{ +public: + unsigned constructorTest(); + unsigned readTest(); + static const string goodMet, nonExist; +}; + +const string MetReader_T::goodMet(gnsstk::getPathData() + gnsstk::getFileSep() + + "arlm2000.15m"); +const string MetReader_T::nonExist(gnsstk::getFileSep() + "hi" + + gnsstk::getFileSep() + "there"); + +unsigned MetReader_T :: +constructorTest() +{ + TUDEF("MetReader", "MetReader"); + gnsstk::MetReader uut1; + TUASSERTE(unsigned, 0, uut1.verboseLevel); + try + { + gnsstk::MetReader uut2(goodMet); + TUPASS("file read"); + TUASSERTE(unsigned, 96, uut2.wx.obs.size()); + } + catch (...) + { + TUFAIL("Unexpected exception opening \"" + goodMet + "\""); + } + try + { + gnsstk::MetReader uut3(nonExist); + TUFAIL("file read"); + } + catch (gnsstk::FileMissingException) + { + TUPASS("Caught the right exception"); + } + catch (...) + { + TUFAIL("Caught wrong exception"); + } + TURETURN(); +} + + +unsigned MetReader_T :: +readTest() +{ + TUDEF("MetReader", "read"); + gnsstk::MetReader uut; + TUASSERTE(bool, true, uut.read(goodMet)); + TUASSERTE(unsigned, 96, uut.wx.obs.size()); + TUASSERTE(bool, false, uut.read(nonExist)); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + MetReader_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.readTest(); + + cout << "Total Failures for " << __FILE__ << ": " << errorTotal << endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/BCISCorrector_T.cpp b/core/tests/GNSSCore/BCISCorrector_T.cpp new file mode 100644 index 000000000..15d7f402b --- /dev/null +++ b/core/tests/GNSSCore/BCISCorrector_T.cpp @@ -0,0 +1,161 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "BCISCorrector.hpp" +#include "NavLibrary.hpp" +#include "MultiFormatNavDataFactory.hpp" +#include "CivilTime.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, CorrectorType t) + { + s << StringUtils::asString(t); + return s; + } +} + +class BCISCorrector_T +{ +public: + BCISCorrector_T(); + unsigned constructorTest(); + unsigned getCorrTestPosition(); + unsigned getCorrTestXvt(); + std::string dataPath; +}; + + +BCISCorrector_T :: +BCISCorrector_T() +{ + dataPath = gnsstk::getPathData() + gnsstk::getFileSep(); +} + + +unsigned BCISCorrector_T :: +constructorTest() +{ + TUDEF("BCISCorrector", "BCISCorrector"); + gnsstk::BCISCorrector uut; + TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::ISC, uut.corrType); + TUASSERT(!uut.navLib); + TURETURN(); +} + + +unsigned BCISCorrector_T :: +getCorrTestPosition() +{ + TUDEF("BCISCorrector", "getCorr(Position)"); + gnsstk::BCISCorrector uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(2, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + uut.navLib = navLib; + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(2.04890966415e-08, corr); + TURETURN(); +} + + +unsigned BCISCorrector_T :: +getCorrTestXvt() +{ + TUDEF("BCISCorrector", "getCorr(Xvt)"); + gnsstk::BCISCorrector uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Xvt svPos; + svPos.x = gnsstk::Triple(-16208820.579, -207275.833, 21038422.516); + // The rest are just bunk with the intent that if the algorithm + // is changed to include the data somehow, the assertion fails. + svPos.v = gnsstk::Triple(123,456,789); + svPos.clkbias = 234; + svPos.clkdrift = 345; + svPos.relcorr = 456; + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(2, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + uut.navLib = navLib; + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(2.04890966415e-08, corr); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + BCISCorrector_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.getCorrTestPosition(); + errorTotal += testClass.getCorrTestXvt(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/BCIonoCorrector_T.cpp b/core/tests/GNSSCore/BCIonoCorrector_T.cpp new file mode 100644 index 000000000..7907bddd8 --- /dev/null +++ b/core/tests/GNSSCore/BCIonoCorrector_T.cpp @@ -0,0 +1,161 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "BCIonoCorrector.hpp" +#include "NavLibrary.hpp" +#include "MultiFormatNavDataFactory.hpp" +#include "CivilTime.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, CorrectorType t) + { + s << StringUtils::asString(t); + return s; + } +} + +class BCIonoCorrector_T +{ +public: + BCIonoCorrector_T(); + unsigned constructorTest(); + unsigned getCorrTestPosition(); + unsigned getCorrTestXvt(); + std::string dataPath; +}; + + +BCIonoCorrector_T :: +BCIonoCorrector_T() +{ + dataPath = gnsstk::getPathData() + gnsstk::getFileSep(); +} + + +unsigned BCIonoCorrector_T :: +constructorTest() +{ + TUDEF("BCIonoCorrector", "BCIonoCorrector"); + gnsstk::BCIonoCorrector uut; + TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::Iono, uut.corrType); + TUASSERT(!uut.navLib); + TURETURN(); +} + + +unsigned BCIonoCorrector_T :: +getCorrTestPosition() +{ + TUDEF("BCIonoCorrector", "getCorr(Position)"); + gnsstk::BCIonoCorrector uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); + gnsstk::CommonTime when(gnsstk::CivilTime(2006,10,1,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "mixed.06n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + uut.navLib = navLib; + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(3.623343027333741, corr); + TURETURN(); +} + + +unsigned BCIonoCorrector_T :: +getCorrTestXvt() +{ + TUDEF("BCIonoCorrector", "getCorr(Xvt)"); + gnsstk::BCIonoCorrector uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Xvt svPos; + svPos.x = gnsstk::Triple(-16208820.579, -207275.833, 21038422.516); + // The rest are just bunk with the intent that if the algorithm + // is changed to include the data somehow, the assertion fails. + svPos.v = gnsstk::Triple(123,456,789); + svPos.clkbias = 234; + svPos.clkdrift = 345; + svPos.relcorr = 456; + gnsstk::CommonTime when(gnsstk::CivilTime(2006,10,1,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "mixed.06n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + uut.navLib = navLib; + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(3.623343027333741, corr); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + BCIonoCorrector_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.getCorrTestPosition(); + errorTotal += testClass.getCorrTestXvt(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/CMakeLists.txt b/core/tests/GNSSCore/CMakeLists.txt index 65f3f79ab..bbbf77f06 100644 --- a/core/tests/GNSSCore/CMakeLists.txt +++ b/core/tests/GNSSCore/CMakeLists.txt @@ -221,5 +221,50 @@ add_test(NAME GNSSCore_HelmertTransformer COMMAND $) +set_property(TEST GNSSCore_GroupPathCorrector PROPERTY LABELS Solutions) + +add_executable(BCISCorrector_T BCISCorrector_T.cpp) +target_link_libraries(BCISCorrector_T gnsstk) +add_test(NAME GNSSCore_BCISCorrector COMMAND $) +set_property(TEST GNSSCore_BCISCorrector PROPERTY LABELS Solutions) + +add_executable(BCIonoCorrector_T BCIonoCorrector_T.cpp) +target_link_libraries(BCIonoCorrector_T gnsstk) +add_test(NAME GNSSCore_BCIonoCorrector COMMAND $) +set_property(TEST GNSSCore_BCIonoCorrector PROPERTY LABELS Solutions) + +add_executable(TropCorrector_T TropCorrector_T.cpp) +target_link_libraries(TropCorrector_T gnsstk) +add_test(NAME GNSSCore_TropCorrector COMMAND $) +set_property(TEST GNSSCore_TropCorrector PROPERTY LABELS Solutions) + +add_executable(CorrectorType_T CorrectorType_T.cpp) +target_link_libraries(CorrectorType_T gnsstk) +add_test(NAME GNSSCore_CorrectorType COMMAND $) +set_property(TEST GNSSCore_CorrectorType PROPERTY LABELS Solutions) + +add_executable(CorrDupHandling_T CorrDupHandling_T.cpp) +target_link_libraries(CorrDupHandling_T gnsstk) +add_test(NAME GNSSCore_CorrDupHandling COMMAND $) +set_property(TEST GNSSCore_CorrDupHandling PROPERTY LABELS Solutions) + +add_executable(GroupPathCorr_T GroupPathCorr_T.cpp) +target_link_libraries(GroupPathCorr_T gnsstk) +add_test(NAME GNSSCore_GroupPathCorr COMMAND $) +set_property(TEST GNSSCore_GroupPathCorr PROPERTY LABELS Solutions) + +add_executable(CorrectionResult_T CorrectionResult_T.cpp) +target_link_libraries(CorrectionResult_T gnsstk) +add_test(NAME GNSSCore_CorrectionResult COMMAND $) +set_property(TEST GNSSCore_CorrectionResult PROPERTY LABELS Solutions) + +add_executable(CorrectionResults_T CorrectionResults_T.cpp) +target_link_libraries(CorrectionResults_T gnsstk) +add_test(NAME GNSSCore_CorrectionResults COMMAND $) +set_property(TEST GNSSCore_CorrectionResults PROPERTY LABELS Solutions) + ############################################################################### ############################################################################### diff --git a/core/tests/GNSSCore/CorrDupHandling_T.cpp b/core/tests/GNSSCore/CorrDupHandling_T.cpp new file mode 100644 index 000000000..1d461eaea --- /dev/null +++ b/core/tests/GNSSCore/CorrDupHandling_T.cpp @@ -0,0 +1,90 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "CorrDupHandling.hpp" +#include "TestUtil.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, gnsstk::CorrDupHandling e) + { + s << StringUtils::asString(e); + return s; + } +} + + +class CorrDupHandling_T +{ +public: + unsigned convertTest(); +}; + + +unsigned CorrDupHandling_T :: +convertTest() +{ + TUDEF("CorrDupHandling", "asString"); + // This effectively tests CorrDupHandlingIterator, asString and + // asCorrDupHandling all at once. + for (gnsstk::CorrDupHandling e : gnsstk::CorrDupHandlingIterator()) + { + TUCSM("asString"); + std::string s(gnsstk::StringUtils::asString(e)); + TUASSERT(!s.empty()); + TUASSERT(s != "???"); + TUCSM("asCorrDupHandling"); + gnsstk::CorrDupHandling e2 = gnsstk::StringUtils::asCorrDupHandling(s); + TUASSERTE(gnsstk::CorrDupHandling, e, e2); + } + TURETURN(); +} + + +int main() +{ + CorrDupHandling_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.convertTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/ext/lib/Rxio/MetReader.hpp b/core/tests/GNSSCore/CorrectionResult_T.cpp similarity index 75% rename from ext/lib/Rxio/MetReader.hpp rename to core/tests/GNSSCore/CorrectionResult_T.cpp index 0d4847c57..ca441bcb2 100644 --- a/ext/lib/Rxio/MetReader.hpp +++ b/core/tests/GNSSCore/CorrectionResult_T.cpp @@ -36,35 +36,36 @@ // //============================================================================== -#ifndef METREADER_HPP -#define METREADER_HPP +#include "TestUtil.hpp" +#include "CorrectionResult.hpp" -#include - -#include "CommandOption.hpp" -#include "WxObsMap.hpp" - -namespace gnsstk -{ -class MetReader +class CorrectionResult_T { public: - MetReader() - : verboseLevel(0) - {}; + unsigned constructorTest(); +}; - MetReader(const std::string& fn) - : verboseLevel(0) - { read(fn); }; - int verboseLevel; +unsigned CorrectionResult_T :: +constructorTest() +{ + TUDEF("CorrectionResult", "CorrectionResult"); + gnsstk::CorrectionResult uut; + TUASSERTE(bool, true, std::isnan(uut.result)); + TUASSERT(uut.source == nullptr); + TURETURN(); +} + - void read(const std::string& fn); +int main() +{ + unsigned errorTotal = 0; + CorrectionResult_T testClass; - std::vector filesRead; + errorTotal += testClass.constructorTest(); - gnsstk::WxObsData wx; + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; -}; + return errorTotal; } -#endif diff --git a/core/tests/GNSSCore/CorrectionResults_T.cpp b/core/tests/GNSSCore/CorrectionResults_T.cpp new file mode 100644 index 000000000..172b8d82d --- /dev/null +++ b/core/tests/GNSSCore/CorrectionResults_T.cpp @@ -0,0 +1,153 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "CorrectionResults.hpp" + +/// Simple class that lets us set the corrType field directly. +class TestCorrector : public gnsstk::GroupPathCorrector +{ +public: + TestCorrector(gnsstk::CorrectorType ct) + { corrType = ct; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 2.0; + return true; + } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 2.0; + return true; + } +}; + + +class CorrectionResults_T +{ +public: + unsigned constructorTest(); + unsigned addGetClearResultsTest(); + unsigned getCorrSumTest(); +}; + + +unsigned CorrectionResults_T :: +constructorTest() +{ + TUDEF("CorrectionResults", "CorrectionResults"); + gnsstk::CorrectionResults uut; + TUASSERTE(bool, true, uut.getResults().empty()); + TURETURN(); +} + + +unsigned CorrectionResults_T :: +addGetClearResultsTest() +{ + TUDEF("CorrectionResults", "addResult/getResults"); + gnsstk::CorrectionResults uut; + // Add an arbitrarily chosen number of results and make sure + // they all appear to be added properly. + for (unsigned i = 1; i < 5; i++) + { + gnsstk::CorrectionResult foo; + foo.result = i; + TUCATCH(uut.addResult(foo)); + const gnsstk::CorrectionResultList &results = uut.getResults(); + TUASSERTE(size_t, i, results.size()); + TUASSERTFE((double)i, results.rbegin()->result); + } + TUCSM("clear"); + uut.clear(); + TUASSERTE(bool, true, uut.getResults().empty()); + TURETURN(); +} + + +unsigned CorrectionResults_T :: +getCorrSumTest() +{ + TUDEF("CorrectionResults", "getCorrSum"); + gnsstk::CorrectionResults uut; + // create our references for the results to use + auto tc1 = std::make_shared(gnsstk::CorrectorType::ISC); + auto tc2 = std::make_shared(gnsstk::CorrectorType::Iono); + auto tc3 = std::make_shared(gnsstk::CorrectorType::Trop); + auto tc4 = std::make_shared(gnsstk::CorrectorType::ISC); + auto tc5 = std::make_shared(gnsstk::CorrectorType::Multipath); + // create our "results" + gnsstk::CorrectionResult r1(1.0, tc1); + gnsstk::CorrectionResult r2(2.0, tc2); + gnsstk::CorrectionResult r3(4.0, tc3); + gnsstk::CorrectionResult r4(8.0, tc4); + gnsstk::CorrectionResult r5(16.0, tc5); + // Add the results. + uut.addResult(r1); + uut.addResult(r2); + uut.addResult(r3); + uut.addResult(r4); + uut.addResult(r5); + // Now check the getCorrSum() method. + TUASSERTFE(23.0, uut.getCorrSum(gnsstk::CorrDupHandling::ComputeFirst)); + TUASSERTFE(23.0, uut.getCorrSum(gnsstk::CorrDupHandling::UseFirst)); + TUASSERTFE(30.0, uut.getCorrSum(gnsstk::CorrDupHandling::ComputeLast)); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + CorrectionResults_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.addGetClearResultsTest(); + errorTotal += testClass.getCorrSumTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/CorrectorType_T.cpp b/core/tests/GNSSCore/CorrectorType_T.cpp new file mode 100644 index 000000000..caee46d4c --- /dev/null +++ b/core/tests/GNSSCore/CorrectorType_T.cpp @@ -0,0 +1,90 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "CorrectorType.hpp" +#include "TestUtil.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, gnsstk::CorrectorType e) + { + s << StringUtils::asString(e); + return s; + } +} + + +class CorrectorType_T +{ +public: + unsigned convertTest(); +}; + + +unsigned CorrectorType_T :: +convertTest() +{ + TUDEF("CorrectorType", "asString"); + // This effectively tests CorrectorTypeIterator, asString and + // asCorrectorType all at once. + for (gnsstk::CorrectorType e : gnsstk::CorrectorTypeIterator()) + { + TUCSM("asString"); + std::string s(gnsstk::StringUtils::asString(e)); + TUASSERT(!s.empty()); + TUASSERT(s != "???"); + TUCSM("asCorrectorType"); + gnsstk::CorrectorType e2 = gnsstk::StringUtils::asCorrectorType(s); + TUASSERTE(gnsstk::CorrectorType, e, e2); + } + TURETURN(); +} + + +int main() +{ + CorrectorType_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.convertTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/GroupPathCorr_T.cpp b/core/tests/GNSSCore/GroupPathCorr_T.cpp new file mode 100644 index 000000000..91c94f42f --- /dev/null +++ b/core/tests/GNSSCore/GroupPathCorr_T.cpp @@ -0,0 +1,530 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "BCISCorrector.hpp" +#include "BCIonoCorrector.hpp" +#include "TropCorrector.hpp" +#include "GroupPathCorr.hpp" +#include "NavLibrary.hpp" +#include "MultiFormatNavDataFactory.hpp" +#include "CivilTime.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, CorrectorType t) + { + s << StringUtils::asString(t); + return s; + } +} + + +class TestISCorrector1 : public gnsstk::GroupPathCorrector +{ +public: + TestISCorrector1() + { corrType = gnsstk::CorrectorType::ISC; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 2.0; + return true; + } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 2.0; + return true; + } +}; + + +class TestISCorrector2 : public gnsstk::GroupPathCorrector +{ +public: + TestISCorrector2() + { corrType = gnsstk::CorrectorType::ISC; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 4.0; + return true; + } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 4.0; + return true; + } +}; + + +class TestTropCorrector : public gnsstk::GroupPathCorrector +{ +public: + TestTropCorrector() + { corrType = gnsstk::CorrectorType::Trop; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 10.0; + return true; + } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 10.0; + return true; + } +}; + + +class TestIonoCorrector : public gnsstk::GroupPathCorrector +{ +public: + TestIonoCorrector() + { corrType = gnsstk::CorrectorType::Iono; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 20.0; + return true; + } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { + corrOut = 20.0; + return true; + } +}; + + + +class GroupPathCorr_T +{ +public: + GroupPathCorr_T(); + unsigned constructorTest(); + unsigned getCorrTestPositionDouble(); + unsigned getCorrTestXvtDouble(); + unsigned getCorrTestPositionResults(); + unsigned getCorrTestXvtResults(); + unsigned initTest(); + unsigned initGlobalTest(); + unsigned initNBTest(); + std::string dataPath; +}; + + +GroupPathCorr_T :: +GroupPathCorr_T() +{ + dataPath = gnsstk::getPathData() + gnsstk::getFileSep(); +} + + +unsigned GroupPathCorr_T :: +constructorTest() +{ + TUDEF("GroupPathCorr", "GroupPathCorr"); + gnsstk::GroupPathCorr uut; + TUASSERTE(bool, true, uut.calcs.empty()); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +getCorrTestPositionDouble() +{ + TUDEF("GroupPathCorr", "getCorr(Position,double)"); + gnsstk::BCISCorrector *isc; + gnsstk::BCIonoCorrector *iono; + gnsstk::GlobalTropCorrector *trop; + gnsstk::GroupPathCorr uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(2, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3; + ec1 = std::make_shared(); + ec2 = std::make_shared(); + ec3 = std::make_shared(); + isc = dynamic_cast(ec1.get()); + iono = dynamic_cast(ec2.get()); + trop = dynamic_cast(ec3.get()); + TUASSERTE(bool, true, trop->loadFile(dataPath+"arlm2000.15m")); + isc->navLib = navLib; + iono->navLib = navLib; + uut.calcs.push_back(ec1); + uut.calcs.push_back(ec2); + uut.calcs.push_back(ec3); + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(13.399231057432754, corr); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +getCorrTestXvtDouble() +{ + TUDEF("GroupPathCorr", "getCorr(Xvt,double)"); + gnsstk::BCISCorrector *isc; + gnsstk::BCIonoCorrector *iono; + gnsstk::GlobalTropCorrector *trop; + gnsstk::GroupPathCorr uut; + std::shared_ptr navLib; + gnsstk::NavDataFactoryPtr ndf; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Xvt svPos; + svPos.x = gnsstk::Triple(-16208820.579, -207275.833, 21038422.516); + // The rest are just bunk with the intent that if the algorithm + // is changed to include the data somehow, the assertion fails. + svPos.v = gnsstk::Triple(123,456,789); + svPos.clkbias = 234; + svPos.clkdrift = 345; + svPos.relcorr = 456; + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(2, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + ndf = std::make_shared(); + gnsstk::MultiFormatNavDataFactory *mfndf = + dynamic_cast(ndf.get()); + TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); + navLib = std::make_shared(); + TUCATCH(navLib->addFactory(ndf)); + double corr = 0.0; + gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3; + ec1 = std::make_shared(); + ec2 = std::make_shared(); + ec3 = std::make_shared(); + isc = dynamic_cast(ec1.get()); + iono = dynamic_cast(ec2.get()); + trop = dynamic_cast(ec3.get()); + TUASSERTE(bool, true, trop->loadFile(dataPath+"arlm2000.15m")); + isc->navLib = navLib; + iono->navLib = navLib; + uut.calcs.push_back(ec1); + uut.calcs.push_back(ec2); + uut.calcs.push_back(ec3); + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(13.399231057432754, corr); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +getCorrTestPositionResults() +{ + TUDEF("GroupPathCorr", "getCorr(Position,CorrectionResults)"); + gnsstk::GroupPathCorr uut; + gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3, ec4; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + gnsstk::CorrectionResults out; + ec1 = std::make_shared(); + ec2 = std::make_shared(); + ec3 = std::make_shared(); + ec4 = std::make_shared(); + uut.calcs.push_back(ec1); + uut.calcs.push_back(ec2); + uut.calcs.push_back(ec3); + uut.calcs.push_back(ec4); + // These assertions verify that the default dup behavior is + // ComputeFirst and that the ComputeFirst behavior hasn't + // changed. + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out)); + const gnsstk::CorrectionResultList& results1 = out.getResults(); + TUASSERTE(size_t, 3, results1.size()); + TUASSERTFE(32.0, out.getCorrSum(gnsstk::CorrDupHandling::ComputeFirst)); + auto i1 = results1.begin(); + TUASSERTFE(2.0, i1->result); + TUASSERT(i1->source == ec1); + i1++; + TUASSERTFE(20.0, i1->result); + TUASSERT(i1->source == ec2); + i1++; + TUASSERTFE(10.0, i1->result); + TUASSERT(i1->source == ec4); + // check ComputeLast + // note that this also tests that getCorr clears the results first + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out, + gnsstk::CorrDupHandling::ComputeLast)); + const gnsstk::CorrectionResultList& results2 = out.getResults(); + TUASSERTE(size_t, 4, results2.size()); + TUASSERTFE(34.0, out.getCorrSum(gnsstk::CorrDupHandling::ComputeLast)); + auto i2 = results2.begin(); + TUASSERTFE(2.0, i2->result); + TUASSERT(i2->source == ec1); + i2++; + TUASSERTFE(20.0, i2->result); + TUASSERT(i2->source == ec2); + i2++; + TUASSERTFE(4.0, i2->result); + TUASSERT(i2->source == ec3); + i2++; + TUASSERTFE(10.0, i2->result); + TUASSERT(i2->source == ec4); + // check UseFirst + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out, + gnsstk::CorrDupHandling::UseFirst)); + const gnsstk::CorrectionResultList& results3 = out.getResults(); + TUASSERTE(size_t, 4, results3.size()); + TUASSERTFE(32.0, out.getCorrSum(gnsstk::CorrDupHandling::UseFirst)); + auto i3 = results3.begin(); + TUASSERTFE(2.0, i3->result); + TUASSERT(i3->source == ec1); + i3++; + TUASSERTFE(20.0, i3->result); + TUASSERT(i3->source == ec2); + i3++; + TUASSERTFE(4.0, i3->result); + TUASSERT(i3->source == ec3); + i3++; + TUASSERTFE(10.0, i3->result); + TUASSERT(i3->source == ec4); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +getCorrTestXvtResults() +{ + TUDEF("GroupPathCorr", "getCorr(Xvt,CorrectionResults)"); + gnsstk::GroupPathCorr uut; + gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3, ec4; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Xvt svPos; + svPos.x = gnsstk::Triple(-16208820.579, -207275.833, 21038422.516); + // The rest are just bunk with the intent that if the algorithm + // is changed to include the data somehow, the assertion fails. + svPos.v = gnsstk::Triple(123,456,789); + svPos.clkbias = 234; + svPos.clkdrift = 345; + svPos.relcorr = 456; + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + gnsstk::CorrectionResults out; + ec1 = std::make_shared(); + ec2 = std::make_shared(); + ec3 = std::make_shared(); + ec4 = std::make_shared(); + uut.calcs.push_back(ec1); + uut.calcs.push_back(ec2); + uut.calcs.push_back(ec3); + uut.calcs.push_back(ec4); + // These assertions verify that the default dup behavior is + // ComputeFirst and that the ComputeFirst behavior hasn't + // changed. + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out)); + const gnsstk::CorrectionResultList& results1 = out.getResults(); + TUASSERTE(size_t, 3, results1.size()); + TUASSERTFE(32.0, out.getCorrSum(gnsstk::CorrDupHandling::ComputeFirst)); + auto i1 = results1.begin(); + TUASSERTFE(2.0, i1->result); + TUASSERT(i1->source == ec1); + i1++; + TUASSERTFE(20.0, i1->result); + TUASSERT(i1->source == ec2); + i1++; + TUASSERTFE(10.0, i1->result); + TUASSERT(i1->source == ec4); + // check ComputeLast + // note that this also tests that getCorr clears the results first + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out, + gnsstk::CorrDupHandling::ComputeLast)); + const gnsstk::CorrectionResultList& results2 = out.getResults(); + TUASSERTE(size_t, 4, results2.size()); + TUASSERTFE(34.0, out.getCorrSum(gnsstk::CorrDupHandling::ComputeLast)); + auto i2 = results2.begin(); + TUASSERTFE(2.0, i2->result); + TUASSERT(i2->source == ec1); + i2++; + TUASSERTFE(20.0, i2->result); + TUASSERT(i2->source == ec2); + i2++; + TUASSERTFE(4.0, i2->result); + TUASSERT(i2->source == ec3); + i2++; + TUASSERTFE(10.0, i2->result); + TUASSERT(i2->source == ec4); + // check UseFirst + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, out, + gnsstk::CorrDupHandling::UseFirst)); + const gnsstk::CorrectionResultList& results3 = out.getResults(); + TUASSERTE(size_t, 4, results3.size()); + TUASSERTFE(32.0, out.getCorrSum(gnsstk::CorrDupHandling::UseFirst)); + auto i3 = results3.begin(); + TUASSERTFE(2.0, i3->result); + TUASSERT(i3->source == ec1); + i3++; + TUASSERTFE(20.0, i3->result); + TUASSERT(i3->source == ec2); + i3++; + TUASSERTFE(4.0, i3->result); + TUASSERT(i3->source == ec3); + i3++; + TUASSERTFE(10.0, i3->result); + TUASSERT(i3->source == ec4); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +initTest() +{ + TUDEF("GroupPathCorr", "init"); + gnsstk::GroupPathCorr uut; + auto navLib = std::make_shared(); + TUASSERTE(bool, true, uut.init(navLib)); + // While the order isn't important, we assume it hasn't changed. + auto i = uut.calcs.begin(); + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + i++; + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +initGlobalTest() +{ + TUDEF("GroupPathCorr", "initGlobal"); + gnsstk::GroupPathCorr uut; + auto navLib = std::make_shared(); + TUASSERTE(bool, true, uut.initGlobal(navLib, dataPath+"arlm2000.15m")); + // While the order isn't important, we assume it hasn't changed. + auto i = uut.calcs.begin(); + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + i++; + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + i++; + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERTE(bool, false, + dynamic_cast(i->get())->wxData.wx.obs.empty()); + TURETURN(); +} + + +unsigned GroupPathCorr_T :: +initNBTest() +{ + TUDEF("GroupPathCorr", "initNB"); + gnsstk::GroupPathCorr uut; + auto navLib = std::make_shared(); + TUASSERTE(bool, true, uut.initNB(navLib, dataPath+"arlm2000.15m")); + // While the order isn't important, we assume it hasn't changed. + auto i = uut.calcs.begin(); + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + i++; + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERT(dynamic_cast(i->get())->navLib == navLib); + i++; + TUASSERT(dynamic_cast(i->get()) != nullptr); + TUASSERTE(bool, false, + dynamic_cast(i->get())->wxData.wx.obs.empty()); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + GroupPathCorr_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.getCorrTestPositionDouble(); + errorTotal += testClass.getCorrTestXvtDouble(); + errorTotal += testClass.getCorrTestPositionResults(); + errorTotal += testClass.getCorrTestXvtResults(); + errorTotal += testClass.initTest(); + errorTotal += testClass.initGlobalTest(); + errorTotal += testClass.initNBTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/GroupPathCorrector_T.cpp b/core/tests/GNSSCore/GroupPathCorrector_T.cpp new file mode 100644 index 000000000..096374bfa --- /dev/null +++ b/core/tests/GNSSCore/GroupPathCorrector_T.cpp @@ -0,0 +1,103 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "GroupPathCorrector.hpp" +#include "NavLibrary.hpp" +#include "MultiFormatNavDataFactory.hpp" +#include "CivilTime.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, CorrectorType t) + { + s << StringUtils::asString(t); + return s; + } +} + + +/// Make GroupPathCorrector instantiatable for testing. +class TestClass : public gnsstk::GroupPathCorrector +{ +public: + TestClass() + {} + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Position& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { return false; } + bool getCorr(const gnsstk::Position& rxPos, const gnsstk::Xvt& svPos, + const gnsstk::SatID& sat, const gnsstk::ObsID& obs, + const gnsstk::CommonTime& when, gnsstk::NavType nav, + double& corrOut) override + { return false; } +}; + + +class GroupPathCorrector_T +{ +public: + unsigned constructorTest(); +}; + + +unsigned GroupPathCorrector_T :: +constructorTest() +{ + TUDEF("GroupPathCorrector", "GroupPathCorrector"); + TestClass uut; + TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::Unknown, + uut.corrType); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + GroupPathCorrector_T testClass; + + errorTotal += testClass.constructorTest(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/TropCorrector_T.cpp b/core/tests/GNSSCore/TropCorrector_T.cpp new file mode 100644 index 000000000..2906f1554 --- /dev/null +++ b/core/tests/GNSSCore/TropCorrector_T.cpp @@ -0,0 +1,201 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include "TestUtil.hpp" +#include "TropCorrector.hpp" +#include "NavLibrary.hpp" +#include "MultiFormatNavDataFactory.hpp" +#include "CivilTime.hpp" + +namespace gnsstk +{ + std::ostream& operator<<(std::ostream& s, CorrectorType t) + { + s << StringUtils::asString(t); + return s; + } +} + + +template +class TestClass : public gnsstk::TropCorrector +{ +public: + TestClass() + {} + bool getUseDefault() const + { return gnsstk::TropCorrector::useDefault; } + double getDefTemp() const + { return gnsstk::TropCorrector::defTemp; } + double getDefPres() const + { return gnsstk::TropCorrector::defPres; } + double getDefHum() const + { return gnsstk::TropCorrector::defHum; } +}; + + +class TropCorrector_T +{ +public: + TropCorrector_T(); + unsigned constructorTest(); + // These test both getCorr and loadFile. + unsigned getCorrTestPosition(); + unsigned getCorrTestXvt(); + std::string dataPath; +}; + + +TropCorrector_T :: +TropCorrector_T() +{ + dataPath = gnsstk::getPathData() + gnsstk::getFileSep(); +} + + +unsigned TropCorrector_T :: +constructorTest() +{ + TUDEF("TropCorrector", "TropCorrector"); + TestClass uut; + TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::Trop, uut.corrType); + TUASSERTE(bool, true, std::isnan(uut.getDefTemp())); + TUASSERTE(bool, true, std::isnan(uut.getDefPres())); + TUASSERTE(bool, true, std::isnan(uut.getDefHum())); + TUASSERTE(bool, false, uut.getUseDefault()); + // Just make sure the typedefs are still usable. + gnsstk::ZeroTropCorrector uut2; + gnsstk::SimpleTropCorrector uut3; + gnsstk::SaasTropCorrector uut4; + gnsstk::NBTropCorrector uut5; + gnsstk::GGTropCorrector uut6; + gnsstk::GGHeightTropCorrector uut7; + gnsstk::NeillTropCorrector uut8; + gnsstk::GlobalTropCorrector uut9; + TURETURN(); +} + + +unsigned TropCorrector_T :: +getCorrTestPosition() +{ + TUDEF("TropCorrector", "getCorr(Position)"); + TestClass uut; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + double corr = 0.0; + TUCSM("loadFile"); + TUASSERTE(bool, true, uut.loadFile(dataPath+"arlm2000.15m")); + TUCSM("getCorr(Position)"); + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(9.775888009609917, corr); + + // test NBTropModel special handling + TestClass uut2; + TUASSERTE(bool, true, + uut2.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + // epsilon so windows passes ... + TUASSERTFEPS(9.4475001293154239335, corr, 1e-14); + + TestClass uut3; + TUASSERTE(bool, false, + uut3.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + + TestClass uut4; + TUCSM("setDefaultWx"); + uut4.setDefaultWx(); + TUASSERTE(bool, true, + uut4.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + // Different value with the default weather compared without + // implies that it's using those default weather values. + // epsilon so windows passes ... + TUASSERTFEPS(9.1431767236047711833, corr, 1e-14); + TURETURN(); +} + + +unsigned TropCorrector_T :: +getCorrTestXvt() +{ + TUDEF("TropCorrector", "getCorr(Xvt)"); + TestClass uut; + gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); + gnsstk::Xvt svPos; + svPos.x = gnsstk::Triple(-16208820.579, -207275.833, 21038422.516); + // The rest are just bunk with the intent that if the algorithm + // is changed to include the data somehow, the assertion fails. + svPos.v = gnsstk::Triple(123,456,789); + svPos.clkbias = 234; + svPos.clkdrift = 345; + svPos.relcorr = 456; + gnsstk::CommonTime when(gnsstk::CivilTime(2015,7,19,4,30,0, + gnsstk::TimeSystem::Any)); + gnsstk::SatID sat(27, gnsstk::SatelliteSystem::GPS); + gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L1, + gnsstk::TrackingCode::CA); + gnsstk::NavType nav = gnsstk::NavType::GPSLNAV; + double corr = 0.0; + TUCSM("loadFile"); + TUASSERTE(bool, true, uut.loadFile(dataPath+"arlm2000.15m")); + TUCSM("getCorr(Xvt)"); + TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); + TUASSERTFE(9.775888009609917, corr); + TURETURN(); +} + + +int main() +{ + unsigned errorTotal = 0; + TropCorrector_T testClass; + + errorTotal += testClass.constructorTest(); + errorTotal += testClass.getCorrTestPosition(); + errorTotal += testClass.getCorrTestXvt(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/NewNav/NavLibrary_T.cpp b/core/tests/NewNav/NavLibrary_T.cpp index 3d56110e3..d5c0328db 100644 --- a/core/tests/NewNav/NavLibrary_T.cpp +++ b/core/tests/NewNav/NavLibrary_T.cpp @@ -609,6 +609,7 @@ getISCTest() ndfp(std::make_shared()); std::string fname = gnsstk::getPathData() + gnsstk::getFileSep() + "arlm2000.15n"; + const gnsstk::SatID sat(1, gnsstk::SatelliteSystem::GPS); const gnsstk::CommonTime when = gnsstk::CivilTime(2015,7,19,10,0,0, gnsstk::TimeSystem::GPS); const gnsstk::ObsID oid(gnsstk::ObservationType::Phase, gnsstk::CarrierBand::L2, @@ -622,47 +623,10 @@ getISCTest() TUCATCH(uut.addFactory(ndfp)); RinexTestFactory *rndfp = dynamic_cast(ndfp.get()); TUASSERT(rndfp->addDataSource(fname)); - TUASSERTE(bool, true, uut.getISC(oid, when, corr)); + TUASSERTE(bool, true, uut.getISC(sat, oid, when, corr)); TUASSERTFE(expCorr, corr); - // check all the combos that are supposed to have 0 corrections - std::list oid1s({ - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::CA), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::P), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::Y), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::Ztracking), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::YCodeless), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L1, - gnsstk::TrackingCode::Semicodeless) - }); - std::list oid2s({ - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L2, - gnsstk::TrackingCode::P), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L2, - gnsstk::TrackingCode::Y), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L2, - gnsstk::TrackingCode::Ztracking), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L2, - gnsstk::TrackingCode::YCodeless), - gnsstk::ObsID(gnsstk::ObservationType::Range, gnsstk::CarrierBand::L2, - gnsstk::TrackingCode::Semicodeless) - }); - for (const auto& i1 : oid1s) - { - for (const auto& i2 : oid2s) - { - corr = 1.2345; - TUASSERTE(bool, true, uut.getISC(i1, i2, when, corr)); - TUASSERTFE(0.0, corr); - } - } // check wonky obs ID - TUASSERTE(bool, false, uut.getISC(woid1, when, corr)); - TUASSERTE(bool, false, uut.getISC(woid1, woid2, when, corr)); + TUASSERTE(bool, false, uut.getISC(sat, woid1, when, corr)); TURETURN(); } diff --git a/ext/lib/GNSSCore/OceanLoading.hpp b/ext/lib/GNSSCore/OceanLoading.hpp index c8cf36a2b..2a047eb0f 100644 --- a/ext/lib/GNSSCore/OceanLoading.hpp +++ b/ext/lib/GNSSCore/OceanLoading.hpp @@ -58,7 +58,7 @@ namespace gnsstk { - /// @ingroup GPSsolutions + /// @ingroup GNSSsolutions //@{ diff --git a/ext/lib/GNSSCore/PoleTides.hpp b/ext/lib/GNSSCore/PoleTides.hpp index 5615ee869..1094487dc 100644 --- a/ext/lib/GNSSCore/PoleTides.hpp +++ b/ext/lib/GNSSCore/PoleTides.hpp @@ -58,7 +58,7 @@ namespace gnsstk { - /// @ingroup GPSsolutions + /// @ingroup GNSSsolutions //@{ /** This class computes the effect of pole tides, or more properly diff --git a/ref/usersguide/gnsstk.bib b/ref/usersguide/gnsstk.bib index f2991a288..49c07f04b 100644 --- a/ref/usersguide/gnsstk.bib +++ b/ref/usersguide/gnsstk.bib @@ -226,7 +226,7 @@ @Book{ me:gsmp } @Manual{ isgps, - title = "NAVSTAR Global Positioning System Interface Specification (IS-GPS-200), Revision D" + title = "NAVSTAR Global Positioning System Interface Specification (IS-GPS-200), Revision M" } @Book{ ps:gta, diff --git a/swig/FileHandling/FileHandling.i b/swig/FileHandling/FileHandling.i index c3051e040..a36c5068b 100644 --- a/swig/FileHandling/FileHandling.i +++ b/swig/FileHandling/FileHandling.i @@ -221,6 +221,7 @@ from __future__ import absolute_import %template(FileStore_YumaHeader) gnsstk::FileStore; %include "YumaData.hpp" %include "YumaStream.hpp" +%include "MetReader.hpp" // ============================================================= // Section 11: Explicit Python wrappers diff --git a/swig/GNSSCore/GNSSCore.i b/swig/GNSSCore/GNSSCore.i index 21b71761c..23e054524 100644 --- a/swig/GNSSCore/GNSSCore.i +++ b/swig/GNSSCore/GNSSCore.i @@ -59,6 +59,8 @@ ENUM_MAPPER(gnsstk::SatelliteSystem, SatelliteSystem, "gnsstk") ENUM_MAPPER(gnsstk::CarrierBand, CarrierBand, "gnsstk") ENUM_MAPPER(gnsstk::TrackingCode, TrackingCode, "gnsstk") ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") +ENUM_MAPPER(gnsstk::CorrectorType, CorrectorType, "gnsstk") +ENUM_MAPPER(gnsstk::CorrDupHandling, CorrDupHandling, "gnsstk") // needs to be before RefFrameRlz.hpp at the very least. %import "CommonTime.hpp" @@ -67,6 +69,8 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %include "CarrierBand.hpp" %include "TrackingCode.hpp" %include "ObservationType.hpp" +%include "CorrectorType.hpp" +%include "CorrDupHandling.hpp" %include "AngleType.hpp" %include "XmitAnt.hpp" %include "RefFrameSys.hpp" @@ -78,6 +82,8 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") renameEnums('CarrierBand') renameEnums('TrackingCode') renameEnums('ObservationType') + renameEnums('CorrectorType') + renameEnums('CorrDupHandling') renameEnums('AngleType') renameEnums('XmitAnt') renameEnums('RefFrameSys') @@ -97,6 +103,18 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") // Section 7: C++11 shared_ptr handling // ============================================================= +%include "std_shared_ptr.i" +%shared_ptr(gnsstk::GroupPathCorrector) +%shared_ptr(gnsstk::BCIonoCorrector) +%shared_ptr(gnsstk::BCISCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) +%shared_ptr(gnsstk::TropCorrector) %shared_ptr(gnsstk::Transformer) %shared_ptr(gnsstk::HelmertTransformer) @@ -104,6 +122,8 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") // Section 9: typemaps that must be declared before the %includes // ============================================================= +// correction is an output +%apply double &OUTPUT { double &corrOut }; %include "gnsstk_typemaps.i" // ============================================================= @@ -122,6 +142,7 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %import "FFData.hpp" %import "RinexObsBase.hpp" %import "RinexObsHeader.hpp" +%import "NavLibrary.hpp" %import "Vector.hpp" %import "Matrix.hpp" @@ -198,6 +219,23 @@ ENUM_MAPPER(gnsstk::ObservationType, ObservationType, "gnsstk") %include "SimpleTropModel.hpp" %include "TransformLibrary.hpp" %include "convhelp.hpp" +%include "GroupPathCorrector.hpp" +%template(GroupPathCorrectorList) std::list >; +%include "BCIonoCorrector.hpp" +%include "BCISCorrector.hpp" +%include "TropCorrector.hpp" +%template(ZeroTropCorrector) gnsstk::TropCorrector; +%template(SimpleTropCorrector) gnsstk::TropCorrector; +%template(SaasTropCorrector) gnsstk::TropCorrector; +%template(NBTropCorrector) gnsstk::TropCorrector; +%template(GGTropCorrector) gnsstk::TropCorrector; +%template(GGHeightTropCorrector) gnsstk::TropCorrector; +%template(NeillTropCorrector) gnsstk::TropCorrector; +%template(GlobalTropCorrector) gnsstk::TropCorrector; +%include "CorrectionResult.hpp" +%template(CorrectionResultList) std::list; +%include "CorrectionResults.hpp" +%include "GroupPathCorr.hpp" // ============================================================= // Section 11: Explicit Python wrappers diff --git a/swig/NewNav/NewNavSharedPtr.i b/swig/NewNav/NewNavSharedPtr.i index 359757b44..b462c70b4 100644 --- a/swig/NewNav/NewNavSharedPtr.i +++ b/swig/NewNav/NewNavSharedPtr.i @@ -108,3 +108,5 @@ %shared_ptr(gnsstk::PNBGLOFNavDataFactory) // silence warnings from swig %shared_ptr(gnsstk::TimeSystemCorrection) + +%shared_ptr(gnsstk::NavLibrary) diff --git a/swig/Rxio/Rxio.i b/swig/Rxio/Rxio.i index 9fbf1973d..4a0048b2a 100644 --- a/swig/Rxio/Rxio.i +++ b/swig/Rxio/Rxio.i @@ -82,7 +82,6 @@ from __future__ import absolute_import %feature("flatnested", ""); %include "AshtechPBEN.hpp" %include "AshtechStream.hpp" -%include "MetReader.hpp" // ============================================================= // Section 11: Explicit Python wrappers diff --git a/swig/gnsstk_swig.hpp b/swig/gnsstk_swig.hpp index c6e25e0d2..f9e5da7ef 100644 --- a/swig/gnsstk_swig.hpp +++ b/swig/gnsstk_swig.hpp @@ -360,6 +360,15 @@ #include "PNBGalFNavDataFactory.hpp" #include "PNBGalINavDataFactory.hpp" #include "PNBMultiGNSSNavDataFactory.hpp" +#include "CorrectorType.hpp" +#include "CorrDupHandling.hpp" +#include "GroupPathCorrector.hpp" +#include "BCIonoCorrector.hpp" +#include "BCISCorrector.hpp" +#include "TropCorrector.hpp" +#include "CorrectionResult.hpp" +#include "CorrectionResults.hpp" +#include "GroupPathCorr.hpp" #include "stl_helpers.hpp" #include "PRSolution.hpp" #include "PoleTides.hpp" diff --git a/swig/gnsstk_swig.i b/swig/gnsstk_swig.i index 33402da8f..718c80542 100644 --- a/swig/gnsstk_swig.i +++ b/swig/gnsstk_swig.i @@ -440,6 +440,15 @@ %import(module="gnsstk") "PNBGalFNavDataFactory.hpp" %import(module="gnsstk") "PNBGalINavDataFactory.hpp" %import(module="gnsstk") "PNBMultiGNSSNavDataFactory.hpp" +%import(module="gnsstk") "CorrectorType.hpp" +%import(module="gnsstk") "CorrDupHandling.hpp" +%import(module="gnsstk") "GroupPathCorrector.hpp" +%import(module="gnsstk") "BCIonoCorrector.hpp" +%import(module="gnsstk") "BCISCorrector.hpp" +%import(module="gnsstk") "TropCorrector.hpp" +%import(module="gnsstk") "CorrectionResult.hpp" +%import(module="gnsstk") "CorrectionResults.hpp" +%import(module="gnsstk") "GroupPathCorr.hpp" %import(module="gnsstk") "stl_helpers.hpp" %import(module="gnsstk") "PRSolution.hpp" %import(module="gnsstk") "PoleTides.hpp" diff --git a/swig/tests/CMakeLists.txt b/swig/tests/CMakeLists.txt index 42fe203dd..1a82e6cd7 100644 --- a/swig/tests/CMakeLists.txt +++ b/swig/tests/CMakeLists.txt @@ -274,3 +274,4 @@ add_test(NAME swig_test_NavDataFactoryCallback WORKING_DIRECTORY ${td} ) prep_swig_test(swig_test_NavDataFactoryCallback swig) + diff --git a/swig/tests/__init__.py b/swig/tests/__init__.py new file mode 100644 index 000000000..e96277b33 --- /dev/null +++ b/swig/tests/__init__.py @@ -0,0 +1,33 @@ +import unittest + +class AbstractBaseTesters: + class EnumTester(unittest.TestCase): + """ + Generic Enum testing framework + + Tests expected values of enum and string conversions + Inherit this class to test typical gnsstk strongly typed enums. + + For each subclass, create the `ENUM`, `EXP_ENUM_STRS`, and `STR_CONVERTER` + class variables. + + ENUM: The enum to test (e.g. gnsstk.CorrDupHandling) + EXP_ENUM_STRS: A dictionary of enum values and their expected string equivalent + STR_CONVERTER: the function the converts strings into enum values + + """ + + def test_enum(self): + """ + Test enum + """ + actual_items = set(self.ENUM) - {self.ENUM.Last} + self.assertEqual(set(self.EXP_ENUM_STRS.keys()), actual_items) + + for exp_enum, exp_enum_str in self.EXP_ENUM_STRS.items(): + with self.subTest(enum=exp_enum): + self.assertEqual(str(exp_enum), exp_enum_str) + # A weird hack since adding a function as an attribute + # causes automatic binding. + str_converter = self.STR_CONVERTER.__func__ + self.assertEqual(str_converter(exp_enum_str), exp_enum) \ No newline at end of file diff --git a/swig/tests/test_GNSSCore.py b/swig/tests/test_GNSSCore.py index 56776fe6c..83b1efafa 100644 --- a/swig/tests/test_GNSSCore.py +++ b/swig/tests/test_GNSSCore.py @@ -1,10 +1,12 @@ #!/usr/env python import unittest, sys, os +import math sys.path.insert(0, os.path.abspath("..")) from gnsstk.test_utils import args,run_unit_tests import gnsstk +from tests import AbstractBaseTesters class TestGNSSCore(unittest.TestCase): @@ -158,7 +160,336 @@ def test_vectorRinexObsID(self): a.append(c) self.assertTrue(not a.empty()) - #All Trop Models already tested + +class TestBCISCorrector(unittest.TestCase): + """ + Tests for BCISCorrector + """ + + def test_getCorr(self): + """ + Test BCISCorrector setup and getCorr + + Python users should be able to create a BCISCorrector + and compute a correction from inputs. + """ + isc = gnsstk.BCISCorrector() + + navLib = gnsstk.NavLibrary() + isc.navLib = navLib + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Phase,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + rv, corr = isc.getCorr(stnPos, svPos, sat, oid, when, nav) + + self.assertEqual(True, rv) + self.assertAlmostEqual(2.04890966415e-08, corr) + + svXvt = gnsstk.Xvt() + svXvt.x = svPos + rv, corr = isc.getCorr(stnPos, svXvt, sat, oid, when, nav) + + self.assertEqual(True, rv) + self.assertAlmostEqual(2.04890966415e-08, corr) + + +class TestBCIonoCorrector(unittest.TestCase): + """ + Tests for BCIonoCorrector + """ + + def test_getCorr(self): + """ + Test BCIonoCorrector setup and getCorr. + + Python users should be able to create a BCIonoCorrector + and compute a correction from inputs. + """ + iono = gnsstk.BCIonoCorrector() + + navLib = gnsstk.NavLibrary() + iono.navLib = navLib + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "mixed.06n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2006,10,1,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + rv, corr = iono.getCorr(stnPos, svPos, sat, oid, when, nav) + + self.assertEqual(True, rv) + self.assertAlmostEqual(3.623343027333741, corr) + + svXvt = gnsstk.Xvt() + svXvt.x = svPos + rv, corr = iono.getCorr(stnPos, svXvt, sat, oid, when, nav) + + self.assertEqual(True, rv) + self.assertAlmostEqual(3.623343027333741, corr) + + +class TestCorrDupHandling(AbstractBaseTesters.EnumTester): + """ + Test existence and string conversions of CorrDupHandling enum + """ + + ENUM = gnsstk.CorrDupHandling + + EXP_ENUM_STRS = { + gnsstk.CorrDupHandling.Unknown: "Unknown", + gnsstk.CorrDupHandling.ComputeFirst: "ComputeFirst", + gnsstk.CorrDupHandling.ComputeLast: "ComputeLast", + gnsstk.CorrDupHandling.UseFirst: "UseFirst", + } + + STR_CONVERTER = gnsstk.asCorrDupHandling + + +class TestCorrectorType(AbstractBaseTesters.EnumTester): + """ + Test existence and string conversions of CorrectorType enum + """ + + ENUM = gnsstk.CorrectorType + + EXP_ENUM_STRS = { + gnsstk.CorrectorType.Unknown: "Unknown", + gnsstk.CorrectorType.Trop: "Trop", + gnsstk.CorrectorType.Iono: "Iono", + gnsstk.CorrectorType.ISC: "ISC", + gnsstk.CorrectorType.Multipath: "Multipath" + } + + STR_CONVERTER = gnsstk.asCorrectorType + + +class TestCorrectionResult(unittest.TestCase): + """ + Tests for CorrectionResult + """ + + def test_result(self): + """ + Test general manipulation of CorrectionResult object + """ + corr_nan = gnsstk.CorrectionResult() + corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector()) + + self.assertTrue(math.isnan(corr_nan.result)) + self.assertEqual(corr_iono.result, 100) + self.assertEqual(corr_iono.source.corrType, gnsstk.CorrectorType.Iono) + +class TestCorrectionResults(unittest.TestCase): + """ + Tests for CorrectionResults + """ + + def test_results(self): + """ + Test general manipulation of CorrectionResults objects. + + Most important will be the ability to get the total sum of corrections + and getting individual corrections within the list. + """ + corr_results = gnsstk.CorrectionResults() + + corr_trop = gnsstk.CorrectionResult(150, gnsstk.GlobalTropCorrector()) + corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector()) + corr_ISC = gnsstk.CorrectionResult(-75, gnsstk.BCISCorrector()) + corr_ISC2 = gnsstk.CorrectionResult(45, gnsstk.BCISCorrector()) + + corr_results.addResult(corr_trop) + corr_results.addResult(corr_iono) + corr_results.addResult(corr_ISC) + corr_results.addResult(corr_ISC2) + + self.assertEqual(len(corr_results.getResults()), 4) + self.assertEqual(corr_results.getResults()[0].result, 150) + self.assertEqual(corr_results.getCorrSum(gnsstk.CorrDupHandling.ComputeFirst), 175) + self.assertEqual(corr_results.getCorrSum(gnsstk.CorrDupHandling.ComputeLast), 295) + +class TestGroupPathCorr(unittest.TestCase): + """ + Tests of the GroupPathCorr SWIG bindings. + """ + + def test_groupPathCorrManual(self): + """ + Test manual setup of GroupPathCorr. + + GroupPathCorr should allow manually appending correctors. + """ + pec = gnsstk.GroupPathCorr() + + navLib = gnsstk.NavLibrary() + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + iono = gnsstk.BCIonoCorrector() + iono.navLib = navLib + trop = gnsstk.GlobalTropCorrector() + trop.setDefaultWx() + + isc = gnsstk.BCISCorrector() + isc.navLib = navLib + + pec.calcs.append(iono) + pec.calcs.append(trop) + pec.calcs.append(isc) + + rv, corr = pec.getCorr(stnPos, svPos, sat, oid, when, nav) + + self.assertTrue(rv) + self.assertAlmostEqual(corr, 13.085598163018554) + + def test_groupPathCorrInit(self): + """ + Test the `init` method and resulting correction. + + This should automatically setup GroupPathCorr with default ISC and Iono + models. + """ + pec = gnsstk.GroupPathCorr() + + navLib = gnsstk.NavLibrary() + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + rv = pec.init(navLib) + self.assertTrue(rv) + + rv, corr = pec.getCorr(stnPos, svPos, sat, oid, when, nav) + self.assertTrue(rv) + self.assertAlmostEqual(corr, 3.6233430478228374) + + def test_groupPathCorrGlobal(self): + """ + Test the `initGlobal` method and resulting correction. + + This should automatically setup GroupPathCorr with default, ISC, Iono, + and Global Trop models. + """ + pec = gnsstk.GroupPathCorr() + + navLib = gnsstk.NavLibrary() + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + rv = pec.initGlobal(navLib, os.path.join(args.input_dir, "arlm2000.15m")) + self.assertTrue(rv) + + rv, corr = pec.getCorr(stnPos, svPos, sat, oid, when, nav) + self.assertTrue(rv) + self.assertAlmostEqual(corr, 13.399231057432754) + + def test_groupPathCorrNB(self): + """ + Test the `initNB` method and resulting correction + + This should automatically setup GroupPathCorr with default + ISC, Iono, and NB Trop models. + """ + pec = gnsstk.GroupPathCorr() + + navLib = gnsstk.NavLibrary() + ndf = gnsstk.MultiFormatNavDataFactory() + ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) + navLib.addFactory(ndf) + + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) + nav = gnsstk.NavType.GPSLNAV + + rv = pec.initNB(navLib, os.path.join(args.input_dir, "arlm2000.15m")) + self.assertTrue(rv) + + rv, corr = pec.getCorr(stnPos, svPos, sat, oid, when, nav) + self.assertTrue(rv) + self.assertAlmostEqual(corr, 12.468046669500502) + + +class TestTropCorrector(unittest.TestCase): + + def test_getCorr(self): + """ + Test TropCorrector getCorr. + + This is a regression test of the computed trop correction + """ + trop = gnsstk.GlobalTropCorrector() + errcalc = gnsstk.GroupPathCorr() + errcalc.calcs.append(trop) + rv = trop.loadFile(os.path.join(args.input_dir, "arlm2000.15m")) + self.assertEqual(True, rv) + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID() + nav = gnsstk.NavType.GPSLNAV + rv,corr = errcalc.getCorr(stnPos,svPos,sat,oid,when,nav) + self.assertEqual(True, rv) + self.assertAlmostEqual(9.775888009609917, corr) + + def test_getCorrDefaultWx(self): + """ + TropCorrector must accept default weather. + + This also serves as a regression test of the compute correction. + """ + trop = gnsstk.NBTropCorrector() + errcalc = gnsstk.GroupPathCorr() + errcalc.calcs.append(trop) + trop.setDefaultWx(15, 1000, 75) + stnPos = gnsstk.Position(-740290.01, -5457071.705, 3207245.599) + svPos = gnsstk.Position(-16208820.579, -207275.833, 21038422.516) + when = gnsstk.CivilTime(2015,7,19,4,30,0,gnsstk.TimeSystem.Any).toCommonTime() + sat = gnsstk.SatID(27, gnsstk.SatelliteSystem.GPS) + oid = gnsstk.ObsID() + nav = gnsstk.NavType.GPSLNAV + rv,corr = errcalc.getCorr(stnPos,svPos,sat,oid,when,nav) + self.assertEqual(True, rv) + self.assertAlmostEqual(9.06752734042942, corr) if __name__ == '__main__': run_unit_tests() From 00390c305b38145f5558e4b9ddb9036c80433aae Mon Sep 17 00:00:00 2001 From: John Knutson Date: Fri, 9 Dec 2022 15:48:24 -0600 Subject: [PATCH 09/16] Fix swig build error --- .gitlab-ci.yml | 12 ------------ swig/GNSSCore/GNSSCore.i | 1 + 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a23d5ba91..4dbe9cc4b 100755 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -353,11 +353,6 @@ build_debian_11_virtualenv: - build/ expire_in: 4 days -build_conda_py2.7: - variables: - PYTHON_VERSION: "2.7" - extends: .build_conda - build_conda_py3.6: variables: PYTHON_VERSION: "3.6" @@ -620,13 +615,6 @@ test_debian_11_virtualenv: expire_in: 4 days -test_conda_py2.7: - variables: - PYTHON_VERSION: "2.7" - extends: .test_conda - needs: [build_conda_py2.7] - dependencies: [build_conda_py2.7] - test_conda_py3.6: variables: PYTHON_VERSION: "3.6" diff --git a/swig/GNSSCore/GNSSCore.i b/swig/GNSSCore/GNSSCore.i index 23e054524..1d0ec9e81 100644 --- a/swig/GNSSCore/GNSSCore.i +++ b/swig/GNSSCore/GNSSCore.i @@ -145,6 +145,7 @@ ENUM_MAPPER(gnsstk::CorrDupHandling, CorrDupHandling, "gnsstk") %import "NavLibrary.hpp" %import "Vector.hpp" %import "Matrix.hpp" +%import "MetReader.hpp" %include "AngleType.hpp" %include "AngleReduced.hpp" From 643cff774c4c8196414693bc3ccfedd33de3c559 Mon Sep 17 00:00:00 2001 From: johnk Date: Mon, 12 Dec 2022 11:03:30 -0600 Subject: [PATCH 10/16] Add a CorrectorType that was missed --- core/lib/GNSSCore/CorrectorType.cpp | 3 +++ core/lib/GNSSCore/CorrectorType.hpp | 1 + swig/tests/test_GNSSCore.py | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/core/lib/GNSSCore/CorrectorType.cpp b/core/lib/GNSSCore/CorrectorType.cpp index f83386376..3c21e5686 100644 --- a/core/lib/GNSSCore/CorrectorType.cpp +++ b/core/lib/GNSSCore/CorrectorType.cpp @@ -51,6 +51,7 @@ namespace gnsstk case CorrectorType::Iono: return "Iono"; case CorrectorType::ISC: return "ISC"; case CorrectorType::Multipath: return "Multipath"; + case CorrectorType::RxChlBias: return "RxChlBias"; default: return "???"; } // switch (e) } // asString(CorrectorType) @@ -68,6 +69,8 @@ namespace gnsstk return CorrectorType::ISC; if (s == "Multipath") return CorrectorType::Multipath; + if (s == "RxChlBias") + return CorrectorType::RxChlBias; return CorrectorType::Unknown; } // asCorrectorType(string) } // namespace StringUtils diff --git a/core/lib/GNSSCore/CorrectorType.hpp b/core/lib/GNSSCore/CorrectorType.hpp index 51eacd663..d0ec50be1 100644 --- a/core/lib/GNSSCore/CorrectorType.hpp +++ b/core/lib/GNSSCore/CorrectorType.hpp @@ -56,6 +56,7 @@ namespace gnsstk Iono, ///< Ionospheric corrector. ISC, ///< Inter-signal bias corrector. Multipath, ///< Multipath corrector. + RxChlBias, ///< Receiver inter-channel bias corrector. Last ///< Used to create an iterator. }; diff --git a/swig/tests/test_GNSSCore.py b/swig/tests/test_GNSSCore.py index 83b1efafa..800ffe5be 100644 --- a/swig/tests/test_GNSSCore.py +++ b/swig/tests/test_GNSSCore.py @@ -270,7 +270,8 @@ class TestCorrectorType(AbstractBaseTesters.EnumTester): gnsstk.CorrectorType.Trop: "Trop", gnsstk.CorrectorType.Iono: "Iono", gnsstk.CorrectorType.ISC: "ISC", - gnsstk.CorrectorType.Multipath: "Multipath" + gnsstk.CorrectorType.Multipath: "Multipath", + gnsstk.CorrectorType.RxChlBias: "RxChlBias" } STR_CONVERTER = gnsstk.asCorrectorType From 6f46adafeea3ab664f90a957b08e540ad3b6162c Mon Sep 17 00:00:00 2001 From: David Barber Date: Tue, 13 Dec 2022 13:48:11 -0600 Subject: [PATCH 11/16] adding ubuntu-20.04 jobs --- .gitlab-ci.yml | 116 ++++++++++++++++++++++++++++++++++++++++++++-- debian/control | 2 +- debian/control.in | 2 +- 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4dbe9cc4b..8a94b72d5 100755 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -91,6 +91,8 @@ variables: - /^version_.*_prep$/ - stable - /^release\/v[0-9.]*$/ + - /^bugfix\/ci_.*$/ + - /^feature\/ci_.*$/ variables: - $RELEASE_ONLY != "True" && $NO_BIGBUILD_CI != "True" @@ -243,6 +245,23 @@ build_debian_11: paths: - build/ +build_ubuntu_20.04: + stage: build + needs: [] + extends: .normal_build + tags: + - docker-executor + image: $DOCKER_REGISTRY/sgl/ubuntu-20.04:pkgbuild + script: + - mkdir -p build + - cd build + - export gnsstk=`pwd`/install + - cmake -DPYTHON_INSTALL_PREFIX=$gnsstk -DCMAKE_INSTALL_PREFIX=install $CMAKE_ARG_DEFAULT + - make all -j 4 + artifacts: + paths: + - build/ + build_ext_noswig: stage: build needs: [] @@ -550,6 +569,25 @@ test_debian_11: dependencies: - build_debian_11 +test_ubuntu_20.04: + stage: test + needs: [build_ubuntu_20.04] + extends: .normal_build + tags: + - docker-executor + image: $DOCKER_REGISTRY/sgl/ubuntu-20.04:pkgbuild + script: + - cd build + - ctest -j 4 + - touch $CI_PROJECT_DIR/success + artifacts: + when: on_failure + paths: + - build/Testing/Temporary/ + - build/swig/ + dependencies: + - build_ubuntu_20.04 + test_debian_10_virtualenv: stage: test needs: [build_debian_10_virtualenv] @@ -773,6 +811,24 @@ user_install_debian_11: dependencies: - build_debian_11 +user_install_ubuntu_20.04: + stage: install + needs: [build_ubuntu_20.04] + extends: .big_build + tags: + - docker-executor + image: $DOCKER_REGISTRY/sgl/ubuntu-20.04:pkgbuild + script: + - cd build + - export gnsstk=`pwd`/install + - cmake -DPYTHON_INSTALL_PREFIX=$gnsstk -DCMAKE_INSTALL_PREFIX=$gnsstk -DPYTHON_USER_INSTALL=ON ../ + - make install -j 4 + artifacts: + paths: + - build/install + dependencies: + - build_ubuntu_20.04 + virtualenv_install_debian_10: stage: install needs: [build_debian_10_virtualenv] @@ -994,6 +1050,43 @@ package_debian_11: dependencies: - build_debian_11 +package_ubuntu_20.04: + stage: package + needs: [] + variables: + BUILD_TYPE: fast + rules: + # Add this rule to prevent an "additional" single element pipeline for merge requests. + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: never + - if: $CI_COMMIT_REF_NAME =~ /main/ || $CI_COMMIT_REF_NAME =~/^ci_.*$/ || $CI_COMMIT_REF_NAME=~/^version_.*_prep$/ + variables: + BUILD_TYPE: debug + - when: on_success + tags: + - docker-executor + image: $DOCKER_REGISTRY/sgl/ubuntu-20.04:pkgbuild + script: + - rm -rf ../*.deb .gitmodules + # Mark the debian log so that this package is a backport. + # Use the most recent Maintainer as current maintainer. + - export DEBEMAIL=$(dpkg-parsechangelog -S Maintainer) + - dch --bpo "No Changes" && dch -l "ubuntu" -D focal 'No Changes' -u low + - if [ "$BUILD_TYPE" == "debug" ]; then BUILD_PROFILES="pkg_python,debug_package"; else BUILD_PROFILES="pkg_python"; fi + - dpkg-buildpackage --build-profiles=${BUILD_PROFILES} -us -uc -d --changes-option="-DDistribution=focal-sgl" + - mkdir debs + - mv ../*.deb debs + - mv ../*.changes debs + - mv ../*.dsc debs + - mv ../*.git ../*.gitshallow debs + - mv ../*.buildinfo debs + artifacts: + paths: + - debs/ + timeout: 90m + dependencies: + - build_ubuntu_20.04 + package_conda: stage: package needs: [] @@ -1147,6 +1240,22 @@ deploy_debian_11: dependencies: - package_debian_11 +deploy_ubuntu_20.04: + stage: deploy + needs: [package_ubuntu_20.04] + extends: .big_build + tags: + - docker-executor + image: $DOCKER_REGISTRY/sgl/ubuntu-20.04:pkgbuild + script: + - cd debs + - apt-get -y install ./*.deb + - python3 -c "import gnsstk" + - df_diff -h + - gnsstk-config --includedir + dependencies: + - package_ubuntu_20.04 + deploy_redhat_8: stage: deploy needs: [package_redhat_8] @@ -1182,8 +1291,9 @@ deploy_redhat_py36: push_artifacts: extends: .push_selected_artifacts variables: - DEB_10_PACKAGES: "debs/*bpo10*.deb" + DEB_10_PACKAGES: "debs/*bpo10+1_amd64.deb" DEB_11_PACKAGES: "debs/*bpo11*.deb" + UBU_20_PACKAGES: "debs/*bpo10+1ubuntu*.deb" stage: push - needs: [package_conda, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] - dependencies: [package_conda, package_debian_10, package_debian_11, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] \ No newline at end of file + needs: [package_conda, package_debian_10, package_debian_11, package_ubuntu_20.04, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] + dependencies: [package_conda, package_debian_10, package_debian_11, package_ubuntu_20.04, package_redhat_8, package_redhat_8_py36, package_windows_vs2019] \ No newline at end of file diff --git a/debian/control b/debian/control index 3ac0b6e04..71142f4c7 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ # debian/control is generated automatically from control.in by running the clean target Source: gnsstk Priority: optional -Maintainer: Bryan Parsons +Maintainer: David Barber Build-Depends: debhelper (>= 9), cmake, python3-dev , dh-python X-Python3-Version: >= 3.5 Standards-Version: 3.9.5 diff --git a/debian/control.in b/debian/control.in index b9a409a9f..d128edc13 100644 --- a/debian/control.in +++ b/debian/control.in @@ -1,7 +1,7 @@ # debian/control is generated automatically from control.in by running the clean target Source: gnsstk Priority: optional -Maintainer: Bryan Parsons +Maintainer: David Barber Build-Depends: debhelper (>= 9), cmake, python3-dev , dh-python X-Python3-Version: >= 3.5 Standards-Version: 3.9.5 From f95c7e428fb218dc4245b03d3f4d1f4386857106 Mon Sep 17 00:00:00 2001 From: johnk Date: Tue, 13 Dec 2022 17:19:44 -0600 Subject: [PATCH 12/16] Change group path corrector navLib from shared_ptr to reference to work around swig/python problem --- core/lib/GNSSCore/BCISCorrector.cpp | 10 ++--- core/lib/GNSSCore/BCISCorrector.hpp | 9 +++-- core/lib/GNSSCore/BCIonoCorrector.cpp | 23 +++++------- core/lib/GNSSCore/BCIonoCorrector.hpp | 9 +++-- core/lib/GNSSCore/GroupPathCorr.cpp | 12 +++--- core/lib/GNSSCore/GroupPathCorr.hpp | 6 +-- core/tests/GNSSCore/BCISCorrector_T.cpp | 21 +++++------ core/tests/GNSSCore/BCIonoCorrector_T.cpp | 21 +++++------ core/tests/GNSSCore/GroupPathCorr_T.cpp | 46 +++++++++++------------ swig/NewNav/NewNavSharedPtr.i | 2 - swig/tests/test_GNSSCore.py | 26 ++++++------- 11 files changed, 84 insertions(+), 101 deletions(-) diff --git a/core/lib/GNSSCore/BCISCorrector.cpp b/core/lib/GNSSCore/BCISCorrector.cpp index b590b6ab2..d4a3471c8 100644 --- a/core/lib/GNSSCore/BCISCorrector.cpp +++ b/core/lib/GNSSCore/BCISCorrector.cpp @@ -42,7 +42,8 @@ namespace gnsstk { BCISCorrector :: - BCISCorrector() + BCISCorrector(NavLibrary& nl) + : navLib(nl) { corrType = CorrectorType::ISC; } @@ -54,12 +55,9 @@ namespace gnsstk const CommonTime& when, NavType nav, double& corrOut) { - if (navLib) + if (navLib.getISC(sat, obs, when, corrOut)) { - if (navLib->getISC(sat, obs, when, corrOut)) - { - return true; - } + return true; } corrOut = std::numeric_limits::quiet_NaN(); return false; diff --git a/core/lib/GNSSCore/BCISCorrector.hpp b/core/lib/GNSSCore/BCISCorrector.hpp index b1df39846..3335c7834 100644 --- a/core/lib/GNSSCore/BCISCorrector.hpp +++ b/core/lib/GNSSCore/BCISCorrector.hpp @@ -57,8 +57,9 @@ namespace gnsstk class BCISCorrector : public GroupPathCorrector { public: - /// Set the #corrType to ISC for GroupPathCorr. - BCISCorrector(); + /** Set the #corrType to ISC for GroupPathCorr. + * @param[in] nl The NavLibrary to use to obtain ISC data. */ + BCISCorrector(NavLibrary& nl); /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) bool getCorr(const Position& rxPos, const Position& svPos, const SatID& sat, const ObsID& obs, @@ -70,8 +71,8 @@ namespace gnsstk const CommonTime& when, NavType nav, double& corrOut) override; - /// Pointer to the nav library from which we will get ISC data. - std::shared_ptr navLib; + /// Reference to the nav library from which we will get ISC data. + NavLibrary& navLib; }; // class BCISCorrector //@} diff --git a/core/lib/GNSSCore/BCIonoCorrector.cpp b/core/lib/GNSSCore/BCIonoCorrector.cpp index 792e6ebef..ba899f2da 100644 --- a/core/lib/GNSSCore/BCIonoCorrector.cpp +++ b/core/lib/GNSSCore/BCIonoCorrector.cpp @@ -42,7 +42,8 @@ namespace gnsstk { BCIonoCorrector :: - BCIonoCorrector() + BCIonoCorrector(NavLibrary& nl) + : navLib(nl) { corrType = CorrectorType::Iono; } @@ -54,13 +55,10 @@ namespace gnsstk const CommonTime& when, NavType nav, double& corrOut) { - if (navLib) + if (navLib.getIonoCorr(sat.system, when, rxPos, svPos, obs.band, + corrOut, nav)) { - if (navLib->getIonoCorr(sat.system, when, rxPos, svPos, obs.band, - corrOut, nav)) - { - return true; - } + return true; } corrOut = std::numeric_limits::quiet_NaN(); return false; @@ -73,14 +71,11 @@ namespace gnsstk const CommonTime& when, NavType nav, double& corrOut) { - if (navLib) + Position svp(svPos.x); + if (navLib.getIonoCorr(sat.system, when, rxPos, svp, obs.band, + corrOut, nav)) { - Position svp(svPos.x); - if (navLib->getIonoCorr(sat.system, when, rxPos, svp, obs.band, - corrOut, nav)) - { - return true; - } + return true; } corrOut = std::numeric_limits::quiet_NaN(); return false; diff --git a/core/lib/GNSSCore/BCIonoCorrector.hpp b/core/lib/GNSSCore/BCIonoCorrector.hpp index 2377dbbc9..8a4f8dd06 100644 --- a/core/lib/GNSSCore/BCIonoCorrector.hpp +++ b/core/lib/GNSSCore/BCIonoCorrector.hpp @@ -56,8 +56,9 @@ namespace gnsstk class BCIonoCorrector : public GroupPathCorrector { public: - /// Set the #corrType to Iono for GroupPathCorr. - BCIonoCorrector(); + /** Set the #corrType to Iono for GroupPathCorr. + * @param[in] nl The NavLibrary to use to obtain Iono data. */ + BCIonoCorrector(NavLibrary& nl); /// @copydoc GroupPathCorrector::getCorr(const Position&, const Position&, const SatID&, const ObsID&, const CommonTime&, NavType, double&) bool getCorr(const Position& rxPos, const Position& svPos, const SatID& sat, const ObsID& obs, @@ -69,8 +70,8 @@ namespace gnsstk const CommonTime& when, NavType nav, double& corrOut) override; - /// Pointer to the nav library from which we will get iono data. - std::shared_ptr navLib; + /// Reference to the nav library from which we will get iono data. + NavLibrary& navLib; }; // class BCIonoCorrector //@} diff --git a/core/lib/GNSSCore/GroupPathCorr.cpp b/core/lib/GNSSCore/GroupPathCorr.cpp index 08593226a..bc33c7a5b 100644 --- a/core/lib/GNSSCore/GroupPathCorr.cpp +++ b/core/lib/GNSSCore/GroupPathCorr.cpp @@ -45,15 +45,13 @@ namespace gnsstk { bool GroupPathCorr :: - init(std::shared_ptr& navLib) + init(NavLibrary& navLib) { GroupPathCorrectorPtr ec1, ec2; - ec1 = std::make_shared(); - ec2 = std::make_shared(); + ec1 = std::make_shared(navLib); + ec2 = std::make_shared(navLib); BCISCorrector *isc = dynamic_cast(ec1.get()); BCIonoCorrector *iono = dynamic_cast(ec2.get()); - isc->navLib = navLib; - iono->navLib = navLib; calcs.push_back(ec1); calcs.push_back(ec2); // No error conditions. Yet. Still returning true/false so @@ -64,7 +62,7 @@ namespace gnsstk bool GroupPathCorr :: - initGlobal(std::shared_ptr& navLib, + initGlobal(NavLibrary& navLib, const std::string& rinMetFile) { if (!init(navLib)) @@ -88,7 +86,7 @@ namespace gnsstk bool GroupPathCorr :: - initNB(std::shared_ptr& navLib, + initNB(NavLibrary& navLib, const std::string& rinMetFile) { if (!init(navLib)) diff --git a/core/lib/GNSSCore/GroupPathCorr.hpp b/core/lib/GNSSCore/GroupPathCorr.hpp index ffa660d86..e3d952bd2 100644 --- a/core/lib/GNSSCore/GroupPathCorr.hpp +++ b/core/lib/GNSSCore/GroupPathCorr.hpp @@ -98,7 +98,7 @@ namespace gnsstk * BCIonoCorrector. * @param[in] navLib The NavLibrary for the correctors to use. * @return true on success, false on error. */ - bool init(std::shared_ptr& navLib); + bool init(NavLibrary& navLib); /** Fill calcs with the default set of BCISCorrector, * BCIonoCorrector and GlobalTropCorrector. @@ -109,7 +109,7 @@ namespace gnsstk * will be up to the caller to do any loading of data * later. * @return true on success, false on error. */ - bool initGlobal(std::shared_ptr& navLib, + bool initGlobal(NavLibrary& navLib, const std::string& rinMetFile = ""); /** Fill calcs with the default set of BCISCorrector, @@ -121,7 +121,7 @@ namespace gnsstk * NBTropModel in this case will use its own internal data * model. * @return true on success, false on error. */ - bool initNB(std::shared_ptr& navLib, + bool initNB(NavLibrary& navLib, const std::string& rinMetFile = ""); /** @param[in] dups Indicate how duplicate CorrectorType diff --git a/core/tests/GNSSCore/BCISCorrector_T.cpp b/core/tests/GNSSCore/BCISCorrector_T.cpp index 15d7f402b..201259cf1 100644 --- a/core/tests/GNSSCore/BCISCorrector_T.cpp +++ b/core/tests/GNSSCore/BCISCorrector_T.cpp @@ -73,9 +73,10 @@ unsigned BCISCorrector_T :: constructorTest() { TUDEF("BCISCorrector", "BCISCorrector"); - gnsstk::BCISCorrector uut; + gnsstk::NavLibrary nl; + gnsstk::BCISCorrector uut(nl); TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::ISC, uut.corrType); - TUASSERT(!uut.navLib); + TUASSERTE(gnsstk::NavLibrary*, &nl, &uut.navLib); TURETURN(); } @@ -84,8 +85,8 @@ unsigned BCISCorrector_T :: getCorrTestPosition() { TUDEF("BCISCorrector", "getCorr(Position)"); - gnsstk::BCISCorrector uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; + gnsstk::BCISCorrector uut(navLib); gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); @@ -99,10 +100,8 @@ getCorrTestPosition() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; - uut.navLib = navLib; TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); TUASSERTFE(2.04890966415e-08, corr); TURETURN(); @@ -113,8 +112,8 @@ unsigned BCISCorrector_T :: getCorrTestXvt() { TUDEF("BCISCorrector", "getCorr(Xvt)"); - gnsstk::BCISCorrector uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; + gnsstk::BCISCorrector uut(navLib); gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Xvt svPos; @@ -135,10 +134,8 @@ getCorrTestXvt() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; - uut.navLib = navLib; TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); TUASSERTFE(2.04890966415e-08, corr); TURETURN(); diff --git a/core/tests/GNSSCore/BCIonoCorrector_T.cpp b/core/tests/GNSSCore/BCIonoCorrector_T.cpp index 7907bddd8..393c58d47 100644 --- a/core/tests/GNSSCore/BCIonoCorrector_T.cpp +++ b/core/tests/GNSSCore/BCIonoCorrector_T.cpp @@ -73,9 +73,10 @@ unsigned BCIonoCorrector_T :: constructorTest() { TUDEF("BCIonoCorrector", "BCIonoCorrector"); - gnsstk::BCIonoCorrector uut; + gnsstk::NavLibrary nl; + gnsstk::BCIonoCorrector uut(nl); TUASSERTE(gnsstk::CorrectorType, gnsstk::CorrectorType::Iono, uut.corrType); - TUASSERT(!uut.navLib); + TUASSERTE(gnsstk::NavLibrary*, &nl, &uut.navLib); TURETURN(); } @@ -84,8 +85,8 @@ unsigned BCIonoCorrector_T :: getCorrTestPosition() { TUDEF("BCIonoCorrector", "getCorr(Position)"); - gnsstk::BCIonoCorrector uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; + gnsstk::BCIonoCorrector uut(navLib); gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); @@ -99,10 +100,8 @@ getCorrTestPosition() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "mixed.06n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; - uut.navLib = navLib; TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); TUASSERTFE(3.623343027333741, corr); TURETURN(); @@ -113,8 +112,8 @@ unsigned BCIonoCorrector_T :: getCorrTestXvt() { TUDEF("BCIonoCorrector", "getCorr(Xvt)"); - gnsstk::BCIonoCorrector uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; + gnsstk::BCIonoCorrector uut(navLib); gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Xvt svPos; @@ -135,10 +134,8 @@ getCorrTestXvt() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "mixed.06n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; - uut.navLib = navLib; TUASSERTE(bool, true, uut.getCorr(stnPos, svPos, sat, oid, when, nav, corr)); TUASSERTFE(3.623343027333741, corr); TURETURN(); diff --git a/core/tests/GNSSCore/GroupPathCorr_T.cpp b/core/tests/GNSSCore/GroupPathCorr_T.cpp index 91c94f42f..dc2d7094d 100644 --- a/core/tests/GNSSCore/GroupPathCorr_T.cpp +++ b/core/tests/GNSSCore/GroupPathCorr_T.cpp @@ -193,7 +193,7 @@ getCorrTestPositionDouble() gnsstk::BCIonoCorrector *iono; gnsstk::GlobalTropCorrector *trop; gnsstk::GroupPathCorr uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Position svPos(-16208820.579, -207275.833, 21038422.516); @@ -207,19 +207,16 @@ getCorrTestPositionDouble() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3; - ec1 = std::make_shared(); - ec2 = std::make_shared(); + ec1 = std::make_shared(navLib); + ec2 = std::make_shared(navLib); ec3 = std::make_shared(); isc = dynamic_cast(ec1.get()); iono = dynamic_cast(ec2.get()); trop = dynamic_cast(ec3.get()); TUASSERTE(bool, true, trop->loadFile(dataPath+"arlm2000.15m")); - isc->navLib = navLib; - iono->navLib = navLib; uut.calcs.push_back(ec1); uut.calcs.push_back(ec2); uut.calcs.push_back(ec3); @@ -237,7 +234,7 @@ getCorrTestXvtDouble() gnsstk::BCIonoCorrector *iono; gnsstk::GlobalTropCorrector *trop; gnsstk::GroupPathCorr uut; - std::shared_ptr navLib; + gnsstk::NavLibrary navLib; gnsstk::NavDataFactoryPtr ndf; gnsstk::Position stnPos(-740290.01, -5457071.705, 3207245.599); gnsstk::Xvt svPos; @@ -258,19 +255,16 @@ getCorrTestXvtDouble() gnsstk::MultiFormatNavDataFactory *mfndf = dynamic_cast(ndf.get()); TUASSERTE(bool, true, mfndf->addDataSource(dataPath + "arlm2000.15n")); - navLib = std::make_shared(); - TUCATCH(navLib->addFactory(ndf)); + TUCATCH(navLib.addFactory(ndf)); double corr = 0.0; gnsstk::GroupPathCorrectorPtr ec1, ec2, ec3; - ec1 = std::make_shared(); - ec2 = std::make_shared(); + ec1 = std::make_shared(navLib); + ec2 = std::make_shared(navLib); ec3 = std::make_shared(); isc = dynamic_cast(ec1.get()); iono = dynamic_cast(ec2.get()); trop = dynamic_cast(ec3.get()); TUASSERTE(bool, true, trop->loadFile(dataPath+"arlm2000.15m")); - isc->navLib = navLib; - iono->navLib = navLib; uut.calcs.push_back(ec1); uut.calcs.push_back(ec2); uut.calcs.push_back(ec3); @@ -452,15 +446,17 @@ initTest() { TUDEF("GroupPathCorr", "init"); gnsstk::GroupPathCorr uut; - auto navLib = std::make_shared(); + gnsstk::NavLibrary navLib; TUASSERTE(bool, true, uut.init(navLib)); // While the order isn't important, we assume it hasn't changed. auto i = uut.calcs.begin(); TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); i++; TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); TURETURN(); } @@ -470,15 +466,17 @@ initGlobalTest() { TUDEF("GroupPathCorr", "initGlobal"); gnsstk::GroupPathCorr uut; - auto navLib = std::make_shared(); + gnsstk::NavLibrary navLib; TUASSERTE(bool, true, uut.initGlobal(navLib, dataPath+"arlm2000.15m")); // While the order isn't important, we assume it hasn't changed. auto i = uut.calcs.begin(); TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); i++; TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); i++; TUASSERT(dynamic_cast(i->get()) != nullptr); TUASSERTE(bool, false, @@ -492,15 +490,17 @@ initNBTest() { TUDEF("GroupPathCorr", "initNB"); gnsstk::GroupPathCorr uut; - auto navLib = std::make_shared(); + gnsstk::NavLibrary navLib; TUASSERTE(bool, true, uut.initNB(navLib, dataPath+"arlm2000.15m")); // While the order isn't important, we assume it hasn't changed. auto i = uut.calcs.begin(); TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); i++; TUASSERT(dynamic_cast(i->get()) != nullptr); - TUASSERT(dynamic_cast(i->get())->navLib == navLib); + TUASSERTE(gnsstk::NavLibrary*, &navLib, + &(dynamic_cast(i->get())->navLib)); i++; TUASSERT(dynamic_cast(i->get()) != nullptr); TUASSERTE(bool, false, diff --git a/swig/NewNav/NewNavSharedPtr.i b/swig/NewNav/NewNavSharedPtr.i index b462c70b4..359757b44 100644 --- a/swig/NewNav/NewNavSharedPtr.i +++ b/swig/NewNav/NewNavSharedPtr.i @@ -108,5 +108,3 @@ %shared_ptr(gnsstk::PNBGLOFNavDataFactory) // silence warnings from swig %shared_ptr(gnsstk::TimeSystemCorrection) - -%shared_ptr(gnsstk::NavLibrary) diff --git a/swig/tests/test_GNSSCore.py b/swig/tests/test_GNSSCore.py index 800ffe5be..64e9557ce 100644 --- a/swig/tests/test_GNSSCore.py +++ b/swig/tests/test_GNSSCore.py @@ -173,10 +173,9 @@ def test_getCorr(self): Python users should be able to create a BCISCorrector and compute a correction from inputs. """ - isc = gnsstk.BCISCorrector() - navLib = gnsstk.NavLibrary() - isc.navLib = navLib + isc = gnsstk.BCISCorrector(navLib) + ndf = gnsstk.MultiFormatNavDataFactory() ndf.addDataSource(os.path.join(args.input_dir, "arlm2000.15n")) navLib.addFactory(ndf) @@ -213,10 +212,9 @@ def test_getCorr(self): Python users should be able to create a BCIonoCorrector and compute a correction from inputs. """ - iono = gnsstk.BCIonoCorrector() - navLib = gnsstk.NavLibrary() - iono.navLib = navLib + iono = gnsstk.BCIonoCorrector(navLib) + ndf = gnsstk.MultiFormatNavDataFactory() ndf.addDataSource(os.path.join(args.input_dir, "mixed.06n")) navLib.addFactory(ndf) @@ -287,7 +285,8 @@ def test_result(self): Test general manipulation of CorrectionResult object """ corr_nan = gnsstk.CorrectionResult() - corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector()) + navLib = gnsstk.NavLibrary() + corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector(navLib)) self.assertTrue(math.isnan(corr_nan.result)) self.assertEqual(corr_iono.result, 100) @@ -306,11 +305,12 @@ def test_results(self): and getting individual corrections within the list. """ corr_results = gnsstk.CorrectionResults() + navLib = gnsstk.NavLibrary() corr_trop = gnsstk.CorrectionResult(150, gnsstk.GlobalTropCorrector()) - corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector()) - corr_ISC = gnsstk.CorrectionResult(-75, gnsstk.BCISCorrector()) - corr_ISC2 = gnsstk.CorrectionResult(45, gnsstk.BCISCorrector()) + corr_iono = gnsstk.CorrectionResult(100, gnsstk.BCIonoCorrector(navLib)) + corr_ISC = gnsstk.CorrectionResult(-75, gnsstk.BCISCorrector(navLib)) + corr_ISC2 = gnsstk.CorrectionResult(45, gnsstk.BCISCorrector(navLib)) corr_results.addResult(corr_trop) corr_results.addResult(corr_iono) @@ -347,13 +347,11 @@ def test_groupPathCorrManual(self): oid = gnsstk.ObsID(gnsstk.ObservationType.Iono,gnsstk.CarrierBand.L1,gnsstk.TrackingCode.CA) nav = gnsstk.NavType.GPSLNAV - iono = gnsstk.BCIonoCorrector() - iono.navLib = navLib + iono = gnsstk.BCIonoCorrector(navLib) trop = gnsstk.GlobalTropCorrector() trop.setDefaultWx() - isc = gnsstk.BCISCorrector() - isc.navLib = navLib + isc = gnsstk.BCISCorrector(navLib) pec.calcs.append(iono) pec.calcs.append(trop) From ea85f75abde008b2d33c9b12128c5ff1b1e26571 Mon Sep 17 00:00:00 2001 From: Taben Malik Date: Wed, 14 Dec 2022 09:27:03 -0600 Subject: [PATCH 13/16] Refactored RawRange --- core/lib/GNSSCore/Xvt.cpp | 48 +- core/lib/GNSSEph/EphemerisRange.cpp | 185 ++---- core/lib/GNSSEph/EphemerisRange.hpp | 24 +- core/lib/GNSSEph/RawRange.cpp | 475 +++++++++++++++ core/lib/GNSSEph/RawRange.hpp | 706 +++++++++++++++++++++++ core/lib/Geomatics/PreciseRange.cpp | 133 +++-- core/lib/Geomatics/PreciseRange.hpp | 27 +- core/lib/ORD/ord.cpp | 235 +++----- core/lib/ORD/ord.hpp | 8 + core/tests/GNSSCore/CMakeLists.txt | 4 + core/tests/GNSSCore/RawRange_T.cpp | 651 +++++++++++++++++++++ core/tests/GNSSCore/Xvt_T.cpp | 28 +- core/tests/GNSSEph/EphemerisRange_T.cpp | 122 +++- core/tests/Geomatics/CMakeLists.txt | 4 + core/tests/Geomatics/PreciseRange_T.cpp | 165 ++++++ core/tests/ORD/OrdRegressionChecks_T.cpp | 6 +- core/tests/ORD/OrdUnitTests_T.cpp | 120 ++-- swig/GNSSEph/GNSSEph.i | 9 + swig/SWIGHelpers/std_tuple.i | 52 ++ swig/gnsstk_swig.hpp | 1 + swig/gnsstk_swig.i | 1 + swig/tests/test_GNSSEph.py | 28 +- 22 files changed, 2533 insertions(+), 499 deletions(-) create mode 100644 core/lib/GNSSEph/RawRange.cpp create mode 100644 core/lib/GNSSEph/RawRange.hpp create mode 100644 core/tests/GNSSCore/RawRange_T.cpp create mode 100644 core/tests/Geomatics/PreciseRange_T.cpp create mode 100644 swig/SWIGHelpers/std_tuple.i diff --git a/core/lib/GNSSCore/Xvt.cpp b/core/lib/GNSSCore/Xvt.cpp index 76169c572..aebaf4da3 100644 --- a/core/lib/GNSSCore/Xvt.cpp +++ b/core/lib/GNSSCore/Xvt.cpp @@ -41,8 +41,10 @@ * Position and velocity as Triples, clock bias and drift as doubles. */ +#include #include #include "Xvt.hpp" +#include "RawRange.hpp" namespace gnsstk { @@ -117,47 +119,13 @@ namespace gnsstk // geometric range at transmit time. This fails to account // for the rotation of the earth, but should be good to // within about 40 m - double sr1 = rxPos.slantRange(x); - double dt = sr1 / ellips.c(); + double tofEstimate = rxPos.slantRange(x) / ellips.c(); - // compute rotation angle in the time of signal transit - double rotation_angle = -ellips.angVelocity() * dt; + double range; + std::tie(std::ignore, range, std::ignore) = + RawRange::fromSvPos(rxPos, *this, ellips, true, tofEstimate, 0, 2); - // rotate original GS coordinates to new values to correct for - // rotation of ECEF frame - // Ref: Satellite Geodesy, Gunter Seeber, 1993, pg 291 and the - // ICD-GPS-200 sheet 102 May 1993 version - // xnew[0]=xg[0]*cos(rotation_angle)-xg[1]*sin(rotation_angle); - // xnew[1]=xg[1]*cos(rotation_angle)+xg[0]*sin(rotation_angle); - // xnew[2]=xg[2]; - // since cosine and sine are small, approximate by the first - // order terms in an expansion. - gnsstk::Triple xnew; - for (int i = 0; i < 2; i++) - { - xnew[0] = x[0] - x[1] * rotation_angle; - xnew[1] = x[1] + x[0] * rotation_angle; - xnew[2] = x[2]; - - // Compute geometric slant range from ground station to - // the rotated new coord's - sr1 = rxPos.slantRange(xnew); - - // Recompute the time of flight (dt) based on PR, with the - // time of flight based on geometric range. Note that - // this is a really unneeded, in that the change in PR is - // < 40 m, hence the change in tof is < 20 ns - dt = sr1 / ellips.c(); - - // Compute new rotation in this time - rotation_angle = -ellips.angVelocity() * dt; - } - - // Account for SV clock drift, relativity and user input correction - double rho = sr1 - (clkbias + relcorr) * ellips.c() - correction; - - return rho; - - } // end of preciseRho() + return range - (clkbias + relcorr) * ellips.c() - correction; + } } // end of gnsstk namespace diff --git a/core/lib/GNSSEph/EphemerisRange.cpp b/core/lib/GNSSEph/EphemerisRange.cpp index dc3a6fb67..a660878ca 100644 --- a/core/lib/GNSSEph/EphemerisRange.cpp +++ b/core/lib/GNSSEph/EphemerisRange.cpp @@ -42,12 +42,15 @@ * given receiver position and time. */ +#include + +#include "EllipsoidModel.hpp" #include "EphemerisRange.hpp" #include "MiscMath.hpp" -#include "GPSEllipsoid.hpp" #include "GNSSconstants.hpp" #include "GPSLNavEph.hpp" #include "TimeString.hpp" +#include "RawRange.hpp" using namespace std; using namespace gnsstk; @@ -66,46 +69,30 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order, SVHealth xmitHealth, - NavValidityType valid) + NavValidityType valid, + const EllipsoidModel& ellipsoid) { try { int nit; double tof,tof_old; - GPSEllipsoid ellipsoid; - - nit = 0; - tof = 0.07; // initial guess 70ms - do { - // best estimate of transmit time - transmit = trNom; - transmit -= tof; - tof_old = tof; - - // get SV position - if(!getXvt(navLib, NavSatelliteID(sat), transmit, order, - xmitHealth, valid)) - { - InvalidRequest ir("getXvt failed"); - GNSSTK_THROW(ir); - } + bool success; + std::tie(success, rawrange, svPosVel) = + RawRange::fromReceive(Rx, trNom, navLib, + NavSatelliteID(sat), ellipsoid); - rotateEarth(Rx); - // update raw range and time of flight - rawrange = RSS(svPosVel.x[0]-Rx.X(), - svPosVel.x[1]-Rx.Y(), - svPosVel.x[2]-Rx.Z()); - tof = rawrange/ellipsoid.c(); - - } while(ABS(tof-tof_old)>1.e-13 && ++nit<5); + if(!success) + { + InvalidRequest ir("getXvt failed"); + GNSSTK_THROW(ir); + } updateCER(Rx); - return (rawrange-svclkbias-relativity); } catch(gnsstk::Exception& e) { GNSSTK_RETHROW(e); } - } // end CorrectedEphemerisRange::ComputeAtReceiveTime + } // Compute the corrected range at TRANSMIT time, from receiver at position Rx, @@ -120,45 +107,27 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order, SVHealth xmitHealth, - NavValidityType valid) + NavValidityType valid, + const EllipsoidModel& ellipsoid) { try { - CommonTime tt; - - // 0-th order estimate of transmit time = receiver - pseudorange/c - transmit = trNom; - transmit -= pr/C_MPS; - tt = transmit; - - // correct for SV clock - for(int i=0; i<2; i++) { - // get SV position - if(! getXvt(navLib, NavSatelliteID(sat), tt, - order, xmitHealth, valid)) - { - InvalidRequest ir("getXvt failed"); - GNSSTK_THROW(ir); - } - - tt = transmit; - // remove clock bias and relativity correction - tt -= (svPosVel.clkbias + svPosVel.relcorr); + bool success; + std::tie(success, rawrange, svPosVel) = + RawRange::fromNominalReceiveWithObs(Rx, trNom, pr, navLib, + NavSatelliteID(sat), ellipsoid); + if(!success) + { + InvalidRequest ir("getXvt failed"); + GNSSTK_THROW(ir); } - rotateEarth(Rx); - // raw range - rawrange = RSS(svPosVel.x[0]-Rx.X(), - svPosVel.x[1]-Rx.Y(), - svPosVel.x[2]-Rx.Z()); - updateCER(Rx); - return (rawrange-svclkbias-relativity); } catch(gnsstk::Exception& e) { GNSSTK_RETHROW(e); } - } // end CorrectedEphemerisRange::ComputeAtTransmitTime + } double CorrectedEphemerisRange::ComputeAtTransmitTime( @@ -168,20 +137,24 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order, SVHealth xmitHealth, - NavValidityType valid) + NavValidityType valid, + const EllipsoidModel& ellipsoid) { try { - if(!getXvt(navLib, NavSatelliteID(sat), trNom, - order, xmitHealth, valid)) + bool success; + std::tie(success, rawrange, svPosVel) = + RawRange::fromNominalReceive(Rx, trNom, navLib, + NavSatelliteID(sat), ellipsoid); + + if(!success) { InvalidRequest ir("getXvt failed"); GNSSTK_THROW(ir); } - gnsstk::GPSEllipsoid gm; - double pr = svPosVel.preciseRho(Rx, gm); + updateCER(Rx); - return ComputeAtTransmitTime(trNom, pr, Rx, sat, navLib); + return (rawrange - svclkbias - relativity); } catch(gnsstk::Exception& e) { GNSSTK_RETHROW(e); @@ -197,38 +170,24 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order, SVHealth xmitHealth, - NavValidityType valid) + NavValidityType valid, + const EllipsoidModel& ellipsoid) { try { - Position trx(rx); - trx.asECEF(); + bool success; + std::tie(success, rawrange, svPosVel) + = RawRange::fromSvTransmitWithObs(rx, pr, navLib, + NavSatelliteID(sat), ttNom, + ellipsoid, true); - if(!getXvt(navLib, NavSatelliteID(sat), ttNom, - order, xmitHealth, valid)) + if(!success) { InvalidRequest ir("getXvt failed"); GNSSTK_THROW(ir); } - // compute rotation angle in the time of signal transit - - // While this is quite similiar to rotateEarth, its not the same - // and jcl doesn't know which is really correct - // BWT this uses the measured pseudorange, corrected for SV clock and - // relativity, to compute the time of flight; rotateEarth uses the value - // computed from the receiver position and the ephemeris. They should be - // very nearly the same, and multiplying by angVel/c should make the angle - // of rotation very nearly identical. - GPSEllipsoid ell; - double range(pr/ell.c() - svPosVel.clkbias - svPosVel.relcorr); - double rotation_angle = -ell.angVelocity() * range; - svPosVel.x[0] = svPosVel.x[0] - svPosVel.x[1] * rotation_angle; - svPosVel.x[1] = svPosVel.x[1] + svPosVel.x[0] * rotation_angle; - svPosVel.x[2] = svPosVel.x[2]; - - rawrange = trx.slantRange(svPosVel.x); - updateCER(trx); + updateCER(rx); return rawrange - svclkbias - relativity; } @@ -256,58 +215,6 @@ namespace gnsstk azimuthGeodetic = Rx.azimuthGeodetic(SV); } - - void CorrectedEphemerisRange::rotateEarth(const Position& Rx) - { - GPSEllipsoid ellipsoid; - double tof = RSS(svPosVel.x[0]-Rx.X(), - svPosVel.x[1]-Rx.Y(), - svPosVel.x[2]-Rx.Z())/ellipsoid.c(); - double wt = ellipsoid.angVelocity()*tof; - double sx = ::cos(wt)*svPosVel.x[0] + ::sin(wt)*svPosVel.x[1]; - double sy = -::sin(wt)*svPosVel.x[0] + ::cos(wt)*svPosVel.x[1]; - svPosVel.x[0] = sx; - svPosVel.x[1] = sy; - sx = ::cos(wt)*svPosVel.v[0] + ::sin(wt)*svPosVel.v[1]; - sy = -::sin(wt)*svPosVel.v[0] + ::cos(wt)*svPosVel.v[1]; - svPosVel.v[0] = sx; - svPosVel.v[1] = sy; - } - - - bool CorrectedEphemerisRange :: - getXvt(NavLibrary& navLib, const NavSatelliteID& sat, const CommonTime& when, - NavSearchOrder order, - SVHealth xmitHealth, - NavValidityType valid) - { - NavMessageID nmid(sat, NavMessageType::Ephemeris); - NavDataPtr ndp; - std::shared_ptr od; - std::shared_ptr ephLNav; - if (!navLib.find(nmid, when, ndp, xmitHealth, valid, order)) - { - return false; - } - if (od = std::dynamic_pointer_cast(ndp)) - { - if (!od->getXvt(when, svPosVel)) - return false; - } - else - { - // Not orbit data? How? - return false; - } - if (ephLNav = std::dynamic_pointer_cast(ndp)) - { - iodc = ephLNav->iodc; - health = ephLNav->healthBits; - } - return true; - } - - double RelativityCorrection(const Xvt& svPosVel) { // relativity correction diff --git a/core/lib/GNSSEph/EphemerisRange.hpp b/core/lib/GNSSEph/EphemerisRange.hpp index 6d6619f0c..406a67fee 100644 --- a/core/lib/GNSSEph/EphemerisRange.hpp +++ b/core/lib/GNSSEph/EphemerisRange.hpp @@ -44,6 +44,8 @@ #ifndef NEW_EPHEMERIS_RANGE_HPP #define NEW_EPHEMERIS_RANGE_HPP +#include "EllipsoidModel.hpp" +#include "GPSEllipsoid.hpp" #include "CommonTime.hpp" #include "SatID.hpp" #include "Position.hpp" @@ -108,6 +110,7 @@ namespace gnsstk * satellite transmitting the nav data. * @param[in] valid Specify whether to search only for valid * or invalid messages, or both. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. * @return The corrected range from rx to sat at trNom. */ double ComputeAtReceiveTime( const CommonTime& trNom, @@ -116,7 +119,8 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order = NavSearchOrder::User, SVHealth xmitHealth = SVHealth::Any, - NavValidityType valid = NavValidityType::ValidOnly); + NavValidityType valid = NavValidityType::ValidOnly, + const EllipsoidModel& ellipsoid = GPSEllipsoid()); /** Compute the corrected range at TRANSMIT time (receiver time frame) * from rx to sat at trNom. @@ -156,6 +160,7 @@ namespace gnsstk * satellite transmitting the nav data. * @param[in] valid Specify whether to search only for valid * or invalid messages, or both. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. * @return The corrected range from rx to sat at trNom. */ double ComputeAtTransmitTime( const CommonTime& trNom, @@ -165,7 +170,8 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order = NavSearchOrder::User, SVHealth xmitHealth = SVHealth::Any, - NavValidityType valid = NavValidityType::ValidOnly); + NavValidityType valid = NavValidityType::ValidOnly, + const EllipsoidModel& ellipsoid = GPSEllipsoid()); /** Compute the corrected range at TRANSMIT time (receiver * time frame), from rx to sat at trNom. @@ -200,6 +206,7 @@ namespace gnsstk * satellite transmitting the nav data. * @param[in] valid Specify whether to search only for valid * or invalid messages, or both. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. * @return The corrected range from rx to sat at trNom. */ double ComputeAtTransmitTime( const CommonTime& trNom, @@ -208,7 +215,8 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order = NavSearchOrder::User, SVHealth xmitHealth = SVHealth::Any, - NavValidityType valid = NavValidityType::ValidOnly); + NavValidityType valid = NavValidityType::ValidOnly, + const EllipsoidModel& ellipsoid = GPSEllipsoid()); /** Compute the corrected range at TRANSMIT time (SV time * frame), from rx to sat at ttNom. @@ -229,6 +237,7 @@ namespace gnsstk * satellite transmitting the nav data. * @param[in] valid Specify whether to search only for valid * or invalid messages, or both. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. * @return The corrected range from rx to sat at ttNom. */ double ComputeAtTransmitSvTime( const CommonTime& ttNom, @@ -238,7 +247,8 @@ namespace gnsstk NavLibrary& navLib, NavSearchOrder order = NavSearchOrder::User, SVHealth xmitHealth = SVHealth::Any, - NavValidityType valid = NavValidityType::ValidOnly); + NavValidityType valid = NavValidityType::ValidOnly, + const EllipsoidModel& ellipsoid = GPSEllipsoid()); /// The computed raw (geometric) range in meters. double rawrange; @@ -276,12 +286,6 @@ namespace gnsstk private: // These are just helper functions to keep from repeating code void updateCER(const Position& rx); - void rotateEarth(const Position& rx); - bool getXvt(NavLibrary& navLib, const NavSatelliteID& sat, - const CommonTime& when, - NavSearchOrder order, - SVHealth xmitHealth, - NavValidityType valid); }; // end class CorrectedEphemerisRange diff --git a/core/lib/GNSSEph/RawRange.cpp b/core/lib/GNSSEph/RawRange.cpp new file mode 100644 index 000000000..25069c7b8 --- /dev/null +++ b/core/lib/GNSSEph/RawRange.cpp @@ -0,0 +1,475 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include +#include +#include "GNSSconstants.hpp" +#include "RawRange.hpp" +#include "Triple.hpp" +#include "CommonTime.hpp" +#include "EllipsoidModel.hpp" +#include "NavLibrary.hpp" +#include "NavSatelliteID.hpp" +#include "EllipsoidModel.hpp" +#include "SVHealth.hpp" +#include "NavValidityType.hpp" +#include "NavSearchOrder.hpp" +#include "Xvt.hpp" +#include "Position.hpp" + +namespace gnsstk +{ + std::tuple RawRange::fromSvPos( + const Position& rxPos, + const Xvt& svXvt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + double seed, + double threshold, + int maxIter + ) + { + int iter = 0; + double tof = seed; + double tof_prev; + double range; + Xvt rotatedSvXvt; + + // Optimize `tau = range(tau) / c` + do { + tof_prev = tof; + + std::tie(range, rotatedSvXvt) = + computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox); + + tof = range / ellipsoid.c(); + + } while(ABS(tof - tof_prev) > threshold && ++iter < maxIter); + + std::tie(range, rotatedSvXvt) = + computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox); + + return std::make_tuple(true, range, rotatedSvXvt); + } + + std::tuple RawRange::fromSvTransmit( + const Position& rxPos, + NavLibrary& navLib, + const NavSatelliteID& sat, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order, + double seed, + double threshold, + int maxIter + ) + { + Xvt svXvt; + // false = always use ephemeris + if(!navLib.getXvt(sat, transmit, svXvt, false, xmitHealth, valid, order)) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + return fromSvPos(rxPos, svXvt, ellipsoid, smallAngleApprox, + seed, threshold, maxIter); + } + + std::tuple RawRange::fromSvTransmitWithObs( + const Position& rxPos, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order + ) + { + Xvt svXvt; + if(!navLib.getXvt(sat, transmit, svXvt, false, xmitHealth, valid, order)) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + double tof = (pseudorange / ellipsoid.c()) - svXvt.clkbias - svXvt.relcorr; + + double range; + Xvt rotatedSvXvt; + std::tie(range, rotatedSvXvt) = + computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox); + + return std::make_tuple(true, range, rotatedSvXvt); + } + + + std::tuple RawRange::fromReceive( + const Position& rxPos, + const CommonTime& receive, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order, + double seed, + double threshold, + int maxIter) + { + bool success; + CommonTime transmitEst; + Xvt svXvt; + + // Estimate transmit time by iterative optimization + std::tie(success, transmitEst) = + estTransmitFromReceive(rxPos, receive, navLib, sat, ellipsoid, + xmitHealth, valid, order, seed, + threshold, maxIter); + if(!success) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + // Get SV position at estimated transmit time + success = navLib.getXvt(sat, transmitEst, svXvt, false, + xmitHealth, valid, order); + if(!success) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + // Compute range between SV and RX + double range; + Xvt rotatedSvXvt; + std::tie(range, rotatedSvXvt) = computeRange(rxPos, receive, svXvt, + transmitEst, ellipsoid, + smallAngleApprox); + return std::make_tuple(true, range, rotatedSvXvt); + } + + std::tuple RawRange::fromNominalReceive( + const Position& rxPos, + const CommonTime& receiveNominal, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order, + double seed, + double threshold, + int maxIter) + { + bool success; + double range; + Xvt rotatedSvXvt; + + // First estimate the range by using the receiveNominal as the + // transmit time. + std::tie(success, range, rotatedSvXvt) = + fromSvTransmit(rxPos, navLib, sat, receiveNominal, ellipsoid, + smallAngleApprox, xmitHealth, valid, order, + seed, threshold, maxIter); + if(!success) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + rotatedSvXvt); + } + + // Create mock pseudorange using the estimated range and clock offsets + double fakePsuedorange = + range - (rotatedSvXvt.clkbias + rotatedSvXvt.relcorr) * ellipsoid.c(); + + // Compute range by using mock pseudorange + std::tie(success, range, rotatedSvXvt) = + fromNominalReceiveWithObs(rxPos, receiveNominal, fakePsuedorange, + navLib, sat, ellipsoid, smallAngleApprox, + xmitHealth, valid, order); + return std::make_tuple(success, range, rotatedSvXvt); + } + + std::tuple RawRange::fromNominalReceiveWithObs( + const Position& rxPos, + const CommonTime& receiveNominal, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order) + { + bool success; + CommonTime transmitEst; + Xvt svXvt; + + // Estimate transmit time + std::tie(success, transmitEst) = + estTransmitFromObs(receiveNominal, pseudorange, navLib, sat, + xmitHealth, valid, order); + if(!success) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + // Get SV position at transmit time + success = navLib.getXvt(sat, transmitEst, svXvt, false, + xmitHealth, valid, order); + if(!success) + { + return std::make_tuple(false, + std::numeric_limits::quiet_NaN(), + svXvt); + } + + // Estimate time of flight (tof) + // Can't use receiveNominal to estimate the time of flight + // since receiveNominal might contain a large receiver clock offset. + // A more consistent approach is to derive tof from the "instantaneous" + // range from the now known SV pos at transmit time + double range; + std::tie(range, std::ignore) = + computeRange(rxPos, svXvt, 0, ellipsoid, smallAngleApprox); + double tof = range / ellipsoid.c(); + + // Compute range using the estimated tof + Xvt rotatedSvXvt; + std::tie(range, rotatedSvXvt) = + computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox); + + return std::make_tuple(true, range, rotatedSvXvt); + } + + + std::tuple RawRange::estTransmitFromReceive( + const Position& rxPos, + const CommonTime& receive, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order, + double seed, + double threshold, + int maxIter) + { + Xvt svXvt; + CommonTime estTransmit; + int iter = 0; + double tof = seed; + double prevTof; + + // Optimize this pair of functions: + // `transmit = receive - tof` + // `tof = range(transmit, tof) / c` + do { + estTransmit = receive - tof; + + if(!navLib.getXvt(sat, estTransmit, svXvt, + false, xmitHealth, valid, order)) + { + return std::make_tuple(false, CommonTime::BEGINNING_OF_TIME); + } + + double range; + std::tie(range, std::ignore) = + computeRange(rxPos, receive, svXvt, estTransmit, ellipsoid); + // std::tie(range, std::ignore) = + // computeRange(rxPos, svXvt, 0, ellipsoid); + // std::tie(range, std::ignore) = + // computeRange(rxPos, svXvt, range / ellipsoid.c(), ellipsoid); + + + prevTof = tof; + tof = range / ellipsoid.c(); + + } while(ABS(tof - prevTof) > threshold && ++iter < maxIter); + + return std::make_tuple(true, estTransmit); + } + + + std::tuple RawRange::estTransmitFromObs( + const CommonTime& nominalReceive, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + SVHealth xmitHealth, + NavValidityType valid, + NavSearchOrder order + ) + { + CommonTime nominalTransmit = nominalReceive - (pseudorange / C_MPS); + + Xvt svXvt; + if(!navLib.getXvt(sat, nominalTransmit, svXvt, false, + xmitHealth, valid, order)) + { + return std::make_tuple(false, CommonTime::BEGINNING_OF_TIME); + } + + CommonTime transmit = nominalTransmit - (svXvt.clkbias + svXvt.relcorr); + return std::make_tuple(true, transmit); + } + + + std::tuple RawRange::computeRange( + const Position& rxPos, + const CommonTime& receive, + const Xvt& svXvt, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + double tof = receive - transmit; + return computeRange(rxPos, svXvt, tof, ellipsoid, smallAngleApprox); + } + + std::tuple RawRange::computeRange( + const Position& rxPos, + const Xvt& svXvt, + double tof, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + Xvt svXvtRotated = rotateECEF(svXvt, tof, ellipsoid, smallAngleApprox); + double dist = range(rxPos, svXvtRotated.x); + return std::make_tuple(dist, svXvtRotated); + } + + std::tuple RawRange::computeRange( + const Position& rxPos, + const CommonTime& receive, + const Position& svPos, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + double tof = receive - transmit; + return computeRange(rxPos, svPos, tof, ellipsoid, smallAngleApprox); + } + + std::tuple RawRange::computeRange( + const Position& rxPos, + const Position& svPos, + double tof, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox + ) + { + Position svPosRotated = rotateECEF(svPos, tof, ellipsoid, smallAngleApprox); + double dist = range(rxPos, svPosRotated); + return std::make_tuple(dist, svPosRotated); + } + + Triple RawRange::rotateECEF( + const Triple& vec, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + double rotate = dt * ellipsoid.angVelocity(); + + Triple vecRotated(vec); + + if(smallAngleApprox) + { + vecRotated[0] = vec[0] + vec[1] * rotate; + vecRotated[1] = vec[1] - vec[0] * rotate; + vecRotated[2] = vec[2]; + } + else + { + vecRotated = vec.R3(rotate * RAD_TO_DEG); + } + + return vecRotated; + } + + Position RawRange::rotateECEF( + const Position& vec, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + Position pos(vec); + Position::CoordinateSystem sys = pos.getCoordinateSystem(); + pos.asECEF(); + + Triple rotatedVec = rotateECEF(static_cast(pos), dt, + ellipsoid, smallAngleApprox); + pos.setECEF(rotatedVec); + pos.transformTo(sys); + + return pos; + } + + Xvt RawRange::rotateECEF( + const Xvt& xvt, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox) + { + Xvt returnXvt(xvt); + returnXvt.x = rotateECEF(xvt.x, dt, ellipsoid, smallAngleApprox); + returnXvt.v = rotateECEF(xvt.v, dt, ellipsoid, smallAngleApprox); + return returnXvt; + } + + +} // namespace gnsstk diff --git a/core/lib/GNSSEph/RawRange.hpp b/core/lib/GNSSEph/RawRange.hpp new file mode 100644 index 000000000..aa86c03cb --- /dev/null +++ b/core/lib/GNSSEph/RawRange.hpp @@ -0,0 +1,706 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +/** + * @file RangeRange.hpp + * Computation of geometric ranges from transmission to reception + */ + +#ifndef NEW_RAW_RANGE_HPP +#define NEW_RAW_RANGE_HPP + +#include + +#include "Triple.hpp" +#include "Position.hpp" +#include "CommonTime.hpp" +#include "NavLibrary.hpp" +#include "NavSatelliteID.hpp" +#include "Position.hpp" +#include "EllipsoidModel.hpp" +#include "SVHealth.hpp" +#include "NavValidityType.hpp" +#include "NavSearchOrder.hpp" + +namespace gnsstk +{ + /// @ingroup GNSSEph + //@{ + + /** Compute the raw range (a.k.a. geometric range) from a receiver at + * at receive time and an SV at transmit time. + * + * When working with coordinates in an ECEF frame, the rotation of the + * frame during the transmission must be accounted for in computing the + * distance. The range equation can be written as such: + * @f[ + * \rho(\tau, t_{sv}) = \biggl|\biggl|\mathbf{R3}\bigl(\tau*\omega\bigl)\cdot r^{sv}(t_{sv}) - r^{rx}\biggl|\biggl| + * @f] + * + * The computeRange() methods perform this exact computation. Note that + * a simple rotation around the Z axis can be used due to the assumption + * of a short time of flight (<1s). This will not work for larger + * time deltas. + * + * The above range equation requires knowing the transmit time and the + * time of flight (tof) but usually neither is known. There are several + * RawRange methods for estimating the transmit time and tof depending on + * the available inputs. + * - fromSvPos(): use this if an SV position at transmit time is already + * known. + * - fromSvTransmit(): the same as fromSvPos() but will look up the + * SV position for you. + * - fromSvTransmitWithObs(): used with smoothed obs + * - fromReceive(): only usable if an unbiased receive time is known + * - fromNominalReceive(): the use case of this methodology is unknown + * - fromNominalReceiveWithObs(): the most common case that will compute + * a good range solution from receiver observations + * + * Documentation and code in this class tries to stay consistent in + * terminology. The table below describes the terminology. + * + * Term | Variable Name | Math Term | Explanation + * ---- | ------------- | --------- | ----------- + * R3 | N/A | @f$\mathbf{R3}@f$ | A rotation about the Z axis + * Time of flight (tof) | tof | @f$\tau@f$ | The time it takes from signal transmission to signal reception + * Angular velocity | N/A | @f$\omega@f$ | An ECEF reference frame's angular velocity, typically provided by an ellipsoid model + * Receiver (RX) position | rxPos | @f$r^{rx}@f$ | A receiver's position in ECEF coordinates + * SV position | svPos | @f$r^{sv}@f$ | An SV's position in ECEF coordinates + * Nominal receive time | receiveNominal | @f$\tilde{t}_{rx}@f$ | The receive time in the time frame of the receiver. + * Receive time | receive | @f$t_{rx}@f$ | The true receive time + * Nominal transmit time | transmitNominal | @f$\tilde{t}_{sv}@f$ | The transmit time in the time frame of the transmitter (e.g. SV) + * Transmit time | transmit | @f$t_{sv}@f$ | The true transmit time + * SV clock offset | N/A | @f$\Delta t_{sv}@f$ | An SV clock's offset from a true time frame (typically GPS) + * RX relativity correction | @f$\delta t_{sv}^{rel}@f$ | A relativity correction due to the ellipictal orbits of SVs + * + * + */ + class RawRange + { + public: + + /** Compute geometric range from an SV's known transmitting position. + * + * This method estimates a transmit time by holding the SV position as + * constant and finding the optimal solution to the set of equations: + * + * @f[ + * \rho(\tau) = \biggl|\biggl|\mathbf{R3}\bigl(\tau*\omega\bigl)\cdot r^{sv} - r^{rx}\biggl|\biggl| + * @f] + * @f[ + * \tau = \rho(\tau) / c + * @f] + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] svXvt An SV's Xvt + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] seed An initial guess of the time of flight (@f$\tau@f$) + * @param[in] threshold Convergence threshold + * @param[in] maxIter Max number of iterations to evaluate + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromSvPos( + const Position& rxPos, + const Xvt& svXvt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + double seed = 0.07, + double threshold = 1.e-13, + int maxIter = 5 + ); + + /** Compute geometric range from an SV's transmitting position + * + * This method is the same as RawRange::fromSvPos() but will look up + * the SV position for you by the provided time and NavLibrary. + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] transmit The transmit time + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @param[in] seed An initial guess of the time of flight (@f$\tau@f$) + * @param[in] threshold Convergence threshold + * @param[in] maxIter Max number of iterations to evaluate + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromSvTransmit( + const Position& rxPos, + NavLibrary& navLib, + const NavSatelliteID& sat, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User, + double seed = 0.07, + double threshold = 1.e-13, + int maxIter = 5 + ); + + + /** Compute geometric range at a known receive time + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] receive The receive time + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @param[in] seed An initial guess of the time of flight (@f$\tau@f$) + * @param[in] threshold Convergence threshold + * @param[in] maxIter Max number of iterations to evaluate + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromReceive( + const Position& rxPos, + const CommonTime& receive, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User, + double seed = 0.07, + double threshold = 1.e-13, + int maxIter = 5 + ); + + /** Compute geometric range from receiver observations + * + * This is the common approach to computing raw range when provided + * receiver observations. It uses estTransmitFromObs to generate + * a transmit time and then compute raw range. + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] receiveNominal The receive time in the time frame of + * the receiver + * @param[in] pseudorange Measured pseudorange at the nominal receive + * time + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromNominalReceiveWithObs( + const Position& rxPos, + const CommonTime& receiveNominal, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User + ); + + /** Compute geometric range using a known transmit time and + * pseudorange measurement. + * + * This is specifically used for smoothed observations which are time + * stamped by SV transmit time. + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] pseudorange A measured pseudorange + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromSvTransmitWithObs( + const Position& rxPos, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User + ); + + /** Compute geometric range from an SV's transmitting positioning + * + * Uses a combination of fromSvTransmit() and fromNominalReceiveWithObs + * to estimate the range from SV to RX. + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] receiveNominal The receive time in the time frame of + * the receiver + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @param[in] seed An initial guess of the time of flight (@f$\tau@f$) + * @param[in] threshold Convergence threshold + * @param[in] maxIter Max number of iterations to evaluate + * @return A tuple of success code, raw range, and rotated SV + * coordinates. The bool is true if successful, false if no nav + * data was found to compute the Xvt. + */ + static std::tuple fromNominalReceive( + const Position& rxPos, + const CommonTime& receiveNominal, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox = false, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User, + double seed = 0.7, + double threshold = 1.e-13, + int maxIter = 5 + ); + + /** Estimate a transmit time using a known receive time and + * geometric constraints. + * + * This method estimates a transmit time by finding the optimal + * solution to the set of equations: + * + * @f[ + * t_{sv} = t_{rx} - \tau + * @f] + * @f[ + * \rho(\tau, t_{sv}) = \biggl|\biggl|\mathbf{R3}\bigl(\tau*\omega\bigl)\cdot r^{sv}(t_{sv}) - r^{rx}\biggl|\biggl| + * @f] + * @f[ + * \tau = \rho(\tau, t_{sv}) / c + * @f] + * + * The above equations are evaluated iteratively until an end condition + * is met. + * + * @param[in] rxPos A receiver's position in ECEF + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] ellipsoid Ellipsoid model to provide an ECEF rotation rate. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @param[in] seed An initial guess of the time of flight (@f$\tau@f$) + * @param[in] threshold Convergence threshold + * @param[in] maxIter Max number of iterations to evaluate + * @return A tuple of success code and estimated transmit time. + * The bool is true if successful, false if no nav data was found + * to compute the Xvt + */ + static std::tuple estTransmitFromReceive( + const Position& rxPos, + const CommonTime& receive, + NavLibrary& navLib, + const NavSatelliteID& sat, + const EllipsoidModel& ellipsoid, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User, + double seed = 0.07, + double threshold = 1.e-13, + int maxIter = 5 + ); + + /** Estimate signal transmission time using receiver observations + * and ephemeris. + * + * A pseudorange is typically formed as the difference between + * nominal receive time and nominal transmit time, multiplied + * by the speed of light. + * + * @f[ + * p = c * (\tilde{t}_{rx} - \tilde{t}_{sv}) + * @f] + * + * The nominal transmit time consists of the actual transmit time + * plus clock offsets at the time of broadcast. Clock offsets + * are provided by SV ephemeris broadcasts. + * + * @f[ + * p = c * (\tilde{t}_{rx} - t_{sv} - \Delta t_{sv} - \delta t_{sv}^{rel}) + * @f] + * + * Solving for transmit time, we get: + * + * @f[ + * t_{sv} = \tilde{t}_{rx} - \frac{p}{c} - \Delta t_{sv} - \delta t_{sv}^{rel} + * @f] + * + * @note Other biases like ISCs and second order relativity are not + * accounted for here. Additional corrections can be applied to the + * output by subtracting any additional known biases. + * + * @param[in] receiveNominal The receive time in the time frame of + * the receiver + * @param[in] pseudorange Measured pseudorange at the nominal receive + * time + * @param[in] navLib The navigation data library to use for + * looking up satellite XVT. + * @param[in] sat Satellite ID to get the position for. + * @param[in] xmitHealth The desired health status of the + * transmitting satellite. + * @param[in] valid Specify whether to search only for valid + * or invalid messages, or both. + * @param[in] order Specify whether to search by receiver + * behavior or by nearest to when in time. + * @return A tuple of success code and estimated transmit time. + * The bool is true if successful, false if no nav data was found + * to compute the Xvt + */ + static std::tuple estTransmitFromObs( + const CommonTime& receiveNominal, + double pseudorange, + NavLibrary& navLib, + const NavSatelliteID& sat, + SVHealth xmitHealth = SVHealth::Any, + NavValidityType valid = NavValidityType::ValidOnly, + NavSearchOrder order = NavSearchOrder::User + ); + + /** Compute geometric range from an SV's transmitting position + * to a receiver's position and accounting for the rotation + * of the ECEF frame during the time of flight. + * + * The computation is equiavalent to + * @f[ + * \rho = \biggl|\biggl|\mathbf{R3}\bigl((t_{rx} - t_{tx})*\omega)\bigl)\cdot r^{sv} - r^{rx}\biggl|\biggl| + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] rxPos (@f$r^rx@f$) The receiver's position in ECEF + * coordinates + * @param[in] receive (@f$t_{rx}@f$) The time of signal receive + * @param[in] svPos (@f$r^sv@f$) The SV's position in ECEF coordinates + * @param[in] transmit (@f$t_{tx}@f$) The time of signal transmit + * @param[in] ellipsoid Used to provide an angular rate of rotation + * of the ECEF (@f$\omega@f$) + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A tuple of the range (@f$\rho@f$) and the rotated SV + * coordinates (@f$\mathbf{R3}(\tau*\omega)\cdot r^{sv}@f$) + */ + static std::tuple computeRange( + const Position& rxPos, + const CommonTime& receive, + const Xvt& svXvt, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Compute geometric range from an SV's transmitting position + * to a receiver's position and accounting for the rotation + * of the ECEF frame during the time of flight. + * + * The computation is equiavalent to + * @f[ + * \rho = \biggl|\biggl|\mathbf{R3}\bigl(\tau*\omega\bigl)\cdot r^{sv} - r^{rx}\biggl|\biggl| + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] rxPos (@f$r^rx@f$) The receiver's position in ECEF + * coordinates + * @param[in] svXvt The SV's position (@f$r^sv@f$) and velocity in + * ECEF coordinates + * @param[in] tof (@f$\tau@f$) The time of flight between transmission + * and reception + * @param[in] ellipsoid Used to provide an angular rate of rotation + * of the ECEF (@f$\omega@f$) + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A tuple of the range (@f$\rho@f$) and the rotated SV + * position and velocity + */ + static std::tuple computeRange( + const Position& rxPos, + const Xvt& svXvt, + double tof, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Compute geometric range from an SV's transmitting position + * to a receiver's position and accounting for the rotation + * of the ECEF frame during the time of flight. + * + * The computation is equiavalent to + * @f[ + * \rho = \biggl|\biggl|\mathbf{R3}\bigl((t_{rx} - t_{tx})*\omega)\bigl)\cdot r^{sv} - r^{rx}\biggl|\biggl| + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] rxPos (@f$r^rx@f$) The receiver's position in ECEF + * coordinates + * @param[in] receive (@f$t_{rx}@f$) The time of signal receive + * @param[in] svPos (@f$r^sv@f$) The SV's position in ECEF coordinates + * @param[in] transmit (@f$t_{tx}@f$) The time of signal transmit + * @param[in] ellipsoid Used to provide an angular rate of rotation + * of the ECEF (@f$\omega@f$) + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A tuple of the range (@f$\rho@f$) and the rotated SV + * coordinates (@f$\mathbf{R3}(\tau*\omega)\cdot r^{sv}@f$) + */ + static std::tuple computeRange( + const Position& rxPos, + const CommonTime& receive, + const Position& svPos, + const CommonTime& transmit, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Compute geometric range from an SV's transmitting position + * to a receiver's position and accounting for the rotation + * of the ECEF frame during the time of flight. + * + * The computation is equiavalent to + * @f[ + * \rho = \biggl|\biggl|\mathbf{R3}\bigl(\tau*\omega\bigl)\cdot r^{sv} - r^{rx}\biggl|\biggl| + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] rxPos (@f$r^rx@f$) The receiver's position in ECEF + * coordinates + * @param[in] svPos (@f$r^sv@f$) The SV's position in ECEF coordinates + * @param[in] tof (@f$\tau@f$) The time of flight between transmission + * and reception + * @param[in] ellipsoid Used to provide an angular rate of rotation + * of the ECEF (@f$\omega@f$) + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A tuple of the range (@f$\rho@f$) and the rotated SV + * coordinates (@f$\mathbf{R3}(\tau*\omega)\cdotr^{sv}@f$) + */ + static std::tuple computeRange( + const Position& rxPos, + const Position& svPos, + double tof, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Transform ECEF coordinates into rotated ECEF frame + * + * The transformation is equiavalent to + * @f[ + * v\prime=\mathbf{R3}(dt*\omega)\cdot v + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] vec An ECEF vector + * @param[in] dt Time of rotation in seconds + * @param[in] ellipsoid Provides the angular rate of the ECEF + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A copy of \a vec but with coordinates in the rotated frame + */ + static Triple rotateECEF( + const Triple& vec, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Transform ECEF coordinates into rotated ECEF frame + * + * The transformation is equiavalent to + * @f[ + * v\prime=\mathbf{R3}(dt*\omega)\cdot v + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] vec A position. If it is not in ECEF it will first + * be converted to ECEF before performing rotation. + * @param[in] dt Time of rotation in seconds + * @param[in] ellipsoid Provides the angular rate of the ECEF + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A copy \a vec but with coordinates in the rotated frame. + * The output Position will be in the same coordinate system + * as the input \a vec. + */ + static Position rotateECEF( + const Position& vec, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + /** Transform ECEF coordinates into rotated ECEF frame + * + * This method will transform both the \a xvt position and velocity + * vectors to keep them consistent. + * + * The transformation is equiavalent to + * @f[ + * v\prime=\mathbf{R3}(dt*\omega)\cdot v + * @f] + * + * @note An approximation of ECEF rotation is used that is + * applicable for small time deltas (<1s). Do not use this + * method for larger rotations. + * + * @param[in] xvt An ECEF position and velocity + * @param[in] dt Time of rotation in seconds + * @param[in] ellipsoid Provides the angular rate of the ECEF + * @param[in] smallAngleApprox If true, uses the small angle + * approximation to skip trigonometric computations. + * This can be used to reduce the number of operations but + * sacrifice precision. + * @return A copy of the provided Xvt but with the position and + * velocity vectors in the rotated ECEF frame + */ + static Xvt rotateECEF( + const Xvt& xvt, + double dt, + const EllipsoidModel& ellipsoid, + bool smallAngleApprox=false + ); + + }; // end class RawRange + + //@} + +} // namespace gnsstk + +#endif diff --git a/core/lib/Geomatics/PreciseRange.cpp b/core/lib/Geomatics/PreciseRange.cpp index 6032e7b7f..ca53429a4 100644 --- a/core/lib/Geomatics/PreciseRange.cpp +++ b/core/lib/Geomatics/PreciseRange.cpp @@ -43,11 +43,15 @@ // system includes #include // for ostringstream +#include // GNSSTk includes #include "GNSSconstants.hpp" +#include "EllipsoidModel.hpp" #include "GPSEllipsoid.hpp" #include "MiscMath.hpp" #include "Xvt.hpp" +#include "RawRange.hpp" + // geomatics #include "SolarPosition.hpp" #include "SunEarthSatGeometry.hpp" @@ -60,95 +64,88 @@ namespace gnsstk { double PreciseRange::ComputeAtTransmitTime(const CommonTime& nomRecTime, const double pr, - const Position& Receiver, + const Position& rxPos, const SatID sat, const AntexData& antenna, - const std::string& Freq1, - const std::string& Freq2, - SolarSystem& SolSys, - NavLibrary& Eph, - bool isCOM) + const std::string& freq1, + const std::string& freq2, + SolarSystem& solSys, + NavLibrary& eph, + bool isCOM, + const EllipsoidModel& ellipsoid) { try { - int i; - Position Rx(Receiver); - GPSEllipsoid ellips; + bool success; Xvt svPosVel; - // nominal transmit time - transmit = nomRecTime; // receive time on receiver's clock - transmit -= - pr / ellips.c(); // correct for measured time of flight and Rx clock - - /* get the satellite position at the nominal time, computing and - correcting for the satellite clock bias and other delays */ - if(! Eph.getXvt(NavSatelliteID(sat), transmit, svPosVel)) + // Initial transmit time estimate from pseudorange + std::tie(success, transmit) = + RawRange::estTransmitFromObs(nomRecTime, pr, eph, + NavSatelliteID(sat)); + if(!success) { InvalidRequest ir("getXvt failed"); GNSSTK_THROW(ir); } - SatR.setECEF(svPosVel.x[0], svPosVel.x[1], svPosVel.x[2]); + if(!eph.getXvt(NavSatelliteID(sat), transmit, svPosVel)) + { + InvalidRequest ir("getXvt failed"); + GNSSTK_THROW(ir); + } - // update the transmit time for sat clk bias + relativity - transmit -= svPosVel.clkbias + svPosVel.relcorr; + SatR.setECEF(svPosVel.x); /* Sagnac effect ref. Ashby and Spilker, GPS: Theory and Application, 1996 Vol 1, pg - 673. this is w(Earth) * (SatR cross Rx).Z() / c*c in seconds beware + 673. this is w(Earth) * (SatR cross rxPos).Z() / c*c in seconds beware numerical error by differencing very large to get very small */ - Sagnac = ((SatR.X() / ellips.c()) * (Rx.Y() / ellips.c()) - - (SatR.Y() / ellips.c()) * (Rx.X() / ellips.c())) * - ellips.angVelocity(); + Sagnac = ((SatR.X() / ellipsoid.c()) * (rxPos.Y() / ellipsoid.c()) - + (SatR.Y() / ellipsoid.c()) * (rxPos.X() / ellipsoid.c())) * + ellipsoid.angVelocity(); transmit -= Sagnac; /* compute other delays -- very small 2GM/c^2 = 0.00887005608 m^3/s^2 * s^2/m^2 = m */ - double rx = Rx.radius(); + double rx = rxPos.radius(); if (::fabs(rx) < 1.e-8) { GNSSTK_THROW(Exception("Rx at origin!")); } double rs = SatR.radius(); - double dr = range(SatR, Rx); + double dr; + std::tie(dr, std::ignore) = + RawRange::computeRange(rxPos, SatR, 0, ellipsoid); relativity2 = -0.00887005608 * ::log((rx + rs + dr) / (rx + rs - dr)); - transmit -= relativity2 / ellips.c(); + transmit -= relativity2 / ellipsoid.c(); // iterate satellite position - if(! Eph.getXvt(NavSatelliteID(sat), transmit, svPosVel)) + if(! eph.getXvt(NavSatelliteID(sat), transmit, svPosVel)) { InvalidRequest ir("getXvt failed"); GNSSTK_THROW(ir); } - // Do NOT replace these with Xvt - SatR.setECEF(svPosVel.x[0], svPosVel.x[1], svPosVel.x[2]); - SatV.setECEF(svPosVel.v[0], svPosVel.v[1], svPosVel.v[2]); // ---------------------------------------------------------- // save relativity and satellite clock - relativity = svPosVel.relcorr * ellips.c(); - satclkbias = svPosVel.clkbias * ellips.c(); - satclkdrift = svPosVel.clkdrift * ellips.c(); + relativity = svPosVel.relcorr * ellipsoid.c(); + satclkbias = svPosVel.clkbias * ellipsoid.c(); + satclkdrift = svPosVel.clkdrift * ellipsoid.c(); // correct for Earth rotation - double sxyz[3], wt; - rawrange = range(SatR, Rx); - wt = ellips.angVelocity() * rawrange / ellips.c(); - sxyz[0] = ::cos(wt) * SatR.X() + ::sin(wt) * SatR.Y(); - sxyz[1] = -::sin(wt) * SatR.X() + ::cos(wt) * SatR.Y(); - sxyz[2] = SatR.Z(); - SatR.setECEF(sxyz); - sxyz[0] = ::cos(wt) * SatV.X() + ::sin(wt) * SatV.Y(); - sxyz[1] = -::sin(wt) * SatV.X() + ::cos(wt) * SatV.Y(); - sxyz[2] = SatV.Z(); - SatV.setECEF(sxyz); - - // geometric range, again - rawrange = range(SatR, Rx); + std::tie(rawrange, std::ignore) = + RawRange::computeRange(rxPos, SatR, 0, ellipsoid); + double dt = rawrange / ellipsoid.c(); + std::tie(rawrange, svPosVel) = + RawRange::computeRange(rxPos, svPosVel, dt, ellipsoid); + + // Do NOT replace these with Xvt + SatR.setECEF(svPosVel.x); + SatV.setECEF(svPosVel.v); // Compute line of sight, satellite to receiver - Triple S2R(Rx.X() - SatR.X(), Rx.Y() - SatR.Y(), Rx.Z() - SatR.Z()); + Triple S2R(rxPos.X() - SatR.X(), rxPos.Y() - SatR.Y(), rxPos.Z() - SatR.Z()); S2R = S2R.unitVector(); // ---------------------------------------------------------- @@ -156,14 +153,14 @@ namespace gnsstk if (isCOM && antenna.isValid()) { // must combine PCO/V from freq1,2 - unsigned int freq1(strtoul(Freq1.substr(1).c_str(), 0, 10)); - unsigned int freq2(strtoul(Freq2.substr(1).c_str(), 0, 10)); - double alpha(getAlpha(sat.system, freq1, freq2)); + unsigned int freq1num(strtoul(freq1.substr(1).c_str(), 0, 10)); + unsigned int freq2num(strtoul(freq2.substr(1).c_str(), 0, 10)); + double alpha(getAlpha(sat.system, freq1num, freq2num)); double fact1((alpha + 1.0) / alpha); double fact2(-1.0 / alpha); // if single frequency, freq2==alpha==0, fact's=nan - if (freq2 == 0) + if (freq2num == 0) { fact1 = 1.0; fact2 = 0.0; @@ -174,9 +171,9 @@ namespace gnsstk // get satellite attitude from SolarSystem; if not valid, get low // accuracy version from SunEarthSatGeometry and SolarPosition. - if (SolSys.EphNumber() != -1) + if (solSys.EphNumber() != -1) { - SVAtt = SolSys.satelliteAttitude(transmit, SatR); + SVAtt = solSys.satelliteAttitude(transmit, SatR); } else { @@ -187,12 +184,12 @@ namespace gnsstk // phase center offset vector in body frame Vector PCO(3); - Triple pco2, pco1(antenna.getPhaseCenterOffset(Freq1)); - if (freq2 != 0) + Triple pco2, pco1(antenna.getPhaseCenterOffset(freq1)); + if (freq2num != 0) { - pco2 = antenna.getPhaseCenterOffset(Freq2); + pco2 = antenna.getPhaseCenterOffset(freq2); } - for (i = 0; i < 3; i++) + for (unsigned int i = 0; i < 3; i++) { // body frame, mm -> m, iono-free combo PCO(i) = (fact1 * pco1[i] + fact2 * pco2[i]) / 1000.0; @@ -208,11 +205,11 @@ namespace gnsstk // phase center variation TD should this should be subtracted from // rawrange? get the body frame azimuth and nadir angles double nadir, az, pcv1, pcv2(0.0); - satelliteNadirAzimuthAngles(SatR, Rx, SVAtt, nadir, az); - pcv1 = antenna.getPhaseCenterVariation(Freq1, az, nadir); - if (freq2 != 0) + satelliteNadirAzimuthAngles(SatR, rxPos, SVAtt, nadir, az); + pcv1 = antenna.getPhaseCenterVariation(freq1, az, nadir); + if (freq2num != 0) { - pcv2 = antenna.getPhaseCenterVariation(Freq2, az, nadir); + pcv2 = antenna.getPhaseCenterVariation(freq2, az, nadir); } satLOSPCV = 0.001 * (fact1 * pcv1 + fact2 * pcv2); } @@ -224,16 +221,16 @@ namespace gnsstk // ---------------------------------------------------------- // direction cosines - for (i = 0; i < 3; i++) + for (unsigned int i = 0; i < 3; i++) { cosines[i] = -S2R[i]; // receiver to satellite } // elevation and azimuth - elevation = Rx.elevation(SatR); - azimuth = Rx.azimuth(SatR); - elevationGeodetic = Rx.elevationGeodetic(SatR); - azimuthGeodetic = Rx.azimuthGeodetic(SatR); + elevation = rxPos.elevation(SatR); + azimuth = rxPos.azimuth(SatR); + elevationGeodetic = rxPos.elevationGeodetic(SatR); + azimuthGeodetic = rxPos.azimuthGeodetic(SatR); // return corrected ephemeris range return (rawrange - satclkbias - relativity - relativity2 - satLOSPCO + diff --git a/core/lib/Geomatics/PreciseRange.hpp b/core/lib/Geomatics/PreciseRange.hpp index e46a8db1f..a47e21584 100644 --- a/core/lib/Geomatics/PreciseRange.hpp +++ b/core/lib/Geomatics/PreciseRange.hpp @@ -46,6 +46,8 @@ //------------------------------------------------------------------------------------ // GNSSTk +#include "EllipsoidModel.hpp" +#include "GPSEllipsoid.hpp" #include "CommonTime.hpp" #include "Matrix.hpp" #include "Position.hpp" @@ -81,30 +83,32 @@ namespace gnsstk as well as all the CER quantities. @param nomRecTime nominal receive time @param pr measured pseudorange at this time - @param Rx receiver position + @param rxPos receiver position @param sat satellite @param antenna satellite antenna data; @param freq1,freq2 ANTEX frequencies to evaluate PCO/Vs eg 'G01' if freq2 is zero e.g. 'G00', compute single freq (freq1) PCO/Vs - @param SolSys SolarSystem object, to get SatelliteAttitude() + @param solSys SolarSystem object, to get SatelliteAttitude() if any of above 4 not valid, PCO/V correction is NOT done (silently) - @param Eph Ephemeris store + @param eph Ephemeris store @param isCOM if true, Eph is Center-of-mass, else antenna-phase-center, default false. + @param ellipsoid Ellipsoid model to provide an ECEF rotation rate. @return corrected raw range @throw Exception if ephemeris is not found */ double ComputeAtTransmitTime(const CommonTime& nomRecTime, const double pr, - const Position& Rx, + const Position& rxPos, const SatID sat, const AntexData& antenna, const std::string& freq1, const std::string& freq2, - SolarSystem& SolSys, - NavLibrary& Eph, - bool isCOM = false); + SolarSystem& solSys, + NavLibrary& eph, + bool isCOM = false, + const EllipsoidModel& ellipsoid = GPSEllipsoid()); /** Version with no antenna, and therefore no Attitude and no SolarSystem; @@ -113,17 +117,18 @@ namespace gnsstk */ double ComputeAtTransmitTime(const CommonTime& nomRecTime, const double pr, - const Position& Rx, + const Position& rxPos, const SatID sat, - NavLibrary& Eph) + NavLibrary& eph, + const EllipsoidModel& ellipsoid = GPSEllipsoid()) { // ant will be invalid, so antenna computations will be skipped; // thus satellite attitude will not be needed. AntexData ant; SolarSystem ss; std::string s; - return ComputeAtTransmitTime(nomRecTime, pr, Rx, sat, ant, s, s, ss, - Eph); + return ComputeAtTransmitTime(nomRecTime, pr, rxPos, sat, ant, s, s, ss, + eph, false, ellipsoid); } /** diff --git a/core/lib/ORD/ord.cpp b/core/lib/ORD/ord.cpp index fc2945d0c..f71a516d6 100644 --- a/core/lib/ORD/ord.cpp +++ b/core/lib/ORD/ord.cpp @@ -36,11 +36,20 @@ // //============================================================================== +#include #include #include #include "ord.hpp" #include "GPSEllipsoid.hpp" #include "GNSSconstants.hpp" +#include "RawRange.hpp" +#include "Position.hpp" +#include "SatID.hpp" +#include "CommonTime.hpp" +#include "NavLibrary.hpp" +#include "Xvt.hpp" +#include "NavSatelliteID.hpp" +#include "GPSEllipsoid.hpp" using std::vector; using std::cout; @@ -48,29 +57,6 @@ using std::cout; namespace gnsstk { namespace ord { -// When calculating range with the receiver's clock, the rotation of the earth -// during the time between transmission and receipt must be included. This -// updates svPosVel to account for that rotation. -// -Xvt rotateEarth(const Position& Rx, const Xvt& svPosVel, - const EllipsoidModel& ellipsoid) { - Xvt revisedXvt(svPosVel); - - double tof = RSS(svPosVel.x[0] - Rx.X(), svPosVel.x[1] - Rx.Y(), - svPosVel.x[2] - Rx.Z()) / ellipsoid.c(); - double wt = ellipsoid.angVelocity() * tof; - double sx = ::cos(wt) * svPosVel.x[0] + ::sin(wt) * svPosVel.x[1]; - double sy = -::sin(wt) * svPosVel.x[0] + ::cos(wt) * svPosVel.x[1]; - revisedXvt.x[0] = sx; - revisedXvt.x[1] = sy; - sx = ::cos(wt) * svPosVel.v[0] + ::sin(wt) * svPosVel.v[1]; - sy = -::sin(wt) * svPosVel.v[0] + ::cos(wt) * svPosVel.v[1]; - revisedXvt.v[0] = sx; - revisedXvt.v[1] = sy; - - return revisedXvt; -} - double IonosphereFreeRange(const std::vector& frequencies, const std::vector& pseudoranges) { // Check vectors are same length @@ -128,148 +114,91 @@ gnsstk::Xvt getSvXvt(const gnsstk::SatID& satId, const gnsstk::CommonTime& time, return rv; } -double RawRange1(const gnsstk::Position& rxLoc, const gnsstk::SatID& satId, - const gnsstk::CommonTime& timeReceived, - NavLibrary& ephemeris, gnsstk::Xvt& svXvt) { - try { - int nit; - double tof, tof_old, rawrange; - GPSEllipsoid ellipsoid; - - CommonTime transmit(timeReceived); - Xvt svPosVel; // Initialize to zero - - nit = 0; - tof = 0.07; // Initial guess 70ms - do { - // best estimate of transmit time - transmit = timeReceived; - transmit -= tof; - tof_old = tof; - // get SV position - try { - /** @todo getXvt was expected to throw an exception on - * failure in the past. This assert more or less mimics - * that behavior. Refactoring is needed. */ - GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), transmit, - svPosVel)); - } catch (InvalidRequest& e) { - GNSSTK_RETHROW(e); - } - - svPosVel = rotateEarth(rxLoc, svPosVel, ellipsoid); - // update raw range and time of flight - rawrange = RSS(svPosVel.x[0] - rxLoc.X(), svPosVel.x[1] - rxLoc.Y(), - svPosVel.x[2] - rxLoc.Z()); - tof = rawrange / ellipsoid.c(); - } while (ABS(tof-tof_old) > 1.e-13 && ++nit < 5); - - svXvt = svPosVel; - - return rawrange; - } catch (gnsstk::Exception& e) { - GNSSTK_RETHROW(e); - } +double RawRange1( + const Position& rxLoc, + const SatID& satId, + const CommonTime& timeReceived, + NavLibrary& ephemeris, + Xvt& svXvt +) +{ + bool success; + double range; + GPSEllipsoid ellipsoid; + std::tie(success, range, svXvt) = + RawRange::fromReceive(rxLoc, timeReceived, ephemeris, + NavSatelliteID(satId), ellipsoid); + GNSSTK_ASSERT(success); + return range; } -double RawRange2(double pseudorange, const gnsstk::Position& rxLoc, - const gnsstk::SatID& satId, const gnsstk::CommonTime& time, - NavLibrary& ephemeris, gnsstk::Xvt& svXvt) { - try { - CommonTime tt, transmit; - Xvt svPosVel; // Initialize to zero - double rawrange; - GPSEllipsoid ellipsoid; - - // 0-th order estimate of transmit time = receiver - pseudorange/c - transmit = time; - transmit -= pseudorange / C_MPS; - tt = transmit; - - // correct for SV clock - for (int i = 0; i < 2; i++) { - // get SV position - try { - /** @todo getXvt was expected to throw an exception on - * failure in the past. This assert more or less mimics - * that behavior. Refactoring is needed. */ - GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), tt, - svPosVel)); - } catch (InvalidRequest& e) { - GNSSTK_RETHROW(e); - } - tt = transmit; - // remove clock bias and relativity correction - tt -= (svPosVel.clkbias + svPosVel.relcorr); - } - - svPosVel = rotateEarth(rxLoc, svPosVel, ellipsoid); - - // raw range - rawrange = RSS(svPosVel.x[0] - rxLoc.X(), - svPosVel.x[1] - rxLoc.Y(), - svPosVel.x[2] - rxLoc.Z()); - - svXvt = svPosVel; - - return rawrange; - } catch (gnsstk::Exception& e) { - GNSSTK_RETHROW(e); - } + +double RawRange2(double pseudorange, const Position& rxLoc, + const SatID& satId, const CommonTime& time, + NavLibrary& ephemeris, Xvt& svXvt) { + + bool success; + double range; + GPSEllipsoid ellipsoid; + std::tie(success, range, svXvt) = + RawRange::fromNominalReceiveWithObs(rxLoc, time, pseudorange, ephemeris, + NavSatelliteID(satId), ellipsoid); + GNSSTK_ASSERT(success); + return range; } + double RawRange3(double pseudorange, const gnsstk::Position& rxLoc, const gnsstk::SatID& satId, const gnsstk::CommonTime& time, NavLibrary& ephemeris, gnsstk::Xvt& svXvt) { - Position trx(rxLoc); - trx.asECEF(); - - Xvt svPosVel; - /** @todo getXvt was expected to throw an exception on - * failure in the past. This assert more or less mimics - * that behavior. Refactoring is needed. */ - GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), time, - svPosVel)); - - // compute rotation angle in the time of signal transit - - // While this is quite similiar to rotateEarth, its not the same - // and jcl doesn't know which is really correct - // BWT this uses the measured pseudorange, corrected for SV clock and - // relativity, to compute the time of flight; rotateEarth uses the value - // computed from the receiver position and the ephemeris. They should be - // very nearly the same, and multiplying by angVel/c should make the angle - // of rotation very nearly identical. - GPSEllipsoid ell; - double range(pseudorange/ell.c() - svPosVel.clkbias - svPosVel.relcorr); - double rotation_angle = -ell.angVelocity() * range; - svPosVel.x[0] = svPosVel.x[0] - svPosVel.x[1] * rotation_angle; - svPosVel.x[1] = svPosVel.x[1] + svPosVel.x[0] * rotation_angle; - // svPosVel.x[2] = svPosVel.x[2]; // ?? Reassign for readability ?? - - double rawrange = trx.slantRange(svPosVel.x); - - svXvt = svPosVel; - return rawrange; + bool success; + double range; + GPSEllipsoid ellipsoid; + std::tie(success, range, svXvt) = + RawRange::fromSvTransmitWithObs(rxLoc, pseudorange, ephemeris, + NavSatelliteID(satId), time, ellipsoid, + true); + GNSSTK_ASSERT(success); + return range; } double RawRange4(const gnsstk::Position& rxLoc, const gnsstk::SatID& satId, const gnsstk::CommonTime& time, NavLibrary& ephemeris, gnsstk::Xvt& svXvt) { - try { - gnsstk::GPSEllipsoid gm; - Xvt svPosVel; - /** @todo getXvt was expected to throw an exception on - * failure in the past. This assert more or less mimics - * that behavior. Refactoring is needed. */ - GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), time, - svPosVel)); - double pr = svPosVel.preciseRho(rxLoc, gm); - return RawRange2(pr, rxLoc, satId, time, ephemeris, svXvt); - } - catch(gnsstk::Exception& e) { - GNSSTK_RETHROW(e); - } + + GNSSTK_ASSERT(ephemeris.getXvt(NavSatelliteID(satId), time, svXvt)); + + // Compute initial time of flight estimate using the + // geometric range at transmit time. This fails to account + // for the rotation of the earth, but should be good to + // within about 40 m + GPSEllipsoid ellipsoid; + double tofEstimate = rxLoc.slantRange(svXvt.x) / ellipsoid.c(); + + bool success; + double range; + Xvt rotatedSvXvt; + + // First estimate the range by using the receiveNominal as the + // transmit time. + std::tie(success, range, rotatedSvXvt) = + RawRange::fromSvTransmit(rxLoc, ephemeris, NavSatelliteID(satId), time, + ellipsoid, true, SVHealth::Any, + NavValidityType::ValidOnly, NavSearchOrder::User, + tofEstimate, 0, 2); + GNSSTK_ASSERT(success); + + // Create a mock pseudorange using the estimated range and SV clock offsets + double fakePsuedorange = range - + (rotatedSvXvt.clkbias + rotatedSvXvt.relcorr) * ellipsoid.c(); + + std::tie(success, range, rotatedSvXvt) = + RawRange::fromNominalReceiveWithObs(rxLoc, time, fakePsuedorange, + ephemeris, NavSatelliteID(satId), + ellipsoid, false); + GNSSTK_ASSERT(success); + svXvt = rotatedSvXvt; + return range; } double SvClockBiasCorrection(const gnsstk::Xvt& svXvt) { diff --git a/core/lib/ORD/ord.hpp b/core/lib/ORD/ord.hpp index a7fb3c48e..4b26649d5 100644 --- a/core/lib/ORD/ord.hpp +++ b/core/lib/ORD/ord.hpp @@ -94,6 +94,8 @@ gnsstk::Xvt getSvXvt(const gnsstk::SatID& sat_id, const gnsstk::CommonTime& time NavLibrary& ephemeris); /// Calculate the raw range at RECEIVE time per RECEIVER clock. +/// @deprecated This function is deprecated as of the December 2022 release +/// Use RawRange::fromReceive() instead /// @see CorrectedEphemerisRange::ComputeAtReceiveTime() /// @param rx_loc The location of the receiver. /// @param sat_id Identifier for the satellite @@ -106,6 +108,8 @@ double RawRange1(const gnsstk::Position& rx_loc, const gnsstk::SatID& sat_id, NavLibrary& ephemeris, gnsstk::Xvt& sv_xvt); /// Calculate the raw range at TRANSMIT time per the RECEIVER clock. +/// @deprecated This function is deprecated as of the December 2022 release +/// Use RawRange::fromNominalReceiveWithObs() instead /// @see CorrectedEphemerisRange::ComputeAtTransmitTime(const CommonTime&, const double&, const Position&, const SatID, NavLibrary&, NavSearchOrder, SVHealth, NavValidityType) /// @param pseudorange Pseudorange in meters to seed the calculation. /// @param rx_loc The location of the receiver. @@ -119,6 +123,8 @@ double RawRange2(double pseudorange, const gnsstk::Position& rx_loc, NavLibrary& ephemeris, gnsstk::Xvt& sv_xvt); /// Calculate the raw range at TRANSMIT time per the SATELLITE clock +/// @deprecated This function is deprecated as of the December 2022 release +/// Use RawRange::fromSvTransmitWithObs() instead /// @see CorrectedEphemerisRange::ComputeAtTransmitSvTime() /// @param pseudorange Pseudorange in meters to seed the calculation. /// @param rx_loc The location of the receiver. @@ -133,6 +139,8 @@ double RawRange3(double pseudorange, const gnsstk::Position& rx_loc, /// Calculate the raw range at TRANSMIT time per RECEIVER clock, without /// seeding the pseudorange. +/// @deprecated This function is deprecated as of the December 2022 release +/// Use RawRange::fromNominalReceive() instead /// @see CorrectedEphemerisRange::ComputeAtTransmitTime(const CommonTime& trNom, const Position&, const SatID, NavLibrary&, NavSearchOrder, SVHealth, NavValidityType) /// @param rx_loc The location of the receiver. /// @param sat_id Identifier for the satellite diff --git a/core/tests/GNSSCore/CMakeLists.txt b/core/tests/GNSSCore/CMakeLists.txt index bbbf77f06..69fb9c78e 100644 --- a/core/tests/GNSSCore/CMakeLists.txt +++ b/core/tests/GNSSCore/CMakeLists.txt @@ -266,5 +266,9 @@ target_link_libraries(CorrectionResults_T gnsstk) add_test(NAME GNSSCore_CorrectionResults COMMAND $) set_property(TEST GNSSCore_CorrectionResults PROPERTY LABELS Solutions) +add_executable(RawRange_T RawRange_T.cpp) +target_link_libraries(RawRange_T gnsstk) +add_test(NAME GNSSCore_RawRange COMMAND $) + ############################################################################### ############################################################################### diff --git a/core/tests/GNSSCore/RawRange_T.cpp b/core/tests/GNSSCore/RawRange_T.cpp new file mode 100644 index 000000000..8fbfd3bac --- /dev/null +++ b/core/tests/GNSSCore/RawRange_T.cpp @@ -0,0 +1,651 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include + +#include "Triple.hpp" +#include "TestUtil.hpp" +#include "NavDataFactory.hpp" +#include "RinexNavDataFactory.hpp" +#include "NavLibrary.hpp" +#include "EphemerisRange.hpp" +#include "GPSEllipsoid.hpp" +#include "SatID.hpp" +#include "NavSatelliteID.hpp" + +#include "RawRange.hpp" + +using namespace gnsstk; + +class RawRange_T +{ +public: + RawRange_T(); + + unsigned testRotateECEFTriple(); + unsigned testRotateECEFPosition(); + unsigned testRotateECEFXvt(); + unsigned testComputeRangePosition(); + unsigned testComputeRangeTriple(); + unsigned testComputeRangeXvt(); + unsigned testEstTransmitFromReceive(); + unsigned testEstTransmitFromObs(); + unsigned testFromSvPos(); + unsigned testFromSvTransmit(); + unsigned testFromSvTransmitWithObs(); + unsigned testFromReceive(); + unsigned testFromNominalReceive(); + unsigned testFromNominalReceiveWithObs(); + NavLibrary navLib; +}; + + +RawRange_T :: +RawRange_T() + : navLib() +{ + NavDataFactoryPtr + ndfp(std::make_shared()); + + std::string fname = getPathData() + getFileSep() + + "arlm2000.15n"; + + navLib.addFactory(ndfp); + + RinexNavDataFactory *rndfp = + dynamic_cast(ndfp.get()); + + GNSSTK_ASSERT(rndfp->addDataSource(fname)); +} + + +unsigned RawRange_T :: +testRotateECEFTriple() +{ + TUDEF("RawRange", "rotateECEF(Triple)"); + Triple t(-7.0e5, -5.0e6, 3.0e6); + double dt = 0.07; + GPSEllipsoid ellipsoid; + Triple actual; + + actual = RawRange::rotateECEF(t, dt, ellipsoid); + TUASSERTFESMRT(-700025.52239389379974, actual[0]); + TUASSERTFESMRT(-4999996.4267984386533, actual[1]); + TUASSERTFESMRT(3000000.0, actual[2]); + + // The small angle approximation approach can make a slight difference + actual = RawRange::rotateECEF(t, dt, ellipsoid, true); + TUASSERTFESMRT(-700025.52240301342681, actual[0]); + TUASSERTFESMRT(-4999996.4268635781482, actual[1]); + TUASSERTFESMRT(3000000.0, actual[2]); + + TURETURN(); +} + +unsigned RawRange_T :: +testRotateECEFPosition() +{ + TUDEF("RawRange", "rotateECEF(Position)"); + // The geodetic equivalent of ECEF -7.0e5, -5.0e6, 3.0e6 + Position p(30.902726259175704, 262.03038960567716, + -499714.8540719012, + Position::CoordinateSystem::Geodetic); + double dt = 0.07; + GPSEllipsoid ellipsoid; + Position actual; + + // Return result should still be in the coordinate system as provided + actual = RawRange::rotateECEF(p, dt, ellipsoid); + TUASSERTE(Position::CoordinateSystem, + Position::CoordinateSystem::Geodetic, + actual.getCoordinateSystem()); + TUASSERTFESMRT(30.902726259174816192, actual[0]); + TUASSERTFESMRT(262.03009714047612988, actual[1]); + TUASSERTFESMRT(-499714.85406564455479, actual[2]); + + // Should be the same as the results from testRotateECEFTriple + // but with additional fudge factor due to geodetic to ECEF conversions + actual.asECEF(); + TUASSERTFEPS(-700025.52239389379974, actual[0], 1e-4); + TUASSERTFEPS(-4999996.4267984386533, actual[1], 1e-4); + TUASSERTFEPS(3000000.0, actual[2], 1e-5); + + // The small angle approximation approach can make a slight difference + actual = RawRange::rotateECEF(p, dt, ellipsoid, true); + actual.asECEF(); + TUASSERTFEPS(-700025.52240301342681, actual[0], 1e-4); + TUASSERTFEPS(-4999996.4268635781482, actual[1], 1e-4); + TUASSERTFEPS(3000000.0, actual[2], 1e-5); + + TURETURN(); +} + +unsigned RawRange_T :: +testRotateECEFXvt() +{ + TUDEF("RawRange", "rotateECEF(Triple)"); + Xvt xvt; + xvt.x = Triple(-7.0e5, -5.0e6, 3.0e6); + xvt.v = Triple(100, 200, 300); + xvt.clkbias = 0.3; + xvt.relcorr = 0.002; + double dt = 0.07; + GPSEllipsoid ellipsoid; + Xvt actual; + + actual = RawRange::rotateECEF(xvt, dt, ellipsoid); + TUASSERTFESMRT(-700025.52239389379974, actual.x[0]); + TUASSERTFESMRT(-4999996.4267984386533, actual.x[1]); + TUASSERTFESMRT(3000000.0, actual.x[2]); + TUASSERTFESMRT(100.00102089481774215, actual.v[0]); + TUASSERTFESMRT(199.99948954933415735, actual.v[1]); + TUASSERTFESMRT(300.0, actual.v[2]); + // Other Xvt member variables should be the same + TUASSERTFE(0.3, xvt.clkbias); + TUASSERTFE(0.002, xvt.relcorr); + + // The small angle approximation approach can make a slight difference + actual = RawRange::rotateECEF(xvt, dt, ellipsoid, true); + TUASSERTFESMRT(-700025.52240301342681, actual.x[0]); + TUASSERTFESMRT(-4999996.4268635781482, actual.x[1]); + TUASSERTFESMRT(3000000.0, actual.x[2]); + TUASSERTFESMRT(100.00102089612053646, actual.v[0]); + TUASSERTFESMRT(199.99948955193971756, actual.v[1]); + TUASSERTFESMRT(300.0, actual.v[2]); + + TURETURN(); +} + + +unsigned RawRange_T :: +testComputeRangePosition() +{ + TUDEF("RawRange", "computeRange(Position)"); + // Should be able to handle Positions in non-ECEF coordinates + Position loc1(-7.0e5, -5.0e6, 3.0e6); + loc1.transformTo(Position::CoordinateSystem::Geodetic); + Position loc2(-7.0e6, -5.0e7, 3.0e7); + loc2.transformTo(Position::CoordinateSystem::Geodetic); + + double dt = 0.07; + CommonTime t1 = CommonTime::BEGINNING_OF_TIME; + GPSEllipsoid ellipsoid; + + double range; + Position rotatedLoc2; + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, loc2, dt, ellipsoid); + TUASSERTFEPS(52855368.696156509221, range, 1.0e-4); + // Returned triple should be the rotated position of loc2 + rotatedLoc2.transformTo(Position::CoordinateSystem::Cartesian); + TUASSERTFEPS(-7000255.2239389382303, rotatedLoc2[0], 1.0e-4); + TUASSERTFEPS(-49999964.267984382808, rotatedLoc2[1], 1.0e-4); + TUASSERTFEPS(30000000.0, rotatedLoc2[2], 1.0e-4); + + // Again with small angle approximation + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, loc2, dt, ellipsoid, true); + TUASSERTFEPS(52855368.696721956134, range, 1.0e-4); + // Returned triple should be the rotated position of loc2 + rotatedLoc2.transformTo(Position::CoordinateSystem::Cartesian); + TUASSERTFEPS(-7000255.2240301342681, rotatedLoc2[0], 1.0e-4); + TUASSERTFEPS(-49999964.268635779619, rotatedLoc2[1], 1.0e-4); + TUASSERTFEPS(30000000.0, rotatedLoc2[2], 1.0e-4); + + // Again with time stamp version + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, t1 + dt, loc2, t1, ellipsoid); + TUASSERTFEPS(52855368.696156509221, range, 1.0e-4); + // Returned triple should be the rotated position of loc2 + rotatedLoc2.transformTo(Position::CoordinateSystem::Cartesian); + TUASSERTFEPS(-7000255.2239389382303, rotatedLoc2[0], 1.0e-4); + TUASSERTFEPS(-49999964.267984382808, rotatedLoc2[1], 1.0e-4); + TUASSERTFEPS(30000000.0, rotatedLoc2[2], 1.0e-4); + + // Again with time stamp version and small angle approximation + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, t1 + dt, loc2, t1, ellipsoid, true); + TUASSERTFEPS(52855368.696721956134, range, 1.0e-4); + // Returned triple should be the rotated position of loc2 + rotatedLoc2.transformTo(Position::CoordinateSystem::Cartesian); + TUASSERTFEPS(-7000255.2240301342681, rotatedLoc2[0], 1.0e-4); + TUASSERTFEPS(-49999964.268635779619, rotatedLoc2[1], 1.0e-4); + TUASSERTFEPS(30000000.0, rotatedLoc2[2], 1.0e-4); + + TURETURN(); +} + +unsigned RawRange_T :: +testComputeRangeTriple() +{ + TUDEF("RawRange", "computeRange(Triple)"); + Triple loc1(-7.0e5, -5.0e6, 3.0e6); + Triple loc2(-7.0e6, -5.0e7, 3.0e7); + double dt = 0.07; + CommonTime t1 = CommonTime::BEGINNING_OF_TIME; + GPSEllipsoid ellipsoid; + + double range; + Triple rotatedLoc2; + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, loc2, dt, ellipsoid); + TUASSERTFESMRT(52855368.696156509221, range); + // Returned triple should be the rotated position of loc2 + TUASSERTFESMRT(-7000255.2239389382303, rotatedLoc2[0]); + TUASSERTFESMRT(-49999964.267984382808, rotatedLoc2[1]); + TUASSERTFESMRT(30000000.0, rotatedLoc2[2]); + + // Again with small angle approximation + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, loc2, dt, ellipsoid, true); + TUASSERTFESMRT(52855368.696721956134, range); + // Returned triple should be the rotated position of loc2 + TUASSERTFESMRT(-7000255.2240301342681, rotatedLoc2[0]); + TUASSERTFESMRT(-49999964.268635779619, rotatedLoc2[1]); + TUASSERTFESMRT(30000000.0, rotatedLoc2[2]); + + // Again with time stamp version + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, t1 + dt, loc2, t1, ellipsoid); + TUASSERTFESMRT(52855368.696156509221, range); + // Returned triple should be the rotated position of loc2 + TUASSERTFESMRT(-7000255.2239389382303, rotatedLoc2[0]); + TUASSERTFESMRT(-49999964.267984382808, rotatedLoc2[1]); + TUASSERTFESMRT(30000000.0, rotatedLoc2[2]); + + // Again with time stamp version and small angle approximation + std::tie(range, rotatedLoc2) = + RawRange::computeRange(loc1, t1 + dt, loc2, t1, ellipsoid, true); + TUASSERTFESMRT(52855368.696721956134, range); + // Returned triple should be the rotated position of loc2 + TUASSERTFESMRT(-7000255.2240301342681, rotatedLoc2[0]); + TUASSERTFESMRT(-49999964.268635779619, rotatedLoc2[1]); + TUASSERTFESMRT(30000000.0, rotatedLoc2[2]); + + TURETURN(); +} + +unsigned RawRange_T :: +testComputeRangeXvt() +{ + TUDEF("RawRange", "computeRange(Xvt)"); + Triple loc1(-7.0e5, -5.0e6, 3.0e6); + + Xvt xvt; + xvt.x = Triple(-7.0e6, -5.0e7, 3.0e7); + xvt.v = Triple(100, 200, 300); + + double dt = 0.07; + CommonTime t1 = CommonTime::BEGINNING_OF_TIME; + GPSEllipsoid ellipsoid; + + double range; + Xvt rotatedXvt; + std::tie(range, rotatedXvt) = + RawRange::computeRange(loc1, xvt, dt, ellipsoid); + TUASSERTFESMRT(52855368.696156509221, range); + // Returned xvt should be the rotated position and velocity + TUASSERTFESMRT(-7000255.2239389382303, rotatedXvt.x[0]); + TUASSERTFESMRT(-49999964.267984382808, rotatedXvt.x[1]); + TUASSERTFESMRT(30000000.0, rotatedXvt.x[2]); + TUASSERTFESMRT(100.00102089481774215, rotatedXvt.v[0]); + TUASSERTFESMRT(199.99948954933415735, rotatedXvt.v[1]); + TUASSERTFESMRT(300.0, rotatedXvt.v[2]); + + // Again with small angle approximation + std::tie(range, rotatedXvt) = + RawRange::computeRange(loc1, xvt, dt, ellipsoid, true); + TUASSERTFESMRT(52855368.696721956134, range); + // Returned xvt should be the rotated position and velocity + TUASSERTFESMRT(-7000255.2240301342681, rotatedXvt.x[0]); + TUASSERTFESMRT(-49999964.268635779619, rotatedXvt.x[1]); + TUASSERTFESMRT(30000000.0, rotatedXvt.x[2]); + TUASSERTFESMRT(100.00102089612053646, rotatedXvt.v[0]); + TUASSERTFESMRT(199.99948955193971756, rotatedXvt.v[1]); + TUASSERTFESMRT(300.0, rotatedXvt.v[2]); + + // Again with time stamp version + std::tie(range, rotatedXvt) = + RawRange::computeRange(loc1, t1 + dt, xvt, t1, ellipsoid); + TUASSERTFESMRT(52855368.696156509221, range); + // Returned xvt should be the rotated position and velocity + TUASSERTFESMRT(-7000255.2239389382303, rotatedXvt.x[0]); + TUASSERTFESMRT(-49999964.267984382808, rotatedXvt.x[1]); + TUASSERTFESMRT(30000000.0, rotatedXvt.x[2]); + TUASSERTFESMRT(100.00102089481774215, rotatedXvt.v[0]); + TUASSERTFESMRT(199.99948954933415735, rotatedXvt.v[1]); + TUASSERTFESMRT(300.0, rotatedXvt.v[2]); + + // Again with time stamp version and small angle approximation + std::tie(range, rotatedXvt) = + RawRange::computeRange(loc1, t1 + dt, xvt, t1, ellipsoid, true); + TUASSERTFESMRT(52855368.696721956134, range); + // Returned xvt should be the rotated position and velocity + TUASSERTFESMRT(-7000255.2240301342681, rotatedXvt.x[0]); + TUASSERTFESMRT(-49999964.268635779619, rotatedXvt.x[1]); + TUASSERTFESMRT(30000000.0, rotatedXvt.x[2]); + TUASSERTFESMRT(100.00102089612053646, rotatedXvt.v[0]); + TUASSERTFESMRT(199.99948955193971756, rotatedXvt.v[1]); + TUASSERTFESMRT(300.0, rotatedXvt.v[2]); + + TURETURN(); +} + +unsigned RawRange_T :: +testEstTransmitFromReceive() +{ + TUDEF("RawRange", "estTransmitFromReceive()"); + + Triple rxPos(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID sat(SatID(5, SatelliteSystem::GPS)); + CommonTime receive(CivilTime(2015, 7, 19, 2, 0, 0.0, TimeSystem::GPS)); + GPSEllipsoid ellipsoid; + + bool success; + CommonTime time; + std::tie(success, time) = RawRange::estTransmitFromReceive( + rxPos, + receive, + navLib, + sat, + ellipsoid); + + TUASSERT(success); + CommonTime exp(CivilTime(2015, 7, 19, 1, 59, 59.92565104107503, TimeSystem::GPS)); + TUASSERT(abs(exp - time) < 1e-9); + + TURETURN(); +} + +unsigned RawRange_T :: +testEstTransmitFromObs() +{ + TUDEF("RawRange", "estTransmitFromObs()"); + + Triple rxPos(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID sat(SatID(5, SatelliteSystem::GPS)); + CommonTime receive(CivilTime(2015, 7, 19, 2, 0, 0.0, TimeSystem::GPS)); + double pseudorange = 2e7; + GPSEllipsoid ellipsoid; + + bool success; + CommonTime time; + std::tie(success, time) = RawRange::estTransmitFromObs( + receive, + pseudorange, + navLib, + sat); + + TUASSERT(success); + CommonTime exp(CivilTime(2015, 7, 19, 1, 59, 59.93350360018778, TimeSystem::GPS)); + TUASSERT(abs(exp - time) < 1e-9); + + TURETURN(); +} + +unsigned RawRange_T :: +testFromReceive() +{ + TUDEF("RawRange", "fromReceive()"); + + Position rxLocation(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID satId(SatID(5, SatelliteSystem::GPS)); + CommonTime time(CivilTime(2015,7,19,2,0,0.0,TimeSystem::GPS)); + GPSEllipsoid ellipsoid; + + Xvt xvt; + double range; + bool success; + std::tie(success, range, xvt) = + RawRange::fromReceive(rxLocation, time, navLib, satId, ellipsoid); + + // @note These fields are slightly different than the Xvt tagged + // at the given time. RawRange tries to determine the position of the SV + // at time of transmit but rotates the coordinates into the ECEF frame + // at time of receive. + TUASSERT(success); + TUASSERTFESMRT(9272533.3762740660459, xvt.x[0]); + TUASSERTFESMRT(-12471159.893898375332, xvt.x[1]); + TUASSERTFESMRT(21480836.886172864586, xvt.x[2]); + TUASSERTFESMRT(2077.3531590469665389, xvt.v[0]); + TUASSERTFESMRT(1796.0597201257969573, xvt.v[1]); + TUASSERTFESMRT(164.40771415613258455, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042654059759786, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8008986915573278037e-09, xvt.relcorr); + TUASSERTFESMRT(22289257.145863413811, range); + TURETURN(); +} + + +unsigned RawRange_T :: +testFromNominalReceiveWithObs() +{ + TUDEF("RawRange", "testFromNominalReceiveWithObs"); + + Position rxLocation(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID satId(SatID(5, SatelliteSystem::GPS)); + CommonTime + time(CivilTime(2015,7,19,2,0,0.0,TimeSystem::GPS)); + double pseduorange = 2e7; + GPSEllipsoid ellipsoid; + + Xvt xvt; + double range; + bool success; + std::tie(success, range, xvt) = + RawRange::fromNominalReceiveWithObs(rxLocation, time, pseduorange, + navLib, satId, ellipsoid); + + // @note These fields are slightly different than the Xvt tagged + // at the given time. RawRange tries to determine the position of the SV + // at time of transmit but rotates the coordinates into the ECEF frame + // at time of receive. + TUASSERT(success); + TUASSERTFESMRT(9272549.688764328137, xvt.x[0]); + TUASSERTFESMRT(-12471145.790274851024, xvt.x[1]); + TUASSERTFESMRT(21480838.177179995924, xvt.x[2]); + TUASSERTFESMRT(2077.3540461841112119, xvt.v[0]); + TUASSERTFESMRT(1796.058914385570688, xvt.v[1]); + TUASSERTFESMRT(164.40410655412986785, xvt.v[2]); + TUASSERTFESMRT(-0.000216410426506673752147, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8009032843852035206e-09, xvt.relcorr); + TUASSERTFESMRT(22289260.787328250706, range); + TURETURN(); +} + + +unsigned RawRange_T :: +testFromSvTransmitWithObs() +{ + TUDEF("RawRange", "fromSvTransmitWithObs"); + + Position rxLocation(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID satId(SatID(5, SatelliteSystem::GPS)); + CommonTime + time(CivilTime(2015,7,19,2,0,0.0,TimeSystem::GPS)); + double pseduorange = 2e7; + GPSEllipsoid ellipsoid; + + Xvt xvt; + double range; + bool success; + std::tie(success, range, xvt) = + RawRange::fromSvTransmitWithObs(rxLocation, pseduorange, navLib, + satId, time, ellipsoid); + + // @note These fields are slightly different than the Xvt tagged + // at the given time. RawRange tries to determine the position of the SV + // at time of transmit but rotates the coordinates into the ECEF frame + // at time of receive. + TUASSERT(success); + TUASSERTFESMRT(9272694.5731354933232, xvt.x[0]); + TUASSERTFESMRT(-12471021.341979622841, xvt.x[1]); + TUASSERTFESMRT(21480849.108445473015, xvt.x[2]); + TUASSERTFESMRT(2077.3605866147809138, xvt.v[0]); + TUASSERTFESMRT(1796.0532152160560599, xvt.v[1]); + TUASSERTFESMRT(164.37355694668559636, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042621940267715, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8009421765298224418e-09, xvt.relcorr); + TUASSERTFESMRT(22289292.961206533015, range); + TURETURN(); +} + + +unsigned RawRange_T :: +testFromNominalReceive() +{ + TUDEF("RawRange", "fromNominalReceive"); + + Position rxLocation(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID satId(SatID(5, SatelliteSystem::GPS)); + CommonTime + time(CivilTime(2015,7,19,2,0,0.0,TimeSystem::GPS)); + GPSEllipsoid ellipsoid; + + Xvt xvt; + double range; + bool success; + std::tie(success, range, xvt) = + RawRange::fromNominalReceive(rxLocation, time, navLib, satId, ellipsoid); + + // @note These fields are slightly different than the Xvt tagged + // at the given time. RawRange tries to determine the position of the SV + // at time of transmit but rotates the coordinates into the ECEF frame + // at time of receive. + TUASSERT(success); + TUASSERTFESMRT(9272533.3759945072234, xvt.x[0]); + TUASSERTFESMRT(-12471159.894135156646, xvt.x[1]); + TUASSERTFESMRT(21480836.886153958738, xvt.x[2]); + TUASSERTFESMRT(2077.353159039827915, xvt.v[0]); + TUASSERTFESMRT(1796.0597201308269177, xvt.v[1]); + TUASSERTFESMRT(164.40771420896862764, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042654059808575, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8008986914900614763e-09, xvt.relcorr); + TUASSERTFESMRT(22289257.145802032202, range); + TURETURN(); +} + +unsigned RawRange_T :: +testFromSvPos() +{ + TUDEF("RawRange","fromSvPos"); + + Position rxPos(-7.0e5, -5.0e6, 3.0e6); + Xvt xvt; + xvt.x = Triple(-9e5, -2e7, 9e6); + xvt.v = Triple(6e2, 1e3, 2e4); + xvt.clkbias = -0.3; + xvt.clkdrift = 0; + xvt.relcorr = -3.5e-6; + GPSEllipsoid ellipsoid; + + double range; + bool success; + Xvt returnXvt; + std::tie(success, range, returnXvt) = + RawRange::fromSvPos(rxPos, xvt, ellipsoid); + TUASSERT(success); + TUASSERTFESMRT(16156730.032176425681, range); + TUASSERTFESMRT(-900078.59885879501235, returnXvt.x[0]); + TUASSERTFESMRT(-19999996.462896592915, returnXvt.x[1]); + TUASSERTFESMRT(9000000.0, returnXvt.x[2]); + TUASSERTFESMRT(600.00392993865398239, returnXvt.v[0]); + TUASSERTFESMRT(999.99764202630535692, returnXvt.v[1]); + TUASSERTFESMRT(20000.0, returnXvt.v[2]); + + TURETURN(); +} + +unsigned RawRange_T :: +testFromSvTransmit() +{ + TUDEF("RawRange","fromSvTransmit"); + + Position rxPos(-7.0e5, -5.0e6, 3.0e6); + NavSatelliteID satId(SatID(5, SatelliteSystem::GPS)); + CommonTime + time(CivilTime(2015,7,19,2,0,0.0,TimeSystem::GPS)); + GPSEllipsoid ellipsoid; + + double range; + bool success; + Xvt returnXvt; + std::tie(success, range, returnXvt) = + RawRange::fromSvTransmit(rxPos, navLib, satId, time, ellipsoid); + TUASSERT(success); + TUASSERTFESMRT(22289291.623843517154, range); + TUASSERTFESMRT(9272687.8255264088511, returnXvt.x[0]); + TUASSERTFESMRT(-12471026.359089374542, returnXvt.x[1]); + TUASSERTFESMRT(21480849.108445473015, returnXvt.x[2]); + TUASSERTFESMRT(2077.361558392346069, returnXvt.v[0]); + TUASSERTFESMRT(1796.0520912329243401, returnXvt.v[1]); + TUASSERTFESMRT(164.37355694668559636, returnXvt.v[2]); + + TURETURN(); +} + + +int main() +{ + RawRange_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.testRotateECEFTriple(); + errorTotal += testClass.testRotateECEFPosition(); + errorTotal += testClass.testRotateECEFXvt(); + errorTotal += testClass.testComputeRangePosition(); + errorTotal += testClass.testComputeRangeTriple(); + errorTotal += testClass.testComputeRangeXvt(); + errorTotal += testClass.testEstTransmitFromReceive(); + errorTotal += testClass.testEstTransmitFromObs(); + errorTotal += testClass.testFromSvPos(); + errorTotal += testClass.testFromSvTransmit(); + errorTotal += testClass.testFromSvTransmitWithObs(); + errorTotal += testClass.testFromReceive(); + errorTotal += testClass.testFromNominalReceive(); + errorTotal += testClass.testFromNominalReceiveWithObs(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/GNSSCore/Xvt_T.cpp b/core/tests/GNSSCore/Xvt_T.cpp index e8338a275..721e5eb68 100644 --- a/core/tests/GNSSCore/Xvt_T.cpp +++ b/core/tests/GNSSCore/Xvt_T.cpp @@ -135,23 +135,29 @@ class Xvt_T TURETURN(); } -#if 0 /* Ensures the preciseRho method is accurate */ unsigned preciseRhoTest() { - TUDEF("Xvt","preciseRho Method Unverified"); + TUDEF("Xvt","preciseRho"); std::string failMesg; -//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -// Unable to verify if operations done in Xvt.hpp are correct -// Creating placeholder for testing, and setting it to fail as a signifier - failMesg = "UNVERIFIED preciseRhoTest. Set to FAIL until verified"; - testFramework.assert(false, failMesg, __LINE__); + Triple rxPos(-7.0e5, -5.0e6, 3.0e6); + Xvt xvt; + xvt.x = Triple(-9e5, -2e7, 9e6); + xvt.v = Triple(6e2, 1e3, 2e4); + xvt.clkbias = -0.3; + xvt.clkdrift = 0; + xvt.relcorr = -3.5e-6; + + double rho; + GPSEllipsoid ellipsoid; + rho = xvt.preciseRho(rxPos, ellipsoid); + TUASSERTFESMRT(106095516.70592290163, rho); + rho = xvt.preciseRho(rxPos, ellipsoid, 10); + TUASSERTFESMRT(106095506.70592290163, rho); - return testFramework.countFails(); -//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + TURETURN(); } -#endif /* Tests to see if the stream output operator << is functioning properly*/ unsigned operatorTest() @@ -232,7 +238,7 @@ int main() //Main function to initialize and run all tests above Xvt_T testClass; errorTotal += testClass.getTest(); - //errorTotal += testClass.preciseRhoTest(); + errorTotal += testClass.preciseRhoTest(); errorTotal += testClass.computeRelativityCorrectionTest(); errorTotal += testClass.operatorTest(); errorTotal += testClass.healthStatusStreamTest(); diff --git a/core/tests/GNSSEph/EphemerisRange_T.cpp b/core/tests/GNSSEph/EphemerisRange_T.cpp index 75482a670..7730e3425 100644 --- a/core/tests/GNSSEph/EphemerisRange_T.cpp +++ b/core/tests/GNSSEph/EphemerisRange_T.cpp @@ -36,18 +36,130 @@ // //============================================================================== -#include "TestUtil.hpp" #include +#include "TestUtil.hpp" +#include "NavDataFactory.hpp" +#include "RinexNavDataFactory.hpp" +#include "NavLibrary.hpp" +#include "EphemerisRange.hpp" + class EphemerisRange_T { public: - EphemerisRange_T() {} // Default Constructor, set the precision value - ~EphemerisRange_T() {} // Default Desructor + EphemerisRange_T(); + unsigned testComputeAtReceiveTime(); + unsigned testComputeAtTransmitTime(); + unsigned testComputeAtTransmitTime2(); + unsigned testComputeAtTransmitSvTime(); + + gnsstk::NavLibrary navLib; }; -int main() //Main function to initialize and run all tests above +EphemerisRange_T :: +EphemerisRange_T() + : navLib() +{ + gnsstk::NavDataFactoryPtr + ndfp(std::make_shared()); + + std::string fname = gnsstk::getPathData() + gnsstk::getFileSep() + + "arlm2000.15n"; + + navLib.addFactory(ndfp); + + gnsstk::RinexNavDataFactory *rndfp = + dynamic_cast(ndfp.get()); + + GNSSTK_ASSERT(rndfp->addDataSource(fname)); +} + + +unsigned EphemerisRange_T :: +testComputeAtReceiveTime() +{ + TUDEF("CorrectedEphemerisRange", "ComputeAtReceiveTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + gnsstk::CorrectedEphemerisRange cer; + double corrected_range = cer.ComputeAtReceiveTime(time, rxPos, satId, navLib); + + TUASSERTFESMRT(22289257.145863413811, cer.rawrange); + TUASSERTFESMRT(22354137.99468812719, corrected_range); + TURETURN(); +} + + +unsigned EphemerisRange_T :: +testComputeAtTransmitTime() { - return 0; //Return the total number of errors + TUDEF("CorrectedEphemerisRange", "ComputeAtTransmitTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + gnsstk::CorrectedEphemerisRange cer; + double corrected_range = cer.ComputeAtTransmitTime(time, 2.7e7, rxPos, satId, navLib); + + TUASSERTFESMRT(22289249.959460116923, cer.rawrange); + TUASSERTFESMRT(22354130.808302134275, corrected_range); + TURETURN(); +} + + +unsigned EphemerisRange_T :: +testComputeAtTransmitTime2() +{ + TUDEF("CorrectedEphemerisRange", "ComputeAtTransmitTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + gnsstk::CorrectedEphemerisRange cer; + double corrected_range = cer.ComputeAtTransmitTime(time, rxPos, satId, navLib); + + TUASSERTFESMRT(22289257.145802032202, cer.rawrange); + TUASSERTFESMRT(22354137.994626745582, corrected_range); + TURETURN(); +} + + +unsigned EphemerisRange_T :: +testComputeAtTransmitSvTime() +{ + TUDEF("CorrectedEphemerisRange", "ComputeAtTransmitSvTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + gnsstk::CorrectedEphemerisRange cer; + double corrected_range = cer.ComputeAtTransmitSvTime(time, 2.7e7, rxPos, satId, navLib); + + TUASSERTFESMRT(22289288.75284050405, cer.rawrange); + TUASSERTFESMRT(22354169.60158220306, corrected_range); + TURETURN(); +} + + +int main() +{ + EphemerisRange_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.testComputeAtReceiveTime(); + errorTotal += testClass.testComputeAtTransmitTime(); + errorTotal += testClass.testComputeAtTransmitTime2(); + errorTotal += testClass.testComputeAtTransmitSvTime(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; } diff --git a/core/tests/Geomatics/CMakeLists.txt b/core/tests/Geomatics/CMakeLists.txt index 25005a2aa..3c6a7457c 100644 --- a/core/tests/Geomatics/CMakeLists.txt +++ b/core/tests/Geomatics/CMakeLists.txt @@ -106,3 +106,7 @@ add_test(NAME KalmanFilter COMMAND $) set_property(TEST KalmanFilter PROPERTY LABELS Geomatics) ################################################################################ +add_executable(PreciseRange_T PreciseRange_T.cpp) +target_link_libraries(PreciseRange_T gnsstk) +add_test(NAME PreciseRange COMMAND $) +set_property(TEST PreciseRange PROPERTY LABELS Geomatics) diff --git a/core/tests/Geomatics/PreciseRange_T.cpp b/core/tests/Geomatics/PreciseRange_T.cpp new file mode 100644 index 000000000..d62b05d90 --- /dev/null +++ b/core/tests/Geomatics/PreciseRange_T.cpp @@ -0,0 +1,165 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== + +#include + +#include "TestUtil.hpp" +#include "NavDataFactory.hpp" +#include "RinexNavDataFactory.hpp" +#include "NavLibrary.hpp" +#include "EphemerisRange.hpp" +#include "PreciseRange.hpp" +#include "SolarSystem.hpp" + +class PreciseRange_T +{ +public: + PreciseRange_T(); + unsigned testComputeAtTransmitTimeWithAntenna(); + unsigned testComputeAtTransmitTimeWithoutAntenna(); + + gnsstk::NavLibrary navLib; +}; + + +PreciseRange_T :: +PreciseRange_T() + : navLib() +{ + gnsstk::NavDataFactoryPtr + ndfp(std::make_shared()); + + std::string fname = gnsstk::getPathData() + gnsstk::getFileSep() + + "arlm2000.15n"; + + navLib.addFactory(ndfp); + + gnsstk::RinexNavDataFactory *rndfp = + dynamic_cast(ndfp.get()); + + GNSSTK_ASSERT(rndfp->addDataSource(fname)); +} + + +unsigned PreciseRange_T :: +testComputeAtTransmitTimeWithAntenna() +{ + TUDEF("PreciseRange_T", "ComputeAtTransmitTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + + gnsstk::AntexData::antennaPCOandPCVData l1data; + l1data.PCOvalue[0] = 1; + l1data.PCOvalue[1] = 2; + l1data.PCOvalue[2] = 3; + l1data.hasAzimuth = true; + gnsstk::AntexData::azimZenMap l1PcvData = { + { 0.0, {{0.0, 0.0}, {90.0, 16.0}}}, + {360.0, {{0.0, 0.0}, {90.0, 16.0}}} + }; + l1data.PCVvalue = l1PcvData; + + gnsstk::AntexData::antennaPCOandPCVData l2data; + l2data.PCOvalue[0] = 3; + l2data.PCOvalue[1] = 2; + l2data.PCOvalue[2] = 1; + l2data.hasAzimuth = true; + gnsstk::AntexData::azimZenMap l2PcvData = { + { 0.0, {{0.0, 0.0}, {90.0, 11.0}}}, + {360.0, {{0.0, 0.0}, {90.0, 11.0}}} + }; + l2data.PCVvalue = l2PcvData; + + gnsstk::AntexData antenna; + antenna.valid = gnsstk::AntexData::validBits::allValid13; + antenna.isRxAntenna = true; + + std::map antennaData; + antennaData["G01"] = l1data; + antennaData["G02"] = l2data; + antenna.freqPCVmap = antennaData; + + // Not bothering to setup a mock solar system object. + // PreciseRange should default to a lower accuracy computation + gnsstk::SolarSystem solsys; + + gnsstk::PreciseRange pr; + double corrected_range = + pr.ComputeAtTransmitTime(time, 2e7, rxPos, satId, antenna, + "G01", "G02", solsys, navLib, true); + + TUASSERTFESMRT(22289260.787348996848, pr.rawrange); + TUASSERTFESMRT(22354141.670028157532, corrected_range); + TURETURN(); +} + + +unsigned PreciseRange_T :: +testComputeAtTransmitTimeWithoutAntenna() +{ + TUDEF("PreciseRange_T", "ComputeAtTransmitTime"); + + gnsstk::Position rxPos(-7.0e5, -5.0e6, 3.0e6); + gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); + gnsstk::CommonTime + time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); + gnsstk::PreciseRange pr; + double corrected_range = pr.ComputeAtTransmitTime(time, 2e7, rxPos, satId, navLib); + + TUASSERTFESMRT(22289260.787348996848, pr.rawrange); + TUASSERTFESMRT(22354141.654476162046, corrected_range); + TURETURN(); +} + + +int main() +{ + PreciseRange_T testClass; + unsigned errorTotal = 0; + + errorTotal += testClass.testComputeAtTransmitTimeWithAntenna(); + errorTotal += testClass.testComputeAtTransmitTimeWithoutAntenna(); + + std::cout << "Total Failures for " << __FILE__ << ": " << errorTotal + << std::endl; + + return errorTotal; +} diff --git a/core/tests/ORD/OrdRegressionChecks_T.cpp b/core/tests/ORD/OrdRegressionChecks_T.cpp index f58058b0a..880dea983 100644 --- a/core/tests/ORD/OrdRegressionChecks_T.cpp +++ b/core/tests/ORD/OrdRegressionChecks_T.cpp @@ -162,7 +162,7 @@ testRawRange2() cer.ComputeAtTransmitTime(time, pseduorange, rxLocation, satId, navLib); // Compare the new calculation to the old, for our contrived variables. - TUASSERTFE(originalRange, resultRange); + TUASSERTFESMRT(originalRange, resultRange); TURETURN(); } @@ -189,7 +189,7 @@ testRawRange3() cer.ComputeAtTransmitSvTime(time, pseduorange, rxLocation, satId, navLib); // Compare the new calculation to the old, for our contrived variables. - TUASSERTFE(originalRange, resultRange); + TUASSERTFESMRT(originalRange, resultRange); TURETURN(); } @@ -213,7 +213,7 @@ testRawRange4() cer.ComputeAtTransmitTime(time, rxLocation, satId, navLib); // Compare the new calculation to the old, for our contrived variables. - TUASSERTFE(originalRange, resultRange); + TUASSERTFESMRT(originalRange, resultRange); TURETURN(); } diff --git a/core/tests/ORD/OrdUnitTests_T.cpp b/core/tests/ORD/OrdUnitTests_T.cpp index fe6c7403e..eb59c289f 100644 --- a/core/tests/ORD/OrdUnitTests_T.cpp +++ b/core/tests/ORD/OrdUnitTests_T.cpp @@ -161,15 +161,15 @@ testGetXvtFromStore() gnsstk::Xvt xvt = getSvXvt(satId, time+35, navLib); - TUASSERTFE(9345531.5274733770639, xvt.x[0]); - TUASSERTFE(-12408177.088141856715, xvt.x[1]); - TUASSERTFE(21486320.848036296666, xvt.x[2]); - TUASSERTFE(2081.276961058104007, xvt.v[0]); - TUASSERTFE(1792.4445008638492709, xvt.v[1]); - TUASSERTFE(148.29209115082824155, xvt.v[2]); - TUASSERTFE(-0.00021641018042870913346, xvt.clkbias); - TUASSERTFE(4.3200998334200003381e-12, xvt.clkdrift); - TUASSERTFE(-8.8197758101551758427e-09, xvt.relcorr); + TUASSERTFESMRT(9345531.5274733770639, xvt.x[0]); + TUASSERTFESMRT(-12408177.088141856715, xvt.x[1]); + TUASSERTFESMRT(21486320.848036296666, xvt.x[2]); + TUASSERTFESMRT(2081.276961058104007, xvt.v[0]); + TUASSERTFESMRT(1792.4445008638492709, xvt.v[1]); + TUASSERTFESMRT(148.29209115082824155, xvt.v[2]); + TUASSERTFESMRT(-0.00021641018042870913346, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8197758101551758427e-09, xvt.relcorr); TURETURN(); } @@ -178,27 +178,28 @@ testRawRange1() { TUDEF("ORD", "RawRange1"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double resultrange = RawRange1(rxLocation, satId, time, navLib, xvt); + double range = RawRange1(rxLocation, satId, time, navLib, xvt); // @note These fields are slightly different than the Xvt tagged // at the given time. RawRange tries to determine the position of the SV // at time of transmit but rotates the coordinates into the ECEF frame // at time of receive. - TUASSERTFE(9272491.2966336440295, xvt.x[0]); - TUASSERTFE(-12471194.724280735478, xvt.x[1]); - TUASSERTFE(21480834.569836761802, xvt.x[2]); - TUASSERTFE(2077.3534126001304685, xvt.v[0]); - TUASSERTFE(1796.0590315277861464, xvt.v[1]); - TUASSERTFE(164.41418674784648601, xvt.v[2]); - TUASSERTFE(-0.00021641042660146218705, xvt.clkbias); - TUASSERTFE(4.3200998334200003381e-12, xvt.clkdrift); - TUASSERTFE(-8.8008904512895476221e-09, xvt.relcorr); + TUASSERTFESMRT(9272533.3762740660459, xvt.x[0]); + TUASSERTFESMRT(-12471159.893898375332, xvt.x[1]); + TUASSERTFESMRT(21480836.886172864586, xvt.x[2]); + TUASSERTFESMRT(2077.3531590469665389, xvt.v[0]); + TUASSERTFESMRT(1796.0597201257969573, xvt.v[1]); + TUASSERTFESMRT(164.40771415613258455, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042654059759786, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8008986915573278037e-09, xvt.relcorr); + TUASSERTFESMRT(22289257.145863413811, range); TURETURN(); } @@ -207,7 +208,7 @@ testRawRange1HandlesException() { TUDEF("ORD", "RawRange1"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); // PRN 1 should not exist in the Nav file gnsstk::SatID satId(1, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime @@ -223,28 +224,29 @@ testRawRange2() { TUDEF("ORD", "RawRange2"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double pseduorange = 999999999; + double pseduorange = 2e7; double range = RawRange2(pseduorange, rxLocation, satId, time, navLib, xvt); // @note These fields are slightly different than the Xvt tagged // at the given time. RawRange tries to determine the position of the SV // at time of transmit but rotates the coordinates into the ECEF frame // at time of receive. - TUASSERTFE(9265746.753331027925, xvt.x[0]); - TUASSERTFE(-12477027.044897323474, xvt.x[1]); - TUASSERTFE(21480298.297345437109, xvt.x[2]); - TUASSERTFE(2076.9863342169719544, xvt.v[0]); - TUASSERTFE(1796.3919531321621434, xvt.v[1]); - TUASSERTFE(165.90589423444734507, xvt.v[2]); - TUASSERTFE(-0.00021641044062876963307, xvt.clkbias); - TUASSERTFE(4.3200998334200003381e-12, xvt.clkdrift); - TUASSERTFE(-8.7989903408158179378e-09, xvt.relcorr); + TUASSERTFESMRT(9272549.688764328137, xvt.x[0]); + TUASSERTFESMRT(-12471145.790274851024, xvt.x[1]); + TUASSERTFESMRT(21480838.177179995924, xvt.x[2]); + TUASSERTFESMRT(2077.3540461841112119, xvt.v[0]); + TUASSERTFESMRT(1796.058914385570688, xvt.v[1]); + TUASSERTFESMRT(164.40410655412986785, xvt.v[2]); + TUASSERTFESMRT(-0.000216410426506673752147, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8009032843852035206e-09, xvt.relcorr); + TUASSERTFESMRT(22289260.787328250706, range); TURETURN(); } @@ -253,12 +255,12 @@ testRawRange2HandlesException() { TUDEF("ORD", "RawRange2"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(1, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double pseduorange = 999999999; + double pseduorange = 2e7; TUTHROW(RawRange2(pseduorange, rxLocation, satId, time, navLib, xvt)); TURETURN(); @@ -269,28 +271,29 @@ testRawRange3() { TUDEF("ORD", "RawRange3"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double pseduorange = 999999999; + double pseduorange = 2e7; double range = RawRange3(pseduorange, rxLocation, satId, time, navLib, xvt); // @note These fields are slightly different than the Xvt tagged // at the given time. RawRange tries to determine the position of the SV // at time of transmit but rotates the coordinates into the ECEF frame // at time of receive. - TUASSERTFE(9269721.8167515993118, xvt.x[0]); - TUASSERTFE(-12473230.988021081313, xvt.x[1]); - TUASSERTFE(21480849.108445473015, xvt.x[2]); - TUASSERTFE(2077.3518208497298474, xvt.v[0]); - TUASSERTFE(1796.0633538716695057, xvt.v[1]); - TUASSERTFE(164.37355694668559636, xvt.v[2]); - TUASSERTFE(-0.00021641042621940267715, xvt.clkbias); - TUASSERTFE(4.3200998334200003381e-12, xvt.clkdrift); - TUASSERTFE(-8.8009421765298224418e-09, xvt.relcorr); + TUASSERTFESMRT(9272694.5732459314167, xvt.x[0]); + TUASSERTFESMRT(-12471021.342128152028, xvt.x[1]); + TUASSERTFESMRT(21480849.108445473015, xvt.x[2]); + TUASSERTFESMRT(2077.3605866395218982, xvt.v[0]); + TUASSERTFESMRT(1796.0532152374469206, xvt.v[1]); + TUASSERTFESMRT(164.37355694668559636, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042621940267715, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8009421765298224418e-09, xvt.relcorr); + TUASSERTFESMRT(22289292.96130572632, range); TURETURN(); } @@ -305,7 +308,7 @@ testRawRange3HandlesException() time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double pseduorange = 999999999; + double pseduorange = 2e7; TUTHROW(RawRange3(pseduorange, rxLocation, satId, time, navLib, xvt)); TURETURN(); @@ -316,27 +319,28 @@ testRawRange4() { TUDEF("ORD", "RawRange4"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(5, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); gnsstk::Xvt xvt; - double resultrange = RawRange4(rxLocation, satId, time, navLib, xvt); + double range = RawRange4(rxLocation, satId, time, navLib, xvt); // @note These fields are slightly different than the Xvt tagged // at the given time. RawRange tries to determine the position of the SV // at time of transmit but rotates the coordinates into the ECEF frame // at time of receive. - TUASSERTFE(9272491.2966245152056, xvt.x[0]); - TUASSERTFE(-12471194.72428862378, xvt.x[1]); - TUASSERTFE(21480834.569836035371, xvt.x[2]); - TUASSERTFE(2077.3534125996338844, xvt.v[0]); - TUASSERTFE(1796.0590315282379379, xvt.v[1]); - TUASSERTFE(164.41418674986550741, xvt.v[2]); - TUASSERTFE(-0.00021641042660146218705, xvt.clkbias); - TUASSERTFE(4.3200998334200003381e-12, xvt.clkdrift); - TUASSERTFE(-8.8008904512869767448e-09, xvt.relcorr); + TUASSERTFESMRT(9272533.3759945072234, xvt.x[0]); + TUASSERTFESMRT(-12471159.894135156646, xvt.x[1]); + TUASSERTFESMRT(21480836.886153958738, xvt.x[2]); + TUASSERTFESMRT(2077.353159039827915, xvt.v[0]); + TUASSERTFESMRT(1796.0597201308269177, xvt.v[1]); + TUASSERTFESMRT(164.40771420896862764, xvt.v[2]); + TUASSERTFESMRT(-0.00021641042654059808575, xvt.clkbias); + TUASSERTFESMRT(4.3200998334200003381e-12, xvt.clkdrift); + TUASSERTFESMRT(-8.8008986914900614763e-09, xvt.relcorr); + TUASSERTFESMRT(22289257.145802032202, range); TURETURN(); } @@ -345,7 +349,7 @@ testRawRange4HandlesException() { TUDEF("ORD", "RawRange4"); - gnsstk::Position rxLocation(10, 10, 0); + gnsstk::Position rxLocation(-7.0e5, -5.0e6, 3.0e6); gnsstk::SatID satId(1, gnsstk::SatelliteSystem::GPS); gnsstk::CommonTime time(gnsstk::CivilTime(2015,7,19,2,0,0.0,gnsstk::TimeSystem::GPS)); diff --git a/swig/GNSSEph/GNSSEph.i b/swig/GNSSEph/GNSSEph.i index 34a142109..561ed1c62 100644 --- a/swig/GNSSEph/GNSSEph.i +++ b/swig/GNSSEph/GNSSEph.i @@ -27,6 +27,7 @@ from __future__ import absolute_import %include "std_list.i" %include "std_set.i" %include "std_multimap.i" +%include "std_tuple.i" %include "stdint.i" %include "typemaps.i" %include "exception.i" @@ -68,12 +69,15 @@ from __future__ import absolute_import %import "SatelliteSystem.hpp" %import(module="gnsstk.GNSSCore") "SatID.hpp" %import "Triple.hpp" +%import "EllipsoidModel.hpp" %import(module="gnsstk.GNSSCore") "Xvt.hpp" %import "ObsID.hpp" %import "SVHealth.hpp" %import "Position.hpp" %import "NavValidityType.hpp" %import "NavSearchOrder.hpp" +%import "NavSignalID.hpp" +%import "NavSatelliteID.hpp" %import "NavLibrary.hpp" %import "ValidType.hpp" @@ -88,6 +92,11 @@ from __future__ import absolute_import %include "PackedNavBits.hpp" %include "EngAlmanac.hpp" %include "EngEphemeris.hpp" +%std_tuple(ComputeRangeResultXvt, double, gnsstk::Xvt); +%std_tuple(ComputeRangeResultPosition, double, gnsstk::Position); +%std_tuple(EstTimeResult, bool, gnsstk::CommonTime); +%std_tuple(RawRangeResult, bool, double, gnsstk::Xvt); +%include "RawRange.hpp" %include "EphemerisRange.hpp" %include "SP3SatID.hpp" diff --git a/swig/SWIGHelpers/std_tuple.i b/swig/SWIGHelpers/std_tuple.i new file mode 100644 index 000000000..e7f590748 --- /dev/null +++ b/swig/SWIGHelpers/std_tuple.i @@ -0,0 +1,52 @@ +// Modified from stackoverflow: https://stackoverflow.com/questions/72816953/support-for-stdtuple-in-swig +// The main use case for this wrapper is to allow tuple unpacking of C++ functions +// that return std::tuple. +%{ +#include +#include +%} + +#define make_getter(pos, type) const type& get##pos() const { return std::get(*$self); } +#define make_setter(pos, type) void set##pos(const type& val) { std::get(*$self) = val; } +#define make_ctorargN(pos, type) , type v##pos +#define make_ctorarg(first, ...) const first& v0 FOR_EACH(make_ctorargN, __VA_ARGS__) + +#define FE_0(...) +#define FE_1(action,a1) action(0,a1) +#define FE_2(action,a1,a2) action(0,a1) action(1,a2) +#define FE_3(action,a1,a2,a3) action(0,a1) action(1,a2) action(2,a3) +#define FE_4(action,a1,a2,a3,a4) action(0,a1) action(1,a2) action(2,a3) action(3,a4) +#define FE_5(action,a1,a2,a3,a4,a5) action(0,a1) action(1,a2) action(2,a3) action(3,a4) action(4,a5) + +#define GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME +%define FOR_EACH(action,...) + GET_MACRO(__VA_ARGS__, FE_5, FE_4, FE_3, FE_2, FE_1, FE_0)(action,__VA_ARGS__) +%enddef + +%define %std_tuple(Name, ...) +%rename(Name) std::tuple<__VA_ARGS__>; +namespace std { + struct tuple<__VA_ARGS__> { + tuple(make_ctorarg(__VA_ARGS__)); + %extend { + FOR_EACH(make_getter, __VA_ARGS__) + FOR_EACH(make_setter, __VA_ARGS__) + size_t __len__() const { return std::tuple_size::type>{}; } + %pythoncode %{ + def __getitem__(self, n): + if n < 0: + n = len(self) + n + if n < 0 or n >= len(self): + raise IndexError() + return getattr(self, 'get%d' % n)() + def __setitem__(self, n, val): + if n < 0: + n = len(self) + n + if n < 0 or n >= len(self): + raise IndexError() + getattr(self, 'set%d' % n)(val) + %} + } + }; +} +%enddef diff --git a/swig/gnsstk_swig.hpp b/swig/gnsstk_swig.hpp index f9e5da7ef..0d53ec5ba 100644 --- a/swig/gnsstk_swig.hpp +++ b/swig/gnsstk_swig.hpp @@ -185,6 +185,7 @@ #include "NavDataFactory.hpp" #include "NavLibrary.hpp" #include "ValidType.hpp" +#include "RawRange.hpp" #include "EphemerisRange.hpp" #include "IonoModel.hpp" #include "IonoModelStore.hpp" diff --git a/swig/gnsstk_swig.i b/swig/gnsstk_swig.i index 718c80542..afdebdbd8 100644 --- a/swig/gnsstk_swig.i +++ b/swig/gnsstk_swig.i @@ -240,6 +240,7 @@ %import(module="gnsstk") "NavLibrary.hpp" %template(NavMessageTypeSet) std::set; %import(module="gnsstk") "ValidType.hpp" +%import(module="gnsstk") "RawRange.hpp" %import(module="gnsstk") "EphemerisRange.hpp" %feature("flatnested"); %import(module="gnsstk") "IonoModel.hpp" diff --git a/swig/tests/test_GNSSEph.py b/swig/tests/test_GNSSEph.py index 8984eff29..2be359748 100644 --- a/swig/tests/test_GNSSEph.py +++ b/swig/tests/test_GNSSEph.py @@ -6,7 +6,7 @@ import gnsstk -class TestGNSSCore(unittest.TestCase): +class TestGNSSEph(unittest.TestCase): def test_NMCTMeta(self): a = gnsstk.NMCTMeta() @@ -73,6 +73,32 @@ def test_IonoModelStore(self): a.edit(gnsstk.CommonTime.END_OF_TIME) self.assertIsInstance(a, gnsstk.IonoModelStore) + def test_RawRange(self): + """ + Test swig interface to RawRange class + + Correctness test already exists in C++ at RawRange_T.cpp. + This test ensures that the class is accessible and usable in python + """ + rxPos = gnsstk.Position(1000, 2000, 3000) + svPos = gnsstk.Position(30000, 20000, 10000) + tof = 0.07 + ellipsoid = gnsstk.GPSEllipsoid() + + rawrange, svPos = gnsstk.RawRange.computeRange(rxPos, svPos, tof, ellipsoid) + self.assertIsInstance(rawrange, float) + self.assertGreater(rawrange, 0) + self.assertIsInstance(svPos, gnsstk.Position) + + svXvt = gnsstk.Xvt() + svXvt.x = gnsstk.Position(30000, 20000, 100000) + success, rawrange, svXvt = gnsstk.RawRange.fromSvPos(rxPos, svXvt, ellipsoid) + self.assertTrue(success) + self.assertGreater(rawrange, 0) + self.assertIsInstance(svXvt, gnsstk.Xvt) + + + if __name__ == '__main__': From 4e9af98ef3086e566b7b2c95fc31cec39b76ae0e Mon Sep 17 00:00:00 2001 From: John Knutson Date: Wed, 14 Dec 2022 15:44:34 -0600 Subject: [PATCH 14/16] Move NewNav enums to the namespace level for consistency --- core/lib/NewNav/GLOFNavData.cpp | 37 +-------- core/lib/NewNav/GLOFNavData.hpp | 34 +------- core/lib/NewNav/GLOFNavEph.cpp | 2 +- core/lib/NewNav/GLOFNavEph.hpp | 2 +- core/lib/NewNav/GLOFNavPCode.cpp | 64 +++++++++++++++ core/lib/NewNav/GLOFNavPCode.hpp | 80 +++++++++++++++++++ core/lib/NewNav/GLOFNavSatType.cpp | 60 ++++++++++++++ core/lib/NewNav/GLOFNavSatType.hpp | 73 +++++++++++++++++ core/lib/NewNav/GPSLNavEph.cpp | 18 +---- core/lib/NewNav/GPSLNavEph.hpp | 19 +---- core/lib/NewNav/GPSLNavL2Codes.cpp | 60 ++++++++++++++ core/lib/NewNav/GPSLNavL2Codes.hpp | 73 +++++++++++++++++ core/lib/NewNav/PNBGLOFNavDataFactory.cpp | 12 +-- core/lib/NewNav/PNBGPSLNavDataFactory.cpp | 2 +- core/lib/NewNav/RinexNavDataFactory.cpp | 2 +- core/tests/NewNav/GLOFNavData_T.cpp | 4 +- core/tests/NewNav/GLOFNavEph_T.cpp | 4 +- core/tests/NewNav/GPSLNavEph_T.cpp | 4 +- core/tests/NewNav/PNBGLOFNavDataFactory_T.cpp | 16 ++-- core/tests/NewNav/PNBGPSLNavDataFactory_T.cpp | 10 +-- core/tests/NewNav/RinexNavDataFactory_T.cpp | 22 ++--- swig/NewNav/NewNav.i | 6 ++ swig/gnsstk_swig.hpp | 3 + swig/gnsstk_swig.i | 3 + 24 files changed, 466 insertions(+), 144 deletions(-) create mode 100644 core/lib/NewNav/GLOFNavPCode.cpp create mode 100644 core/lib/NewNav/GLOFNavPCode.hpp create mode 100644 core/lib/NewNav/GLOFNavSatType.cpp create mode 100644 core/lib/NewNav/GLOFNavSatType.hpp create mode 100644 core/lib/NewNav/GPSLNavL2Codes.cpp create mode 100644 core/lib/NewNav/GPSLNavL2Codes.hpp diff --git a/core/lib/NewNav/GLOFNavData.cpp b/core/lib/NewNav/GLOFNavData.cpp index 7b000be9a..d21eb31ca 100644 --- a/core/lib/NewNav/GLOFNavData.cpp +++ b/core/lib/NewNav/GLOFNavData.cpp @@ -45,7 +45,7 @@ namespace gnsstk GLOFNavData :: GLOFNavData() : health(SVHealth::Unknown), - satType(SatType::Unknown), + satType(GLOFNavSatType::Unknown), slot(-1), lhealth(false) { @@ -59,39 +59,4 @@ namespace gnsstk /// @todo implement some checking. return true; } - - - namespace StringUtils - { - std::string asString(GLOFNavData::PCode e) - { - switch (e) - { - case GLOFNavData::PCode::CRelGPSRel: - return "tau_c from CS, tau_GPS from CS"; - case GLOFNavData::PCode::CRelGPSCalc: - return "tau_c from CS, tau_GPS calc SV"; - case GLOFNavData::PCode::CCalcGPSRel: - return "tau_c calc SV, tau_GPS from CS"; - case GLOFNavData::PCode::CCalcGPSCalc: - return "tau_c calc SV, tau_GPS calc SV"; - default: - return "???????"; - } - } - - - std::string asString(GLOFNavData::SatType e) - { - switch (e) - { - case GLOFNavData::SatType::GLONASS: - return "GLONASS SV"; - case GLOFNavData::SatType::GLONASS_M: - return "GLONASS-M SV"; - default: - return "??????"; - } - } - } } diff --git a/core/lib/NewNav/GLOFNavData.hpp b/core/lib/NewNav/GLOFNavData.hpp index c1081d02a..2963da1fa 100644 --- a/core/lib/NewNav/GLOFNavData.hpp +++ b/core/lib/NewNav/GLOFNavData.hpp @@ -42,6 +42,8 @@ #include "OrbitData.hpp" #include "NavFit.hpp" #include "SVHealth.hpp" +#include "GLOFNavPCode.hpp" +#include "GLOFNavSatType.hpp" namespace gnsstk { @@ -53,28 +55,6 @@ namespace gnsstk class GLOFNavData : public OrbitData, public NavFit { public: - /** Values for Word P. The values indicate whether the tau_c - * parameter and tau_GPS parameter are relayed from the control - * segment or calculated on-board the GLONASS-M satellite. - * @note This seems to imply P has no meaning on legacy - * GLONASS, only in GLONASS-M. */ - enum class PCode - { - Unknown =-1, ///< Unknown/Uninitialized value. - CRelGPSRel = 0, ///< C parameter relayed, GPS parameter relayed - CRelGPSCalc = 1, ///< C parameter relayed, GPS parameter calculated - CCalcGPSRel = 2, ///< C parameter calculated, GPS parameter relayed - CCalcGPSCalc = 3, ///< C parameter calculated, GPS parameter calculated - }; - - /// Values for Word M. - enum class SatType - { - Unknown = -1, ///< Unknown/Uninitialized value. - GLONASS = 0, ///< Legacy GLONASS satellite. - GLONASS_M = 1, ///< GLONASS-M satellite. - }; - /// Sets the nav message type and all other data members to 0. GLOFNavData(); @@ -85,7 +65,7 @@ namespace gnsstk bool validate() const override; CommonTime xmit2; ///< Transmit time for string 2 (eph) or odd string. - SatType satType; ///< Satellite type (M_n: GLONASS or GLONASS-M). + GLOFNavSatType satType; ///< Satellite type (M_n: GLONASS or GLONASS-M). unsigned slot; ///< Slot number (n). bool lhealth; ///< Health flag? Different from B_n and C_n? SVHealth health; ///< SV health status. @@ -93,14 +73,6 @@ namespace gnsstk //@} - namespace StringUtils - { - /// Convert PCode to a printable string for dump(). - std::string asString(GLOFNavData::PCode e); - /// Convert SatType to a printable string for dump(). - std::string asString(GLOFNavData::SatType e); - } - } #endif // GNSSTK_GLOFNAVDATA_HPP diff --git a/core/lib/NewNav/GLOFNavEph.cpp b/core/lib/NewNav/GLOFNavEph.cpp index 4d00f15c2..f2e002f86 100644 --- a/core/lib/NewNav/GLOFNavEph.cpp +++ b/core/lib/NewNav/GLOFNavEph.cpp @@ -54,7 +54,7 @@ namespace gnsstk tb(-1), P1(-1), P2(-1), P3(-1), P4(-1), interval(-1), - opStatus(PCode::Unknown), + opStatus(GLOFNavPCode::Unknown), tauDelta(std::numeric_limits::quiet_NaN()), aod(-1), accIndex(-1), diff --git a/core/lib/NewNav/GLOFNavEph.hpp b/core/lib/NewNav/GLOFNavEph.hpp index 52af9f016..049b448b7 100644 --- a/core/lib/NewNav/GLOFNavEph.hpp +++ b/core/lib/NewNav/GLOFNavEph.hpp @@ -124,7 +124,7 @@ namespace gnsstk unsigned P3; ///< Flag 1=5 almanac sats in frame, 0=4 almanac sats. unsigned P4; ///< Flag 1=ephemeris present/uploaded. 0=nope. unsigned interval; ///< P1 interval (minutes, see PNBGLOFNavDataFactory). - PCode opStatus; ///< Operational status flag. + GLOFNavPCode opStatus; ///< Operational status flag. double tauDelta; ///< Inter-frequency bias. unsigned aod; ///< Age of data in days (E_n). unsigned accIndex; ///< User accuracy index (F_T). diff --git a/core/lib/NewNav/GLOFNavPCode.cpp b/core/lib/NewNav/GLOFNavPCode.cpp new file mode 100644 index 000000000..1d57cf633 --- /dev/null +++ b/core/lib/NewNav/GLOFNavPCode.cpp @@ -0,0 +1,64 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "GLOFNavPCode.hpp" + +using namespace std; + +namespace gnsstk +{ + namespace StringUtils + { + std::string asString(GLOFNavPCode e) + { + switch (e) + { + case GLOFNavPCode::CRelGPSRel: + return "tau_c from CS, tau_GPS from CS"; + case GLOFNavPCode::CRelGPSCalc: + return "tau_c from CS, tau_GPS calc SV"; + case GLOFNavPCode::CCalcGPSRel: + return "tau_c calc SV, tau_GPS from CS"; + case GLOFNavPCode::CCalcGPSCalc: + return "tau_c calc SV, tau_GPS calc SV"; + default: + return "???????"; + } + } + } +} diff --git a/core/lib/NewNav/GLOFNavPCode.hpp b/core/lib/NewNav/GLOFNavPCode.hpp new file mode 100644 index 000000000..b4c0d693f --- /dev/null +++ b/core/lib/NewNav/GLOFNavPCode.hpp @@ -0,0 +1,80 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_GLOFNAVPCODE_HPP +#define GNSSTK_GLOFNAVPCODE_HPP + +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup NavFactory + //@{ + + /** Values for GLONASS FDMA nav message, Word P. The values + * indicate whether the tau_c parameter and tau_GPS parameter + * are relayed from the control segment or calculated + * on-board the GLONASS-M satellite. + * @note This seems to imply P has no meaning on legacy + * GLONASS, only in GLONASS-M. */ + enum class GLOFNavPCode + { + Unknown =-1, ///< Unknown/Uninitialized value. + CRelGPSRel = 0, ///< C parameter relayed, GPS parameter relayed + CRelGPSCalc = 1, ///< C parameter relayed, GPS parameter calculated + CCalcGPSRel = 2, ///< C parameter calculated, GPS parameter relayed + CCalcGPSCalc = 3, ///< C parameter calculated, GPS parameter calculated + Last, ///< Used to verify that all items are described at compile time + }; + + /** Define an iterator so C++11 can do things like + * for (GLOFNavPCode i : GLOFNavPCodeIterator()) */ + typedef EnumIterator GLOFNavPCodeIterator; + + namespace StringUtils + { + /// Convert GLOFNavPCode to a printable string for dump(). + std::string asString(GLOFNavPCode e); + } + + //@} + +} // namespace gnsstk + +#endif // GNSSTK_GLOFNAVPCODE_HPP diff --git a/core/lib/NewNav/GLOFNavSatType.cpp b/core/lib/NewNav/GLOFNavSatType.cpp new file mode 100644 index 000000000..eb255e6a5 --- /dev/null +++ b/core/lib/NewNav/GLOFNavSatType.cpp @@ -0,0 +1,60 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "GLOFNavSatType.hpp" + +using namespace std; + +namespace gnsstk +{ + namespace StringUtils + { + std::string asString(GLOFNavSatType e) + { + switch (e) + { + case GLOFNavSatType::GLONASS: + return "GLONASS SV"; + case GLOFNavSatType::GLONASS_M: + return "GLONASS-M SV"; + default: + return "??????"; + } + } // asString(GLOFNavData::SatType e) + } // namespace StringUtils +} // namespace gnsstk diff --git a/core/lib/NewNav/GLOFNavSatType.hpp b/core/lib/NewNav/GLOFNavSatType.hpp new file mode 100644 index 000000000..0f19437af --- /dev/null +++ b/core/lib/NewNav/GLOFNavSatType.hpp @@ -0,0 +1,73 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_GLOFNAVSATTYPE_HPP +#define GNSSTK_GLOFNAVSATTYPE_HPP + +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup NavFactory + //@{ + + /// Values for GLONASS FDMA nav message, Word M. + enum class GLOFNavSatType + { + Unknown = -1, ///< Unknown/Uninitialized value. + GLONASS = 0, ///< Legacy GLONASS satellite. + GLONASS_M = 1, ///< GLONASS-M satellite. + Last, ///< Used to verify that all items are described at compile time + }; + + /** Define an iterator so C++11 can do things like + * for (GLOFNavSatType i : GLOFNavSatTypeIterator()) */ + typedef EnumIterator GLOFNavSatTypeIterator; + + namespace StringUtils + { + /// Convert SatType to a printable string for dump(). + std::string asString(GLOFNavSatType e); + } + + //@} + +} + +#endif // GNSSTK_GLOFNAVSATTYPE_HPP diff --git a/core/lib/NewNav/GPSLNavEph.cpp b/core/lib/NewNav/GPSLNavEph.cpp index 73b878d05..286c3da96 100644 --- a/core/lib/NewNav/GPSLNavEph.cpp +++ b/core/lib/NewNav/GPSLNavEph.cpp @@ -63,7 +63,7 @@ namespace gnsstk asFlag3(false), alert2(false), alert3(false), - codesL2(L2Codes::Invalid1), + codesL2(GPSLNavL2Codes::Invalid1), aodo(-1), L2Pdata(false) { @@ -237,22 +237,6 @@ namespace gnsstk } - namespace StringUtils - { - std::string asString(GPSLNavEph::L2Codes e) - { - switch (e) - { - case GPSLNavEph::L2Codes::Invalid1: return "Invalid1"; - case GPSLNavEph::L2Codes::Pcode: return "P only"; - case GPSLNavEph::L2Codes::CAcode: return "C/A only"; - case GPSLNavEph::L2Codes::Invalid2: return "Invalid2"; - default: return "Unknown"; - } - } - } - - bool GPSLNavEphIODCComp :: operator()(const std::shared_ptr lhs, const std::shared_ptr rhs) const diff --git a/core/lib/NewNav/GPSLNavEph.hpp b/core/lib/NewNav/GPSLNavEph.hpp index e257f9efd..791fba3ec 100644 --- a/core/lib/NewNav/GPSLNavEph.hpp +++ b/core/lib/NewNav/GPSLNavEph.hpp @@ -40,6 +40,7 @@ #define GNSSTK_GPSLNAVEPH_HPP #include "GPSLNavData.hpp" +#include "GPSLNavL2Codes.hpp" namespace gnsstk { @@ -50,15 +51,6 @@ namespace gnsstk class GPSLNavEph : public GPSLNavData { public: - /// Codes on L2 channel, per IS-GPS-200 20.3.3.3.1.2 - enum class L2Codes - { - Invalid1 = 0, - Pcode = 1, - CAcode = 2, - Invalid2 = 3 - }; - /// Sets the nav message type and all other data members to 0. GPSLNavEph(); /// Create a deep copy of this object. @@ -113,7 +105,7 @@ namespace gnsstk bool alert3; ///< Alert flag from SF3 HOW bool asFlag2; ///< Anti-spoof flag from SF2 HOW. bool asFlag3; ///< Anti-spoof flag from SF3 HOW. - L2Codes codesL2; ///< Code on L2 in-phase component. + GPSLNavL2Codes codesL2; ///< Code on L2 in-phase component. /** L2 P data flag from subframe 1, word 3. * @note This retains the behavior as described in * IS-GPS-200K 20.3.3.3.1.6, in that true (1) indicates the @@ -123,13 +115,6 @@ namespace gnsstk long aodo; ///< Age of Data Offset in seconds (-1=uninitialized). }; - - namespace StringUtils - { - /// Convert L2Codes to a printable string for dump(). - std::string asString(GPSLNavEph::L2Codes e); - } - /** Class that sorts GPSLNavEph using the combination of * NavSatelliteID, GPS week and IODC. Intended to be used as a * comparator for standard C++ library containers. */ diff --git a/core/lib/NewNav/GPSLNavL2Codes.cpp b/core/lib/NewNav/GPSLNavL2Codes.cpp new file mode 100644 index 000000000..4b45ee470 --- /dev/null +++ b/core/lib/NewNav/GPSLNavL2Codes.cpp @@ -0,0 +1,60 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#include "GPSLNavL2Codes.hpp" + +using namespace std; + +namespace gnsstk +{ + namespace StringUtils + { + std::string asString(GPSLNavL2Codes e) + { + switch (e) + { + case GPSLNavL2Codes::Invalid1: return "Invalid1"; + case GPSLNavL2Codes::Pcode: return "P only"; + case GPSLNavL2Codes::CAcode: return "C/A only"; + case GPSLNavL2Codes::Invalid2: return "Invalid2"; + default: return "Unknown"; + } + } // asString(GPSLNavL2Codes e) + } // namespace StringUtils +} // namespace gnsstk + diff --git a/core/lib/NewNav/GPSLNavL2Codes.hpp b/core/lib/NewNav/GPSLNavL2Codes.hpp new file mode 100644 index 000000000..a84678854 --- /dev/null +++ b/core/lib/NewNav/GPSLNavL2Codes.hpp @@ -0,0 +1,73 @@ +//============================================================================== +// +// This file is part of GNSSTk, the ARL:UT GNSS Toolkit. +// +// The GNSSTk is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 3.0 of the License, or +// any later version. +// +// The GNSSTk is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with GNSSTk; if not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin. +// Copyright 2004-2022, The Board of Regents of The University of Texas System +// +//============================================================================== + + +//============================================================================== +// +// This software was developed by Applied Research Laboratories at the +// University of Texas at Austin, under contract to an agency or agencies +// within the U.S. Department of Defense. The U.S. Government retains all +// rights to use, duplicate, distribute, disclose, or release this software. +// +// Pursuant to DoD Directive 523024 +// +// DISTRIBUTION STATEMENT A: This software has been approved for public +// release, distribution is unlimited. +// +//============================================================================== +#ifndef GNSSTK_GPSLNAVL2CODES_HPP +#define GNSSTK_GPSLNAVL2CODES_HPP + +#include +#include "EnumIterator.hpp" + +namespace gnsstk +{ + /// @ingroup NavFactory + //@{ + + /// Codes on L2 channel, per IS-GPS-200 20.3.3.3.1.2 + enum class GPSLNavL2Codes + { + Unknown =-1, ///< Unknown/Uninitialized value. + Invalid1 = 0, ///< Not a valid broadcast value. + Pcode = 1, ///< P/Y-code is broadcast on L2. + CAcode = 2, ///< C/A-code is broadcast on L2. + Invalid2 = 3, ///< Not a valid broadcast value. + Last, ///< Used to verify that all items are described at compile time + }; + + /** Define an iterator so C++11 can do things like + * for (GPSLNavL2Codes i : GPSLNavL2CodesIterator()) */ + typedef EnumIterator GPSLNavL2CodesIterator; + + namespace StringUtils + { + /// Convert GPSLNavL2Codes to a printable string for dump(). + std::string asString(GPSLNavL2Codes e); + } + +} // namespace gnsstk + +#endif // GNSSTK_GPSLNAVL2CODES_HPP diff --git a/core/lib/NewNav/PNBGLOFNavDataFactory.cpp b/core/lib/NewNav/PNBGLOFNavDataFactory.cpp index 54e4bb6a9..d7a698d0a 100644 --- a/core/lib/NewNav/PNBGLOFNavDataFactory.cpp +++ b/core/lib/NewNav/PNBGLOFNavDataFactory.cpp @@ -275,7 +275,7 @@ namespace gnsstk eph->interval = 0; break; } - eph->opStatus = static_cast( + eph->opStatus = static_cast( ephS[esiP]->asUnsignedLong(esbP,enbP,escP)); eph->tauDelta = ephS[esidtaun]->asSignMagDouble( esbdtaun,enbdtaun,escdtaun); @@ -283,7 +283,7 @@ namespace gnsstk eph->accIndex = ephS[esiFT]->asUnsignedLong(esbFT,enbFT,escFT); eph->dayCount = ephS[esiNT]->asUnsignedLong(esbNT,enbNT,escNT); eph->slot = ephS[esin]->asUnsignedLong(esbn,enbn,escn); - eph->satType = static_cast( + eph->satType = static_cast( ephS[esiM]->asUnsignedLong(esbM,enbM,escM)); YDSTime toe(eph->timeStamp); // This is a kludge to have what was deemed to be a @@ -447,15 +447,9 @@ namespace gnsstk alm->health = (alm->healthBits == 1 ? SVHealth::Healthy : SVHealth::Unhealthy); - alm->satType = static_cast( + alm->satType = static_cast( almS[almIdx+asoM]->asUnsignedLong(asbM,anbM,ascM)); alm->taunA = almS[almIdx+asotau]->asSignMagDouble(asbtau,anbtau,asctau); - // cerr << "almIdx+asolambda=" << (almIdx+asolambda) << endl; - unsigned long fudge1 = almS[almIdx]->asUnsignedLong( - fsbStrNum,fnbStrNum,fscStrNum); - unsigned long fudge2 = almS[almIdx+1]->asUnsignedLong( - fsbStrNum,fnbStrNum,fscStrNum); - // cerr << "fudge1=" << fudge1 << " fudge2=" << fudge2 << endl; alm->lambdanA = almS[almIdx+asolambda]->asSignMagDoubleSemiCircles( asblambda,anblambda,asclambda); alm->deltainA = almS[almIdx+asodeltai]->asSignMagDoubleSemiCircles( diff --git a/core/lib/NewNav/PNBGPSLNavDataFactory.cpp b/core/lib/NewNav/PNBGPSLNavDataFactory.cpp index 4611e3cc7..7eadd8b95 100644 --- a/core/lib/NewNav/PNBGPSLNavDataFactory.cpp +++ b/core/lib/NewNav/PNBGPSLNavDataFactory.cpp @@ -354,7 +354,7 @@ namespace gnsstk eph->alert3 = ephSF[sf3]->asBool(fsbAlert); eph->asFlag2 = ephSF[sf2]->asBool(fsbAS); eph->asFlag3 = ephSF[sf3]->asBool(fsbAS); - eph->codesL2 = static_cast( + eph->codesL2 = static_cast( ephSF[esiL2]->asUnsignedLong(esbL2,enbL2,escL2)); eph->L2Pdata = ephSF[esiL2P]->asUnsignedLong(esbL2P,enbL2P,escL2P); eph->aodo = ephSF[esiAODO]->asUnsignedLong(esbAODO,enbAODO,escAODO); diff --git a/core/lib/NewNav/RinexNavDataFactory.cpp b/core/lib/NewNav/RinexNavDataFactory.cpp index 4178db6bb..cc586c673 100644 --- a/core/lib/NewNav/RinexNavDataFactory.cpp +++ b/core/lib/NewNav/RinexNavDataFactory.cpp @@ -367,7 +367,7 @@ namespace gnsstk gps->asFlag = gps->asFlag2 = gps->asFlag3 = false; } gps->alert = gps->alert2 = gps->alert3 = false; - gps->codesL2 = (GPSLNavEph::L2Codes)navIn.codeflgs; + gps->codesL2 = (GPSLNavL2Codes)navIn.codeflgs; gps->L2Pdata = (navIn.L2Pdata > 0); gps->fixFit(); break; diff --git a/core/tests/NewNav/GLOFNavData_T.cpp b/core/tests/NewNav/GLOFNavData_T.cpp index 93aa9d0b2..9987f9943 100644 --- a/core/tests/NewNav/GLOFNavData_T.cpp +++ b/core/tests/NewNav/GLOFNavData_T.cpp @@ -41,7 +41,7 @@ namespace gnsstk { - std::ostream& operator<<(std::ostream& s, GLOFNavData::SatType e) + std::ostream& operator<<(std::ostream& s, GLOFNavSatType e) { s << StringUtils::asString(e); return s; @@ -83,7 +83,7 @@ constructorTest() TestClass uut; gnsstk::CommonTime exp; TUASSERTE(gnsstk::CommonTime, exp, uut.xmit2); - TUASSERTE(gnsstk::GLOFNavData::SatType,gnsstk::GLOFNavData::SatType::Unknown, + TUASSERTE(gnsstk::GLOFNavSatType, gnsstk::GLOFNavSatType::Unknown, uut.satType); TUASSERTE(unsigned, -1, uut.slot); TUASSERTE(bool, false, uut.lhealth); diff --git a/core/tests/NewNav/GLOFNavEph_T.cpp b/core/tests/NewNav/GLOFNavEph_T.cpp index c6abf771a..477448363 100644 --- a/core/tests/NewNav/GLOFNavEph_T.cpp +++ b/core/tests/NewNav/GLOFNavEph_T.cpp @@ -44,7 +44,7 @@ namespace gnsstk { - std::ostream& operator<<(std::ostream& s, GLOFNavData::PCode e) + std::ostream& operator<<(std::ostream& s, GLOFNavPCode e) { s << StringUtils::asString(e); return s; @@ -93,7 +93,7 @@ constructorTest() TUASSERTE(unsigned, -1, uut.P3); TUASSERTE(unsigned, -1, uut.P4); TUASSERTE(unsigned, -1, uut.interval); - TUASSERTE(gnsstk::GLOFNavData::PCode, gnsstk::GLOFNavData::PCode::Unknown, + TUASSERTE(gnsstk::GLOFNavPCode, gnsstk::GLOFNavPCode::Unknown, uut.opStatus); TUASSERT(isnan(uut.tauDelta)); TUASSERTE(unsigned, -1, uut.aod); diff --git a/core/tests/NewNav/GPSLNavEph_T.cpp b/core/tests/NewNav/GPSLNavEph_T.cpp index f5557aade..74b2d957e 100644 --- a/core/tests/NewNav/GPSLNavEph_T.cpp +++ b/core/tests/NewNav/GPSLNavEph_T.cpp @@ -48,7 +48,7 @@ namespace gnsstk s << StringUtils::asString(e); return s; } - std::ostream& operator<<(std::ostream& s, gnsstk::GPSLNavEph::L2Codes e) + std::ostream& operator<<(std::ostream& s, gnsstk::GPSLNavL2Codes e) { s << static_cast(e); return s; @@ -102,7 +102,7 @@ constructorTest() TUASSERTE(bool, false, obj.asFlag3); TUASSERTE(bool, false, obj.alert2); TUASSERTE(bool, false, obj.alert3); - TUASSERTE(gnsstk::GPSLNavEph::L2Codes, gnsstk::GPSLNavEph::L2Codes::Invalid1, + TUASSERTE(gnsstk::GPSLNavL2Codes, gnsstk::GPSLNavL2Codes::Invalid1, obj.codesL2); TUASSERTE(bool, false, obj.L2Pdata); TUASSERTE(gnsstk::NavMessageType, gnsstk::NavMessageType::Ephemeris, diff --git a/core/tests/NewNav/PNBGLOFNavDataFactory_T.cpp b/core/tests/NewNav/PNBGLOFNavDataFactory_T.cpp index 75a73c0b5..a595c0b9a 100644 --- a/core/tests/NewNav/PNBGLOFNavDataFactory_T.cpp +++ b/core/tests/NewNav/PNBGLOFNavDataFactory_T.cpp @@ -66,12 +66,12 @@ namespace gnsstk s << StringUtils::asString(h); return s; } - ostream& operator<<(ostream& s, GLOFNavData::SatType e) + ostream& operator<<(ostream& s, GLOFNavSatType e) { s << StringUtils::asString(e); return s; } - ostream& operator<<(ostream& s, GLOFNavData::PCode e) + ostream& operator<<(ostream& s, GLOFNavPCode e) { s << StringUtils::asString(e); return s; @@ -391,8 +391,8 @@ processEphTest() // OrbitData has no data of its own // GLOFNavData fields TUASSERTE(gnsstk::CommonTime, navFNAVGLOStr2ct, eph->xmit2); - TUASSERTE(gnsstk::GLOFNavData::SatType, - gnsstk::GLOFNavData::SatType::GLONASS_M, eph->satType); + TUASSERTE(gnsstk::GLOFNavSatType, + gnsstk::GLOFNavSatType::GLONASS_M, eph->satType); TUASSERTE(unsigned, 1, eph->slot); TUASSERTE(bool, false, eph->lhealth); TUASSERTE(gnsstk::SVHealth, gnsstk::SVHealth::Healthy, eph->health); @@ -420,8 +420,8 @@ processEphTest() TUASSERTE(unsigned, 1, eph->P3); TUASSERTE(unsigned, 0, eph->P4); TUASSERTE(unsigned, 0, eph->interval); - TUASSERTE(gnsstk::GLOFNavData::PCode, - gnsstk::GLOFNavData::PCode::CCalcGPSCalc, eph->opStatus); + TUASSERTE(gnsstk::GLOFNavPCode, + gnsstk::GLOFNavPCode::CCalcGPSCalc, eph->opStatus); TUASSERTFE(8.3819031715393066406e-09, eph->tauDelta); TUASSERTE(unsigned, 0, eph->aod); TUASSERTE(unsigned, 1, eph->accIndex); @@ -515,8 +515,8 @@ processAlmTest() // OrbitData has no data of its own // GLOFNavData fields TUASSERTE(gnsstk::CommonTime, navFNAVGLOStr7ct, alm->xmit2); - TUASSERTE(gnsstk::GLOFNavData::SatType, - gnsstk::GLOFNavData::SatType::GLONASS_M, alm->satType); + TUASSERTE(gnsstk::GLOFNavSatType, + gnsstk::GLOFNavSatType::GLONASS_M, alm->satType); TUASSERTE(unsigned, 1, alm->slot); TUASSERTE(bool, false, alm->lhealth); TUASSERTE(gnsstk::SVHealth, gnsstk::SVHealth::Healthy, alm->health); diff --git a/core/tests/NewNav/PNBGPSLNavDataFactory_T.cpp b/core/tests/NewNav/PNBGPSLNavDataFactory_T.cpp index 85ae88570..1d610966f 100644 --- a/core/tests/NewNav/PNBGPSLNavDataFactory_T.cpp +++ b/core/tests/NewNav/PNBGPSLNavDataFactory_T.cpp @@ -55,7 +55,7 @@ using GPSFactoryCounter = FactoryCounter(e); return s; @@ -494,8 +494,8 @@ processEphTest() TUASSERTE(bool, false, eph->alert3); TUASSERTE(bool, true, eph->asFlag2); TUASSERTE(bool, true, eph->asFlag3); - TUASSERTE(gnsstk::GPSLNavEph::L2Codes, - gnsstk::GPSLNavEph::L2Codes::Pcode, eph->codesL2); + TUASSERTE(gnsstk::GPSLNavL2Codes, + gnsstk::GPSLNavL2Codes::Pcode, eph->codesL2); TUASSERTE(bool, false, eph->L2Pdata); } } @@ -980,8 +980,8 @@ processEphQZSSTest() TUASSERTE(bool, false, eph->alert3); TUASSERTE(bool, false, eph->asFlag2); TUASSERTE(bool, false, eph->asFlag3); - TUASSERTE(gnsstk::GPSLNavEph::L2Codes, - gnsstk::GPSLNavEph::L2Codes::CAcode, eph->codesL2); + TUASSERTE(gnsstk::GPSLNavL2Codes, + gnsstk::GPSLNavL2Codes::CAcode, eph->codesL2); TUASSERTE(bool, true, eph->L2Pdata); } } diff --git a/core/tests/NewNav/RinexNavDataFactory_T.cpp b/core/tests/NewNav/RinexNavDataFactory_T.cpp index 7ab8f3b68..341f078af 100644 --- a/core/tests/NewNav/RinexNavDataFactory_T.cpp +++ b/core/tests/NewNav/RinexNavDataFactory_T.cpp @@ -65,7 +65,7 @@ namespace gnsstk { - std::ostream& operator<<(std::ostream& s, gnsstk::GPSLNavEph::L2Codes e) + std::ostream& operator<<(std::ostream& s, gnsstk::GPSLNavL2Codes e) { s << static_cast(e); return s; @@ -90,12 +90,12 @@ namespace gnsstk s << StringUtils::asString(e); return s; } - std::ostream& operator<<(std::ostream& s, GLOFNavData::PCode e) + std::ostream& operator<<(std::ostream& s, GLOFNavPCode e) { s << StringUtils::asString(e); return s; } - std::ostream& operator<<(std::ostream& s, GLOFNavData::SatType e) + std::ostream& operator<<(std::ostream& s, GLOFNavSatType e) { s << StringUtils::asString(e); return s; @@ -553,8 +553,8 @@ loadIntoMapTest() TUASSERTE(unsigned, 0, ephL->healthBits); TUASSERTE(unsigned, 0, ephL->uraIndex); // 2m TUASSERTFE( 5.122274160385e-09, ephL->tgd); - TUASSERTE(gnsstk::GPSLNavEph::L2Codes, - gnsstk::GPSLNavEph::L2Codes::Pcode, ephL->codesL2); + TUASSERTE(gnsstk::GPSLNavL2Codes, + gnsstk::GPSLNavL2Codes::Pcode, ephL->codesL2); TUASSERTE(bool, false, ephL->L2Pdata); } ephLCount++; @@ -1008,8 +1008,8 @@ loadIntoMapTest() TUASSERTE(gnsstk::NavMessageID, expNMID, ephF->signal); // GLOFNavData TUASSERTE(gnsstk::CommonTime, expTS+2.0, ephF->xmit2); - TUASSERTE(gnsstk::GLOFNavData::SatType, - gnsstk::GLOFNavData::SatType::Unknown, + TUASSERTE(gnsstk::GLOFNavSatType, + gnsstk::GLOFNavSatType::Unknown, ephF->satType); TUASSERTE(unsigned, 1, ephF->slot); TUASSERTE(bool, false, ephF->lhealth); @@ -1040,8 +1040,8 @@ loadIntoMapTest() TUASSERTE(unsigned, -1, ephF->P3); TUASSERTE(unsigned, -1, ephF->P4); TUASSERTE(unsigned, 0, ephF->interval); - TUASSERTE(gnsstk::GLOFNavData::PCode, - gnsstk::GLOFNavData::PCode::Unknown, + TUASSERTE(gnsstk::GLOFNavPCode, + gnsstk::GLOFNavPCode::Unknown, ephF->opStatus); TUASSERTE(int, 1, isnan(ephF->tauDelta)); TUASSERTE(unsigned, 1, ephF->aod); @@ -1321,8 +1321,8 @@ loadIntoMapQZSSTest() TUASSERTE(bool, false, eph->alert3); TUASSERTE(bool, false, eph->asFlag2); TUASSERTE(bool, false, eph->asFlag3); - TUASSERTE(gnsstk::GPSLNavEph::L2Codes, - gnsstk::GPSLNavEph::L2Codes::CAcode, eph->codesL2); + TUASSERTE(gnsstk::GPSLNavL2Codes, + gnsstk::GPSLNavL2Codes::CAcode, eph->codesL2); TUASSERTE(bool, true, eph->L2Pdata); } else if ((hea=dynamic_cast(ti.second.get())) diff --git a/swig/NewNav/NewNav.i b/swig/NewNav/NewNav.i index 7894f853f..c336aa0ee 100644 --- a/swig/NewNav/NewNav.i +++ b/swig/NewNav/NewNav.i @@ -64,8 +64,11 @@ ENUM_MAPPER(gnsstk::NavMessageType, NavMessageType, "gnsstk") %include "NavSearchOrder.hpp" %include "NavValidityType.hpp" %include "DumpDetail.hpp" +%include "GPSLNavL2Codes.hpp" %include "GalHealthStatus.hpp" %include "GalDataValid.hpp" +%include "GLOFNavPCode.hpp" +%include "GLOFNavSatType.hpp" %include "renameEnums.i" %pythoncode %{ @@ -76,8 +79,11 @@ ENUM_MAPPER(gnsstk::NavMessageType, NavMessageType, "gnsstk") renameEnums('NavSearchOrder') renameEnums('NavValidityType') renameEnums('DumpDetail') + renameEnums('GPSLNavL2Codes') renameEnums('GalHealthStatus') renameEnums('GalDataValid') + renameEnums('GLOFNavPCode') + renameEnums('GLOFNavSatType') %} %include "cleanup.i" diff --git a/swig/gnsstk_swig.hpp b/swig/gnsstk_swig.hpp index c6e25e0d2..1194d5b75 100644 --- a/swig/gnsstk_swig.hpp +++ b/swig/gnsstk_swig.hpp @@ -229,6 +229,8 @@ #include "GLOCNavIono.hpp" #include "GLOCNavUT1TimeOffset.hpp" /* #include "GLOFBits.hpp" */ +#include "GLOFNavPCode.hpp" +#include "GLOFNavSatType.hpp" #include "GLOFNavData.hpp" #include "GLOFNavAlm.hpp" #include "GLOFNavEph.hpp" @@ -253,6 +255,7 @@ #include "GPSCNavRedAlm.hpp" #include "GPSCNavTimeOffset.hpp" #include "GPSLNavData.hpp" +#include "GPSLNavL2Codes.hpp" #include "GPSLNavAlm.hpp" #include "GPSLNavEph.hpp" #include "GPSLNavHealth.hpp" diff --git a/swig/gnsstk_swig.i b/swig/gnsstk_swig.i index 33402da8f..d41e2200f 100644 --- a/swig/gnsstk_swig.i +++ b/swig/gnsstk_swig.i @@ -299,6 +299,8 @@ %import(module="gnsstk") "GLOCNavIono.hpp" %import(module="gnsstk") "GLOCNavUT1TimeOffset.hpp" /* %import(module="gnsstk") "GLOFBits.hpp" */ +%import(module="gnsstk") "GLOFNavPCode.hpp" +%import(module="gnsstk") "GLOFNavSatType.hpp" %import(module="gnsstk") "GLOFNavData.hpp" %import(module="gnsstk") "GLOFNavAlm.hpp" %import(module="gnsstk") "GLOFNavEph.hpp" @@ -322,6 +324,7 @@ %import(module="gnsstk") "GPSCNavIono.hpp" %import(module="gnsstk") "GPSCNavRedAlm.hpp" %import(module="gnsstk") "GPSCNavTimeOffset.hpp" +%import(module="gnsstk") "GPSLNavL2Codes.hpp" %import(module="gnsstk") "GPSLNavData.hpp" %import(module="gnsstk") "GPSLNavAlm.hpp" %import(module="gnsstk") "GPSLNavEph.hpp" From f67f9b33a0ec7a1fcce2009e86828c7fe07332cf Mon Sep 17 00:00:00 2001 From: John Knutson Date: Thu, 15 Dec 2022 09:57:40 -0600 Subject: [PATCH 15/16] Update NewNav docs --- core/lib/NewNav/NavLibrary.hpp | 62 +++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 12 deletions(-) diff --git a/core/lib/NewNav/NavLibrary.hpp b/core/lib/NewNav/NavLibrary.hpp index b556d0656..203ad7784 100644 --- a/core/lib/NewNav/NavLibrary.hpp +++ b/core/lib/NewNav/NavLibrary.hpp @@ -63,7 +63,7 @@ namespace gnsstk * * The NavFactory classes provide an interface for searching for * navigation message data, including ephemeris, almanac, health - * and time offset data, where + * ionospheric, ISC and time offset data, where * \li Ephemeris is the more precise orbital information where * the subject and transmitting satellite are the same. * \li Almanac is less precise orbit information where the @@ -73,6 +73,16 @@ namespace gnsstk * is in a usable state. * \li Time offset data provides the necessary data for * converting between time systems, e.g. GPS and UTC. + * \li Ionospheric data is provided by the system to model + * signal delays through the ionosphere for + * single-frequency users. + * \li ISC (inter-signal correction) data is provided by the + * system to determine the delay between a given signal + * and the defined reference signal. + * + * @note Clock data also appears but only in SP3 data and is + * really only used for internal storage. It is factored into + * the computed Xvt in that case. * * The simplest portion of this interface is defined in the * NavLibrary class, which provides an interface for computing @@ -91,6 +101,8 @@ namespace gnsstk * below), velocity and clock offset. * \li NavLibrary::getHealth() to get a satellite's health status. * \li NavLibrary::getOffset() to get TimeSystem conversion information. + * \li NavLibrary::getIonoCorr() to get ionospheric corrections. + * \li NavLibrary::getISC() to get inter-signal corrections. * \li NavLibrary::find() to get arbitrary navigation message * data (excluding TimeOffset information). * @@ -213,9 +225,9 @@ namespace gnsstk * } * // Search the NavLibrary * gnsstk::NavSatelliteID sat(subjID, system, gnsstk::CarrierBand::Any, - * gnsstk::TrackingCode::Any, - * gnsstk::XmitAnt::Any, freqOffs, - * !freqOffsSpec); + * gnsstk::TrackingCode::Any, + * gnsstk::XmitAnt::Any, freqOffs, + * !freqOffsSpec); * if (!navLib.getXvt(sat, when, xvt)) * { * cerr << "Unable to find XVT for " << sat << " @ " << when << endl; @@ -259,7 +271,7 @@ namespace gnsstk * } * // Search the NavLibrary * gnsstk::NavSatelliteID sat(subjID, system, band, code, xmitAnt, - * freqOffs, !freqOffsSpec, nav); + * freqOffs, !freqOffsSpec, nav); * if (!navLib.getXvt(sat, when, xvt, false)) * { * cerr << "Unable to find XVT for " << sat << " @ " << when << endl; @@ -305,7 +317,7 @@ namespace gnsstk * } * // Search the NavLibrary * gnsstk::ObsID oid(gnsstk::ObservationType::NavMsg, band, code, - * freqOffs, xmitAnt, !freqOffsSpec); + * freqOffs, xmitAnt, !freqOffsSpec); * gnsstk::SatID subjSat(subjID, subjSys); * gnsstk::SatID xmitSat(xmitID, xmitSys); * gnsstk::NavSatelliteID sat(subjSat, xmitSat, oid, nav); @@ -350,6 +362,34 @@ namespace gnsstk * } * \endcode * + * @subsubsection NavLibraryPracticalExamples Practical Examples + * + * Some practical examples may be found in gnsstk (library + * code). These are: + * + * | Source file | Use case | + * | ------------------- | -------- | + * | EphemerisRange.cpp | Get Xvt+IODC+health | + * | BCIonoCorrector.cpp | Look up ionospheric corrections | + * | BCISCorrector.cpp | Look up inter-signal corrections | + * + * More complete practical examples for NavLibrary and related classes + * can be found in the gnsstk-apps repository. Those are: + * + * | Source file | Use case | + * | --------------- | -------- | + * | timeconvert.cpp | Look up TimeOffsetData and change time systems. | + * | navdump.cpp | Dump data, look up arbitrary data types, compute | + * | ^ | Xvt, load different data types from different | + * | ^ | files. | + * | WhereSat.cpp | Print Xvt of all known satellites in a time range | + * + * (If you see ^ rendered in the table above, try a newer + * version of Doxygen) + * + * Practical examples using Python are somewhat scarce, but what + * there is can be found in swig/tests, e.g. test_NavLibrary.py. + * * @section NavFactorySearchParams Search Parameters * * The NavLibrary entry points have a common set of parameters @@ -615,10 +655,10 @@ namespace gnsstk * * \li Only use data from healthy satellites... * * The NavLibrary::getXvt(), NavLibrary::getHealth(), - * NavLibrary::getOffset(), NavLibrary::find() and - * NavDataFactory::find() methods all support the - * specification of the desired health status of the - * transmitting satellite (in the form of the SVHealth + * NavLibrary::getOffset(), NavLibrary::getISC(), + * NavLibrary::find() and NavDataFactory::find() methods all + * support the specification of the desired health status of + * the transmitting satellite (in the form of the SVHealth * enumeration). By default, the health of the transmitting * satellite is ignored, which is the fastest option as it * does not engender searches for or checking of health @@ -828,8 +868,6 @@ namespace gnsstk * custom factory to MultiFormatNavDataFactory whenever the * code is used. * - * As an example of how this is done, refer to ExtFactoryInitializer.cpp. - * * @warning It is possible that even with this implementation, * the static initialization may not happen properly, a problem * we have seen under Windows at the very least. It is strongly From 1feba5bea2fd88438cc9fa485fed9ae6729d39e8 Mon Sep 17 00:00:00 2001 From: David Barber Date: Wed, 21 Dec 2022 16:21:22 -0600 Subject: [PATCH 16/16] Release v14.0.0 --- CMakeLists.txt | 4 +- ChangeLog.md | 31 ++++ Doxyfile | 2 +- RELNOTES.md | 156 ++++++++++-------- debian/changelog | 27 +++ debian/control | 12 +- ...13-dev.install => libgnsstk14-dev.install} | 0 ...ibgnsstk13.install => libgnsstk14.install} | 0 rpm_files/SPECS/gnsstk.spec | 21 ++- rpm_files/SPECS/gnsstk_py36.spec | 4 +- swig/sphinx/conf.py | 4 +- 11 files changed, 176 insertions(+), 85 deletions(-) rename debian/{libgnsstk13-dev.install => libgnsstk14-dev.install} (100%) rename debian/{libgnsstk13.install => libgnsstk14.install} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ab7837a8..c98adf361 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,8 @@ cmake_minimum_required( VERSION 3.7.2 ) project( GNSSTK ) -set( GNSSTK_VERSION_MAJOR "13" ) -set( GNSSTK_VERSION_MINOR "8" ) +set( GNSSTK_VERSION_MAJOR "14" ) +set( GNSSTK_VERSION_MINOR "0" ) set( GNSSTK_VERSION_PATCH "0" ) set( GNSSTK_VERSION "${GNSSTK_VERSION_MAJOR}.${GNSSTK_VERSION_MINOR}.${GNSSTK_VERSION_PATCH}" ) diff --git a/ChangeLog.md b/ChangeLog.md index 77e4a9c9d..b4d18d9da 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,34 @@ +# Version 14.0.0 Tuesday December 20, 2022 + +Modifications by Author +----------------------- + Dan Wright (2): + Ci clean build + Deprecated debian 9 + + David Barber (1): + adding ubuntu-20.04 jobs + + John Knutson (10): + Add NavData::clone method to leaf classes to make alterable shared_ptr copies that don't affect the original + Update SWIG cmake rules now that we're no longer supporting cmake version 2 + Add signal details to nav dump methods + Helmert transform/reference frames refactor + Implement group delay calculator + Fix swig build error + Add a CorrectorType that was missed + Change group path corrector navLib from shared_ptr to reference to work around swig/python problem + Move NewNav enums to the namespace level for consistency + Update NewNav docs + + Sarah Magliocca (1): + Updating the GNSSTk build scripts for visual studio 2019 + + Taben Malik (1): + Refactored RawRange + + + # Version 13.8.0 Monday October 31, 2022 Modifications by Author diff --git a/Doxyfile b/Doxyfile index 06290eb08..843446d6e 100644 --- a/Doxyfile +++ b/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "GNSS ToolKit Software Library" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 13.8.0 +PROJECT_NUMBER = 14.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/RELNOTES.md b/RELNOTES.md index bc492007e..d7ee34a0d 100755 --- a/RELNOTES.md +++ b/RELNOTES.md @@ -1,90 +1,102 @@ -GNSSTk 13.8.0 Release Notes +GNSSTk 14.0.0 Release Notes ======================== - * This release includes the following: - * Updating documentation of TropModel classes. - * Spliting test data into gnsstk-data repo with submodules configured. - * Updating sphinx documentation of SWIG bindings. - * Adding support for GLONASS CDMA nav data processing (See New Modules below) - * Additionally, it contains bug fixes, build and CI updates. + * This release introduces a major update to the toolkit. + * It includes the following: + * Refactoring HelmertTransform into HelmertTransformer and reference frames into RefFrame. + * Adding signal details to nav dump methods. + * Adding group path delay calculator GroupPathCorr and related classes. (See New Modules below). + * Refactoring duplicate raw range implementations into a single class. + * Moving NewNav enums to the namespace level for consistency. + * Deprecating support for Debian 9. + * Adding support for Ubuntu20.04 (focal) + * Additionally, it contains minor library updates and bug fixes -Updates since v13.7.0 +Updates since v13.8.0 --------------------- **Build System and Test Suite** - * Update Changed the minimum cmake version - * Fix Remove SystemTime tests that randomly fail - * Fix ORD tests to use the GNSSTk testing framework + * Update the clean build parameter + * Update SWIG cmake rules now that we're no longer supporting cmake version 2 + * Update compiler to Visual Studio 2019 in the Windows build scripts. **Gitlab CI** - * Update CODEOWNERS. - * Fix pipeline push artifacts + * Update Deprecated Debian 9 build + * Add Ubuntu 20.04 pipeline jobs **Library Changes** - * Update change string name in StringUtils to avoid conflict with curses library macro - * Update exception specifications from throw() to noexcept - * Update documentation of TropModel classes - * Update move nav message bit definition enums out of PNBNavDataFactory.cpp files and into their own files. - * Add documentation on raw range (geometric range) computations - * Add Split test data into gnsstk-data repo with submodules configured - * Add support for GLONASS CDMA nav data processing - * Update sphinx documentation of SWIG bindings - * Update Deprecate extraneous swig binding for function that no longer exists. + * Add group path delay calculator (GroupPathCorr and related classes). + * Update Refactor HelmertTransform into HelmertTransformer + * Update Refactor reference frames into RefFrame + * Update the nonsensical ISC interface in NavLibrary with one that does make sense. + * Update Refactor duplicate raw range implementations into a single class. + * Update group path corrector navLib from shared_ptr to reference to work around swig/python problem + * Update Move NewNav enums to the namespace level for consistency + * Update NewNav docs + * Add NavData::clone method + * Add signal details to nav dump methods + * Add group path delay calculator (GroupPathCorr and related classes). + * Add a CorrectorType that was missed -Fixes since v13.7.0 +Fixes since v13.8.0 -------------------- - * Fix week rollover issues in GPS LNav, Galileo F/Nav and Galileo I/Nav decoders. - * Fix bugs in GLONASS CDMA nav data processing + * Fix swig build error Removed Code due to Deprecation ------------------------------- - core/tests/ORD/OrdMockClasses.hpp - swig/sphinx/sphinxsetup.py + core/lib/GNSSEph/GloEphemeris.cpp + core/lib/GNSSEph/GloEphemeris.hpp New Modules ------------------------------- - core/lib/NewNav/GLOCBits.hpp - core/lib/NewNav/GLOCNavAlm.cpp - core/lib/NewNav/GLOCNavAlm.hpp - core/lib/NewNav/GLOCNavAlmCorrected.hpp - core/lib/NewNav/GLOCNavAlmDeltas.hpp - core/lib/NewNav/GLOCNavAlmNumberCruncher.hpp - core/lib/NewNav/GLOCNavAlmUncorrected.hpp - core/lib/NewNav/GLOCNavData.cpp - core/lib/NewNav/GLOCNavEph.cpp - core/lib/NewNav/GLOCNavEph.hpp - core/lib/NewNav/GLOCNavHeader.cpp - core/lib/NewNav/GLOCNavHeader.hpp - core/lib/NewNav/GLOCNavHealth.cpp - core/lib/NewNav/GLOCNavHealth.hpp - core/lib/NewNav/GLOCNavIono.cpp - core/lib/NewNav/GLOCNavIono.hpp - core/lib/NewNav/GLOCNavLTDMP.cpp - core/lib/NewNav/GLOCNavLTDMP.hpp - core/lib/NewNav/GLOCNavUT1TimeOffset.cpp - core/lib/NewNav/GLOCNavUT1TimeOffset.hpp - core/lib/NewNav/GLOCOrbitType.cpp - core/lib/NewNav/GLOCOrbitType.hpp - core/lib/NewNav/GLOCRegime.cpp - core/lib/NewNav/GLOCRegime.hpp - core/lib/NewNav/GLOCSatType.cpp - core/lib/NewNav/GLOCSatType.hpp - core/lib/NewNav/GPSC2Bits.hpp - core/lib/NewNav/GPSCBits.hpp - core/lib/NewNav/GPSLBits.hpp - core/lib/NewNav/GalFBits.hpp - core/lib/NewNav/GalIBits.hpp - core/lib/NewNav/NavFit.hpp - core/lib/NewNav/PNBGLOCNavDataFactory.cpp - core/lib/NewNav/PNBGLOCNavDataFactory.hpp - core/lib/TimeHandling/GLONASSTime.cpp - core/lib/TimeHandling/GLONASSTime.hpp - core/tests/NewNav/GLOCNavAlm_T.cpp - core/tests/NewNav/GLOCNavEph_T.cpp - core/tests/NewNav/GLOCNavHealth_T.cpp - core/tests/NewNav/GLOCNavLTDMP_T.cpp - core/tests/NewNav/GLOCNavTestDataDecl.hpp - core/tests/NewNav/GLOCNavTestDataDef.hpp - core/tests/NewNav/GLOCNavUT1TimeOffset_T.cpp - core/tests/NewNav/PNBGLOCNavDataFactory_T.cpp - core/tests/TimeHandling/GLONASSTime_T.cpp \ No newline at end of file + core/lib/FileHandling/MetReader.hpp + core/lib/GNSSCore/BCISCorrector.cpp + core/lib/GNSSCore/BCISCorrector.hpp + core/lib/GNSSCore/BCIonoCorrector.cpp + core/lib/GNSSCore/BCIonoCorrector.hpp + core/lib/GNSSCore/CorrDupHandling.cpp + core/lib/GNSSCore/CorrDupHandling.hpp + core/lib/GNSSCore/CorrectionResult.hpp + core/lib/GNSSCore/CorrectionResults.cpp + core/lib/GNSSCore/CorrectionResults.hpp + core/lib/GNSSCore/CorrectorType.cpp + core/lib/GNSSCore/CorrectorType.hpp + core/lib/GNSSCore/GroupPathCorr.cpp + core/lib/GNSSCore/GroupPathCorr.hpp + core/lib/GNSSCore/GroupPathCorrector.hpp + core/lib/GNSSCore/HelmertTransformer.cpp + core/lib/GNSSCore/HelmertTransformer.hpp + core/lib/GNSSCore/RefFrame.cpp + core/lib/GNSSCore/RefFrame.hpp + core/lib/GNSSCore/RefFrameRlz.cpp + core/lib/GNSSCore/RefFrameRlz.hpp + core/lib/GNSSCore/RefFrameSys.cpp + core/lib/GNSSCore/RefFrameSys.hpp + core/lib/GNSSCore/TransformLibrary.cpp + core/lib/GNSSCore/TransformLibrary.hpp + core/lib/GNSSCore/Transformer.hpp + core/lib/GNSSCore/TropCorrector.hpp + core/lib/GNSSEph/RawRange.cpp + core/lib/GNSSEph/RawRange.hpp + core/lib/NewNav/GLOFNavPCode.cpp + core/lib/NewNav/GLOFNavPCode.hpp + core/lib/NewNav/GLOFNavSatType.hpp + core/lib/NewNav/GPSLNavL2Codes.cpp + core/lib/NewNav/GPSLNavL2Codes.hpp + core/tests/FileHandling/MetReader_T.cpp + core/tests/GNSSCore/BCISCorrector_T.cpp + core/tests/GNSSCore/BCIonoCorrector_T.cpp + core/tests/GNSSCore/CorrDupHandling_T.cpp + core/tests/GNSSCore/CorrectionResults_T.cpp + core/tests/GNSSCore/CorrectorType_T.cpp + core/tests/GNSSCore/GroupPathCorr_T.cpp + core/tests/GNSSCore/GroupPathCorrector_T.cpp + core/tests/GNSSCore/HelmertTransformer_T.cpp + core/tests/GNSSCore/RawRange_T.cpp + core/tests/GNSSCore/RefFrameRlz_T.cpp + core/tests/GNSSCore/RefFrameSys_T.cpp + core/tests/GNSSCore/TransformLibrary_T.cpp + core/tests/GNSSCore/TropCorrector_T.cpp + core/tests/Geomatics/PreciseRange_T.cpp + swig/SWIGHelpers/std_tuple.i + swig/tests/__init__.py \ No newline at end of file diff --git a/debian/changelog b/debian/changelog index bd6cea7eb..5dedb8738 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,30 @@ +gnsstk (14.0.0-1) stable; urgency=low + + * Updated to version 14.0.0 + * Updated the clean build parameter + * Add NavData::clone method + * Update SWIG cmake rules now that we're no longer supporting cmake + version 2 + * Update Deprecated Debian 9 build + * Add signal details to nav dump methods + * Update compiler to Visual Studio 2019 in the Windows build scripts. + * Update Refactor HelmertTransform into HelmertTransformer + * Update Refactor reference frames into RefFrame + * Add group path delay calculator (GroupPathCorr and related classes). + * Update the nonsensical ISC interface in NavLibrary with one that + does make sense. + * Fix swig build error + * Add a CorrectorType that was missed + * Add Ubuntu 20.04 pipeline jobs + * Update Refactor duplicate raw range implementations into a single + class. + * Update group path corrector navLib from shared_ptr to reference to + work around swig/python problem + * Update Move NewNav enums to the namespace level for consistency + * Update NewNav docs + + -- David Barber Tue, 20 Dec 2022 11:22:45 -0600 + gnsstk (13.8.0-1) stable; urgency=low * Updated to version 13.8.0 diff --git a/debian/control b/debian/control index 71142f4c7..f7d8e282a 100644 --- a/debian/control +++ b/debian/control @@ -12,7 +12,7 @@ Vcs-Browser: https://github.com/SGL-UT/GNSSTk.git Package: gnsstk-bin Architecture: any -Depends: libgnsstk13 (>= ${binary:Version}), python3-gnsstk , ${misc:Depends}, ${shlibs:Depends}, ${python3:Depends} +Depends: libgnsstk14 (>= ${binary:Version}), python3-gnsstk , ${misc:Depends}, ${shlibs:Depends}, ${python3:Depends} Description: GNSS Toolkit (GNSSTk) - command line tools The GNSS Toolkit (GNSSTk) is an open-source (LGPL) project sponsored by the Space and Geophysics Laboratory (SGL), part of the Applied Research @@ -21,10 +21,10 @@ Description: GNSS Toolkit (GNSSTk) - command line tools * provide applications for use by the GNSS and satellite navigation community. * provide a core library to facilitate the development of GNSS applications. -Package: libgnsstk13-dev +Package: libgnsstk14-dev Section: libdevel Architecture: any -Depends: libgnsstk13 (= ${binary:Version}), ${misc:Depends} +Depends: libgnsstk14 (= ${binary:Version}), ${misc:Depends} Description: GNSS Toolkit (GNSSTk) - Headers The GNSS Toolkit (GNSSTk) is an open-source (LGPL) project sponsored by the Space and Geophysics Laboratory (SGL), part of the Applied Research @@ -33,7 +33,7 @@ Description: GNSS Toolkit (GNSSTk) - Headers * provide applications for use by the GNSS and satellite navigation community. * provide a core library to facilitate the development of GNSS applications. -Package: libgnsstk13 +Package: libgnsstk14 Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: GNSS Toolkit (GNSSTk) - Shared Libraries @@ -44,12 +44,12 @@ Description: GNSS Toolkit (GNSSTk) - Shared Libraries * provide applications for use by the GNSS and satellite navigation community. * provide a core library to facilitate the development of GNSS applications. -Package: libgnsstk13-dbg +Package: libgnsstk14-dbg Build-Profiles: Architecture: any Section: debug Priority: extra -Depends: libgnsstk13 (= ${binary:Version}), ${misc:Depends} +Depends: libgnsstk14 (= ${binary:Version}), ${misc:Depends} Description: GNSS Toolkit (GNSSTk) - Shared Library Debugging Symbols The GNSS Toolkit (GNSSTk) is an open-source (LGPL) project sponsored by the Space and Geophysics Laboratory (SGL), part of the Applied Research diff --git a/debian/libgnsstk13-dev.install b/debian/libgnsstk14-dev.install similarity index 100% rename from debian/libgnsstk13-dev.install rename to debian/libgnsstk14-dev.install diff --git a/debian/libgnsstk13.install b/debian/libgnsstk14.install similarity index 100% rename from debian/libgnsstk13.install rename to debian/libgnsstk14.install diff --git a/rpm_files/SPECS/gnsstk.spec b/rpm_files/SPECS/gnsstk.spec index 6e38ba444..b51c0c555 100644 --- a/rpm_files/SPECS/gnsstk.spec +++ b/rpm_files/SPECS/gnsstk.spec @@ -1,5 +1,5 @@ %define name gnsstk -%define version 13.8.0 +%define version 14.0.0 %define release 1 Summary: GNSS Toolkit @@ -57,6 +57,25 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Dec 20 2022 David Barber +- Updated for v14.0.0 release +- Update NewNav docs +- Update Move NewNav enums to the namespace level for consistency +- Update group path corrector navLib from shared_ptr to reference to work around swig/python problem +- Update Refactor duplicate raw range implementations into a single class. +- Add Ubuntu 20.04 pipeline jobs +- Add a CorrectorType that was missed +- Fix swig build error +- Update the nonsensical ISC interface in NavLibrary with one that does make sense. +- Add group path delay calculator (GroupPathCorr and related classes). +- Update Refactor reference frames into RefFrame +- Update Refactor HelmertTransform into HelmertTransformer +- Update compiler to Visual Studio 2019 in the Windows build scripts. +- Add signal details to nav dump methods +- Update Deprecated Debian 9 build +- Update SWIG cmake rules now that we're no longer supporting cmake version 2 +- Add NavData::clone method +- Updated the clean build parameter * Mon Oct 31 2022 David Barber - Updated for v13.8.0 release - Fix Remove SystemTime tests that randomly fail diff --git a/rpm_files/SPECS/gnsstk_py36.spec b/rpm_files/SPECS/gnsstk_py36.spec index 68559f5d2..3e3b81145 100644 --- a/rpm_files/SPECS/gnsstk_py36.spec +++ b/rpm_files/SPECS/gnsstk_py36.spec @@ -1,5 +1,5 @@ %define name python3-gnsstk -%define version 13.8.0 +%define version 14.0.0 %define release 1 Summary: GNSS Toolkit @@ -67,6 +67,8 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Dec 20 2022 David Barber +- Updated for v14.0.0 release * Mon Oct 31 2022 David Barber - Updated for v13.8.0 release * Fri Aug 26 2022 David Barber diff --git a/swig/sphinx/conf.py b/swig/sphinx/conf.py index 160d1dbf3..f134202c7 100755 --- a/swig/sphinx/conf.py +++ b/swig/sphinx/conf.py @@ -13,8 +13,8 @@ copyright = '2022, ARL:UT' import gnsstk -version = '13.8' -release = '13.8.0' +version = '14.0' +release = '14.0.0' # -- General configuration ------------------------------------------------------------------------ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration