Skip to content

Commit

Permalink
implemented new PGRME sentence type support
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianmo committed Aug 24, 2015
1 parent 129f87e commit 76321c6
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -20,6 +20,7 @@ At this moment, this library supports the following sentence types:
- [GPGGA](http://aprs.gids.nl/nmea/#gga) - Global Positioning System Fix Data
- [GPGSA](http://aprs.gids.nl/nmea/#gsa) - GPS DOP and active satellites
- [GPGLL](http://aprs.gids.nl/nmea/#gll) - Geographic Position, Latitude / Longitude and time
- [PGRME](http://aprs.gids.nl/nmea/#rme) - Estimated Position Error (Garmin proprietary sentence)

I will implement new types whenever I find some time. Also feel free to implement it yourself and send a pull-request to include it to the library.

Expand Down
6 changes: 6 additions & 0 deletions nmea.go
Expand Up @@ -107,6 +107,12 @@ func Parse(s string) (SentenceI, error) {
return nil, err
}
return gpgll, nil
} else if sentence.Type == PrefixPGRME {
pgrme := NewPGRME(sentence)
if err := pgrme.parse(); err != nil {
return nil, err
}
return pgrme, nil
}

err := fmt.Errorf("Sentence type '%s' not implemented", sentence.Type)
Expand Down
71 changes: 71 additions & 0 deletions pgrme.go
@@ -0,0 +1,71 @@
package nmea

import (
"fmt"
"strconv"
)

const (
// PrefixPGRME prefix for PGRME sentence type
PrefixPGRME = "PGRME"
// ErrorUnit must be meters (M)
ErrorUnit = "M"
)

// PGRME is Estimated Position Error (Garmin proprietary sentence)
// http://aprs.gids.nl/nmea/#rme
type PGRME struct {
Sentence
Horizontal float64 // Estimated horizontal position error (HPE) in metres
Vertical float64 // Estimated vertical position error (VPE) in metres
Spherical float64 // Overall spherical equivalent position error in meters
}

// NewPGRME constructor
func NewPGRME(sentence Sentence) PGRME {
s := new(PGRME)
s.Sentence = sentence
return *s
}

// GetSentence getter
func (s PGRME) GetSentence() Sentence {
return s.Sentence
}

func (s *PGRME) parse() error {
var err error

if s.Type != PrefixPGRME {
return fmt.Errorf("%s is not a %s", s.Type, PrefixPGRME)
}

s.Horizontal, err = strconv.ParseFloat(s.Fields[0], 64)
if err != nil {
return fmt.Errorf("PGRME decode invalid horizontal error: '%s'", s.Fields[0])
}

if s.Fields[1] != ErrorUnit {
return fmt.Errorf("PGRME decode invalid horizontal error unit: '%s'", s.Fields[1])
}

s.Vertical, err = strconv.ParseFloat(s.Fields[2], 64)
if err != nil {
return fmt.Errorf("PGRME decode invalid vertical error: '%s'", s.Fields[2])
}

if s.Fields[3] != ErrorUnit {
return fmt.Errorf("PGRME decode invalid vertical error unit: '%s'", s.Fields[3])
}

s.Spherical, err = strconv.ParseFloat(s.Fields[4], 64)
if err != nil {
return fmt.Errorf("PGRME decode invalid spherical error: '%s'", s.Fields[4])
}

if s.Fields[5] != ErrorUnit {
return fmt.Errorf("PGRME decode invalid spherical error unit: '%s'", s.Fields[5])
}

return nil
}
70 changes: 70 additions & 0 deletions pgrme_test.go
@@ -0,0 +1,70 @@
package nmea

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestPGRMEGoodSentence(t *testing.T) {
goodMsg := "$PGRME,3.3,M,4.9,M,6.0,M*25"
s, err := Parse(goodMsg)

assert.NoError(t, err, "Unexpected error parsing good sentence")
assert.Equal(t, PrefixPGRME, s.GetSentence().Type, "Prefix does not match")

sentence := s.(PGRME)

assert.Equal(t, 3.3, sentence.Horizontal, "Horizontal error does not match")
assert.Equal(t, 4.9, sentence.Vertical, "Vertical error does not match")
assert.Equal(t, 6.0, sentence.Spherical, "Spherical error does not match")

}

func TestPGRMEInvalidHorizontalError(t *testing.T) {
badMsg := "$PGRME,A,M,4.9,M,6.0,M*4A"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid horizontal error: 'A'", err.Error(), "Incorrect error message")
}

func TestPGRMEInvalidHorizontalErrorUnit(t *testing.T) {
badMsg := "$PGRME,3.3,A,4.9,M,6.0,M*29"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid horizontal error unit: 'A'", err.Error(), "Incorrect error message")
}

func TestPGRMEInvalidVerticalError(t *testing.T) {
badMsg := "$PGRME,3.3,M,A,M,6.0,M*47"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid vertical error: 'A'", err.Error(), "Incorrect error message")
}

func TestPGRMEInvalidVerticalErrorUnit(t *testing.T) {
badMsg := "$PGRME,3.3,M,4.9,A,6.0,M*29"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid vertical error unit: 'A'", err.Error(), "Incorrect error message")
}

func TestPGRMEInvalidSphericalError(t *testing.T) {
badMsg := "$PGRME,3.3,M,4.9,M,A,M*4C"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid spherical error: 'A'", err.Error(), "Incorrect error message")
}

func TestPGRMEInvalidSphericalErrorUnit(t *testing.T) {
badMsg := "$PGRME,3.3,M,4.9,M,6.0,A*29"
_, err := Parse(badMsg)

assert.Error(t, err, "Parse error not returned")
assert.Equal(t, "PGRME decode invalid spherical error unit: 'A'", err.Error(), "Incorrect error message")
}

0 comments on commit 76321c6

Please sign in to comment.