MAVLink 中文版
AI+手工+机翻的勉强看吧,有问题联系我更新
MAVLink 2 数据包格式
| Byte Index | C version | Content | Value | Explanation |
|---|---|---|---|---|
| 0 | uint8_t magic | 数据包起始标记 | 0xFD | 协议特定的文本开始 (STX) 标记,用于指示新数据包的开始。任何不理解协议版本的系统都会跳过该数据包。 |
| 1 | uint8_t len | Payload length | 0 - 255 | 指示以下 payload 部分的长度。这可能会受到 payload truncation. |
| 2 | uint8_t incompat_flags | Incompatibility Flags | 为了实现 MAVLink 兼容性必须理解的标志(如果实现不理解标志,则会丢弃数据包)。 | |
| 3 | uint8_t compat_flags | Compatibility Flags | 0x01 | 为了实现 MAVLink 兼容性必须理解的标志(如果实现不理解标志,则会丢弃数据包)。 |
| 4 | uint8_t seq | Packet sequence number | 0 - 255 | 用于检测数据包丢失。组件为发送的每条消息增加值。 |
| 5 | uint8_t sysid | System ID (sender) | 1 - 255 | 发送消息的 system (飞机) 的 ID。 用于区分网络上的系统 |
| 6 | uint8_t compid | Component ID (sender) | 1 - 255 | 发送消息的组件的 ID。用于区分系统中的组件(例如自动驾驶仪和摄像头)。在 MAV_COMPONENT 中使用适当的值。请注意,广播地址“MAV_COMP_ID_ALL”不能在此字段中使用,因为它是无效的源地址。 |
| 7 to 9 | uint32_t msgid:24 | Message ID (low, middle, high bytes) | 0 - 16777215 | 有效负载中的 消息类型 的 ID。用于将数据解码回消息对象。 |
For n-byte payload: n=0: NA, n=1: 10, n>=2: 10 to (9+n) | uint8_t payload[max 255] | Payload | 消息数据。取决于消息类型(即消息 ID)和内容。 | |
| (n+10) to (n+11) | uint16_t checksum | Checksum (low byte, high byte) | 消息的 CRC-16/MCRF4XX(不包括“magic”字节)。包括 CRC_EXTRA 字节。 | |
| (n+12) to (n+25) | uint8_t signature[13] | Signature | (可选)签名以确保链接不可篡改。 |
CRC
Python
def message_checksum(msg):
'''calculate a 8-bit checksum of the key fields of a message, so we
can detect incompatible XML changes'''
from .mavcrc import x25crc
crc = x25crc()
crc.accumulate_str(msg.name + ' ')
# in order to allow for extensions the crc does not include
# any field extensions
crc_end = msg.base_fields()
for i in range(crc_end):
f = msg.ordered_fields[i]
crc.accumulate_str(f.type + ' ')
crc.accumulate_str(f.name + ' ')
if f.array_length:
crc.accumulate([f.array_length])
return (crc.crc&0xFF) ^ (crc.crc>>8)
Rust-AI
use std::vec::Vec;
// Define a struct for Field
struct Field {
type_: String,
name: String,
array_length: Option<u8>,
}
// Define a struct for Message
struct Message {
name: String,
ordered_fields: Vec<Field>,
}
impl Message {
fn base_fields(&self) -> usize {
self.ordered_fields.len()
}
}
// Define a struct for CRC with relevant methods
struct X25Crc {
crc: u16,
}
impl X25Crc {
fn new() -> X25Crc {
X25Crc { crc: 0xffff }
}
fn accumulate(&mut self, bytes: &[u8]) {
for &byte in bytes {
let tmp = byte ^ (self.crc as u8);
let tmp = (tmp ^ (tmp << 4)) as u16;
self.crc = (self.crc >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4);
}
}
fn accumulate_str(&mut self, string: &str) {
self.accumulate(string.as_bytes());
}
}
fn message_checksum(msg: &Message) -> u8 {
let mut crc = X25Crc::new();
crc.accumulate_str(&(msg.name.clone() + " "));
// in order to allow for extensions the crc does not include
// any field extensions
let crc_end = msg.base_fields();
for i in 0..crc_end {
let f = &msg.ordered_fields[i];
crc.accumulate_str(&(f.type_.clone() + " "));
crc.accumulate_str(&(f.name.clone() + " "));
if let Some(length) = f.array_length {
crc.accumulate(&[length]);
}
}
(crc.crc & 0xFF) as u8 ^ (crc.crc >> 8) as u8
}
fn main() {
// Example usage
let fields = vec![
Field { type_: "int".to_string(), name: "field1".to_string(), array_length: None },
Field { type_: "float".to_string(), name: "field2".to_string(), array_length: Some(5) }
];
let msg = Message { name: "example".to_string(), ordered_fields: fields };
let checksum = message_checksum(&msg);
println!("Checksum: {}", checksum);
}