Giter Club home page Giter Club logo

go-nmea's People

Contributors

adrianmo avatar aldas avatar bertoldvdb avatar bezineb5 avatar bmurray avatar borud avatar buxtronix avatar calmh avatar fhedberg avatar icholy avatar kamil-krawczyk avatar krasi-georgiev avatar maescool avatar quartercastle avatar simeonmiteff avatar skladd avatar sthorshaug avatar tzneal avatar yavosh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-nmea's Issues

processing multiline / segmented messages

I could not find an example for processing AIS 5 message here. This type of message has more than one line for example:

\g:1-2-3730,s:43576,c:1654340281,t:165434038119!AIVDM,2,1,7,,569EH`8000009aGUB20IF1UD4r1UF3OK7>22220N4PT38t0000000000,042

\g:2-2-37305A!AIVDM,2,2,7,,000000000000000,262

Is there any way to process such cases?

Doesn't handle null fields.

I have the following sentence:

$GPRMC,142754.0,A,4302.539570,N,07920.379823,W,0.0,,070617,0.0,E,A*3F

Which fails to parse with: GPRMC decode course error: due to the parser not handling null fields correctly. The easiest solution would be to use 0 when there's a null field, but idk if that's a good idea.

https://www.trimble.com/OEM_ReceiverHelp/V4.44/en/NMEA-0183messages_MessageOverview.html

All messages conform to the NMEA-0183 version 3.01 format. All begin with $ and end with a carriage return and a line feed. Data fields follow comma (,) delimiters and are variable in length. Null fields still follow comma (,) delimiters, but contain no information.

Default value for empty string

When a value is missing in a nmea string the float or int value in the parsed sentence is set to 0. This way it is hard to determine if the value is really 0 or the data was missing. E.g. $GPVTG,0.3,T,,M,,N,12.6,K*78 would result in GroundSpeedKnots: 0 and GroundSpeedKPH: 12.6. Now it is easy to guess that that GroundSpeedKnots is invalid, but for TrueTrack: 0.3 and MagneticTrack: 0 it is not possible.

Is there a specific reason why this is done in this way?

I would suggest to add getters to the sentences for all the value like:

func (s VTG) GetTrueTrack() (float64, error) {
	if s.hasValidTrueTrack {
		return s.TrueTrack, nil
	}
	return 0, fmt.Errorf("TrueTrack is missing in the nmea string")
}

These getters can check an internal state for each value and return an error if the value was not available in the original nmea string. This will also not break existing code because it is still possible to use TrueTrack, MagneticTrack etc directly.

Update example in readme file

Update the example to show how to access sentence fields.

E.g.:

package main

import (
	"fmt"
	"github.com/adrianmo/go-nmea"
)

func main() {
	sentence := "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70"
	m, err := nmea.Parse(sentence)
	if err == nil {
		s := m.(nmea.GPRMC)
		fmt.Printf("Raw sentence: %v\n", s)
		fmt.Printf("Time: %v\n", s.Time.String())
		fmt.Printf("Validity: %v\n", s.Validity)
		fmt.Printf("Latitude GPS: %v\n", s.Latitude.PrintGPS())
		fmt.Printf("Latitude DMS: %v\n", s.Latitude.PrintDMS())
		fmt.Printf("Longitude GPS: %v\n", s.Longitude.PrintGPS())
		fmt.Printf("Longitude DMS: %v\n", s.Longitude.PrintDMS())
		fmt.Printf("Speed: %v\n", s.Speed)
		fmt.Printf("Course: %v\n", s.Course)
		fmt.Printf("Date: %v\n", s.Date.String())
		fmt.Printf("Variation: %v\n", s.Variation)
	} else {
		panic(err)
	}
}

Output:

$ go run main/main.go

Raw sentence: $GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70
Time: 22:05:16.0000
Validity: A
Latitude GPS: 5133.8200
Latitude DMS: 51° 33' 49.200000"
Longitude GPS: 042.2400
Longitude DMS: 0° 42' 14.400000"
Speed: 173.8
Course: 231.8
Date: 13/06/94
Variation: -4.2

feature: could sentence expose list of field names it has

I am creating application to read nmea values and send them to NATS message bus and I one feature that I have is that user can provide configuration (file) that has list of sentences and fields that should filter out of stream of NMEA messages it receives.

For example - we have GPS, Echosounder, Wind sensor all multiplexed into NMEA0183 bus we read. Sometimes we only want to filter GPS RMC messages but sometimes we want other hardware messages also. As this library evolves more and more supported sentences will be added. For each of those messages we would need to create if/switch to be able to read it - pack all fields of message into custom struct we have. We can not just marshall current nmea.Sentence as our schema is different from what marshalling nmea.Sentence creates.

So it would be nice if there would be way to get list of field names that sentence has and then we can pair them with nmea.BaseSentence.Fields slice values to our own schema.

Maybe that context argument that is used when adding field to sentence, could be stored and exposed as public slice

go-nmea/rmc.go

Line 34 in a4c9590

Latitude: p.LatLong(2, 3, "latitude"),

or there would be some method on Sentence what would return list/map of fieldname+fieldvalue (ala map[string]interface{}) so you could "dynamically" get all fields and filter what you need.

parsing errors

About errors. When parsing fails currently only first error is stored and all subsequent errors are discarded. I propose if p.EnumString and other parsing method errors would be distinguishable from each other and parsers would store all errors. it would allow you to introspect what went wrong and some circumstances ignore some error types and still use the parsed sentence.

maybe just wrapping them (or storing into slice or multierror)

func (p *Parser) SetErr(context, value string) {
	if p.err == nil {
		p.err = fmt.Errorf("nmea: %s invalid %s: %s", p.Prefix(), context, value)
	} else {
		p.err = fmt.Errorf("nmea: %s invalid %s: %s, err: %w", p.Prefix(), context, value, p.err)
	}
}

nmea.ParseSentence output

Hi, i am newbie on Golang and the NMEA library too.

I have a question about the output when i use nmea.ParseSentence.

this is the code, i changed nmea.Parse to nmea.ParseSentence

package main

import (
"fmt"
"github.com/adrianmo/go-nmea"
)

func main() {
m, err := nmea.ParseSentence("$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70")

if err == nil {
fmt.Printf("%+v\n", m)
}
}

but the output still same with nmea.Parse. The output:
$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70
is it the right output?
I want to parse that NMEA, so i choose the ParseSentence.

Thanks for your help

Parse latitude and longitude along with the context of the direction

Version 2.x should take into account that geographical coordinate parsing must always be done in the context of the direction. Latitude and longitude have different ranges. In addition, currently only the Decimal format stores information about the direction of a given coordinate (positive / negative values). Parsing data in other formats loses direction information.

Document message specification

Since there's no public canonical nmea reference, we've been linking to different resources on the web. It would be better to maintain our own copy of the message specifications that we implement.

Fails to parse IIXDR

occur error when parsing data.
i received error message, "nmea: IIXDR invalid transducer type: A"

my gps data sender is providing bellow data
$IIXDR, A, 0.0, D, ROLL, A, 0.0, D, PITCH*15

Fails to parse correct RMC sentence

As of version 1.5.0 and higher, I get the following when parsing data from my boat:

  • Sentence: $YDRMC,050700.00,A,5524.8683,N,01255.7938,E,0.2,181.3,230623,4.3,E,A,C*5F
  • Error: nmea: YDRMC invalid navigation status: C

sentence checksum error reported, though both values seem the same

I am running your example code on GNRMC data received from my GNSS module.
On nmea.Parse(sentence) I get:

]019/06/17 21:26:23 Couldn't parse GPS data: nmea: sentence checksum mismatch [79 != 79
2019/06/17 21:26:24 $GNRMC,192624.000,A,5327.813301,N,01432.630601,E,0.00,325.41,170619,,,A*7E
]019/06/17 21:26:24 Couldn't parse GPS data: nmea: sentence checksum mismatch [7E != 7E
2019/06/17 21:26:25 $GNRMC,192625.000,A,5327.813301,N,01432.630601,E,0.00,325.41,170619,,,A*7F
]019/06/17 21:26:25 Couldn't parse GPS data: nmea: sentence checksum mismatch [7F != 7F
^C2019/06/17 21:26:25 main: Got signal: interrupt
2019/06/17 21:26:26 $GNRMC,192626.000,A,5327.813301,N,01432.630601,E,0.00,325.41,170619,,,A*7C
]019/06/17 21:26:26 Couldn't parse GPS data: nmea: sentence checksum mismatch [7C != 7C
^C2019/06/17 21:26:27 $GNRMC,192627.000,A,5327.813301,N,01432.630601,E,0.00,325.41,170619,,,A*7D
]019/06/17 21:26:27 Couldn't parse GPS data: nmea: sentence checksum mismatch [7D != 7D

Both checksums seem the same to me in the output above.
The place I pasted your example code:

https://github.com/madwizard/zut_wifi_logger/blob/2aead364882076d5a836c105a30cb6760d14c266/gps.go#L42

DPT third field depends on nmea version?

DPT documentation refers to https://gpsd.gitlab.io/gpsd/NMEA.html#_dpt_depth_of_water and in that is example $INDPT,2.3,0.0*46

that example is not parseable by the library. I get nmea: INDPT invalid range scale: index out of range

Some other documents ala https://www.tronico.fi/OH6NT/docs/NMEA0183.pdf
describe DPT as
image

or https://www.eye4software.com/hydromagic/documentation/nmea0183/ as Example: $SDDPT,3.6,0.0*52

It would be nice if DTP parsing can handle 2 and 3 fields gracefully without erroring.

possibility to make CRC check optional for certain sentences

Older devices sometimes do not implement NMEA0183 correctly by omitting CRC. It would be nice if there would be way to make parser ignore CRC mismatches for certain sentences.

We are retrofitting 2005 built vessel that has GPS device sending sentences without CRC. Our navigation engineers say it is not very rare to have older devices like that. So for example devices reading/receiving NMEA0183 sentences have sometimes option to disable CRC checks because of this sad reality.

Trouble using - nmea.Sentence is nmea.GPVTG, not nmea.GPRMC

When I am trying to parse the serial output of an u-blox USB GPS Interface, I get the following message, along other checksum warnings.

2018/07/17 11:24:37 $GPRMC,092441.00,V,,,,,,,170718,,,N*7F
panic: interface conversion: nmea.Sentence is nmea.GPVTG, not nmea.GPRMC
--
2018/07/17 11:25:42 $GPRMC,092546.00,V,,,,,,,170718,,,N*79
]018/07/17 11:25:42 nmea: sentence checksum mismatch [79 != 79
--
2018/07/17 11:59:10 NMEA RAW is: '$GPVTG,,,,,,,,,N*30'
panic: interface conversion: nmea.Sentence is nmea.GPVTG, not nmea.GPRMC

Support custom message types

I would like to extend this lib to support custom message parsing, is this something you would consider merging. We are using this to parse some custom message which are not part of the NMEA standard. The idea is to have a way to register parsers for new message types.

Make `ParseSentence` function unexported

Judging by #18, it looks like the ParseSentence function is causing confusion when using the library. Making it unexported would remove this potential confusion.

In a first inspection, I didn't see any reason to export the function as it's only used internally.

@icholy any thoughts?

1.0 API Freeze

I think the API is in a good place right now and we should tag a 1.0 release. No more breaking changes after that.

Accept other talkers than "GP"

The NMEA 0183 protocol offers multiple talkers based on which equipment generated the message.
GP indicates a GPS receiver, GL a GLONASS receiver, GN a combined GNSS receiver, IN an integrated navigation receiver and so forth. See here for examples of different talkers.

As of today, go-nmea only accepts GP for most messages as talker. Is there an easy way of allowing different talkers for all NMEA messages, or is it necessary to implement specific functions for all talkers?

A concrete example is the HDT, which in many cases is HEHDT and INHDT.

An easy (but dirty) way is of course to manipulate the talker into GP.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.