【无人机学习之DroidPlanner】MAVLink协议

█ 【无人机学习之DroidPlanner】MAVLink协议


█ 系列文章目录

提示:这里是收集了无人机的相关文章


█ 文章目录


█ 读前说明


█ 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 版内容说明
STX0uint8_t magic起始标志位0xFD表示新数据包的开始,固定以“FD”开头
LEN1uint8_t len载荷长度0 - 255有效载荷数据的字节长度(N)
INC FLAGS2uint8_t incompat_flags不兼容标志不了解标志,则实现将丢弃数据包
CMP FLAGS3uint8_t compat_flags兼容性标志不理解该标志,仍可以处理数据包
SEQ4uint8_t seq包序号0 - 255用于检测数据包丢失,每发送完一个消息,加1
SYS ID5uint8_t sysid系统ID(发送者)1 - 255发送消息的系统(飞机/车辆)的ID
COMP ID6uint8_t compid部件 ID (发送者)1 - 255发送消息的部件的ID 。用来区分在系统中的不同组件,如自动驾驶仪和照相机
MSG ID 7 to 9uint32_t msgid:24 消息ID(低,中,高字节) 0 - 16777215 有效载荷中消息类型的ID 。用于将数据解码回消息对象。
PLAYLOAD10 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生成器软件:

█ DroidPlanner怎么发送消息(mavlink v1.0)

1.mavlink 版本

从代码中可以看出:
使用的mavlink的版本是v1.0;
其实比V2.0少了INC FLAGS、CMP FLAGS、SIGNATURE 三个参数;

在这里插入图片描述

2.代码过程

过程说明
new msg_command_long()msgid = 76;
设置target_systemdrone.getSysid(); drone.getCompid();
设置target_componentdrone.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;
 @Override
    public 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);// 下一步需要查看的信息:MavLinkConnection

        packetSeqNumber = (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 systemtarget componentcommandconfirmationPitchparam2param3YawLatitudeLongitudeAltitude
飞控系统id飞控部件 IDMAV_CMD指令确认位最高点EmptyEmpty偏航角维度经度高度
drone.Sysiddrone.CompidTAKEOFFalt

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 stx
    public 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, type
    public 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;
            
        }
        /// <summary>Bitmap of capabilities MAV_PROTOCOL_CAPABILITY  bitmask</summary>
        [Units("")]
        [Description("Bitmap of capabilities")]
        public  /*MAV_PROTOCOL_CAPABILITY*/ulong capabilities;
            /// <summary>UID if provided by hardware (see uid2)   </summary>
        [Units("")]
        [Description("UID if provided by hardware (see uid2)")]
        public  ulong uid;
            /// <summary>Firmware version number   </summary>
        [Units("")]
        [Description("Firmware version number")]
        public  uint flight_sw_version;
            /// <summary>Middleware version number   </summary>
        [Units("")]
        [Description("Middleware version number")]
        public  uint middleware_sw_version;
            /// <summary>Operating system version number   </summary>
        [Units("")]
        [Description("Operating system version number")]
        public  uint os_sw_version;
            /// <summary>HW / board version (last 8 bytes should be silicon ID, if any)   </summary>
        [Units("")]
        [Description("HW / board version (last 8 bytes should be silicon ID, if any)")]
        public  uint board_version;
            /// <summary>ID of the board vendor   </summary>
        [Units("")]
        [Description("ID of the board vendor")]
        public  ushort vendor_id;
            /// <summary>ID of the product   </summary>
        [Units("")]
        [Description("ID of the product")]
        public  ushort product_id;
            /// <summary>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.   </summary>
        [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;
            /// <summary>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.   </summary>
        [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;
            /// <summary>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.   </summary>
        [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;
            /// <summary>UID if provided by hardware (supersedes the uid field. If this is non-zero, use this field, otherwise use uid)   </summary>
        [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;
    
    };
 }

█ 相关资料

提示:这里是参考的相关文章

  1. mavlink官网:MAVLink
  2. pixhawk官网:Mavlink 消息简介 - pixhawk
  3. 2020-10-06 ardupilot 如何为android 增加mavlink协议_陌城烟雨-CSDN博客
  4. 打造自己的HelloDrone 无人机APP过程《2》_陌城烟雨-CSDN博客_drone无人机怎么下app
  5. 2015-04-02 Mavlink协议理解Pixhawk APM(一)_super_mice的专栏-CSDN博客
  6. 2018-12-24 无人机中级篇:第十四讲:外部通信总线Mavlink服务 - 知乎
  7. 2019-02-15 MAVLINK 请求参数和接收参数_小马哔哔-CSDN博客
  8. 很直白:2020-02-06 MAVLink笔记 #02# MAVLink绝对傻瓜教程(译) - xkfx - 博客园

█ 免责声明

博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持!

提示:转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/112827387

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值