Skip to content

GPS: keep the GPS on for a 3D fix, prefer a recent 3D fix over a 2D one - #3821

Merged
fdlamotte merged 3 commits into
meshcore-dev:devfrom
AlexandrTyshchenko:feature/gps-guard-3d-fix
Nov 13, 2026
Merged

fdlamotte merged 3 commits into
meshcore-dev:devfrom
AlexandrTyshchenko:feature/gps-guard-3d-fix

Conversation

@AlexandrTyshchenko

@AlexandrTyshchenko AlexandrTyshchenko commented Nov 11, 2026 •

Copy link
Copy Markdown

Follow-up to the review comment by Avamander in #3753 (fix type was not checked), reworked after review: a 2D fix is valid, only less precise, and in some places a receiver never gets a 3D fix. So the fix mode decides when the GPS may sleep, not whether a fix is accepted.

  • MicroNMEALocationProvider reads the fix mode from GSA (any talker: GPGSA, GNGSA, BDGSA, ...) for every NMEA receiver; MicroNMEA itself does not parse GSA. The mode is stored with the last fix.
  • In periodic mode and for gps once, the GPS goes to sleep only after a 3D fix (or any fix from a receiver that does not report the mode). After a 2D fix it stays on up to the acquisition timeout to get a 3D fix.
  • A 2D fix is used as the position, but does not replace a 3D fix younger than 5 min (GPS_3D_FIX_PREFERRED_MS); an older 3D fix is replaced.
  • The guard (GPS_GUARD) does not look at the fix mode: its other checks apply to 2D and 3D fixes alike.
  • Receivers that don't send GSA are unchanged: with no GSA in the last 2 s the fix mode is unknown.
  • gps diag shows the fix mode as fm (1 none, 2 2D, 3 3D, 0 no recent GSA).

Not done: an almanac check, plain NMEA does not report it.

Testing

  • Faketec (nRF52840) with a u-blox MAX-M10S over UART: gps diag goes fm:1 → fm:3 during an acquisition, the GPS sleeps after the 3D fix as before.
  • The 2D path (GPS stays on, a recent 3D fix is kept) is not hardware-tested: no 2D fix on the bench.
  • Builds: Faketec SX1268 repeater and companion (with GPS_GUARD), RAK_4631_repeater and Heltec_v3_companion_radio_ble (without).

The guard checked satellites and HDOP but not the fix type. When the
receiver sends GSA, a fix it reports as 2D or no-fix is now rejected
(`rej 2d`). Receivers without GSA are unchanged (fix mode unknown).
GPS_GUARD_REQUIRE_3D=0 turns the check off. `gps diag` shows the fix
mode as `fm`.
@AlexandrTyshchenko

Copy link
Copy Markdown
Author

@fdlamotte gentle ping: this is the 3D-fix follow-up to the point Avamander raised in #3753. Small change in the guard only: a fix the receiver reports as 2D in GSA is rejected. Tested on our Faketec board, still merges cleanly into dev. Could you take a look when you have a moment?

@fdlamotte

Copy link
Copy Markdown
Collaborator

Nice

I think there are two different issues here ... wether we want to totally ignore 2D fixes or if we want to let the gps awake longer to give it a chance to get a better (3D fix)

Sometimes we are in places where we won't get any 3D fixes (here for instance I sometimes never get fixes while I'm outside)

So my stand would be to differenciate the "fix" condition and "gps off" condition ... and do gps off only if we meet certain requirements (3D fix, almanach ok ...) but accept any fix that seems valid (a 2D fix is valid but does not have a great precision)

We might also consider how we treat a 2D fix after a 3D fix, because if it comes close from the 3D fix, the 3D one might be less precise in the end, but if 3D fix is (lets say) more than 5min old, then I guess the 2D fix would be more precise ...

Per review: a 2D fix is valid, only less precise, and in some places a
receiver never gets a 3D fix. So the guard no longer rejects it; instead
the fix mode decides when the GPS may sleep:

- the fix mode is read from GSA for every NMEA receiver, not only with
  GPS_GUARD (`fm:` in `gps diag`), and stored with the last fix;
- in periodic mode, and for `gps once`, the GPS sleeps only after a 3D
  fix (or a fix from a receiver that does not report the mode); after a
  2D fix it stays on up to the acquisition timeout;
- a 2D fix does not replace a 3D fix younger than 5 min
  (GPS_3D_FIX_PREFERRED_MS).
@AlexandrTyshchenko AlexandrTyshchenko changed the title GPS guard: reject a fix the receiver reports as 2D (GSA) GPS: keep the GPS on for a 3D fix, prefer a recent 3D fix over a 2D one Nov 13, 2026
@AlexandrTyshchenko

Copy link
Copy Markdown
Author

Agreed, that is a better split. Reworked:

  • a 2D fix is accepted again (the guard no longer rejects it);
  • the fix mode from GSA is read for every NMEA receiver (fm: in gps diag) and stored with the last fix;
  • in periodic mode and for gps once, the GPS goes to sleep only after a 3D fix (or any fix from a receiver that does not report the mode); after a 2D fix it stays on up to the acquisition timeout;
  • a 2D fix does not replace a 3D fix younger than 5 min (GPS_3D_FIX_PREFERRED_MS); an older 3D fix is replaced.

I did not add an almanac check: plain NMEA does not report it, so it would need receiver-specific messages.

Tested on our Faketec board (MAX-M10S): fm:1 → fm:3, GPS sleeps after the 3D fix as before. The 2D path is not hardware-tested (no 2D fix here).

@fdlamotte

Copy link
Copy Markdown
Collaborator

I like it, thanks !

@fdlamotte
fdlamotte merged commit 888c7ca into meshcore-dev:dev Nov 13, 2026
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