Mercurial > ublox > ublox8
changeset 70:919ca4da4660
gnss-galileo: estimate each satellites GST based on page numbers
The pages are sent in a well defined sequence, so we can make educated
guesses about how much time has passed since the last page we received.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Wed, 22 Jan 2020 11:26:34 -0500 |
parents | 9dd833ef57d3 |
children | 5937a255131f |
files | gnss-galileo-state.c gnss-galileo.h |
diffstat | 2 files changed, 90 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/gnss-galileo-state.c Mon Jan 20 12:58:48 2020 -0500 +++ b/gnss-galileo-state.c Wed Jan 22 11:26:34 2020 -0500 @@ -191,6 +191,17 @@ __sync_time(&state->time, gst, wn, tow, true); /* + * We know the exact time, update the estimate with it. We update + * only the current sv's estimate otherwise it becomes confusing. + * Specifically, if we were to set another sv's estimate to the + * current time, when it tries to update its estimate in early page + * 5 processing, it'll believe that it missed everything since the + * previous page 5 - causing it to estimate 30 seconds in the + * future. + */ + state->sv[sv].gst_estimate = gst; + + /* * If this is *not* the first time message from the constellation, * we were able to tag all ephemeris pages received since then with * that GST timestamp. This timestamp is required to sync the @@ -204,6 +215,78 @@ state->ops->time(state, sv, &state->time, &prev_sv); } +static void galileo_state_guess_time(struct galileo_state *state, int sv, int pg) +{ + /* + * map page number to the second offset into the 30 second subframe + * + * The values are the offsets of the start of the second half of the + * page - as listed in the ICD. + */ + static const uint32_t offsets[64] = { + [2] = 1, + [4] = 3, + [6] = 5, + [7] = 7, + [9] = 7, + [8] = 9, + [10] = 9, + [1] = 21, + [3] = 23, + [5] = 25, + }; + uint32_t prevoff; + uint32_t curoff; + uint32_t adj; + + ASSERT3U(pg, <, ARRAY_LEN(offsets)); + + curoff = offsets[pg]; + + if (curoff) { + /* + * We know that it is currently (gst % 30) == curoff. But + * because we may have missed some messages, we cannot just + * set our estimate to 'off' seconds past the last subframe + * start as that could cause our estimate to go backwards. + */ + + prevoff = state->sv[sv].gst_estimate % 30; + + if (prevoff >= curoff) { + /* + * We are certain that we are looking at a page from + * a different subframe than we had before. We do + * not know if it is the immediately adjacent + * subframe, or if we missed one or more. We assume + * that it is the adjacent one. + */ + adj = -prevoff + 30 + curoff; + } else { + /* + * We cannot tell if this page is from the same + * subframe as the one we had before. Therefore, we + * assume that it is the same one. + */ + adj = -prevoff + curoff; + } + } else { + /* + * We have no idea where in the 30 second subframe we are, + * but we know that we must be at least 2 seconds later than + * before. + * + * Note that it is *two* seconds because we get whole pages + * at a time. If we were getting the page halves, we would + * have to look at the even/odd bit to decide whether to + * step by one or two seconds. + */ + adj = 2; + } + + state->sv[sv].gst_estimate += adj; +} + bool galileo_state_apply_page(struct galileo_state *state, const unsigned int sv, const struct galileo_inav_page *pg) @@ -216,6 +299,8 @@ state->sv[sv].pages[pg->nominal.type].count++; + galileo_state_guess_time(state, sv, pg->nominal.type); + if (pg->nominal.type == 63) return true; /* nothing to do for dummy pages */
--- a/gnss-galileo.h Mon Jan 20 12:58:48 2020 -0500 +++ b/gnss-galileo.h Wed Jan 22 11:26:34 2020 -0500 @@ -233,8 +233,13 @@ /* each SV's data */ struct { struct galileo_ephemeris eph; + + /* last received GST update (page 5) */ struct galileo_state_time last_time; + /* guess at current time */ + uint32_t gst_estimate; + /* per page-type info */ struct { uint64_t count; /* number of pages received */