erb

package
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2022 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package erb provides primitives for parsing the Emlid Reach Binary protocol (ERB).

Implementation is based on the ERB Protocol spec version 0.1.0:

https://files.emlid.com/ERB.pdf

Index

Examples

Constants

View Source
const (
	SupportedProtocolVersionHigh   = 0
	SupportedProtocolVersionMedium = 1
	SupportedProtocolVersionLow    = 0
)

Supported protocol versions.

Variables

This section is empty.

Functions

func ScanPackets

func ScanPackets(data []byte, _ bool) (advance int, token []byte, err error)

ScanPackets is a split function for a bufio.Scanner that returns each ERB packet.

Types

type DOPS

type DOPS struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// Geometric DOP.
	Geometric float64
	// Position DOP.
	Position float64
	// Vertical DOP.
	Vertical float64
	// Horizontal DOP.
	Horizontal float64
}

DOPS message outputs dimensionless values of DOP.

The raw values are scaled by factor 100.

For example, if received value is 123, then real is 1.23.

type FixType

type FixType uint8

FixType represents a type of navigation fix.

const (
	FixTypeNoFix  FixType = 0x00
	FixTypeSingle FixType = 0x01
	FixTypeFloat  FixType = 0x02
	FixTypeRTK    FixType = 0x03
)

func (FixType) String

func (i FixType) String() string

type ID

type ID uint8

ID represents an ERB message ID.

const (
	// IDVER is the ID of the VER message.
	IDVER ID = 0x01
	// IDPOS is the ID of the POS message.
	IDPOS ID = 0x02
	// IDSTAT is the ID of the STAT message.
	IDSTAT ID = 0x03
	// IDDOPS is the ID of the DOPS message.
	IDDOPS ID = 0x04
	// IDVEL is the ID of the VEL message.
	IDVEL ID = 0x05
	// IDSVI is the ID of the SVI message.
	IDSVI ID = 0x06
)

func (ID) String

func (i ID) String() string

type POS

type POS struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// Longitude component (degrees).
	LongitudeDegrees float64
	// Latitude component (degrees).
	LatitudeDegrees float64
	// AltitudeEllipsoid is the height above ellipsoid (m).
	AltitudeEllipsoidMeters float64
	// AltitudeMeanSeaLevel is the height above mean sea level (m).
	AltitudeMeanSeaLevelMeters float64
	// HorizontalAccuracyMillimeters is the horizontal accuracy estimate (mm).
	HorizontalAccuracyMillimeters uint32
	// VerticalAccuracy is the vertical accuracy estimate (mm).
	VerticalAccuracyMillimeters uint32
}

POS message contains the geodetic coordinates.

Longitude, latitude, altitude and information about accuracy estimate.

type STAT

type STAT struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// WeekGPS is the week number of the navigation epoch.
	WeekGPS uint16
	// FixType is the fix type.
	FixType FixType
	// HasFix is true when position and velocity are valid.
	HasFix bool
	// NumSVs is the number of used space vehicles.
	NumSVs uint8
}

STAT message contains status of fix, its type and also the number of used satellites.

type SV

type SV struct {
	// ID of SV.
	ID uint8
	// Type of SV.
	Type SVType
	// SignalStrength of SV in dB-Hz.
	SignalStrength float64
	// CarrierPhase of SV in cycles.
	CarrierPhase float64
	// PseudoRangeResidual of SV (m).
	PseudoRangeResidualMeters int32
	// DopplerFrequencyHz of SV.
	DopplerFrequencyHz float64
	// Azimuth of SV (degrees).
	AzimuthDegrees float64
	// Elevation of SV (degrees).
	ElevationDegrees float64
}

SV message contains information about a single observation satellite.

type SVI

type SVI struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// NumSVs is the number of visible SVs.
	NumSVs uint8
}

SVI message contains information about used observation satellites.

type SVType

type SVType uint8

SVType represents the type of an SV (space vehicle).

const (
	SVTypeGPS     SVType = 0
	SVTypeGLONASS SVType = 1
	SVTypeGalileo SVType = 2
	SVTypeQZSS    SVType = 3
	SVTypeBeiDou  SVType = 4
	SVTypeLEO     SVType = 5
	SVTypeSBAS    SVType = 6
)

func (SVType) String

func (i SVType) String() string

type Scanner

type Scanner struct {
	// contains filtered or unexported fields
}

Scanner provides a convenient interface for reading and parsing ERB messages from a stream.

Example
package main

