19 个版本
0.3.4 | 2024 年 8 月 9 日 |
---|---|
0.3.3 | 2024 年 3 月 25 日 |
0.2.2 | 2024 年 1 月 26 日 |
0.1.3 | 2024 年 1 月 10 日 |
0.1.2 | 2023 年 12 月 30 日 |
12 在 机器人 中排名 12
767 每月下载量
用于 2 crates
81KB
714 行
MAVSpec
MAVLink 的代码生成器。
MAVLink 是一种轻量级的开源协议,用于无人机、机载组件和地面控制站之间的通信。它被像 PX4 或 ArduPilot 这样的自动驾驶仪使用。MAVLink 具有简单紧凑的序列化模型。基本抽象是 message
,可以通过链路(UDP、TCP、UNIX 套接字、UART 等)发送,并反序列化为具有原始类型字段或原始类型数组结构的 struct。这些字段可以通过 enum
变体进一步限制,并标注元数据,如测量单位、默认值或无效值。存在几个 MAVLink 方言。官方方言定义是可以在 MAVlink 存储库 中找到的 XML 文件。基于 message
抽象,MAVLink 定义了所谓的 microservices
,这些微服务指定了客户端在特定条件下如何对特定消息做出响应,或者如何启动特定操作。
这个库是其他 MAVLink 相关工具(遥测收集器、IO 等)的构建块。它只负责代码生成。其他 Mavka 项目专注于自己的领域
- MAVInspect 负责解析 mavlink 消息 XML 定义。
MAVSpec
使用这个库来发现和解析 MAVLink 方言。 - Mavio 是一个用 Rust 编写的最小化 MAVLink 通信库,支持无标准(
no-std
)和内存分配(no-alloc
)目标,并专注于 MAVLink 协议的无状态部分。 - Maviola 是一个基于
Mavio
的 MAVLink 通信库,提供了 MAVLink 消息的高级接口,并处理协议的有状态功能:顺序、消息时间戳、自动心跳、简化消息签名等。
此项目遵守 semantic versioning
。
安装
作为 Cargo 依赖项安装。
cargo add mavspec --features specs
启用 specs
功能将启用所有核心接口,这些接口用于自动生成的代码。
由于您可能希望将代码生成作为构建序列的一部分,我们建议还添加 MAVSpec 作为构建依赖项。
cargo add --build mavspec --featurs generators
启用 generators
功能将启用所有代码生成器。
用法
以下解释了如何使用库 API,有关命令行工具的使用,请参阅 CLI 部分。
Rust
Rust 代码生成的 API 文档可以在 此处 找到。
将具有 rust
功能的 MAVSpec 添加到依赖项中。
cargo add mavspec --features rust
此功能启用您的生成代码将依赖的接口。您可以通过 use mavspec::rust::spec
访问这些接口。
可选地,如果您的目标支持,则启用 std
(Rust 标准库)或 alloc
(内存分配支持)功能(如果您不是为嵌入式设备开发,我们建议始终启用 std
)。
将具有 rust_gen
的 MAVSpec 添加为构建依赖项
cargo add --build mavspec --features rust_gen
如有必要,请将可选部分添加到您的 Cargo.toml
中,以生成特定的 MAVLink 实体
[package.metadata.mavspec]
microservices = ["HEARTBEAT", "MISSION"]
messages = ["PROTOCOL_VERSION", "MAV_INSPECT_V1", "PING"]
enums = ["STORAGE_STATUS", "GIMBAL_*"]
commands = ["MAV_CMD_DO_CHANGE_SPEED", "MAV_CMD_DO_SET_ROI*"]
generate_tests = false
这将在很大程度上减少编译时间,并且可能会略微减少内存占用(如果您不打算将自动生成的代码作为库API的一部分暴露,那么Rust编译器可能会优化掉所有未使用的部分)。
如果您想为生成的代码生成测试,请将generate_tests
设置为true
。此模式默认禁用。
更新您的build.rs
use std::env::var;
use std::path::Path;
use mavspec::rust::BuildHelper;
fn main() {
// Assume that your library and `message_definitions` are both in the root of your project.
let sources = vec![
"./message_definitions/standard",
"./message_definitions/extra",
];
// Output path
let destination = Path::new(&var("OUT_DIR").unwrap()).join("mavlink");
// Path to your `Cargo.toml` manifest
let manifest_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.toml");
// Parse XML definitions and generate Rust code
BuildHelper::builder(&destination)
.set_sources(&sources)
.set_manifest_path(&manifest_path)
.generate()
.unwrap();
}
OUT_DIR
环境变量由Rust构建工具链提供,指向您的crate的输出库。在构建脚本中写入此路径之外被认为是不良做法。
最后,将生成的代码导入到您的lib.rs
(或任何看起来合适的地方)
mod mavlink {
include!(concat!(env!("OUT_DIR"), "/mavlink/mod.rs"));
}
pub use mavlink::dialects;
检查examples/rust
,以获取一个更详细的示例,该示例使用Cargo功能作为MAVLink方言选择的标志。
Rust命名约定
在MAVSpec
中,我们试图在MAVLink XML定义中出现的名称和Rust命名约定之间保持平衡。在大多数情况下,我们倾向于使用Rust的方式,除非它会引起混淆。如果我们失败了,并且您感到困惑,所有实体都补充了描述,其中提到了规范MAVlink名称。以下是命名规则的列表
- 对于结构体和枚举,
MAVSpec
使用UpperCamelCase
。 - 对于消息字段,我们使用
snake_case
。 - 对于枚举条目(枚举条目),我们使用
UpperCamelCase
,并从MAVLink枚举名称前缀中删除(如果适用)。例如,如果位掩码枚举的名称为IMPORTANCE_LEVEL
,则标志名称为IMPORTANCE_LEVEL_THE_MATTER_OF_LIFE_AND_DEATH
,则标志名称将为TheMatterOfLifeAndDeath
。 - 对于位掩码标志(枚举的枚举条目,这些枚举是位掩码),我们使用
SCREAMING_SNAKE_CASE
,并从MAVLink枚举名称前缀中删除(如果适用)。例如,如果位掩码枚举的名称为VERY_IMPORTANT_FLAGS
,则标志名称为VERY_IMPORTANT_FLAGS_THE_MATTER_OF_LIFE_AND_DEATH_FLAG
,则标志名称将为THE_MATTER_OF_LIFE_AND_DEATH_FLAG
。 - 在与rust关键词冲突的情况下,我们添加下划线后缀。例如,
type
字段为HEARTBEAT
消息将被编码为type_
。 - 在罕见的情况下,当符号名称以数字字符开头时,它将被前缀
_
。
检查mavspec_examples_rust.rs
,该文件显示了如何处理不便的名称的最后两个情况(这并不是什么高审美价值的东西,但我们必须说,我们考虑过的所有方法看起来都同样难看)。
指纹
如果方言没有更改,MAVInspect可能会跳过代码重新生成。它使用64位CRC指纹来监控更改。将fingerprints
功能标志设置为启用此行为。
此功能对于在开发和CI运行期间减少构建时间非常有用。请确保您的发布版是干净的,并且不依赖于指纹。
不稳定功能
不稳定功能通过unstable
功能标志启用。这些功能是实验性的,并且可以在未来的版本中更改或删除。
CLI
安装mavspec
命令行工具。
cargo install mavspec --features cli
检查安装
mavspec -V
如果您正在从 MAVSpec
仓库中工作,那么您始终可以使用 cargo 运行 CLI 工具。
cargo run --bin mavspec --features cli --
从 ./message_definitions/standard
解析 XML 定义,并在 tmp/mavlink 目录中生成方言。
mavspec --src message_definitions/standard --out tmp/mavlink rust
打印 Rust 代码生成器的 mavspec
帮助信息。
mavspec rust -h
示例
examples/rust
— 一个包含自动生成代码的示例库。cargo run --package mavspec_examples_rust --bin mavspec_examples_rust
路线图
API 被认为是相对稳定的,但某些高级功能尚未开发。然而,这些功能大多数是可选的,而不是这个库完整性的必要条件。
里程碑 v1
包含了达到稳定版本 1.0.0
所需的功能。其中大部分功能与 Rust 代码生成器相关。
其他代码生成器(将构成其他 Mavka 项目的基石)
telemetry
里程碑专注于存储在时间序列数据库(如 InfluxDB 或 Timescale)中的 MAVLink 数据所需的代码生成器。gRPC
里程碑保留用于 Protobuf 和 gRPC 绑定。
欢迎提出 建议 和 pull-requests。
其他 MAVLink 工具
首先,值得提及的是官方的 Rust MAVLink 客户端:rust-mavlink
。编写这个库的原因之一是我希望将解析器和代码生成器解耦为单独的项目。
我受到了 gomavlib
库(用于 MAVLink 的 Go 语言)的启发。我喜欢它的编写方式,其源代码在官方 MAVLink 文档不够清晰时帮助了我多次。
如果您想自动生成语言绑定并偏好 Python,可能会对官方的 mavgen
代码生成工具感兴趣。如果您在寻找 MAVLink 消息的路由器,我们建议使用 mavp2p
。如果您需要一个支持 MAVLink 微服务的解决方案,那么检查使用 gRPC API 的 MAVSDK
值得考虑。
MAVLink 几乎有 15 年的历史,但围绕这个协议的生态系统仍然动态发展。一些项目稳定且健壮,而其他项目功能丰富但尚不完整。
许可
我们简单遵循根据 Rust API 指南(C-PERMISSIVE)建议的双重许可。
以下任一许可下使用:
- Apache License,版本 2.0(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
由您自行选择。
贡献
除非您明确声明,否则任何按照Apache-2.0许可证定义提交的、旨在包含在作品中的贡献,都将按照上述方式双授权,无需附加任何条款或条件。
依赖项
~0–1.5MB
~25K SLoC