MAVLink源文件结构

MAVLink是为微型飞行器MAV(Micro Air Vehicle)设计的(LGPL)开源的通讯协议。是无人飞行器和地面站(Ground Control Station ,GCS)之间,以及无人飞行器之间通讯常用的协议。APM、PIXHAWK飞控,Mission Planner、QGroundControl地面站均使用了MAVLink协议进行通讯。

  • common文件夹:原始的MAVLink消息,包括各种消息的头文件

    • common.h :定义MAVLink各个消息包中用到的枚举类型,各个消息包对应的CRC-EXTRA值、LENGTH值,包含(include)各个消息包的头文件
    • 各个消息的头文件:
      • 1)定义消息内容对应的数据结构
      • 2)打包、发送消息的便捷函数
      • 3)消息包解析并获取各个参数
  • autopilotmega,ASLUAV,pixhawk等文件夹:包含各个飞控自定义的MAVLink消息类型
  • checksum.h:计算校验码的代码
  • mavlink_conversions.h:dcm,欧拉角,四元数之间的转换
  • mavlink_helper.h:提供各种便捷函数:
    • 将各个消息包补充完整并发送。将数据载荷加上消息帧的头部,如sysid和compid等,计算校验码,补充成为完整的mavlink消息包后发送;
    • MAVLink消息包解析。
  • mavlink_types.h:定义用到的各种基本结构体(如mavlink_message_t)、枚举类型(如
    mavlink_param_union_t)

mavlink消息包



 注: 校验(checksum)功能。加入MAVLINK_CRC_EXTRA,当两个通讯终端之间(飞行器和地面站,或飞行器和飞行器)使用不同版本的MAVLink协议时,双方计算得到的校验码会不同,则不同版本的MAVLink协议之间将无法通讯。

  • MAVLINK_MESSAGE_CRCS中存储了每种消息包对应的MAVLINK_CRC_EXTRA。
  • 这个MAVLINK_CRC_EXTRA在用python生成MAVLink代码时在common.h头文件中自动生成。

mavlink解析函数

