Skip to content

Commit 7315e63

Browse files
authored
Add sentences: HDG, HDM, MTW, ROT, TXT, PHTRO, PRDID, PSONCMS. Improve docs with formats and examples. Add NMEA 2.3/4.0 related field (FAA mode and Navigation status) (#87)
1 parent a4c9590 commit 7315e63

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1237
-100
lines changed

Makefile

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
.DEFAULT_GOAL := check
2+
check: lint vet test ## Check project
3+
4+
lint: ## Lint the files
5+
@golint -set_exit_status ./...
6+
7+
vet: ## Vet the files
8+
@go vet ./...
9+
10+
test: ## Run tests with data race detector
11+
@go test -race ./...
12+
13+
init:
14+
@go get -u golang.org/x/lint/golint@latest
15+
16+
goversion ?= "1.17"
17+
test_version: ## Run tests inside Docker with given version (defaults to 1.17). Example for Go1.15: make test_version goversion=1.15
18+
@docker run --rm -it -v $(shell pwd):/project golang:$(goversion) /bin/sh -c "cd /project && make test"

README.md

+45-29
Original file line numberDiff line numberDiff line change
@@ -29,32 +29,47 @@ To update go-nmea to the latest version, use `go get -u github.com/adrianmo/go-n
2929

3030
At this moment, this library supports the following sentence types:
3131

32-
| Sentence type | Description |
33-
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
34-
| [RMC](http://aprs.gids.nl/nmea/#rmc) | Recommended Minimum Specific GPS/Transit data |
35-
| [PMTK](https://www.rhydolabz.com/documents/25/PMTK_A11.pdf) | Messages for setting and reading commands for MediaTek gps modules. |
36-
| [GGA](http://aprs.gids.nl/nmea/#gga) | GPS Positioning System Fix Data |
37-
| [GSA](http://aprs.gids.nl/nmea/#gsa) | GPS DOP and active satellites |
38-
| [GSV](http://aprs.gids.nl/nmea/#gsv) | GPS Satellites in view |
39-
| [GLL](http://aprs.gids.nl/nmea/#gll) | Geographic Position, Latitude / Longitude and time |
40-
| [VTG](http://aprs.gids.nl/nmea/#vtg) | Track Made Good and Ground Speed |
41-
| [ZDA](http://aprs.gids.nl/nmea/#zda) | Date & time data |
42-
| [HDT](http://aprs.gids.nl/nmea/#hdt) | Actual vessel heading in degrees True |
43-
| [GNS](https://www.trimble.com/oem_receiverhelp/v4.44/en/NMEA-0183messages_GNS.html) | Combined GPS fix for GPS, Glonass, Galileo, and BeiDou |
44-
| [PGRME](http://aprs.gids.nl/nmea/#rme) | Estimated Position Error (Garmin proprietary sentence) |
45-
| [THS](http://www.nuovamarea.net/pytheas_9.html) | Actual vessel heading in degrees True and status |
46-
| [VDM/VDO](http://catb.org/gpsd/AIVDM.html) | Encapsulated binary payload |
47-
| [WPL](http://aprs.gids.nl/nmea/#wpl) | Waypoint location |
48-
| [RTE](http://aprs.gids.nl/nmea/#rte) | Route |
49-
| [VHW](https://www.tronico.fi/OH6NT/docs/NMEA0183.pdf) | Water Speed and Heading |
50-
| [DPT](https://gpsd.gitlab.io/gpsd/NMEA.html#_dpt_depth_of_water) | Depth of Water |
51-
| [DBS](https://gpsd.gitlab.io/gpsd/NMEA.html#_dbs_depth_below_surface) | Depth Below Surface |
52-
| [DBT](https://gpsd.gitlab.io/gpsd/NMEA.html#_dbt_depth_below_transducer) | Depth below transducer |
53-
| [MDA](#) | Meteorological Composite |
54-
| [MWD](#) | Wind Direction and Speed |
55-
| [MWV](#) | Wind Speed and Angle |
56-
57-
If you need to parse a message that contains an unsupported sentence type you can implement and register your own message parser and get yourself unblocked immediately. Check the example below to know how to [implement and register a custom message parser](#custom-message-parsing). However, if you think your custom message parser could be beneficial to other users we encourage you to contribute back to the library by submitting a PR and get it included in the list of supported sentences.
32+
| Sentence type | Description |
33+
|-------------------------------------------------------------------------------|-----------------------------------------------------------|
34+
| [RMC](http://aprs.gids.nl/nmea/#rmc) | Recommended Minimum Specific GPS/Transit data |
35+
| [GGA](http://aprs.gids.nl/nmea/#gga) | GPS Positioning System Fix Data |
36+
| [GSA](http://aprs.gids.nl/nmea/#gsa) | GPS DOP and active satellites |
37+
| [GSV](http://aprs.gids.nl/nmea/#gsv) | GPS Satellites in view |
38+
| [GLL](http://aprs.gids.nl/nmea/#gll) | Geographic Position, Latitude / Longitude and time |
39+
| [VTG](http://aprs.gids.nl/nmea/#vtg) | Track Made Good and Ground Speed |
40+
| [ZDA](http://aprs.gids.nl/nmea/#zda) | Date & time data |
41+
| [HDT](http://aprs.gids.nl/nmea/#hdt) | Actual vessel heading in degrees True |
42+
| [HDG](https://gpsd.gitlab.io/gpsd/NMEA.html#_hdg_heading_deviation_variation) | Heading, Deviation & Variation |
43+
| [HDM](https://gpsd.gitlab.io/gpsd/NMEA.html#_hdm_heading_magnetic) | Heading - Magnetic |
44+
| [GNS](https://gpsd.gitlab.io/gpsd/NMEA.html#_gns_fix_data) | Combined GPS fix for GPS, Glonass, Galileo, and BeiDou |
45+
| [VDM/VDO](https://gpsd.gitlab.io/gpsd/AIVDM.html) | Encapsulated binary payload (commonly used with AIS data) |
46+
| [WPL](http://aprs.gids.nl/nmea/#wpl) | Waypoint location |
47+
| [RTE](http://aprs.gids.nl/nmea/#rte) | Route |
48+
| [ROT](https://gpsd.gitlab.io/gpsd/NMEA.html#_rot_rate_of_turn) | Rate of turn |
49+
| [VHW](https://www.tronico.fi/OH6NT/docs/NMEA0183.pdf) | Water Speed and Heading |
50+
| [DPT](https://gpsd.gitlab.io/gpsd/NMEA.html#_dpt_depth_of_water) | Depth of Water |
51+
| [DBS](https://gpsd.gitlab.io/gpsd/NMEA.html#_dbs_depth_below_surface) | Depth Below Surface |
52+
| [DBT](https://gpsd.gitlab.io/gpsd/NMEA.html#_dbt_depth_below_transducer) | Depth below transducer |
53+
| [MDA](https://gpsd.gitlab.io/gpsd/NMEA.html#_mda_meteorological_composite) | Meteorological Composite |
54+
| [MWD](https://www.tronico.fi/OH6NT/docs/NMEA0183.pdf) | Wind Direction and Speed |
55+
| [MWV](https://gpsd.gitlab.io/gpsd/NMEA.html#_mwv_wind_speed_and_angle) | Wind Speed and Angle |
56+
| [MTW](https://gpsd.gitlab.io/gpsd/NMEA.html#_mtw_mean_temperature_of_water) | Mean Temperature of Water |
57+
| [THS](http://www.nuovamarea.net/pytheas_9.html) | Actual vessel heading in degrees True and status |
58+
| [TXT](https://www.nmea.org/Assets/20160520%20txt%20amendment.pdf) | Sentence is for the transmission of text messages |
59+
60+
| Proprietary sentence type | Description |
61+
|-------------------------------------------------------------|-------------------------------------------------------------------------------------------------|
62+
| [PMTK](https://www.rhydolabz.com/documents/25/PMTK_A11.pdf) | Messages for setting and reading commands for MediaTek gps modules. |
63+
| [PGRME](http://aprs.gids.nl/nmea/#rme) | Estimated Position Error (Garmin proprietary sentence) |
64+
| [PSONCMS](#) | Quaternion, acceleration, rate of turn, magnetic field, sensor temperature (Xsens IMU/VRU/AHRS) |
65+
| [PRDID](#) | Vessel pitch, roll and heading (Xsens IMU/VRU/AHRS) |
66+
| [PHTRO](#) | Vessel pitch and roll (Xsens IMU/VRU/AHRS) |
67+
68+
If you need to parse a message that contains an unsupported sentence type you can implement and register your own
69+
message parser and get yourself unblocked immediately. Check the example below to know how
70+
to [implement and register a custom message parser](#custom-message-parsing). However, if you think your custom message
71+
parser could be beneficial to other users we encourage you to contribute back to the library by submitting a PR and get
72+
it included in the list of supported sentences.
5873

5974
## Examples
6075

@@ -147,8 +162,8 @@ TAG Block source: Satelite_1
147162

148163
### Custom message parsing
149164

150-
If you need to parse a message not supported by the library you can implement your own message parsing.
151-
The following example implements a parser for the hypothetical XYZ NMEA sentence type.
165+
If you need to parse a message not supported by the library you can implement your own message parsing. The following
166+
example implements a parser for the hypothetical XYZ NMEA sentence type.
152167

153168
```go
154169
package main
@@ -220,7 +235,8 @@ Value: 5133.820000
220235

221236
## Contributing
222237

223-
Please feel free to submit issues or fork the repository and send pull requests to update the library and fix bugs, implement support for new sentence types, refactor code, etc.
238+
Please feel free to submit issues or fork the repository and send pull requests to update the library and fix bugs,
239+
implement support for new sentence types, refactor code, etc.
224240

225241
## License
226242

dbs.go

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const (
77

88
// DBS - Depth Below Surface
99
// https://gpsd.gitlab.io/gpsd/NMEA.html#_dbs_depth_below_surface
10+
//
11+
// Format: $--DBS,x.x,f,x.x,M,x.x,F*hh<CR><LF>
12+
// Example: $23DBS,01.9,f,0.58,M,00.3,F*21
1013
type DBS struct {
1114
BaseSentence
1215
DepthFeet float64

dbs_test.go

+12-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@ var dbstests = []struct {
1616
name: "good sentence",
1717
raw: "$23DBS,01.9,f,0.58,M,00.3,F*21",
1818
msg: DBS{
19-
DepthFeet: MustParseDecimal("1.9"),
20-
DepthMeters: MustParseDecimal("0.58"),
21-
DepthFathoms: MustParseDecimal("0.3"),
19+
DepthFeet: 1.9,
20+
DepthMeters: 0.58,
21+
DepthFathoms: 0.3,
22+
},
23+
},
24+
{
25+
name: "good sentence 2",
26+
raw: "$SDDBS,,,0187.5,M,,*1A", // Simrad ITI Trawl System
27+
msg: DBS{
28+
DepthFeet: 0,
29+
DepthMeters: 187.5,
30+
DepthFathoms: 0,
2231
},
2332
},
2433
{

dbt.go

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const (
77

88
// DBT - Depth below transducer
99
// https://gpsd.gitlab.io/gpsd/NMEA.html#_dbt_depth_below_transducer
10+
//
11+
// Format: $--DBT,x.x,f,x.x,M,x.x,F*hh<CR><LF>
12+
// Example: $IIDBT,032.93,f,010.04,M,005.42,F*2C
1013
type DBT struct {
1114
BaseSentence
1215
DepthFeet float64

dbt_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ var dbttests = []struct {
1616
name: "good sentence",
1717
raw: "$IIDBT,032.93,f,010.04,M,005.42,F*2C",
1818
msg: DBT{
19-
DepthFeet: MustParseDecimal("32.93"),
20-
DepthMeters: MustParseDecimal("10.04"),
21-
DepthFathoms: MustParseDecimal("5.42"),
19+
DepthFeet: 32.93,
20+
DepthMeters: 10.04,
21+
DepthFathoms: 5.42,
2222
},
2323
},
2424
{

deprecated_test.go

+21-10
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,14 @@ var gnrmctests = []struct {
247247
msg: GNRMC{
248248
Time: Time{true, 22, 05, 16, 0},
249249
Validity: "A",
250+
Latitude: MustParseGPS("5133.82 N"),
251+
Longitude: MustParseGPS("00042.24 W"),
250252
Speed: 173.8,
251253
Course: 231.8,
252254
Date: Date{true, 13, 06, 94},
253255
Variation: -4.2,
254-
Latitude: MustParseGPS("5133.82 N"),
255-
Longitude: MustParseGPS("00042.24 W"),
256+
FFAMode: "",
257+
NavStatus: "",
256258
},
257259
},
258260
{
@@ -261,12 +263,14 @@ var gnrmctests = []struct {
261263
msg: GNRMC{
262264
Time: Time{true, 14, 27, 54, 0},
263265
Validity: "A",
266+
Latitude: MustParseGPS("4302.539570 N"),
267+
Longitude: MustParseGPS("07920.379823 W"),
264268
Speed: 0,
265269
Course: 0,
266270
Date: Date{true, 7, 6, 17},
267271
Variation: 0,
268-
Latitude: MustParseGPS("4302.539570 N"),
269-
Longitude: MustParseGPS("07920.379823 W"),
272+
FFAMode: FAAModeAutonomous,
273+
NavStatus: "",
270274
},
271275
},
272276
{
@@ -275,12 +279,14 @@ var gnrmctests = []struct {
275279
msg: GNRMC{
276280
Time: Time{true, 10, 5, 38, 0},
277281
Validity: "A",
282+
Latitude: MustParseGPS("5546.27711 N"),
283+
Longitude: MustParseGPS("03736.91144 E"),
278284
Speed: 0.061,
279285
Course: 0,
280286
Date: Date{true, 26, 3, 18},
281287
Variation: 0,
282-
Latitude: MustParseGPS("5546.27711 N"),
283-
Longitude: MustParseGPS("03736.91144 E"),
288+
FFAMode: FAAModeAutonomous,
289+
NavStatus: "",
284290
},
285291
},
286292
{
@@ -383,6 +389,7 @@ var gpglltests = []struct {
383389
Millisecond: 0,
384390
},
385391
Validity: "A",
392+
FFAMode: FAAModeAutonomous,
386393
},
387394
},
388395
{
@@ -600,12 +607,14 @@ var gprmctests = []struct {
600607
msg: GPRMC{
601608
Time: Time{true, 22, 5, 16, 0},
602609
Validity: "A",
610+
Latitude: MustParseGPS("5133.82 N"),
611+
Longitude: MustParseGPS("00042.24 W"),
603612
Speed: 173.8,
604613
Course: 231.8,
605614
Date: Date{true, 13, 6, 94},
606615
Variation: -4.2,
607-
Latitude: MustParseGPS("5133.82 N"),
608-
Longitude: MustParseGPS("00042.24 W"),
616+
FFAMode: "",
617+
NavStatus: "",
609618
},
610619
},
611620
{
@@ -614,12 +623,14 @@ var gprmctests = []struct {
614623
msg: GPRMC{
615624
Time: Time{true, 14, 27, 54, 0},
616625
Validity: "A",
626+
Latitude: MustParseGPS("4302.539570 N"),
627+
Longitude: MustParseGPS("07920.379823 W"),
617628
Speed: 0,
618629
Course: 0,
619630
Date: Date{true, 7, 6, 17},
620631
Variation: 0,
621-
Latitude: MustParseGPS("4302.539570 N"),
622-
Longitude: MustParseGPS("07920.379823 W"),
632+
FFAMode: FAAModeAutonomous,
633+
NavStatus: "",
623634
},
624635
},
625636
{

dpt.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,15 @@ const (
77

88
// DPT - Depth of Water
99
// https://gpsd.gitlab.io/gpsd/NMEA.html#_dpt_depth_of_water
10+
//
11+
// Format: $--DPT,x.x,x.x,x.x*hh<CR><LF>
12+
// Example: $SDDPT,0.5,0.5,*7B
13+
// $INDPT,2.3,0.0*46
1014
type DPT struct {
1115
BaseSentence
12-
Depth float64
13-
Offset float64
14-
RangeScale float64
16+
Depth float64 // Water depth relative to transducer, meters
17+
Offset float64 // offset from transducer
18+
RangeScale float64 // OPTIONAL, Maximum range scale in use (NMEA 3.0 and above)
1519
}
1620

1721
// newDPT constructor

dpt_test.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,27 @@ var dpttests = []struct {
1616
name: "good sentence",
1717
raw: "$SDDPT,0.5,0.5,*7B",
1818
msg: DPT{
19-
Depth: MustParseDecimal("0.5"),
20-
Offset: MustParseDecimal("0.5"),
21-
RangeScale: MustParseDecimal("0"),
19+
Depth: 0.5,
20+
Offset: 0.5,
21+
RangeScale: 0,
2222
},
2323
},
2424
{
2525
name: "good sentence with scale",
2626
raw: "$SDDPT,0.5,0.5,0.1*54",
2727
msg: DPT{
28-
Depth: MustParseDecimal("0.5"),
29-
Offset: MustParseDecimal("0.5"),
30-
RangeScale: MustParseDecimal("0.1"),
28+
Depth: 0.5,
29+
Offset: 0.5,
30+
RangeScale: 0.1,
3131
},
3232
},
3333
{
3434
name: "good sentence with 2 fields",
3535
raw: "$INDPT,2.3,0.0*46",
3636
msg: DPT{
37-
Depth: MustParseDecimal("2.3"),
38-
Offset: MustParseDecimal("0.0"),
39-
RangeScale: MustParseDecimal("0"),
37+
Depth: 2.3,
38+
Offset: 0,
39+
RangeScale: 0,
4040
},
4141
},
4242
{

gga.go

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ const (
2020
)
2121

2222
// GGA is the Time, position, and fix related data of the receiver.
23+
// http://aprs.gids.nl/nmea/#gga
24+
// https://gpsd.gitlab.io/gpsd/NMEA.html#_gga_global_positioning_system_fix_data
25+
//
26+
// Format: $--GGA,hhmmss.ss,ddmm.mm,a,ddmm.mm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
27+
// Example: $GNGGA,203415.000,6325.6138,N,01021.4290,E,1,8,2.42,72.5,M,41.5,M,,*7C
2328
type GGA struct {
2429
BaseSentence
2530
Time Time // Time of fix.

gll.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,34 @@ const (
1111

1212
// GLL is Geographic Position, Latitude / Longitude and time.
1313
// http://aprs.gids.nl/nmea/#gll
14+
// https://gpsd.gitlab.io/gpsd/NMEA.html#_gll_geographic_position_latitudelongitude
15+
//
16+
// Format : $--GLL,ddmm.mm,a,dddmm.mm,a,hhmmss.ss,a*hh<CR><LF>
17+
// Format (NMEA 2.3+): $--GLL,ddmm.mm,a,dddmm.mm,a,hhmmss.ss,a,m*hh<CR><LF>
18+
// Example: $IIGLL,5924.462,N,01030.048,E,062216,A*38
19+
// Example: $GNGLL,4404.14012,N,12118.85993,W,001037.00,A,A*67
1420
type GLL struct {
1521
BaseSentence
1622
Latitude float64 // Latitude
1723
Longitude float64 // Longitude
1824
Time Time // Time Stamp
19-
Validity string // validity - A-valid
25+
Validity string // validity - A=valid, V=invalid
26+
FFAMode string // FAA mode indicator (filled in NMEA 2.3 and later)
2027
}
2128

2229
// newGLL constructor
2330
func newGLL(s BaseSentence) (GLL, error) {
2431
p := NewParser(s)
2532
p.AssertType(TypeGLL)
26-
return GLL{
33+
gll := GLL{
2734
BaseSentence: s,
2835
Latitude: p.LatLong(0, 1, "latitude"),
2936
Longitude: p.LatLong(2, 3, "longitude"),
3037
Time: p.Time(4, "time"),
3138
Validity: p.EnumString(5, "validity", ValidGLL, InvalidGLL),
32-
}, p.Err()
39+
}
40+
if len(p.Fields) > 6 {
41+
gll.FFAMode = p.String(6, "FAA mode")
42+
}
43+
return gll, p.Err()
3344
}

gll_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,24 @@ var glltests = []struct {
2626
Millisecond: 0,
2727
},
2828
Validity: "A",
29+
FFAMode: FAAModeAutonomous,
30+
},
31+
},
32+
{
33+
name: "good sentence without FAA mode",
34+
raw: "$IIGLL,5924.462,N,01030.048,E,062216,A*38",
35+
msg: GLL{
36+
Latitude: MustParseLatLong("5924.462 N"),
37+
Longitude: MustParseLatLong("01030.048 E"),
38+
Time: Time{
39+
Valid: true,
40+
Hour: 6,
41+
Minute: 22,
42+
Second: 16,
43+
Millisecond: 0,
44+
},
45+
Validity: "A",
46+
FFAMode: "",
2947
},
3048
},
3149
{

0 commit comments

Comments
 (0)