mirror of
https://github.com/bettercap/bettercap
synced 2025-07-16 10:03:39 -07:00
misc: updated go-nmea dependency and refactored code for v1.1.0
This commit is contained in:
parent
f8ede4ddbe
commit
3d1936ef61
22 changed files with 262 additions and 205 deletions
5
Gopkg.lock
generated
5
Gopkg.lock
generated
|
@ -2,11 +2,12 @@
|
|||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:fa526d5f6ec66a1833c687768639251d6db3bc3b7f32abd0265ae9625a9233de"
|
||||
digest = "1:4132a4623657c2ba93a7cf83dccc6869b3e3bb91dc2afefa7c7032e10ceeaa12"
|
||||
name = "github.com/adrianmo/go-nmea"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "22095aa1b48050243d3eb9a001ca80eb91a0c6fa"
|
||||
revision = "a32116e4989e2b0e17c057ee378b4d5246add74e"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
|
|
|
@ -93,6 +93,10 @@
|
|||
branch = "master"
|
||||
name = "github.com/tarm/serial"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/adrianmo/go-nmea"
|
||||
version = "1.1.0"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
|
|
@ -129,13 +129,10 @@ func (gps *GPS) Start() error {
|
|||
|
||||
for gps.Running() {
|
||||
if line, err := gps.readLine(); err == nil {
|
||||
if info, err := nmea.Parse(line); err == nil {
|
||||
s := info.Sentence()
|
||||
if s, err := nmea.Parse(line); err == nil {
|
||||
// http://aprs.gids.nl/nmea/#gga
|
||||
if s.Type == "GNGGA" {
|
||||
gps.Session.GPS = info.(nmea.GNGGA)
|
||||
} else {
|
||||
log.Debug("Skipping message %s: %v", s.Type, s)
|
||||
if m, ok := s.(nmea.GNGGA); ok {
|
||||
gps.Session.GPS = m
|
||||
}
|
||||
} else {
|
||||
log.Debug("Error parsing line '%s': %s", line, err)
|
||||
|
|
5
vendor/github.com/adrianmo/go-nmea/.travis.yml
generated
vendored
5
vendor/github.com/adrianmo/go-nmea/.travis.yml
generated
vendored
|
@ -5,7 +5,10 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.7.x
|
||||
- 1.8.x
|
||||
- 1.9.x
|
||||
- 1.10.x
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
|
|
45
vendor/github.com/adrianmo/go-nmea/README.md
generated
vendored
45
vendor/github.com/adrianmo/go-nmea/README.md
generated
vendored
|
@ -27,6 +27,7 @@ At this moment, this library supports the following sentence types:
|
|||
- [GPVTG](http://aprs.gids.nl/nmea/#vtg) - Track Made Good and Ground Speed
|
||||
- [GPZDA](http://aprs.gids.nl/nmea/#zda) - Date & time data
|
||||
- [PGRME](http://aprs.gids.nl/nmea/#rme) - Estimated Position Error (Garmin proprietary sentence)
|
||||
- [GPHDT](http://aprs.gids.nl/nmea/#hdt) - Actual vessel heading in degrees True
|
||||
|
||||
|
||||
## Example
|
||||
|
@ -35,18 +36,50 @@ At this moment, this library supports the following sentence types:
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/adrianmo/go-nmea"
|
||||
"fmt"
|
||||
"log"
|
||||
"github.com/adrianmo/go-nmea"
|
||||
)
|
||||
|
||||
func main() {
|
||||
m, err := nmea.Parse("$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)
|
||||
}
|
||||
sentence := "$GPRMC,220516,A,5133.82,N,00042.24,W,173.8,231.8,130694,004.2,W*70"
|
||||
s, err := nmea.Parse(sentence)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
m := s.(nmea.GPRMC)
|
||||
fmt.Printf("Raw sentence: %v\n", m)
|
||||
fmt.Printf("Time: %s\n", m.Time)
|
||||
fmt.Printf("Validity: %s\n", m.Validity)
|
||||
fmt.Printf("Latitude GPS: %s\n", nmea.FormatGPS(m.Latitude))
|
||||
fmt.Printf("Latitude DMS: %s\n", nmea.FormatDMS(m.Latitude))
|
||||
fmt.Printf("Longitude GPS: %s\n", nmea.FormatGPS(m.Longitude))
|
||||
fmt.Printf("Longitude DMS: %s\n", nmea.FormatDMS(m.Longitude))
|
||||
fmt.Printf("Speed: %f\n", m.Speed)
|
||||
fmt.Printf("Course: %f\n", m.Course)
|
||||
fmt.Printf("Date: %s\n", m.Date)
|
||||
fmt.Printf("Variation: %f\n", m.Variation)
|
||||
}
|
||||
```
|
||||
|
||||
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.800000
|
||||
Course: 231.800000
|
||||
Date: 13/06/94
|
||||
Variation: -4.200000
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Please, feel free to implement support for new sentences, fix bugs, refactor code, etc. and send a pull-request to update the library.
|
||||
|
|
1
vendor/github.com/adrianmo/go-nmea/VERSION
generated
vendored
Normal file
1
vendor/github.com/adrianmo/go-nmea/VERSION
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
v1.1.0
|
8
vendor/github.com/adrianmo/go-nmea/glgsv.go
generated
vendored
8
vendor/github.com/adrianmo/go-nmea/glgsv.go
generated
vendored
|
@ -8,7 +8,7 @@ const (
|
|||
// GLGSV represents the GPS Satellites in view
|
||||
// http://aprs.gids.nl/nmea/#glgsv
|
||||
type GLGSV struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
TotalMessages int64 // Total number of messages of this type in this cycle
|
||||
MessageNumber int64 // Message number
|
||||
NumberSVsInView int64 // Total number of SVs in view
|
||||
|
@ -23,11 +23,11 @@ type GLGSVInfo struct {
|
|||
SNR int64 // SNR, 00-99 dB (null when not tracking)
|
||||
}
|
||||
|
||||
// NewGLGSV constructor
|
||||
func NewGLGSV(s Sent) (GLGSV, error) {
|
||||
// newGLGSV constructor
|
||||
func newGLGSV(s BaseSentence) (GLGSV, error) {
|
||||
p := newParser(s, PrefixGLGSV)
|
||||
m := GLGSV{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
TotalMessages: p.Int64(0, "total number of messages"),
|
||||
MessageNumber: p.Int64(1, "message number"),
|
||||
NumberSVsInView: p.Int64(2, "number of SVs in view"),
|
||||
|
|
16
vendor/github.com/adrianmo/go-nmea/gngga.go
generated
vendored
16
vendor/github.com/adrianmo/go-nmea/gngga.go
generated
vendored
|
@ -7,10 +7,10 @@ const (
|
|||
|
||||
// GNGGA is the Time, position, and fix related data of the receiver.
|
||||
type GNGGA struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Time Time // Time of fix.
|
||||
Latitude LatLong // Latitude.
|
||||
Longitude LatLong // Longitude.
|
||||
Latitude float64 // Latitude.
|
||||
Longitude float64 // Longitude.
|
||||
FixQuality string // Quality of fix.
|
||||
NumSatellites int64 // Number of satellites in use.
|
||||
HDOP float64 // Horizontal dilution of precision.
|
||||
|
@ -20,16 +20,16 @@ type GNGGA struct {
|
|||
DGPSId string // DGPS reference station ID.
|
||||
}
|
||||
|
||||
// NewGNGGA constructor
|
||||
func NewGNGGA(s Sent) (GNGGA, error) {
|
||||
// newGNGGA constructor
|
||||
func newGNGGA(s BaseSentence) (GNGGA, error) {
|
||||
p := newParser(s, PrefixGNGGA)
|
||||
return GNGGA{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Latitude: p.LatLong(1, 2, "latitude"),
|
||||
Longitude: p.LatLong(3, 4, "longitude"),
|
||||
FixQuality: p.EnumString(5, "fix quality", Invalid, GPS, DGPS),
|
||||
NumSatellites: p.Int64(6, "number of satelites"),
|
||||
FixQuality: p.EnumString(5, "fix quality", Invalid, GPS, DGPS, PPS, RTK, FRTK),
|
||||
NumSatellites: p.Int64(6, "number of satellites"),
|
||||
HDOP: p.Float64(7, "hdop"),
|
||||
Altitude: p.Float64(8, "altitude"),
|
||||
Separation: p.Float64(10, "separation"),
|
||||
|
|
28
vendor/github.com/adrianmo/go-nmea/gnrmc.go
generated
vendored
28
vendor/github.com/adrianmo/go-nmea/gnrmc.go
generated
vendored
|
@ -8,30 +8,30 @@ const (
|
|||
// GNRMC is the Recommended Minimum Specific GNSS data.
|
||||
// http://aprs.gids.nl/nmea/#rmc
|
||||
type GNRMC struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Time Time // Time Stamp
|
||||
Validity string // validity - A-ok, V-invalid
|
||||
Latitude LatLong // Latitude
|
||||
Longitude LatLong // Longitude
|
||||
Latitude float64 // Latitude
|
||||
Longitude float64 // Longitude
|
||||
Speed float64 // Speed in knots
|
||||
Course float64 // True course
|
||||
Date Date // Date
|
||||
Variation float64 // Magnetic variation
|
||||
}
|
||||
|
||||
// NewGNRMC constructor
|
||||
func NewGNRMC(s Sent) (GNRMC, error) {
|
||||
// newGNRMC constructor
|
||||
func newGNRMC(s BaseSentence) (GNRMC, error) {
|
||||
p := newParser(s, PrefixGNRMC)
|
||||
m := GNRMC{
|
||||
Sent: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Validity: p.EnumString(1, "validity", ValidRMC, InvalidRMC),
|
||||
Latitude: p.LatLong(2, 3, "latitude"),
|
||||
Longitude: p.LatLong(4, 5, "longitude"),
|
||||
Speed: p.Float64(6, "speed"),
|
||||
Course: p.Float64(7, "course"),
|
||||
Date: p.Date(8, "date"),
|
||||
Variation: p.Float64(9, "variation"),
|
||||
BaseSentence: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Validity: p.EnumString(1, "validity", ValidRMC, InvalidRMC),
|
||||
Latitude: p.LatLong(2, 3, "latitude"),
|
||||
Longitude: p.LatLong(4, 5, "longitude"),
|
||||
Speed: p.Float64(6, "speed"),
|
||||
Course: p.Float64(7, "course"),
|
||||
Date: p.Date(8, "date"),
|
||||
Variation: p.Float64(9, "variation"),
|
||||
}
|
||||
if p.EnumString(10, "direction", West, East) == West {
|
||||
m.Variation = 0 - m.Variation
|
||||
|
|
3
vendor/github.com/adrianmo/go-nmea/go.mod
generated
vendored
Normal file
3
vendor/github.com/adrianmo/go-nmea/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
module github.com/adrianmo/go-nmea
|
||||
|
||||
require github.com/stretchr/testify v1.2.1
|
22
vendor/github.com/adrianmo/go-nmea/gpgga.go
generated
vendored
22
vendor/github.com/adrianmo/go-nmea/gpgga.go
generated
vendored
|
@ -9,15 +9,21 @@ const (
|
|||
GPS = "1"
|
||||
// DGPS fix quality
|
||||
DGPS = "2"
|
||||
// PPS fix
|
||||
PPS = "3"
|
||||
// RTK real time kinematic fix
|
||||
RTK = "4"
|
||||
// FRTK float RTK fix
|
||||
FRTK = "5"
|
||||
)
|
||||
|
||||
// GPGGA represents fix data.
|
||||
// http://aprs.gids.nl/nmea/#gga
|
||||
type GPGGA struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Time Time // Time of fix.
|
||||
Latitude LatLong // Latitude.
|
||||
Longitude LatLong // Longitude.
|
||||
Latitude float64 // Latitude.
|
||||
Longitude float64 // Longitude.
|
||||
FixQuality string // Quality of fix.
|
||||
NumSatellites int64 // Number of satellites in use.
|
||||
HDOP float64 // Horizontal dilution of precision.
|
||||
|
@ -27,17 +33,17 @@ type GPGGA struct {
|
|||
DGPSId string // DGPS reference station ID.
|
||||
}
|
||||
|
||||
// NewGPGGA parses the GPGGA sentence into this struct.
|
||||
// newGPGGA parses the GPGGA sentence into this struct.
|
||||
// e.g: $GPGGA,034225.077,3356.4650,S,15124.5567,E,1,03,9.7,-25.0,M,21.0,M,,0000*58
|
||||
func NewGPGGA(s Sent) (GPGGA, error) {
|
||||
func newGPGGA(s BaseSentence) (GPGGA, error) {
|
||||
p := newParser(s, PrefixGPGGA)
|
||||
return GPGGA{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Latitude: p.LatLong(1, 2, "latitude"),
|
||||
Longitude: p.LatLong(3, 4, "longitude"),
|
||||
FixQuality: p.EnumString(5, "fix quality", Invalid, GPS, DGPS),
|
||||
NumSatellites: p.Int64(6, "number of satelites"),
|
||||
FixQuality: p.EnumString(5, "fix quality", Invalid, GPS, DGPS, PPS, RTK, FRTK),
|
||||
NumSatellites: p.Int64(6, "number of satellites"),
|
||||
HDOP: p.Float64(7, "hdap"),
|
||||
Altitude: p.Float64(8, "altitude"),
|
||||
Separation: p.Float64(10, "separation"),
|
||||
|
|
20
vendor/github.com/adrianmo/go-nmea/gpgll.go
generated
vendored
20
vendor/github.com/adrianmo/go-nmea/gpgll.go
generated
vendored
|
@ -12,21 +12,21 @@ const (
|
|||
// GPGLL is Geographic Position, Latitude / Longitude and time.
|
||||
// http://aprs.gids.nl/nmea/#gll
|
||||
type GPGLL struct {
|
||||
Sent
|
||||
Latitude LatLong // Latitude
|
||||
Longitude LatLong // Longitude
|
||||
BaseSentence
|
||||
Latitude float64 // Latitude
|
||||
Longitude float64 // Longitude
|
||||
Time Time // Time Stamp
|
||||
Validity string // validity - A-valid
|
||||
}
|
||||
|
||||
// NewGPGLL constructor
|
||||
func NewGPGLL(s Sent) (GPGLL, error) {
|
||||
// newGPGLL constructor
|
||||
func newGPGLL(s BaseSentence) (GPGLL, error) {
|
||||
p := newParser(s, PrefixGPGLL)
|
||||
return GPGLL{
|
||||
Sent: s,
|
||||
Latitude: p.LatLong(0, 1, "latitude"),
|
||||
Longitude: p.LatLong(2, 3, "longitude"),
|
||||
Time: p.Time(4, "time"),
|
||||
Validity: p.EnumString(5, "validity", ValidGLL, InvalidGLL),
|
||||
BaseSentence: s,
|
||||
Latitude: p.LatLong(0, 1, "latitude"),
|
||||
Longitude: p.LatLong(2, 3, "longitude"),
|
||||
Time: p.Time(4, "time"),
|
||||
Validity: p.EnumString(5, "validity", ValidGLL, InvalidGLL),
|
||||
}, p.Err()
|
||||
}
|
||||
|
|
14
vendor/github.com/adrianmo/go-nmea/gpgsa.go
generated
vendored
14
vendor/github.com/adrianmo/go-nmea/gpgsa.go
generated
vendored
|
@ -18,7 +18,7 @@ const (
|
|||
// GPGSA represents overview satellite data.
|
||||
// http://aprs.gids.nl/nmea/#gsa
|
||||
type GPGSA struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Mode string // The selection mode.
|
||||
FixType string // The fix type.
|
||||
SV []string // List of satellite PRNs used for this fix.
|
||||
|
@ -27,17 +27,17 @@ type GPGSA struct {
|
|||
VDOP float64 // Vertical dilution of precision.
|
||||
}
|
||||
|
||||
// NewGPGSA parses the GPGSA sentence into this struct.
|
||||
func NewGPGSA(s Sent) (GPGSA, error) {
|
||||
// newGPGSA parses the GPGSA sentence into this struct.
|
||||
func newGPGSA(s BaseSentence) (GPGSA, error) {
|
||||
p := newParser(s, PrefixGPGSA)
|
||||
m := GPGSA{
|
||||
Sent: s,
|
||||
Mode: p.EnumString(0, "selection mode", Auto, Manual),
|
||||
FixType: p.EnumString(1, "fix type", FixNone, Fix2D, Fix3D),
|
||||
BaseSentence: s,
|
||||
Mode: p.EnumString(0, "selection mode", Auto, Manual),
|
||||
FixType: p.EnumString(1, "fix type", FixNone, Fix2D, Fix3D),
|
||||
}
|
||||
// Satellites in view.
|
||||
for i := 2; i < 14; i++ {
|
||||
if v := p.String(i, "satelite in view"); v != "" {
|
||||
if v := p.String(i, "satellite in view"); v != "" {
|
||||
m.SV = append(m.SV, v)
|
||||
}
|
||||
}
|
||||
|
|
8
vendor/github.com/adrianmo/go-nmea/gpgsv.go
generated
vendored
8
vendor/github.com/adrianmo/go-nmea/gpgsv.go
generated
vendored
|
@ -8,7 +8,7 @@ const (
|
|||
// GPGSV represents the GPS Satellites in view
|
||||
// http://aprs.gids.nl/nmea/#gpgsv
|
||||
type GPGSV struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
TotalMessages int64 // Total number of messages of this type in this cycle
|
||||
MessageNumber int64 // Message number
|
||||
NumberSVsInView int64 // Total number of SVs in view
|
||||
|
@ -23,11 +23,11 @@ type GPGSVInfo struct {
|
|||
SNR int64 // SNR, 00-99 dB (null when not tracking)
|
||||
}
|
||||
|
||||
// NewGPGSV constructor
|
||||
func NewGPGSV(s Sent) (GPGSV, error) {
|
||||
// newGPGSV constructor
|
||||
func newGPGSV(s BaseSentence) (GPGSV, error) {
|
||||
p := newParser(s, PrefixGPGSV)
|
||||
m := GPGSV{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
TotalMessages: p.Int64(0, "total number of messages"),
|
||||
MessageNumber: p.Int64(1, "message number"),
|
||||
NumberSVsInView: p.Int64(2, "number of SVs in view"),
|
||||
|
|
25
vendor/github.com/adrianmo/go-nmea/gphdt.go
generated
vendored
Normal file
25
vendor/github.com/adrianmo/go-nmea/gphdt.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package nmea
|
||||
|
||||
const (
|
||||
// PrefixGPHDT prefix of GPHDT sentence type
|
||||
PrefixGPHDT = "GPHDT"
|
||||
)
|
||||
|
||||
// GPHDT is the Actual vessel heading in degrees True.
|
||||
// http://aprs.gids.nl/nmea/#hdt
|
||||
type GPHDT struct {
|
||||
BaseSentence
|
||||
Heading float64 // Heading in degrees
|
||||
True bool // Heading is relative to true north
|
||||
}
|
||||
|
||||
// newGPHDT constructor
|
||||
func newGPHDT(s BaseSentence) (GPHDT, error) {
|
||||
p := newParser(s, PrefixGPHDT)
|
||||
m := GPHDT{
|
||||
BaseSentence: s,
|
||||
Heading: p.Float64(0, "heading"),
|
||||
True: p.EnumString(1, "true", "T") == "T",
|
||||
}
|
||||
return m, p.Err()
|
||||
}
|
28
vendor/github.com/adrianmo/go-nmea/gprmc.go
generated
vendored
28
vendor/github.com/adrianmo/go-nmea/gprmc.go
generated
vendored
|
@ -12,30 +12,30 @@ const (
|
|||
// GPRMC is the Recommended Minimum Specific GNSS data.
|
||||
// http://aprs.gids.nl/nmea/#rmc
|
||||
type GPRMC struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Time Time // Time Stamp
|
||||
Validity string // validity - A-ok, V-invalid
|
||||
Latitude LatLong // Latitude
|
||||
Longitude LatLong // Longitude
|
||||
Latitude float64 // Latitude
|
||||
Longitude float64 // Longitude
|
||||
Speed float64 // Speed in knots
|
||||
Course float64 // True course
|
||||
Date Date // Date
|
||||
Variation float64 // Magnetic variation
|
||||
}
|
||||
|
||||
// NewGPRMC constructor
|
||||
func NewGPRMC(s Sent) (GPRMC, error) {
|
||||
// newGPRMC constructor
|
||||
func newGPRMC(s BaseSentence) (GPRMC, error) {
|
||||
p := newParser(s, PrefixGPRMC)
|
||||
m := GPRMC{
|
||||
Sent: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Validity: p.EnumString(1, "validity", ValidRMC, InvalidRMC),
|
||||
Latitude: p.LatLong(2, 3, "latitude"),
|
||||
Longitude: p.LatLong(4, 5, "longitude"),
|
||||
Speed: p.Float64(6, "speed"),
|
||||
Course: p.Float64(7, "course"),
|
||||
Date: p.Date(8, "date"),
|
||||
Variation: p.Float64(9, "variation"),
|
||||
BaseSentence: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Validity: p.EnumString(1, "validity", ValidRMC, InvalidRMC),
|
||||
Latitude: p.LatLong(2, 3, "latitude"),
|
||||
Longitude: p.LatLong(4, 5, "longitude"),
|
||||
Speed: p.Float64(6, "speed"),
|
||||
Course: p.Float64(7, "course"),
|
||||
Date: p.Date(8, "date"),
|
||||
Variation: p.Float64(9, "variation"),
|
||||
}
|
||||
if p.EnumString(10, "variation", West, East) == West {
|
||||
m.Variation = 0 - m.Variation
|
||||
|
|
8
vendor/github.com/adrianmo/go-nmea/gpvtg.go
generated
vendored
8
vendor/github.com/adrianmo/go-nmea/gpvtg.go
generated
vendored
|
@ -8,19 +8,19 @@ const (
|
|||
// GPVTG represents track & speed data.
|
||||
// http://aprs.gids.nl/nmea/#vtg
|
||||
type GPVTG struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
TrueTrack float64
|
||||
MagneticTrack float64
|
||||
GroundSpeedKnots float64
|
||||
GroundSpeedKPH float64
|
||||
}
|
||||
|
||||
// NewGPVTG parses the GPVTG sentence into this struct.
|
||||
// newGPVTG parses the GPVTG sentence into this struct.
|
||||
// e.g: $GPVTG,360.0,T,348.7,M,000.0,N,000.0,K*43
|
||||
func NewGPVTG(s Sent) (GPVTG, error) {
|
||||
func newGPVTG(s BaseSentence) (GPVTG, error) {
|
||||
p := newParser(s, PrefixGPVTG)
|
||||
return GPVTG{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
TrueTrack: p.Float64(0, "true track"),
|
||||
MagneticTrack: p.Float64(2, "magnetic track"),
|
||||
GroundSpeedKnots: p.Float64(4, "ground speed (knots)"),
|
||||
|
|
8
vendor/github.com/adrianmo/go-nmea/gpzda.go
generated
vendored
8
vendor/github.com/adrianmo/go-nmea/gpzda.go
generated
vendored
|
@ -8,7 +8,7 @@ const (
|
|||
// GPZDA represents date & time data.
|
||||
// http://aprs.gids.nl/nmea/#zda
|
||||
type GPZDA struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
Time Time
|
||||
Day int64
|
||||
Month int64
|
||||
|
@ -17,11 +17,11 @@ type GPZDA struct {
|
|||
OffsetMinutes int64 // Local time zone offset from GMT, minutes
|
||||
}
|
||||
|
||||
// NewGPZDA constructor
|
||||
func NewGPZDA(s Sent) (GPZDA, error) {
|
||||
// newGPZDA constructor
|
||||
func newGPZDA(s BaseSentence) (GPZDA, error) {
|
||||
p := newParser(s, PrefixGPZDA)
|
||||
return GPZDA{
|
||||
Sent: s,
|
||||
BaseSentence: s,
|
||||
Time: p.Time(0, "time"),
|
||||
Day: p.Int64(1, "day"),
|
||||
Month: p.Int64(2, "month"),
|
||||
|
|
16
vendor/github.com/adrianmo/go-nmea/parser.go
generated
vendored
16
vendor/github.com/adrianmo/go-nmea/parser.go
generated
vendored
|
@ -8,21 +8,21 @@ import (
|
|||
// parser provides a simple way of accessing and parsing
|
||||
// sentence fields
|
||||
type parser struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
prefix string
|
||||
err error
|
||||
}
|
||||
|
||||
// newParser constructor
|
||||
func newParser(s Sent, prefix string) *parser {
|
||||
p := &parser{Sent: s, prefix: prefix}
|
||||
func newParser(s BaseSentence, prefix string) *parser {
|
||||
p := &parser{BaseSentence: s, prefix: prefix}
|
||||
if p.Type != prefix {
|
||||
p.SetErr("prefix", p.Type)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Err returns the first error encounterd during the parser's usage.
|
||||
// Err returns the first error encountered during the parser's usage.
|
||||
func (p *parser) Err() error {
|
||||
return p.err
|
||||
}
|
||||
|
@ -48,10 +48,10 @@ func (p *parser) String(i int, context string) string {
|
|||
}
|
||||
|
||||
// EnumString returns the field value at the specified index.
|
||||
// An error occurs if the value is not one of the options.
|
||||
// An error occurs if the value is not one of the options and not empty.
|
||||
func (p *parser) EnumString(i int, context string, options ...string) string {
|
||||
s := p.String(i, context)
|
||||
if p.err != nil {
|
||||
if p.err != nil || s == "" {
|
||||
return ""
|
||||
}
|
||||
for _, o := range options {
|
||||
|
@ -64,7 +64,7 @@ func (p *parser) EnumString(i int, context string, options ...string) string {
|
|||
}
|
||||
|
||||
// Int64 returns the int64 value at the specified index.
|
||||
// If the value is an emtpy string, 0 is returned.
|
||||
// If the value is an empty string, 0 is returned.
|
||||
func (p *parser) Int64(i int, context string) int64 {
|
||||
s := p.String(i, context)
|
||||
if p.err != nil {
|
||||
|
@ -126,7 +126,7 @@ func (p *parser) Date(i int, context string) Date {
|
|||
}
|
||||
|
||||
// LatLong returns the coordinate value of the specified fields.
|
||||
func (p *parser) LatLong(i, j int, context string) LatLong {
|
||||
func (p *parser) LatLong(i, j int, context string) float64 {
|
||||
a := p.String(i, context)
|
||||
b := p.String(j, context)
|
||||
if p.err != nil {
|
||||
|
|
14
vendor/github.com/adrianmo/go-nmea/pgrme.go
generated
vendored
14
vendor/github.com/adrianmo/go-nmea/pgrme.go
generated
vendored
|
@ -10,14 +10,14 @@ const (
|
|||
// PGRME is Estimated Position Error (Garmin proprietary sentence)
|
||||
// http://aprs.gids.nl/nmea/#rme
|
||||
type PGRME struct {
|
||||
Sent
|
||||
BaseSentence
|
||||
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(s Sent) (PGRME, error) {
|
||||
// newPGRME constructor
|
||||
func newPGRME(s BaseSentence) (PGRME, error) {
|
||||
p := newParser(s, PrefixPGRME)
|
||||
|
||||
horizontal := p.Float64(0, "horizontal error")
|
||||
|
@ -30,9 +30,9 @@ func NewPGRME(s Sent) (PGRME, error) {
|
|||
_ = p.EnumString(5, "spherical error unit", ErrorUnit)
|
||||
|
||||
return PGRME{
|
||||
Sent: s,
|
||||
Horizontal: horizontal,
|
||||
Vertical: vertial,
|
||||
Spherical: spherical,
|
||||
BaseSentence: s,
|
||||
Horizontal: horizontal,
|
||||
Vertical: vertial,
|
||||
Spherical: spherical,
|
||||
}, p.Err()
|
||||
}
|
||||
|
|
60
vendor/github.com/adrianmo/go-nmea/sentence.go
generated
vendored
60
vendor/github.com/adrianmo/go-nmea/sentence.go
generated
vendored
|
@ -16,43 +16,35 @@ const (
|
|||
ChecksumSep = "*"
|
||||
)
|
||||
|
||||
// Message interface for all NMEA sentence
|
||||
type Message interface {
|
||||
// Sentence interface for all NMEA sentence
|
||||
type Sentence interface {
|
||||
fmt.Stringer
|
||||
Sentence() Sent
|
||||
Prefix() string
|
||||
Validate() error
|
||||
}
|
||||
|
||||
// Sent contains the information about the NMEA sentence
|
||||
type Sent struct {
|
||||
// BaseSentence contains the information about the NMEA sentence
|
||||
type BaseSentence struct {
|
||||
Type string // The sentence type (e.g $GPGSA)
|
||||
Fields []string // Array of fields
|
||||
Checksum string // The Checksum
|
||||
Raw string // The raw NMEA sentence received
|
||||
}
|
||||
|
||||
// Sentence returns the Messages Sent
|
||||
func (s Sent) Sentence() Sent { return s }
|
||||
|
||||
// Prefix returns the type of the message
|
||||
func (s Sent) Prefix() string { return s.Type }
|
||||
func (s BaseSentence) Prefix() string { return s.Type }
|
||||
|
||||
// String formats the sentence into a string
|
||||
func (s Sent) String() string { return s.Raw }
|
||||
func (s BaseSentence) String() string { return s.Raw }
|
||||
|
||||
// Validate returns an error if the sentence is not valid
|
||||
func (s Sent) Validate() error { return nil }
|
||||
|
||||
// ParseSentence parses a raw message into it's fields
|
||||
func ParseSentence(raw string) (Sent, error) {
|
||||
// parseSentence parses a raw message into it's fields
|
||||
func parseSentence(raw string) (BaseSentence, error) {
|
||||
startIndex := strings.Index(raw, SentenceStart)
|
||||
if startIndex != 0 {
|
||||
return Sent{}, fmt.Errorf("nmea: sentence does not start with a '$'")
|
||||
return BaseSentence{}, fmt.Errorf("nmea: sentence does not start with a '$'")
|
||||
}
|
||||
sumSepIndex := strings.Index(raw, ChecksumSep)
|
||||
if sumSepIndex == -1 {
|
||||
return Sent{}, fmt.Errorf("nmea: sentence does not contain checksum separator")
|
||||
return BaseSentence{}, fmt.Errorf("nmea: sentence does not contain checksum separator")
|
||||
}
|
||||
var (
|
||||
fieldsRaw = raw[startIndex+1 : sumSepIndex]
|
||||
|
@ -62,10 +54,10 @@ func ParseSentence(raw string) (Sent, error) {
|
|||
)
|
||||
// Validate the checksum
|
||||
if checksum != checksumRaw {
|
||||
return Sent{}, fmt.Errorf(
|
||||
return BaseSentence{}, fmt.Errorf(
|
||||
"nmea: sentence checksum mismatch [%s != %s]", checksum, checksumRaw)
|
||||
}
|
||||
return Sent{
|
||||
return BaseSentence{
|
||||
Type: fields[0],
|
||||
Fields: fields[1:],
|
||||
Checksum: checksumRaw,
|
||||
|
@ -84,34 +76,36 @@ func xorChecksum(s string) string {
|
|||
}
|
||||
|
||||
// Parse parses the given string into the correct sentence type.
|
||||
func Parse(raw string) (Message, error) {
|
||||
s, err := ParseSentence(raw)
|
||||
func Parse(raw string) (Sentence, error) {
|
||||
s, err := parseSentence(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch s.Type {
|
||||
case PrefixGPRMC:
|
||||
return NewGPRMC(s)
|
||||
return newGPRMC(s)
|
||||
case PrefixGNRMC:
|
||||
return NewGNRMC(s)
|
||||
return newGNRMC(s)
|
||||
case PrefixGPGGA:
|
||||
return NewGPGGA(s)
|
||||
return newGPGGA(s)
|
||||
case PrefixGNGGA:
|
||||
return NewGNGGA(s)
|
||||
return newGNGGA(s)
|
||||
case PrefixGPGSA:
|
||||
return NewGPGSA(s)
|
||||
return newGPGSA(s)
|
||||
case PrefixGPGLL:
|
||||
return NewGPGLL(s)
|
||||
return newGPGLL(s)
|
||||
case PrefixGPVTG:
|
||||
return NewGPVTG(s)
|
||||
return newGPVTG(s)
|
||||
case PrefixGPZDA:
|
||||
return NewGPZDA(s)
|
||||
return newGPZDA(s)
|
||||
case PrefixPGRME:
|
||||
return NewPGRME(s)
|
||||
return newPGRME(s)
|
||||
case PrefixGPGSV:
|
||||
return NewGPGSV(s)
|
||||
return newGPGSV(s)
|
||||
case PrefixGLGSV:
|
||||
return NewGLGSV(s)
|
||||
return newGLGSV(s)
|
||||
case PrefixGPHDT:
|
||||
return newGPHDT(s)
|
||||
default:
|
||||
return nil, fmt.Errorf("nmea: sentence type '%s' not implemented", s.Type)
|
||||
}
|
||||
|
|
120
vendor/github.com/adrianmo/go-nmea/types.go
generated
vendored
120
vendor/github.com/adrianmo/go-nmea/types.go
generated
vendored
|
@ -9,7 +9,6 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
// "unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -31,42 +30,6 @@ const (
|
|||
West = "W"
|
||||
)
|
||||
|
||||
// LatLong type
|
||||
type LatLong float64
|
||||
|
||||
// PrintGPS returns the GPS format for the given LatLong.
|
||||
func (l LatLong) PrintGPS() string {
|
||||
padding := ""
|
||||
value := float64(l)
|
||||
degrees := math.Floor(math.Abs(value))
|
||||
fraction := (math.Abs(value) - degrees) * 60
|
||||
if fraction < 10 {
|
||||
padding = "0"
|
||||
}
|
||||
return fmt.Sprintf("%d%s%.4f", int(degrees), padding, fraction)
|
||||
}
|
||||
|
||||
// PrintDMS returns the degrees, minutes, seconds format for the given LatLong.
|
||||
func (l LatLong) PrintDMS() string {
|
||||
val := math.Abs(float64(l))
|
||||
degrees := int(math.Floor(val))
|
||||
minutes := int(math.Floor(60 * (val - float64(degrees))))
|
||||
seconds := 3600 * (val - float64(degrees) - (float64(minutes) / 60))
|
||||
|
||||
return fmt.Sprintf("%d\u00B0 %d' %f\"", degrees, minutes, seconds)
|
||||
}
|
||||
|
||||
//ValidRange validates if the range is between -180 and +180.
|
||||
func (l LatLong) ValidRange() bool {
|
||||
return -180.0 <= l && l <= 180.0
|
||||
}
|
||||
|
||||
// IsNear returns whether the coordinate is near the other coordinate,
|
||||
// by no further than the given distance away.
|
||||
func (l LatLong) IsNear(o LatLong, max float64) bool {
|
||||
return math.Abs(float64(l-o)) <= max
|
||||
}
|
||||
|
||||
// ParseLatLong parses the supplied string into the LatLong.
|
||||
//
|
||||
// Supported formats are:
|
||||
|
@ -74,27 +37,30 @@ func (l LatLong) IsNear(o LatLong, max float64) bool {
|
|||
// - Decimal (e.g. 33.23454)
|
||||
// - GPS (e.g 15113.4322S)
|
||||
//
|
||||
func ParseLatLong(s string) (LatLong, error) {
|
||||
var l LatLong
|
||||
var err error
|
||||
invalid := LatLong(0.0) // The invalid value to return.
|
||||
if l, err = ParseDMS(s); err == nil {
|
||||
return l, nil
|
||||
} else if l, err = ParseGPS(s); err == nil {
|
||||
return l, nil
|
||||
} else if l, err = ParseDecimal(s); err == nil {
|
||||
return l, nil
|
||||
func ParseLatLong(s string) (float64, error) {
|
||||
var l float64
|
||||
if v, err := ParseDMS(s); err == nil {
|
||||
l = v
|
||||
} else if v, err := ParseGPS(s); err == nil {
|
||||
l = v
|
||||
} else if v, err := ParseDecimal(s); err == nil {
|
||||
l = v
|
||||
} else {
|
||||
return 0, fmt.Errorf("cannot parse [%s], unknown format", s)
|
||||
}
|
||||
if !l.ValidRange() {
|
||||
return invalid, errors.New("coordinate is not in range -180, 180")
|
||||
if l < -180.0 || 180.0 < l {
|
||||
return 0, errors.New("coordinate is not in range -180, 180")
|
||||
}
|
||||
return invalid, fmt.Errorf("cannot parse [%s], unknown format", s)
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// ParseGPS parses a GPS/NMEA coordinate.
|
||||
// e.g 15113.4322S
|
||||
func ParseGPS(s string) (LatLong, error) {
|
||||
func ParseGPS(s string) (float64, error) {
|
||||
parts := strings.Split(s, " ")
|
||||
if len(parts) != 2 {
|
||||
return 0, fmt.Errorf("invalid format: %s", s)
|
||||
}
|
||||
dir := parts[1]
|
||||
value, err := strconv.ParseFloat(parts[0], 64)
|
||||
if err != nil {
|
||||
|
@ -106,28 +72,39 @@ func ParseGPS(s string) (LatLong, error) {
|
|||
value = degrees + minutes/60
|
||||
|
||||
if dir == North || dir == East {
|
||||
return LatLong(value), nil
|
||||
return value, nil
|
||||
} else if dir == South || dir == West {
|
||||
return LatLong(0 - value), nil
|
||||
return 0 - value, nil
|
||||
} else {
|
||||
return 0, fmt.Errorf("invalid direction [%s]", dir)
|
||||
}
|
||||
}
|
||||
|
||||
// FormatGPS formats a GPS/NMEA coordinate
|
||||
func FormatGPS(l float64) string {
|
||||
padding := ""
|
||||
degrees := math.Floor(math.Abs(l))
|
||||
fraction := (math.Abs(l) - degrees) * 60
|
||||
if fraction < 10 {
|
||||
padding = "0"
|
||||
}
|
||||
return fmt.Sprintf("%d%s%.4f", int(degrees), padding, fraction)
|
||||
}
|
||||
|
||||
// ParseDecimal parses a decimal format coordinate.
|
||||
// e.g: 151.196019
|
||||
func ParseDecimal(s string) (LatLong, error) {
|
||||
func ParseDecimal(s string) (float64, error) {
|
||||
// Make sure it parses as a float.
|
||||
l, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil || s[0] != '-' && len(strings.Split(s, ".")[0]) > 3 {
|
||||
return LatLong(0.0), errors.New("parse error (not decimal coordinate)")
|
||||
return 0.0, errors.New("parse error (not decimal coordinate)")
|
||||
}
|
||||
return LatLong(l), nil
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// ParseDMS parses a coordinate in degrees, minutes, seconds.
|
||||
// - e.g. 33° 23' 22"
|
||||
func ParseDMS(s string) (LatLong, error) {
|
||||
func ParseDMS(s string) (float64, error) {
|
||||
degrees := 0
|
||||
minutes := 0
|
||||
seconds := 0.0
|
||||
|
@ -138,42 +115,55 @@ func ParseDMS(s string) (LatLong, error) {
|
|||
var err error
|
||||
|
||||
for i, r := range s {
|
||||
if unicode.IsNumber(r) || r == '.' {
|
||||
switch {
|
||||
case unicode.IsNumber(r) || r == '.':
|
||||
if !endNumber {
|
||||
tmpBytes = append(tmpBytes, s[i])
|
||||
} else {
|
||||
return 0, errors.New("parse error (no delimiter)")
|
||||
}
|
||||
} else if unicode.IsSpace(r) && len(tmpBytes) > 0 {
|
||||
case unicode.IsSpace(r) && len(tmpBytes) > 0:
|
||||
endNumber = true
|
||||
} else if r == Degrees {
|
||||
case r == Degrees:
|
||||
if degrees, err = strconv.Atoi(string(tmpBytes)); err != nil {
|
||||
return 0, errors.New("parse error (degrees)")
|
||||
}
|
||||
tmpBytes = tmpBytes[:0]
|
||||
endNumber = false
|
||||
} else if s[i] == Minutes {
|
||||
case s[i] == Minutes:
|
||||
if minutes, err = strconv.Atoi(string(tmpBytes)); err != nil {
|
||||
return 0, errors.New("parse error (minutes)")
|
||||
}
|
||||
tmpBytes = tmpBytes[:0]
|
||||
endNumber = false
|
||||
} else if s[i] == Seconds {
|
||||
case s[i] == Seconds:
|
||||
if seconds, err = strconv.ParseFloat(string(tmpBytes), 64); err != nil {
|
||||
return 0, errors.New("parse error (seconds)")
|
||||
}
|
||||
tmpBytes = tmpBytes[:0]
|
||||
endNumber = false
|
||||
} else if unicode.IsSpace(r) && len(tmpBytes) == 0 {
|
||||
case unicode.IsSpace(r) && len(tmpBytes) == 0:
|
||||
continue
|
||||
} else {
|
||||
default:
|
||||
return 0, fmt.Errorf("parse error (unknown symbol [%d])", s[i])
|
||||
}
|
||||
}
|
||||
val := LatLong(float64(degrees) + (float64(minutes) / 60.0) + (float64(seconds) / 60.0 / 60.0))
|
||||
if len(tmpBytes) > 0 {
|
||||
return 0, fmt.Errorf("parse error (trailing data [%s])", string(tmpBytes))
|
||||
}
|
||||
val := float64(degrees) + (float64(minutes) / 60.0) + (float64(seconds) / 60.0 / 60.0)
|
||||
return val, nil
|
||||
}
|
||||
|
||||
// FormatDMS returns the degrees, minutes, seconds format for the given LatLong.
|
||||
func FormatDMS(l float64) string {
|
||||
val := math.Abs(l)
|
||||
degrees := int(math.Floor(val))
|
||||
minutes := int(math.Floor(60 * (val - float64(degrees))))
|
||||
seconds := 3600 * (val - float64(degrees) - (float64(minutes) / 60))
|
||||
return fmt.Sprintf("%d\u00B0 %d' %f\"", degrees, minutes, seconds)
|
||||
}
|
||||
|
||||
// Time type
|
||||
type Time struct {
|
||||
Valid bool
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue