【无人机学习之DroidPlanner】MAVLink协议
█ 【无人机学习之DroidPlanner】MAVLink协议
█ 系列文章目录
提示:这里是收集了无人机的相关文章
- 【无人机学习】无人机基础知识
- 【无人机学习】Mission Planner(pc端)和QGroundControl(android端)
- 【无人机学习之DroidPlanner】MAVLink协议
- 【无人机学习之DroidPlanner】msg_heartbeat心跳处理
- 【无人机学习之DroidPlanner】msg_sys_status系统状态
- 【无人机学习之QGroundControl】android端App初解1
- 【无人机学习之QGroundControl】android端App初解2-APMPowerComponent(含QML的介绍)
- 【无人机学习之QGroundControl】android端App初解3-ParameterEditorController
█ 文章目录
- █ 【无人机学习之DroidPlanner】MAVLink协议
- █ 系列文章目录
- █ 文章目录
- █ 读前说明
- █ MAVLink
- 1.简介
- 2.协议格式
- 3.使用Python写的用于生成C、Java等语言的MavLink生成器软件:
- █ DroidPlanner怎么发送消息(mavlink v1.0)
- 1.mavlink 版本
- 2.代码过程
- 3.配置起飞模式(MavLinkCommands.java)
- 4.发送(MAVLinkClient.java)
- 5.发送(MavLinkConnection.java)
- 6.MAVLink协议
- 7.其他
- █ 相关资料
- █ 免责声明
█ 读前说明
-
本文通过学习别人写demo,学习一些课件,参考一些博客,学习相关知识,如有涉及侵权请告知
-
本文可能只简单罗列了一些相关的代码实现过程,复制了一些大神的高论,如内容有误请自行辨别
-
涉及到的逻辑以及说明可能只做了简单的介绍,主要当做笔记,了解过程而已,如有不同看法,欢迎下方评论
-
本文源码:DroidPlanner/Tower
dronekit/dronekit-android -
MAVLink定义:
MAVLink - common - msg_attitude
MissionPlanner-master2021 - Mavlink.cs
█ MAVLink
1.简介
- 官网:MAVLink
- MAVLink是一种非常轻量级的通信协议,主要是用于无人机上,还有无人车等;
- 目前MAVLink有两个版本:V1.0(2013年发布)和V2.0版本(2017年发布);
- V2是V1的拓展版本,简化传输,向下兼容V1.0,是一个更加安全和可扩展的协议;
- MAVLink通信内容包含常见通信协议帧头、帧尾、长度、校验等。
- MAVLink目前最新版本是 V 2.3;
- qgc地面站使用的是mavlink ,和px4是同一个人研发的;
2.协议格式
官网:mavlink协议格式
比较重要的字段是msgid和payload,msgid用来区分消息类型,判断需要转换成什么类型的对话,payload是对应的值


