找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 32316|回复: 5

MAVLink—最强大的微型飞行器通信协议

[复制链接]
发表于 2015-3-30 23:14:53 | 显示全部楼层 |阅读模式
本帖最后由 Bluesky 于 2015-4-28 13:15 编辑

MAVLink—MicroAir Vehicle Communication Protocol


1 简介MAVLink通讯协议是一个为微型飞行器设计的非常轻巧的、只由头文件构成的信息编组库。
它可以通过串口非常高效地封装C结构数据,并将这些数据包发送至地面控制站。该协议被PX4, PIXHAWK, APM和Parrot AR.Drone平台所广泛测试并在以上的项目中作为MCU/IMU间以及Linux进程和地面站链路通信间的主干通信协议。

MAVLink最初由LorenzMeier根据LGPL许可在2009年初发表。


1.1  综合教程(见附件1)1.2  MAVLink消息格式及MAVLink API标准文件(见附件2)1.3  协议内容

1)线上(On-the-wire)格式和CRC冗余校验——
2)MAVLink 1.1版兼容性和特点
3)MAVLink任务内容
(1)  路径点协议
(2)  参数协议
(3)  图像传输协议
(4)  控制接口
4)MAVLink数据类型及相关约定
5)常见MAVLink消息

1.4 MAVLink代码及生成器
“普通信息集”包含了非常广泛的常用信息并以C语言头文件储存。如果你想定义并使用自己的代码,可以使用MAVLink Generator(C/C++,python)或QGroundcontrol。

1.5 MAVLink生态系统
1) 使用MAVLink的自动驾系统
Ÿ  ArduPilotMega (mainprotocol)
Ÿ  pxIMU Autopilot (mainprotocol)
Ÿ  SLUGS Autopilot (mainprotocol)
Ÿ  FLEXIPILOT (optionalprotocol)
Ÿ  UAVDevBoard/Gentlenav/MatrixPilot (optionalprotocol)
Ÿ  SenseSoarAutopilot (main protocol)
Ÿ  SmartAPAutopilot (main protocol)
Ÿ  AutoQuad 6 AutoPilot (mainprotocol)
2) 使用MAVLink的软件包
Ÿ  ROS to MAVLink bridge: https://github.com/mavlink/mavlink-ros
Ÿ  MAVCONN Lightweight Aerial Middleware http://pixhawk.ethz.ch/software/middleware/start
Ÿ  MAVProxy (allows toconnect multiple UDP/serial links, including flightgear):
3) 使用MAVLink的项目
Ÿ   MatrixPilot UAVDevBoard http://code.google.com/p/gentlenav/
Ÿ   ETH Flying MachineArena http://www.idsc.ethz.ch/Research_DAndrea/FMA
Ÿ   ETH SenseSoarSolar Airplane Project http://www.sensesoar.ethz.ch/doku.php?id=news
Ÿ   ETH Skye BlimpProject http://www.projectskye.ch/
Ÿ   UC Santa CruzSLUGS http://slugsuav.soe.ucsc.edu/index.html
Ÿ   Sky-Drones - UAVFlight Control Systems http://www.sky-drones.com/
Ÿ   AutoQuad -Autonomous Multirotor Vehicle controller http://autoquad.org/

1.6 MAVLink 数据格式分解
以一个MAVLink数据包为例,下图为其数据包具体的结构剖析。该结构是受到CANSAE AS-4标准的启发构建的。
                              
  
字节顺序
  
  
内容
  
  
  
  
含义
  
  
0
  
  
数据包开始标志
  
  
v1.0: 0xFE  (v0.9: 0x55)
  
  
指示新的数据包即将开始
  
  
1
  
  
有效载荷长度
  
  
0 - 255
  
  
指示接下来的有效负载长度
  
  
2
  
  
数据包 序列号
  
  
0 - 255
  
  
每个传输部件都会对发送序列进行计数。该结构能够检测到数据包的丢失
  
  
3
  
  
系统ID
  
  
1 – 255
  
  
发送该包的系统ID。该结构能够区分在同一网络中不同的MAV
  
  
4
  
  
设备ID
  
  
0 – 255
  
  
发送该数据包的设备ID。该结构能够区分同一系统的不同发送设备。如:IMUAutoPilot
  
  
5
  
  
消息ID
  
  
0 - 255
  
  
消息ID。该ID定义了有效负载的“含义”以及负载应被如何正确的解码
  
  
6(n+6)
  
  
数据
  
  
(0 – 255)字节
  
  
消息数据。具体内容取决于消息ID
  
  
(n+7)(n+8)
  
  
校验位
  
