mavlink的数据封装的结构体以及封装解析的函数都在mavlink代码库中的头文件中。
主要的结构体:E:\mavlink\mavlink\include\v1.0\mavlink_types.h
MAVPACKED(
typedef struct __mavlink_message {
uint16_t checksum; ///< sent at end of packet
uint8_t magic; ///< protocol magic marker
uint8_t len; ///< Length of payload
uint8_t seq; ///< Sequence of packet
uint8_t sysid; ///< ID of message sender system/aircraft
uint8_t compid; ///< ID of the message sender component
uint8_t msgid; ///< ID of message in payload
uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
}) mavlink_message_t;
mavlink数据的解析流程:
linux平台从串口接收到mavlink数据,解析出mavlink数据,根据msg_id区分不同的mavlink消息。
s_ret = read(uart_fd, mavlink_data, BUFFER_SIZE);//从串口接收飞控发送的mavlink数据
for (i = 0; i < s_ret; i++)
{
if (mavlink_parse_char(1, mavlink_data[i], &mavlMsg, &_status))//解析出完整的一帧mavlink数据
{
handle_message(&mavlMsg);//根据msgid,区分不同的mavlink
}
}
mavlink_parse_char:E:\mavlink\mavlink\include\v1.0\mavlink_helpers.h
MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
{
uint8_t msg_received = mavlink_frame_char(chan, c, r_message, r_mavlink_status);
if (msg_received == MAVLINK_FRAMING_BAD_CRC) {
// we got a bad CRC. Treat as a parse failure
mavlink_message_t* rxmsg = mavlink_get_channel_buffer(chan);
mavlink_status_t* status = mavlink_get_channel_status(chan);
status->parse_error++;
status->msg_received = MAVLINK_FRAMING_INCOMPLETE;
status->parse_state = MAVLINK_PARSE_STATE_IDLE;
if (c == MAVLINK_STX)
{
status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
rxmsg->len = 0;
mavlink_start_checksum(rxmsg);
}
return 0;
}
return msg_received;
}
例如接收飞控发送的心跳包:使用E:\mavlink\mavlink\include\v1.0\mavlink_msg_heartbeat.h中的函数 1532 u8RecvFcUavId = mavlink_msg_heartbeat_get_autopilot(msg);//解析出无人机的id号
gu8RecvFcFirmwareVersion = mavlink_msg_heartbeat_get_mavlink_version(msg);//解析出无人机的固件版本好
也可以调用mavlink_msg_heartbeat_decode函数,先将mavlink消息解码为本地的数据结构,然后直接调用结构体中的成员即可。
mavlink_msg_heartbeat_decode(msg,&heartbeat);
同理如果想发送mavlink心跳数据帧,直接使用E:\mavlink\mavlink\include\v1.0\mavlink_msg_heartbeat.h中的函数接口,进行mavlink数据帧的编码和发送操作。
下面是工作中遇到的具体的mavlink数据包:
fe 24 10 1 1 20 63 2a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b2 72 8b bf c3 77
【0】fe:起始标志
【1】24:63 2a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b2 72 8b bf 这一串总的字节长度n,负载长度
【2】10:消息的序列号
【3】1:系统ID号
【4】1:component id
【5】20:消息id
【6--n】:具体消息的信息,负载id
【n】【n+1】:前面n+6个字节信息的crc校验。这里就是 fe 24 10 1 1 20 63 2a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 b2 72 8b bf
理论基础学习参考:
http://www.cnblogs.com/warrior1988/p/7729997.html
https://blog.csdn.net/gongyuhonglou/article/details/72817763
https://zhuanlan.zhihu.com/p/57693160