机器人地面站-[QGroundControl源码解析]-[10]-[Comm]

2023-11-10

前言

因为项目进度排期较紧,并且觉得之前在代码中添加注释的方法有些生硬用处不大,所以从本片开始,着重介绍类的内容和功能,只对重要代码进行粘贴。

Comm文件夹下有众多的类

一.LinkConfiguration

这个类处理链路的配置,查看属性可以看到有名称,具体的链路接口类,链路类型,是否动态的,是否自动连接的等等。

    Q_PROPERTY(QString          name                READ name           WRITE setName           NOTIFY nameChanged)
    Q_PROPERTY(LinkInterface*   link                READ link                                   NOTIFY linkChanged)
    Q_PROPERTY(LinkType         linkType            READ type                                   CONSTANT)
    Q_PROPERTY(bool             dynamic             READ isDynamic      WRITE setDynamic        NOTIFY dynamicChanged)
    Q_PROPERTY(bool             autoConnect         READ isAutoConnect  WRITE setAutoConnect    NOTIFY autoConnectChanged)
    Q_PROPERTY(QString          settingsURL         READ settingsURL                            CONSTANT)
    Q_PROPERTY(QString          settingsTitle       READ settingsTitle                          CONSTANT)
    Q_PROPERTY(bool             highLatency         READ isHighLatency  WRITE setHighLatency    NOTIFY highLatencyChanged)

 以下是qgc支持的链路类型

    ///  The link types supported by QGC QGC支持的链路类型
    ///  Any changes here MUST be reflected in LinkManager::linkTypeStrings() 这里的任何更改都必须反映在LinkManager::linkTypeStrings()中
    enum LinkType {
#ifndef NO_SERIAL_LINK
        TypeSerial,     ///< Serial Link 串口
#endif
        TypeUdp,        ///< UDP Link
        TypeTcp,        ///< TCP Link
#ifdef QGC_ENABLE_BLUETOOTH
        TypeBluetooth,  ///< Bluetooth Link 蓝牙
#endif
#ifdef QT_DEBUG
        TypeMock,       ///< Mock Link for Unitesting
#endif
        TypeLogReplay,
        TypeLast        // Last type value (type >= TypeLast == invalid)
    };
    Q_ENUM(LinkType)

其中类中有一个创建链路配置的工厂方法

/*!
  Configuration Factory
  @return A new instance of the given type
*/
LinkConfiguration* LinkConfiguration::createSettings(int type, const QString& name)
{
    LinkConfiguration* config = nullptr;
    switch(type) {
#ifndef NO_SERIAL_LINK
        case LinkConfiguration::TypeSerial:
            config = new SerialConfiguration(name);
            break;
#endif
        case LinkConfiguration::TypeUdp:
            config = new UDPConfiguration(name);
            break;
        case LinkConfiguration::TypeTcp:
            config = new TCPConfiguration(name);
            break;
#ifdef QGC_ENABLE_BLUETOOTH
    case LinkConfiguration::TypeBluetooth:
        config = new BluetoothConfiguration(name);
        break;
#endif
        case LinkConfiguration::TypeLogReplay:
            config = new LogReplayLinkConfiguration(name);
            break;
#ifdef QT_DEBUG
        case LinkConfiguration::TypeMock:
            config = new MockConfiguration(name);
            break;
#endif
    }
    return config;
}

根据不同的链路类型创建不同的链路配置类。

二.LinkInterface

该类定义用于与地面站应用程序通信的所有链接的接口。继承自thread,是一个用于通信的类。

三.Link Manager

该类负责组织物理链路。它可以管理任意链接,并负责连接它们,以及分配正确的协议实例将链接数据传输到应用程序。

四.LogReplayLink

该类的文件中还定义了一个类叫做LogReplayLinkConfiguration,继承自上边的LinkConfiguration,是针对本协议的定义的链接配置类。

