gomavlib

package module
v0.0.0-...-431ba6b Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2019 License: MIT Imports: 18 Imported by: 0

README

gomavlib

GoDoc Go Report Card Build Status

gomavlib is a library that implements Mavlink 2.0 and 1.0 in the Go programming language. It can power UGVs, UAVs, ground stations, monitoring systems or routers acting in a Mavlink network.

Mavlink is a lighweight and transport-independent protocol that is mostly used to communicate with unmanned ground vehicles (UGV) and unmanned aerial vehicles (UAV, drones, quadcopters, multirotors). It is supported by the most popular open-source flight controllers (Ardupilot and PX4).

This library powers the mavp2p router.

Features

  • Decodes and encodes Mavlink v2.0 and v1.0. Supports checksums, empty-byte truncation (v2.0), signatures (v2.0), message extensions (v2.0)
  • Dialects are optional, the library can work a standard dialect (standard dialects are provided in directory dialects/), a custom dialect or no dialect at all. A dialect generator is provided to convert XML-based custom dialects into their Go representation.
  • Provides a high-level API (Node) with:
    • ability to communicate with multiple endpoints in parallel:
      • serial
      • UDP (server, client or broadcast mode)
      • TCP (server or client mode)
      • custom reader/writer
    • automatic heartbeat emission
    • automatic stream requests to Ardupilot devices (disabled by default)
  • Provides a low-level API (Parser) with ability to decode/encode frames from/to a generic reader/writer
  • UDP connections are tracked and removed when inactive
  • Supports both domain names and IPs
  • Examples provided for every feature
  • Comprehensive test suite

Installation

Go ≥ 1.11 is required. If modules are enabled (i.e. there's a go.mod file in your project folder), it is enough to write the library name in the import section of the source files that are referring to it. Go will take care of downloading the needed files:

import (
    "github.com/gswly/gomavlib"
)

If modules are not enabled, the library must be downloaded manually:

go get github.com/gswly/gomavlib

Examples

Documentation

https://godoc.org/github.com/gswly/gomavlib

Dialect generation

Although standard dialects are provided in the dialects/ folder, dialect definitions in XML format can be converted into Go files by running the dialgen utility:

go get github.com/gswly/gomavlib/dialgen
dialgen --output=dialect.go [path_or_url_to_xml_definition]

Testing

If you want to edit the library and test the results, unit tests can be launched with:

make test

Protocol references

Other Go libraries

Other non-Go libraries

Documentation

Overview

Package gomavlib is a library that implements Mavlink 2.0 and 1.0 in the Go programming language. It can power UGVs, UAVs, ground stations, monitoring systems or routers acting in a Mavlink network.

Mavlink is a lighweight and transport-independent protocol that is mostly used to communicate with unmanned ground vehicles (UGV) and unmanned aerial vehicles (UAV, drones, quadcopters, multirotors). It is supported by the most common open-source flight controllers (Ardupilot and PX4).

Basic example (more are available at https://github.com/gswly/gomavlib/tree/master/example)

  package main

  import (
  	"fmt"
  	"github.com/gswly/gomavlib"
  	"github.com/gswly/gomavlib/dialects/ardupilotmega"
  )

  func main() {
  	node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointSerial{"/dev/ttyUSB0:57600"},
		},
  		Dialect:     ardupilotmega.Dialect,
  		OutSystemId: 10,
  	})
  	if err != nil {
  		panic(err)
  	}
  	defer node.Close()

  	for evt := range node.Events() {
  		if frm,ok := evt.(*gomavlib.EventFrame); ok {
  			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetId(), frm.Message())
  		}
  	}
  }

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Channel

type Channel struct {
	// the endpoint which the channel belongs to
	Endpoint Endpoint
	// contains filtered or unexported fields
}

Channel is a communication channel created by an endpoint. For instance, a TCP client endpoint creates a single channel, while a TCP server endpoint creates a channel for each incoming connection.

func (*Channel) String

func (ch *Channel) String() string

String implements fmt.Stringer and returns the channel label.

type Dialect

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

Dialect contains available messages and the configuration needed to encode and decode them.

func MustDialect

func MustDialect(version uint, messages []Message) *Dialect

MustDialect is like NewDialect but panics in case of error.

func NewDialect

func NewDialect(version uint, messages []Message) (*Dialect, error)

NewDialect allocates a Dialect.

type Endpoint

type Endpoint interface {
	// Conf returns the configuration used to initialize the endpoint
	Conf() interface{}
	// contains filtered or unexported methods
}

Endpoint represents an endpoint, which contains zero or more channels.

type EndpointConf

type EndpointConf interface {
	// contains filtered or unexported methods
}

EndpointConf is the interface implemented by all endpoint configurations.

type EndpointCustom

type EndpointCustom struct {
	// the struct or interface implementing Read(), Write() and Close()
	ReadWriteCloser io.ReadWriteCloser
}

EndpointCustom sets up a endpoint that works through a custom interface that provides the Read(), Write() and Close() functions.

type EndpointSerial

type EndpointSerial struct {
	// the address of the serial port in format name:baudrate
	// example: /dev/ttyUSB0:57600
	Address string
}

EndpointSerial sets up a endpoint that works through a serial port.

type EndpointTcpClient

type EndpointTcpClient struct {
	// domain name or IP of the server to connect to, example: 1.2.3.4:5600
	Address string
}

EndpointTcpClient sets up a endpoint that works through a TCP client. TCP is fit for routing frames through the internet, but is not the most appropriate way for transferring frames from a UAV to a GCS, since it does not allow frame losses.

type EndpointTcpServer

type EndpointTcpServer struct {
	// listen address, example: 0.0.0.0:5600
	Address string
}

EndpointTcpServer sets up a endpoint that works through a TCP server. TCP is fit for routing frames through the internet, but is not the most appropriate way for transferring frames from a UAV to a GCS, since it does not allow frame losses.

type EndpointUdpBroadcast

type EndpointUdpBroadcast struct {
	// the broadcast address to which sending outgoing frames, example: 192.168.5.255:5600
	BroadcastAddress string
	// (optional) the listening address. if empty, it will be computed
	// from the broadcast address.
	LocalAddress string
}

EndpointUdpBroadcast sets up a endpoint that works through UDP broadcast packets.

type EndpointUdpClient

type EndpointUdpClient struct {
	// domain name or IP of the server to connect to, example: 1.2.3.4:5600
	Address string
}

EndpointUdpClient sets up a endpoint that works through a UDP client.

type EndpointUdpServer

type EndpointUdpServer struct {
	// listen address, example: 0.0.0.0:5600
	Address string
}

EndpointUdpServer sets up a endpoint that works through an UDP server. This is the most appropriate way for transferring frames from a UAV to a GCS if they are connected to the same network.

type Event

type Event interface {
	// contains filtered or unexported methods
}

Event is the interface implemented by all events received through node.Events().

type EventChannelClose

type EventChannelClose struct {
	Channel *Channel
}

EventChannelClose is the event fired when a channel is closed.

type EventChannelOpen

type EventChannelOpen struct {
	Channel *Channel
}

EventChannelOpen is the event fired when a channel is opened.

type EventFrame

type EventFrame struct {
	// the frame
	Frame Frame

	// the channel from which the frame was received
	Channel *Channel
}

EventFrame is the event fired when a frame is received.

func (*EventFrame) ComponentId

func (res *EventFrame) ComponentId() byte

ComponentId returns the frame component id.

func (*EventFrame) Message

func (res *EventFrame) Message() Message

Message returns the message inside the frame.

func (*EventFrame) SystemId

func (res *EventFrame) SystemId() byte

SystemId returns the frame system id.

type EventParseError

type EventParseError struct {
	// the error
	Error error

	// the channel used to send the frame
	Channel *Channel
}

EventParseError is the event fired when a parse error occurs.

type EventStreamRequested

type EventStreamRequested struct {
	// the channel to which the stream request is addressed
	Channel *Channel
	// the system id to which the stream requests is addressed
	SystemId byte
	// the component id to which the stream requests is addressed
	ComponentId byte
}

EventStreamRequested is the event fired when an automatic stream request is sent.

type Frame

type Frame interface {
	// the frame version.
	GetVersion() int
	// the system id of the author of the frame.
	GetSystemId() byte
	// the component id of the author of the frame.
	GetComponentId() byte
	// the message encapsuled in the frame.
	GetMessage() Message
	// the frame checksum.
	GetChecksum() uint16
	// generate a clone of the frame
	Clone() Frame
}

Frame is the interface implemented by frames of every supported version.

type FrameV1

type FrameV1 struct {
	SequenceId  byte
	SystemId    byte
	ComponentId byte
	Message     Message
	Checksum    uint16
}

FrameV1 represents a 1.0 frame.

func (*FrameV1) Clone

func (f *FrameV1) Clone() Frame

Clone is part of the Frame interface.

func (*FrameV1) GetChecksum

func (f *FrameV1) GetChecksum() uint16

GetChecksum is part of the Frame interface.

func (*FrameV1) GetComponentId

func (f *FrameV1) GetComponentId() byte

GetComponentId is part of the Frame interface.

func (*FrameV1) GetMessage

func (f *FrameV1) GetMessage() Message

GetMessage is part of the Frame interface.

func (*FrameV1) GetSystemId

func (f *FrameV1) GetSystemId() byte

GetSystemId is part of the Frame interface.

func (*FrameV1) GetVersion

func (f *FrameV1) GetVersion() int

GetVersion is part of the Frame interface.

type FrameV2

type FrameV2 struct {
	IncompatibilityFlag byte
	CompatibilityFlag   byte
	SequenceId          byte
	SystemId            byte
	ComponentId         byte
	Message             Message
	Checksum            uint16
	SignatureLinkId     byte
	SignatureTimestamp  uint64
	Signature           *Signature
}

FrameV2 represents a 2.0 frame.

func (*FrameV2) Clone

func (f *FrameV2) Clone() Frame

Clone is part of the Frame interface.

func (*FrameV2) GetChecksum

func (f *FrameV2) GetChecksum() uint16

GetChecksum is part of the Frame interface.

func (*FrameV2) GetComponentId

func (f *FrameV2) GetComponentId() byte

GetComponentId is part of the Frame interface.

func (*FrameV2) GetMessage

func (f *FrameV2) GetMessage() Message

GetMessage is part of the Frame interface.

func (*FrameV2) GetSystemId

func (f *FrameV2) GetSystemId() byte

GetSystemId is part of the Frame interface.

func (*FrameV2) GetVersion

func (f *FrameV2) GetVersion() int

GetVersion is part of the Frame interface.

func (*FrameV2) IsSigned

func (f *FrameV2) IsSigned() bool

IsSigned checks whether the frame contains a signature. It does not validate the signature.

type Hash16

type Hash16 interface {
	hash.Hash
	Sum16() uint16
}

Hash16 is an interface modeled on the standard hash.Hash32 and hash.Hash64. In this library, it is implemented by NewX25().

func NewX25

func NewX25() Hash16

NewX25 allocates a X25 hasher. X25 is the hash used to compute Frame checksums.

type Key

type Key [32]byte

Key is a key able to sign and validate V2 frames.

func NewKey

func NewKey(in []byte) *Key

NewKey allocates a Key.

type Message

type Message interface {
	GetId() uint32
}

Message is the interface that all mavlink messages must implements. Furthermore, message structs must be labeled MessageNameOfMessage.

type MessageRaw

type MessageRaw struct {
	Id      uint32
	Content []byte
}

MessageRaw is a special struct that contains a byte-encoded message, available in Content. It is used:

* as intermediate step in the encoding/decoding process

* when the parser receives an unknown message

func (*MessageRaw) GetId

func (m *MessageRaw) GetId() uint32

GetId implements the message interface.

type Node

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

Node is a high-level Mavlink encoder and decoder that works with endpoints.

func NewNode

func NewNode(conf NodeConf) (*Node, error)

NewNode allocates a Node. See NodeConf for the options.

func (*Node) Close

func (n *Node) Close()

Close halts node operations and waits for all routines to return.

func (*Node) Events

func (n *Node) Events() chan Event

Events returns a channel from which receiving events. Possible events are:

*EventChannelOpen
*EventChannelClose
*EventFrame
*EventParseError
*EventStreamRequested

See individual events for meaning and content.

func (*Node) WriteFrameAll

func (n *Node) WriteFrameAll(frame Frame)

WriteFrameAll writes a frame to all channels. This function is intended for routing frames to other nodes, since all frame fields must be filled manually.

func (*Node) WriteFrameExcept

func (n *Node) WriteFrameExcept(exceptChannel *Channel, frame Frame)

WriteFrameExcept writes a frame to all channels except specified channel. This function is intended for routing frames to other nodes, since all frame fields must be filled manually.

func (*Node) WriteFrameTo

func (n *Node) WriteFrameTo(channel *Channel, frame Frame)

WriteFrameTo writes a frame to given channel. This function is intended for routing frames to other nodes, since all frame fields must be filled manually.

func (*Node) WriteMessageAll

func (n *Node) WriteMessageAll(message Message)

WriteMessageAll writes a message to all channels.

func (*Node) WriteMessageExcept

func (n *Node) WriteMessageExcept(exceptChannel *Channel, message Message)

WriteMessageExcept writes a message to all channels except specified channel.

func (*Node) WriteMessageTo

func (n *Node) WriteMessageTo(channel *Channel, message Message)

WriteMessageTo writes a message to given channel.

type NodeConf

type NodeConf struct {
	// the endpoints with which this node will
	// communicate. Each endpoint contains zero or more channels
	Endpoints []EndpointConf

	// the messages which will be automatically decoded and
	// encoded. If not provided, messages are decoded in the MessageRaw struct.
	Dialect *Dialect

	// (optional) the secret key used to validate incoming frames.
	// Non signed frames are discarded, as well as frames with a version < 2.0.
	InKey *Key

	// Mavlink version used to encode frames. See Version
	// for the available options.
	OutVersion Version
	// the system id, added to every outgoing frame and used to identify this
	// node in the network.
	OutSystemId byte
	// (optional) the component id, added to every outgoing frame, defaults to 1.
	OutComponentId byte
	// (optional) the secret key used to sign outgoing frames.
	// This feature requires a version >= 2.0.
	OutKey *Key

	// (optional) disables the periodic sending of heartbeats to open channels.
	HeartbeatDisable bool
	// (optional) the period between heartbeats. It defaults to 5 seconds.
	HeartbeatPeriod time.Duration
	// (optional) the system type advertised by heartbeats.
	// It defaults to MAV_TYPE_GCS
	HeartbeatSystemType int
	// (optional) the autopilot type advertised by heartbeats.
	// It defaults to MAV_AUTOPILOT_GENERIC
	HeartbeatAutopilotType int

	// (optional) automatically request streams to detected Ardupilot devices,
	// that need an explicit request in order to emit telemetry stream.
	StreamRequestEnable bool
	// (optional) the requested stream frequency in Hz. It defaults to 4.
	StreamRequestFrequency int
}

NodeConf allows to configure a Node.

type Parser

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

Parser is a low-level Mavlink encoder and decoder that works with a Reader and a Writer.

func NewParser

func NewParser(conf ParserConf) (*Parser, error)

NewParser allocates a Parser, a low level frame encoder and decoder. See ParserConf for the options.

func (*Parser) Checksum

func (p *Parser) Checksum(f Frame) uint16

Checksum computes the checksum of a given frame.

func (*Parser) Read

func (p *Parser) Read() (Frame, error)

Read returns the first Frame parsed from the reader. It must not be called by multiple routines in parallel.

func (*Parser) Signature

func (p *Parser) Signature(ff *FrameV2, key *Key) *Signature

Signature computes the signature of a given frame with the given key.

func (*Parser) Write

func (p *Parser) Write(f Frame, route bool) error

Write writes a Frame into the writer. It must not be called by multiple routines in parallel. If route is false, the following fields will be filled:

IncompatibilityFlag
SequenceId
SystemId
ComponentId
Checksum
SignatureLinkId
SignatureTimestamp
Signature

if route is true, the frame will be written untouched.

type ParserConf

type ParserConf struct {
	// the reader from which frames will be read.
	Reader io.Reader
	// the writer to which frames will be written.
	Writer io.Writer

	// contains the messages which will be automatically decoded and
	// encoded. If not provided, messages are decoded in the MessageRaw struct.
	Dialect *Dialect

	// (optional) the secret key used to validate incoming frames.
	// Non-signed frames are discarded. This feature requires Mavlink v2.
	InKey *Key

	// the system id, added to every outgoing frame and used to identify this
	// node in the network.
	OutSystemId byte
	// (optional) the component id, added to every outgoing frame, defaults to 1.
	OutComponentId byte
	// (optional) the value to insert into the signature link id
	OutSignatureLinkId byte
	// (optional) the secret key used to sign outgoing frames.
	// This feature requires Mavlink v2.
	OutKey *Key
}

ParserConf configures a Parser.

type ParserError

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

ParserError is the error returned in case of non-fatal parsing errors.

func (*ParserError) Error

func (e *ParserError) Error() string

type Signature

type Signature [6]byte

Signature is a V2 frame signature.

type Version

type Version int

Version allows to set the frame version used to wrap outgoing messages.

const (
	// V2 wrap outgoing messages in v2 frames.
	V2 Version = iota
	// V1 wrap outgoing messages in v1 frames.
	V1
)

Directories

Path Synopsis
ASLUAV
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
ardupilotmega
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
autoquad
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
common
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
icarous
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
matrixpilot
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
minimal
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
paparazzi
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
pythonarraytest
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
slugs
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
standard
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
test
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
uAvionix
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.
ualberta
Autogenerated with dialgen, do not edit.
Autogenerated with dialgen, do not edit.

Jump to

Keyboard shortcuts

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