当前位置: 代码迷 >> 综合 >> MavLink
  详细解决方案

MavLink

热度:5   发布时间:2024-02-12 03:07:00.0

2.1 MAVLink (Micro Air Vehicle Link)是一种用于小型无人载具的通信协议,

于2009年首次发布。该协议广泛应用于地面站(Ground Control Station,GCS)
与无人载具(Unmanned vehicles)之间的通信,同时也应用在载具内部子系统的
内部通信中,协议以消息库的形式定义了参数传输的规则。MAVLink协议支持
无人固定翼飞行器、无人旋翼飞行器、无人车辆等多种载具。
? 官方使用文档网站:
https://mavlink.io/en/messages/common.html
? MAVLink源码:
https://github.com/mavlink/mavlink
? 基于MAVLink的QGroundControl地面站源码:
https://github.com/mavlink/qgroundcontrol

2.2 MAVLink的本质就是字节流的封装与解析协议

  • MAVLink 1的数据包格式如下:
    在这里插入图片描述

  • MAVLink 2的数据包如下:
    在这里插入图片描述
    在这里插入图片描述

2.3 解析原理

? 读取:所有字节流存入buffer,依次读取buffer中的字节数据,遇到STX标志位(MAVLink v1的标志位是0xFE,v2的标志位为0xFD)开始识别一条消息直到消息尾部,如果消息校验正确则将消息发送给处
理程序? 发送:按上一页PPT将消息转换成字节流。
在这里插入图片描述

2.4 接收解析源码分析

给定一定长度的字节流buffer,长度为length,通过下列脚本解析,每解析出一
个mavlink数据包就执行onMavLinkMessage函数

for(int i = 0 ; i < length ; ++i)
{
msgReceived = mavlink_parse_char(MAVLINK_COMM_1, (uint8_t)buffer[i], &message, &status);
if(msgReceived){
emit onMavLinkMessage(message);
} 
}

其中:
void onMavLinkMessage(mavlink_message_t message);
是得到一个MAVLink消息包后的处理函数,需要根据这个消息的ID来识别当前包的用途(心跳包,
GPS位置,姿态等),并提取出感兴趣的数据。
解析函数实现如下,根据message.msgid跳到对应的_decode函数,解码出数据

void onMavLinkMessage(mavlink_message_t message){
switch (message.msgid){
case MAVLINK_MSG_ID_GLOBAL_POSITION_INT:{
mavlink_global_position_int_t gp;
mavlink_msg_global_position_int_decode(&message, &gp);
outHilData.time_boot_ms = m_LastReceiveMavMsg;
outHilData.GpsPos[0]=gp.lat;
outHilData.GpsPos[1]=gp.lon;
outHilData.GpsPos[2]=gp.alt;
outHilData.relative_alt = gp.relative_alt;
outHilData.GpsVel[0]=gp.vx;
outHilData.GpsVel[1]=gp.vy;
outHilData.GpsVel[2]=gp.vz;
outHilData.hdg = gp.hdg;
break;
}
}
}

2.5 发送源码解析 — 发送一条mavlink_hil_actuator_controls消息

void sendHILCtrlMessage(uint8_t modes, uint64_t flags, float ctrl[])
{
mavlink_hil_actuator_controls_t hilctrl;
hilctrl.mode = modes;
hilctrl.flags = flags;
for(int i=0;i<16;i++){
hilctrl.controls[i]=ctrl[i];
}
mavlink_message_t mess;
mavlink_msg_hil_actuator_controls_encode(SystemID, TargetCompID, &mess, &hilctrl);
char buffer[500];
memset(buffer,0,500);
unsigned int length = mavlink_msg_to_send_buffer((uint8_t*)buffer, & mess);
udp.writeDatagram(buffer,length);//通过UDP或者串口将buffer发送出去即可
}

2.6 MAVLink消息包的ID列表
在这里插入图片描述