概述
MAVLink协议是一种(应用层)数据协议,不依赖传输协议。传输层可以是TCP、UDP、RS232串口,甚至基于WebSocket。在定义数据的基础上,补充描述了几种子协议(microservice,直译是微服务)的现有实现。协议不保证送达,客户端需要经常检查机器状态确认命令被执行。
具体的数据定义包括:
数据帧格式,包括协议头和载荷(Payload),协议头包括协议版本、载荷长度、兼容标识、次序号、发送者系统号、发送者组件号、消息号、CRC检验和可选的签名。
消息号枚举和意义,不同的消息号其载荷的长度和意义。
命令子协议(一种特殊的消息),命令枚举和意义
官方提供了数据帧的装帧和解析基础库,支持12种语言,还有非官方的库额外多支持3种语言。官方的基础库是通过脚本解析多个XML生成的,XML原始地描述了所有的消息、命令、枚举。这些XML是包含的关系,按消息数量多少排序是:厂商定制消息集(例如ardupilotmega.xml) > common.xml(常用消息集,有161种消息)> minimal.xml(最小消息集,有2种消息)。生成基础库时可传参给脚本指定消息集。
MAVLink的Java库
生成目标为APM板子。源码都在com.MAVLink包中,目录文件结构:
uAvionix/CRC.java。CRC算法,算法的约定整数序列全是0。
enums/
97个java文件,按协议规范定义了各种枚举值。
Messages/
MAVLinkMessage.java。各种消息的抽象基类。每种MAVLink消息都有一个子类。
MAVLinkPayload.java。表示协议载荷,直接操作ByteBuffer。
MAVLinkStats.java。统计收发帧的数量和错误数。主要实现协议中的seq消息次序号。
ardupilotmega/
CRC.java。CRC算法,算法的约定整数序列已设为MAVLink自定义的值。
msg_*.java。63个消息类,APM特有的,都继承MAVLinkMessage。
common/
CRC.java。和ardupilot/CRC.java是一样的。
msg_*.java。136个消息类,都继承MAVLinkMessage。
MAVLinkPacket.java。对一帧数据的封装,有装帧和解析(生成一个具体的消息类)操作。
Parser.java。解析过程的实现类,逐字节传入数据。
数据接收流程:
将底层连接接收的字节流逐个字节传入Parser.mavlink_parse_char(int c)函数,至一帧接收完毕时会返回一个MAVLinkPacket实例,否则返回null。
调用MAVLinkPacket.unpack()函数,即得到一个MAVLinkMessage实例
根据msgid成员变量判断,强制转换成对应子类。
发送流程:
new一个具体的消息,对成员变量赋(业务)值
调用MAVLinkMessage.pack()函数得到一个MAVLinkPacket实例
调用MAVLinkPacket.encodePacket()函数得到byte[]传给底层连接。
重要的协议流程
系统号和组件号
协议中各用一个字节(0~255)分别表示消息发送者的系统号(system ID)和组件号(component ID)。系统就两种,飞控和地面站(飞控客户端都叫地面站)。可以同时有多架飞机和多个地面站连接,所以系统号必须唯一。组件可以是飞控(固件)、无线电台、相机、电机、万向节、电池、显示设备、降落伞,地面站控制模块、惯性导航、GPS等,有固定枚举值来表示这些组件。
部分消息的载荷里,有targetSystemID和targetComponentID参数来表示期望执行命令的系统组件。
多架飞机的SystemID从1开始递增。多个地面站的SystemID从255开始递减。
心跳
各组件都发出HEARTBEAT ( #0 )消息,被其它系统组件用来判断是否在线。各组件必须有规律地发出心跳消息,即使不发控制命令的也要。通常频率为1Hz,如果连续4或5次没收到消息就认为那个系统掉线了。
参数type
地面站应为6,MAV_TYPE_GCS
飞控是按类型有不同取值,例如14,MAV_TYPE_OCTOROTOR,是4轴8桨飞行器。
参数(组件能力与状态)
飞控客户端可以请求想要的数据以及设置响应频率,这些数据都来自上文的组件。完整的可请求的数据列表在这:https://ardupilot.org/dev/docs/mavlink-requesting-data.html。
涉及4种消息。
获取
PARAM_REQUEST_LIST,获取所有参数。地面站发出这个命令,飞控用PARAM_VALUE消息逐个参数回复。PARAM_VALUE消息有param_count参数表示总共有多少个参数以及param_index表示这是第几个。
PARAM_REQUEST_READ,获取单个参数,飞控用PARAM_VALUE消息回复。
设置
PARAM_SET,设置单个参数。地面站发出这个命令,飞控用PARAM_VALUE消息再广播一次表示收到。
航线
涉及10种消息
上传
地面站发出MISSION_COUNT,表示有多少个item
飞控发来MISSION_REQUEST_INT,参数seq表示第几个。
地面站回复MISSION_ITEM_INT,按seq第几个来上传
飞控发来MISSION_ACK表示已接受所有item。
查询
地面站发出MISSION_REQUEST_LIST
然后是上传过程调换角色,即地面站发MISSION_REQUEST_INT,飞控发MISSION_ITEM_INT,最后地面站发MISSION_ACK
流程图如下:
报告
飞控发出MISSION_CURRENT消息,当前执行的item:飞控会报告当前执行的mission item seq号
飞控发出MISSION_ITEM_REACHED消息,飞控每到达一个mission item的地点就会报告一次,参数为seq
设置当前item
地面站发出MISSION_SET_CURRENT消息。我们不会用。
清除
地面站发出MISSION_CLEAR_ALL消息,清除所有任务item
重要的命令
MAV_CMD_NAV_WAYPOINT (16 ),航点信息,会直线飞过去。用在MISSION_ITEM_INT消息中
MAV_CMD_NAV_RETURN_TO_LAUNCH (20 ),返航命令。用在MISSION_ITEM_INT消息中
MAV_CMD_NAV_LAND (21 ),着陆命令。用在MISSION_ITEM_INT消息中
MAV_CMD_NAV_TAKEOFF (22 ),起飞命令。用在COMMAND_LOG消息中
MAV_CMD_NAV_SPLINE_WAYPOINT (82 ),航点信息,会延曲线路径飞过去。用在MISSION_ITEM_INT消息中
MAV_CMD_MISSION_START (300 ),开始执行任务。用在COMMAND_LOG消息中
MAV_CMD_COMPONENT_ARM_DISARM (400 ),锁定或解锁。用在COMMAND_LOG消息中
MAV_CMD_SET_MESSAGE_INTERVAL (511 ),设置消息的发送间隔。用在COMMAND_LOG消息中
MAV_CMD_REQUEST_MESSAGE (512 ),511命令的一次性版。用在COMMAND_LOG消息中
MAV_CMD_REQUEST_PROTOCOL_VERSION (519 ),请求对方的MAVLink版本兼容性。对方应该ACK并发回一个PROTOCOL_VERSION消息。用在COMMAND_LOG消息中
MAV_CMD_REQUEST_AUTOPILOT_CAPABILITIES (520 ),获取自动驾驶的能力。用在COMMAND_LOG消息中。
参考资料
设计原则。https://docs.google.com/document/d/1XtbD0ORNkhZ8eKrsbSIZNLyg9sFRXMXbsR2mp37KbIg/edit文章来源:https://www.toymoban.com/news/detail-662229.html
基础知识。MAVLink Basics ‒ Dev documentation文章来源地址https://www.toymoban.com/news/detail-662229.html
到了这里,关于开源飞控初探(五):MAVLink协议和Java库的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!