import (
	"bufio"
	"context"
	"fmt"
	"net"
	"os"
	"strconv"
	"strings"
	"time"

	"go.einride.tech/reach/erb"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	// This example uses a mocked Reach unit that answers with recorded data.
	reach := newExampleReach(ctx)
	// Connect to the Emlid Reach Binary (ERB) protocol port of the Reach.
	conn, err := net.Dial("tcp", reach.Address)
	if err != nil {
		panic(err)
	}
	// Wrap the connection in an ERB protocol scanner.
	sc := erb.NewScanner(conn)
	// Scan 5 packets then exit.
	const maxPacketCount = 5
	packetCount := 0
	for sc.Scan() {
		// Handle packet.
		switch sc.ID() {
		case erb.IDVER:
			ver := sc.VER()
			fmt.Printf("VER:  %d.%d.%d\n", ver.High, ver.Medium, ver.Low)
		case erb.IDPOS:
			pos := sc.POS()
			fmt.Printf("POS:  %f,%f\n", pos.LatitudeDegrees, pos.LongitudeDegrees)
		case erb.IDSTAT:
			stat := sc.STAT()
			fmt.Printf("STAT: fix:%t type:%v satellites:%d\n", stat.HasFix, stat.FixType, stat.NumSVs)
		case erb.IDDOPS:
			dops := sc.DOPS()
			fmt.Printf("DOPS: pdop:%f\n", dops.Position)
		case erb.IDVEL:
			vel := sc.VEL()
			fmt.Printf("VEL:  speed:%dcm/s\n", vel.SpeedCentimetersPerSecond)
		case erb.IDSVI:
			svi := sc.SVI()
			fmt.Printf("SVI:  satellites:%d\n", svi.NumSVs)
			for sc.ScanSVI() {
				sv := sc.SV()
				fmt.Printf("SV:   id:%v\n", sv.ID)
			}
		}
		packetCount++
		if packetCount >= maxPacketCount {
			break
		}
	}
	if sc.Err() != nil {
		panic(err)
	}
	if err := conn.Close(); err != nil {
		panic(err)
	}
}

type exampleReach struct {
	Address string
}

func newExampleReach(ctx context.Context) *exampleReach {
	lis, err := (&net.ListenConfig{}).Listen(ctx, "tcp", "localhost:0")
	if err != nil {
		panic(err)
	}
	go func() {
		conn, err := lis.Accept()
		if err != nil {
			panic(err)
		}
		if _, err := conn.Write(loadHexDump("testdata/hexdump.asta")); err != nil {
			panic(err)
		}
		if err := conn.Close(); err != nil {
			panic(err)
		}
		if err := lis.Close(); err != nil {
			panic(err)
		}
	}()
	return &exampleReach{
		Address: lis.Addr().String(),
	}
}

func loadHexDump(filename string) []byte {
	var data []byte
	f, err := os.Open(filename)
	if err != nil {
		panic(err)
	}
	sc := bufio.NewScanner(f)
	sc.Split(bufio.ScanLines)
	for sc.Scan() {
		fields := strings.Fields(sc.Text())
		if len(fields) == 0 {
			continue
		}
		for _, field := range fields[1:] {
			b, err := strconv.ParseUint(field, 8, 8)
			if err != nil {
				panic(err)
			}
			data = append(data, byte(b))
		}
	}
	if sc.Err() != nil {
		panic(sc.Err())
	}
	if err := f.Close(); err != nil {
		panic(err)
	}
	return data
}
Output:

VER:  0.1.0
POS:  57.777683,12.780540
STAT: fix:true type:Single satellites:20
DOPS: pdop:1.210000
VEL:  speed:0cm/s

func NewScanner

func NewScanner(r io.Reader) *Scanner

NewScanner returns a new Scanner to read from r.

func (*Scanner) Bytes

func (c *Scanner) Bytes() []byte

func (*Scanner) DOPS

func (c *Scanner) DOPS() DOPS

func (*Scanner) Err added in v0.6.0

func (c *Scanner) Err() error

func (*Scanner) ID

func (c *Scanner) ID() ID

func (*Scanner) POS

func (c *Scanner) POS() POS

func (*Scanner) STAT

func (c *Scanner) STAT() STAT

func (*Scanner) SV

func (c *Scanner) SV() SV

func (*Scanner) SVI

func (c *Scanner) SVI() SVI

func (*Scanner) Scan

func (c *Scanner) Scan() bool

Scan advances the Scanner to the next message, whose ID will then be available through the ID method.

func (*Scanner) ScanSVI

func (c *Scanner) ScanSVI() bool

ScanSVI advances to the next SV packet in an SVI packet.

func (*Scanner) VEL

func (c *Scanner) VEL() VEL

func (*Scanner) VER

func (c *Scanner) VER() VER

type VEL

type VEL struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// North velocity component (cm/s).
	NorthCentimetersPerSecond int32
	// East velocity component (cm/s).
	EastCentimetersPerSecond int32
	// Down velocity component (cm/s).
	DownCentimetersPerSecond int32
	// Speed is the 2D ground speed (cm/s).
	SpeedCentimetersPerSecond int32
	// Heading is the 2D heading of motion.
	HeadingDegrees float64
	// SpeedAccuracy is the speed accuracy estimate.
	SpeedAccuracyCentimetersPerSecond uint32
}

VEL message contains the velocity in NED (North East Down) coordinates.

type VER

type VER struct {
	// TimeGPS is the time of week in milliseconds of the navigation epoch.
	TimeGPS uint32
	// High level of version.
	High uint8
	// Medium level of version.
	Medium uint8
	// Low level of version.
	Low uint8
}

VER message contains version of the ERB protocol.

It comprises 3 numbers: high level of version, medium level of version and low level of version.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL