1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2025-01-07 07:50:32 +00:00

Implement reading of reduced CED data in Galileo E1B INAV message. Used if found

This commit is contained in:
Carles Fernandez 2021-04-09 15:00:58 +02:00
parent f4c7b43505
commit d4a9b6f316
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
10 changed files with 383 additions and 21 deletions

View File

@ -10,20 +10,13 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next) ## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Portability: ### Improvements in Availability:
- Avoid collision of the `cpu_features` library when installing the - Added the reading of reduced clock and ephemeris data (CED) in the Galileo E1B
`volk_gnsssdr` library by its own, and VOLK has already installed its version. INAV message introduced in Galileo ICD v2.0. If the reduced CED is available
Added a new building option `ENABLE_OWN_CPUFEATURES`, defaulting to `ON` when before the full ephemeris set, it is used for PVT computation until the full
building `gnss-sdr` but defaulting to `OFF` when building a stand-alone set has not yet been received. This can contribute to shorten the
version of `volk_gnsssdr`. When this building option is set to `ON`, it forces Time-To-First-Fix.
the building of the local version of the cpu_features library, regardless of
whether it is already installed or not.
- Fix building when using the Xcode generator, Xcode >= 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 `<filesystem>` library when using GCC 8.x and GNU Radio >=
3.8.
### Improvements in Maintainability: ### Improvements in Maintainability:
@ -46,6 +39,21 @@ SPDX-FileCopyrightText: 2011-2021 Carles Fernandez-Prades <carles.fernandez@cttc
providing a common nomenclature for ephemeris' parameters. New generated XML providing a common nomenclature for ephemeris' parameters. New generated XML
files make use of the new parameters' name. files make use of the new parameters' name.
### Improvements in Portability:
- Avoid collision of the `cpu_features` library when installing the
`volk_gnsssdr` library by its own, and VOLK has already installed its version.
Added a new building option `ENABLE_OWN_CPUFEATURES`, defaulting to `ON` when
building `gnss-sdr` but defaulting to `OFF` when building a stand-alone
version of `volk_gnsssdr`. When this building option is set to `ON`, it forces
the building of the local version of the cpu_features library, regardless of
whether it is already installed or not.
- Fix building when using the Xcode generator, Xcode >= 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 `<filesystem>` library when using GCC 8.x and GNU Radio >=
3.8.
### Improvements in Usability: ### Improvements in Usability:
- Avoid segmentation faults in the flow graph connection and/or starting due to - Avoid segmentation faults in the flow graph connection and/or starting due to

View File

@ -208,6 +208,9 @@ galileo_telemetry_decoder_gs::galileo_telemetry_decoder_gs(
d_state0.reserve(max_states); d_state0.reserve(max_states);
d_state1.reserve(max_states); d_state1.reserve(max_states);
d_inav_nav.init_PRN(d_satellite.get_PRN());
d_first_eph_sent = false;
// create appropriate transition matrices // create appropriate transition matrices
nsc_transit(d_out0.data(), d_state0.data(), 0, g_encoder.data(), d_KK, d_nn); nsc_transit(d_out0.data(), d_state0.data(), 0, g_encoder.data(), d_KK, d_nn);
nsc_transit(d_out1.data(), d_state1.data(), 1, g_encoder.data(), d_KK, d_nn); nsc_transit(d_out1.data(), d_state1.data(), 1, g_encoder.data(), d_KK, d_nn);
@ -354,7 +357,19 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << '\n'; std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel " << d_channel << ": ephemeris from satellite " << d_satellite << TEXT_RESET << '\n';
} }
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); this->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<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(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) if (d_inav_nav.have_new_iono_and_GST() == true)
{ {
// get object for this SV (mandatory) // get object for this SV (mandatory)

View File

@ -139,6 +139,7 @@ private:
bool d_dump; bool d_dump;
bool d_dump_mat; bool d_dump_mat;
bool d_remove_dat; bool d_remove_dat;
bool d_first_eph_sent;
}; };

View File

@ -17,6 +17,7 @@ set(SYSTEM_PARAMETERS_SOURCES
galileo_cnav_message.cc galileo_cnav_message.cc
galileo_fnav_message.cc galileo_fnav_message.cc
galileo_inav_message.cc galileo_inav_message.cc
galileo_reduced_ced.cc
beidou_dnav_navigation_message.cc beidou_dnav_navigation_message.cc
beidou_dnav_ephemeris.cc beidou_dnav_ephemeris.cc
sbas_ephemeris.cc sbas_ephemeris.cc
@ -52,6 +53,7 @@ set(SYSTEM_PARAMETERS_HEADERS
galileo_fnav_message.h galileo_fnav_message.h
galileo_has_data.h galileo_has_data.h
galileo_inav_message.h galileo_inav_message.h
galileo_reduced_ced.h
sbas_ephemeris.h sbas_ephemeris.h
gps_cnav_ephemeris.h gps_cnav_ephemeris.h
gps_cnav_navigation_message.h gps_cnav_navigation_message.h

View File

@ -245,12 +245,44 @@ const std::vector<std::pair<int32_t, int32_t>> T_0_G_10_BIT({{115, 8}});
constexpr int32_t T_0_G_10_LSB = 3600; constexpr int32_t T_0_G_10_LSB = 3600;
const std::vector<std::pair<int32_t, int32_t>> WN_0_G_10_BIT({{123, 6}}); const std::vector<std::pair<int32_t, int32_t>> WN_0_G_10_BIT({{123, 6}});
/* Page 16 */
constexpr double CED_DeltaAred_LSB = TWO_P8;
const std::vector<std::pair<int32_t, int32_t>> CED_DeltaAred_BIT({{7, 5}});
constexpr double CED_exred_LSB = TWO_N22;
const std::vector<std::pair<int32_t, int32_t>> CED_exred_BIT({{12, 13}});
constexpr double CED_eyred_LSB = TWO_N22;
const std::vector<std::pair<int32_t, int32_t>> CED_eyred_BIT({{25, 13}});
constexpr double CED_Deltai0red_LSB = TWO_N22;
const std::vector<std::pair<int32_t, int32_t>> CED_Deltai0red_BIT({{38, 17}});
constexpr double CED_Omega0red_LSB = TWO_N22;
const std::vector<std::pair<int32_t, int32_t>> CED_Omega0red_BIT({{55, 23}});
constexpr double CED_lambda0red_LSB = TWO_N22;
const std::vector<std::pair<int32_t, int32_t>> CED_lambda0red_BIT({{78, 23}});
constexpr double CED_af0red_LSB = TWO_N26;
const std::vector<std::pair<int32_t, int32_t>> CED_af0red_BIT({{101, 22}});
constexpr double CED_af1red_LSB = TWO_N35;
const std::vector<std::pair<int32_t, int32_t>> CED_af1red_BIT({{123, 6}});
/* Pages 17, 18, 19, 20 */
const std::vector<std::pair<int32_t, int32_t>> 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 */ /* Page 0 */
const std::vector<std::pair<int32_t, int32_t>> TIME_0_BIT({{7, 2}}); const std::vector<std::pair<int32_t, int32_t>> TIME_0_BIT({{7, 2}});
const std::vector<std::pair<int32_t, int32_t>> WN_0_BIT({{97, 12}}); const std::vector<std::pair<int32_t, int32_t>> WN_0_BIT({{97, 12}});
const std::vector<std::pair<int32_t, int32_t>> TOW_0_BIT({{109, 20}}); const std::vector<std::pair<int32_t, int32_t>> 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";
/** \} */ /** \} */
/** \} */ /** \} */

View File

@ -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_P3 = 8.0; //!< 2^3
constexpr double TWO_P4 = 16.0; //!< 2^4 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_P11 = 2048.0; //!< 2^11
constexpr double TWO_P12 = 4096.0; //!< 2^12 constexpr double TWO_P12 = 4096.0; //!< 2^12
constexpr double TWO_P14 = 16384.0; //!< 2^14 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_N19 = 1.907348632812500e-006; //!< 2^-19
constexpr double TWO_N20 = 9.536743164062500e-007; //!< 2^-20 constexpr double TWO_N20 = 9.536743164062500e-007; //!< 2^-20
constexpr double TWO_N21 = 4.768371582031250e-007; //!< 2^-21 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_N23 = 1.192092895507810e-007; //!< 2^-23
constexpr double TWO_N24 = 5.960464477539063e-008; //!< 2^-24 constexpr double TWO_N24 = 5.960464477539063e-008; //!< 2^-24
constexpr double TWO_N25 = 2.980232238769531e-008; //!< 2^-25 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_N27 = 7.450580596923828e-009; //!< 2^-27
constexpr double TWO_N29 = 1.862645149230957e-009; //!< 2^-29 constexpr double TWO_N29 = 1.862645149230957e-009; //!< 2^-29
constexpr double TWO_N30 = 9.313225746154785e-010; //!< 2^-30 constexpr double TWO_N30 = 9.313225746154785e-010; //!< 2^-30

View File

@ -17,6 +17,7 @@
*/ */
#include "galileo_inav_message.h" #include "galileo_inav_message.h"
#include "galileo_reduced_ced.h"
#include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal #include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal
#include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset #include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset
#include <glog/logging.h> // for DLOG #include <glog/logging.h> // for DLOG
@ -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 Galileo_Inav_Message::get_ephemeris() const
{ {
Galileo_Ephemeris ephemeris; 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<int32_t, 4> 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) int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
{ {
const std::string data_jk_string = 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; DLOG(INFO) << "flag_tow_set" << flag_TOW_set;
break; break;
case 16: // Word type 16: Reduced Clock and Ephemeris Data (CED) parameters
DLOG(INFO) << "Word type 16 arrived";
ced_DeltaAred = static_cast<double>(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<double>(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<double>(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<double>(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<double>(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<double>(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<double>(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<double>(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<std::pair<int32_t, int32_t>> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}});
gamma_rs0[0] = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, gamma_octet_bits));
IODnav_LSB17 = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS));
DLOG(INFO) << "IODnav 2 LSBs in Word type 17: " << static_cast<float>(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<int32_t, int32_t>({start_bit, BITS_IN_OCTET});
gamma_rs0[i] = static_cast<uint8_t>(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<std::pair<int32_t, int32_t>> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}});
gamma_rs1[0] = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, gamma_octet_bits));
IODnav_LSB18 = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS));
DLOG(INFO) << "IODnav 2 LSBs in Word type 18: " << static_cast<float>(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<int32_t, int32_t>({start_bit, BITS_IN_OCTET});
gamma_rs1[i] = static_cast<uint8_t>(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<std::pair<int32_t, int32_t>> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}});
gamma_rs2[0] = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, gamma_octet_bits));
IODnav_LSB19 = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS));
DLOG(INFO) << "IODnav 2 LSBs in Word type 19: " << static_cast<float>(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<int32_t, int32_t>({start_bit, BITS_IN_OCTET});
gamma_rs2[i] = static_cast<uint8_t>(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<std::pair<int32_t, int32_t>> gamma_octet_bits({{FIRST_RS_BIT, BITS_IN_OCTET}});
gamma_rs3[0] = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, gamma_octet_bits));
IODnav_LSB20 = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, RS_IODNAV_LSBS));
DLOG(INFO) << "IODnav 2 LSBs in Word type 20: " << static_cast<float>(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<int32_t, int32_t>({start_bit, BITS_IN_OCTET});
gamma_rs3[i] = static_cast<uint8_t>(read_navigation_unsigned(data_jk_bits, gamma_octet_bits));
start_bit += BITS_IN_OCTET;
}
break;
}
case 0: // Word type 0: I/NAV Spare Word case 0: // Word type 0: I/NAV Spare Word
Time_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, TIME_0_BIT)); Time_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, TIME_0_BIT));
DLOG(INFO) << "Time_0= " << Time_0; DLOG(INFO) << "Time_0= " << Time_0;

