QGC地面站Mavlink生成和MockLink模拟收发通讯
Mavlink生成和收发通讯
- 1. 演示效果
- 2. Mavlink 生成
- 2.1 安装python3
- 2.2 Mavlink下载和运行
- 2.3 xml文件修改
- 2.4 自定义Mavlink生成
- 3. 业务逻辑实现
- 3.1 QML前端显示
- 3.1.1 发送部分
- 3.1.2 接收显示
- 3.2 C++后端
- 3.2.1 QGC发送
- 3.2.2 MockLink接收
- 3.2.3 MockLink发送
- 3.2.4 QGC接收
所有的热爱都要不遗余力,真正喜欢它便给它更高的优先级,和更多的时间吧!
关于QGC地面站其它文章请点击这里: QGC地面站
本文源码地址: QGC_CCH地面站
我建了个QGC学习交流群,感兴趣的小伙伴们可以扫码加入哦,失效了,可以加我微信拉进群
1. 演示效果
测试的时候如下,连接MockLink中的PX4:
QGC发送数据: 需要手动点击发送,MockLink中会打印接收到的两个字节
MockLink发送数据: 1HZ的定时器发送
2. Mavlink 生成
主要流程参考官网:
Installing MAVLink
Generating MAVLink Libraries
2.1 安装python3
安装教程可以参考这个,Python3.7.3安装(Win10),现在已经是3.9.5版本了。安装完后测试下看是否装成功了
然后安装 pip3,直接打开cmd命令
pip3 install future
如果报这个:
可以升级一下,不升级应该也行吧~
python -m pip install --upgrade pip
然后查看版本:
pip show pip
2.2 Mavlink下载和运行
需要递归下载
git clone https://github.com/mavlink/mavlink.git --recursive
下载不完全会导致运行不了Mavlink生成器,需要安装包,关注后评论留邮箱私发
进入下载的Mavlink的根文件夹,执行
python mavgenerate.py
如下,弹出了Mavlink生成器:
2.3 xml文件修改
打开 ~\libs\mavlink\include\mavlink\v2.0\message_definitions\ardupilotmega.xml
仿原有的格式,自定义236号ID,并添加在226号后,如下:
<message id="226" name="RPM"><description>RPM sensor output.</description><field type="float" name="rpm1">RPM Sensor1.</field><field type="float" name="rpm2">RPM Sensor2.</field>
</message>
<message id="236" name="CSDN_TEST"><description>CSDN TEST.</description><field type="uint8_t" name="byte1">FRIST BYTE.</field><field type="uint8_t" name="byte2">SECOND BYTE.</field>
</message>
定义了byte1、byte1两个字节的数据,此处就是你需要与无人机通讯的数据。
PX4中定义的话最好在 common.xml 中添加。
2.4 自定义Mavlink生成
如下:
XML: ~\libs\mavlink\include\mavlink\v2.0\message_definitions\ardupilotmega.xml
Out: 可以新建个文件作为输出,也可以直接覆盖QGC中的mavlink库(不太推荐,但是此次测试就是直接覆盖的,覆盖的话记得先备份下原本的mavlink库)
这就是生成的mavlink库:
复制 ardupilotmega 下的 mavlink_msg_csdn_test.h到 qgc的mavlink对应位置下( 如果全选OUT下的文夹复制到qgc mavlink库中可跳过这些步骤)
覆盖 qgc的mavlink的ardupilotmega.h ,注意看其实就改了几处:
① 修改 #define MAVLINK_MESSAGE_CRCS 校验处,增加了236号ID的校验
② include mavlink_msg_csdn_test.h 头文件
③ 修改 MAVLINK_MESSAGE_INFO
④ 修改 MAVLINK_MESSAGE_NAMES
注意: 其中最重要的是第一处的 MAVLINK_MESSAGE_CRCS 校验,如果在Mocklink中能通讯,实际的飞控无法通讯多半是检验位没通过,就是此处有问题,可以分别检查下 ardupilotmega.h、common.h、standard中的MAVLINK_MESSAGE_CRCS,甚至可以都加上新增的校验ID
3. 业务逻辑实现
3.1 QML前端显示
添加在 FlightDisplayView.qml (有些版本是FlyView.qml)后:
3.1.1 发送部分
发送的关键就是 activeVehicle.testSendToVehicle(protectTextField1.text, protectTextField2.text) ,把两个用户输入数据的文本框发送给MockLink
//FlightDisplayView.qml (有些版本是FlyView.qml) 最后Rectangle {id: sendRectanchors.top: parent.topanchors.topMargin: 20anchors.horizontalCenter: parent.horizontalCenterheight: col.height * 1.1width: col.width * 1.1radius: 2color: "black"Column {id: colspacing: 4anchors.centerIn: parentQGCLabel {anchors.horizontalCenter: parent.horizontalCentertext: "Mavlink 发送测试!"font.pointSize: 12font.bold: truecolor: "red"}Row {anchors.left: parent.leftanchors.right: parent.rightQGCLabel {id: tipsLabelanchors.verticalCenter: protectTextField1.verticalCentertext: qsTr("第一个字节:")font.pointSize: 11font.bold: truecolor: "#B7FF4A"}QGCTextField {id: protectTextField1width: parent.width - parent.spacing - tipsLabel.widthheight: tipsLabel.implicitHeight * 1.5text: "1"inputMethodHints: Qt.ImhFormattedNumbersOnlyfocus: trueonEditingFinished: {if(text > 256) {text = 256mainWindow.showMessageDialog(qsTr("警告"), qsTr("输入必须小于等于256"))}else if(text < 0) {text = 0mainWindow.showMessageDialog(qsTr("警告"), qsTr("输入必须大于等于0"))}}}}Row {anchors.left: parent.leftanchors.right: parent.rightQGCLabel {id: tipsLabel2anchors.verticalCenter: protectTextField2.verticalCentertext: qsTr("第二个字节:")font.pointSize: 11font.bold: truecolor: "#B7FF4A"}//保护距离的输入QGCTextField {id: protectTextField2width: parent.width - parent.spacing - tipsLabel2.widthheight: tipsLabel2.implicitHeight * 1.5text: "1"inputMethodHints: Qt.ImhFormattedNumbersOnlyfocus: trueonEditingFinished: {if(text > 256) {text = 256mainWindow.showMessageDialog(qsTr("警告"), qsTr("输入必须小于等于256"))}else if(text < 0) {text = 0mainWindow.showMessageDialog(qsTr("警告"), qsTr("输入必须大于等于0"))}}}}QGCButton {id: mavTestButtonbackRadius: height/2text: qsTr("MAVLINK消息发送测试")enabled: activeVehicleonClicked: {if(activeVehicle)activeVehicle.testSendToVehicle(protectTextField1.text, protectTextField2.text)}}}}
3.1.2 接收显示
接收的关键就是:activeVehicle.rcvByte1 和 activeVehicle.rcvByte2,后续C++中还会提及。
//FlightDisplayView.qml (有些版本是FlyView.qml) 最后Rectangle {anchors.top: sendRect.bottomanchors.topMargin: 20anchors.horizontalCenter: parent.horizontalCenterheight: colSendRect.height * 1.2width: colSendRect.width * 1.2radius: 2color: "black"Column {id: colSendRectspacing: 4anchors.centerIn: parentQGCLabel {anchors.horizontalCenter: parent.horizontalCentertext: "Mavlink 接收测试!"font.pointSize: 12font.bold: truecolor: "red"}Row {id: row1anchors.horizontalCenter: parent.horizontalCenterheight: label1.heightQGCLabel {id: label1anchors.verticalCenter: parent.verticalCentertext: qsTr("接收的第一个字节:")font.pointSize: 11font.bold: truecolor: "#B7FF4A"}QGCLabel {anchors.verticalCenter: parent.verticalCentertext: activeVehicle ? activeVehicle.rcvByte1 : ""font.pointSize: 11font.bold: truecolor: "#B7FF4A"}}Row {anchors.left: row1.leftheight: label2.heightQGCLabel {id: label2anchors.verticalCenter: parent.verticalCentertext: qsTr("接收的第二个字节:")font.pointSize: 11font.bold: truecolor: "#B7FF4A"}QGCLabel {anchors.verticalCenter: parent.verticalCentertext: activeVehicle ? activeVehicle.rcvByte2 : ""font.pointSize: 11font.bold: truecolor: "#B7FF4A"}}}}
3.2 C++后端
使用QGC与MockLink的通讯可以模拟QGC地面站与PX4/APM飞控的通讯,来验证QGC地面站是否编写有问题,再与飞控对接这样能确保地面站是没问题的。再提醒下,MockLink和QGC本身用的是同一套mavlink,所以检验位肯定正确,如不正确,请看前文的分析。
以下代码配合 QGC_CCH地面站 饮用更佳
3.2.1 QGC发送
上述QML中发送的核心就是:
activeVehicle.testSendToVehicle(protectTextField1.text, protectTextField2.text)
protectTextField1.text, protectTextField2.text 为两个文本框中数据
QGC中发送函数:
//Vehicle.cc
void Vehicle::testSendToVehicle(quint8 byte1, quint8 byte2)
{mavlink_message_t msg;mavlink_csdn_test_t csdn_test_t;//用户数据填充到结构体中csdn_test_t.byte1 = byte1;csdn_test_t.byte2 = byte2;qDebug() << "csdn_test_t.byte1" << csdn_test_t.byte1; //QGC send cmd to xxxqDebug() << "csdn_test_t.byte2" << csdn_test_t.byte2; //QGC send cmd to xxxmavlink_msg_csdn_test_encode_chan(_mavlink->getSystemId(),_mavlink->getComponentId(),priorityLink()->mavlinkChannel(),&msg,&csdn_test_t);sendMessageOnLink(priorityLink(), msg);//有些版本可用以下方式发送//sendMessageOnLinkThreadSafe(priorityLink(), msg);
}
Vehicle.h中声明:
public:
...
Q_INVOKABLE void testSendToVehicle(quint8 byte1, quint8 byte2);
3.2.2 MockLink接收
MockLink接收函数:
//MockLink.cc
void MockLink::_handleCSDNTest(const mavlink_message_t& msg)
{mavlink_csdn_test_t csdn_test_t;mavlink_msg_csdn_test_decode(&msg, &csdn_test_t);qDebug() << "[MockLink] Rcv byte1: " << csdn_test_t.byte1;qDebug() << "[MockLink] Rcv byte2: " << csdn_test_t.byte2;
}
调用MockLink接收函数:
//MockLink.cc
void MockLink::_handleIncomingMavlinkBytes(const uint8_t* bytes, int cBytes)
{//最后加入:case MAVLINK_MSG_ID_CSDN_TEST:_handleCSDNTest(msg);break;
}
接收函数声明:
//MockLink.h
class MockLink : public LinkInterface {...
private:
...void _handleCSDNTest(const mavlink_message_t& msg);
}
3.2.3 MockLink发送
发送两个字节数据的声明:
//MockLink.h
class MockLink : public LinkInterface {...
private:
...void _sendCSDNTest(void);//发送的两个数据uint8_t _testByte1;uint8_t _testByte2;}
数据初始化:
//MockLink.cc
MockLink::MockLink(SharedLinkConfigurationPointer& config) {...//初始化列表最后添加, _testByte1 (0), _testByte2 (0)
}
发送函数:
void MockLink::_sendCSDNTest(void)
{mavlink_message_t msg;//发送的两个数据一个加,一个减_testByte1++;_testByte2--;mavlink_msg_csdn_test_pack_chan(_vehicleSystemId,_vehicleComponentId,_mavlinkChannel,&msg,_testByte1, // MAV_TYPE_testByte2 // MAV_AUTOPILOT);respondWithMavlinkMessage(msg);
}
模拟发送需要借助定时器,以下为1HZ发送的:
// MockLink.cc
void MockLink::_run1HzTasks(void)
{..._sendVibration();_sendSysStatus();_sendADSBVehicles();//[修改]_sendCSDNTest();...
}
3.2.4 QGC接收
QGC中接收函数:
void Vehicle::_handleCSDNTestRcv(mavlink_message_t& message)
{mavlink_csdn_test_t csdn_test_t;mavlink_msg_csdn_test_decode(&message, &csdn_test_t);//赋值_rcvByte1 = csdn_test_t.byte1;_rcvByte2 = csdn_test_t.byte2;//触发信号,QML前端中接收,可搜 activeVehicle.rcvByte1emit rcvByte1Changed(_rcvByte1);emit rcvByte2Changed(_rcvByte2);// qDebug() << "[Vehicle] Rcv RcvByte1:" << _rcvByte1;
// qDebug() << "[Vehicle] Rcv RcvByte2:" << _rcvByte2;
}
调用接收函数:
void Vehicle::_mavlinkMessageReceived(LinkInterface* link, mavlink_message_t message) {...case MAVLINK_MSG_ID_WIND:_handleWind(message);break;//[修改]case MAVLINK_MSG_ID_CSDN_TEST:_handleCSDNTestRcv(message);break;}
变量初始化:
Vehicle::Vehicle(...): FactGroup(_vehicleUIUpdateRateMSecs, ":/json/Vehicle/VehicleFact.json")..., _gitHash(versionNotSetValue), _uid(0)//[修改], _rcvByte1(0), _rcvByte2(0)
{}
变量和函数声明:
class Vehicle : public FactGroup
{Q_OBJECT
public:...Q_PROPERTY(quint8 rcvByte1 READ rcvByte1 NOTIFY rcvByte1Changed)Q_PROPERTY(quint8 rcvByte2 READ rcvByte2 NOTIFY rcvByte2Changed)...quint8 rcvByte1 () { return _rcvByte1; }quint8 rcvByte2 () { return _rcvByte2; }signals:...void rcvByte1Changed (quint8 rcvByte1);void rcvByte2Changed (quint8 rcvByte2);...
private:void _handleCSDNTestRcv(mavlink_message_t& message);...quint8 _rcvByte1;quint8 _rcvByte2;...
}
看都看完了,如果对你有任何帮助,请不要吝啬你的一键三连哦,感谢各位~
关于QGC地面站其它文章请点击这里: QGC地面站
本文源码地址: QGC_CCH地面站
QGC地面站Mavlink生成和MockLink模拟收发通讯相关推荐
- QGC地面站二次开发(二)QGC 界面自定义和修改
目录 1.QGC 地面站的显示机制 1.1.C++类注册为 qml 可访问类型 1.2.注册属性或者方法 1.1.1. 属性声明 1.1.2.方法声明 2.QGC 地面站界面初步修改 3.QGC 地面 ...
- QGC地面站中视频流配置及gstreamer安装
QGC地面站中视频流配置及gstreamer安装 1. QGC地面站各版本视频流测试 2. 安装gstreamer 3. 修改路径 4. 地面站配置 5. Android版本安装 关于QGC地面站其它 ...
- QGC地面站二次开发(一)地面站介绍以及软件框架(1)地面站使用介绍和接口介绍
目录 QGC界面显示框架 页面介绍 飞行页面 Application Setting页面 General Offline map 连接 Mock Link Vehicle Setup页面 Plan页面 ...
- apm软件仿真+QGC地面站 环境搭建
本教程使用场景:apm软件仿真运行于虚拟机 ubuntu环境.qgc地面站位于windows 系统.两个环境在同一台电脑上. 一.apm仿真环境搭建 1.安装vm虚拟机及ubuntu 18. 2.ub ...
- QGC地面站小白安装与简单实用
QGC二次开发 电脑:联想拯救者Lenovo R720,在电脑上安装虚拟机-->在虚拟机中安装UBuntu系统-->在Ubuntu中安装QGC以及Qt编译器. 1 安装VMware Wor ...
- PX4 QGC地面站自定义参数
QGC地面站自定义参数(新手操作)v1.8.2 QGC以往版本下载地址 htps://github.com/mavlink/qgroundcontrol/tags 最终的添加结果如下: 具体步骤如下: ...
- 【测试】QGC地面站开发课程完结篇--一站多机控制测试说明
阿木实验室去年推出的QGC地面站开发实战课程,随着地面站控制多架飞机的测试的成功,课程全部完结,以下是我们户外测试最终版地面站的测试视频: 视频地址: https://v.qq.com/x/page/ ...
- Ubuntu18.04下px4+MAVROSM+QGC地面站安装教程及避坑指南
下面安装建立在已经安装好了ROS的基础,未安装ROS的请先按照下面教程安装ROSROS 安装教程 目录 一.安装px4_toolchain 二.编译PX4固件 三.mavros and mavlink ...
- 树莓派ubuntu mate系统连接PX4并通过UDP连接至QGC地面站
前提条件: 树莓派安装了ubuntu mate 20.04系统 ubuntu mate已经安装好ros(这里是noetic版本)系统,Mavros 安装好QGC地面站的PC USB数据线(确定能传输数 ...
最新文章
- Oracle数据库日常维护知识总结
- PHP5 VC9、VC6、Thread Safe、Non Thread Safe各个版本区别
- easymock快速入门
- golang经典书籍--Go语言圣经
- javascript自定义事件原理
- android开发微博搜索,一款帮助用户自动提取微博热搜、知乎热榜、百度实时热点条目中与特定领域...
- flink中datastream和dataset各自print()的异同
- python asyncio 并发编程_asyncio并发编程
- django-命名空间与反向解析-模板反向解析-视图反向解析
- 【IT】关于Code打卡机时遇到的问题及解决
- 手机分辨率大小自适应功能
- 背阔肌(04):杠铃俯身划船
- linux键盘控制鼠标软件下载,手机控制电脑软件(Mouse Server)
- 前端面试题总结(js、html、小程序、React、算法、vue 、全栈热门视频资源)
- Android应用权限大全(Manifest.permission)
- IDEA如何简单的设置中文
- caffe安装详细完整过程(Ubuntu16.04、Ubuntu18.04系统)
- sqrt函数,对数进行开根号
- linux pam mysql,Linux-PAM PAM-MySQL的总结
- 求根节点到叶节点数字之和(C语言)
热门文章
- 外链自动转内链html,一个简单的HTML实现外链转内链
- 【EDA设计笔记】EDA-USB_SPI_FLASH-设计与实现
- oracle crs 4639,处理CRS-4639和CRS-4000错误
- httpclient4.5 结合 讯代理 实现IP代理
- 智能电表专用DC-DC芯片
- 华语乐坛到底姓什么?------酷狗篇
- java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承, 请说出他们分别是哪些类?
- 将cooledit作为一个音频信号发生器(http://www.zsjys.net/JYJY/ShowArticle.asp?ArticleID=64)
- python缩写月份单词_Python替换月份为英文缩写的实现方法
- 旗杆的安装方法和流程