10 个版本
0.2.6 | 2024 年 8 月 9 日 |
---|---|
0.2.5 | 2024 年 3 月 26 日 |
0.2.0-rc1 | 2024 年 1 月 26 日 |
0.1.1 | 2024 年 1 月 11 日 |
0.1.0 | 2023 年 12 月 30 日 |
#35 在 机器人
220 每月下载量
用于 maviola
250KB
3.5K SLoC
Mavio
支持传输无关的 MAVLink 通信的简约库。它支持 no-std
(和 no-alloc
)目标。
仓库
目前,我们使用 GitLab 作为主要项目仓库,并将 GitHub 作为官方镜像。
我们只在 GitLab 上接受 问题 和 合并请求,但我们会尽力让 GitHub 讨论 尽可能活跃。
镜像将始终包含最新的发布标签,并自动保持更新。
简介
马维奥是一个用于构建更复杂工具的组件。它完全专注于一件事:为与使用 MAVLink 协议的所有设备进行正确通信,提供所需的最小功能集。
- 支持
MAVLink 1
和MAVLink 2
协议版本。 - 提供中间 MAVLink 数据包解码,以“帧”的形式存在,仅包含头部、校验和签名进行反序列化。这意味着客户端不需要解码整个消息进行路由和验证。
- 通过利用由 MAVSpec 生成的 MAVLink 抽象,支持可选的高级消息解码。
- 包括由 Cargo 功能启用的标准 MAVLink 方言。
- 通过校验和实现消息验证。
- 包括用于 消息签名 的工具。
换句话说,马维奥实现了 MAVLink 协议的所有 无状态 功能。这意味着它不提供对消息序列化、自动心跳等功能的支持。客户端需要自行实现这些协议部分或使用专门的库。我们决定将马维奥保持得尽可能简单和吸引人,就像一个 8 位旋律。
同时,马维奥具有灵活性,并尽量少地强制规定。特别是
- 它支持 自定义方言 或可能根本不使用方言(用于中间解码)。后者在只想简单地路由或签名消息时很有用。
- 可以读取和写入实现
std::io::Read
和std::io::Write
特性的任何内容。 - 与
no_std
目标兼容。在这种情况下,库提供了Read
和Write
特性的简化版本。 - 通过 Tokio 支持异步 I/O。
- 允许过滤掉不必要的 MAVLink 实体(即消息、枚举、命令),以减少编译时间。
此库是 Mavka 工具链的一部分。它与以下项目集成
- MAVInspect 负责解析 MAVLink XML 定义。
- MAVSpec 专注于代码生成。马维奥使用此库生成 MAVLink 方言。
- Maviola,是一个基于
Mavio
的 MAVLink 通信库,提供高级接口用于 MAVLink 消息,并处理协议的 有状态 功能:序列化、消息时间戳、自动心跳、简化消息签名等。
此项目遵循 语义版本控制
。根据规范,在达到版本 1.0.0
之前,可以在次要版本中引入破坏性更改。然而,我们将在可能的情况下,将不稳定的功能保持在 unstable
功能标志下。
安装
使用 cargo 安装马维奥
cargo add mavio
用法
接收 MAVLink 帧
作为TCP客户端连接,接收10个帧,并解码任何接收到的HEARTBEAT
消息
use std::net::TcpStream;
use mavio::{Frame, Receiver};
use mavio::dialects::minimal as dialect;
use dialect::Minimal;
fn main() -> mavio::errors::Result<()> {
let mut receiver = Receiver::new(TcpStream::connect("0.0.0.0:5600")?);
for i in 0..10 {
let frame = receiver.recv_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,
);
}
}
}
更详细的用例可以在tcp_client.rs
示例中找到。
发送MAVLink帧
作为服务器监听TCP端口,使用MAVLink 2协议向任何连接的客户端发送10个HEARTBEAT
消息,然后断开客户端。
use std::net::TcpStream;
use mavio::dialects::minimal as dialect;
use dialect::enums::{MavAutopilot, MavModeFlag, MavState, MavType};
use mavio::prelude::*;
fn main() -> Result<()> {
let mut sender = Sender::new(TcpStream::connect("0.0.0.0:5600")?);
// 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: 3,
};
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(&frame)?;
println!("FRAME #{} sent: {:#?}", i, frame);
}
}
查看tcp_server.rs
以获取更详细的用例。
API说明
本节提供了一般的API概述。对于更详细的信息,请查看API文档。
I/O
Mavio提供了两个基本的I/O原语:Sender
和Receiver
。这些结构体发送和接收Frame
实例。
Sender
和Receiver
是针对std::io::Write
和std::io::Read
泛型的。这意味着您可以通过实现这些特性的各种传输来通信MAVLink消息,包括UDP、TCP、Unix套接字和文件。实现自定义传输也很容易。
对于no-std
目标,Mavio提供了Read
和Write
特性的自定义实现。您可以针对特定的硬件通信(如串行端口)实现它们。
对于异步I/O,Mavio提供了与它们的同步对应物类似工作的AsyncSender
和AsyncReceiver
。除了使用Tokio
之外,它们的操作方式相同。要启用异步支持,请添加tokio
功能标志。
编码/解码
在接收后,MAVLink Frame
可以被验证并解码为MAVLink消息。帧可以在不进行解码的情况下被路由、签名或转发到另一个系统/组件ID。
注意!
MAVLink校验和验证需要
CRC_EXTRA
字节,它反过来依赖于方言规范。这意味着,如果您正在从嘈杂的源或实现过时消息规范的设备进行无方言路由,您可能会转发垃圾消息。在高延迟通道的情况下,您可能希望强制符合特定的方言以过滤不兼容的消息。
要将帧解码为MAVLink消息,您需要使用特定的方言。标准MAVLink方言可在mavio::dialects
下找到,并且可以通过相应的功能标志启用
minimal
— 这是暴露您的存在给其他MAVLink设备所需的最小方言。standard
— 是minimal
方言的超集,几乎所有飞行栈都期望使用。common
— 最小可行方言,具有大多数功能,是其他未来丰富方言的基石。ardupilotmega
— 功能齐全的方言,由 ArduPilot 使用。在大多数情况下,如果您想识别现有飞行栈中使用的几乎所有 MAVLink 消息,则此方言通常是首选。all
— 包含所有其他标准方言(包括为测试目的而创建的方言)的元方言。保证all
家族方言的命名空间不会冲突。- MAVLink XML 定义 中的其他方言:
asluav
、avssuas
、csairlink
、cubepilot
、development
、icarous
、matrixpilot
、paparazzi
、ualberta
、uavionix
。这些不包括python_array_test
和test
方言,这些应该手动生成或作为all
元方言的一部分。
自定义方言
方言的具体实现由 MAVSpec 生成,有关详细信息,请参阅其 文档。如果您想生成自定义方言,还可以查看 build.rs
。
示例
./examples/sync/examples
中有同步 I/O 的示例
tcp_server.rs
是一个简单的 TCP 服务器,等待连接,发送和接收心跳cargo run --package mavio_examples_sync --example tcp_server
tcp_client.rs
是一个 TCP 客户端,连接到服务器,发送和接收心跳cargo run --package mavio_examples_sync --example tcp_client
tcp_ping_pong.rs
服务器和客户端通过 TCP 通信cargo run --package mavio_examples_sync --example tcp_ping_pong
./examples/async/examples
中有异步 I/O 的示例
async_tcp_ping_pong.rs
服务器和客户端通过 TCP 通信cargo run --package mavio_examples_async --example async_tcp_ping_pong
有关使用过滤后的 MAVLink 实体的自定义方言生成的示例,请参阅 ./examples/custom/examples
custom_dialects_usage.rs
是自定义生成的方言的基本用法cargo run --package mavio_examples_custom --example mavio_examples_custom_usage
custom_message.rs
创建和使用自定义消息cargo run --package mavio_examples_custom --example custom_message
许可
我们简单遵循根据 Rust API 指南(C-PERMISSIVE)的建议双许可。
在以下任一项下许可:
- Apache许可证,版本2.0(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您选择。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的任何有意提交以包含在作品中的贡献,将按上述方式双许可,不附加任何额外条款或条件。
依赖项
~1–3.5MB
~65K SLoC