semuconsulting / pynmeagps

Python library for parsing and generating NMEA 0183 GNSS/GPS protocol messages.
BSD 3-Clause "New" or "Revised" License
81 stars 28 forks source link

Reported latitude seems incorrect #37

Closed dekinet closed 1 year ago

dekinet commented 1 year ago

Describe the bug

I'm using NMEAReader.parse() to parse a line of text containing a GLL sentence. The resulting longitude is correct, but the latitude is not.

pynmeagps v1.0.24

To Reproduce

Steps to reproduce the behaviour:

msg = NMEAReader.parse('$GNGLL,02348.3822990,S,15313.5862807,E,040856.82,A,D*5F') print(msg)

output: <NMEA(GNGLL, lat=-7.80637165, NS=S, lon=153.2264380117, EW=E, time=04:08:56.820000, status=A, posMode=D)>

Expected Behavior

The output latitude should be -23.80637 degrees.

Desktop (please complete the following information):

Windows 10 jupyter_client 8.2.0 pyhd8ed1ab_0 conda-forge jupyter_core 5.3.0 py311haa95532_0 anaconda Command line client (version 1.11.2) Python 3.11.3 pynmeagps-1.0.24

GNSS/GPS Device (please complete the following information as best you can):

I'm post-processing text captured from a GNSS receiver. Example text shown above.

semuadmin commented 1 year ago

Hi @dekinet,

Sorry you're having difficulties.

What's the origin of your GNGLL sentence i.e. what model of GNSS receiver are you using?

According to the NMEA 0183 standard, latitude values should be in the format "DDMM.MMMMM" i.e. 2 digit degrees value (since the lat value should never exceed 90 degrees). High-precision receivers may output 7 decimal places of minutes rather than 5, but the latitude degrees value should always be just 2 digits.

In your case the sentence has a non-standard 3 digit degrees value, and the value is being interpreted in my code as 02 degrees, 348.3822990 minutes, which is equivalent to 7.80637165 degrees.

If, for example, you parse the following well-formed sentence, you get the correct latitude value:

> msg = NMEAReader.parse("$GNGLL,2348.3822990,S,15313.5862807,E,040856.82,A,D*6F")
> print(msg)
<NMEA(GNGLL, lat=-23.80637165, NS=S, lon=153.2264380117, EW=E, time=04:08:56.820000, status=A, posMode=D)>

I can amend the code to cater for such non-standard latitude values, but it's arguably a bug in your receiver's firmware.

dekinet commented 1 year ago

Hi, thanks for the quick response.

In parallel to you writing the repsonse I managed to get the python debugger working and found the "issue" in dmm2ddd() -- not expecting a leading '0' just as you've described.

The NMEA source is a proprietary embedded application that converts binary high-precision data to NMEA. I will contact the author and point out that the NMEA output is non-compliant and see if it can be corrected. If not, I'm happy to try and submit a PR to modify the dmm2ddd() function to process a (non-standard) leading zero.

semuadmin commented 1 year ago

Hi, thanks for the quick response.

In parallel to you writing the repsonse I managed to get the python debugger working and found the "issue" in dmm2ddd() -- not expecting a leading '0' just as you've described.

The NMEA source is a proprietary embedded application that converts binary high-precision data to NMEA. I will contact the author and point out that the NMEA output is non-compliant and see if it can be corrected. If not, I'm happy to try and submit a PR to modify the dmm2ddd() function to process a (non-standard) leading zero.

As I say, I'm happy to make a change to cater for a non-compliant latitude value (within reason!) if you're not able to reach a satisfactory resolution with your embedded application any time soon - see https://github.com/semuconsulting/pynmeagps/commit/0fc70e0f42672bdb82ae58fbe0d90364dd948120

semuadmin commented 1 year ago

Hi @dekinet I've applied this change in v1.0.25 - it makes the dmm2ddd method slightly more robust anyway.

dekinet commented 1 year ago

That's awesome - thank you.