Skip to content

Commit 7e728f7

Browse files
authored
add pashr sentence (#119)
1 parent e4d24e3 commit 7e728f7

File tree

5 files changed

+161
-34
lines changed

5 files changed

+161
-34
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ on [IEC 61162-1:2016 (Edition 5.0 2016-08)](https://webstore.iec.ch/publication/
4646
| [ALF](./alf.go) | Alert sentence | |
4747
| [ALR](./alr.go) | Set alarm state | |
4848
| [APB](./apb.go) | Heading/track controller (autopilot) sentence B | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_apb_autopilot_sentence_b) |
49-
| [ARC](./arc.go) | Alert command refused | |
49+
| [ARC](./arc.go) | Alert command refused | |
5050
| [BBM](./bbm.go) | AIS broadcast binary message | |
5151
| [BEC](./bec.go) | Bearing and distance to waypoint, Dead reckoning | [1](http://www.nmea.de/nmea0183datensaetze.html#bec) |
5252
| [BOD](./bod.go) | Bearing origin to destination | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_bod_bearing_waypoint_to_waypoint) |
@@ -174,6 +174,7 @@ on [IEC 61162-1:2016 (Edition 5.0 2016-08)](https://webstore.iec.ch/publication/
174174

175175
| Proprietary sentence type | Description | References |
176176
|---------------------------|-------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
177+
| [PASHR](./pashr.go) | Proprietary - Heading, Pitch, Roll, Heave, Time | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_pashr_rt300_proprietary_roll_and_pitch_sentence) [trimble](https://receiverhelp.trimble.com/oem-gnss/nmea0183-messages-pashr.html) |
177178
| [PNG](./pgn.go) | Transfer NMEA2000 frame as NMEA0183 sentence (ShipModul MiniPlex-3) | [1](https://opencpn.org/wiki/dokuwiki/lib/exe/fetch.php?media=opencpn:software:mxpgn_sentence.pdf) |
178179
| [PCDIN](./pcdin.go) | Transfer NMEA2000 frame as NMEA0183 sentence (SeaSmart.Net Protocol) | [1](http://www.seasmart.net/pdf/SeaSmart_HTTP_Protocol_RevG_043012.pdf) |
179180
| [PGRME](./pgrme.go) | Estimated Position Error (Garmin proprietary sentence) | [1](http://aprs.gids.nl/nmea/#rme) |

go.sum

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
66
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
77
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
88
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
9-
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
10-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
11-
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
12-
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
13-
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
14-
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
15-
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
16-
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
17-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
18-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
19-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
20-
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
21-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
22-
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
23-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
24-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
25-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
26-
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
27-
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
28-
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
29-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
30-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
31-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
32-
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
33-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
34-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
35-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
36-
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
37-
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
38-
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
39-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
40-
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
41-
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
429
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4310
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4411
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

pashr.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package nmea
2+
3+
const (
4+
// TypePASHR type for ASHR sentences
5+
TypePASHR = "ASHR"
6+
)
7+
8+
// PASHR represents proprietary roll and pitch sentence
9+
// https://gpsd.gitlab.io/gpsd/NMEA.html#_pashr_rt300_proprietary_roll_and_pitch_sentence
10+
//
11+
// Format: $-PASHR,hhmmss.sss,hhh.hh,T,rrr.rr,ppp.pp,xxx.xx,a.aaa,b.bbb,c.ccc,d,e*hh<CR><LF>
12+
// Example: $PASHR,085335.000,224.19,T,-01.26,+00.83,+00.10,0.101,0.113,0.267,1,0*07
13+
type PASHR struct {
14+
BaseSentence
15+
Time Time
16+
Heading float64
17+
TrueHeading string
18+
Roll float64
19+
Pitch float64
20+
Heave float64
21+
RollAccuracy float64
22+
PitchAccuracy float64
23+
HeadingAccuracy float64
24+
// GNSSQuality is the quality of the GNSS signal
25+
// The documentation differs from Trimble and Novatel about the meaning of the number.
26+
//
27+
// Trimble https://receiverhelp.trimble.com/oem-gnss/nmea0183-messages-pashr.html
28+
//
29+
// 0 – Fix not available
30+
//
31+
// 1 – GNSS mode, fix valid
32+
//
33+
// 2 – Differential GPS
34+
//
35+
// 3 – GNSS PPS mode
36+
//
37+
// 4 – Fixed RTK mode
38+
//
39+
// 5 – Float RTK mode
40+
//
41+
// 6 – DR mode
42+
//
43+
// Novatel https://docs.novatel.com/OEM7/Content/SPAN_Logs/PASHR.htm
44+
//
45+
// 0 = No position
46+
//
47+
// 1 = All non-RTK fixed integer positions
48+
//
49+
// 2 = RTK fixed integer position
50+
GNSSQuality int64
51+
// IMUAlignmentStatus is the status of the IMU alignment
52+
// The documentation differs from Trimble and Novatel about the meaning of the number.
53+
//
54+
// Trimble https://receiverhelp.trimble.com/oem-gnss/nmea0183-messages-pashr.html
55+
// 0 – GPS Only
56+
//
57+
// 1 – Coarse Leveling
58+
//
59+
// 2 – Degraded Solution
60+
//
61+
// 3 – Aligned
62+
//
63+
// 4 – Full Navigation Mode
64+
//
65+
// Novatel https://docs.novatel.com/OEM7/Content/SPAN_Logs/PASHR.htm
66+
//
67+
// 0 = All SPAN Pre-Alignment INS Status
68+
//
69+
// 1 = All SPAN Post-Alignment INS Status - These include: INS_ALIGNMENT_COMPLETE, INS_SOLUTION_GOOD, INS_HIGH_VARIANCE, INS_SOLUTION_FREE
70+
IMUAlignmentStatus int64
71+
}
72+
73+
// newPASHR constructor
74+
func newPASHR(s BaseSentence) (Sentence, error) {
75+
p := NewParser(s)
76+
p.AssertType(TypePASHR)
77+
return PASHR{
78+
BaseSentence: s,
79+
Time: p.Time(0, "time"),
80+
Heading: p.Float64(1, "heading"),
81+
TrueHeading: p.EnumString(2, "true heading", "T", "F"),
82+
Roll: p.Float64(3, "roll"),
83+
Pitch: p.Float64(4, "pitch"),
84+
Heave: p.Float64(5, "heave"),
85+
RollAccuracy: p.Float64(6, "roll accuracy"),
86+
PitchAccuracy: p.Float64(7, "pitch accuracy"),
87+
HeadingAccuracy: p.Float64(8, "heading accuracy"),
88+
GNSSQuality: p.Int64(9, "gnss quality"),
89+
IMUAlignmentStatus: p.Int64(10, "imu alignment status"),
90+
}, p.Err()
91+
}

pashr_test.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package nmea
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
var pashrtests = []struct {
10+
name string
11+
raw string
12+
err string
13+
msg PASHR
14+
}{
15+
{
16+
name: "good sentence A",
17+
raw: "$PASHR,085335.000,224.19,T,-01.26,+00.83,+00.10,0.101,0.113,0.267,1,0*07",
18+
msg: PASHR{
19+
Time: Time{
20+
Valid: true,
21+
Hour: 8,
22+
Minute: 53,
23+
Second: 35,
24+
Millisecond: 0,
25+
},
26+
Heading: 224.19,
27+
TrueHeading: "T",
28+
Roll: -1.26,
29+
Pitch: 0.83,
30+
Heave: 0.1,
31+
RollAccuracy: 0.101,
32+
PitchAccuracy: 0.113,
33+
HeadingAccuracy: 0.267,
34+
GNSSQuality: 1,
35+
IMUAlignmentStatus: 0,
36+
},
37+
},
38+
{
39+
name: "invalid checksum",
40+
raw: "$PASHR,085335.000,224.19,T,-01.26,+00.83,+00.10,0.101,0.0,0.267,1,0*07",
41+
err: "nmea: sentence checksum mismatch [04 != 07]",
42+
},
43+
{
44+
name: "invalid true heading value",
45+
raw: "$PASHR,085335.000,224.19,X,-01.26,+00.83,+00.10,0.101,0.113,0.267,1,0*0B",
46+
err: "nmea: PASHR invalid true heading: X",
47+
},
48+
}
49+
50+
func TestPASHR(t *testing.T) {
51+
for _, tt := range pashrtests {
52+
t.Run(tt.name, func(t *testing.T) {
53+
54+
m, err := Parse(tt.raw)
55+
if tt.err != "" {
56+
assert.Error(t, err)
57+
assert.EqualError(t, err, tt.err)
58+
} else {
59+
assert.NoError(t, err)
60+
pashr := m.(PASHR)
61+
pashr.BaseSentence = BaseSentence{}
62+
assert.Equal(t, tt.msg, pashr)
63+
}
64+
})
65+
}
66+
}

sentence.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,8 @@ func (p *SentenceParser) Parse(raw string) (Sentence, error) {
445445
return newPKNDS(s)
446446
case TypePKWDWPL:
447447
return newPKWDWPL(s)
448+
case TypePASHR:
449+
return newPASHR(s)
448450
}
449451
}
450452
if s.Raw[0] == SentenceStartEncapsulated[0] {

0 commit comments

Comments
 (0)