feat: Service Registry + Bridge 解耦架构 + 全工程代码清理
## 架构升级:Service Registry + Bridge 模式 - 新增 PluginSDK/IPluginServices.h:10 个纯虚服务接口(IDataProvider/ILinkProvider/...) - 新增 MavLinkServiceBridge:单 QObject 实现全部服务,隔离 MavLinkNode 依赖 - 升级 PluginManifest:支持 plugin.json 的 provides/consumes 声明式依赖 - 实现 ExtensionHost::autoWire():元对象自省自动连接信号槽 - 集成到 AppController:initModules() 中创建桥接器并注册到 ServiceRegistry - CockpitPlugin 演示服务发现:initialize() 中通过 PluginContext 查找服务 ## 代码清理 - Plugins/opmap:~280 行死代码(waypointsetting 100行注释块/tilematrix 54行/等27个文件) - Plugins/MavLinkNode:~200 行 GBK 乱码注释翻译为 UTF-8 + 12 行注释死代码 - Plugins/ToolsUI:~222 行死代码(ECU.cpp 82行/INS.cpp 113行/Parse/ToolsUI 等) - StatusUI/Setting/MissionUI:~65 行注释死代码 - Cockpit/leftladder.cpp:10 处 GBK 乱码翻译为中文 - 清理头文件注释掉的 #include(19 处)、空 if-else 分支、注释变量声明 ## 编译验证 - [100%] Built target GCS 零错误 - 运行时 timeout 3s 正常退出,无崩溃
This commit is contained in:
@@ -0,0 +1,294 @@
|
||||
/****************************************************************************
|
||||
*
|
||||
* (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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "MissionSettingsItem.h"
|
||||
#include "JsonHelper.h"
|
||||
#include "MissionController.h"
|
||||
#include "QGCGeo.h"
|
||||
#include "QGroundControlQmlGlobal.h"
|
||||
#include "SimpleMissionItem.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "AppSettings.h"
|
||||
#include "MissionCommandUIInfo.h"
|
||||
|
||||
#include <QPolygonF>
|
||||
|
||||
QGC_LOGGING_CATEGORY(MissionSettingsComplexItemLog, "MissionSettingsComplexItemLog")
|
||||
|
||||
const char* MissionSettingsItem::_plannedHomePositionAltitudeName = "PlannedHomePositionAltitude";
|
||||
|
||||
QMap<QString, FactMetaData*> MissionSettingsItem::_metaDataMap;
|
||||
|
||||
MissionSettingsItem::MissionSettingsItem(Vehicle* vehicle, bool flyView, QObject* parent)
|
||||
: ComplexMissionItem (vehicle, flyView, parent)
|
||||
, _plannedHomePositionAltitudeFact (0, _plannedHomePositionAltitudeName, FactMetaData::valueTypeDouble)
|
||||
, _cameraSection (vehicle)
|
||||
, _speedSection (vehicle)
|
||||
{
|
||||
_isIncomplete = false;
|
||||
_editorQml = "qrc:/qml/MissionSettingsEditor.qml";
|
||||
|
||||
if (_metaDataMap.isEmpty()) {
|
||||
_metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/MissionSettings.FactMetaData.json"), nullptr /* metaDataParent */);
|
||||
}
|
||||
|
||||
_plannedHomePositionAltitudeFact.setMetaData (_metaDataMap[_plannedHomePositionAltitudeName]);
|
||||
_plannedHomePositionAltitudeFact.setRawValue (_plannedHomePositionAltitudeFact.rawDefaultValue());
|
||||
setHomePositionSpecialCase(true);
|
||||
|
||||
_cameraSection.setAvailable(true);
|
||||
_speedSection.setAvailable(true);
|
||||
|
||||
connect(this, &MissionSettingsItem::specifyMissionFlightSpeedChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
|
||||
connect(&_cameraSection, &CameraSection::itemCountChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
|
||||
connect(&_speedSection, &CameraSection::itemCountChanged, this, &MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber);
|
||||
connect(this, &MissionSettingsItem::terrainAltitudeChanged, this, &MissionSettingsItem::_setHomeAltFromTerrain);
|
||||
connect(&_cameraSection, &CameraSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
|
||||
connect(&_speedSection, &SpeedSection::dirtyChanged, this, &MissionSettingsItem::_sectionDirtyChanged);
|
||||
connect(&_cameraSection, &CameraSection::specifiedGimbalYawChanged, this, &MissionSettingsItem::specifiedGimbalYawChanged);
|
||||
connect(&_cameraSection, &CameraSection::specifiedGimbalPitchChanged, this, &MissionSettingsItem::specifiedGimbalPitchChanged);
|
||||
connect(&_speedSection, &SpeedSection::specifiedFlightSpeedChanged, this, &MissionSettingsItem::specifiedFlightSpeedChanged);
|
||||
connect(_vehicle, &Vehicle::homePositionChanged, this, &MissionSettingsItem::_updateHomePosition);
|
||||
connect(&_plannedHomePositionAltitudeFact, &Fact::rawValueChanged, this, &MissionSettingsItem::_updateAltitudeInCoordinate);
|
||||
|
||||
_updateHomePosition(_vehicle->homePosition());
|
||||
}
|
||||
|
||||
int MissionSettingsItem::lastSequenceNumber(void) const
|
||||
{
|
||||
int lastSequenceNumber = _sequenceNumber;
|
||||
|
||||
lastSequenceNumber += _cameraSection.itemCount();
|
||||
lastSequenceNumber += _speedSection.itemCount();
|
||||
|
||||
return lastSequenceNumber;
|
||||
}
|
||||
|
||||
void MissionSettingsItem::setDirty(bool dirty)
|
||||
{
|
||||
if (_dirty != dirty) {
|
||||
_dirty = dirty;
|
||||
if (!dirty) {
|
||||
_cameraSection.setDirty(false);
|
||||
_speedSection.setDirty(false);
|
||||
}
|
||||
emit dirtyChanged(_dirty);
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::save(QJsonArray& missionItems)
|
||||
{
|
||||
QList<MissionItem*> items;
|
||||
|
||||
appendMissionItems(items, this);
|
||||
|
||||
// First item should be planned home position, we are not responsible for save/load
|
||||
// Remaining items we just output as is
|
||||
for (int i=1; i<items.count(); i++) {
|
||||
MissionItem* item = items[i];
|
||||
QJsonObject saveObject;
|
||||
item->save(saveObject);
|
||||
missionItems.append(saveObject);
|
||||
item->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::setSequenceNumber(int sequenceNumber)
|
||||
{
|
||||
if (_sequenceNumber != sequenceNumber) {
|
||||
_sequenceNumber = sequenceNumber;
|
||||
emit sequenceNumberChanged(sequenceNumber);
|
||||
emit lastSequenceNumberChanged(lastSequenceNumber());
|
||||
}
|
||||
}
|
||||
|
||||
bool MissionSettingsItem::load(const QJsonObject& complexObject, int sequenceNumber, QString& errorString)
|
||||
{
|
||||
Q_UNUSED(complexObject);
|
||||
Q_UNUSED(sequenceNumber);
|
||||
Q_UNUSED(errorString);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
double MissionSettingsItem::greatestDistanceTo(const QGeoCoordinate &other) const
|
||||
{
|
||||
Q_UNUSED(other);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MissionSettingsItem::specifiesCoordinate(void) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void MissionSettingsItem::appendMissionItems(QList<MissionItem*>& items, QObject* missionItemParent)
|
||||
{
|
||||
int seqNum = _sequenceNumber;
|
||||
|
||||
// IMPORTANT NOTE: If anything changes here you must also change MissionSettingsItem::scanForMissionSettings
|
||||
|
||||
// Planned home position
|
||||
MissionItem* item = new MissionItem(seqNum++,
|
||||
MAV_CMD_NAV_WAYPOINT,
|
||||
MAV_FRAME_GLOBAL,
|
||||
0, // Hold time
|
||||
0, // Acceptance radius
|
||||
0, // Not sure?
|
||||
0, // Yaw
|
||||
coordinate().latitude(),
|
||||
coordinate().longitude(),
|
||||
_plannedHomePositionAltitudeFact.rawValue().toDouble(),
|
||||
true, // autoContinue
|
||||
false, // isCurrentItem
|
||||
missionItemParent);
|
||||
items.append(item);
|
||||
|
||||
_cameraSection.appendSectionItems(items, missionItemParent, seqNum);
|
||||
_speedSection.appendSectionItems(items, missionItemParent, seqNum);
|
||||
}
|
||||
|
||||
bool MissionSettingsItem::addMissionEndAction(QList<MissionItem*>& /*items*/, int /*seqNum*/, QObject* /*missionItemParent*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MissionSettingsItem::scanForMissionSettings(QmlObjectListModel* visualItems, int scanIndex)
|
||||
{
|
||||
bool foundSpeedSection = false;
|
||||
bool foundCameraSection = false;
|
||||
|
||||
qCDebug(MissionSettingsComplexItemLog) << "MissionSettingsItem::scanForMissionSettings count:scanIndex" << visualItems->count() << scanIndex;
|
||||
|
||||
// Scan through the initial mission items for possible mission settings
|
||||
foundCameraSection = _cameraSection.scanForSection(visualItems, scanIndex);
|
||||
foundSpeedSection = _speedSection.scanForSection(visualItems, scanIndex);
|
||||
|
||||
return foundSpeedSection || foundCameraSection;
|
||||
}
|
||||
|
||||
double MissionSettingsItem::complexDistance(void) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_setDirty(void)
|
||||
{
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_setCoordinateWorker(const QGeoCoordinate& coordinate)
|
||||
{
|
||||
if (_plannedHomePositionCoordinate != coordinate) {
|
||||
_plannedHomePositionCoordinate = coordinate;
|
||||
emit coordinateChanged(coordinate);
|
||||
emit exitCoordinateChanged(coordinate);
|
||||
_plannedHomePositionAltitudeFact.setRawValue(coordinate.altitude());
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::setHomePositionFromVehicle(Vehicle* vehicle)
|
||||
{
|
||||
// If the user hasn't moved the planned home position manually we use the value from the vehicle
|
||||
if (!_plannedHomePositionMovedByUser) {
|
||||
QGeoCoordinate coordinate = vehicle->homePosition();
|
||||
// ArduPilot tends to send crap home positions at initial vehicle boot, discard them
|
||||
if (coordinate.isValid() && (coordinate.latitude() != 0 || coordinate.longitude() != 0)) {
|
||||
_plannedHomePositionFromVehicle = true;
|
||||
_setCoordinateWorker(coordinate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::setInitialHomePosition(const QGeoCoordinate& coordinate)
|
||||
{
|
||||
_plannedHomePositionMovedByUser = false;
|
||||
_plannedHomePositionFromVehicle = false;
|
||||
_setCoordinateWorker(coordinate);
|
||||
}
|
||||
|
||||
void MissionSettingsItem::setInitialHomePositionFromUser(const QGeoCoordinate& coordinate)
|
||||
{
|
||||
_plannedHomePositionMovedByUser = true;
|
||||
_plannedHomePositionFromVehicle = false;
|
||||
_setCoordinateWorker(coordinate);
|
||||
}
|
||||
|
||||
|
||||
void MissionSettingsItem::setCoordinate(const QGeoCoordinate& coordinate)
|
||||
{
|
||||
if (coordinate != this->coordinate()) {
|
||||
// The user is moving the planned home position manually. Stop tracking vehicle home position.
|
||||
_plannedHomePositionMovedByUser = true;
|
||||
_plannedHomePositionFromVehicle = false;
|
||||
_setCoordinateWorker(coordinate);
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_setDirtyAndUpdateLastSequenceNumber(void)
|
||||
{
|
||||
emit lastSequenceNumberChanged(lastSequenceNumber());
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_sectionDirtyChanged(bool dirty)
|
||||
{
|
||||
if (dirty) {
|
||||
setDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
double MissionSettingsItem::specifiedGimbalYaw(void)
|
||||
{
|
||||
return _cameraSection.specifyGimbal() ? _cameraSection.gimbalYaw()->rawValue().toDouble() : std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
double MissionSettingsItem::specifiedGimbalPitch(void)
|
||||
{
|
||||
return _cameraSection.specifyGimbal() ? _cameraSection.gimbalPitch()->rawValue().toDouble() : std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_updateAltitudeInCoordinate(QVariant value)
|
||||
{
|
||||
double newAltitude = value.toDouble();
|
||||
|
||||
if (!qFuzzyCompare(_plannedHomePositionCoordinate.altitude(), newAltitude)) {
|
||||
_plannedHomePositionCoordinate.setAltitude(newAltitude);
|
||||
emit coordinateChanged(_plannedHomePositionCoordinate);
|
||||
emit exitCoordinateChanged(_plannedHomePositionCoordinate);
|
||||
}
|
||||
}
|
||||
|
||||
double MissionSettingsItem::specifiedFlightSpeed(void)
|
||||
{
|
||||
if (_speedSection.specifyFlightSpeed()) {
|
||||
return _speedSection.flightSpeed()->rawValue().toDouble();
|
||||
} else {
|
||||
return std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_setHomeAltFromTerrain(double terrainAltitude)
|
||||
{
|
||||
if (!_plannedHomePositionFromVehicle && !qIsNaN(terrainAltitude)) {
|
||||
_plannedHomePositionAltitudeFact.setRawValue(terrainAltitude);
|
||||
}
|
||||
}
|
||||
|
||||
QString MissionSettingsItem::abbreviation(void) const
|
||||
{
|
||||
return _flyView ? tr("L") : tr("Launch");
|
||||
}
|
||||
|
||||
void MissionSettingsItem::_updateHomePosition(const QGeoCoordinate& homePosition)
|
||||
{
|
||||
if (_flyView) {
|
||||
setCoordinate(homePosition);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user