Skip to content

fix bug where has_fix remained True even though the fix was lost #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2021

Conversation

jkittner
Copy link
Contributor

I am experiencing the following behavior with this sample code:

import time
import serial

import adafruit_gps

uart = serial.Serial('/dev/ttyS0', baudrate=9600, timeout=10)

gps = adafruit_gps.GPS(uart, debug=False)
gps.send_command(b"PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0")
gps.send_command(b"PMTK220,1000")

while True:
    gps.update()
    print(f'gps.has_fix={gps.has_fix}')
    print(f'gps.has_3d_fix={gps.has_3d_fix}')
    print(f'gps.fix_quality={gps.fix_quality}')
    print(f'gps.fix_quality_3d={gps.fix_quality_3d}')
    print('=' * 79)
    time.sleep(.1)
  1. start the system inside, no fix, red led blinks quicky, everything as expected
gps.has_fix=False
gps.has_3d_fix=False
gps.fix_quality=0
gps.fix_quality_3d=0
  1. bring the GPS-unit outside, as expected it gets a fix, red led blinks slowly, property has_fix is set correctly
gps.has_fix=True
gps.has_3d_fix=False
gps.fix_quality=1
gps.fix_quality_3d=0
  1. bring the GPS unit back inside, the red LED starts to blink quickly, however it still returns has_fix=True
gps.has_fix=True
gps.has_3d_fix=False
gps.fix_quality=1
gps.fix_quality_3d=0

I had a look at what _read_sentence returns, and it seems like the GPS continues to return some data for quite some time e.g b'$GPGGA,150745.000,1234.1234,N,12345.1234,E,1,06,2.89,33.2,M,47.4,M,,*5A\r\n' .
after a while it actually stops, to return proper data, but has_fix remains True even though the red led blinks quickly. The number of satellites goes down to 1 and the RMC sends V for Warning, but has_fix remains true...

b'$GPRMC,154518.000,V,,,,,0.00,0.00,230921,,,N*4A\r\n'
gps.has_fix=True
gps.has_3d_fix=False
gps.fix_quality=6
gps.fix_quality_3d=0

Solution/Fix

The issue is, that the sentence b'$GPRMC,154518.000,V,,,,,0.00,0.00,230921,,,N*4A\r\n' cannot be parsed here and the method returns early and self.fix_quality is not set and the property has_fix remains at the point of the last successfull parse:

data = _parse_data({12: _RMC, 13: _RMC_4_1}[len(data)], data)
if data is None:
return False # Params didn't parse

so this way the code below is never reached:
if data[1].lower() == "a":
if self.fix_quality == 0:
self.fix_quality = 1
else:
self.fix_quality = 0

A different way than the one I chose here would be to add another parsing step to check if at least the A or V parameter is parsable and set has_fix according to this. My though for this solution was, that if there was no parsable data, we also don't have a fix so has_fix must be false.

This is also the case for gga and gsa, however they also send a fix parameter in their data, so we could try to parse them separately to differentiate between a lost fix and some other non parsable data problem. I am not sure if this even makes sense to do...

@jepler jepler requested a review from a team September 24, 2021 16:36
@jepler
Copy link
Contributor

jepler commented Sep 24, 2021

Thanks! I approved the workflow to run so that we can make sure it passes our automated checks. I don't know enough about GPS to comment on the correctness of this fix.

@jepler
Copy link
Contributor

jepler commented Sep 24, 2021

The failure of the automated checks appears to be unrelated to your change. I'm consulting with a colleague about the problem.

Copy link
Contributor

@kattni kattni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for doing this!

@kattni
Copy link
Contributor

kattni commented Sep 24, 2021

I'm going to merge this because we are merging a fix soon for the failures.

@kattni kattni merged commit f7c9e71 into adafruit:main Sep 24, 2021
@jkittner
Copy link
Contributor Author

jkittner commented Sep 24, 2021

Thanks for merging!

The CI failure can be fixed with this addition to the .pylintrc or by passing a --py-version=3.5 to the call.

diff --git a/.pylintrc b/.pylintrc
index 845d2b0..fc11b6d 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -55,7 +55,7 @@ confidence=
 # no Warning level messages displayed, use"--disable=all --enable=classes
 # --disable=W"
 # disable=import-error,print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call
-disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation,pointless-string-statement
+disable=print-statement,parameter-unpacking,unpacking-in-except,old-raise-syntax,backtick,long-suffix,old-ne-operator,old-octal-literal,import-star-module-level,raw-checker-failed,bad-inline-option,locally-disabled,locally-enabled,file-ignored,suppressed-message,useless-suppression,deprecated-pragma,apply-builtin,basestring-builtin,buffer-builtin,cmp-builtin,coerce-builtin,execfile-builtin,file-builtin,long-builtin,raw_input-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,no-absolute-import,old-division,dict-iter-method,dict-view-method,next-method-called,metaclass-assignment,indexing-exception,raising-string,reload-builtin,oct-method,hex-method,nonzero-method,cmp-method,input-builtin,round-builtin,intern-builtin,unichr-builtin,map-builtin-not-iterating,zip-builtin-not-iterating,range-builtin-not-iterating,filter-builtin-not-iterating,using-cmp-argument,eq-without-hash,div-method,idiv-method,rdiv-method,exception-message-attribute,invalid-str-codec,sys-max-int,bad-python3-import,deprecated-string-function,deprecated-str-translate-call,import-error,bad-continuation,pointless-string-statement,consider-using-f-string
 
 # Enable the message, report, category or checker with the given id(s). You can
 # either give multiple identifier separated by comma (,) or put this option

