Skip to content
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

Additional sentences v1 #110

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ on [IEC 61162-1:2016 (Edition 5.0 2016-08)](https://webstore.iec.ch/publication/
| [ALR](./alr.go) | Set alarm state | |
| [APB](./apb.go) | Heading/track controller (autopilot) sentence B | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_apb_autopilot_sentence_b) |
| [ARC](./arc.go) | Alert command refused | |
| [AZT](./azt.go) | Azimuth Thruster message | |
| [BBM](./bbm.go) | AIS broadcast binary message | |
| [BEC](./bec.go) | Bearing and distance to waypoint, Dead reckoning | [1](http://www.nmea.de/nmea0183datensaetze.html#bec) |
| [BOD](./bod.go) | Bearing origin to destination | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_bod_bearing_waypoint_to_waypoint) |
Expand Down Expand Up @@ -95,6 +96,7 @@ on [IEC 61162-1:2016 (Edition 5.0 2016-08)](https://webstore.iec.ch/publication/
| LR3 | AIS long-range reply sentence 3 | |
| LRF | AIS long-range function | |
| LRI | AIS long-range interrogation | |
| [MCP](./mcp.go) | Micropilot Joystick controller message | |
| [MDA](./mda.go) | Meteorological Composite | [gpsd](https://gpsd.gitlab.io/gpsd/NMEA.html#_mda_meteorological_composite) |
| [MTA](./mta.go) | Air Temperature (obsolete, use XDR instead) | |
| MOB | Man over board notification | |
Expand Down
60 changes: 60 additions & 0 deletions azt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package nmea

const (
// TypeAZT type for AZT sentences
TypeAZT = "AZT"
)

// AZT - Azimuth Thruster Message
// Format: $--AZT,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x.x,x*hh<CR><LF>
// Example: $IIAZT,1,45.5,90.0,50.0,60.0,75.0,30.0,40.0,80.0,70.0,3,85.0,0,0,0,12345,9876,5432*2B
type AZT struct {
BaseSentence
ThrusterNo int64 // 1...9 Azimuth thruster number 1..9.
SteeringCommandSetValue float64 // 0...359.9 ° Steering command set value.
SteeringMeasurementActualValue float64 // 0...359.9 ° Steering measurement actual value.
PrimeMoverCommandSetValue float64 // -100...+100 % Prime mover (P.M.) RPM command set value. +100% equals nominal RPM (negative optional).
PrimeMoverMeasurementActualValue float64 // -100...+100 % P.M. RPM measurement actual value. +100% equals nominal RPM (negative optional).
VariableSlippingClutchCommandSetValue float64 // 0...100 % Variable slipping clutch command set value. 100% equals fully engaged clutch (no slipping), 0% equals clutch disengaged. <zero value if not used>.
PitchCommandSetValue float64 // -100...+100 % Pitch command set value. -100% equals max. negative pitch, 0% equals zero pitch, +100% equals max. positive pitch. <zero value if not used>.
PitchMeasurementActualValue float64 // -100...+100 % Pitch measurement actual value. <zero value if not used>.
PMLoadLimitSetValue float64 // 0...120 % P.M. load limit set value (LLS). <zero value if not used>.
PMLoadLimitCurrentMaxValue float64 // 0...120 % P.M. load limit current max. allowed value. <zero value if not used>.
PMLoadMeasurementActualValue float64 // 0...120 % P.M. load measurement actual value (FPS). <zero value if not used>.
ActiveControlStationNumber int64 // 0...9 Active control station number in range of 1…9. Value is zero if no control station is selected.
PropellerRPMMeasurementActualValue float64 // 0...100 % Propeller RPM measurement actual value. +100% equals nominal RPM (used with slipping clutch).
Reserved1 float64 // Reserved for future use. <zero value>.
Reserved2 float64 // Reserved for future use. <zero value>.
Reserved3 float64 // Reserved for future use. <zero value>.
ValueErrorStatusWord int64 // Value error status word for values 1...15, each bit indicates a single value error condition state either OK or ERROR.
ControlStateWord1 int64 // Control state word 1, each bit indicates a separate condition state either ON or OFF.
ControlStateWord2 int64 // Control state word 2 (pitch), each bit indicates a separate condition state either ON or OFF.
}

// newAZT constructor
func newAZT(s BaseSentence) (Sentence, error) {
p := NewParser(s)
p.AssertType(TypeAZT)
return AZT{
BaseSentence: s,
ThrusterNo: p.Int64(0, "x"),
SteeringCommandSetValue: p.Float64(1, "value1"),
SteeringMeasurementActualValue: p.Float64(2, "value2"),
PrimeMoverCommandSetValue: p.Float64(3, "value3"),
PrimeMoverMeasurementActualValue: p.Float64(4, "value4"),
VariableSlippingClutchCommandSetValue: p.Float64(5, "value5"),
PitchCommandSetValue: p.Float64(6, "value6"),
PitchMeasurementActualValue: p.Float64(7, "value7"),
PMLoadLimitSetValue: p.Float64(8, "value8"),
PMLoadLimitCurrentMaxValue: p.Float64(9, "value9"),
PMLoadMeasurementActualValue: p.Float64(10, "value10"),
ActiveControlStationNumber: p.Int64(11, "value11"),
PropellerRPMMeasurementActualValue: p.Float64(12, "value12"),
Reserved1: p.Float64(13, "value13"),
Reserved2: p.Float64(14, "value14"),
Reserved3: p.Float64(15, "value15"),
ValueErrorStatusWord: p.Int64(16, "vesw"),
ControlStateWord1: p.Int64(17, "csw1"),
ControlStateWord2: p.Int64(18, "csw2"),
}, p.Err()
}
61 changes: 61 additions & 0 deletions azt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package nmea

import (
"github.com/stretchr/testify/assert"
"testing"
)

var azttests = []struct {
name string
raw string
err string
msg AZT
}{
{
name: "good sentence",
raw: "$IIAZT,1,45.5,90.0,50.0,60.0,75.0,30.0,40.0,80.0,70.0,70.0,3,85.0,0,0,0,12345,9876,5432*70",
msg: AZT{
ThrusterNo: 1,
SteeringCommandSetValue: 45.5,
SteeringMeasurementActualValue: 90.0,
PrimeMoverCommandSetValue: 50.0,
PrimeMoverMeasurementActualValue: 60.0,
VariableSlippingClutchCommandSetValue: 75.0,
PitchCommandSetValue: 30.0,
PitchMeasurementActualValue: 40.0,
PMLoadLimitSetValue: 80.0,
PMLoadLimitCurrentMaxValue: 70.0,
PMLoadMeasurementActualValue: 70.0,
ActiveControlStationNumber: 3,
PropellerRPMMeasurementActualValue: 85.0,
Reserved1: 0,
Reserved2: 0,
Reserved3: 0,
ValueErrorStatusWord: 12345,
ControlStateWord1: 9876,
ControlStateWord2: 5432,
},
},
{
name: "bad validity",
raw: "$IIAZT,1,45.5,90.0,50.0,60.0,75.0,30.0,40.0,80.0,70.0,70.0,3,85.0,0,0,0,12345,9876,5432*74",
err: "nmea: sentence checksum mismatch [70 != 74]",
},
}

func TestAZT(t *testing.T) {
for _, tt := range azttests {
t.Run(tt.name, func(t *testing.T) {
m, err := Parse(tt.raw)
if tt.err != "" {
assert.Error(t, err)
assert.EqualError(t, err, tt.err)
} else {
assert.NoError(t, err)
azt := m.(AZT)
azt.BaseSentence = BaseSentence{}
assert.Equal(t, tt.msg, azt)
}
})
}
}
38 changes: 38 additions & 0 deletions mcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package nmea

const (
// TypeMCP type for MCP sentences
TypeMCP = "MCP"
)

// MCP - Micropilot Joystick Controller Message
// Format: $--MCP,x.x,f,x.x,f,x.x,f,x.x,f,x.x,f,x,i,x,i,x,i*hh<CR><LF>
// Example: $IIMCP,50.0,%f,30.0,%f,45.0,%f,0,0,0*hh
type MCP struct {
BaseSentence
JoystickSurgeAxisCommandSetValue float64 // Joystick surge axis (ahead - astern) command set value.
JoystickSwayAxisCommandSetValue float64 // Joystick sway axis (sideways port - sideways starboard) command set value.
JoystickYawAxisCommandSetValue float64 // Joystick yaw axis (rotation counter-clockwise - clockwise) command set value.
Reserved1 float64 // Reserved for future use.
Reserved2 float64 // Reserved for future use.
ValueErrorStatusWord int64 // Value error status word for values 1...5, each bit indicates a single value error condition state either OK or ERROR.
ControlStateWord1 int64 // Control state word 1, each bit indicates a separate condition state either ON or OFF.
ControlStateWord2 int64 // Control state word 2, each bit indicates a separate condition state either ON or OFF.
}

// newMCP constructor
func newMCP(s BaseSentence) (Sentence, error) {
p := NewParser(s)
p.AssertType(TypeMCP)
return MCP{
BaseSentence: s,
JoystickSurgeAxisCommandSetValue: p.Float64(0, "value1"),
JoystickSwayAxisCommandSetValue: p.Float64(1, "value2"),
JoystickYawAxisCommandSetValue: p.Float64(2, "value3"),
Reserved1: p.Float64(3, "value4"),
Reserved2: p.Float64(4, "value5"),
ValueErrorStatusWord: p.Int64(5, "vesw"),
ControlStateWord1: p.Int64(6, "csw1"),
ControlStateWord2: p.Int64(7, "csw2"),
}, p.Err()
}
50 changes: 50 additions & 0 deletions mcp_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package nmea

import (
"github.com/stretchr/testify/assert"
"testing"
)

var mcptests = []struct {
name string
raw string
err string
msg MCP
}{
{
name: "good sentence",
raw: "$IIMCP,50.0,25.0,10.0,0,0,12345,9876,5432*72",
msg: MCP{
JoystickSurgeAxisCommandSetValue: 50.0,
JoystickSwayAxisCommandSetValue: 25.0,
JoystickYawAxisCommandSetValue: 10.0,
Reserved1: 0,
Reserved2: 0,
ValueErrorStatusWord: 12345,
ControlStateWord1: 9876,
ControlStateWord2: 5432,
},
},
{
name: "bad validity",
raw: "$IIMCP,50.0,25.0,10.0,0,0,12345,9876,5432*64",
err: "nmea: sentence checksum mismatch [72 != 64]",
},
}

func TestMCP(t *testing.T) {
for _, tt := range mcptests {
t.Run(tt.name, func(t *testing.T) {
m, err := Parse(tt.raw)
if tt.err != "" {
assert.Error(t, err)
assert.EqualError(t, err, tt.err)
} else {
assert.NoError(t, err)
mcp := m.(MCP)
mcp.BaseSentence = BaseSentence{}
assert.Equal(t, tt.msg, mcp)
}
})
}
}
4 changes: 4 additions & 0 deletions sentence.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ func (p *SentenceParser) Parse(raw string) (Sentence, error) {
return newXDR(s)
case TypeXTE:
return newXTE(s)
case TypeMCP:
return newMCP(s)
case TypeAZT:
return newAZT(s)
}
}
if s.Raw[0] == SentenceStartEncapsulated[0] {
Expand Down