uint8_t magic; ///< protocol magic marker
uint8_t len; ///< Length of payload
uint8_t incompat_flags; ///< flags that must be understood (V2.0增加)
uint8_t compat_flags; ///< flags that can be ignored if not understood(V2.0增加)
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 0:7; ///< first 8 bits of the ID of the message
uint8_t msgid 8:15; ///< middle 8 bits of the ID of the message
uint8_t msgid 16:23; ///< last 8 bits of the ID of the message
uint8_t payload[max 255]; ///< A maximum of 255 payload bytes
uint16_t checksum; ///< CRC-16/MCRF4XX
uint8_t signature[13]; ///< Signature which allows ensuring that the link is tamper-proof (optional)(V2.0增加)
| 索引 | C 版 | 内容 | 值 | 说明 | |
|---|---|---|---|---|---|
| STX | 0 | uint8_t magic | 起始标志位 | 0xFD | 表示新数据包的开始,固定以“FD”开头 |
| LEN | 1 | uint8_t len | 载荷长度 | 0 - 255 | 有效载荷数据的字节长度(N) |
| INC FLAGS | 2 | uint8_t incompat_flags | 不兼容标志 | 不了解标志,则实现将丢弃数据包 | |
| CMP FLAGS | 3 | uint8_t compat_flags | 兼容性标志 | 不理解该标志,仍可以处理数据包 | |
| SEQ | 4 | uint8_t seq | 包序号 | 0 - 255 | 用于检测数据包丢失,每发送完一个消息,加1 |
| SYS ID | 5 | uint8_t sysid | 系统ID(发送者) | 1 - 255 | 发送消息的系统(飞机/车辆)的ID |
| COMP ID | 6 | uint8_t compid | 部件 ID (发送者) | 1 - 255 | 发送消息的部件的ID 。用来区分在系统中的不同组件,如自动驾驶仪和照相机 |
| MSG ID | 7 to 9 | uint32_t msgid:24 | 消息ID(低,中,高字节) | 0 - 16777215 | 有效载荷中消息类型的ID 。用于将数据解码回消息对象。 |
| PLAYLOAD | 10 to (n+10) | uint8_t payload[max 255] | 载荷 | 消息数据。取决于消息类型(即消息ID)和内容。 | |
| CHECKSUM | (n+10) to (n+11) | uint16_t checksum | 冗余校验/校验和(低字节,高字节) | 消息的CRC-16 / MCRF4XX(不包括magic字节),包括CRC_EXTRA字节 | |
| SIGNATURE | (n+12) to (n+25) | uint8_t signature[13] | 签名 | (可选)签名以确保链接是防篡改的。 |

3.使用Python写的用于生成C、Java等语言的MavLink生成器软件:
- https://github.com/mavlink/mavlink
█ DroidPlanner怎么发送消息(mavlink v1.0)
1.mavlink 版本
从代码中可以看出:
使用的mavlink的版本是v1.0;
其实比V2.0少了INC FLAGS、CMP FLAGS、SIGNATURE 三个参数;

2.代码过程
| 过程 | 说明 |
|---|---|
| new msg_command_long() | msgid = 76; |
| 设置target_system | drone.getSysid(); drone.getCompid(); |
| 设置target_component | drone.getCompid(); |
3.配置起飞模式(MavLinkCommands.java)
提示:此文件全路径为:org.droidplanner.services.android.impl.core.MAVLink.MavLinkCommands.java
- 首先看下这份代码的1个发送命令方法:(配置起飞模式)
public static void sendTakeoff(MavLinkDrone drone, double alt, ICommandListener listener) {msg_command_long msg = new msg_command_long();// msgid = 76; msg.target_system = drone.getSysid();msg.target_component = drone.getCompid();msg.command = MAV_CMD.MAV_CMD_NAV_TAKEOFF;// 起飞模式msg.param7 = (float) alt;// z轴,即高度drone.getMavClient().sendMessage(msg, listener);// 下一步需要查看的信息:MAVLinkClient.sendMessage()
}
- new msg_command_long()就是创建了一个 msgid = MAVLINK_MSG_ID_COMMAND_LONG;即76;
- 查看#76的协议文档:
提示:注意到command的数据类型是MAV_CMD

- 查看MAV_CMD的协议文档:
MAVLink Commands (MAV_CMD)
MAVLink命令(MAV_CMD)和消息不同,定义了最多7个参数的值,被打包在特定任务中使用的协议和命令协议的消息。命令执行的飞行器
MAV_CMD_NAV_TAKEOFF:(22 起飞模式)


4.发送(MAVLinkClient.java)
提示:此文件全路径为:org.droidplanner.services.android.impl.communication.service.MAVLinkClient.java
private static final int DEFAULT_SYS_ID = 255;private static final int DEFAULT_COMP_ID = 190;
@Overridepublic synchronized void sendMessage(MAVLinkMessage message, ICommandListener listener) {sendMavMessage(message, DEFAULT_SYS_ID, DEFAULT_COMP_ID, listener);}
protected void sendMavMessage(MAVLinkMessage message, int sysId, int compId, ICommandListener listener){if (isDisconnected() || message == null) {return;}final MAVLinkPacket packet = message.pack();packet.sysid = sysId;packet.compid = compId;packet.seq = packetSeqNumber;mavlinkConn.sendMavPacket(packet);// 下一步需要查看的信息:MavLinkConnectionpacketSeqNumber = (packetSeqNumber + 1) % (MAX_PACKET_SEQUENCE + 1);if (commandTracker != null && listener != null) {commandTracker.onCommandSubmitted(message, listener);}}
5.发送(MavLinkConnection.java)
提示:此文件全路径为:org.droidplanner.services.android.impl.core.MAVLink.connection.MavLinkConnection.java
// 转换成16进制大写字符串发送出去public void sendMavPacket(MAVLinkPacket packet) {final byte[] packetData = packet.encodePacket();Log.e("sendMavPacket", String2ByteArrayUtils.INSTANCE.bytes2Hex(packetData));if (!mPacketsToSend.offer(packetData)) {mLogger.logErr(TAG, "Unable to send mavlink packet. Packet queue is full!");}}
6.MAVLink协议
提示:
每个数基本上都是一个字节(uint8_t )即0x00-0xff;
msg_command_long 的发送结构
| STX | LEN|SEQ|SYS ID|COMPID ID|MSG ID|PLAYLOAD|CHECK SUM|
|–|–|–|–|–|–|–|–|–|
|起始位|载荷长度|包序号|地面站系统ID|地面站部件 ID|消息ID|载荷|校验|
|固定值|自动|自动|固定值|固定值|COMMAND LONG|–|自动|
|0xFE|–|–|255|190|76|–|–|
PLAYLOAD的发送结构(MAV_CMD_NAV_TAKEOFF)
| target system | target component | command | confirmation | Pitch | param2 | param3 | Yaw | Latitude | Longitude | Altitude |
|---|---|---|---|---|---|---|---|---|---|---|
| 飞控系统id | 飞控部件 ID | MAV_CMD指令 | 确认位 | 最高点 | Empty | Empty | 偏航角 | 维度 | 经度 | 高度 |
| drone.Sysid | drone.Compid | TAKEOFF | – | – | – | – | – | – | – | alt |
7.其他
1.MissionPlanner 使用的是 MAVLink 2.0(参考 “MissionPlanner-master\ExtLibs\Mavlink\Mavlink.cs”)
public partial class MAVLink
{public const string MAVLINK_BUILD_DATE = "Sat Dec 26 2020";public const string MAVLINK_WIRE_PROTOCOL_VERSION = "2.0";// ###V2.0标记public const int MAVLINK_MAX_PAYLOAD_LEN = 255;public const byte MAVLINK_CORE_HEADER_LEN = 9;///< Length of core header (of the comm. layer)public const byte MAVLINK_CORE_HEADER_MAVLINK1_LEN = 5;///< Length of MAVLink1 core header (of the comm. layer)public const byte MAVLINK_NUM_HEADER_BYTES = (MAVLINK_CORE_HEADER_LEN + 1);///< Length of all header bytes, including core and stxpublic const byte MAVLINK_NUM_CHECKSUM_BYTES = 2;public const byte MAVLINK_NUM_NON_PAYLOAD_BYTES = (MAVLINK_NUM_HEADER_BYTES + MAVLINK_NUM_CHECKSUM_BYTES);public const byte MAVLINK_STX_MAVLINK1 = 0xFE;// ###V2.0标记,V1.0是0xFD。。。。。。// msgid, name, crc, minlength, length, typepublic static message_info[] MAVLINK_MESSAGE_INFOS = new message_info[] {new message_info(148, "AUTOPILOT_VERSION", 178, 60, 78, typeof( mavlink_autopilot_version_t )),new message_info(42001, "ICAROUS_KINEMATIC_BANDS", 239, 46, 46, typeof( mavlink_icarous_kinematic_bands_t )),new message_info(269, "VIDEO_STREAM_INFORMATION", 58, 246, 246, typeof( mavlink_video_stream_information_t )),new message_info(0, "HEARTBEAT", 50, 9, 9, typeof( mavlink_heartbeat_t )),};public const byte MAVLINK_VERSION = 2;public const byte MAVLINK_IFLAG_SIGNED= 0x01;public const byte MAVLINK_IFLAG_MASK = 0x01;public struct message_info{public uint msgid { get; internal set; }public string name { get; internal set; }public byte crc { get; internal set; }public uint minlength { get; internal set; }public uint length { get; internal set; }public Type type { get; internal set; }}public struct mavlink_autopilot_version_t{public mavlink_autopilot_version_t(/*MAV_PROTOCOL_CAPABILITY*/ulong capabilities,ulong uid,uint flight_sw_version,uint middleware_sw_version,uint os_sw_version,uint board_version,ushort vendor_id,ushort product_id,byte[] flight_custom_version,byte[] middleware_custom_version,byte[] os_custom_version,byte[] uid2) {this.capabilities = capabilities;this.uid = uid;this.flight_sw_version = flight_sw_version;this.middleware_sw_version = middleware_sw_version;this.os_sw_version = os_sw_version;this.board_version = board_version;this.vendor_id = vendor_id;this.product_id = product_id;this.flight_custom_version = flight_custom_version;this.middleware_custom_version = middleware_custom_version;this.os_custom_version = os_custom_version;this.uid2 = uid2;}/// Bitmap of capabilities MAV_PROTOCOL_CAPABILITY bitmask [Units("")][Description("Bitmap of capabilities")]public /*MAV_PROTOCOL_CAPABILITY*/ulong capabilities;/// UID if provided by hardware (see uid2) [Units("")][Description("UID if provided by hardware (see uid2)")]public ulong uid;/// Firmware version number [Units("")][Description("Firmware version number")]public uint flight_sw_version;/// Middleware version number [Units("")][Description("Middleware version number")]public uint middleware_sw_version;/// Operating system version number [Units("")][Description("Operating system version number")]public uint os_sw_version;/// HW / board version (last 8 bytes should be silicon ID, if any) [Units("")][Description("HW / board version (last 8 bytes should be silicon ID, if any)")]public uint board_version;/// ID of the board vendor [Units("")][Description("ID of the board vendor")]public ushort vendor_id;/// ID of the product [Units("")][Description("ID of the product")]public ushort product_id;/// Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases. [Units("")][Description("Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.")][MarshalAs(UnmanagedType.ByValArray,SizeConst=8)]public byte[] flight_custom_version;/// Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases. [Units("")][Description("Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.")][MarshalAs(UnmanagedType.ByValArray,SizeConst=8)]public byte[] middleware_custom_version;/// Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases. [Units("")][Description("Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.")][MarshalAs(UnmanagedType.ByValArray,SizeConst=8)]public byte[] os_custom_version;/// UID if provided by hardware (supersedes the uid field. If this is non-zero, use this field, otherwise use uid) [Units("")][Description("UID if provided by hardware (supersedes the uid field. If this is non-zero, use this field, otherwise use uid)")][MarshalAs(UnmanagedType.ByValArray,SizeConst=18)]public byte[] uid2;};}
█ 相关资料
提示:这里是参考的相关文章
- mavlink官网:MAVLink
- pixhawk官网:Mavlink 消息简介 - pixhawk
- 2020-10-06 ardupilot 如何为android 增加mavlink协议_陌城烟雨-CSDN博客
- 打造自己的HelloDrone 无人机APP过程《2》_陌城烟雨-CSDN博客_drone无人机怎么下app
- 2015-04-02 Mavlink协议理解Pixhawk APM(一)_super_mice的专栏-CSDN博客
- 2018-12-24 无人机中级篇:第十四讲:外部通信总线Mavlink服务 - 知乎
- 2019-02-15 MAVLINK 请求参数和接收参数_小马哔哔-CSDN博客
- 很直白:2020-02-06 MAVLink笔记 #02# MAVLink绝对傻瓜教程(译) - xkfx - 博客园
█ 免责声明
| 博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持! |
|---|
提示:转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/112827387
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
