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)
### Improvements in Portability:
### Improvements in Availability:
- 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.
- 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 <carles.fernandez@cttc
providing a common nomenclature for ephemeris' parameters. New generated XML
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:
- 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_state1.reserve(max_states);
d_inav_nav.init_PRN(d_satellite.get_PRN());
d_first_eph_sent = false;
// create appropriate transition matrices
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);
@ -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';
}
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)
{
// get object for this SV (mandatory)

View File

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

View File

@ -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

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;
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 */
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>> 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_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

View File

@ -17,6 +17,7 @@
*/
#include "galileo_inav_message.h"
#include "galileo_reduced_ced.h"
#include <boost/crc.hpp> // for boost::crc_basic, boost::crc_optimal
#include <boost/dynamic_bitset.hpp> // for boost::dynamic_bitset
#include <glog/logging.h> // for DLOG
@ -55,7 +56,7 @@ bool Galileo_Inav_Message::CRC_test(std::bitset<GALILEO_DATA_FRAME_BITS> bits, u
}
uint64_t Galileo_Inav_Message::read_navigation_unsigned(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const
uint64_t Galileo_Inav_Message::read_navigation_unsigned(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& 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<GALILEO_DATA
}
uint64_t Galileo_Inav_Message::read_page_type_unsigned(std::bitset<GALILEO_PAGE_TYPE_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const
uint64_t Galileo_Inav_Message::read_page_type_unsigned(std::bitset<GALILEO_PAGE_TYPE_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& 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<GALILEO_PAGE_
}
int64_t Galileo_Inav_Message::read_navigation_signed(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const
int64_t Galileo_Inav_Message::read_navigation_signed(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& 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<GALILEO_DATA_JK
}
bool Galileo_Inav_Message::read_navigation_bool(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const
bool Galileo_Inav_Message::read_navigation_bool(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const
{
bool value;
if (static_cast<int>(static_cast<int>(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<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)
{
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<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
Time_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, TIME_0_BIT));
DLOG(INFO) << "Time_0= " << Time_0;

View File

@ -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<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;
uint64_t read_navigation_unsigned(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const;
uint64_t read_page_type_unsigned(std::bitset<GALILEO_PAGE_TYPE_BITS> bits, const std::vector<std::pair<int32_t, int32_t> >& parameter) const;
int64_t read_navigation_signed(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;
uint64_t read_navigation_unsigned(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const;
uint64_t read_page_type_unsigned(std::bitset<GALILEO_PAGE_TYPE_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& parameter) const;
int64_t read_navigation_signed(std::bitset<GALILEO_DATA_JK_BITS> bits, const std::vector<std::pair<int32_t, int32_t>>& 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<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{};
bool flag_CRC_test{};
@ -346,6 +385,8 @@ private:
bool flag_GGTO_2{};
bool flag_GGTO_3{};
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