AeroRust / nmea

NMEA 0183 - for communication between marine electronics such as echo sounder, sonars, anemometer, gyrocompass, autopilot, GNSS receivers and many other types of instruments. Defined and controlled by the National Marine Electronics Association (NMEA)
https://crates.io/crates/nmea
Other
56 stars 41 forks source link

xxGNS parsing issue #108

Open StefanB7 opened 1 year ago

StefanB7 commented 1 year ago

Hi. Hope all is well.

I've encountered a parsing problem while trying to parse a GNS message from my u-blox SAM-M10Q module. I think I've narrowed it down, but some help will be appreciated. The message received from the module (no gps fix): $GNGNS,,,,,,NNNNNN,00,99.99,,,,,V*07 The error I got while trying to parse the message:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParsingError(Failure(Error { input: "NNNN", code: Fail }))', src\main.rs:6:35
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\gpsdecoder.exe` (exit code: 101)

Now from what I can gather, the NNNNNN is fix flags for each of the satellite constellations supported and being used by the u-blox module, parsed with the parse_faa_modes function.

However, the parse_faa_modes function checks the next character to parse (in this case the first GNSS's flag), parses it and builds a FaaModes struct, and since there is still characters to parse (the rest of the GNSS's flags), it adds a second system state to the same FaaModes struct it just created for the first one. Thereafter, the rest of the GNSS's flags are still there, the parse_faa_modes function doesn't know what to do and returns an error.

Now I think this can be solved by running the parse_faa_modes function on each character in this group and not on the group as a whole.

I am willing to create a PR for this, but I need some help.

Thanks for your assistance, Stefan

elpiel commented 10 months ago

Hello @StefanB7, I've missed posting my comment in September to the issue so sorry about the delay. First of all - thank you for reporting the issue!

Do you have any specific questions? Maybe you can take a look at nom first and see how we can parse more than the 2 we have defined now.

Accordingly to the gpsd docs - https://gpsd.gitlab.io/gpsd/NMEA.html#_gns_fix_data, the first two are for GPS and GLONASS. We could read all characters up to the comma , with nom, parse the first one (GPS) and the rest we could put behind an Option. We could keep the 2nd FAA mode required then and have a heapless::Vec (fixed size Vec) with maximum of e.g. 4 (6 total - 2).

struct FaaModes {
   /// This is usually GPS
   sys_state0: FaaMode,
   //// Rest of the fix flags, could be 0 or more than 1
   sys_staten: Option<FaaModesN>,
}

struct FaaModesN {
    /// Usually GLONASS
    sys_state1: FaaMode,
    sys_states: heapless::Vec<FaaMode, 4>,
}

Do you know if u-blox defines a maximum number of FAA modes that it can return? Maybe there's something in the Datasheet for your module?