diff --git a/CMakeLists.txt b/CMakeLists.txt index f25f704f3..dfde4c3b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -326,13 +326,13 @@ set(GNSSSDR_PROTOBUF_MIN_VERSION "3.0.0") ################################################################################ set(GNSSSDR_GFLAGS_LOCAL_VERSION "2.2.2") set(GNSSSDR_GLOG_LOCAL_VERSION "0.4.0") -set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.3.x") +set(GNSSSDR_ARMADILLO_LOCAL_VERSION "10.4.x") set(GNSSSDR_GTEST_LOCAL_VERSION "1.10.0") set(GNSSSDR_GNSS_SIM_LOCAL_VERSION "master") set(GNSSSDR_GPSTK_LOCAL_VERSION "8.0.0") set(GNSSSDR_MATIO_LOCAL_VERSION "1.5.21") set(GNSSSDR_PUGIXML_LOCAL_VERSION "1.11.4") -set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.15.7") +set(GNSSSDR_PROTOCOLBUFFERS_LOCAL_VERSION "3.15.8") set(GNSSSDR_BENCHMARK_LOCAL_VERSION "1.5.2") set(GNSSSDR_MATHJAX_EXTERNAL_VERSION "2.7.7") diff --git a/README.md b/README.md index 8f6d16285..c5c493868 100644 --- a/README.md +++ b/README.md @@ -292,9 +292,9 @@ $ sudo apt-get install libblas-dev liblapack-dev # For Debian/Ubuntu/Linux $ sudo yum install lapack-devel blas-devel # For Fedora/CentOS/RHEL $ sudo zypper install lapack-devel blas-devel # For OpenSUSE $ sudo pacman -S blas lapack # For Arch Linux -$ wget http://sourceforge.net/projects/arma/files/armadillo-10.3.0.tar.xz -$ tar xvfz armadillo-10.3.0.tar.xz -$ cd armadillo-10.3.0 +$ wget http://sourceforge.net/projects/arma/files/armadillo-10.4.0.tar.xz +$ tar xvfz armadillo-10.4.0.tar.xz +$ cd armadillo-10.4.0 $ cmake . $ make $ sudo make install @@ -395,9 +395,9 @@ $ sudo apt-get install autoconf automake libtool curl make g++ unzip and then: ``` -$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.7/protobuf-cpp-3.15.7.tar.gz -$ tar xvfz protobuf-cpp-3.15.7.tar.gz -$ cd protobuf-3.15.7 +$ wget https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protobuf-cpp-3.15.8.tar.gz +$ tar xvfz protobuf-cpp-3.15.8.tar.gz +$ cd protobuf-3.15.8 $ ./autogen.sh $ ./configure $ make diff --git a/docs/changelog.md b/docs/changelog.md index c7ec3c833..a7d2b988f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -10,20 +10,13 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades = 12 and CMake >= 3.19. -- Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or - Boost >= 1.74. -- Fix linking of the `` library when using GCC 8.x and GNU Radio >= - 3.8. +- Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B + INAV message introduced in Galileo ICD v2.0. If the reduced CED is available + before the full ephemeris set, it is used for PVT computation until the full + set has not yet been received. This can contribute to shorten the + Time-To-First-Fix. ### Improvements in Maintainability: @@ -46,6 +39,21 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades = 12 and CMake >= 3.19. +- Fix building of FPGA blocks when linking against GNU Radio >= 3.9 and/or + Boost >= 1.74. +- Fix linking of the `` library when using GCC 8.x and GNU Radio >= + 3.8. + ### Improvements in Usability: - Avoid segmentation faults in the flow graph connection and/or starting due to @@ -68,6 +76,9 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + d_first_eph_sent = true; // do not send reduced CED anymore, since we have the full ephemeris set } + else + { + // If we still do not have ephemeris, check if we have a reduced CED + if ((d_band == '1') && !d_first_eph_sent && (d_inav_nav.have_new_reduced_ced() == true)) + { + const std::shared_ptr tmp_obj = std::make_shared(d_inav_nav.get_reduced_ced()); + std::cout << "New Galileo E1 I/NAV reduced CED message received in channel " << d_channel << " from satellite " << d_satellite << '\n'; + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + } + if (d_inav_nav.have_new_iono_and_GST() == true) { // get object for this SV (mandatory) diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h index 7243613ce..9ce42be3d 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.h @@ -139,6 +139,7 @@ private: bool d_dump; bool d_dump_mat; bool d_remove_dat; + bool d_first_eph_sent; }; diff --git a/src/core/system_parameters/CMakeLists.txt b/src/core/system_parameters/CMakeLists.txt index c885892cc..e7898b75e 100644 --- a/src/core/system_parameters/CMakeLists.txt +++ b/src/core/system_parameters/CMakeLists.txt @@ -17,6 +17,7 @@ set(SYSTEM_PARAMETERS_SOURCES galileo_cnav_message.cc galileo_fnav_message.cc galileo_inav_message.cc + galileo_reduced_ced.cc beidou_dnav_navigation_message.cc beidou_dnav_ephemeris.cc sbas_ephemeris.cc @@ -52,6 +53,7 @@ set(SYSTEM_PARAMETERS_HEADERS galileo_fnav_message.h galileo_has_data.h galileo_inav_message.h + galileo_reduced_ced.h sbas_ephemeris.h gps_cnav_ephemeris.h gps_cnav_navigation_message.h diff --git a/src/core/system_parameters/Galileo_INAV.h b/src/core/system_parameters/Galileo_INAV.h index 54ed2db28..793de4789 100644 --- a/src/core/system_parameters/Galileo_INAV.h +++ b/src/core/system_parameters/Galileo_INAV.h @@ -19,6 +19,7 @@ #define GNSS_SDR_GALILEO_INAV_H #include "MATH_CONSTANTS.h" +#include #include #include #include @@ -245,12 +246,44 @@ const std::vector> T_0_G_10_BIT({{115, 8}}); constexpr int32_t T_0_G_10_LSB = 3600; const std::vector> WN_0_G_10_BIT({{123, 6}}); +/* Page 16 */ +constexpr double CED_DeltaAred_LSB = TWO_P8; +const std::vector> CED_DeltaAred_BIT({{7, 5}}); +constexpr double CED_exred_LSB = TWO_N22; +const std::vector> CED_exred_BIT({{12, 13}}); +constexpr double CED_eyred_LSB = TWO_N22; +const std::vector> CED_eyred_BIT({{25, 13}}); +constexpr double CED_Deltai0red_LSB = TWO_N22; +const std::vector> CED_Deltai0red_BIT({{38, 17}}); +constexpr double CED_Omega0red_LSB = TWO_N22; +const std::vector> CED_Omega0red_BIT({{55, 23}}); +constexpr double CED_lambda0red_LSB = TWO_N22; +const std::vector> CED_lambda0red_BIT({{78, 23}}); +constexpr double CED_af0red_LSB = TWO_N26; +const std::vector> CED_af0red_BIT({{101, 22}}); +constexpr double CED_af1red_LSB = TWO_N35; +const std::vector> CED_af1red_BIT({{123, 6}}); + +/* Pages 17, 18, 19, 20 */ +const std::vector> RS_IODNAV_LSBS({{15, 2}}); +constexpr size_t INAV_RS_SUBVECTOR_LENGTH = 15; +constexpr size_t INAV_RS_PARITY_VECTOR_LENGTH = 60; +constexpr int32_t BITS_IN_OCTET = 8; +constexpr int32_t FIRST_RS_BIT = 7; +constexpr int32_t FIRST_RS_BIT_AFTER_IODNAV = 17; /* Page 0 */ const std::vector> TIME_0_BIT({{7, 2}}); const std::vector> WN_0_BIT({{97, 12}}); const std::vector> TOW_0_BIT({{109, 20}}); +/* Secondary Synchronization Patters */ +constexpr char GALILEO_INAV_PLAIN_SSP1[9] = "00000100"; +constexpr char GALILEO_INAV_PLAIN_SSP2[9] = "00101011"; +constexpr char GALILEO_INAV_PLAIN_SSP3[9] = "00101111"; +constexpr char GALILEO_INAV_ENCODED_SSP1[17] = "1110100100100101"; +constexpr char GALILEO_INAV_ENCODED_SSP2[17] = "0110110001001110"; +constexpr char GALILEO_INAV_ENCODED_SSP3[17] = "1101000000111110"; /** \} */ /** \} */ diff --git a/src/core/system_parameters/MATH_CONSTANTS.h b/src/core/system_parameters/MATH_CONSTANTS.h index 749468828..5f1cd98f1 100644 --- a/src/core/system_parameters/MATH_CONSTANTS.h +++ b/src/core/system_parameters/MATH_CONSTANTS.h @@ -58,6 +58,7 @@ constexpr double TWO_PI = 2.0 * GNSS_PI; //!< 2 * pi constexpr double TWO_P3 = 8.0; //!< 2^3 constexpr double TWO_P4 = 16.0; //!< 2^4 +constexpr double TWO_P8 = 256.0; //!< 2^8 constexpr double TWO_P11 = 2048.0; //!< 2^11 constexpr double TWO_P12 = 4096.0; //!< 2^12 constexpr double TWO_P14 = 16384.0; //!< 2^14 @@ -83,9 +84,11 @@ constexpr double TWO_N18 = 3.814697265625000e-006; //!< 2^-18 constexpr double TWO_N19 = 1.907348632812500e-006; //!< 2^-19 constexpr double TWO_N20 = 9.536743164062500e-007; //!< 2^-20 constexpr double TWO_N21 = 4.768371582031250e-007; //!< 2^-21 +constexpr double TWO_N22 = 2.384185791015625e-007; //!< 2^-22 constexpr double TWO_N23 = 1.192092895507810e-007; //!< 2^-23 constexpr double TWO_N24 = 5.960464477539063e-008; //!< 2^-24 constexpr double TWO_N25 = 2.980232238769531e-008; //!< 2^-25 +constexpr double TWO_N26 = 1.490116119384765e-009; //!< 2^-26 constexpr double TWO_N27 = 7.450580596923828e-009; //!< 2^-27 constexpr double TWO_N29 = 1.862645149230957e-009; //!< 2^-29 constexpr double TWO_N30 = 9.313225746154785e-010; //!< 2^-30 diff --git a/src/core/system_parameters/galileo_inav_message.cc b/src/core/system_parameters/galileo_inav_message.cc index 64bc9dbbb..43bbef2d9 100644 --- a/src/core/system_parameters/galileo_inav_message.cc +++ b/src/core/system_parameters/galileo_inav_message.cc @@ -17,6 +17,7 @@ */ #include "galileo_inav_message.h" +#include "galileo_reduced_ced.h" #include // for boost::crc_basic, boost::crc_optimal #include // for boost::dynamic_bitset #include // for DLOG @@ -55,7 +56,7 @@ bool Galileo_Inav_Message::CRC_test(std::bitset bits, u } -uint64_t Galileo_Inav_Message::read_navigation_unsigned(std::bitset bits, const std::vector >& parameter) const +uint64_t Galileo_Inav_Message::read_navigation_unsigned(std::bitset bits, const std::vector>& parameter) const { uint64_t value = 0ULL; const int32_t num_of_slices = parameter.size(); @@ -74,7 +75,7 @@ uint64_t Galileo_Inav_Message::read_navigation_unsigned(std::bitset bits, const std::vector >& parameter) const +uint64_t Galileo_Inav_Message::read_page_type_unsigned(std::bitset bits, const std::vector>& parameter) const { uint64_t value = 0ULL; const int32_t num_of_slices = parameter.size(); @@ -93,7 +94,7 @@ uint64_t Galileo_Inav_Message::read_page_type_unsigned(std::bitset bits, const std::vector >& parameter) const +int64_t Galileo_Inav_Message::read_navigation_signed(std::bitset bits, const std::vector>& parameter) const { int64_t value = 0LL; const int32_t num_of_slices = parameter.size(); @@ -124,7 +125,7 @@ int64_t Galileo_Inav_Message::read_navigation_signed(std::bitset bits, const std::vector >& parameter) const +bool Galileo_Inav_Message::read_navigation_bool(std::bitset bits, const std::vector>& parameter) const { bool value; if (static_cast(static_cast(bits[GALILEO_DATA_JK_BITS - parameter[0].first])) == 1) @@ -262,6 +263,18 @@ bool Galileo_Inav_Message::have_new_almanac() // Check if we have a new almanac } +bool Galileo_Inav_Message::have_new_reduced_ced() +{ + // Check if we have a new CED data set stored in the galileo navigation class + if ((flag_CED == true) && (WN_5 > 0)) // We need the week number to compute GST + { + flag_CED = false; + return true; + } + return false; +} + + Galileo_Ephemeris Galileo_Inav_Message::get_ephemeris() const { Galileo_Ephemeris ephemeris; @@ -416,6 +429,42 @@ Galileo_Almanac_Helper Galileo_Inav_Message::get_almanac() const } +Galileo_Ephemeris Galileo_Inav_Message::get_reduced_ced() const +{ + Galileo_Reduced_CED ced{}; + ced.PRN = SV_ID_PRN_4; + if (TOW_5 > TOW_6) + { + ced.TOTRedCED = WN_5 * 604800 + TOW_5 + 4; // According to ICD 2.0, Table 38 + } + else + { + ced.TOTRedCED = WN_5 * 604800 + TOW_6 + 10; // According to ICD 2.0, Table 38 + } + std::array iod_navs = {IOD_nav_1, IOD_nav_2, IOD_nav_3, IOD_nav_4}; + int32_t max_IOD_nav = IOD_nav_1; + for (int i = 1; i < 4; i++) + { + if (iod_navs[i] > max_IOD_nav) + { + max_IOD_nav = iod_navs[i]; + } + } + ced.IODnav = max_IOD_nav; + ced.DeltaAred = ced_DeltaAred; + ced.exred = ced_exred; + ced.eyred = ced_eyred; + ced.Deltai0red = ced_Deltai0red; + ced.Omega0red = ced_Omega0red; + ced.lambda0red = ced_lambda0red; + ced.af0red = ced_af0red; + ced.af1red = ced_af1red; + + Galileo_Ephemeris eph = ced.compute_eph(); + return eph; +} + + int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) { const std::string data_jk_string = data_jk; @@ -750,6 +799,99 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) DLOG(INFO) << "flag_tow_set" << flag_TOW_set; break; + case 16: // Word type 16: Reduced Clock and Ephemeris Data (CED) parameters + DLOG(INFO) << "Word type 16 arrived"; + ced_DeltaAred = static_cast(read_navigation_signed(data_jk_bits, CED_DeltaAred_BIT)); + ced_DeltaAred = ced_DeltaAred * CED_DeltaAred_LSB; + DLOG(INFO) << "DeltaAred = " << ced_DeltaAred; + ced_exred = static_cast(read_navigation_signed(data_jk_bits, CED_exred_BIT)); + ced_exred = ced_exred * CED_exred_LSB; + DLOG(INFO) << "exred = " << ced_exred; + ced_eyred = static_cast(read_navigation_signed(data_jk_bits, CED_eyred_BIT)); + ced_eyred = ced_eyred * CED_eyred_LSB; + DLOG(INFO) << "eyred = " << ced_eyred; + ced_Deltai0red = static_cast(read_navigation_signed(data_jk_bits, CED_Deltai0red_BIT)); + ced_Deltai0red = ced_Deltai0red * CED_Deltai0red_LSB; + DLOG(INFO) << "Deltai0red = " << ced_Deltai0red; + ced_Omega0red = static_cast(read_navigation_signed(data_jk_bits, CED_Omega0red_BIT)); + ced_Omega0red = ced_Omega0red * CED_Omega0red_LSB; + DLOG(INFO) << "Omega0red = " << ced_Omega0red; + ced_lambda0red = static_cast(read_navigation_signed(data_jk_bits, CED_lambda0red_BIT)); + ced_lambda0red = ced_lambda0red * CED_lambda0red_LSB; + DLOG(INFO) << "lambda0red = " << ced_lambda0red; + ced_af0red = static_cast(read_navigation_signed(data_jk_bits, CED_af0red_BIT)); + ced_af0red = ced_af0red * CED_af0red_LSB; + DLOG(INFO) << "af0red = " << ced_af0red; + ced_af1red = static_cast(read_navigation_signed(data_jk_bits, CED_af1red_BIT)); + ced_af1red = ced_af1red * CED_af1red_LSB; + DLOG(INFO) << "af1red = " << ced_af1red; + flag_CED = true; + break; + + case 17: // Word type 17: FEC2 Reed-Solomon for CED + { + std::vector> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}}); + gamma_rs0[0] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + IODnav_LSB17 = static_cast(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS)); + DLOG(INFO) << "IODnav 2 LSBs in Word type 17: " << static_cast(IODnav_LSB17); + int32_t start_bit = FIRST_RS_BIT_AFTER_IODNAV; + for (size_t i = 1; i < INAV_RS_SUBVECTOR_LENGTH; i++) + { + gamma_octet_bits[0] = std::pair({start_bit, BITS_IN_OCTET}); + gamma_rs0[i] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + start_bit += BITS_IN_OCTET; + } + break; + } + + case 18: // Word type 18: FEC2 Reed-Solomon for CED + { + std::vector> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}}); + gamma_rs1[0] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + IODnav_LSB18 = static_cast(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS)); + DLOG(INFO) << "IODnav 2 LSBs in Word type 18: " << static_cast(IODnav_LSB18); + int32_t start_bit = FIRST_RS_BIT_AFTER_IODNAV; + for (size_t i = 1; i < INAV_RS_SUBVECTOR_LENGTH; i++) + { + gamma_octet_bits[0] = std::pair({start_bit, BITS_IN_OCTET}); + gamma_rs1[i] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + start_bit += BITS_IN_OCTET; + } + break; + } + + case 19: // Word type 19: FEC2 Reed-Solomon for CED + { + std::vector> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}}); + gamma_rs2[0] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + IODnav_LSB19 = static_cast(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS)); + DLOG(INFO) << "IODnav 2 LSBs in Word type 19: " << static_cast(IODnav_LSB19); + int32_t start_bit = FIRST_RS_BIT_AFTER_IODNAV; + for (size_t i = 1; i < INAV_RS_SUBVECTOR_LENGTH; i++) + { + gamma_octet_bits[0] = std::pair({start_bit, BITS_IN_OCTET}); + gamma_rs2[i] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + start_bit += BITS_IN_OCTET; + } + break; + } + + case 20: // Word type 20: FEC2 Reed-Solomon for CED + { + std::vector> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}}); + gamma_rs3[0] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + IODnav_LSB20 = static_cast(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS)); + DLOG(INFO) << "IODnav 2 LSBs in Word type 20: " << static_cast(IODnav_LSB20); + int32_t start_bit = FIRST_RS_BIT_AFTER_IODNAV; + for (size_t i = 1; i < INAV_RS_SUBVECTOR_LENGTH; i++) + { + gamma_octet_bits[0] = std::pair({start_bit, BITS_IN_OCTET}); + gamma_rs3[i] = static_cast(read_navigation_unsigned(data_jk_bits, gamma_octet_bits)); + start_bit += BITS_IN_OCTET; + } + break; + } + case 0: // Word type 0: I/NAV Spare Word Time_0 = static_cast(read_navigation_unsigned(data_jk_bits, TIME_0_BIT)); DLOG(INFO) << "Time_0= " << Time_0; diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index c06c59647..b5defdd34 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -78,6 +78,11 @@ public: */ bool have_new_almanac(); + /* + * \brief Returns true if new Reduced CED parameters have arrived. The flag is set to false when the function is executed + */ + bool have_new_reduced_ced(); + /* * \brief Returns a Galileo_Ephemeris object filled with the latest navigation data received */ @@ -98,6 +103,11 @@ public: */ Galileo_Almanac_Helper get_almanac() const; + /* + * \brief Returns a Galileo_Ephemeris object filled with the latest reduced CED received + */ + Galileo_Ephemeris get_reduced_ced() const; + inline bool get_flag_CRC_test() const { return flag_CRC_test; @@ -173,12 +183,20 @@ public: return WN_0G_10; } + /* + * \brief Initialize PRN field so we do not need to wait for page 4. + */ + inline void init_PRN(uint32_t prn) + { + SV_ID_PRN_4 = prn; + } + private: bool CRC_test(std::bitset bits, uint32_t checksum) const; - bool read_navigation_bool(std::bitset bits, const std::vector >& parameter) const; - uint64_t read_navigation_unsigned(std::bitset bits, const std::vector >& parameter) const; - uint64_t read_page_type_unsigned(std::bitset bits, const std::vector >& parameter) const; - int64_t read_navigation_signed(std::bitset bits, const std::vector >& parameter) const; + bool read_navigation_bool(std::bitset bits, const std::vector>& parameter) const; + uint64_t read_navigation_unsigned(std::bitset bits, const std::vector>& parameter) const; + uint64_t read_page_type_unsigned(std::bitset bits, const std::vector>& parameter) const; + int64_t read_navigation_signed(std::bitset bits, const std::vector>& parameter) const; std::string page_Even{}; @@ -321,6 +339,27 @@ private: int32_t WN_0{}; int32_t TOW_0{}; + // Word type 16: Reduced Clock and Ephemeris Data (CED) parameters + double ced_DeltaAred{}; + double ced_exred{}; + double ced_eyred{}; + double ced_Deltai0red{}; + double ced_Omega0red{}; + double ced_lambda0red{}; + double ced_af0red{}; + double ced_af1red{}; + + // Word types 17, 18, 19, 20: Reed-Solomon parity vector + std::vector gamma_rs0{INAV_RS_SUBVECTOR_LENGTH, 0}; + std::vector gamma_rs1{INAV_RS_SUBVECTOR_LENGTH, 0}; + std::vector gamma_rs2{INAV_RS_SUBVECTOR_LENGTH, 0}; + std::vector gamma_rs3{INAV_RS_SUBVECTOR_LENGTH, 0}; + std::vector rs_parity_vector{INAV_RS_PARITY_VECTOR_LENGTH, 0}; + uint8_t IODnav_LSB17{}; + uint8_t IODnav_LSB18{}; + uint8_t IODnav_LSB19{}; + uint8_t IODnav_LSB20{}; + double Galileo_satClkDrift{}; bool flag_CRC_test{}; @@ -346,6 +385,8 @@ private: bool flag_GGTO_2{}; bool flag_GGTO_3{}; bool flag_GGTO_4{}; + + bool flag_CED{}; }; diff --git a/src/core/system_parameters/galileo_reduced_ced.cc b/src/core/system_parameters/galileo_reduced_ced.cc new file mode 100644 index 000000000..30f316c9f --- /dev/null +++ b/src/core/system_parameters/galileo_reduced_ced.cc @@ -0,0 +1,56 @@ +/*! + * \file galileo_reduced_ced.cc + * \brief Galileo Reduced Clock and Ephemeris Data storage class + * \author Carles Fernandez, 2021. cfernandez(at)cttc.cat + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + +#include "galileo_reduced_ced.h" +#include "MATH_CONSTANTS.h" +#include + + +Galileo_Ephemeris Galileo_Reduced_CED::compute_eph() const +{ + Galileo_Ephemeris eph{}; + + const double A_nominal = 29600000; // meters (Table 1 Galileo ICD 2.0) + const double Ared = DeltaAred + A_nominal; + eph.sqrtA = std::sqrt(Ared); // Square root of the semi-major axis [meters^1/2] + const double i_nominal = 56.0; // degrees (Table 1 Galileo ICD 2.0) + const double i0red = Deltai0red + i_nominal / 180.0; + eph.i_0 = i0red; // Inclination angle at reference time [semi-circles] + eph.ecc = std::sqrt(exred * exred + eyred * eyred); // Eccentricity + const double omega_semicircles = std::atan2(eyred, exred) / GNSS_PI; + eph.omega = omega_semicircles; // Argument of perigee [semi-circles] + eph.M_0 = lambda0red - omega_semicircles; // Mean anomaly at reference time [semi-circles] + eph.OMEGA_0 = Omega0red; // Longitude of ascending node of orbital plane at weekly epoch [semi-circles] + + eph.flag_all_ephemeris = true; + eph.IOD_ephemeris = IODnav; + eph.IOD_nav = IODnav; + eph.PRN = PRN; + + int32_t t0r = (30 * (TOTRedCED / 30) + 1) % 604800; + eph.toe = t0r; // Ephemeris reference time [s] + + // Clock correction parameters + eph.toc = t0r; // Clock correction data reference Time of Week [sec] + eph.af0 = af0red; // SV clock bias correction coefficient [s] + eph.af1 = af1red; // SV clock drift correction coefficient [s/s] + + // GST + eph.WN = TOTRedCED / 604800; // Week number + eph.tow = TOTRedCED % 604800; // Time of Week + + return eph; +} diff --git a/src/core/system_parameters/galileo_reduced_ced.h b/src/core/system_parameters/galileo_reduced_ced.h new file mode 100644 index 000000000..edd20c9c3 --- /dev/null +++ b/src/core/system_parameters/galileo_reduced_ced.h @@ -0,0 +1,62 @@ +/*! + * \file galileo_reduced_ced.h + * \brief Galileo Reduced Clock and Ephemeris Data storage class + * \author Carles Fernandez, 2021. cfernandez(at)cttc.cat + * + * ----------------------------------------------------------------------------- + * + * GNSS-SDR is a Global Navigation Satellite System software-defined receiver. + * This file is part of GNSS-SDR. + * + * Copyright (C) 2010-2021 (see AUTHORS file for a list of contributors) + * SPDX-License-Identifier: GPL-3.0-or-later + * + * ----------------------------------------------------------------------------- + */ + + +#ifndef GNSS_SDR_GALILEO_REDUCED_CED_H +#define GNSS_SDR_GALILEO_REDUCED_CED_H + +#include "galileo_ephemeris.h" +#include + +/** \addtogroup Core + * \{ */ +/** \addtogroup System_Parameters + * \{ */ + + +/*! + * \brief This class manages the Galileo Reduced Clock and Ephemeris Data + */ +class Galileo_Reduced_CED +{ +public: + /*! + * Default constructor + */ + Galileo_Reduced_CED() = default; + + /*! + * Convert to Galileo_Ephemeris + */ + Galileo_Ephemeris compute_eph() const; + + uint32_t PRN{}; //!< Satellite ID + int32_t TOTRedCED{}; //!< Start time of transmission of the Reduced CED word in GST + int32_t IODnav{}; //!< Issue of Data + double DeltaAred{}; //!< Difference between the Reduced CED semi-major axis and the nominal semi-major axis [meters] + double exred{}; //!< Reduced CED eccentricity vector component x + double eyred{}; //!< Reduced CED eccentricity vector component y + double Deltai0red{}; //!< Difference between the Reduced CED inclination angle at reference time and the nominal inclination [semi-circles] + double Omega0red{}; //!< Reduced CED longitude of ascending node at weekly epoch [semi-circles] + double lambda0red{}; //!< Reduced CED mean argument of latitude [semi-circles] + double af0red{}; //!< Reduced CED satellite clock bias correction coefficient [seconds] + double af1red{}; //!< Reduced CED satellite clock drift correction coefficient [seconds/seconds] +}; + + +/** \} */ +/** \} */ +#endif // GNSS_SDR_GALILEO_REDUCED_CED_H diff --git a/src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc b/src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc index 6f856bf99..9c1e4a243 100644 --- a/src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc +++ b/src/tests/unit-tests/system-parameters/galileo_e1b_reed_solomon_test.cc @@ -79,7 +79,7 @@ TEST(ReedSolomonE1BTest, EncodeWithCustomMatrix) const int nroots = 60; const int minpoly = 29; const int prim = 1; - const int fcr = 1; + const int fcr = 195; const int pad = 0; const int shortening = 137; const std::vector genpoly_coeff;