第二个类就是LogReplayLink,他继承自上边的LinkInterface,用于专门处理logreplay出的信息。

五.MAVLinkProtocol

此类处理所有设备的mavlink协议相关的操作

/****************************************************************************
 *
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#pragma once

#include <QObject>
#include <QMutex>
#include <QString>
#include <QTimer>
#include <QFile>
#include <QMap>
#include <QByteArray>
#include <QLoggingCategory>

#include "LinkInterface.h"
#include "QGCMAVLink.h"
#include "QGC.h"
#include "QGCTemporaryFile.h"
#include "QGCToolbox.h"

class LinkManager;
class MultiVehicleManager;
class QGCApplication;

Q_DECLARE_LOGGING_CATEGORY(MAVLinkProtocolLog)

/**
 * @brief MAVLink micro air vehicle protocol reference implementation.
 * MAVLink微型飞行器协议参考实现。
 * MAVLink is a generic communication protocol for micro air vehicles.MAVLink是一种用于微型飞行器的通用通信协议。
 * for more information, please see the official website: https://mavlink.io更多信息请访问官方网站:https://mavlink.io
 **/
class MAVLinkProtocol : public QGCTool
{
    Q_OBJECT

public:
    MAVLinkProtocol(QGCApplication* app, QGCToolbox* toolbox);
    ~MAVLinkProtocol();

    /** @brief Get the human-friendly name of this protocol 获取此协议的人类友好的名称 */
    QString getName();
    /** @brief Get the system id of this application 获取此应用程序的系统id*/
    int getSystemId() const;
    /** @brief Get the component id of this application 获取此应用程序的组件id*/
    int getComponentId();

    /** @brief Get protocol version check state 获取协议版本检查状态*/
    bool versionCheckEnabled() const {
        return m_enable_version_check;
    }
    /** @brief Get the protocol version 获取协议版本*/
    int getVersion() {
        return MAVLINK_VERSION;
    }
    /** @brief Get the currently configured protocol version 获取当前配置的协议版本*/
    unsigned getCurrentVersion() const{
        return _current_version;
    }
    /**
     * Reset the counters for all metadata for this link.
     * 重置此链接的所有元数据的计数器
     */
    virtual void resetMetadataForLink(LinkInterface *link);

    /// Suspend/Restart logging during replay.在重播期间暂停/重新启动日志记录
    void suspendLogForReplay(bool suspend);

    /// Set protocol version 设置协议版本
    void setVersion(unsigned version);

    // Override from QGCTool
    virtual void setToolbox(QGCToolbox *toolbox);

public slots:
    /** @brief Receive bytes from a communication interface 从通信接口接收字节*/
    void receiveBytes(LinkInterface* link, QByteArray b);

    /** @brief Log bytes sent from a communication interface 从通信接口发送的日志字节*/
    void logSentBytes(LinkInterface* link, QByteArray b);

    /** @brief Set the system id of this application 设置此应用程序的系统id */
    void setSystemId(int id);

    /** @brief Enable / disable version check 启用/禁用版本检查*/
    void enableVersionCheck(bool enabled);

    /** @brief Load protocol settings 加载协议设置*/
    void loadSettings();
    /** @brief Store protocol settings 存储协议设置*/
    void storeSettings();

    /// @brief Deletes any log files which are in the temp directory 删除临时目录中的所有日志文件
    static void deleteTempLogFiles(void);

    /// Checks for lost log files 检查丢失的日志文件
    void checkForLostLogFiles(void);

protected:
    bool        m_enable_version_check;                         ///< Enable checking of version match of MAV and QGC 开启MAV和QGC版本匹配检查
    uint8_t     lastIndex[256][256];                            ///< Store the last received sequence ID for each system/componenet pair 为每个系统/组件对存储最后接收到的序列ID
    uint8_t     firstMessage[256][256];                         ///< First message flag 第一个消息标志
    uint64_t    totalReceiveCounter[MAVLINK_COMM_NUM_BUFFERS];  ///< The total number of successfully received messages 成功接收的消息总数
    uint64_t    totalLossCounter[MAVLINK_COMM_NUM_BUFFERS];     ///< Total messages lost during transmission. 传输过程中丢失的消息总数。
    float       runningLossPercent[MAVLINK_COMM_NUM_BUFFERS];   ///< Loss rate 丢失率

