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
61 stars 41 forks source link

use `f64` (double) over `f32` precision in the Parser #67

Open elpiel opened 2 years ago

elpiel commented 2 years ago

Research whether:

TODOs:

Replace all places to use f64 (double) precision rather than complicating the source code.

clemarescx commented 2 years ago

From the first results I could find with a quick DuckDuckGo for "nmea gpgll", both Trimble (don't know them) and Arduino (I know them!) are using double precision in their examples:

Some datasheets for products on sparkfun.com are showing examples with single precision however (here or here), so :man_shrugging:

To handle both f32 and f64, perhaps other crates like nalgebra or bevy can be an inspiration.

elpiel commented 2 years ago

Good research. I didn't quite understand where Trimble and Arduino use double precision. For Trimble they mention mm,mmmm (0-7 digits) for lat/long, so f32 should be sufficient?

Also to be embedded friendly, we can just use f32 exclusively and only if the necessity arises to think of a way to allow a double (f64) precision.

clemarescx commented 2 years ago

For Trimble they mention mm,mmmm (0-7 digits) for lat/long, so f32 should be sufficient?

Ahh right, they mention mm.mmmm in the field meanings, but I referred myself to their example for the latitude and longitude (3953.88008971 and 10506.75318910 respectively), which are bigger than that format. I copied them in VSCode and tried to assign them to an f32, and clippy immediately gave me the excessive_precision warning.

But if the format is respected, those values should instead be 53.8801 and 06.7532 (if we just keep the minutes), and indeed, both can fit as f32. As for hardware limitations for embedded systems, I'm afraid I know very little in that domain so I don't know how much precision loss is acceptable.

elpiel commented 2 years ago

Yes, you are right. It does give an error and somehow I thought that these values should fit in a f32 with 7 numbers after the decimal point.

It is 7 digits after the decimal point so f64 should be used. As far as the embedded limitations, people have told me that there is a way to store and use 2 memory addresses and for f64 on 32bit systems. Sadly this is where my experience ends with that solution 😅 This needs more research on how this could be used on embedded systems. When I get back home I can try to run it on my nrf board which has a 32bit microcontroller and see what it does.

I do know that rust automagically compiles any programs with f64 numbers on 32bit OS and it works but not sure about embedded systems.

elpiel commented 2 years ago

Based on the research I did, double (f64) will work on 32bit systems with some performance penalty (probably not that large).

Nonetheless, I will run it on the nrf board I have just to confirm it before updating this issue. The lat/long makes sense to be double, but we have to double check the other floating numbers in the parsers.