Fix Galileo reduced CED handling

This commit is contained in:
Carles Fernandez
2026-07-19 10:10:56 +02:00
parent 4ca75aaa6e
commit a7e72cd522
11 changed files with 387 additions and 144 deletions
@@ -417,7 +417,7 @@ 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
if (flag_CED == true)
{
flag_CED = false;
return true;
@@ -592,30 +592,10 @@ Galileo_Almanac_Helper Galileo_Inav_Message::get_almanac() const
}
Galileo_Ephemeris Galileo_Inav_Message::get_reduced_ced() const
Galileo_Reduced_CED Galileo_Inav_Message::get_reduced_ced() const
{
Galileo_Reduced_CED ced{};
ced.PRN = SV_ID_PRN_4;
// From ICD: TOTRedCED is the start time of transmission of the
// Reduced CED word 16 in GST
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;
@@ -624,10 +604,13 @@ Galileo_Ephemeris Galileo_Inav_Message::get_reduced_ced() const
ced.lambda0red = ced_lambda0red;
ced.af0red = ced_af0red;
ced.af1red = ced_af1red;
ced.BGD_E1E5b = BGD_E1E5b_5;
ced.E5b_HS = E5b_HS_5;
ced.E1B_HS = E1B_HS_5;
ced.E5b_DVS = E5b_DVS_5;
ced.E1B_DVS = E1B_DVS_5;
Galileo_Ephemeris eph = ced.compute_eph();
return eph;
return ced;
}
@@ -1061,7 +1044,8 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
spare_5 = static_cast<double>(read_navigation_unsigned(data_jk_bits, SPARE_5_BIT));
DLOG(INFO) << "spare_5= " << spare_5;
flag_iono_and_GST = true; // set to false externally
flag_TOW_set = true; // set to false externally
flag_word_5_received = true;
flag_TOW_set = true; // set to false externally
DLOG(INFO) << "flag_tow_set" << flag_TOW_set;
nav_bits_word_5 = data_jk_bits.to_string().substr(6, 67);
break;
@@ -24,6 +24,7 @@
#include "galileo_ephemeris.h"
#include "galileo_iono.h"
#include "galileo_ism.h"
#include "galileo_reduced_ced.h"
#include "galileo_utc_model.h"
#include "gnss_sdr_make_unique.h" // for std::unique_ptr in C++11
#include <array>
@@ -129,9 +130,17 @@ public:
Galileo_Almanac_Helper get_almanac() const;
/*
* \brief Returns a Galileo_Ephemeris object filled with the latest reduced CED received
* \brief Returns a Galileo_Reduced_CED object filled with the latest Word 16 and Word 5 data received
*/
Galileo_Ephemeris get_reduced_ced() const;
Galileo_Reduced_CED get_reduced_ced() const;
/*
* \brief Returns true after a CRC-valid Word 5 has been received for the current satellite.
*/
inline bool has_valid_word_5() const
{
return flag_word_5_received;
}
/*
* \brief Returns a Galileo_ISMs object filled with the latest ISM data received
@@ -259,6 +268,8 @@ public:
inline void init_PRN(uint32_t prn)
{
SV_ID_PRN_4 = prn;
flag_CED = false;
flag_word_5_received = false;
nma_msg.PRN = prn;
nma_msg.mack = std::array<uint32_t, 15>{};
nma_msg.hkroot = std::array<uint8_t, 15>{};
@@ -482,7 +493,8 @@ private:
bool flag_ephemeris_3{}; // Flag indicating that ephemeris 3/4 (word 3) have been received
bool flag_ephemeris_4{}; // Flag indicating that ephemeris 4/4 (word 4) have been received
bool flag_iono_and_GST{}; // Flag indicating that ionospheric and GST parameters (word 5) have been received
bool flag_iono_and_GST{}; // Flag indicating that ionospheric and GST parameters (word 5) have been received
bool flag_word_5_received{}; // Persistent Word 5 validity for Reduced CED auxiliary data
bool flag_TOW_5{};
bool flag_TOW_6{};
bool flag_TOW_0{};
@@ -34,12 +34,13 @@ Galileo_Ephemeris Galileo_Reduced_CED::compute_eph() const
eph.M_0 = lambda0red * GNSS_PI - eph.omega; // Mean anomaly at reference time [rad]
eph.OMEGA_0 = Omega0red * GNSS_PI; // Longitude of ascending node of orbital plane at weekly epoch [rad]
eph.flag_all_ephemeris = true;
eph.IOD_ephemeris = IODnav;
eph.IOD_nav = IODnav;
// Word 16 has no IODnav and is not a full-precision ephemeris set.
eph.flag_all_ephemeris = false;
eph.IOD_ephemeris = -1;
eph.IOD_nav = -1;
eph.PRN = PRN;
int32_t t0r = (30 * (TOTRedCED / 30) + 1) % 604800;
const uint32_t t0r = reference_time();
eph.toe = t0r; // Ephemeris reference time [s]
// Clock correction parameters
@@ -48,8 +49,34 @@ Galileo_Ephemeris Galileo_Reduced_CED::compute_eph() const
eph.af1 = af1red; // SV clock drift correction coefficient [s/s]
// GST
eph.WN = TOTRedCED / 604800; // Week number
eph.tow = TOTRedCED % 604800; // Time of Week
eph.WN = WN;
eph.tow = TOTRedCED;
eph.BGD_E1E5b = BGD_E1E5b;
eph.E5b_HS = E5b_HS;
eph.E1B_HS = E1B_HS;
eph.E5b_DVS = E5b_DVS;
eph.E1B_DVS = E1B_DVS;
return eph;
}
uint32_t Galileo_Reduced_CED::reference_time() const
{
return (30U * (TOTRedCED / 30U) + 1U) % 604800U;
}
bool Galileo_Reduced_CED::is_valid_at(uint32_t week, uint32_t tow) const
{
if (TOTRedCED >= 604800U || tow >= 604800U)
{
return false;
}
const uint64_t reference_epoch = static_cast<uint64_t>(WN) * 604800ULL + reference_time();
const uint64_t observation_epoch = static_cast<uint64_t>(week) * 604800ULL + tow;
return observation_epoch >= reference_epoch &&
observation_epoch - reference_epoch < static_cast<uint64_t>(CED_VALIDITY_SECONDS);
}
@@ -43,17 +43,37 @@ public:
*/
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 [rad]
double Omega0red{}; //!< Reduced CED longitude of ascending node at weekly epoch [rad]
double lambda0red{}; //!< Reduced CED mean argument of latitude [rad]
double af0red{}; //!< Reduced CED satellite clock bias correction coefficient [seconds]
double af1red{}; //!< Reduced CED satellite clock drift correction coefficient [seconds/seconds]
/*!
* \brief Return true when this Reduced CED set is applicable at the given GST epoch.
*/
bool is_valid_at(uint32_t week, uint32_t tow) const;
/*!
* \brief Return the Reduced CED orbit and clock reference time of week.
*/
uint32_t reference_time() const;
static constexpr uint32_t CED_VALIDITY_SECONDS = 600U;
uint32_t PRN{}; //!< Satellite ID
uint32_t WN{}; //!< GST week containing the start of transmission
uint32_t TOTRedCED{}; //!< Start time of transmission of the Reduced CED word as GST TOW [s]
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 [rad]
double Omega0red{}; //!< Reduced CED longitude of ascending node at weekly epoch [rad]
double lambda0red{}; //!< Reduced CED mean argument of latitude [rad]
double af0red{}; //!< Reduced CED satellite clock bias correction coefficient [seconds]
double af1red{}; //!< Reduced CED satellite clock drift correction coefficient [seconds/seconds]
// Word 5 data used by the E1/E5b user algorithms. These are not combined
// with full-precision CED orbit or clock parameters.
double BGD_E1E5b{}; //!< E1-E5b Broadcast Group Delay [s]
int32_t E5b_HS{}; //!< E5b Signal Health Status
int32_t E1B_HS{}; //!< E1B Signal Health Status
bool E5b_DVS{}; //!< E5b Data Validity Status
bool E1B_DVS{}; //!< E1B Data Validity Status
};