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 uses MAVSpec to generate MAVLink dialects.
§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;
let mut receiver = Receiver::versionless(TcpStream::connect("0.0.0.0:5600")?);
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 mut sender = Sender::new(TcpStream::connect("0.0.0.0:5600")?);
// 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);
}
§Features
This library is a building block for more sophisticated tools. It includes absolute minimum of functionality required for correct communication with everything that speaks MAVLink protocol:
- It supports both
MAVLink 1
andMAVLink 2
protocol versions. - Provides intermediate MAVLink packets decoding with
Frame
that 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 aFrame
with a correct sequence as required by MAVLink protocol. - Includes tools for message signing.
§Extra features
Most of the “extra” features are related to decoupling from MAVLink XML definitions parsing and code generation. These tasks are performed by MAVInspect and MAVSpec respectively.
- Supports custom dialects or may work with no dialect at all (for intermediate decoding).
- Includes support for custom payload decoders and encoders. Which means that clients are not bounded by abstractions generated by MAVSpec.
- Can read and write messages to anything that implements
std::io::Read
andstd::io::Write
traits. - Supports asynchronous I/O with
AsyncSender
andAsyncReceiver
that available under theasync
feature flag. - Compatible with
no_std
targets. For such cases the library provides simplified versions ofRead
andWrite
traits. - Respects dialect inheritance. Messages defined in one dialect are not redefined upon inclusion
into another dialect. This means that if you have a message
M
from dialectA
being included by dialectB
, it guaranteed that you can use Rust structs for messageM
with both of the dialects. The same is true for MAVLink enums and bitmasks.
§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 heartbeat updates as inactive or invalid.
- Stateful timestamp management for message signing ensuring, that two messages are not sent with the same timestamp.
§Dialects
Standard MAVLink dialect can be enabled by the corresponding feature flags.
minimal
— minimal dialect required to expose your presence to other MAVLink devices.standard
— a superset ofminimal
dialect, 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 these which were created for testing purposes. It is guaranteed that namespaces of the dialects inall
family do not collide.- Other dialects from MAVLink XML definitions:
asluav
,avssuas
,csairlink
,cubepilot
,development
,icarous
,matrixpilot
,paparazzi
,ualberta
,uavionix
. These do not includepython_array_test
andtest
dialects which should be either generated manually or as a part ofall
meta-dialect.
§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.
Modules§
- Constants
- Autogenerated MAVLink dialects
- Errors
- Basic MAVLink I/O
- Common imports
- MAVLink protocol
- Utils
Structs§
- Receives MAVLink frames asynchronously.
- Sends MAVLink frames asynchronously.
- MAVLink device with defined
ID
and internal frame sequence counter. - MAVLink frame.
- MAVLink device
ID
. - Receives MAVLink frames.
- Sends MAVLink frames.
Enums§
- Version-agnostic MAVLink frame, that can be matched according to its protocol version.
Traits§
mavspec
Interface for autogenerated or custom MAVLink dialect specification.mavspec
MAVLink message implementation.
Type Aliases§
- Common result type returned by
mavio
functions and methods.