MAVLINK_HELPER uint8_t mavlink_frame_char_buffer(mavlink_message_t* rxmsg, mavlink_status_t* status,uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
{/* Enable this option to check the length of each message.This allows invalid messages to be caught much sooner. Use if the transmissionmedium is prone to missing (or extra) characters (e.g. a radio that fades inand out). Only use if the channel will only contain messages types listed inthe headers.*/
#ifdef MAVLINK_CHECK_MESSAGE_LENGTH
#ifndef MAVLINK_MESSAGE_LENGTHstatic const uint8_t mavlink_message_lengths[256] = MAVLINK_MESSAGE_LENGTHS;
#define MAVLINK_MESSAGE_LENGTH(msgid) mavlink_message_lengths[msgid]
#endif
#endifint bufferIndex = 0;status->msg_received = MAVLINK_FRAMING_INCOMPLETE;switch (status->parse_state){case MAVLINK_PARSE_STATE_UNINIT:case MAVLINK_PARSE_STATE_IDLE:if (c == MAVLINK_STX){status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;rxmsg->len = 0;rxmsg->magic = c;status->flags &= ~MAVLINK_STATUS_FLAG_IN_MAVLINK1;mavlink_start_checksum(rxmsg);} else if (c == MAVLINK_STX_MAVLINK1){status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;rxmsg->len = 0;rxmsg->magic = c;status->flags |= MAVLINK_STATUS_FLAG_IN_MAVLINK1;mavlink_start_checksum(rxmsg);}break;case MAVLINK_PARSE_STATE_GOT_STX:if (status->msg_received
/* Support shorter buffers than thedefault maximum packet size */
#if (MAVLINK_MAX_PAYLOAD_LEN < 255)|| c > MAVLINK_MAX_PAYLOAD_LEN
#endif){status->buffer_overrun++;_mav_parse_error(status);status->msg_received = 0;status->parse_state = MAVLINK_PARSE_STATE_IDLE;}else{// NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2rxmsg->len = c;status->packet_idx = 0;mavlink_update_checksum(rxmsg, c);if (status->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1) {rxmsg->incompat_flags = 0;rxmsg->compat_flags = 0;status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPAT_FLAGS;} else {status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;}}break;case MAVLINK_PARSE_STATE_GOT_LENGTH:rxmsg->incompat_flags = c;if ((rxmsg->incompat_flags & ~MAVLINK_IFLAG_MASK) != 0) {// message includes an incompatible feature flag_mav_parse_error(status);status->msg_received = 0;status->parse_state = MAVLINK_PARSE_STATE_IDLE;break;}mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_INCOMPAT_FLAGS;break;case MAVLINK_PARSE_STATE_GOT_INCOMPAT_FLAGS:rxmsg->compat_flags = c;mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPAT_FLAGS;break;case MAVLINK_PARSE_STATE_GOT_COMPAT_FLAGS:rxmsg->seq = c;mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;break;case MAVLINK_PARSE_STATE_GOT_SEQ:rxmsg->sysid = c;mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;break;case MAVLINK_PARSE_STATE_GOT_SYSID:rxmsg->compid = c;mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;break;case MAVLINK_PARSE_STATE_GOT_COMPID:rxmsg->msgid = c;mavlink_update_checksum(rxmsg, c);if (status->flags & MAVLINK_STATUS_FLAG_IN_MAVLINK1) {if(rxmsg->len > 0){status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID3;} else {status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;}
#ifdef MAVLINK_CHECK_MESSAGE_LENGTHif (rxmsg->len != MAVLINK_MESSAGE_LENGTH(rxmsg->msgid)){_mav_parse_error(status);status->parse_state = MAVLINK_PARSE_STATE_IDLE;break;}
#endif} else {status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID1;}break;case MAVLINK_PARSE_STATE_GOT_MSGID1:rxmsg->msgid |= c<<8;mavlink_update_checksum(rxmsg, c);status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID2;break;case MAVLINK_PARSE_STATE_GOT_MSGID2:rxmsg->msgid |= ((uint32_t)c)<<16;mavlink_update_checksum(rxmsg, c);if(rxmsg->len > 0){status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID3;} else {status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;}
#ifdef MAVLINK_CHECK_MESSAGE_LENGTHif (rxmsg->len != MAVLINK_MESSAGE_LENGTH(rxmsg->msgid)){_mav_parse_error(status);status->parse_state = MAVLINK_PARSE_STATE_IDLE;break;}
#endifbreak;case MAVLINK_PARSE_STATE_GOT_MSGID3:_MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx++] = (char)c;mavlink_update_checksum(rxmsg, c);if (status->packet_idx == rxmsg->len){status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;}break;case MAVLINK_PARSE_STATE_GOT_PAYLOAD: {const mavlink_msg_entry_t *e = mavlink_get_msg_entry(rxmsg->msgid);uint8_t crc_extra = e?e->crc_extra:0;mavlink_update_checksum(rxmsg, crc_extra);if (c != (rxmsg->checksum & 0xFF)) {status->parse_state = MAVLINK_PARSE_STATE_GOT_BAD_CRC1;} else {status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;}rxmsg->ck[0] = c;// zero-fill the packet to cope with short incoming packetsif (e && status->packet_idx < e->max_msg_len) {memset(&_MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx], 0, e->max_msg_len - status->packet_idx);}break;}case MAVLINK_PARSE_STATE_GOT_CRC1:case MAVLINK_PARSE_STATE_GOT_BAD_CRC1:if (status->parse_state == MAVLINK_PARSE_STATE_GOT_BAD_CRC1 || c != (rxmsg->checksum >> 8)) {// got a bad CRC messagestatus->msg_received = MAVLINK_FRAMING_BAD_CRC;} else {// Successfully got messagestatus->msg_received = MAVLINK_FRAMING_OK;}rxmsg->ck[1] = c;if (rxmsg->incompat_flags & MAVLINK_IFLAG_SIGNED) {status->parse_state = MAVLINK_PARSE_STATE_SIGNATURE_WAIT;status->signature_wait = MAVLINK_SIGNATURE_BLOCK_LEN;// If the CRC is already wrong, don't overwrite msg_received,// otherwise we can end up with garbage flagged as valid.if (status->msg_received != MAVLINK_FRAMING_BAD_CRC) {status->msg_received = MAVLINK_FRAMING_INCOMPLETE;}} else {if (status->signing &&(status->signing->accept_unsigned_callback == NULL ||!status->signing->accept_unsigned_callback(status, rxmsg->msgid))) {// If the CRC is already wrong, don't overwrite msg_received.if (status->msg_received != MAVLINK_FRAMING_BAD_CRC) {status->msg_received = MAVLINK_FRAMING_BAD_SIGNATURE;}}status->parse_state = MAVLINK_PARSE_STATE_IDLE;if (r_message != NULL) {memcpy(r_message, rxmsg, sizeof(mavlink_message_t));}}break;case MAVLINK_PARSE_STATE_SIGNATURE_WAIT:rxmsg->signature[MAVLINK_SIGNATURE_BLOCK_LEN-status->signature_wait] = c;status->signature_wait--;if (status->signature_wait == 0) {// we have the whole signature, check it is OKbool sig_ok = mavlink_signature_check(status->signing, status->signing_streams, rxmsg);if (!sig_ok &&(status->signing->accept_unsigned_callback &&status->signing->accept_unsigned_callback(status, rxmsg->msgid))) {// accepted via application level overridesig_ok = true;}if (sig_ok) {status->msg_received = MAVLINK_FRAMING_OK;} else {status->msg_received = MAVLINK_FRAMING_BAD_SIGNATURE;}status->parse_state = MAVLINK_PARSE_STATE_IDLE;if (r_message !=NULL) {memcpy(r_message, rxmsg, sizeof(mavlink_message_t));}}break;}bufferIndex++;// If a message has been sucessfully decoded, check indexif (status->msg_received == MAVLINK_FRAMING_OK){//while(status->current_seq != rxmsg->seq)//{//    status->packet_rx_drop_count++;//               status->current_seq++;//}status->current_rx_seq = rxmsg->seq;// Initial condition: If no packet has been received so far, drop count is undefinedif (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;// Count this packet as receivedstatus->packet_rx_success_count++;}if (r_message != NULL) {r_message->len = rxmsg->len; // Provide visibility on how far we are into current msg}if (r_mavlink_status != NULL) {    r_mavlink_status->parse_state = status->parse_state;r_mavlink_status->packet_idx = status->packet_idx;r_mavlink_status->current_rx_seq = status->current_rx_seq+1;r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;r_mavlink_status->packet_rx_drop_count = status->parse_error;r_mavlink_status->flags = status->flags;}status->parse_error = 0;if (status->msg_received == MAVLINK_FRAMING_BAD_CRC) {/*the CRC came out wrong. We now need to overwrite themsg CRC with the one on the wire so that if thecaller decides to forward the message anyway thatmavlink_msg_to_send_buffer() won't overwrite thechecksum*/if (r_message != NULL) {r_message->checksum = rxmsg->ck[0] | (rxmsg->ck[1]<<8);}}return status->msg_received;
}

此函数首先找到消息标志位 0xFE,然后逐字节的遍历,放入对应的mavlink_message_t结构体中,同时进行CRC检查。mavlink_status_t结构体是检测mavlink_message_t消息的结构体,存储消息的状态。

mavlink接收消息——统一赋值到mavlink_message_t结构体中——然后通过encode代码函数将各个变量成员提取——将变量成员赋值给mavlink_message_t结构体——通过读取真正的消息长度,将消息转换成buffer——mavlink发送消息

mavlink协议关键文件位:

参考博客:https://www.cnblogs.com/warrior1988/p/7729997.html

MAVLink--结构相关推荐

  1. 无人机、无人船通信协议——MAVLink(V1.0、V2.0,心跳包,GPS定位,7种飞行模式)

    目录 1.什么是MAVLink 2.MAVLink的优势 3.MAVLink信息结构 3.1.MAVLink V1.0 3.2.MAVLink V2.0 4.心跳包(HEARTBEAT MESSAGE ...

  2. PX4读取串口消息,并通过MAVLINK发送给地面站

    参考:(131条消息) PX4飞控读取UART串口信息通过Mavlink传给QGC地面站显示_XXX_UUU_XXX的博客-CSDN博客_px4串口2 PX4版本:1.12.1-3 QGC版本: 4. ...

  3. QGC地面站二次开发(三)Qt 简洁地面站

    目录 多机控制原理 多机控制实现 简洁地面站优化 1. 飞机的飞行轨迹以不同的颜色区分 2. 控制所有的飞机 3. 将设定航线送给特定的飞机 多机控制原理 多机地面站支持 TCP. UDP 和串口等三 ...

  4. Pixhawk飞控源码目录结构及编译流程分析

     http://blog.csdn.net/xlb7679/article/details/51658956 (PS:这是第一次写博客,以前也有记录一些经验总结心得什么的,不过都是手写笔记或者记在 ...

  5. 转载:Pixhawk源码笔记一:APM代码基本结构

    转自 新浪微博@WalkAnt 基础知识 详细参考:http://dev.ardupilot.com/wiki/learning-the-ardupilot-codebase/ 第一部分:介绍 详细参 ...

  6. MAVLink 协议解析之XML定义篇

    文章目录 1 MAVLink XML 文件的基本结构 2 message 3 enum 1 MAVLink XML 文件的基本结构 下面的代码块是 mavlink 消息定义的 xml 数据文档 代码块 ...

  7. 6005.boost多线程与mavlink协议结合实现消息收发

    boost多线程与mavlink协议结合实现消息收发 本文将实现boost库创建多线程,利用mavlink协议进行数据链消息打包.解包,解放了很多数据解析的工作,不得不佩服mavlink协议功能的强大 ...

  8. 6003.mavlink协议自定义消息编程

    mavlink 自定义消息编程 紧接着上一篇的操作方法,根据自定义的xml生成基于mavlink协议形式的消息.将其添加到工程中,并且调用起来的示例demo代码如下: 将生成自定义消息目录拷贝到工程下 ...

  9. Mavlink 协议硬解析主要代码

    2013-08-16 11:26 1744人阅读 评论(1) 收藏 举报 [cpp] view plaincopy int MAVLinkProtocol::ParseMsg(BYTE arMsgBu ...

  10. Mavlink协议概要

    转:http://blog.csdn.net/luckpl/article/details/52608868#mavlink协议简介 Mavlink协议简介 Mavlink协议简介 一Mavlink协 ...

最新文章

  1. Python之旅.第九章.并发编程..
  2. 远程办公在美国有多受欢迎?有人宁愿降薪 50% 也不愿再回办公室
  3. 消息云服务器,对方启用云消息服务器
  4. mac osx linux,Linux 、Mac OSX 常见问题 及 笔记
  5. 多线程线程池的基本创建,使用方法
  6. eclipse常用窗口和功能总结
  7. java excel导出 模板_Java Excel 导出 模板
  8. paip.找回密码功能流程设计(通过email)
  9. 一文了解Clickhouse
  10. 【iOS开发】页面卡顿监控和优化
  11. 苹果电池显示维修_安装第三方电池的iPhone也可享受苹果官方维修
  12. 使用OpenSSL生成/签发证书的原理、流程与示例
  13. 解决xp共享的批处理文件
  14. IT大学生成长周报 | 第 5 期
  15. 【免费】捷微微信管家公众号运营培训开课啦!
  16. 英文XP如何正常显示中文
  17. icloud安装错误怎么办_给你细说win7系统icloud win7安装失败的修复办法
  18. 分析:人名搜索Spock会成下个谷歌吗
  19. html模块 码工助手,码工助手
  20. 如何判断一棵树是不是另一棵树的子树

热门文章

  1. 阿里的新游戏—计蒜客A1183
  2. 2017 计蒜之道 初赛 第一场 A题B题
  3. 304 Not Modified详解
  4. ie304报错解决方案
  5. JavaWeb - Servlet实现文件下载漂亮小姐姐视频(文末有小姐姐视频Gif图哦)
  6. 基于ik分词器和布隆过滤器实现敏感词过滤
  7. python计算灰色关联度
  8. 陈丹琦团队提出低内存高效零阶优化器MeZO,单卡A100可训练300亿参数模型
  9. 初学者需要了解Linux这么多
  10. spring + mybatis + c3p0 整合(配置篇)