Mavlink-1-概述介绍

2023-05-16

1. MAVLink简介

MAVLink(Micro Air Vehicle Link,微型空中飞行器链路通讯协议)是无人飞行器与地面站(Ground Control Station ,GCS)之间通讯,以及无人飞行器之间通讯最常用的协议。它已经在PX4、APM、PIXHAWK和Parrot AR.Drone飞控平台上进行了大量测试。

2.发明者Lorenz Meier简介

MAVLink的最初开发于2009年,由Lorenz Meier完成。Lorenz Meier的LinkedIn主页是:https://www.linkedin.com/in/meierlorenz,个人主页是:https://www.inf.ethz.ch/personal/lomeier/。 
根据官网和个人主页,Lorenz Meie的个人经历如下: 
 2004年~2008年在德国康斯坦茨大学(Universität Konstanz)就读信息工程专业; 

 2008 年~2011年在苏黎世联邦理工学院(德语:Eidgenössische Technische Hochschule Zürich,简称 ETH Zürich或ETHZ)就读视觉计算方向研究生; 

 2011~至今在ETHZ攻读博士后,研究方向是:Research on Drones and mobile phones focused on obstacle mapping, path planning and control. 
 2011年到现在,Lorenz Meier一直是开源无人机项目Autopilot的建立者和维护者。关于Autopilot,我会另辟章节介绍。 
从介绍来看,Lorenz Meier的研究方向包括了无人机避障、基于智能手机或无人机的3D重建、无人机通讯协议等有趣又前言的内容。 
这个页面是Lorenz Meier发表的几篇文章:https://www.researchgate.net/profile/Lorenz_Meier3

3. MAVLink相关资料

维基百科:https://en.wikipedia.org/wiki/MAVLink 
MavLink官方网站:http://qgroundcontrol.org/mavlink/start 
Python写的用于生成C、Java等语言的MavLink生成器软件:https://github.com/mavlink/mavlink

4.协议构成

下面内容引自官网。 
这里写图片描述

• The checksum is the same as used in ITU X.25 and SAE AS-4 standards (CRC-16-CCITT), documented in SAE AS5669A. Please see the MAVLink source code for a documented C-implementation of it. LINK TO CHECKSUM 
• The minimum packet length is 8 bytes for acknowledgement packets without payload 
• The maximum packet length is 263 bytes for full payload

MavLink的长度是固定的,即 17byte= 6 bytes header + 9 bytes payload + 2 bytes checksum。

5.封包过程

由用户生成的部分包括PlayLoad本身、消息包的STX、COMP、MSG,其他部分自动生成。

这里写图片描述

6.3DR Service实现MavLink协议

3DR Service是Autopilot提供的Android端的app服务,用于做SDK,提供与无人机通讯,以AIDL的方式为上层的App提供服务。基于3DRService,开发者可以不用处理复杂的MavLink通讯,只根据AIDL接口调用服务即可。 
这里下载了3DRService用于分析,地址为:https://github.com/ne0fhyk/3DRServices。3DRService将MavLink的协议部分作为单独的包,即项目中的dependencyLibs文件夹。

6.1. UML图

绘制dependencyLibs的UML图。该包主要提供了MavLink的所有类型的封包类和解析类。 
这里写图片描述

例如,对于MAVLinkPacket类,其核心部分为封包过程。

    /**
    * Encode this packet for transmission.
    *
    * @return Array with bytes to be transmitted
    */
    public byte[] encodePacket() {
        byte[] buffer = new byte[6 + len + 2];

        int i = 0;
        buffer[i++] = (byte) MAVLINK_STX;
        buffer[i++] = (byte) len;
        buffer[i++] = (byte) seq;
        buffer[i++] = (byte) sysid;
        buffer[i++] = (byte) compid;
        buffer[i++] = (byte) msgid;

        final int payloadSize = payload.size();
        for (int j = 0; j < payloadSize; j++) {
            buffer[i++] = payload.payload.get(j);
        }

        generateCRC();
        buffer[i++] = (byte) (crc.getLSB());
        buffer[i++] = (byte) (crc.getMSB());
        return buffer;
    }