    mavlink_message_t _message; //消息
    mavlink_status_t _status; //消息状态

    bool        versionMismatchIgnore;
    int         systemId;
    unsigned    _current_version;
    int         _radio_version_mismatch_count;

signals:
    /// Heartbeat received on link 链路上收到心跳
    void vehicleHeartbeatInfo(LinkInterface* link, int vehicleId, int componentId, int vehicleFirmwareType, int vehicleType);

    /** @brief Message received and directly copied via signal 接收到的信息通过信号直接复制*/
    void messageReceived(LinkInterface* link, mavlink_message_t message);
    /** @brief Emitted if version check is enabled / disabled 如果启用/禁用版本检查,则触发*/
    void versionCheckChanged(bool enabled);
    /** @brief Emitted if a message from the protocol should reach the user 当来自协议的消息到达用户时发出*/
    void protocolStatusMessage(const QString& title, const QString& message);
    /** @brief Emitted if a new system ID was set 如果设置了新的系统ID,则触发*/
    void systemIdChanged(int systemId);

    void mavlinkMessageStatus(int uasId, uint64_t totalSent, uint64_t totalReceived, uint64_t totalLoss, float lossPercent);

    /**
     * @brief Emitted if a new radio status packet received 当接收到一个新的无线电状态包时发出
     *
     * @param rxerrors receive errors
     * @param fixed count of error corrected packets
     * @param rssi local signal strength in dBm
     * @param remrssi remote signal strength in dBm
     * @param txbuf how full the tx buffer is as a percentage
     * @param noise background noise level
     * @param remnoise remote background noise level
     */
    void radioStatusChanged(LinkInterface* link, unsigned rxerrors, unsigned fixed, int rssi, int remrssi,
    unsigned txbuf, unsigned noise, unsigned remnoise);

    /// Emitted when a temporary telemetry log file is ready for saving 当临时遥测日志文件准备好保存时发出
    void saveTelemetryLog(QString tempLogfile);

    /// Emitted when a telemetry log is started to save. 当遥测日志开始保存时发出
    void checkTelemetrySavePath(void);

private slots:
    void _vehicleCountChanged(void);

private:
    bool _closeLogFile(void);
    void _startLogging(void);
    void _stopLogging(void);

    bool _logSuspendError;      ///< true: Logging suspended due to error 日志记录由于错误而挂起
    bool _logSuspendReplay;     ///< true: Logging suspended due to replay 由于重放,日志暂停
    bool _vehicleWasArmed;      ///< true: Vehicle was armed during log sequence 在日志序列中,车辆被武装起来

    QGCTemporaryFile    _tempLogFile;            ///< File to log to
    static const char*  _tempLogFileTemplate;    ///< Template for temporary log file
    static const char*  _logFileExtension;       ///< Extension for log files

    LinkManager*            _linkMgr;
    MultiVehicleManager*    _multiVehicleManager;
};

总结:

后面的文件类似都是协议管理消息的收发,因此不再赘述。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器人地面站-[QGroundControl源码解析]-[10]-[Comm] 的相关文章

  • binary_log_types.h:没有这样的文件或目录

    我正在编译一个小型 mysql C 项目并且 遇到以下错误 C Program Files x86 MySQL MySQL Server 5 7 include mysql com h 22 30 fatal error binary lo
  • 动态选择和更新 LINQ 结果集中的列值

    我有一个场景 其中存在 LINQ 结果集 我使用了以下查询 var stockDetails from d in db BloodBanks where d bbUserName Session username ToString sele
  • 如何通知父线程所有子线程都已终止?

    我有一个控制台应用程序正在移植到 WPF 该应用程序有 3 个工作线程 在将一些输出结果打印到屏幕上之前 这些线程都连接到主线程 我的理解是 如果我尝试在 WPF 应用程序中执行相同的操作 GUI 将被阻止并且不会响应用户 那么如何通知父线
  • 为什么这个 oracle 批量插入不起作用?

    我正在尝试将一些数据批量插入到 oracle 数据库中 我按照文档中的示例进行操作 this DataBaseAccess new OracleConnection connString var dataAdapter new Oracle
  • WPF Dispatchertimer 延迟反应/冻结

    在我的 WPF 应用程序中 我使用 3 个不同的 DispatcherTimers 一种是用于显示当前时间 一种是每 5 秒运行一次数据库查询 第三个每 1 秒刷新一次自定义按钮的值 当我的程序运行时 有很多延迟 冻结 例如 时间开始正确计
  • 将 void *user_data 转换为对象

    我该如何投射void something到标准 C 中的对象 具体来说我想投void userdata to std map
  • 计算复杂数组的abs()值的最快方法

    我想计算 C 或 C 中复杂数组元素的绝对值 最简单的方法是 for int i 0 i lt N i b i cabs a i 但对于大向量来说 速度会很慢 有没有办法加快速度 例如使用并行化 语言可以是 C 或 C 鉴于所有循环迭代都是
  • 为什么将 char 传递给函数会改变它在 c 中的值?

    我目前正在关注本作业簿 http www cs bham ac uk exr lectures opsys 10 11 lectures os dev pdf关于构建操作系统 我的目的是写一个64位内核 我已经在文本模式下加载 内核 代码并
  • boost::asio::io_service 是否保留处理程序的顺序?

    Does boost asio io service http www boost org doc libs release doc html boost asio reference io service html保证处理程序的调用顺序与
  • 我要恢复我的记忆!我怎样才能真正处理一个控件?

    我正在制作一个应用程序 它创建大量的窗口控件 按钮和标签等 它们都是通过函数动态生成的 我遇到的问题是 当我删除控件并处置它们时 它们不会从内存中删除 void loadALoadOfStuff while tabControlToClea
  • 试图使用加密来混淆我的项目打破了它

    我试图尝试不同的混淆选项 为了做到这一点 我首先尝试了加密货币 以下是我遵循的步骤 打开加密向导并选择一些选项 选择我的解决方案文件 完成向导后 我看到有些 Dll 被很好地混淆了 但我的项目现在无法构建 我注意到的两件事是 我的文件夹中有
  • EF Core 一对多关系列表返回 null

    我正在尝试学习如何在 EF Core 中正确利用 DbContext 我有一个团队课程 public class Team public int ID get set public string Name get set public bo
  • 如何从Web JavaScript应用程序获取桌面C#程序中的变量

    我遇到一个问题 有两个应用程序 一种是 C 中的桌面应用程序 另一种是 javascript 中的 Web 应用程序 运行桌面应用程序中的一些变量或信息需要传输到Web应用程序 有谁知道如何解决这个问题 有人愿意提供更多细节来解决这个问题吗
  • 为什么这个单独的定义会导致错误?

    挑战 我有这段代码无法编译 你能找出问题所在吗 有一次让我很头疼 header namespace values extern std string address extern int port cpp file std string v
  • 执行存储过程时 ExecuteNonQuery() 返回 -1

    我正在尝试在 Visual Studio 中执行存储过程 下面给出 CREATE PROCEDURE dbo addStudent stuName varchar 50 address varchar 100 tel varchar 15
  • QListWidget 拖放项目从 Symbian 列表中消失

    我在实现带有可通过拖放重新排序的自定义项的 QListWidget 时遇到问题 问题是当我在某个项目上快速双击 非常短的拖放 时 该项目有时会从 QListWidget 中消失 这是我的小部件的构造函数 ListPopisiDragDrop
  • 类型别名和不完整类型

    我可能已经超出了解决这个本应简单的问题的范围 我在这里开始这个问题 在编译时获取基类的类型 https stackoverflow com questions 17735852 getting type of a base class at
  • 使用 _Alignas 进行结构成员对齐

    我想知道以下问题 是新的吗 Alignas结盟 C11 中的说明符适用于结构成员吗 我一直假设这么多 但彻底阅读了 N1570 公开草案似乎表明对齐说明符不能 出现在一个说明符限定符列表 这就是我所期望的 如果得到支持的话 我已经读过几遍语
  • 使用非字符串作为字符串(而不是自动使用 ToString)时如何显示错误?

    建议的重复确实是一个类似的问题 然而 答案只涵盖一种选择 禁用 ToString 本身 还有其他可能的解决方案 例如让 Visual Studio 警告我 或者不调用 ToString 仔细阅读那里的答案 他认为is调用 只是解释说没有办法
  • C#:如何处理乱序 TCP 数据包?

    请有人解释一下如何处理乱序数据包 我使用原始套接字来捕获数据包 并在数据包到来时解析它们 但其中一些数据包的顺序错误 例如 ID 标志 16390 PSH ACK 16535 PSH ACK 16638 确认 16640 PSH ACK 1

