QGC关于通信连接建立部分的程序比较复杂,但感觉写的很厉害,通过读代码把自己的一点理解记录下来。
收集接收
空地通信管理
空地通信的管理在“应用程序设置->通讯连接”中进行通信连接创建,连接和断开。
通讯连接添加完成后点击“连接”按钮,进行空地通信连接
连接创建过程
“连接”按钮与LinkSetting.qml中的QGCButton绑定,绑定LinkManager::createConnectedLink(),其中传参为当前连接名称。
创建连接的的实际程序在LinkManager::createConnectedLink(SharedLinkConfigurationPointer& config, bool isPX4Flow)中,其中传参为通讯的参数和isPx4Flow。创建LinkInterface类指针,通过端口类型创建不同的实例(串口、TCP、UDP、LogReplay、Mock),本文只分析UDP创建过程。
pLink = new UDPLink(config);
创建UDP连接
在UDPLink类初始化中通过新建一个线程运行数据接收。
在线程运行中首先判断Socket是否连接,如果已经连接则运行线程。其中exec()作用是开启一个循环,执行一个事件,即运行该线程。
在_hardwareConnect()中主要是判断UDP Socket是否已将创建完成。如果创建完成则_connectState为true,则使用信号槽将QUdpSocket::readyRead, this与UDPLink::readBytes进行连接,当有数据更新通过readyRead触发readBytes函数。
数据接收
数据接收首先通过readBytes()接收databuffer,收到数据后使用信号bytesReceived()触发数据接收任务。
通过信号槽连接LinkManager::receiveBytes,在receiveBytes中进行数据解析转成mavlink。
通过信号槽,将messageReceive()与Vehicle::_mavlinkMessageReceived()函数进行连接,在_mavlinkMessageReceived中就可以进行mavlink消息分类处理。
以上就实现的下传数据接收和解析工作。
数据上传
地面站通过通讯连接进行数据上传,通过调用Vehicle::sendMessageOnLink(LinkInterface* link, mavlink_message_t message)实现数据上传。
在Vehicle中使用信号槽将Vehicle::_sendMessageOnLinkOnThread和Vehicle::_sendMessageOnLink进行绑定,在_sendMessageOnLink函数中调用通讯连接
link->writeBytesSafe((const char*)buffer, len)实现数据上传。
在LinkInterface.cc中使用信号槽将LinkInterface::_invokeWriteBytes和LinkInterface::_writeBytes绑定触发_writeBytes。
在LinkInterface.h中将_writeBytes函数定义为了虚函数,通过类继承的方式,分别在串口、TCP、UDP类中进行函数实现。
在UDPLink.cc中使用_writeBytes函数实现数据上传。
至此完成了地面站数据上传的功能