解包的核心部分在Parser类中:

    /**
     * This is a convenience function which handles the complete MAVLink
     * parsing. the function will parse one byte at a time and return the
     * complete packet once it could be successfully decoded. Checksum and other
     * failures will be silently ignored.
     * 
     * @param c
     *            The char to parse
     */
    public MAVLinkPacket mavlink_parse_char(int c) {
        msg_received = false;

        switch (state) {
        case MAVLINK_PARSE_STATE_UNINIT:
        case MAVLINK_PARSE_STATE_IDLE:

            if (c == MAVLinkPacket.MAVLINK_STX) {
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
            }
            break;

        case MAVLINK_PARSE_STATE_GOT_STX:
            if (msg_received) {
                msg_received = false;
                state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
            } else {
                m = new MAVLinkPacket(c);
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_LENGTH;
            }
            break;

        case MAVLINK_PARSE_STATE_GOT_LENGTH:
            m.seq = c;
            state = MAV_states.MAVLINK_PARSE_STATE_GOT_SEQ;
            break;

        case MAVLINK_PARSE_STATE_GOT_SEQ:
            m.sysid = c;
            state = MAV_states.MAVLINK_PARSE_STATE_GOT_SYSID;
            break;

        case MAVLINK_PARSE_STATE_GOT_SYSID:
            m.compid = c;
            state = MAV_states.MAVLINK_PARSE_STATE_GOT_COMPID;
            break;

        case MAVLINK_PARSE_STATE_GOT_COMPID:
            m.msgid = c;
            if (m.len == 0) {
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_PAYLOAD;
            } else {
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_MSGID;
            }
            break;

        case MAVLINK_PARSE_STATE_GOT_MSGID:
            m.payload.add((byte) c);
            if (m.payloadIsFilled()) {
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_PAYLOAD;
            }
            break;

        case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
            m.generateCRC();
            // Check first checksum byte
            if (c != m.crc.getLSB()) {
                msg_received = false;
                state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
                if (c == MAVLinkPacket.MAVLINK_STX) {
                    state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
                    m.crc.start_checksum();
                }
                stats.crcError();
            } else {
                state = MAV_states.MAVLINK_PARSE_STATE_GOT_CRC1;
            }
            break;

        case MAVLINK_PARSE_STATE_GOT_CRC1:
            // Check second checksum byte
            if (c != m.crc.getMSB()) {
                msg_received = false;
                state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
                if (c == MAVLinkPacket.MAVLINK_STX) {
                    state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
                    m.crc.start_checksum();
                }
                stats.crcError();
            } else { // Successfully received the message
                stats.newPacket(m);
                msg_received = true;
                state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
            }

            break;

        }
        if (msg_received) {
            return m;
        } else {
            return null;
        }
}

