Fix XB wrap-around in GPS L5 I5/Q5 code replicas. Fixes #1151

This commit is contained in:
Carles Fernandez
2026-10-19 18:06:37 +02:00
parent 856f8ad0b3
commit d60ddcbef8
3 changed files with 17 additions and 6 deletions
+10
View File
@@ -14,6 +14,16 @@ All notable changes to GNSS-SDR will be documented in this file.
## [Unreleased](https://github.com/gnss-sdr/gnss-sdr/tree/next)
### Improvements in Availability:
- Fixed the GPS L5 I5 and Q5 local code replicas. The XB sequence was wrapped
modulo the 10230-chip code length instead of its natural 8191-chip period
(IS-GPS-705J, Section 3.3.2.2), so the last chips of every code (as many as
its XB code advance) were taken from the wrong XB phase. Depending on the PRN,
this cost between 0.2 and 13.5 dB (about 5 dB on average) of correlation gain
in acquisition and tracking, also in FPGA-offloaded receivers. Reported by
@ObvMamut.
### Improvements in Efficiency:
- Improved Signal Conditioner scheduling with portable, configuration-aware
+6 -6
View File
@@ -78,9 +78,9 @@ std::deque<bool> make_l5i_xa()
std::deque<bool> make_l5i_xb()
{
std::deque<bool> xb = {true, true, true, true, true, true, true, true, true, true, true, true, true};
std::deque<bool> y(GPS_L5I_CODE_LENGTH_CHIPS, false);
std::deque<bool> y(GPS_L5_XB_CODE_LENGTH_CHIPS, false);
for (int32_t i = 0; i < GPS_L5I_CODE_LENGTH_CHIPS; i++)
for (int32_t i = 0; i < GPS_L5_XB_CODE_LENGTH_CHIPS; i++)
{
y[i] = xb[12];
xb = l5i_xb_shift(xb);
@@ -106,9 +106,9 @@ std::deque<bool> make_l5q_xa()
std::deque<bool> make_l5q_xb()
{
std::deque<bool> xb = {true, true, true, true, true, true, true, true, true, true, true, true, true};
std::deque<bool> y(GPS_L5Q_CODE_LENGTH_CHIPS, false);
std::deque<bool> y(GPS_L5_XB_CODE_LENGTH_CHIPS, false);
for (int32_t i = 0; i < GPS_L5Q_CODE_LENGTH_CHIPS; i++)
for (int32_t i = 0; i < GPS_L5_XB_CODE_LENGTH_CHIPS; i++)
{
y[i] = xb[12];
xb = l5q_xb_shift(xb);
@@ -127,7 +127,7 @@ void make_l5i(own::span<int32_t> dest, int32_t prn)
for (int32_t n = 0; n < GPS_L5I_CODE_LENGTH_CHIPS; n++)
{
xb_shift[n] = xb[(xb_offset + n) % GPS_L5I_CODE_LENGTH_CHIPS];
xb_shift[n] = xb[(xb_offset + n) % GPS_L5_XB_CODE_LENGTH_CHIPS];
}
for (int32_t n = 0; n < GPS_L5I_CODE_LENGTH_CHIPS; n++)
@@ -147,7 +147,7 @@ void make_l5q(own::span<int32_t> dest, int32_t prn)
for (int32_t n = 0; n < GPS_L5Q_CODE_LENGTH_CHIPS; n++)
{
xb_shift[n] = xb[(xb_offset + n) % GPS_L5Q_CODE_LENGTH_CHIPS];
xb_shift[n] = xb[(xb_offset + n) % GPS_L5_XB_CODE_LENGTH_CHIPS];
}
for (int32_t n = 0; n < GPS_L5Q_CODE_LENGTH_CHIPS; n++)
+1
View File
@@ -168,6 +168,7 @@ constexpr int32_t GPS_L5I_NH_CODE_LENGTH = 10;
constexpr int32_t GPS_L5I_NH_CODE[10] = {0, 0, 0, 0, 1, 1, 0, 1, 0, 1};
constexpr int32_t GPS_L5Q_NH_CODE_LENGTH = 20;
constexpr int32_t GPS_L5Q_NH_CODE[20] = {0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0};
constexpr int32_t GPS_L5_XB_CODE_LENGTH_CHIPS = 8191;
constexpr char GPS_L5I_NH_CODE_STR[11] = "0000110101";
constexpr char GPS_L5Q_NH_CODE_STR[21] = "00000100110101001110";