From cec340f4aaaa22c28a11ee8fd49ff1bbf3251cf3 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 17 Jul 2026 20:49:00 +0200 Subject: [PATCH] Propagate broadcast SISA and NAPA to PVT --- src/algorithms/libs/rtklib/rtklib.h | 2 +- .../libs/rtklib/rtklib_conversions.cc | 1 + .../libs/rtklib/rtklib_ephemeris.cc | 48 ++++++++++++++++++- src/algorithms/libs/rtklib/rtklib_ephemeris.h | 1 + .../system_parameters/galileo_ephemeris.h | 2 +- .../system_parameters/galileo_fnav_message.cc | 1 + 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/algorithms/libs/rtklib/rtklib.h b/src/algorithms/libs/rtklib/rtklib.h index 96ddd6d6f..4c4fd6ac1 100644 --- a/src/algorithms/libs/rtklib/rtklib.h +++ b/src/algorithms/libs/rtklib/rtklib.h @@ -434,7 +434,7 @@ typedef struct { /* GPS/QZS/GAL broadcast ephemeris type */ int sat; /* satellite number */ int iode, iodc; /* IODE,IODC */ - int sva; /* SV accuracy (URA index) */ + int sva; /* SV accuracy (URA index, GAL: SISA index) */ int svh; /* SV health (0:ok) */ int week; /* GPS/QZS: gps week, GAL: galileo week */ int code; /* GPS/QZS: code on L2, GAL/BDS: data sources */ diff --git a/src/algorithms/libs/rtklib/rtklib_conversions.cc b/src/algorithms/libs/rtklib/rtklib_conversions.cc index e5c0afbd1..f182835ae 100644 --- a/src/algorithms/libs/rtklib/rtklib_conversions.cc +++ b/src/algorithms/libs/rtklib/rtklib_conversions.cc @@ -430,6 +430,7 @@ eph_t eph_to_rtklib(const Galileo_Ephemeris& gal_eph, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, {}, {}, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, false, 0, 0, 0, 0, 0.0, -1, 0}; // Galileo is the third satellite system for RTKLIB, so, add the required offset to discriminate Galileo ephemeris rtklib_sat.sat = gal_eph.PRN + NSATGPS + NSATGLO; + rtklib_sat.sva = gal_eph.SISA; rtklib_sat.A = gal_eph.sqrtA * gal_eph.sqrtA; rtklib_sat.M0 = gal_eph.M_0; rtklib_sat.deln = gal_eph.delta_n; diff --git a/src/algorithms/libs/rtklib/rtklib_ephemeris.cc b/src/algorithms/libs/rtklib/rtklib_ephemeris.cc index 197105adc..30941edd6 100644 --- a/src/algorithms/libs/rtklib/rtklib_ephemeris.cc +++ b/src/algorithms/libs/rtklib/rtklib_ephemeris.cc @@ -77,6 +77,41 @@ double var_uraeph(int ura) } +/* variance by galileo sisa ephemeris (OS SIS ICD, table 91) ----------------*/ +double var_sisaeph(int sisa) +{ + double sisa_m; + if (sisa == -1) + { + // Reduced CED does not contain SISA. Retain RTKLIB's default + // broadcast-ephemeris accuracy when no index was supplied. + sisa_m = 2.4; + } + else if (sisa < 0 || sisa > 125) + { + // Spare values and NAPA (255) provide no usable accuracy prediction. + sisa_m = 6144.0; + } + else if (sisa <= 49) + { + sisa_m = static_cast(sisa) * 0.01; + } + else if (sisa <= 74) + { + sisa_m = 0.50 + static_cast(sisa - 50) * 0.02; + } + else if (sisa <= 99) + { + sisa_m = 1.00 + static_cast(sisa - 75) * 0.04; + } + else + { + sisa_m = 2.00 + static_cast(sisa - 100) * 0.16; + } + return std::pow(sisa_m, 2.0); +} + + static double cnav_ura_upper_bound_m(int ura_index) { switch (ura_index) @@ -517,7 +552,18 @@ void eph2pos(gtime_t time, const eph_t *eph, double *rs, double *dts, } /* position and clock error variance */ - *var = eph->cnav_ura_valid ? std::pow(cnav_uraeph(time, eph), 2.0) : var_uraeph(eph->sva); + if (eph->cnav_ura_valid) + { + *var = std::pow(cnav_uraeph(time, eph), 2.0); + } + else if (satsys(eph->sat, nullptr) == SYS_GAL) + { + *var = var_sisaeph(eph->sva); + } + else + { + *var = var_uraeph(eph->sva); + } } diff --git a/src/algorithms/libs/rtklib/rtklib_ephemeris.h b/src/algorithms/libs/rtklib/rtklib_ephemeris.h index 7a6565045..1a09199d6 100644 --- a/src/algorithms/libs/rtklib/rtklib_ephemeris.h +++ b/src/algorithms/libs/rtklib/rtklib_ephemeris.h @@ -38,6 +38,7 @@ double var_uraeph(int ura); +double var_sisaeph(int sisa); double var_urassr(int ura); void alm2pos(gtime_t time, const alm_t *alm, double *rs, double *dts); double eph2clk(gtime_t time, const eph_t *eph); diff --git a/src/core/system_parameters/galileo_ephemeris.h b/src/core/system_parameters/galileo_ephemeris.h index 1b23c0b6e..6482a52e7 100644 --- a/src/core/system_parameters/galileo_ephemeris.h +++ b/src/core/system_parameters/galileo_ephemeris.h @@ -50,7 +50,7 @@ public: int32_t IOD_nav{}; // SV status - int32_t SISA{}; //!< Signal in space accuracy index + int32_t SISA{-1}; //!< Signal in space accuracy index (-1 if unavailable in the source data) int32_t E5a_HS{}; //!< E5a Signal Health Status int32_t E5b_HS{}; //!< E5b Signal Health Status int32_t E1B_HS{}; //!< E1B Signal Health Status diff --git a/src/core/system_parameters/galileo_fnav_message.cc b/src/core/system_parameters/galileo_fnav_message.cc index 2fa9a708d..674ad4e23 100644 --- a/src/core/system_parameters/galileo_fnav_message.cc +++ b/src/core/system_parameters/galileo_fnav_message.cc @@ -407,6 +407,7 @@ Galileo_Ephemeris Galileo_Fnav_Message::get_ephemeris() const ephemeris.af0 = FNAV_af0_1; // SV clock bias correction coefficient [s] ephemeris.af1 = FNAV_af1_1; // SV clock drift correction coefficient [s/s] ephemeris.af2 = FNAV_af2_1; // SV clock drift rate correction coefficient [s/s^2] + ephemeris.SISA = FNAV_SISA_1; // Signal In Space Accuracy index ephemeris.BGD_E1E5a = FNAV_BGD_1; // E1-E5a Broadcast Group Delay [s] // GST