fix: 修复启动白屏与地图崩溃问题
- SetUseOpenGL(false): QGLWidget 在当前系统不兼容,改用软件渲染 - ExtensionHost_v2: 添加 contributionRegistry() getter 修复空指针 - main.cpp: 两阶段启动 (show → QTimer::singleShot → initialize) - mainwindow: 分离构造函数与 initialize(),结尾调用 onTabIndexChanged(3) - 修复 Qt DLL 部署:使用 windeployqt 确保运行时库版本匹配
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# PluginSDK — 插件开发工具包(静态库)
|
||||
# 包含:IPlugin、PluginContext、ServiceRegistry、MavLinkService、PluginManifest
|
||||
# PluginSDK � �件��工具包(��库�
|
||||
# 包�:IPlugin�PluginContext�ServiceRegistry�MavLinkService�PluginManifest
|
||||
add_library(PluginSDK STATIC
|
||||
PluginContext.cpp
|
||||
ServiceRegistry.cpp
|
||||
MavLinkService.cpp
|
||||
MavLinkServiceBridge.cpp
|
||||
Logging.cpp
|
||||
${CMAKE_SOURCE_DIR}/App/Plugins/PluginManifest.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include "mavlink_types.h"
|
||||
|
||||
// ============================================================
|
||||
// 服务接口体系(纯虚接口,不继承QObject,避免菱形继承)
|
||||
// 插件通过 ServiceRegistry 发现服务
|
||||
// 服务接口体系(纯虚接口,不继承QObject,避免菱形继承)
|
||||
// 插件通过 ServiceRegistry 发现服务
|
||||
// ============================================================
|
||||
|
||||
class IDataProvider
|
||||
@@ -18,6 +18,10 @@ class IDataProvider
|
||||
public:
|
||||
virtual ~IDataProvider() = default;
|
||||
virtual QString serviceId() const = 0;
|
||||
virtual void requestSystemStatus() = 0;
|
||||
virtual void requestAllParams() = 0;
|
||||
virtual void setUpdateInterval(int ms) = 0;
|
||||
virtual void enableDataStream(bool enabled) = 0;
|
||||
};
|
||||
|
||||
class ILinkProvider
|
||||
@@ -25,6 +29,10 @@ class ILinkProvider
|
||||
public:
|
||||
virtual ~ILinkProvider() = default;
|
||||
virtual QString serviceId() const = 0;
|
||||
virtual void connectToVehicle(const QString &port, int baudRate) = 0;
|
||||
virtual void disconnectFromVehicle() = 0;
|
||||
virtual bool isLinkConnected() const = 0;
|
||||
virtual QStringList availablePorts() const = 0;
|
||||
};
|
||||
|
||||
class ICommandProvider
|
||||
@@ -80,6 +88,9 @@ class ISensorProvider
|
||||
public:
|
||||
virtual ~ISensorProvider() = default;
|
||||
virtual QString serviceId() const = 0;
|
||||
virtual void enableSensorStream(const QString &sensorName, bool enabled) = 0;
|
||||
virtual void requestSensorCalibration() = 0;
|
||||
virtual QVariantMap getSensorHealth() const = 0;
|
||||
};
|
||||
|
||||
class IRCProvider
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "Logging.h"
|
||||
|
||||
// 日志分类定义(每个分类一行,在 .cpp 中定义以遵守 ODR)
|
||||
Q_LOGGING_CATEGORY(gcs_comm, "gcs.comm")
|
||||
Q_LOGGING_CATEGORY(gcs_mavlink, "gcs.mavlink")
|
||||
Q_LOGGING_CATEGORY(gcs_mission, "gcs.mission")
|
||||
Q_LOGGING_CATEGORY(gcs_command, "gcs.command")
|
||||
Q_LOGGING_CATEGORY(gcs_param, "gcs.param")
|
||||
Q_LOGGING_CATEGORY(gcs_vehicle, "gcs.vehicle")
|
||||
Q_LOGGING_CATEGORY(gcs_ui, "gcs.ui")
|
||||
Q_LOGGING_CATEGORY(gcs_map, "gcs.map")
|
||||
Q_LOGGING_CATEGORY(gcs_datalog, "gcs.datalog")
|
||||
Q_LOGGING_CATEGORY(gcs_app, "gcs.app")
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef GCS_LOGGING_H
|
||||
#define GCS_LOGGING_H
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
// ============================================================
|
||||
// GCS 统一日志分类系统
|
||||
//
|
||||
// 替代散落的 qDebug()/qWarning() 裸调用,
|
||||
// 支持运行时通过 QT_LOGGING_RULES 环境变量按模块过滤日志。
|
||||
//
|
||||
// 用法:
|
||||
// qCDebug(gcs_comm) << "Serial port opened:" << portName;
|
||||
// qCWarning(gcs_mavlink) << "Checksum mismatch, msgid:" << msg.msgid;
|
||||
//
|
||||
// 运行时控制示例:
|
||||
// QT_LOGGING_RULES="gcs.comm.debug=true;gcs.mavlink.info=true"
|
||||
// ============================================================
|
||||
|
||||
// 通讯层:串口/UDP/组播连接、收发统计
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_comm)
|
||||
|
||||
// MAVLink 协议层:解析、编解码、帧校验
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_mavlink)
|
||||
|
||||
// 任务/航线:上传、下载、航点处理
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_mission)
|
||||
|
||||
// 指令:指令下发、ACK 处理
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_command)
|
||||
|
||||
// 参数:参数读写、同步
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_param)
|
||||
|
||||
// 飞控数据:传感器、姿态、GPS 数据
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_vehicle)
|
||||
|
||||
// UI 界面:面板切换、用户操作
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_ui)
|
||||
|
||||
// 地图:瓦片加载、航点编辑
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_map)
|
||||
|
||||
// 数据记录:CSV/TLOG 文件 I/O
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_datalog)
|
||||
|
||||
// 通用/启动/配置
|
||||
Q_DECLARE_LOGGING_CATEGORY(gcs_app)
|
||||
|
||||
#endif // GCS_LOGGING_H
|
||||
+212
-144
@@ -1,144 +1,212 @@
|
||||
#include "MavLinkServiceBridge.h"
|
||||
#include "dlink.h"
|
||||
#include "mavlinknode.h"
|
||||
|
||||
MavLinkServiceBridge::MavLinkServiceBridge(DLink *dlink, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_dlink(dlink)
|
||||
{
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::wireFromMavLinkNode()
|
||||
{
|
||||
if (!m_dlink || !m_dlink->mavlinknode) return;
|
||||
|
||||
MavLinkNode *node = m_dlink->mavlinknode;
|
||||
|
||||
connect(node, &MavLinkNode::CommuniationLost, this, &MavLinkServiceBridge::commLost);
|
||||
connect(node, &MavLinkNode::beep, this, &MavLinkServiceBridge::beepRequested);
|
||||
connect(node, &MavLinkNode::updateDlink, this, &MavLinkServiceBridge::dlinkStatsChanged);
|
||||
|
||||
if (node->Commander) {
|
||||
connect(node->Commander, &commandprocess::commandAccepted,
|
||||
this, &MavLinkServiceBridge::commandResult);
|
||||
}
|
||||
|
||||
if (node->Mission) {
|
||||
connect(node->Mission, &MissionProcess::clearWaypoint,
|
||||
this, &MavLinkServiceBridge::waypointCleared);
|
||||
connect(node->Mission, &MissionProcess::sendItemOK,
|
||||
this, &MavLinkServiceBridge::waypointSendOk);
|
||||
connect(node->Mission, &MissionProcess::currentPoint,
|
||||
this, &MavLinkServiceBridge::waypointCurrent);
|
||||
}
|
||||
connect(node, &MavLinkNode::addVehicles, this, &MavLinkServiceBridge::vehicleListChanged);
|
||||
|
||||
if (node->replay) {
|
||||
connect(node->replay, &Replay::currentPercentage,
|
||||
this, &MavLinkServiceBridge::replayProgressChanged);
|
||||
connect(node->replay, &Replay::replayComplete,
|
||||
this, &MavLinkServiceBridge::replayEnded);
|
||||
}
|
||||
if (node->Terminal) {
|
||||
connect(node->Terminal, &terminal::Recieve,
|
||||
this, &MavLinkServiceBridge::terminalOutput);
|
||||
}
|
||||
if (node->RC) {
|
||||
connect(node->RC, &rcprocess::new_remote_ctrl,
|
||||
this, &MavLinkServiceBridge::rcChannelsUpdated);
|
||||
}
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::writeCommandLong(float p1, float p2, float p3, float p4,
|
||||
float p5, float p6, float p7,
|
||||
uint16_t cmd, uint8_t confirmation)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Commander)
|
||||
m_dlink->mavlinknode->Commander->WriteCmd_long(p1, p2, p3, p4, p5, p6, p7, cmd, confirmation);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::writeParameter(uint8_t sysid, uint8_t compid,
|
||||
QVariant parmname, QVariant type, QVariant value)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
|
||||
m_dlink->mavlinknode->Parameter->WriteCmd2(sysid, compid, parmname, type, value);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::readWaypoints(uint8_t sysid, uint8_t compid, int count)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
|
||||
m_dlink->mavlinknode->Mission->ReadCmd(sysid, compid, count);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::writeWaypoints(uint8_t sysid, uint8_t compid, uint32_t total, int current)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
|
||||
m_dlink->mavlinknode->Mission->WriteCmd(sysid, compid, total, current);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::setCurrentPoint(int point)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Mission)
|
||||
m_dlink->mavlinknode->Mission->SetCurrentPoint(point);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::readAll(uint8_t sysid, uint8_t compid, uint8_t index)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
|
||||
m_dlink->mavlinknode->Parameter->ReadCmd(sysid, compid, index);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::writeValue(uint8_t sysid, uint8_t compid,
|
||||
const char *id, uint8_t type, float value)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Parameter)
|
||||
m_dlink->mavlinknode->Parameter->WriteCmd(sysid, compid, id, type, value);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::startReplay(bool start)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
|
||||
m_dlink->mavlinknode->replay->startReplay(start);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::setPercentage(float pct)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
|
||||
m_dlink->mavlinknode->replay->setPercentage(pct);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::setMultiple(double mul)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->replay)
|
||||
m_dlink->mavlinknode->replay->setMultiple(mul);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::transmit(const QString &data)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->Terminal)
|
||||
m_dlink->mavlinknode->Terminal->Transmit(data);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::softUpdate(const QList<uint16_t> &channels)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->RC)
|
||||
m_dlink->mavlinknode->RC->SoftRCUpdate(channels);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::setActive(uint32_t mask)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode && m_dlink->mavlinknode->RC)
|
||||
m_dlink->mavlinknode->RC->setRCActive(mask);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::setLogFile(const QString &path)
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode)
|
||||
m_dlink->mavlinknode->setLogfile(path);
|
||||
}
|
||||
|
||||
void MavLinkServiceBridge::createCSV()
|
||||
{
|
||||
if (m_dlink && m_dlink->mavlinknode)
|
||||
m_dlink->mavlinknode->CreateCSV();
|
||||
}
|
||||
#include "MavLinkServiceBridge.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "dlink.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "mavlinknode.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MavLinkServiceBridge::MavLinkServiceBridge(DLink *dlink, QObject *parent)
|
||||
|
||||
|
||||
|
||||
|
||||
: QObject(parent)
|
||||
|
||||
|
||||
|
||||
|
||||
, m_dlink(dlink)
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MavLinkServiceBridge::wireFromMavLinkNode()
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
if (!m_dlink || !m_dlink->mavlinknode) return;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MavLinkNode *node = m_dlink->mavlinknode;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node, &MavLinkNode::CommuniationLost, this, &MavLinkServiceBridge::commLost);
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node, &MavLinkNode::beep, this, &MavLinkServiceBridge::beepRequested);
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node, &MavLinkNode::updateDlink, this, &MavLinkServiceBridge::dlinkStatsChanged);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (node->Commander) {
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->Commander, &commandprocess::commandAccepted,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::commandResult);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (node->Mission) {
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->Mission, &MissionProcess::clearWaypoint,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::waypointCleared);
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->Mission, &MissionProcess::sendItemOK,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::waypointSendOk);
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->Mission, &MissionProcess::currentPoint,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::waypointCurrent);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node, &MavLinkNode::addVehicles, this, &MavLinkServiceBridge::vehicleListChanged);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (node->replay) {
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->replay, &Replay::currentPercentage,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::replayProgressChanged);
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->replay, &Replay::replayComplete,
|
||||
|
||||
|
||||
|
||||
|
||||
this, &MavLinkServiceBridge::replayEnded);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (node->Terminal) {
|
||||
|
||||
|
||||
|
||||
|
||||
connect(node->Terminal, &terminal::Recieve,
|
||||
|
||||
|
||||
@@ -61,6 +61,23 @@ public:
|
||||
void setLogFile(const QString &path) override;
|
||||
void createCSV() override;
|
||||
|
||||
// IDataProvider
|
||||
void requestSystemStatus() override;
|
||||
void requestAllParams() override;
|
||||
void setUpdateInterval(int ms) override;
|
||||
void enableDataStream(bool enabled) override;
|
||||
|
||||
// ILinkProvider
|
||||
void connectToVehicle(const QString &port, int baudRate) override;
|
||||
void disconnectFromVehicle() override;
|
||||
bool isLinkConnected() const override;
|
||||
QStringList availablePorts() const override;
|
||||
|
||||
// ISensorProvider
|
||||
void enableSensorStream(const QString &sensorName, bool enabled) override;
|
||||
void requestSensorCalibration() override;
|
||||
QVariantMap getSensorHealth() const override;
|
||||
|
||||
signals:
|
||||
void commLost(bool lost);
|
||||
void beepRequested(int type);
|
||||
@@ -83,6 +100,8 @@ signals:
|
||||
void rawMavlinkMsg(const QByteArray &data);
|
||||
void rawSensorData(int channel, const QByteArray &data);
|
||||
|
||||
void mavlinkMessageReceived(const mavlink_message_t &msg);
|
||||
|
||||
public:
|
||||
DLink *getDLink() const { return m_dlink; }
|
||||
|
||||
|
||||
@@ -35,14 +35,12 @@ public:
|
||||
template<typename T>
|
||||
T *get(const QString &serviceId) const
|
||||
{
|
||||
static_assert(std::is_base_of_v<IService, T>, "T must derive from IService");
|
||||
return dynamic_cast<T*>(m_services.value(serviceId, nullptr));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T *get()
|
||||
{
|
||||
static_assert(std::is_base_of_v<IService, T>, "T must derive from IService");
|
||||
for (auto *s : m_services) {
|
||||
if (auto *t = dynamic_cast<T*>(s)) {
|
||||
return t;
|
||||
|
||||
Reference in New Issue
Block a user