View File

@ -78,6 +78,11 @@ public:
*/ */
bool have_new_almanac(); 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 * \brief Returns a Galileo_Ephemeris object filled with the latest navigation data received
*/ */
@ -98,6 +103,11 @@ public:
*/ */
Galileo_Almanac_Helper get_almanac() const; 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 inline bool get_flag_CRC_test() const
{ {
return flag_CRC_test; return flag_CRC_test;
@ -173,6 +183,14 @@ public:
return WN_0G_10; 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: private:
bool CRC_test(std::bitset<GALILEO_DATA_FRAME_BITS> bits, uint32_t checksum) const; bool CRC_test(std::bitset<GALILEO_DATA_FRAME_BITS> bits, uint32_t checksum) const;
bool read_navigation_bool(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const; bool read_navigation_bool(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const;
@ -321,6 +339,27 @@ private:
int32_t WN_0{}; int32_t WN_0{};
int32_t TOW_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<uint8_t> gamma_rs0{INAV_RS_SUBVECTOR_LENGTH, 0};
std::vector<uint8_t> gamma_rs1{INAV_RS_SUBVECTOR_LENGTH, 0};
std::vector<uint8_t> gamma_rs2{INAV_RS_SUBVECTOR_LENGTH, 0};
std::vector<uint8_t> gamma_rs3{INAV_RS_SUBVECTOR_LENGTH, 0};
std::vector<uint8_t> 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{}; double Galileo_satClkDrift{};
bool flag_CRC_test{}; bool flag_CRC_test{};
@ -346,6 +385,8 @@ private:
bool flag_GGTO_2{}; bool flag_GGTO_2{};
bool flag_GGTO_3{}; bool flag_GGTO_3{};
bool flag_GGTO_4{}; bool flag_GGTO_4{};
bool flag_CED{};
}; };

View File

@ -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 <cmath>
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;
}

View File

@ -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 <cstdint>
/** \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