`



 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108

这个类的使用是逐个直接解析,解析完毕后返回完整的包,例如,对字节数组packet,解析过程如下:

for(int i = 0; i < packet.length - 1; i++){
    parser.mavlink_parse_char(packet[i] & 0xFF);//每次解析1位
}
MAVLinkPacket m = parser.mavlink_parse_char(packet[packet.length - 1] & 0xFF);//最后1位即可返回

6.2 MavLink包测试

dependencyLibs提供了测试实例。以msg_altitude为例,判断生成的包和解析的包是否相同,即可判断该类是否正确。

/**
* The current system altitude.
*/
public class msg_altitude_test{

public static final int MAVLINK_MSG_ID_ALTITUDE = 141;
public static final int MAVLINK_MSG_LENGTH = 24;
private static final long serialVersionUID = MAVLINK_MSG_ID_ALTITUDE;

private Parser parser = new Parser();//1位解析类

public CRC generateCRC(byte[] packet){
    CRC crc = new CRC();
    for (int i = 1; i < packet.length - 2; i++) {
        crc.update_checksum(packet[i] & 0xFF);
    }
    crc.finish_checksum(MAVLINK_MSG_ID_ALTITUDE);
    return crc;
}

public byte[] generateTestPacket(){
    ByteBuffer payload = ByteBuffer.allocate(6 + MAVLINK_MSG_LENGTH + 2);
    payload.put((byte)MAVLinkPacket.MAVLINK_STX); //stx
    payload.put((byte)MAVLINK_MSG_LENGTH); //len
    payload.put((byte)0); //seq
    payload.put((byte)255); //sysid
    payload.put((byte)190); //comp id
    payload.put((byte)MAVLINK_MSG_ID_ALTITUDE); //msg id
    payload.putFloat((float)17.0); //altitude_monotonic
    payload.putFloat((float)45.0); //altitude_amsl
    payload.putFloat((float)73.0); //altitude_local
    payload.putFloat((float)101.0); //altitude_relative
    payload.putFloat((float)129.0); //altitude_terrain
    payload.putFloat((float)157.0); //bottom_clearance

    CRC crc = generateCRC(payload.array());
    payload.put((byte)crc.getLSB());
    payload.put((byte)crc.getMSB());
    return payload.array();
}

@Test
public void test(){
    byte[] packet = generateTestPacket();
    for(int i = 0; i < packet.length - 1; i++){
        parser.mavlink_parse_char(packet[i] & 0xFF);//每次解析1位
    }
    MAVLinkPacket m = parser.mavlink_parse_char(packet[packet.length - 1] & 0xFF);//最后1位即可返回
    byte[] processedPacket = m.encodePacket();//解析
    assertArrayEquals("msg_altitude", processedPacket, packet);
}
}

参考

[1]http://mrsxm.mfzgi5lqnfwg65bomnxw2.erenta.ru/wp-content/uploads/sites/6/2015/05/MAVLINK_FOR_DUMMIESPart1_v.1.1.pdf 
[2]http://blog.csdn.net/u013983741/article/details/48053235

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mavlink-1-概述介绍 的相关文章

  • mavlink消息帧里最重要的两个东西,一个是msgid;一个是payload

    mavlink消息帧里最重要的两个东西 xff0c 一个是msgid xff1b 一个是payload 在这里也可以看出 https blog csdn net sinat 16643223 article details 10891315
  • putty串口打开没反应_树莓派3B使用mavlink串口连接PIXHAWK_V5

    树莓派3B使用mavlink串口连接PIXHAWK V5 参考网址 xff1a http ardupilot org dev docs raspberry pi via mavlink html https dev px4 io en ro
  • MyBatisPlus(一)概述介绍

    一 概述 需要的基础 xff1a 把MyBatis Spring SpringMVC学习了 为什么要学习它呢 xff1f MyBatisPlus 可以节省我们大量工作时间 xff0c 所有的CRUD 代码它都可以自动化完成 比如 xff1a
  • 新建Mavlink消息

    1 下载Mavlink生成器 1 1 Git clone 需要在翻墙的网络环境下下载 span class token function git span clone https github com mavlink mavlink git
  • QGC添加自定义组件和发送自定义MAVLINK消息

    QGC添加自定义组件和发送自定义MAVLINK消息 一 添加自定义组件1 1 在飞行界面添加组件1 2 实现组件事件1 3 在MOCK模拟链接中实现验证1 4 验证 二 自定义MAVLINK消息的一些预备知识三 QGC自定义MAVLINK消
  • ardupilot之mavlink消息--从飞控发出--单向

    飞控采用mavlink消息进行数据的传输 普遍说法是 xff0c 现有的mavlink消息几乎已经涵盖了所有你的能想象到的内容 xff0c 完全可以覆盖多处需求 无奈科研总是要定义一些新鲜玩意 xff0c 所以总是有无法完全满足需求 xff
  • pixhawk px4 添加自定义mavlink消息

    首先添加一个 uORB topic xff0c 然后添加一个 mavlink 解析程序 xff0c 这将会将一个输入的 mavlink 消息解析并传入 uORB topic 中 注 xff1a 本例程 xff0c nsh仍然看不到消息 xf
  • px4 mavlink消息自定义及其发送

    在px4源码中自定义消息 xff0c 并发送主要有以下三个大步骤 xff1a 一 自定义mavlink消息 1 在myMessage XML文件中自定义消息 xff08 注意消息ID不要与原有的重复 xff09 具体消息ID可参考这里 2
  • QGC通过网络连接飞控(树莓派+ROS桥接MavLink)

    1 为树莓派刷ubuntu 因为无界面的ubuntu在连接无线 设置自动登录等方面的设置比较复杂 我经过各种百度尝试后 均没有成功 所以我放弃了 转而又刷了ubuntu mate 带界面 然后连接了无线 设置了自动登录 静态IP 自此树莓派
  • 【飞控协议】MavLink介绍和编译

    MavLink是什么 xff1f MavLink xff08 Micro Air Vehicle Link xff0c 微型空中飞行器链路通讯协议 xff09 是在串口通讯基础上的一种更高层的开源通讯协议 xff0c 主要应用在无人飞行器与
  • PX4自定义Mavlink消息(一)px4发送

    用于项目需求 xff0c 需要在PX4和QGC新增自定义消息用于通信控制 xff0c 看了很多有关文章 xff0c 我就不明白 xff0c 为啥代码都是复制来复制去的 xff0c 大部分的文章连变量名的起的一样 一点帮助都没有 xff0c
  • MAVLink简介

    MAVLink简介 Mavlink协议最早由 苏黎世联邦理工学院 计算机视觉与几何实验组 的 Lorenz Meier于2009年发布 xff0c 并遵循LGPL开源协议 Mavlink协议是在串口通讯基础上的一种更高层的开源通讯协议 xf
  • MAVLINK 请求参数和接收参数

    if decodeState 61 61 1 之后是放在mavlink消息解析后面 请求返回参数配置列表 void MavDebug on pushButton 3 clicked mavlink message t msg mavlink
  • MAVLink v1.0详解——结构

    本文针对 MAVLink v1 0版本 xff0c 协议版本 xff1a 3 MAVLink是为微型飞行器MAV xff08 Micro Air Vehicle xff09 设计的 xff08 LGPL xff09 开源的通讯协议 是无人飞
  • 在ubuntu上安装mavlink-router

    版本说明 xff1a ubuntu 20 0 04 mavlink router 2 为了安装mavlink router 需要预先安装一些依赖库 xff1a autoconf libtool python future python3 f
  • 【2020-8-9】APM,PX4,GAZEBO,MAVLINK,MAVROS,ROS之间的关系以及科研设备选型

    0 概述 无人机自主飞行平台可以分为四个部分 xff1a 动力平台 xff0c 飞行控制器 xff0c 机载电脑和模拟平台 动力平台 xff1a 负责执行飞行任务 xff0c 包括螺旋桨 电机 机架等 xff0c 用于科研的一般都是F380
  • QGC二次开发---自定义MAVLink消息

    MAVLink库下载 下载网站https github com mavlink mavlink 可以通过git工具 xff0c 在存放文件夹下打开git工具 xff0c 输入命令 xff1a git clone https github c
  • ardupilot之添加mavlink消息

    本文是这篇文章的复现 xff1a http www sohu com a 213599378 175233 一 mavlink分析 Mavlink 的全称是Micro Air Vehicle link xff0c pixhawk把它作为与地
  • PX4模块设计之五:自定义MAVLink消息

    PX4模块设计之五 xff1a 自定义MAVLink消息 1 MAVLink Dialects1 1 PX4 Dialects1 2 Paprazzi Dialects1 3 MAVLink XML File Format 2 添加自定义M
  • PX4中自定义MAVLink消息(记录)

    简单记录一下这个过程 一 自定义uORB消息 这一步比较简单 xff0c 首先在msg 中新建ca trajectory msg文件 uint64 timestamp time since system start span class t

随机推荐

  • 物理地址和逻辑地址

    1 物理地址和逻辑地址 物理地址 xff1a 加载到内存地址寄存器中的地址 xff0c 内存单元的真正地址 在前端总线上传输的内存地址都是物理内存地址 xff0c 编号从0开始一直到可用物理内存的最高端 这些数字被北桥 Nortbridge
  • 树莓派无opencv时进行视频实时处理

    用树莓派 xff0c 想要进行图像处理 xff0c 但网上的很多教程都用opencv xff0c opencv在树莓派上安装很麻烦 xff0c 那怎样进行图像处理呢 xff1f 代码如下 xff1a from picamera array
  • make: warning: Clock skew detected. Your build may be incomplete.

    问题现象 xff1a make warning Clock skew detected Your build may be incomplete 问题分析 xff1a 根据报警提示 xff0c 应该问题出现时钟问题 问题原因 xff1a 当
  • 关于Java之IO流音乐拼接小项目

    需求 xff1a 做一个音乐串烧 分析 xff1a 1 有n个音乐 xff0c 找到高潮部分 xff0c 2 获取高潮部分的流对象 3 把这部分对象保存成一个mp3 4 把它们拼接起来 以下为源码供大家分享 xff1a 方法一 xff1a
  • pixhawk源码下载与编译

    今天和同学在一起讨论发现自己还在看的pixhawk源码的版本好低啊 xff0c 就下个最新的吧 想起有些人还不会下载源码 xff0c 以及用什么工具查看 源码的下载我用的是git shell工具下的 xff0c px4的github网址是h
  • pixhawk开发环境

    Windows 7 64bit 软件安装 首先 xff0c 需要安装一些软件 xff0c CMake 32位的Java jdk以及PX4 Toolchain Installer CMake的话笔者使用的是CMake 3 3 2 win32
  • Pixhawk-信息流浅解析

    根深方能叶茂 在等待的日子里 xff0c 刻苦读书 xff0c 谦卑做人 xff0c 养得深根 xff0c 日后才能枝叶茂盛 Better 根爷 之前我们已经谈到系统框架 xff0c 之前谈到了定制自己功能的两部 xff1a 添加模块和修改
  • Python跨进程共享数据/对象

    1 跨进程共享方式 在multiprocess库中 xff0c 跨进程对象共享有三种方式 xff1a xff08 1 xff09 第一种仅适用于原生机器类型 xff0c 即python ctypes当中的类型 xff0c 这种在mp库的文档
  • Pixhawk-姿态解算-互补滤波

    根深方能叶茂 在等待的日子里 xff0c 刻苦读书 xff0c 谦卑做人 xff0c 养得深根 xff0c 日后才能枝叶茂盛 Better 根爷 终于说到了正题 xff0c 姿态解算这一部分很重要 xff0c 主要的基础就是惯性导航和多传感
  • Pixhawk-姿态解算源码注释

    根深方能叶茂 在等待的日子里 xff0c 刻苦读书 xff0c 谦卑做人 xff0c 养得深根 xff0c 日后才能枝叶茂盛 Better 根爷 这一部分是我在看源码时 xff0c 自己注释的一点笔记 xff0c 现在直接贴上来 当然这其中
  • Pixhawk-串级pid介绍

    根深方能叶茂 在等待的日子里 xff0c 刻苦读书 xff0c 谦卑做人 xff0c 养得深根 xff0c 日后才能枝叶茂盛 Better 根爷 鉴于串级PID在pixhawk系统中的重要性 xff0c 无论是误差的补偿 xff0c 如姿态
  • pixhawk串口读取传感器数据

    1 Pixhawk板上串口说明 xff1a 测试 使用Pixhawk板上TELEM2接口的USART2 xff0c 对应的Nuttx UART设备文件尾 dev ttyS2 xff1a 2 读取数据测试 步骤 xff1a 在Firmware
  • Android调用系统自带的文件管理器进行文件选择

    这几天在做的项目网盘 上传时需要用到调用系统自带的文件管理器来选择文件 xff0c 后来就在考虑怎么调用 xff0c 网上也搜了很久 xff0c 没有很好的解决方法 xff0c 后来在一瞬间发现了一篇不错的文章 xff0c 借鉴了一下代码
  • Android下如何读取文件的内容

    唉 xff0c 尝试了好半天了 xff0c 才弄懂 xff0c 1 首先权限的问题 我们需要在根文件中添加权限 lt uses permission android name 61 34 android permission WRITE E
  • Mavlink地面站编写之二–Mission PLanner地面站构架分析之MAVLINK航点读写

    转载请注明出处 http www amovauto com 阿木社区 玩也要玩的专业 xff01 3DR这个地面站还是非常专业的 xff0c 最近研究MAVLINK通信协议 就来分析下Mission planner的构架 至于Msissio
  • Mavlink地面站编写之三–Mission PLanner地面站构架分析之MAVLINK航点写入

    转载注意出处 xff1a http www amovauto com p 61 601 more 601 阿木社区 玩也要玩的专业 xff01 我们知道了怎么利用mavlink读取航点 xff0c 那么如果我们要写入航点 xff0c 也是一
  • Mavlink地面站编写之四-Mission Planner中ProgressReporterDialogue和读串口线程serialreaderthread的分析

    转载请注明出处 http www amovauto com p 61 660 阿木社区 xff0c 玩也要玩的专业 QQ群 526221258 ProgressReporterDialogue 这个对话框很有意思 xff0c 在MP中连接阶
  • Mavlink地面站编写之八–MAVLINK消息自定义

    PIXHAWk MAVLINK消息自定义 对于PIXHAWK这个系统来讲 xff0c MAVLINK是个小型的数据通信协议 xff0c 负责地面站和飞控本身的数据交互和地面站向飞控发送数据指令 前面的文章已经讲过MAVLINK这个数据格式解
  • Python参数校验工具:validate.py

    一直都在找一个比较好用的参数校验工具包 xff08 Python xff09 xff0c 这次终于找到了就做个记录 包名 xff1a validate py 安装方式 xff1a xff08 pip已收入 当前最新版本是1 3 0 xff0
  • Mavlink-1-概述介绍

    1 MAVLink简介 MAVLink xff08 Micro Air Vehicle Link xff0c 微型空中飞行器链路通讯协议 xff09 是无人飞行器与地面站 xff08 Ground Control Station xff0c