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 the 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 a client doesnβ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 using custom MAVLink dialects. This includes both dialects generated from XML definitions and adhoc 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 guarantees 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 subdialects 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 an encoded message body in Frame::payload and additional fields
(such as sequence or system_id) as required by MAVLink specification.
Once a 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 the generic version parameter of a Frame.
Β§Receive
Connect to TCP port and receive the 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 adapters
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.
Β§MAVLink protocol
We use MAVSpec to generate MAVLink entities and additional abstractions. These entities are bundled with Mavio for a better user experience and to prevent discrepancies in crate versions.
Β§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 of theminimaldialect that is expected to be used by almost all flight stacks.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 in theallfamily 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.
Use Frame::decode with an implicit or explicit generic parameter of a 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 */
};Β§Direct decoding into a message
When memory footprint is critical, using dialect enums is suboptimal. In this case you can use
Frame::decode_message to decode a frame into a specific message:
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.message_id() {
Heartbeat::ID => {
let message = frame.decode_message::<Heartbeat>().unwrap();
/* process heartbeat */
}
/* process other messages */
};Β§Default dialect
When standard MAVLink dialects are used and at least dlct-minimal Cargo feature is enabled,
this library exposes default_dialect and DefaultDialect entities that allow to access
the most feature-rich enabled MAVLink dialect. Other features such as microservices or
microservice utils are based on this convention.
The sequence of default dialects is the following (in the order of the increased completeness):
minimalβ enabled bydlct-minimalfeature flagstandardβ enabled bydlct-standardfeature flagcommonβ enabled bydlct-commonfeature flagardupilotmegaβ enabled bydlct-ardupilotmegafeature flagallβ enabled bydlct-allfeature flag
Β§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 microservices.
Β§Microservice utils
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::utils module and
bundled inside the corresponding microservice.
Β§Message definitions
It is possible to bundle message definitions generated by MAVInspect
into the definitions module. This can be useful for ground control stations that require to present the
user with the descriptions of MAVLink entities.
To enable MAVLink definitions bundling, use the definitions feature flag.
Β§Metadata
MAVSpec can generate additional metadata such as MAVLink enum entry names. This can be a useful
addition to MAVlink definitions when ground stations are considered. To enable metadata
support, use the metadata 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 refraining from using functionality hidden under the
unsafe feature flags.
Β§Unstable Features
Certain features are considered unstable and available only when the unstable feature flag
is enabled. Unstable features are marked with β and could be changed in future
versions.
Β§Incompatible Features
- Specta requires the
stdfeature to be enabled. - MAVlink
definitionsrequires thestdfeature 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 microservices as well as microservices::utils to reduce the
API surface you are interacting with.
Β§Feature flags
In most of the cases you will be interested in dlct-* features to access MAVLink dialects,
I/O adapters, 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 the internal state of the entities.allocβ Enable memory allocation support.stdβ Enable the 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 such 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 are quite large and may bloat the size of the binary.
β οΈ This feature wonβt compile without the
stdfeature enabled. -
metadataβ Adds additional metadata to MAVLink entities.
Β§Dialects
Bundle standard MAVLink dialects as defined in XML message definitions generated by MAVSpec.
All enabled dialects can be found in the dialects module. The default dialect, if available, can be found in
the default_dialect or as a DefaultDialect.
-
dlct-ardupilotmegaβ IncludeardupilotmegadialectThe dialect can be found in
dialects::ardupilotmegamodule. -
dlct-asluavβ IncludeASLUAVdialectThe dialect can be found in
dialects::asluavmodule. -
dlct-avssuasβ IncludeAVSSUASdialectThe dialect can be found in
dialects::avssuasmodule. -
dlct-commonβ IncludecommondialectThe dialect can be found in
dialects::commonmodule. -
dlct-cs_air_linkβ IncludecsAirLinkdialectThe dialect can be found in
dialects::cs_air_linkmodule. -
dlct-cubepilotβ IncludecubepilotdialectThe dialect can be found in
dialects::cubepilotmodule. -
dlct-developmentβ IncludedevelopmentdialectThe dialect can be found in
dialects::developmentmodule. -
dlct-icarousβ IncludeicarousdialectThe dialect can be found in
dialects::icarousmodule. -
dlct-matrixpilotβ IncludematrixpilotdialectThe dialect can be found in
dialects::matrixpilotmodule. -
dlct-minimalβ IncludeminimaldialectThe dialect can be found in
dialects::minimalmodule. -
dlct-paparazziβ IncludepaparazzidialectThe dialect can be found in
dialects::paparazzimodule. -
dlct-standardβ IncludestandarddialectThe dialect can be found in
dialects::standardmodule. -
dlct-ualbertaβ IncludeualbertadialectThe dialect can be found in
dialects::ualbertamodule. -
dlct-uavionixβ IncludeuAvionixdialectThe dialect can be found in
dialects::u_avionixmodule. -
dlct-allβ Includeallmeta-dialectThe dialect can be found in
dialects::allmodule.
Β§MAVLink microservices
These features will control the generation of MAVLink microservice-specific bindings.
If enabled, microservices can be found in the microservices module.
-
msrv-allβ Support for all MavLink microservices -
msrv-heartbeatβ Heartbeat protocol supportThis microservice can be found in
microservices::heartbeatmodule. -
msrv-missionβ Mission protocol supportThis microservice can be found in
microservices::missionmodule. -
msrv-parameterβ Parameter protocol supportThis microservice can be found in
microservices::parametermodule. -
msrv-parameter-extβ Extended parameter protocol supportThis microservice can be found in
microservices::parameter_extmodule. -
msrv-commandβ Command protocol supportThis microservice can be found in
microservices::commandmodule. -
msrv-manual-controlβ Manual control protocol supportThis microservice can be found in
microservices::manual_controlmodule. -
msrv-cameraβ Camera protocol v2 supportThis microservice can be found in
microservices::cameramodule. -
msrv-gimbal-v1β Gimbal protocol v1 supportThis microservice can be found in
microservices::gimbal_v1module. -
msrv-gimbal-v2β Gimbal protocol v2 supportThis microservice can be found in
microservices::gimbal_v2module. -
msrv-arm-authβ Arm authorization protocol supportThis microservice can be found in
microservices::arm_authmodule. -
msrv-image-transmissionβ Image transmission protocol supportThis microservice can be found in
microservices::image_transmissionmodule. -
msrv-ftpβ File transfer protocol supportThis microservice can be found in
microservices::ftpmodule. -
msrv-landing-targetβ Landing target protocol supportThis microservice can be found in
microservices::landing_targetmodule. -
msrv-pingβ Ping protocol supportThis microservice can be found in
microservices::pingmodule. -
msrv-path-planningβ Path planning protocol supportThis microservice can be found in
microservices::path_planningmodule. -
msrv-batteryβ Battery protocol supportThis microservice can be found in
microservices::batterymodule. -
msrv-terrainβ Terrain protocol supportThis microservice can be found in
microservices::terrainmodule. -
msrv-tunnelβ Tunnel protocol supportThis microservice can be found in
microservices::tunnelmodule. -
msrv-open-drone-idβ Open Drone ID protocol supportThis microservice can be found in
microservices::open_drone_idmodule. -
msrv-high-latencyβ High latency protocol supportThis microservice can be found in
microservices::high_latencymodule. -
msrv-component-metadataβ Component metadata protocol supportThis microservice can be found in
microservices::component_metadatamodule. -
msrv-payloadβ Payload protocol supportThis microservice can be found in
microservices::payloadmodule. -
msrv-traffic-managementβ Traffic management protocol supportThis microservice can be found in
microservices::traffic_managementmodule. -
msrv-events-interfaceβ Events interface protocol supportThis microservice can be found in
microservices::events_interfacemodule. -
msrv-time-syncβ Time synchronization protocol supportThis microservice can be found in
microservices::time_syncmodule.
Β§Additional MAVLink tools
These features will enable additional MAVLink utilities such as *.waypoints file support, mission planninc, etc.
β οΈ All such features require unstable feature to be enabled to take effect.
-
msrv-utils-allβ All MAVLink microservices utilsβ οΈ Requires
unstablefeature to take effect. -
msrv-utils-missionβ Mission protocol utilsThese additional utils are packaged into
microservices::missionmicroservice and can be alternatively accessed throughmicroservices::utils::mission.β οΈ 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
mavspecMAVLink 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.