随机推荐

  • C++的++

    include stdafx h int main int x y m n x 0 x x printf x 0 x x的值是 d n x x 0 y 0 y x printf x 0 y 0 y x的值是 d n y x 0 x x pr
  • Zotero使用指南02:配合Word

    转载Zotero使用指南02 配合Word Zotero是一款广受好评的文献管理软件 其具有四大优点 首先是开源免费 源代码托管在Github平台 其次 其软件界面基于浏览器内核 支持Windows MacOS Linux多种操作系统 此外
  • Threejs基础代码段(二)Tweenjs补间动画

    一 Tweenjs是什么 tween js是一款可生成平滑动画效果的js动画库 只需要告诉tween你想修改什么值 以及动画结束时它的最终值是什么 动画花费多少时间等信息 tween引擎就可以计算从开始动画点到结束动画点之间值 来产生平滑的
  • sqlmap tamper脚本_注入工具 -- sqlmap(注入参数)

    任何关系走到最后 不过相识一场 有心者有所累 无心者无所谓 情出自愿 事过无悔 不负遇见 不谈亏欠 一 指定数据库类型 dbms http 192 168 1 121 sqli Less 1 id 1 name 2 dbms mysql d
  • 前后端部署具体详解(Go+Vue+Nginx)

    与你相识 博主介绍 本人是普通大学生一枚 每天钻研计算机技能 CSDN主要分享一些技术内容 因我常常去寻找资料 不经常能找到合适的 精品的 全面的内容 导致我花费了大量的时间 所以会将摸索的内容全面细致记录下来 另外 我更多关于管理 生活的
  • AcWing 172. 立体推箱子 BFS+状态表示

    题 代码参考了书上的 判断是否合法的函数写的好精简 这题理解了 就能很好的理解BFS 状态表示的理解 lie 0 立着 lie 1 横着躺着 lie 2 竖着躺着 j 0123分别表示左右上下 nextx i j 代表lie i时x往j方向
  • C++进阶:继承

    继承 面向对象的三大特性 封装 继承 多态 继承在实际中用的也不是太多 但必须能熟练使用 1 继承的概念 继承机制是面向对象思想中复用代码的一种手段 它能够在原有类的特性的基础上进行扩展 由此产生新的类 称为派生类 原有类称作基类 继承体现
  • mybatis 中的<![CDATA[ ]]>用法及说明

    作用 在mybatis ibatis等书写SQL的xml中比较常见 是一种XML语法 他的作用是 可以忽略xml的转义 在该标签中的语句和字符原本是什么样的 在拼接成SQL后还是什么样的 使用 select from user where
  • 如何自定义设置虚拟机的的IP地址

    如何自定义设置虚拟机的的IP地址 之前我们装虚拟机的时候是选择使用DHCP服务器帮我们自动分配 现在我们想固定一个IP给虚拟机 方便以后使用 1 首先我们需要知道虚拟机可用的网段是哪一段 在VMware的主页点击编辑 然后点击里面的虚拟网络
  • 【区块链】(四)之常见的加密算法

    我们经常在谍战片里看到 我军传递情报用电报发送 但敌人也可以截取电报 这就需要对电报发送的内容进行加密 当时常用的加密方式是通过一段密文 对情报进行加密 比如说是当天的日报 这种属于对称加密 差不多是DES加密算法 这里简单介绍几种 主要介
  • 对话生成模型中的条件变分自编码器(CVAE)

    废话不多说直接上模型 这是一个非常经典的对话生成模型 叫做HRED Hierarchical RNN Enconder Decoder 思路很简单 就是用一个RNN来建模前 j 1 j 1 j 1句话 再用一个RNN来建模第 j j j句话
  • 实验3:C++多态编程——实验任务五

    实验任务五 人 学生和教师 设计一个类people 有保护数据成员 age 年龄 整型 name 姓名 string 行为成员 两个构造函数 一个默认 另一个有参数 默认析构函数 void setValue int m string str
  • (七)nodejs写http服务

    1 加载http模块 var http require http 2 创建http服务对象 var server http createServer 3 监听request请求事件 server on request function re
  • c语言作业:一帮一

    一帮一学习小组 是中小学中常见的学习组织方式 老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组 本题就请你编写程序帮助老师自动完成这个分配工作 即在得到全班学生的排名后 在当前尚未分组的学生中 将名次最靠前的学生与名次最靠后的异性学生分
  • Java课题笔记~ SpringMVC的四种跳转方式

    默认的跳转是请求转发 直接跳转到jsp页面展示 还可以使用框架提供的关键字redirect 进行一个重定向操作 包括重定向页面和重定向action 使用框架提供的关键字forward 进行服务器内部转发操作 包括转发页面和转发action
  • opencv(C++) 视频处理,通过三通道像素值平均 将视频分辨率缩小为原来的一半

    项目要求 将一个 1920 1080 的视频压缩为 960 540 的视频 帧率不变 将每个 2 2 相邻像素点的像素值求平均 变成一个新的像素点 即 2 2 的平均池化 程序中很多代码都来源于 OpenCv 4 快速入门 方法一 分别取出
  • vs2019中 当前上下文中不存在名称“ViewBag”和不存在“model”的解决思路

    如果你已经改了Web config的相关配置 还是没有解决这个问题 你可以尝试保存并退出当前的vs 然后重新启动你的项目 本人通过许多途径找解决的办法 结果还是没有解决 最后还是通过重新启动项目解决的
  • 金融和大模型的“两层皮”问题

    几年前 我采访一位产业专家 他提到了一个高科技到产业落地的主要困惑 两层皮 一些特别牛的技术成果在论文上发表了 这是一层皮 企业的技术人员 将这些成果产品化 商品化的时候 可能出于工程化的原因 会做一些简化 这是另一层皮 两层皮之间 是有g
  • mvc html类的作用域,SpringMVC使用session保存数据以及applicationContext作用域

    使用session保存数据 session是一次会话 里面可以有多次请求 1 HttpSession session 1 1 index jsp Hello World 1 2 success jsp Created by IntelliJ
  • 机器人地面站-[QGroundControl源码解析]-[10]-[Comm]

    前言 因为项目进度排期较紧 并且觉得之前在代码中添加注释的方法有些生硬用处不大 所以从本片开始 着重介绍类的内容和功能 只对重要代码进行粘贴 Comm文件夹下有众多的类 一 LinkConfiguration 这个类处理链路的配置 查看属性