From da791bf9f4c8bbb21cd9d7b5f039c59fc602ef86 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Sat, 14 Jan 2023 12:32:45 +0100 Subject: [PATCH] gps: add support for GLL sentence type, add original sentence to gps errors Signed-off-by: deadprogram --- gps/gps.go | 20 ++++++++++++-------- gps/gpsparser.go | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/gps/gps.go b/gps/gps.go index 80cdb03..21bee2e 100644 --- a/gps/gps.go +++ b/gps/gps.go @@ -17,22 +17,25 @@ var ( errUnknownNMEASentence = errors.New("unsupported NMEA sentence type") errInvalidGGASentence = errors.New("invalid GGA NMEA sentence") errInvalidRMCSentence = errors.New("invalid RMC NMEA sentence") + errInvalidGLLSentence = errors.New("invalid GLL NMEA sentence") ) type GPSError struct { - Info string - Err error + Err error + Info string + Sentence string } -func newGPSError(err error, info string) GPSError { +func newGPSError(err error, sentence string, info string) GPSError { return GPSError{ - Info: info, - Err: err, + Info: info, + Err: err, + Sentence: sentence, } } func (ge GPSError) Error() string { - return ge.Err.Error() + " " + ge.Info + return ge.Err.Error() + " " + ge.Info + " " + ge.Sentence } // Device wraps a connection to a GPS device. @@ -156,8 +159,9 @@ func validSentence(sentence string) error { } checksum := strings.ToUpper(hex.EncodeToString([]byte{cs})) if checksum != sentence[len(sentence)-2:len(sentence)] { - return newGPSError(errInvalidNMEAChecksum, "expected "+sentence[len(sentence)-2:len(sentence)]+ - " got "+checksum) + return newGPSError(errInvalidNMEAChecksum, sentence, + "expected "+sentence[len(sentence)-2:len(sentence)]+ + " got "+checksum) } return nil diff --git a/gps/gpsparser.go b/gps/gpsparser.go index 77abacc..d0232f6 100644 --- a/gps/gpsparser.go +++ b/gps/gpsparser.go @@ -54,6 +54,7 @@ func (parser *Parser) Parse(sentence string) (Fix, error) { typ := sentence[3:6] switch typ { case "GGA": + // https://docs.novatel.com/OEM7/Content/Logs/GPGGA.htm fields := strings.Split(sentence, ",") if len(fields) != 15 { return fix, errInvalidGGASentence @@ -66,8 +67,23 @@ func (parser *Parser) Parse(sentence string) (Fix, error) { fix.Time = findTime(fields[1]) fix.Valid = (fix.Altitude != -99999) && (fix.Satellites > 0) + return fix, nil + case "GLL": + // https://docs.novatel.com/OEM7/Content/Logs/GPGLL.htm + fields := strings.Split(sentence, ",") + if len(fields) != 8 { + return fix, errInvalidGLLSentence + } + + fix.Latitude = findLatitude(fields[2], fields[3]) + fix.Longitude = findLongitude(fields[4], fields[5]) + fix.Time = findTime(fields[6]) + + fix.Valid = (fields[7] == "A") + return fix, nil case "RMC": + // https://docs.novatel.com/OEM7/Content/Logs/GPRMC.htm fields := strings.Split(sentence, ",") if len(fields) != 13 { return fix, errInvalidRMCSentence @@ -83,7 +99,7 @@ func (parser *Parser) Parse(sentence string) (Fix, error) { return fix, nil } - return fix, newGPSError(errUnknownNMEASentence, typ) + return fix, newGPSError(errUnknownNMEASentence, sentence, typ) } // findTime returns the time from an NMEA sentence: