-
Notifications
You must be signed in to change notification settings - Fork 320
Fix GPS week rollover handling in RTCM3 decoder #767
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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().
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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());
There was a problem hiding this comment.
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().
|
I will close this Pull Request and open a new one with just the fix for adjgpsweek(). |
|
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! |
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)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)adjgpsweek()function by changing the week adjustment calculation from(w-week+1)/1024*1024to(w-week+512)/1024*1024