Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@gary7530
Copy link

@gary7530 gary7530 commented Oct 9, 2025

Pull Request Description:

Summary

This PR fixes the GPS week rollover handling in the RTCM3 decoder by replacing local time-based calculations with ephemeris time.

Changes Made

1. RTCM3 Decoder (src/rtcm3.c)

  • Simplified week rollover logic in multiple decode functions:
    • decode_type1019() (GPS)
    • decode_type1041() (IRNSS)
    • decode_type1044() (QZSS)
    • decode_type1045() (Galileo F/NAV)
    • decode_type1046() (Galileo I/NAV)
    • decode_type1042() (BeiDou)

2. Common Functions (src/rtkcmn.c)

  • Fixed adjgpsweek() function by changing the week adjustment calculation from (w-week+1)/1024*1024 to (w-week+512)/1024*1024
  • This ensures proper handling of the GPS week rollover boundary

src/rtkcmn.c Outdated
(void)time2gpst(utc2gpst(timeget()),&w);
if (w<1560) w=1560; /* use 2009/12/1 if time is earlier than 2009/12/1 */
return week+(w-week+1)/1024*1024;
return week+(w-week+512)/1024*1024;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well spotted, this looks correct. Fwiw using +511 rather than +512 would have a 2-complement split.

tt=timediff(gpst2time(eph.week,eph.toes),rtcm->time);
if (tt<-302400.0) eph.week++;
else if (tt>=302400.0) eph.week--;
rtcm->time=gpst2time(eph.week,eph.toes);
Copy link

@ourairquality ourairquality Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note sure about setting the rtcm->time to the eph time. adjgpsweek() also uses timeget(). Might be best to leave that.

The further adjustment to the eph.week might be to handle the rtcm->time being different to timeget() used in adjgpsweek(), handling half a week difference here. If this code is not broken then I suggest not changing it as there are a lot of complex code paths here e.g. replying data etc. Could you split these 'simplifications' out and just include the fix to adjgpsweek().

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for changing rtcm->time to use the ephemeris time is that in the original code, when timeget() and the ephemeris time differ by more than two weeks, it causes incorrect behavior. Using the eph time avoids this issue.

Copy link

@ourairquality ourairquality Oct 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With adjgpsweek() improved wouldn't that make eph.weeks consistent with timeget(). Can't see why the other eph.week adjustment was needed, and with that removed it should not be an issue even if the eph time is weeks off timeget() or rtcm->time? Still seems best to initialize the rtcm->time using timeget() as that is used everywhere else. So suggest:

eph.week=adjgpsweek(week);
if (rtcm->time.time==0) rtcm->time=utc2gpst(timeget());

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my situation is a bit special — I’m actually running RTKLIB on an ESP32. On this platform, every time the ESP32 boots, timeget() starts counting from the firmware’s compile time.

Because of that, when rtcm->time is initialized using timeget(), RTKLIB works correctly during the current week and the following week, but by the second week it encounters a week rollover error.

To fix this, I changed the code to set rtcm->time using the ephemeris time (after correction with adjgpsweek()), instead of relying on timeget().

@gary7530
Copy link
Author

I will close this Pull Request and open a new one with just the fix for adjgpsweek().

@ourairquality
Copy link

PR #775 adds support for message 1013 which does have the time and that might be a better option for initializing the real time clock on a disconnected device if the rtcm stream is the only option.

Fwiw the esp-idf includes a sntp client integrated with the time functions and that might be a quick option for the esp32. For my own esp32 loggers they support the DS3231 RTC when they need to be ready to go, and also synchronise their time when interacting with clients and servers, the web interface sends the web client time and when data is pushed to a server the server responds with the time (better option as it is trusted and there is a round trip time for better estimate), and it also caches data in the flash including the time, and it synchronises these rough real times to the esp32 64-bit system tick counter - there is a lot of code dedicated to the time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants