Expand description
Β§Mavio
Minimalistic library for transport-agnostic MAVLink communication.
It supports no-std (and no-alloc) targets.
This library is a part of Mavka toolchain. It focuses on I/O and uses MAVSpec to generate MAVLink dialects.
Β§Features
Mavio is focused on I/O primitives for MAVLink that can be used in no-std and no-alloc
environments. Since Mavio is designed as a building block for more sophisticated tools,
it includes absolute minimum of functionality required for correct communication with everything
that speaks MAVLink protocol.
Β§Basic capabilities
- Mavio supports both
MAVLink 1andMAVLink 2protocol versions. - Provides intermediate MAVLink packets decoding with
Framethat contain only header, checksum and signature being deserialized. Which means that client donβt have to decode the entire message for routing and verification. - Supports optional high-level message decoding by utilizing MAVLink abstractions generated by MAVSpec.
- Includes standard MAVLink dialects enabled by cargo features.
- Implements message verification via checksum.
- Provides a mechanism for message sequencing through
Endpoint::next_frame, that encodes a MAVLink message into aFramewith a correct sequence as required by MAVLink protocol. - Includes tools for message signing.
Β§Flexible approach to I/O
Mavio is designed to be flexible and useful in different scenarios.
- It can work without any MAVLink dialect at all (for intermediate decoding and proxying).
- Includes support for custom payload decoders and encoders. Which means that clients are not bounded by abstractions generated by MAVSpec.
- Uses implementation-agnostic I/O primitives with a variety of I/O adapters.
- Provides synchronous I/O adapters for embedded-io and
std::io. - Supports asynchronous I/O by providing lightweight adapters for embedded-io-async, Tokio, and futures-rs.
Β§MAVLink protocol support
Such features are mainly related to the functionality provided by other parts of Mavka toolchain. These tasks are mainly performed by MAVInspect and MAVSpec (a message definition parser and code-generator respectively). In particular:
- Mavio allows to use custom MAVLink dialects. This includes both dialects generated from XML definitions and ad-hoc dialects defined with pure Rust.
- Respects dialect inheritance. Messages defined in one dialect are not redefined upon inclusion
into another dialect. This means that if you have a message
Mfrom dialectAbeing included by dialectB, it guaranteed that you can use Rust structs for messageMwith both of the dialects. The same is true for MAVLink enums and bitmasks. - Provides optional support for MAVLink microservices as sub-dialects and helpers to work with them such as mission file format.
Β§Serialization / deserialization and FFI
Mavio provides support for serde and specta. The
latter is supported only for std targets. All MAVLink entities are fully supported.
Β§Out of scope
There are few stateful features required by MAVLink protocol this library intentionally does not implement and leaves for the client:
- Sending automatic heartbeats. This is required by most of the clients which would consider nodes without heartbeats as inactive or invalid.
- Stateful timestamp management for message signing (ensuring, that two messages are not sent with the same timestamp).
- Retry logic for failed connections.
All such features are provided by Maviola.
Β§Usage
This library exposes Sender and Receiver to send and receive instances of MAVLink
Frame. Frames contain encoded message body in Frame::payload and additional fields (such
as sequence or system_id) as required by MAVLink specification.
Once frame is received, it can be decoded into a specific Message. Frame decoding requires
dialect specification which can be either generated manually by using
MAVSpec or by enabling built-in
dialect features.
Upon receiving or building a frame, it can be converted into a protocol-agnostic MavFrame,
that hides generic version parameter of a Frame.
Β§Receive
Connect to TCP port and receive first 10 MAVLink frames, decode any received HEARTBEAT messages.
use std::net::TcpStream;
use mavio::prelude::*;
use mavio::dialects::minimal as dialect;
use dialect::Minimal;
// Create a TCP client receiver
let reader = StdIoReader::new(TcpStream::connect("0.0.0.0:5600")?);
let mut receiver = Receiver::versionless(reader);
for i in 0..10 {
let frame = receiver.recv()?;
// Validate MAVLink frame
if let Err(err) = frame.validate_checksum::<Minimal>() {
eprintln!("Invalid checksum: {err:?}");
continue;
}
if let Ok(Minimal::Heartbeat(msg)) = frame.decode() {
println!(
"HEARTBEAT #{}: mavlink_version={:#?}",
frame.sequence(),
msg.mavlink_version,
);
}
}
Β§Send
Connect to TCP port and send 10 HEARTBEAT messages using
MAVLink 2 protocol.
use std::net::TcpStream;
use mavio::prelude::*;
use mavio::dialects::minimal as dialect;
use dialect::enums::{MavAutopilot, MavModeFlag, MavState, MavType};
// Create a TCP client sender
let writer = StdIoWriter::new(TcpStream::connect("0.0.0.0:5600")?);
let mut sender = Sender::new(writer);
// Create an endpoint that represents a MAVLink device speaking `MAVLink 2` protocol
let endpoint = Endpoint::v2(MavLinkId::new(15, 42));
// Create a message
let message = dialect::messages::Heartbeat {
type_: MavType::FixedWing,
autopilot: MavAutopilot::Generic,
base_mode: MavModeFlag::TEST_ENABLED & MavModeFlag::CUSTOM_MODE_ENABLED,
custom_mode: 0,
system_status: MavState::Active,
mavlink_version: dialect::Minimal::version().unwrap(),
};
println!("MESSAGE: {message:?}");
for i in 0..10 {
// Build the next frame for this endpoint.
// All required fields will be populated, including frame sequence counter.
let frame = endpoint.next_frame(&message)?;
sender.send(&frame)?;
println!("FRAME #{} sent: {:#?}", i, frame);
}
Β§I/O
We provide lightweight Read / Write and
AsyncRead / AsyncWrite pairs for synchronous and
asynchronous I/O.
Mavio packages a set of I/O adapters available under the corresponding feature flags:
embedded-ioβio::EmbeddedIoReader/io::EmbeddedIoWriterembedded-io-asyncβio::EmbeddedIoAsyncReader/io::EmbeddedIoAsyncWriterstdβio::StdIoReader/io::StdIoWritertokioβio::TokioReader/io::TokioWriterfuturesβio::FuturesReader/io::FuturesWriter
See adapters for details.
Β§Dialects
Standard MAVLink dialect can be enabled by the corresponding feature flags (dlct-<dialect name>).
minimalβ minimal dialect required to expose your presence to other MAVLink devices.standardβ a superset ofminimaldialect, that expected to be used by almost all flight stack.commonβ minimum viable dialect with most of the features, a building block for other future-rich dialects.ardupilotmegaβ feature-full dialect used by ArduPilot. In most cases this dialect is the go-to choice if you want to recognize almost all MAVLink messages used by existing flight stacks.allβ meta-dialect which includes all other standard dialects including those which were created for testing purposes. It is guaranteed that namespaces of the dialects inallfamily do not collide.- Other dialects from MAVLink XML definitions:
asluav,avssuas,csairlink,cubepilot,development,icarous,matrixpilot,paparazzi,ualberta,uavionix. These do not includepython_array_testandtestdialects which should be either generated manually or as a part ofallmeta-dialect.
For example:
use mavio::dialects::common as dialect;
use dialect::{Common, messages::Heartbeat};
use mavio::prelude::*;
let frame: Frame<V2> = /* obtain a frame */
// Decode MavLink frame into a dialect message:
match frame.decode()? {
Common::Heartbeat(msg) => {
/* process heartbeat */
}
/* process other messages */
};Β§Default Dialect
When standard MAVLink dialects are used and at least minimal Cargo feature is enabled, this
library exposes default_dialect and DefaultDialect entities that allow to access the
most feature-rich enabled MAVLink dialect.
Β§Microservices
Mavio re-exports MAVLink microservices from
MAVSpec. To control which microservices you want to generate,
use msrv-* feature flags family. Check MAVSpec API docs for
details.
At the moment, microservices are generated only for default_dialect and can be accessed
through default_dialect::microservices.
In addition, Mavio re-exports extra tools for working with microservices. These tools can be
enabled by msrv-utils-* feature flags and available in microservices module.
Microservice utils feature flags:
msrv-utils-allβ all microservice utils.msrv-utils-missionβmicroservices::missionβ MAVLink mission protocol utils including support for unofficial mission file format.
Β§Message definitions
It is possible to bundle message definitions generated by MAVInspect
into definitions module. This can be useful for ground control stations that require to present the
user with the descriptions of MAVLink entities.
To enable definitions bundling use definitions feature flag.
Β§Caveats
The API is straightforward and generally stable, however, some caution is required when working with edge-cases.
Β§Unsafe Features
This library does not use unsafe Rust, however, certain manipulations on MAVLink frames, if not
performed carefully, could lead to data corruption and undefined behavior. All such operations
are covered by unsafe cargo features and marked with β in the documentation.
Most of the unsafe operations are related to updating existing frames in-place. In general,
situations when you need mutable access to frames are rare. If your use-case does not strictly
require such manipulations, we suggest to refrain from using functionality hidden under the
unsafe feature flags.
Β§Unstable Features
Certain features are considered unstable and available only when unstable feature flag is
enabled. Unstable features are marked with β and are may be changed in futures
versions.
Β§Incompatible Features
- Specta requires
stdfeature to be enabled. - MAVlink
definitionsrequiresstdfeature to be enabled.
Β§Binary Size
For small applications that use only a small subset of messages, avoid using dialect enums as they contain all message variants. Instead, decode messages directly from frames:
use mavio::dialects::common as dialect;
use dialect::messages::Heartbeat;
use mavio::prelude::*;
let frame: Frame<V2> = /* obtain a frame */
// Use only specific messages:
match frame.message_id() {
Heartbeat::ID => {
let msg = Heartbeat::try_from(frame.payload())?;
/* process heartbeat */
}
/* process other messages */
};This will help compiler to throw away unnecessary pieces of code.
Additionally, you may use default_dialect::microservices as well as microservices tools
to reduce the API surface you are interacting with.
Β§Feature flags
In most of the cases you will be interested in dlct-* features, I/O providers, and
alloc / std target specification. However, a more fine-grained control may be required.
Β§Generic features
defaultβ Default features (nothing is enabled).unstableβ Enable unstable API features.extrasβ Additional auxilary tools.unsafeβ Unsafe features, that allow access to internal state of the entities.allocβ Enable memory allocation support.stdβ Enable Rust std library.sha2β Enable sha2 backend for message signing
Β§Serialization and reflection
These features enable serde and specta support.
serdeβ Enable serde support.spectaβ Enable specta support.
Β§I/O providers
These features enable I/O providers such as Tokio or embedded-io
futuresβ Enable async support via futures-rstokioβ Enable async support via Tokioembedded-ioβ Enable synchronous I/O support from embedded HALembedded-io-asyncβ Enable asynchronous I/O support from embedded HAL
Β§MAVSpec tools
These features package additional MAVSpec utils suc as derive macros and message definitions.
-
deriveβ Adds derive macros for MAVLink entities.You can access them as
mavio::derive. -
definitionsβ Bundles MAVLink message definitions.Message
definitionswill be generated only for bundled MAVLink dialects. Microservices will be ignored as they are just subsets of existing dialects.Note, that while being useful for ground control stations, the generated definitions is quite large and may bloat the size of the binary.
β οΈ This feature wonβt compile without
stdfeature enabled.
Β§Dialects
Bundle standard MAVLink dialects as defined in XML message definitions generated by MAVSpec.
dlct-ardupilotmegaβ Includeardupilotmegadialectdlct-asluavβ IncludeASLUAVdialectdlct-avssuasβ IncludeAVSSUASdialectdlct-commonβ Includecommondialectdlct-cs_air_linkβ IncludecsAirLinkdialectdlct-cubepilotβ Includecubepilotdialectdlct-developmentβ Includedevelopmentdialectdlct-icarousβ Includeicarousdialectdlct-matrixpilotβ Includematrixpilotdialectdlct-minimalβ Includeminimaldialectdlct-paparazziβ Includepaparazzidialectdlct-standardβ Includestandarddialectdlct-ualbertaβ Includeualbertadialectdlct-uavionixβ IncludeuAvionixdialectdlct-allβ Includeallmeta-dialect
Β§MAVLink microservices
These features will control generation of MAVLink microservice-specific bindings.
msrv-allβ Support for all MavLink microservicesmsrv-heartbeatβ Heartbeat protocol supportmsrv-missionβ Mission protocol supportmsrv-parameterβ Parameter protocol supportmsrv-parameter-extβ Extended parameter protocol supportmsrv-commandβ Command protocol supportmsrv-manual-controlβ Manual control protocol supportmsrv-cameraβ Camera protocol v2 supportmsrv-gimbal-v1β Gimbal protocol v1 supportmsrv-gimbal-v2β Gimbal protocol v2 supportmsrv-arm-authβ Arm authorization protocol supportmsrv-image-transmissionβ Image transmission protocol supportmsrv-ftpβ File transfer protocol supportmsrv-landing-targetβ Landing target protocol supportmsrv-pingβ Ping protocol supportmsrv-path-planningβ Path planning protocol supportmsrv-batteryβ Battery protocol supportmsrv-terrainβ Terrain protocol supportmsrv-tunnelβ Tunnel protocol supportmsrv-open-drone-idβ Open Drone ID protocol supportmsrv-high-latencyβ High latency protocol supportmsrv-component-metadataβ Component metadata protocol supportmsrv-payloadβ Payload protocol supportmsrv-traffic-managementβ Traffic management protocol supportmsrv-events-interfaceβ Events interface protocol supportmsrv-time-syncβ Time synchronization protocol support
Β§Additional MAVLink tools
These features will enable additional MAVLink utilities such as *.waypoints files support, mission planninc, etc.
β οΈ All such features require unstable feature to be enabled in order to take effect.
-
msrv-utils-allβ All MAVLink microservices utilsβ οΈ Requires
unstablefeature to take effect. -
msrv-utils-missionβ Mission protocol utilsβ οΈ Requires
unstablefeature to take effect.
Β§Technical features
These features should not be used directly.
-
msrvβ β Enable MAVLink microservices supportDo not use directly as this feature does not give access to any specific functionality by itself. Instead, use one of
msrv-*features. -
msrv-utilsβ βοΈ Enables MAVLink microservices extra utilsDo not use directly as this feature does not give access to any specific functionality by itself. Instead, use one of
msrv-utils-*features.
ModulesΒ§
- consts
- Constants
- default_
dialect mavspecDefault MAVLink dialect module- definitions
mavspecMAVLink message definitions- derive
mavspecMAVSpec procedural macros- dialects
mavspecMAVLink dialects- error
- Errors
- io
- Basic MAVLink I/O
- mavspec
mavspecMAVSpec re-exported- microservices
mavspecTools for MAVLink microservices- prelude
- Common imports
- protocol
- MAVLink protocol
- utils
- Utils
StructsΒ§
- Async
Receiver - Receives MAVLink frames asynchronously.
- Async
Sender - Sends MAVLink frames asynchronously.
- Endpoint
- MAVLink device with defined
IDand internal frame sequence counter. - Frame
- MAVLink frame.
- MavLink
Id mavspecMAVLink deviceID.- Receiver
- Receives MAVLink frames.
- Sender
- Sends MAVLink frames.
EnumsΒ§
- Default
Dialect mavspecDefault MAVLink dialect- Error
maviotop-level error.- MavFrame
- Version-agnostic MAVLink frame, that can be matched according to its protocol version.
TraitsΒ§
- Dialect
mavspecInterface for autogenerated or custom MAVLink dialect specification.- Message
mavspecMAVLink message implementation.
Type AliasesΒ§
- Result
- Common result type returned by
maviofunctions and methods.