(低字节和高字节)
  
  
ITU X.25/ SAE AS-4哈希校验,不包括数据包开始的标志,所以字节1 ..N+6注意:校验码同样包括MAVLINK_CRC_EXTRA(数值从消息字段开始计算,避免同一个数据包因版本而变量值不同因其的解码问题。
  
Ÿ 校验值使用的是与 ITU X.25 SAE AS-4相同的校验标准(CRC-16-CCITT,在文档SAE AS5669A中有叙述。
Ÿ 通信包的最小长度为不带任何有效负载的8字节大小。
Ÿ 通信包的最大长度为满载263字节。

1.7    协议支持的数据结构

MAVLink协议支持固定大小的整形数据类型、IEEE 754协议规定的单精度浮点型数据、以上数据构成的数组(如:char[10]),以及由协议自动添加的特别的MAVLink版本字段类型。具体如下:

§ char -Characters / strings
§ uint8_t - Unsigned8 bit
§ int8_t - Signed 8bit
§ uint16_t - Unsigned16 bit
§ int16_t - Signed16 bit
§ uint32_t - Unsigned32 bit
§ int32_t - Signed32 bit
§ uint64_t - Unsigned64 bit
§ int64_t - Signed64 bit
§ float - IEEE 754single precision floating point number
§ double - IEEE 754double precision floating point number
§ uint8_t_mavlink_version - 无符号8位字段,以当前的MAVLink版本发送时被自动添加,它不能被更改只是在数据包中以通常无符号8位整型字段读取。

1.8  性能
该协议主要面向两方面特性:传输速度和安全性。协议允许检验消息内容,同样允许检测丢失的消息序列但仍然只需要每个包中6个字节的开销来保证。
传输实例:
  链路速度/波特
  
   硬件
  
   更新速率
  
   负载
  
   浮点值
  
  115200 baud
  
   XBee Pro 2.4 GHz
  
   50  Hz
  
   224 bytes
  
   56
  
  115200 baud
  
   XBee Pro 2.4 GHz
  
   100 Hz
  
   109 bytes
  
   27
  
  57600 baud
  
   XBee Pro 2.4 GHz
  
   100 Hz
  
   51  bytes
  
   12
  
  9600 baud
  
   XBee Pro XSC 900
  
   50  Hz
  
   13  bytes
  
   3
  
  9600 baud
  
   XBee Pro XSC 900
  
   20  Hz
  
   42  bytes
  
   10
  

1.9  未来的工作/想法
Ÿ 采用变长数组
Ÿ 支持位域(例如:将8个布尔型的值封装入一个uint8_t结构中,但所有的C结构函数都可调用全部的8个布尔型量。用户就不必在整体移动或隐藏中浪费时间)
Ÿ 可变的多样头部,允许设定目标系统和目标部件(不改变协议本身,只是方便函数调用它们)


2  路径点协议
路径点协议描述了路径点是如何被发送到MAV并被它所读取的。其目标是在发送端和接收端确保建立一种连续稳定的状态。QGroundControl执行了在地面控制端的协议要求,每个在MAV上使用MAVLink实现路径点协议的规划模块能够和QGroundControl通讯并交换和更新它的路径点。

2.1 通信/状态机
协议中包含很多事务,每一个事务的完成情况以成功和失败来描述,在接收端的路径点列表状态未改变则被认为该事务的完成情况是失败的。只有在两个正在通讯的部分之间么有其他的事务在活动中时,新的事务才可以被一个特定的消息字段唤起进行。这意味着,如果想要发起一个新的事务,参与到该事务中的通讯部分必须全部处于IDLE即空状态。如果开始了一个事务,则通讯部分的状态将改变。引入一个以这种方式工作的状态机,则路径点协议可以十分简单的实现。
除了应答消息之外的其他信息在被发送之后,发送端的部件就会启动一个定时器。如果在特定的时间内,没有收到响应则请求的消息将会被重新发送一次。该重传过程会重复数次,如果在最后一次的重传超时后仍然没有收到相应,则认定该项事务失败。该重传机制意味着所有的部件必须能够处理重复的消息。


2.2 读取MAV的路径点列表

  为了能够从部件中检索含有所有路径点的列表,将会发送一个WAYPOINT_REQUEST_LIST的消息,而目标部件将会回应一个WAYPOINT_COUNT消息,描述在它的列表中的路径点数量。

之后,正在发送请求的部件会要求没有个路径点从序列号0开始发送WAYPOINT_REQUEST消息,而目标部件会以包含有路径点数据的对应的WAYPOINT消息来回应每一个请求。
当最后一个路径节点成功的接收到消息之后,发送请求的部件会向目的地部件发送一个WAYPOINT_ACK消息。这个消息将结束该项事务。需要注意的是,目的地部件必须监听来自最后一个路径节点的WAYPOINT_REQUEST消息,知道它拿到WAYPOINT_ACK消息或另一个消息命令开启一个不同的事务或者发生了超时。

2.3 书写MAV的路径列表

  为了能够发送一个路径点的列表,一个包含有列表中路径点数量的WAYPOINT_COUNT消息会被发送至目的地设备。而该设备将做好接收消息的准备,同时通过发送从序列号0开始的WAYPOINT_REQUEST消息开始检索所有的路径点。而发送路径点列表的设备将会以WAYPOINT消息来回应所有的请求。

当最后一个路径节点被目的地设备成功接收后,该目标设备将向发送设备发送一个WAYPOINT_ACK消息。之后将结束该事务。
如果一个路径点计划器设备在事务之外收到了WAYPOINT消息,它将发送一个WAYPOINT_ACK消息。


2.4 清除MAV的路径点列表

  要清除一个设备的路径点列表则可以发送WAYPOINT_CLEAR_ALL消息。在清除了路径点列表之后,目标设备将以WAYPOINT_ACK消息作为回应。


2.5 设置新的当前MAV路径点

  要向设备设置新的当前活跃路径点,发送一个WAYPOINT_SET_CURRENT消息即可。在完成了更改当前的路径点后目标设备将通过带有新的当前序列号的WAYPOINT_CURRENT消息作为回应。


2.6 MAV抵达路径点的状态消息
如果MAV上的路径点规划设备抵达一个路径点,它将会广播一个WAYPOINT_REACHED消息。由于是广播消息,因此不需要发送ACK消息,同样也就不能保证消息的接收。

2.7  MAV更改当前路径点的状态消息
如果一个MAV上的路径点规划设备选择了一个新的路径点作为它的新的当前航电,它将会广播一个WAYPOINT_CURRENT消息。由于是广播消息,因此不需要发送ACK消息,同样也就不能保证消息的接收。建议该消息能够在较小的间隔中发送两次,从而保证能够有较大的可能性使得所有接收端收到。

2.8  路径点文件格式
尽管这不是MAVLink协议的一部分,这个是建议的路径点文件格式(QGroundControl和其他设备默认使用)。请注意在参数之间的空格实质上是<tab>(在大多数编程语言中是”\t”)

3  参数协议
板载参数协议接口允许向内存(RAM)读写参数(例如:PID增益)也可以向参数存储器读写(EEPROM或者硬盘)。
   它不仅可以被部署安装在一个微型控制器上(例如:带有ARM7的pxIMU),也可以是标准软件(如:Linux系统中的px_multitracker进程)。


3.1  支持的数据类型
MAVLink v1.0支持如下数据类型:
§ uint32_t - 32bit unsigned integer (use the ENUMvalue MAV_PARAM_TYPE_UINT32)
§ int32_t - 32bit signed integer (use the ENUM value MAV_PARAM_TYPE_INT32)
§ float - IEEE754 single precision floating point number(use the ENUM value MAV_PARAM_TYPE_FLOAT)

注意:所有的参数都以浮点型的mavlink_param_union_t值发送,也就是意味着一个参数应当已这个按字节转换为相应的浮点型数据(没有类型转换)【which means that a parameter should be byte-wise convertedwith this union to a byte-wise float (no type conversion)】。这对于为了不影响和限制扩展后的整型参数的最大精确度的目的是非常必要的。例如:GPS定位的参数以单精度浮点型数据只能精确到几米的级别,而GPS定位参数如果以1E7


3.2  多系统和多部件支持
MAVLink在同一链接上支持并行的多系统/飞行器。不仅如此,它同样还支持在同一飞行器上的多个支持MAVLink协议设备的情况。例如,协议允许自动驾驶设备和负载单元在一个电磁波链接上来沟通。因此,在不同的部件之间参数协议也是不同的。通过发送请求参数消息target_component从0开始进行计数(步进值设置:MAV_COMP_ID_ALL)来从系统获得完整的参数列表。所有的机载部件都应当以带有他们的ID或是MAV_COMP_ID_ALL(0)的ID对参数请求信息进行回应。QGroundControl默认查询系统的所有部件(它只查询当前选定的系统,并不是所有系统),因此发送ID 0/MAV_COMP_ID_ALL。

3.3    QGroundControl里的图形用户界面
基于这个原因,参数接口将会辨别不同系统(一个系统就是一架飞机)和部件(一个部件就是一个实体的架构,例如:IMU或一个Linux进程)。这可以允许透明的访问每一个独立的部件参数而不再需要一个主要的机载单元来负责翻译对于机载部件的读/写参数请求。
如下图所示,在参数树中每个部件被一个顶层节点代表。系统(即无人机)可以从顶层的下拉菜单中选择。GUI将会跟踪参数的改变并且将参数发送至正确的部件当中。
为了方便多个参数的使用,树是根据第一下划线中的参数名称从顶层开始分组和构建的。所以PID_POS_X_P和PID_POS_Y_P将会被划分在在PID节点下。


3.4  通信/状态机
机载参数被定义为一个14字符的字符串并存储了一个浮点值(IEEE 754 单精度,4字节)。此键值对有许多重要的属性:
Ÿ  可读的变量名对于用户来说是非常有帮助的,但是它仍然足够小。
Ÿ  GCS不需要提前知道机载部件的参数有哪些。
Ÿ  确保支持未知的autopilots设备,只要他们执行协议内容。
Ÿ  添加一个参数只会改变飞机上的代码。

3.4.1读取参数

发送PARAM_REQUEST_LIST消息将激活读取参数列表的活动。飞机上的部件在收到这条指令后应当开始独立的传输参数。发送过程中在每个参数之后要适当的延迟,以免占用     
全部的无线电带宽。


3.4.2读取单个参数
单个参数可以通过PARAM_REQUEST_READ消息来读取。

3.4.3写参数
由于QGroundControl在初始状态时并没有自己的参数列表,在写参数列表之前参数列表首先要被读取一次。在那之后,参数才可以通过向部件发送键值对来被写入进去。由于QGroundControl会追踪参数的改变,电机写入按钮只会传输那些已经被更改的值。MAV必须确认这个写入的操作通过发送一个含有最新被写入进去的参数值的PARAM_VALUE的参数值消息。


3.5  机上永久存储器
参数接口提供了两个按钮来将飞机上的参数从永久的机上存储器装载至RAM和将当前的参数值从RAM保存至永久存储器。若需要从QGroundControl向永久存储器写入数据,首先数据需要被传输然后必须执行写入到ROM的命令。

3.6  QGroundControl的参数文档
QGroundControl允许将当前飞机上的参数值保存至一个文本文档中。之后文档可以被再次的导入和传输到MAV中。这就可以允许如配置几个飞行器都是完全相似的默认安全值。

3.7  MCU
这个单片机实现来自PIXHAWK IMU/Autopilot代码库。它允许贮存机上参数。请注意,这段代码可能没有编译,您首先需要调整你的板载数据结构。

4  图像传输协议
本节讲述图像数据流是如何工作和如何囊括了包括实施细节(在MAV和QGroundControl)和MAV与QGroundControl之间的通讯。
图像传输协议包含两个模块:图像流和视频流:


Ÿ  图像流
部分使用MAVLink作为通讯频道,同时图像流部分能够被用来从MAV向QGroundControl传输任何类型的图像(原始图像、体感数据…)。它主要是获取相机的实时图像病将其分解为小块通过MAVLink来进行发送。该模块主要是用来直接向QGroundControl传输图像(即HUD不见如下所述)。
注意:该模块也可以用来向QGroundControl发送海量数据块而不是图像。

Ÿ  视频流
部分以MPEG2的格式流式发送“真实(real)”的视频。它使用实时的照相机图像并使用FFMpeg来编码视频流。这个模块的主要应用情形是在任意的移动设备(笔记本电脑、只能手机、、、)上观看实时的视频传输而不需要使用QGroundControl和MAVLink的客户端。
图像流部分相较于视频流部分的主要优点是更好的融入了QGroundControl。最主要的缺点是需要MAVLink的支持(因此不像视频流部分由较好的跨平台特性)。
4.1  通讯4.1.1 图像流
图像流部分使用了两个MAVLink消息:一个是握手消息,DATA_TRANSMISSION_HANDSHAKE来初始化、控制和停止图像流;还有一个数据容器消息,ENCAPSULATED_IMAGE,来传输图像数据(见右图)。
(1)       通讯是由QGroundControl发起开始数据流的请求而发起的。因此,若要开始通讯,MAVLink消息的如下字段必须被设置:
Ÿ   target:设置为目标MAV的ID;
Ÿ   state:设置为0;
Ÿ   id:表示图像流的ID;
注意:目前,图像流部分只支持每个图像类型一个数据流,因此需要将id设置为和type字段想吐的整数。
Ÿ   type:在mavlink.h头文件中ENUM MAVLINK_DATA_STREAM_TYPES记录的任意类型。
Ÿ   freq:对于“frame per seconds”则大于0,“seconds per frame”则小于0。

该协议允许请求一个特定图像的质量。如需要,则必须设置quality字段。在初始请求时所有其他的字段必须为0。
(2)       当目标MAV收到握手请求之后,它会回送一个确认消息并开始在请求的帧频上进行图像流传输。握手消息的ACK包通常情况下包含和由QGroundControl请求的消息相同的值(state设置为1,因为这是ACK消息),并增添有关下一个发送消息的大小的相关数据:
Ÿ   值packets包括MAVLink ENCAPSULATED_DATA包的数量;
Ÿ   值payload指定了每个数据包的有效载荷大小(通常为252字节)。
Ÿ   值size指定了图像的字节大小。
(3)       之后,图像数据会被分割成适合正常的MAVLink消息的数据块。它们会被封装在ENCAPSULATED_DATA数据包中通过MAVLink进行发送。每个数据包包含一个序列号以及图像流对应的ID。然后,图像流就开始定期的发送新的图片,期间不再需要其他的交互。每一个新图像都有一个新的DATA_TRANSMISSION_HANDSHAKE的ACK包并更新图像的size,packets和payload值。在这个ACK包之后,新的图像作为一系列的ENCAPSULATED_DATA包而到达。注意:对于流中的每一个新图像,序列号都从0开始。
(4)       要停止一个图像流,你必须要发送一个新的DATA_TRANSMISSION_HANDSHAKE请求包,并将频率设置为0。

4.1.2 视频流
视频传输协议相较于图像传输协议简单许多:它只包含一个MAVLink消息,VIDEO_STREAM,用来开始和停止视频流(见下图)。

     
视频流消息有两个值需要设置:

Ÿ   target:目标MAV;
Ÿ   start_stop:1为开始视频流,0为结束视频流。
视频流由FFMpeg于MAV端创建并开始。一个小的MAVLink包抓取摄像机图像,添加(Y)UV渠道给YUV420 rawimage格式,并将该图片填制FFMpeg。之后,输出将被传输至地面站(注意:目前,这需要地面站有一个固定的IP并且在初始状态时有一个配置MAV的步骤)。收到视频后,QGroundControl打开VLC窗口对视频流进行重新分配:它从MAV得到这个视频流并将它作为RTP流(在一个多播地址)和HTTP流(直接单播流)提供给网络。这个过程并没有对原始流进行代码转换,以保持尽可能低的性能影响。
现在其他的移动设备可以通过多播地址 239.255.12.45 来链接到这个视频流,或通过[url=http://[qgc-host]/MAVLive.mpg%E6%9D%A5%E9%93%BE%E6%8E%A5%E5%88%B0HTTP]http://[QGC-HOST]/MAVLive.mpg来链接到HTTP[/url]流。多播流通过SAP声明为”MAVLive”.


4.2  使用/配置
在MAV上使用这两个模块,你需要做如下几步:

4.2.1 图像流
1、为你的MAV编译mavconn中间件
2、至少开启MAV上的这些设备:

px_mavlink_bridge_udp&

px_system_control--heartbeat &

px_camera -o lcm&

3、编译并启动QGroundControl
4、开启图像流设备(你可以添加-v标志来查看更多输出):
px_imagestreamer
5、初始化图像流: 打开HUD部件,到小部件上单击右键并选择“启用图像直播”。
现在你可以观看每秒一个画面的视频了(默认,此处为硬编码


4.2.2 视频流
1、执行上文所述的图像流的1至3步;
2、在主目录中创建一个符号链接:

cd~                                                        

ln-s mavconn/src/comm/video/px_videostreamer.sh px_videostreamer.sh


注意:你可以复制这个文件,但不建议这么做);
3、开启MAV上的视频流传输部件:
px_videostreamer

4、初始化视频流:打开HUD插件,单击右键并选择“启用视频直播”。

之后一个VLC窗口将开启。只要你想向其他人传输视频流,就请不要关闭这个窗口!如果你想观看当前的视频流,只需在其他的VLC窗口中打开这个视频流。


4.2.3  Developer
目前,只实现了对当前摄像机的图像以JPEG格式进行图像流传输。要想实现自己的图像流传输,你必须做如下的事情:
Ÿ   编写一个MAVLink处理程序来处理您选定的格式的图片流开始传输的请求。
Ÿ   编写一个数据处理程序来处理你的数据(如,立体相机图像),将其编码为你选择的格式(如,原始图像、JPEG、BMP)然后将其分散并通过MAVLink进行传输。
Ÿ   扩展QGroundControl中UAS部件内的数据/消息处理程序来正确处理你的数据(如,对选定的格式进行拆包)。
Ÿ   编写或对原来的插件进行扩展来根据你的想法显示你的数据。



回复

使用道具 举报

发表于 2015-11-5 20:45:54 | 显示全部楼层
不错,值得参考
回复 支持 反对

使用道具 举报

发表于 2015-11-10 16:06:25 | 显示全部楼层
使用MAVLINK会不会被黑客劫持飞机?
回复 支持 反对

使用道具 举报

发表于 2015-11-17 22:30:18 | 显示全部楼层
深入学习mavlink~
回复 支持 反对

使用道具 举报

发表于 2016-4-24 23:59:01 | 显示全部楼层
发帖看啊看
回复 支持 反对

使用道具 举报

发表于 2017-1-17 11:00:29 | 显示全部楼层
多谢分享,学习了~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表