Dear Mr. Takasu,
I hope you are doing well.
I would like to report a GPS week-number unwrapping problem that appears
when pocket_trk is used to replay an IF recording whose signal time is
only a few weeks away from the host PC clock.
Symptom
On IF replay, GPS/QZS LNAV ephemerides are decoded (nav count increases)
but the satellites are never used in PVT. toe is rejected by the 2 h
MAXDTOE check in seleph(). The stored eph week is 1024 weeks (about 19
years) off.
Cause
decode_frame() expands the 10-bit LNAV week with adjgpsweek(), which
uses the host CPU time:
return week + (w - week + 1) / 1024 * 1024;
The +1 bias does not pick the nearest 1024-week era. If the 10-bit WN
is only a few weeks ahead of the host GPS week, integer division falls
into the previous era.
Numerical example (August 2026, host GPS week ~2432, SF1 WN = 390):
ch->week = 390 + 2048 = 2438 (signal time, GPST_OFF_W)
adjgpsweek(390)
old (+1) : 390 + (2432 - 390 + 1) / 1024 * 1024 = 1414
new (+512): 390 + (2432 - 390 + 512) / 1024 * 1024 = 2438
Week 1414 is late 2007. |toe - obs time| is then ~19 years, so
MAXDTOE = 7200 s fails and the satellite is excluded from PVT.
The same situation occurs on live tracking if the host clock is a few
weeks behind the broadcast WN (or on IF files recorded a few weeks in
the future relative to the PC).
Proposed fix
The attached patch is against the current PocketSDR tree (paths without
the software/ prefix).
-
lib/RTKLIB/src/rtkcmn.c
Change adjgpsweek() to nearest-era unwrapping (+512), the same
convention already used for RTCM/BDS week adjustment.
-
src/sdr_pvt.c
After decode_frame() for GPS/QZS LNAV, rebase eph week / toe / toc /
ttr to the tracking-channel week. ch->week already comes from the
same SF1 WN plus GPST_OFF_W, so it follows the signal, not the host
clock. This still protects IF replay when the host date is many
weeks away even after the +512 change.
-
test/src/test_sdr_pvt.c
Unit test pack_gps_lnav_eph() / test_sdr_pvt_udnav_gps_week()
checks adjgpsweek(390) == 2438 and that sdr_pvt_udnav() stores
week 2438 with toe at 36000 s.
The PVT unit tests pass, including the new case contained in the patch.
Thank you very much for PocketSDR and for considering this.
Best regards,
Hugo Sobreira
ESA
hugo.sobreira@esa.int
0001-fix-GPS-WN-unwrapping-when-IF-recording-time-is-weeks-away.patch
Dear Mr. Takasu,
I hope you are doing well.
I would like to report a GPS week-number unwrapping problem that appears
when pocket_trk is used to replay an IF recording whose signal time is
only a few weeks away from the host PC clock.
Symptom
On IF replay, GPS/QZS LNAV ephemerides are decoded (nav count increases)
but the satellites are never used in PVT. toe is rejected by the 2 h
MAXDTOE check in seleph(). The stored eph week is 1024 weeks (about 19
years) off.
Cause
decode_frame() expands the 10-bit LNAV week with adjgpsweek(), which
uses the host CPU time:
The +1 bias does not pick the nearest 1024-week era. If the 10-bit WN
is only a few weeks ahead of the host GPS week, integer division falls
into the previous era.
Numerical example (August 2026, host GPS week ~2432, SF1 WN = 390):
Week 1414 is late 2007. |toe - obs time| is then ~19 years, so
MAXDTOE = 7200 s fails and the satellite is excluded from PVT.
The same situation occurs on live tracking if the host clock is a few
weeks behind the broadcast WN (or on IF files recorded a few weeks in
the future relative to the PC).
Proposed fix
The attached patch is against the current PocketSDR tree (paths without
the software/ prefix).
lib/RTKLIB/src/rtkcmn.c
Change adjgpsweek() to nearest-era unwrapping (+512), the same
convention already used for RTCM/BDS week adjustment.
src/sdr_pvt.c
After decode_frame() for GPS/QZS LNAV, rebase eph week / toe / toc /
ttr to the tracking-channel week. ch->week already comes from the
same SF1 WN plus GPST_OFF_W, so it follows the signal, not the host
clock. This still protects IF replay when the host date is many
weeks away even after the +512 change.
test/src/test_sdr_pvt.c
Unit test pack_gps_lnav_eph() / test_sdr_pvt_udnav_gps_week()
checks adjgpsweek(390) == 2438 and that sdr_pvt_udnav() stores
week 2438 with toe at 36000 s.
The PVT unit tests pass, including the new case contained in the patch.
Thank you very much for PocketSDR and for considering this.
Best regards,
Hugo Sobreira
ESA
hugo.sobreira@esa.int
0001-fix-GPS-WN-unwrapping-when-IF-recording-time-is-weeks-away.patch