I was wondering why the second pylint pre-commit hook uses language system which is kidna pre-commit's escape hatch? This is not very portable...

Or have you considered making this >= 3.6 only? and maybe use pyupgrade to reformat e.g. the .format calls to f-strings? I'd be happy to work on this.

@jkittner jkittner deleted the has_fix branch September 24, 2021 18:01
@jepler
Copy link
Contributor

jepler commented Sep 24, 2021

f-strings are not supported in all circuitpython boards, so it's not appropriate to start using them in libraries, unlesss those libraries are known to only work with the higher capacity boards in the first place.

adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Oct 6, 2021
Updating https://github.com/adafruit/Adafruit_CircuitPython_DHT to 3.6.2 from 3.6.1:
  > Merge pull request adafruit/Adafruit_CircuitPython_DHT#75 from adafruit/linting
  > Revert "Revert "Globally disabled consider-using-f-string pylint check""
  > Revert "Fixed linting"
  > Revert "Globally disabled consider-using-f-string pylint check"
  > Fixed linting
  > Globally disabled consider-using-f-string pylint check
  > Moved default branch to main
  > Moved CI to Python 3.7
  > Added help text and problem matcher
  > Added pull request template

Updating https://github.com/adafruit/Adafruit_CircuitPython_GPS to 3.9.2 from 3.9.1:
  > Globally disabled consider-using-f-string pylint check
  > Merge pull request adafruit/Adafruit_CircuitPython_GPS#67 from theendlessriver13/has_fix

Updating https://github.com/adafruit/Adafruit_CircuitPython_RA8875 to 3.1.6 from 3.1.5:
  > Merge pull request adafruit/Adafruit_CircuitPython_RA8875#26 from adafruit/linting
  > Globally disabled consider-using-f-string pylint check
  > Moved default branch to main
  > Moved CI to Python 3.7
  > Added help text and problem matcher
  > Added pull request template
  > "Increase duplicate code check threshold "

Updating https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display to 3.10.8 from 3.10.7:
  > Merge pull request adafruit/Adafruit_CircuitPython_RGB_Display#97 from adafruit/Linted
  > Globally disabled consider-using-f-string pylint check
  > Moved default branch to main
  > Moved CI to Python 3.7
  > Added help text and problem matcher
  > Added pull request template

Updating https://github.com/adafruit/Adafruit_CircuitPython_FakeRequests to 1.0.4 from 1.0.3:
  > Merge pull request adafruit/Adafruit_CircuitPython_FakeRequests#5 from adafruit/patch-fix
  > Globally disabled consider-using-f-string pylint check
  > Moved CI to Python 3.7
  > Added help text and problem matcher
  > Added pull request template

Updating https://github.com/adafruit/Adafruit_CircuitPython_MIDI to 1.4.4 from 1.4.3:
  > Merge pull request adafruit/Adafruit_CircuitPython_MIDI#44 from adafruit/note_private_fix
  > Added pylint disable for f-strings in tests directory
  > Globally disabled consider-using-f-string pylint check

Updating https://github.com/adafruit/Adafruit_CircuitPython_PortalBase to 1.9.3 from 1.9.2:
  > Merge pull request adafruit/Adafruit_CircuitPython_PortalBase#50 from makermelissa/fix_push_to_io
  > Globally disabled consider-using-f-string pylint check

Updating https://github.com/adafruit/Adafruit_CircuitPython_ServoKit to 1.3.5 from 1.3.4:
  > Merge pull request adafruit/Adafruit_CircuitPython_ServoKit#33 from adafruit/linting
  > Globally disabled consider-using-f-string pylint check
  > Moved default branch to main
  > Moved CI to Python 3.7
  > Added help text and problem matcher
  > Added pull request template
@jkittner jkittner mentioned this pull request Oct 30, 2021
dniprox pushed a commit to dniprox/Adafruit_CircuitPython_GPS that referenced this pull request Jan 9, 2024
Enable GSV (satellites in view) parsing.

Rewrote the GSA and GSV parsing to handle each satellite system
(talker) separately.
- self.sats now uses keys based upon the talker and satellite
  number, eg. GL67 for GLONASS adafruit#67, GP7 for GPS adafruit#7
- When the end message of a GSV sequence is received, eg. 3 of 3,
  all previous records in self.sats matching that talker are removed
  before adding the updated ones.
- self.sat_prns stores the last satellite IDs that were used for a
  fix and returned in the most recent GSA sentence. They will be
  from only one Satellite system and should have a record in
  self.sats .
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.

4 participants