diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f1aed2be392..0ca7fbcef173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,8 @@ set(QGC_RESOURCES ${CMAKE_SOURCE_DIR}/src/FirmwarePlugin/PX4/PX4Resources.qrc ) -if(CONFIG_UTM_ADAPTER) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) list(APPEND QGC_RESOURCES ${CMAKE_SOURCE_DIR}/src/UTMSP/utmsp.qrc) else() list(APPEND QGC_RESOURCES ${CMAKE_SOURCE_DIR}/src/UTMSP/dummy/utmsp_dummy.qrc) diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index 390c347a5a35..7cf69f1518d9 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -227,9 +227,11 @@ contains (DEFINES, DISABLE_ZEROCONF) { } # UTM Adapter Enabled -contains (DEFINES, CONFIG_UTM_ADAPTER){ +contains (DEFINES, QGC_CONFIG_UTM_ADAPTER){ + message("Updating git submodule for libevents...") + system(cd $$PWD/libs/libevents/libevents/libs/cpp/parse/nlohmann_json && git submodule update --init --recursive ) + INCLUDEPATH += $$PWD/libs/libevents/libevents/libs/cpp/parse/nlohmann_json/include - LIBS += -lboost_system -lboost_thread -lssl -lcrypto } HEADERS += \ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 30725ecb679a..6f24256fcab1 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -1301,7 +1301,7 @@ LinuxBuild { } # UTM Adapter Enabled -contains (DEFINES, CONFIG_UTM_ADAPTER) { +contains (DEFINES, QGC_UTM_ADAPTER) { message("UTM enabled") #-- To test with UTM Adapter Enabled Flag diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b39a53b1b97..a6fa5ff513cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,10 @@ qt_add_library(QGC STATIC QGCToolbox.h ) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() + add_subdirectory(ADSB) add_subdirectory(AirLink) add_subdirectory(AnalyzeView) diff --git a/src/FlightDisplay/GuidedActionConfirm.qml b/src/FlightDisplay/GuidedActionConfirm.qml index d6d92dc0ccce..1578b9663265 100644 --- a/src/FlightDisplay/GuidedActionConfirm.qml +++ b/src/FlightDisplay/GuidedActionConfirm.qml @@ -15,6 +15,7 @@ import QGroundControl import QGroundControl.ScreenTools import QGroundControl.Controls import QGroundControl.Palette +import QGroundControl.UTMSP Rectangle { id: _root @@ -133,6 +134,10 @@ Rectangle { mapIndicator.actionConfirmed() mapIndicator = undefined } + + UTMSPStateStorage.indicatorOnMissionStatus = true + UTMSPStateStorage.currentNotificationIndex = 7 + UTMSPStateStorage.currentStateIndex = 3 } } diff --git a/src/MissionManager/CMakeLists.txt b/src/MissionManager/CMakeLists.txt index 70eea93b3794..373aff127d76 100644 --- a/src/MissionManager/CMakeLists.txt +++ b/src/MissionManager/CMakeLists.txt @@ -1,4 +1,7 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui Positioning Qml Xml) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() qt_add_library(MissionManager STATIC BlankPlanCreator.cc diff --git a/src/MissionManager/GeoFenceController.cc b/src/MissionManager/GeoFenceController.cc index 700e9ce01fe8..744b3c5fe43e 100644 --- a/src/MissionManager/GeoFenceController.cc +++ b/src/MissionManager/GeoFenceController.cc @@ -604,7 +604,7 @@ bool GeoFenceController::isEmpty(void) const } -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER void GeoFenceController::loadFlightPlanData() { QJsonArray jsonPolygonArray; @@ -635,10 +635,4 @@ void GeoFenceController::loadFlightPlanData() emit polygonBoundarySent(geoCoordinates); } -bool GeoFenceController::loadUploadFlag() -{ - emit uploadFlagSent(true); - - return true; -} #endif diff --git a/src/MissionManager/GeoFenceController.h b/src/MissionManager/GeoFenceController.h index f375a0c377f7..06e9130c543d 100644 --- a/src/MissionManager/GeoFenceController.h +++ b/src/MissionManager/GeoFenceController.h @@ -62,9 +62,8 @@ class GeoFenceController : public PlanElementController /// Clears the interactive bit from all fence items Q_INVOKABLE void clearAllInteractive(void); -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER Q_INVOKABLE void loadFlightPlanData(void); - Q_INVOKABLE bool loadUploadFlag(void); #endif double paramCircularFence (void); @@ -98,7 +97,7 @@ class GeoFenceController : public PlanElementController void loadComplete (void); void paramCircularFenceChanged (void); -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER void uploadFlagSent (bool flag); void polygonBoundarySent (QList coords); #endif diff --git a/src/PlanView/CMakeLists.txt b/src/PlanView/CMakeLists.txt index 1709a033392b..302427337564 100644 --- a/src/PlanView/CMakeLists.txt +++ b/src/PlanView/CMakeLists.txt @@ -2,6 +2,10 @@ find_package(Qt6 REQUIRED COMPONENTS Core Qml) qt_add_library(PlanView STATIC) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() + file(GLOB QML_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.qml) qt_add_qml_module(PlanView URI QGroundControl.PlanView diff --git a/src/PlanView/MissionItemMapVisual.qml b/src/PlanView/MissionItemMapVisual.qml index e3eb848abb58..72f64f30f7a0 100644 --- a/src/PlanView/MissionItemMapVisual.qml +++ b/src/PlanView/MissionItemMapVisual.qml @@ -35,7 +35,7 @@ Item { if (component.status === Component.Error) { console.log("Error loading Qml: ", object.mapVisualQML, component.errorString()) } - _visualItem = component.createObject(map, { "map": _root.map, vehicle: _root.vehicle, 'opacity': Qt.binding(function() { return _root.opacity }), 'interactive': Qt.binding(function() { return _root.interactive }) }) + _visualItem = component.createObject(map, { "map": _root.map, vehicle: _root.vehicle, 'opacity': 0, 'interactive': Qt.binding(function() { return _root.interactive }) }) _visualItem.clicked.connect(_root.clicked) } } diff --git a/src/PlanView/PlanToolBarIndicators.qml b/src/PlanView/PlanToolBarIndicators.qml index 883abd2e757c..84c8ea73dad3 100644 --- a/src/PlanView/PlanToolBarIndicators.qml +++ b/src/PlanView/PlanToolBarIndicators.qml @@ -70,20 +70,7 @@ Item { readonly property real _margins: ScreenTools.defaultFontPixelWidth // Properties of UTM adapter - property var _utmspController: _planMasterController.geoFenceController property bool _utmspEnabled: QGroundControl.utmspSupported - property bool responseFlag - // Dummy object when utm adapter flag is not enabled - QtObject { - id: dummyTarget - signal uploadFlagSent(bool flag) - } - Connections { - target: _utmspEnabled ? _utmspController: dummyTarget - onUploadFlagSent: function(flag) { - responseFlag = flag - } - } function getMissionTime() { if (!_missionTime) { @@ -227,13 +214,14 @@ Item { QGCButton { id: uploadButton text: _controllerDirty ? qsTr("Upload Required") : qsTr("Upload") - enabled: _utmspEnabled ? !_controllerSyncInProgress && responseFlag : !_controllerSyncInProgress + enabled: _utmspEnabled ? !_controllerSyncInProgress && UTMSPStateStorage.enableMissionUploadButton : !_controllerSyncInProgress visible: !_controllerOffline && !_controllerSyncInProgress primary: _controllerDirty onClicked: { if (_utmspEnabled) { QGroundControl.utmspManager.utmspVehicle.triggerActivationStatusBar(true); UTMSPStateStorage.removeFlightPlanState = true + UTMSPStateStorage.indicatorDisplayStatus = true } _planMasterController.upload(); } diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 53ade8a5d6c0..825b3b7465a2 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -69,7 +69,6 @@ Item { readonly property int _layerUTMSP: 4 // Additional Tab button when UTMSP is enabled readonly property string _armedVehicleUploadPrompt: qsTr("Vehicle is currently armed. Do you want to upload the mission to the vehicle?") - signal activationParamsSent(string startTime, bool activate, string flightID) function mapCenter() { var coordinate = editorMap.center @@ -826,26 +825,6 @@ Item { } } - Connections { - target: utmspEditor - function onResponseSent(response, responseFlag) { - if(responseFlag===true){ - successPopup.opacity = 1 - successPopup.visible = true - success_notify.text = "Flight Plan for Vehicle:" + _vehicleID +" is successfully Registered..." - var disappearTimer1 = Qt.createQmlObject("import QtQuick 2.0; Timer { interval: 3000; onTriggered: {successPopup.visible = false; successPopup.opacity = 0;} }", parent, "disappearTimer"); - disappearTimer1.start() - } - else{ - failPopup.opacity = 1 - failPopup.visible = true - fail_notify.text = "Error in Flightblender Response..." //TODO->Will pass the response message - var disappearTimer4 = Qt.createQmlObject("import QtQuick 2.0; Timer { interval: 3000; onTriggered: {failPopup.visible = false; failPopup.opacity = 0;} }", parent, "disappearTimer"); - disappearTimer4.start() - } - } - } - QGCLabel { // Elevation provider notice on top of terrain plot readonly property string _licenseString: QGroundControl.elevationProviderNotice @@ -919,7 +898,19 @@ Item { mainWindow.showMessageDialog(qsTr("Clear"), qsTr("Are you sure you want to remove all mission items and clear the mission from the vehicle?"), Dialog.Yes | Dialog.Cancel, - function() { _planMasterController.removeAllFromVehicle(); _missionController.setCurrentPlanViewSeqNum(0, true); if(_utmspEnabled){_resetRegisterFlightPlan = true; QGroundControl.utmspManager.utmspVehicle.triggerActivationStatusBar(false);}}) + function() { _planMasterController.removeAllFromVehicle(); + _missionController.setCurrentPlanViewSeqNum(0, true); + if(_utmspEnabled) + {_resetRegisterFlightPlan = true; + QGroundControl.utmspManager.utmspVehicle.triggerActivationStatusBar(false); + UTMSPStateStorage.startTimeStamp = ""; + UTMSPStateStorage.showActivationTab = false; + UTMSPStateStorage.flightID = ""; + UTMSPStateStorage.enableMissionUploadButton = false; + UTMSPStateStorage.indicatorPendingStatus = true; + UTMSPStateStorage.indicatorApprovedStatus = false; + UTMSPStateStorage.indicatorActivatedStatus = false; + UTMSPStateStorage.currentStateIndex = 0}}) } //- ToolStrip DropPanel Components @@ -1172,130 +1163,6 @@ Item { } } - Rectangle { - id: successPopup - x: Math.round((mainWindow.width - width) * 0.5) - y: ScreenTools.defaultFontPixelHeight - width: mainWindow.width * 0.55 - height: ScreenTools.defaultFontPixelHeight * 2.944 - color: _utmspEnabled? qgcPal.successNotifyUTMSP: qgcPal.buttonText - radius: ScreenTools.defaultFontPixelHeight * 0.5 - border.color: qgcPal.alertBorder - border.width: 1 - opacity: 0 - visible: false - Text{ - id: success_notify - width: successPopup.width - (ScreenTools.defaultFontPixelHeight * 2) - x: ScreenTools.defaultFontPixelWidth * 2 - y: ScreenTools.defaultFontPixelHeight * 0.667 - textFormat: TextEdit.RichText - font.pointSize: ScreenTools.defaultFontPointSize - font.family: ScreenTools.demiboldFontFamily - wrapMode: TextEdit.WordWrap - color: qgcPal.alertText - } - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.topMargin: -(height / 2) - color: _utmspEnabled? qgcPal.successNotifyUTMSP: qgcPal.buttonText - radius: ScreenTools.defaultFontPixelHeight * 0.25 - border.color: qgcPal.alertBorder - border.width: 1 - width: statusLabel.contentWidth + _margins - height: statusLabel.contentHeight + _margins - - property real _margins: ScreenTools.defaultFontPixelHeight * 0.25 - - QGCLabel { - id: statusLabel - anchors.centerIn: parent - text: qsTr("Status") - font.pointSize: ScreenTools.smallFontPointSize - color: qgcPal.alertText - } - } - Behavior on opacity { - NumberAnimation { duration: 1000 } - } - function hidesuccessPopup() { - successPopup.visible = false; - successPopup.opacity = 0; - } - Behavior on visible { - SequentialAnimation { - NumberAnimation { from: 2.5; to: 3.5; duration: 500 } - PauseAnimation { duration: 2000 } - NumberAnimation { from: 3.5; to: 2.5; duration: 500 } - } - } - } - // Failure Notification Popup - Rectangle { - id: failPopup - x: Math.round((mainWindow.width - width) * 0.5) - y: ScreenTools.defaultFontPixelHeight - width: mainWindow.width * 0.55 - height: ScreenTools.defaultFontPixelHeight * 2.944 - color: qgcPal.alertBackground - radius: ScreenTools.defaultFontPixelHeight * 0.5 - opacity: 0 - visible: false - Text{ - id:fail_notify - width: successPopup.width - (ScreenTools.defaultFontPixelHeight * 2) - x: ScreenTools.defaultFontPixelWidth * 2 - y: ScreenTools.defaultFontPixelHeight * 0.667 - textFormat: TextEdit.RichText - font.pointSize: ScreenTools.defaultFontPointSize - font.family: ScreenTools.demiboldFontFamily - wrapMode: TextEdit.WordWrap - color: qgcPal.alertText - } - Rectangle { - anchors.horizontalCenter: parent.horizontalCenter - anchors.top: parent.top - anchors.topMargin: -(height / 2) - color: qgcPal.alertBackground - radius: ScreenTools.defaultFontPixelHeight * 0.25 - border.color: qgcPal.alertBorder - border.width: 1 - width: warningLabel.contentWidth + _margins - height: warningLabel.contentHeight + _margins - - property real _margins: ScreenTools.defaultFontPixelHeight * 0.25 - - QGCLabel { - id: warningLabel - anchors.centerIn: parent - text: qsTr("Status Error") - font.pointSize: ScreenTools.smallFontPointSize - color: qgcPal.alertText - } - } - Behavior on opacity { - NumberAnimation { duration: 1000 } - } - function hidefailPopup() { - failPopup.visible = false; - failPopup.opacity = 0; - } - Behavior on visible { - SequentialAnimation { - NumberAnimation { from: 2.5; to: 3.5; duration: 500 } - PauseAnimation { duration: 2000 } - NumberAnimation { from: 3.5; to: 2.5; duration: 500 } - } - } - } - Connections{ - target: utmspEditor - function onTimeStampSent(timestamp, activateflag, id){ - activationParamsSent(timestamp,activateflag, id) - } - } - Connections { target: utmspEditor function onVehicleIDSent(id) { diff --git a/src/QGCToolbox.cc b/src/QGCToolbox.cc index 4c552d850e61..268a7e458fa8 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -36,7 +36,7 @@ #include CUSTOMHEADER #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER #include "UTMSPManager.h" #endif @@ -69,7 +69,7 @@ QGCToolbox::QGCToolbox(QGCApplication* app) #ifndef QGC_AIRLINK_DISABLED _airlinkManager = new AirLinkManager (app, this); #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER _utmspManager = new UTMSPManager (app, this); #endif } @@ -100,7 +100,7 @@ void QGCToolbox::setChildToolboxes(void) #ifndef QGC_AIRLINK_DISABLED _airlinkManager->setToolbox(this); #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER _utmspManager->setToolbox(this); #endif } diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index 78c803049118..e16ede3a50d0 100644 --- a/src/QGCToolbox.h +++ b/src/QGCToolbox.h @@ -34,7 +34,7 @@ class ADSBVehicleManager; #ifndef QGC_AIRLINK_DISABLED class AirLinkManager; #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER class UTMSPManager; #endif @@ -66,7 +66,7 @@ class QGCToolbox : public QObject { #ifndef QGC_AIRLINK_DISABLED AirLinkManager* airlinkManager () { return _airlinkManager; } #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPManager* utmspManager () { return _utmspManager; } #endif @@ -98,7 +98,7 @@ class QGCToolbox : public QObject { AirLinkManager* _airlinkManager = nullptr; #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPManager* _utmspManager = nullptr; #endif friend class QGCApplication; diff --git a/src/QmlControls/CMakeLists.txt b/src/QmlControls/CMakeLists.txt index 5bffc60942b7..cd23cf524010 100644 --- a/src/QmlControls/CMakeLists.txt +++ b/src/QmlControls/CMakeLists.txt @@ -1,5 +1,9 @@ find_package(Qt6 REQUIRED COMPONENTS Concurrent Core Gui Location Positioning Qml QmlIntegration Quick Widgets) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() + qt_add_library(QmlControls STATIC AppMessages.cc AppMessages.h diff --git a/src/QmlControls/QGCPalette.cc b/src/QmlControls/QGCPalette.cc index fedfa73b4886..18ae2f32998d 100644 --- a/src/QmlControls/QGCPalette.cc +++ b/src/QmlControls/QGCPalette.cc @@ -98,7 +98,7 @@ void QGCPalette::_buildMap() DECLARE_QGC_SINGLE_COLOR(surveyPolygonTerrainCollision, "red") // Colors for UTM Adapter -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER DECLARE_QGC_COLOR(switchUTMSP, "#b0e0e6", "#b0e0e6", "#b0e0e6", "#b0e0e6"); DECLARE_QGC_COLOR(sliderUTMSP, "#9370db", "#9370db", "#9370db", "#9370db"); DECLARE_QGC_COLOR(successNotifyUTMSP, "#3cb371", "#3cb371", "#3cb371", "#3cb371"); diff --git a/src/QmlControls/QGCPalette.h b/src/QmlControls/QGCPalette.h index ceb860a71965..0a959becd003 100644 --- a/src/QmlControls/QGCPalette.h +++ b/src/QmlControls/QGCPalette.h @@ -156,7 +156,7 @@ class QGCPalette : public QObject DEFINE_QGC_COLOR(toolStripHoverColor, setToolStripHoverColor) DEFINE_QGC_COLOR(groupBorder, setGroupBorder) -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER DEFINE_QGC_COLOR(switchUTMSP, setSwitchUTMSP) DEFINE_QGC_COLOR(sliderUTMSP, setSliderUTMSP) DEFINE_QGC_COLOR(successNotifyUTMSP, setSuccessNotifyUTMSP) diff --git a/src/UTMSP/dummy/qmldir b/src/QmlControls/QGroundControl/UTMSP/qmldir similarity index 60% rename from src/UTMSP/dummy/qmldir rename to src/QmlControls/QGroundControl/UTMSP/qmldir index aff750760dea..a3ed2d38b103 100644 --- a/src/UTMSP/dummy/qmldir +++ b/src/QmlControls/QGroundControl/UTMSP/qmldir @@ -4,4 +4,8 @@ UTMSPAdapterEditor 1.0 UTMSPAdapterEditor.qml UTMSPMapVisuals 1.0 UTMSPMapVisuals.qml UTMSPActivationStatusBar 1.0 UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals 1.0 UTMSPMapPolygonVisuals.qml +UTMSPNotificationSlider 1.0 UTMSPNotificationSlider.qml +UTMSPFlightStatusIndicator 1.0 UTMSPFlightStatusIndicator.qml + +singleton UTMSPStateStorage 1.0 UTMSPStateStorage.qml diff --git a/src/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index a47391a80347..902644afdd31 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.cc +++ b/src/QmlControls/QGroundControlQmlGlobal.cc @@ -96,7 +96,7 @@ void QGroundControlQmlGlobal::setToolbox(QGCToolbox* toolbox) #ifndef QGC_AIRLINK_DISABLED _airlinkManager = toolbox->airlinkManager(); #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER _utmspManager = toolbox->utmspManager(); #endif } diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index e934c581a6a1..c368804309a8 100644 --- a/src/QmlControls/QGroundControlQmlGlobal.h +++ b/src/QmlControls/QGroundControlQmlGlobal.h @@ -46,7 +46,7 @@ Q_MOC_INCLUDE("QGCPalette.h") Q_MOC_INCLUDE("PositionManager.h") Q_MOC_INCLUDE("SettingsManager.h") Q_MOC_INCLUDE("VideoManager.h") -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER Q_MOC_INCLUDE("UTMSPManager.h") #endif #ifndef QGC_AIRLINK_DISABLED @@ -128,7 +128,7 @@ class QGroundControlQmlGlobal : public QGCTool Q_PROPERTY(bool utmspSupported READ utmspSupported CONSTANT) -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER Q_PROPERTY(UTMSPManager* utmspManager READ utmspManager CONSTANT) #endif @@ -192,7 +192,7 @@ class QGroundControlQmlGlobal : public QGCTool bool airlinkSupported () { return false; } #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPManager* utmspManager () {return _utmspManager;} #endif @@ -239,7 +239,7 @@ class QGroundControlQmlGlobal : public QGCTool QString qgcVersion (void) const; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER bool utmspSupported() { return true; } #else bool utmspSupported() { return false; } @@ -275,7 +275,7 @@ class QGroundControlQmlGlobal : public QGCTool ADSBVehicleManager* _adsbVehicleManager = nullptr; QGCPalette* _globalPalette = nullptr; QmlUnitsConversion _unitsConversion; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPManager* _utmspManager; #endif diff --git a/src/UI/MainRootWindow.qml b/src/UI/MainRootWindow.qml index fe604cfc2b26..4053305ec690 100644 --- a/src/UI/MainRootWindow.qml +++ b/src/UI/MainRootWindow.qml @@ -30,9 +30,6 @@ ApplicationWindow { minimumHeight: ScreenTools.isMobile ? ScreenTools.screenHeight : Math.min(ScreenTools.defaultFontPixelWidth * 50, Screen.height) visible: true - property string _startTimeStamp - property bool _showVisible - property string _flightID property bool _utmspSendActTrigger property bool _utmspStartTelemetry @@ -253,14 +250,6 @@ ApplicationWindow { id: planView anchors.fill: parent visible: false - - onActivationParamsSent:{ - if(_utmspEnabled){ - _startTimeStamp = startTime - _showVisible = activate - _flightID = flightID - } - } } footer: LogReplayStatusBar { @@ -837,9 +826,9 @@ ApplicationWindow { UTMSPActivationStatusBar{ id: activationbar - activationStartTimestamp: _startTimeStamp - activationApproval: _showVisible && QGroundControl.utmspManager.utmspVehicle.vehicleActivation - flightID: _flightID - anchors.fill: parent + activationStartTimestamp: UTMSPStateStorage.startTimeStamp + activationApproval: UTMSPStateStorage.showActivationTab && QGroundControl.utmspManager.utmspVehicle.vehicleActivation + flightID: UTMSPStateStorage.flightID + anchors.fill: parent } } diff --git a/src/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index d7e96cee36db..09d870f09262 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -6,17 +6,18 @@ qt_add_library(UTMSP STATIC) option(QGC_UTM_ADAPTER "Enable UTM Adapter" OFF) if(QGC_UTM_ADAPTER) message(STATUS "UTMSP is Initialized") + add_definitions(-DQGC_UTM_ADAPTER) - if(NOT nlohmann_json_FOUND) - message(STATUS "UTMSP: Fetching nlohmann/json") - include(FetchContent) - FetchContent_Declare(json - GIT_REPOSITORY https://github.com/nlohmann/json.git - GIT_TAG v3.11.3 - GIT_SHALLOW TRUE - ) - FetchContent_MakeAvailable(json) - endif() + # if(NOT nlohmann_json_FOUND) + # message(STATUS "UTMSP: Fetching nlohmann/json") + # include(FetchContent) + # FetchContent_Declare(json + # GIT_REPOSITORY https://github.com/nlohmann/json.git + # GIT_TAG v3.11.3 + # GIT_SHALLOW TRUE + # ) + # FetchContent_MakeAvailable(json) + # endif() find_package(Qt6 REQUIRED COMPONENTS Network Positioning Qml) find_package(Threads REQUIRED) @@ -30,6 +31,8 @@ if(QGC_UTM_ADAPTER) UTMSPAuthorization.h UTMSPBlenderRestInterface.cpp UTMSPBlenderRestInterface.h + UTMSPFlightDetails.cpp + UTMSPFlightDetails.h UTMSPFlightPlanManager.cpp UTMSPFlightPlanManager.h UTMSPLogger.h @@ -50,7 +53,6 @@ if(QGC_UTM_ADAPTER) target_link_libraries(UTMSP PRIVATE - boost_system nlohmann_json Threads::Threads Qt6::Network diff --git a/src/UTMSP/UTMSPActivationStatusBar.qml b/src/UTMSP/UTMSPActivationStatusBar.qml index e97e7b07d524..68343acdc601 100644 --- a/src/UTMSP/UTMSPActivationStatusBar.qml +++ b/src/UTMSP/UTMSPActivationStatusBar.qml @@ -40,9 +40,18 @@ Item { property string timeDifference property bool activationErrorFlag + signal activationTriggered(bool value) + onActivationApprovalChanged: { + if(activationApproval === true){ + activationTriggered(false) + displayActivationTabTimer.start() + } + } + Timer { + id: displayActivationTabTimer interval: 1000 running: activationApproval repeat: activationApproval @@ -55,12 +64,13 @@ Item { var activationErrorFlag = QGroundControl.utmspManager.utmspVehicle.activationFlag if(activationErrorFlag === true){ QGroundControl.utmspManager.utmspVehicle.loadTelemetryFlag(true) - approvetag.visible = false - activatetag.visible = true activationTriggered(true) - hideTimer.start() + UTMSPStateStorage.indicatorActivatedStatus = true + displayActivationTabTimer.stop() + UTMSPStateStorage.currentStateIndex = 2 + UTMSPStateStorage.currentNotificationIndex = 4 + UTMSPStateStorage.indicatorDisplayStatus = false }else{ - approvetag.visible = false failtag.visible = true } } else { @@ -68,130 +78,145 @@ Item { var minutes = Math.floor((diff % 3600000) / 60000) var seconds = Math.floor((diff % 60000) / 1000) timeDifference = hours + " hours " + minutes + " minutes " + seconds + " seconds" + UTMSPStateStorage.indicatorActivationTime = timeDifference.toString() + UTMSPStateStorage.currentNotificationIndex = 3 } } } - Timer { - id: hideTimer - interval: 5000 - running: false - onTriggered: activationBar.visible = false + //TODO: Create a dynamic real time mission progress bar + Canvas { + anchors.fill: parent + + onPaint: { + var centerX = ScreenTools.defaultFontPixelHeight * 7.5 /2 + ScreenTools.defaultFontPixelHeight * 1.25 + var centerY = parent.height - ScreenTools.defaultFontPixelHeight * 7.5 /2 - ScreenTools.defaultFontPixelHeight * 0.3 + var ctx = getContext("2d") + ctx.reset() + ctx.strokeStyle = qgcPal.window + ctx.lineWidth = ScreenTools.defaultFontPixelHeight * 0.75 + ctx.beginPath() + + var attitudeRadius = 78 + var zeroAttitudeRadians = 2.18166 + var maxRadians = 0 + + ctx.arc(centerX, centerY, attitudeRadius, zeroAttitudeRadians, maxRadians) + ctx.stroke() + } } - Rectangle { - id: activationBar - color: qgcPal.textFieldText - border.color: qgcPal.textFieldText - width: ScreenTools.defaultFontPixelWidth * 83.33 - height: ScreenTools.defaultFontPixelHeight * 8.33 - anchors.right: parent.right - anchors.bottom: parent.bottom - opacity: 0.7 - visible: activationApproval - radius: ScreenTools.defaultFontPixelWidth * 0.833 - - QGCColoredImage { - id: closeButton - width: ScreenTools.defaultFontPixelWidth * 5 - height: ScreenTools.defaultFontPixelWidth * 5 - x: 460 - y: 5 - source: "/res/XDelete.svg" - fillMode: Image.PreserveAspectFit - color: qgcPal.text + //TODO: same as above + Canvas { + anchors.fill: parent + + onPaint: { + var centerX = ScreenTools.defaultFontPixelHeight * 7.5 /2 + ScreenTools.defaultFontPixelHeight * 1.25 + var centerY = parent.height - ScreenTools.defaultFontPixelHeight * 7.5 /2 - ScreenTools.defaultFontPixelHeight * 0.3 + var ctx = getContext("2d") + ctx.reset() + ctx.strokeStyle = qgcPal.window + ctx.lineWidth = ScreenTools.defaultFontPixelHeight * 0.75 + ctx.beginPath() + + var attitudeRadius = 78 + var zeroAttitudeRadians = 2.18166 + var maxRadians = 0 + + ctx.arc(centerX, centerY, attitudeRadius, zeroAttitudeRadians, maxRadians) // TODO: Create a variable values + ctx.stroke() } - QGCMouseArea { - fillItem: closeButton - onClicked: { - activationBar.visible = false - activationApproval = false - } + } + + //TODO: Same as above + Canvas { + anchors.fill: parent + + onPaint: { + var centerX = ScreenTools.defaultFontPixelHeight * 7.5 /2 + ScreenTools.defaultFontPixelHeight * 1.25 + var centerY = parent.height - ScreenTools.defaultFontPixelHeight * 7.5 /2 - ScreenTools.defaultFontPixelHeight * 0.3 + var ctx = getContext("2d") + ctx.reset() + ctx.strokeStyle = qgcPal.text + ctx.lineWidth = 2 + ctx.beginPath() + + var attitudeRadius = 84 + var angleRadians = 2.18166 + + var outerX = centerX + attitudeRadius * Math.cos(angleRadians) + var outerY = centerY + attitudeRadius * Math.sin(angleRadians) + + var tickMarkLength = 13 + var innerX = centerX + (attitudeRadius - tickMarkLength) * Math.cos(angleRadians) + var innerY = centerY + (attitudeRadius - tickMarkLength) * Math.sin(angleRadians) + + ctx.moveTo(outerX, outerY) + ctx.lineTo(innerX, innerY) + ctx.stroke() } + } - Column{ - spacing: ScreenTools.defaultFontPixelWidth * 1.667 - anchors.centerIn: parent - Text{ - text: "Remaining time for activation!!!" - color: qgcPal.buttonText - font.pixelSize: ScreenTools.defaultFontPixelWidth * 2.5 - font.bold: true - horizontalAlignment: Text.AlignHCenter - anchors.horizontalCenter: parent.horizontalCenter - visible: true - } + UTMSPNotificationSlider{ + id: notificationslider + overlay: overlayRect + } - Text { - text: timeDifference - color: qgcPal.buttonText - font.pixelSize: ScreenTools.defaultFontPixelWidth * 3.667 - font.bold: true - horizontalAlignment: Text.AlignHCenter - anchors.horizontalCenter: parent.horizontalCenter - } + Rectangle{ + id: overlayRect + width: notificationslider.width + 20 + height: 40 + radius: 3 + color: qgcPal.window + opacity: 0.8 + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.leftMargin: ScreenTools.defaultFontPixelHeight * 3.75 + anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 3.4 + visible: false - Row{ - spacing: ScreenTools.defaultFontPixelWidth * 0.5 - anchors.horizontalCenter: parent.horizontalCenter - Text { - text: "FLIGHT ID: " - color: qgcPal.buttonText - font.pixelSize: ScreenTools.defaultFontPixelWidth * 2.5 - font.bold: true - horizontalAlignment: Text.AlignHCenter + Column{ + spacing: 5 + anchors.verticalCenter: parent.verticalCenter + Row { + x: 100 + Text{ + text: "Serial-Number: " + color: "white" + font.pointSize: 7 + font.bold: true } - Text { - text: flightID - color: qgcPal.buttonText - font.pixelSize: ScreenTools.defaultFontPixelWidth * 2.5 - horizontalAlignment: Text.AlignHCenter + Text{ + text: UTMSPStateStorage.serialNumber + color: "white" + font.pointSize: 7 } } - Row{ - spacing: ScreenTools.defaultFontPixelWidth * 0.5 - anchors.horizontalCenter: parent.horizontalCenter - Text { - text: "STATUS: " - color: qgcPal.buttonText - font.pixelSize: ScreenTools.defaultFontPixelWidth * 2.5 - font.bold: true - horizontalAlignment: Text.AlignHCenter + Row { + x: 100 + Text{ + text: "FlightID: " + color: "white" + font.pointSize: 7 + font.bold: true } - Text { - id: approvetag - text: "Approved" - color: qgcPal.colorOrange - font.pixelSize: ScreenTools.defaultFontPixelWidth * 3 - horizontalAlignment: Text.AlignHCenter - visible: true - font.bold: true - } - - Text { - id: activatetag - text: "Activated" - color: qgcPal.colorGreen - font.pixelSize: ScreenTools.defaultFontPixelWidth * 3 - horizontalAlignment: Text.AlignHCenter - visible: false - font.bold: true - } - Text { - id: failtag - text: "Activation Failed" - color: qgcPal.colorRed - font.pixelSize: ScreenTools.defaultFontPixelWidth * 3 - horizontalAlignment: Text.AlignHCenter - visible: false - font.bold: true + Text{ + text: UTMSPStateStorage.flightID + color: "white" + font.pointSize: 7 } } + } } + + UTMSPFlightStatusIndicator { + //TODO: add conformance notification + } + } diff --git a/src/UTMSP/UTMSPAdapterEditor.qml b/src/UTMSP/UTMSPAdapterEditor.qml index ec7da943398e..041786c18952 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -36,28 +36,23 @@ QGCFlickable { property var mapControl property var flightMap property var currentMissionItems - property int currentYear : new Date().getFullYear() - property int currentMonth : new Date().getMonth() + 1 - property int currentHour : (new Date()).getHours() - property int currentMin : (new Date()).getMinutes() - property int currentDate : (new Date()).getDay() property var myActiveVehicle : QGroundControl.multiVehicleManager.activeVehicle property var flightID property var startTimeStamp property bool submissionFlag - property bool approvalFlag property bool triggerSubmitButton property bool resetRegisterFlightPlan + property var endDay + property var endMonth + property var endYear readonly property real _editFieldWidth: Math.min(width - _margin * 2, ScreenTools.defaultFontPixelWidth * 15) readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2 readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2 // Send parameters to PlanView qml - signal responseSent(string response, bool responseFlag) // Send the flight blender response to PlanVeiw signal vehicleIDSent(string id) // Send Vehcile ID to PlanView signal resetGeofencePolygonTriggered() // Send FlightPlan Trigger Value to PlanView - signal timeStampSent(string timestamp, bool activateflag, string id) // Send the flight timestamp to UTMSPActivationStatusBar signal removeFlightPlanTriggered() // Set default Geofence Polygon @@ -68,6 +63,18 @@ QGCFlickable { myGeoFenceController.addInclusionPolygon(topLeftCoord,bottomRightCoord) } + function loadEndDateTime(){ + var endHour = endhours.model[endhours.currentIndex] + var startHour = starthours.model[starthours.currentIndex] + var endDate = new Date(); + if (endHour < startHour){ + endDate.setDate(endDate.getDate() + 1); + } + endDay = endDate.getDate(); + endMonth = endDate.getMonth() + 1; + endYear = endDate.getFullYear(); + } + Rectangle { id: utmspEditorRect anchors.left: parent.left @@ -153,9 +160,9 @@ QGCFlickable { // Logout button QGCButton{ - width: ScreenTools.defaultFontPixelWidth * 7.5 - height: ScreenTools.defaultFontPixelHeight * 1.389 - text: "Logout" + text: qsTr("Logout") + width: ScreenTools.defaultFontPixelWidth * 7.8 + height: ScreenTools.defaultFontPixelHeight * 2 visible: !UTMSPStateStorage.loginState onClicked:{ UTMSPStateStorage.loginState = !UTMSPStateStorage.loginState @@ -165,6 +172,13 @@ QGCFlickable { removeFlightPlanTriggered() geoSwitch.enabled = true UTMSPStateStorage.removeFlightPlanState + + UTMSPStateStorage.indicatorIdleStatus = true + UTMSPStateStorage.indicatorApprovedStatus = false + UTMSPStateStorage.indicatorActivatedStatus = false + UTMSPStateStorage.indicatorDisplayStatus = false + UTMSPStateStorage.currentStateIndex = 0 + UTMSPStateStorage.currentNotificationIndex = 5 } } @@ -177,7 +191,6 @@ QGCFlickable { Row{ spacing: _margin * 5 - visible: UTMSPStateStorage.loginState QGCLabel{ id: notifyText @@ -219,7 +232,7 @@ QGCFlickable { spacing:_margin * 1.667 QGCLabel { text: qsTr("User ID") } - FactTextField { + QGCTextField { id: userName width: ScreenTools.defaultFontPixelWidth * 50 height: ScreenTools.defaultFontPixelHeight * 1.667 @@ -235,7 +248,7 @@ QGCFlickable { spacing: _margin * 1.5 QGCLabel { text: qsTr("Password:") } - FactTextField { + QGCTextField { id: password width: ScreenTools.defaultFontPixelWidth * 50 height: ScreenTools.defaultFontPixelHeight * 1.667 @@ -280,6 +293,8 @@ QGCFlickable { delayTimer.interval = 2500 delayTimer.repeat = false delayTimer.start() + UTMSPStateStorage.indicatorDisplayStatus = true + UTMSPStateStorage.currentNotificationIndex = 1 } else{ errorLogin.visible = true @@ -437,8 +452,15 @@ QGCFlickable { deletePolygon.visible = true deleteFlightPlan.visible = false } + }else { + myGeoFenceController.deletePolygon(0) } } + + ListView { + id: deletePolygon + model: myGeoFenceController.polygons + } } Row{ @@ -565,23 +587,6 @@ QGCFlickable { } } - Row { - ListView { - id: deletePolygon - model: myGeoFenceController.polygons - delegate: QGCButton { - text: qsTr("Delete") - width: ScreenTools.defaultFontPixelWidth * 6.667 - height: ScreenTools.defaultFontPixelHeight * 1.667 - x: ScreenTools.defaultFontPixelWidth * 43 - y: ScreenTools.defaultFontPixelHeight * 2 - onClicked: { - myGeoFenceController.deletePolygon(index) - geoSwitch.checked =false - } - } - } - } } // Date Interface @@ -1285,36 +1290,38 @@ QGCFlickable { submissionTimer.interval = 2500 submissionTimer.repeat = false submissionTimer.start() - var minAltitude = minSlider.value.toFixed(0) - var maxAltitude = maxSlider.value.toFixed(0) - var sday = scrollDate.model[scrollDate.currentIndex] - var smonth = scrollMonth.currentIndex + 1 - var syear = scrollYear.model[scrollYear.currentIndex] - var shour = starthours.model[starthours.currentIndex] - var sminute = startMinutes.model[startMinutes.currentIndex] - var ssecond = startSeconds.model[startSeconds.currentIndex] - var ehour = endhours.model[endhours.currentIndex] - var eminute = endMinutes.model[endMinutes.currentIndex] - var esecond = endSeconds.model[endSeconds.currentIndex] - var st = syear + "-" + smonth + "-" + sday + "T" + shour + ":" + sminute + ":" + ssecond+ "." + "000000" + "Z" - var et = syear + "-" + smonth + "-" + sday + "T" + ehour + ":" + eminute + ":" + esecond+ "." + "000000" + "Z" - var activateTD = syear + "-" + String(smonth).padStart(2, '0') + "-" + String(sday).padStart(2, '0') + "T" + String(shour).padStart(2, '0') + ":" + String(sminute).padStart(2, '0') + ":" + String(ssecond).padStart(2, '0') + "." + "000000" + "Z" + loadEndDateTime() + var minAltitude = minSlider.value.toFixed(0) + var maxAltitude = maxSlider.value.toFixed(0) + var startDay = scrollDate.model[scrollDate.currentIndex] + var startMonth = scrollMonth.currentIndex + 1 + var startYear = scrollYear.model[scrollYear.currentIndex] + var startHour = starthours.model[starthours.currentIndex] + var startMinute = startMinutes.model[startMinutes.currentIndex] + var startSecond = startSeconds.model[startSeconds.currentIndex] + var endHour = endhours.model[endhours.currentIndex] + var endMinute = endMinutes.model[endMinutes.currentIndex] + var endSecond = endSeconds.model[endSeconds.currentIndex] + var startDateTime = startYear + "-" + startMonth + "-" + startDay + "T" + startHour + ":" + startMinute + ":" + startSecond+ "." + "000000" + "Z" + var endDateTime = endYear + "-" + endMonth + "-" + endDay + "T" + endHour + ":" + endMinute + ":" + endSecond+ "." + "000000" + "Z" + var activateTD = startYear + "-" + String(startMonth).padStart(2, '0') + "-" + String(startDay).padStart(2, '0') + "T" + String(startHour).padStart(2, '0') + ":" + String(startMinute).padStart(2, '0') + ":" + String(startSecond).padStart(2, '0') + "." + "000000" + "Z" resetGeofencePolygonTriggered() myGeoFenceController.loadFlightPlanData() - QGroundControl.utmspManager.utmspVehicle.updateStartDateTime(st.toString()) - QGroundControl.utmspManager.utmspVehicle.updateEndDateTime(et.toString()) + QGroundControl.utmspManager.utmspVehicle.updateStartDateTime(startDateTime.toString()) + QGroundControl.utmspManager.utmspVehicle.updateEndDateTime(endDateTime.toString()) QGroundControl.utmspManager.utmspVehicle.updateMinAltitude(minAltitude) QGroundControl.utmspManager.utmspVehicle.updateMaxAltitude(maxAltitude) QGroundControl.utmspManager.utmspVehicle.triggerFlightAuthorization() var responseFlightID = QGroundControl.utmspManager.utmspVehicle.responseFlightID - var responseFlag = QGroundControl.utmspManager.utmspVehicle.responseFlag - var responseJson = QGroundControl.utmspManager.utmspVehicle.responseJson + var responseFlag = QGroundControl.utmspManager.utmspVehicle.activationFlag var serialNumber = QGroundControl.utmspManager.utmspVehicle.vehicleSerialNumber vehicleIDSent(serialNumber) flightID = responseFlightID - startTimeStamp = activateTD submissionFlag = responseFlag - responseSent(responseJson,responseFlag) + UTMSPStateStorage.startTimeStamp = activateTD + UTMSPStateStorage.showActivationTab = responseFlag + UTMSPStateStorage.flightID = flightID + UTMSPStateStorage.serialNumber = serialNumber } } @@ -1324,13 +1331,17 @@ QGCFlickable { onTriggered: { if(submissionFlag === true) { - approvalFlag = myGeoFenceController.loadUploadFlag() - timeStampSent(startTimeStamp,approvalFlag,flightID) + UTMSPStateStorage.enableMissionUploadButton = true submitFlightPlan.visible = false geoSwitch.checked = false deletePolygon.visible = false deleteFlightPlan.visible = true geoSwitch.enabled = false + UTMSPStateStorage.indicatorIdleStatus = false + UTMSPStateStorage.indicatorApprovedStatus = true + UTMSPStateStorage.indicatorDisplayStatus = true + UTMSPStateStorage.currentStateIndex = 1 + UTMSPStateStorage.currentNotificationIndex = 2 } else{ submitFlightPlan.enabled = true @@ -1349,6 +1360,17 @@ QGCFlickable { deleteFlightPlan.visible = false geoSwitch.enabled = true QGroundControl.utmspManager.utmspVehicle.triggerActivationStatusBar(false) + QGroundControl.utmspManager.utmspVehicle.loadTelemetryFlag(false) + UTMSPStateStorage.startTimeStamp = "" + UTMSPStateStorage.showActivationTab = false + UTMSPStateStorage.flightID = "" + UTMSPStateStorage.enableMissionUploadButton = false + UTMSPStateStorage.indicatorIdleStatus = true + UTMSPStateStorage.indicatorApprovedStatus = false + UTMSPStateStorage.indicatorActivatedStatus = false + UTMSPStateStorage.indicatorDisplayStatus = false + UTMSPStateStorage.currentStateIndex = 0 + UTMSPStateStorage.currentNotificationIndex = 6 } } } diff --git a/src/UTMSP/UTMSPAircraft.h b/src/UTMSP/UTMSPAircraft.h index ad1c5815d398..a35fdd7c0c22 100644 --- a/src/UTMSP/UTMSPAircraft.h +++ b/src/UTMSP/UTMSPAircraft.h @@ -9,11 +9,10 @@ #pragma once +#include "mavlink_types.h" #include #include -typedef struct __mavlink_message_t mavlink_message_t; - class UTMSPAircraft { public: UTMSPAircraft(); diff --git a/src/UTMSP/UTMSPAuthorization.cpp b/src/UTMSP/UTMSPAuthorization.cpp index 35e9871048b4..efd2c1d06401 100644 --- a/src/UTMSP/UTMSPAuthorization.cpp +++ b/src/UTMSP/UTMSPAuthorization.cpp @@ -7,21 +7,19 @@ * ****************************************************************************/ -#include #include +#include +#include +#include +#include #include "UTMSPLogger.h" #include "UTMSPAuthorization.h" using json = nlohmann::ordered_json; -UTMSPAuthorization::UTMSPAuthorization(): - UTMSPRestInterface("passport.utm.dev.airoplatform.com") -{ - -} - -UTMSPAuthorization::~UTMSPAuthorization() +UTMSPAuthorization::UTMSPAuthorization(QObject *parent): + QObject(parent) { } @@ -30,37 +28,14 @@ thread_local std::string clientToken = ""; bool UTMSPAuthorization::requestOAuth2Client(const QString &clientID, const QString &clientSecret) { - // Convert QString to std::string - _clientID = clientID.toStdString(); - _clientSecret = clientSecret.toStdString(); - - // Generate the basic Token - std::string combinedCredential = _clientID + ":" + _clientSecret; - BIO *bio, *b64; - BUF_MEM *bufferPtr; - - b64 = BIO_new(BIO_f_base64()); - bio = BIO_new(BIO_s_mem()); - bio = BIO_push(b64, bio); - - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); - BIO_write(bio, combinedCredential.c_str(), combinedCredential.length()); - BIO_flush(bio); - BIO_get_mem_ptr(bio, &bufferPtr); - BIO_set_close(bio, BIO_NOCLOSE); - BIO_free_all(bio); - - std::string encodedBasicToken(bufferPtr->data, bufferPtr->length); - BUF_MEM_free(bufferPtr); - setBasicToken(encodedBasicToken); - - // Get the Access Token - setHost("AuthClient"); - connectNetwork(); - const std::string target = "/oauth/token/"; - std::string body = "grant_type=client_credentials&scope=blender.write blender.read&audience=blender.utm.dev.airoplatform.com&client_id=" + _clientID + "&client_secret=" + _clientSecret + "\r\n\r\n"; - modifyRequest(target, http::verb::post, body); - auto [status, response] = executeRequest(); + QString combinedCredential = clientID + ":" + clientSecret; + QString encodedBasicToken = combinedCredential.toUtf8().toBase64(); + _utmspRestInterface.setBasicToken(encodedBasicToken); + _utmspRestInterface.setHost("AuthClient"); + const QString target = "/oauth/token/"; + QString body = "grant_type=client_credentials&scope=blender.write blender.read&audience=testflight.flightblender.com&client_id=" + clientID + "&client_secret=" + clientSecret + "\r\n\r\n"; + _utmspRestInterface.modifyRequest(target, QNetworkAccessManager::PostOperation, body); + auto [status, response] = _utmspRestInterface.executeRequest(); UTMSP_LOG_INFO() << "UTMSPAuthorization: Authorization Response: " << response; if(status == 200) diff --git a/src/UTMSP/UTMSPAuthorization.h b/src/UTMSP/UTMSPAuthorization.h index 852ee17c4b47..de82af82575a 100644 --- a/src/UTMSP/UTMSPAuthorization.h +++ b/src/UTMSP/UTMSPAuthorization.h @@ -14,23 +14,22 @@ #include "UTMSPRestInterface.h" -class UTMSPAuthorization: public QObject, public UTMSPRestInterface +class UTMSPAuthorization: public QObject { Q_OBJECT public: - UTMSPAuthorization(); - ~UTMSPAuthorization(); + UTMSPAuthorization(QObject *parent = nullptr); + virtual ~UTMSPAuthorization() = default; const std::string& getOAuth2Token(); + std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len); protected slots: bool requestOAuth2Client(const QString& clientID, const QString& clientSecret); -protected: - http::request _request; - private: - std::string _clientID; - std::string _clientSecret; bool _isValidToken; + UTMSPRestInterface _utmspRestInterface; + + static const std::string base64_chars; }; diff --git a/src/UTMSP/UTMSPBlenderRestInterface.cpp b/src/UTMSP/UTMSPBlenderRestInterface.cpp index 68c02b456ed3..f5e17882b230 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.cpp +++ b/src/UTMSP/UTMSPBlenderRestInterface.cpp @@ -9,34 +9,43 @@ #include "UTMSPBlenderRestInterface.h" -UTMSPBlenderRestInterface::UTMSPBlenderRestInterface(): - UTMSPRestInterface("blender.utm.dev.airoplatform.com") +UTMSPBlenderRestInterface::UTMSPBlenderRestInterface(QObject *parent): + UTMSPRestInterface(parent) { - + setHost("BlenderClient"); } -std::pair UTMSPBlenderRestInterface::setFlightPlan(const std::string& body) +QPair UTMSPBlenderRestInterface::setFlightPlan(const std::string& body) { // Post Flight plan - const std::string setFlightPlanTarget = "/flight_declaration_ops/set_flight_declaration"; - modifyRequest(setFlightPlanTarget, http::verb::post, body); + QString setFlightPlanTarget = "/flight_declaration_ops/set_flight_declaration"; + modifyRequest(setFlightPlanTarget, QNetworkAccessManager::PostOperation, QString::fromStdString(body)); + + return executeRequest(); +} + +QPair UTMSPBlenderRestInterface::requestTelemetry(const std::string& body) +{ + // Post RID data + QString target = "/flight_stream/set_telemetry"; + modifyRequest(target, QNetworkAccessManager::PutOperation, QString::fromStdString(body)); return executeRequest(); } -std::pair UTMSPBlenderRestInterface::requestTelemetry(const std::string& body) +QPair UTMSPBlenderRestInterface::updateFlightState(const std::string& body, const std::string &flightID) { // Post RID data - const std::string target = "/flight_stream/set_telemetry"; - modifyRequest(target, http::verb::put, body); + QString target = "/flight_declaration_ops/flight_declaration_state/" + QString::fromStdString(flightID); + modifyRequest(target, QNetworkAccessManager::PutOperation, QString::fromStdString(body)); return executeRequest(); } -std::pair UTMSPBlenderRestInterface::ping() +QPair UTMSPBlenderRestInterface::ping() { - const std::string target = "/ping"; - modifyRequest(target, http::verb::get); + QString target = "/ping"; + modifyRequest(target, QNetworkAccessManager::GetOperation); return executeRequest(); } diff --git a/src/UTMSP/UTMSPBlenderRestInterface.h b/src/UTMSP/UTMSPBlenderRestInterface.h index 841d65dcdd14..7f09e4214cc3 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.h +++ b/src/UTMSP/UTMSPBlenderRestInterface.h @@ -11,15 +11,17 @@ #include "UTMSPRestInterface.h" +#include +#include + class UTMSPBlenderRestInterface: public UTMSPRestInterface { public: - UTMSPBlenderRestInterface(); + UTMSPBlenderRestInterface(QObject *parent = nullptr); - std::pair setFlightPlan(const std::string& body); - std::pair requestTelemetry(const std::string& body); - std::pair ping(); + QPair setFlightPlan(const std::string& body); + QPair requestTelemetry(const std::string& body); + QPair updateFlightState(const std::string& body, const std::string& flightID); + QPair ping(); -private: - http::request _request; }; diff --git a/src/UTMSP/UTMSPFlightPlanManager.cpp b/src/UTMSP/UTMSPFlightPlanManager.cpp index e40a09f8a597..785aeffd055e 100644 --- a/src/UTMSP/UTMSPFlightPlanManager.cpp +++ b/src/UTMSP/UTMSPFlightPlanManager.cpp @@ -9,6 +9,7 @@ #include "UTMSPFlightPlanManager.h" #include "UTMSPLogger.h" +#include UTMSPFlightPlanManager::UTMSPFlightPlanManager(): _currentState(FlightState::Idle), @@ -51,6 +52,8 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, this->_flightData.user = "user@example.com"; //TODO this->_flightData.operation = 1; this->_flightData.party = "Flight 1023"; //TODO + this->_flightData.aircraftID = "Test Flight-01"; //TODO : Replace with actual ID + this->_flightData.gcsID = "Test GCS-01"; //TODO : Replace with actual ID this->_flightData.startDateTime = startDateTime; this->_flightData.endDateTime = endDateTime; this->_flightData.flightDeclaration.type = "FeatureCollection"; @@ -62,6 +65,7 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, this->_flightData.flightDeclaration.features.geometry.type = "Polygon"; this->_flightData.flightDeclaration.features.geometry.coordinates = boundaryPolygons; + _flightDataJson.clear(); // Generate GeoJson for flight plan @@ -69,6 +73,8 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, _flightDataJson["submitted_by"] = this->_flightData.user; _flightDataJson["type_of_operation"]= this->_flightData.operation; _flightDataJson["originating_party"]= this->_flightData.party; + _flightDataJson["aircraft_id"]=this->_flightData.aircraftID ; + _flightDataJson["gcs_id"]=this->_flightData.gcsID; _flightDataJson["start_datetime"]= this->_flightData.startDateTime; _flightDataJson["end_datetime"] = this->_flightData.endDateTime; _flightDataJson["flight_declaration_geo_json"]["type"] = this->_flightData.flightDeclaration.type; @@ -96,12 +102,11 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, json data = _flightDataJson; setHost("BlenderClient"); - connectNetwork(); setBearerToken(token); auto [statusCode, response] = setFlightPlan(data.dump(4)); UTMSP_LOG_INFO() << "UTMSPFlightPlanManager: Register Response -->" << response; - if(statusCode == 201) + if(statusCode == 200) { try { json jsonData = json::parse(response); @@ -130,9 +135,33 @@ std::tuple UTMSPFlightPlanManager::registerFligh return std::make_tuple(_responseJSON, _flightResponseID, _responseStatus); } -void UTMSPFlightPlanManager::activateFlightPlan() +bool UTMSPFlightPlanManager::activateFlightPlan(const std::string &token) { //TODO : Plan for conformance Monitering phase 2 + _updateState["state"] = 2; + _updateState["submitted_by"] = this->_flightData.user; + json data = _updateState; + std::cout << data.dump(4) << std::endl; + setHost("BlenderClient"); + setBearerToken(token); + auto [statusCode, response] = updateFlightState(data.dump(4), _flightResponseID); + + if(statusCode == 200) + { + try { + UTMSP_LOG_DEBUG() << "Update flight plan response" << response; + return true; + } + catch (const json::parse_error& e) { + UTMSP_LOG_ERROR() << "UTMSPFlightPlanManager: Error parsing the response: " << e.what(); + return false; + } + } + else + { + UTMSP_LOG_ERROR() << "UTMSPFlightPlanManager: Invalid Status Code"; + return false; + } } void UTMSPFlightPlanManager::activateFlightPlanNotification() diff --git a/src/UTMSP/UTMSPFlightPlanManager.h b/src/UTMSP/UTMSPFlightPlanManager.h index b771283aec43..691ad475fef3 100644 --- a/src/UTMSP/UTMSPFlightPlanManager.h +++ b/src/UTMSP/UTMSPFlightPlanManager.h @@ -41,7 +41,7 @@ class UTMSPFlightPlanManager: public UTMSPBlenderRestInterface const std::string& startDateTime, const std::string& endDateTime); std::tuple registerFlightPlanNotification(); - void activateFlightPlan(); + bool activateFlightPlan(const std::string &token); void activateFlightPlanNotification(); void updateFlightPlanState(FlightState state); FlightState getFlightPlanState(); @@ -83,6 +83,8 @@ class UTMSPFlightPlanManager: public UTMSPBlenderRestInterface struct FlightData{ std::string user; int operation; + std::string aircraftID; + std::string gcsID; std::string party; std::string startDateTime; std::string endDateTime; @@ -96,4 +98,5 @@ class UTMSPFlightPlanManager: public UTMSPBlenderRestInterface std::string _responseJSON; bool _responseStatus; std::string _flightResponseID; + json _updateState; }; diff --git a/src/UTMSP/UTMSPFlightStatusIndicator.qml b/src/UTMSP/UTMSPFlightStatusIndicator.qml new file mode 100644 index 000000000000..af641b61dd88 --- /dev/null +++ b/src/UTMSP/UTMSPFlightStatusIndicator.qml @@ -0,0 +1,131 @@ +/**************************************************************************** + * + * (c) 2023 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Dialogs +import QtQuick.Controls +import QtPositioning +import QtLocation + +import QGroundControl +import QGroundControl.FlightMap +import QGroundControl.ScreenTools +import QGroundControl.Controls +import QGroundControl.FactSystem +import QGroundControl.FactControls +import QGroundControl.Palette +import QGroundControl.Controllers +import QGroundControl.ShapeFileHelper +import QGroundControl.UTMSP +import QGroundControl.FlightDisplay +import QGroundControl.MultiVehicleManager + +//Indicator + +Rectangle { + id: statusCircle + width: ScreenTools.defaultFontPixelHeight * 7.5 + height: ScreenTools.defaultFontPixelHeight * 7.5 + radius: width / 2 + color: qgcPal.window + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 0.3 + anchors.leftMargin: ScreenTools.defaultFontPixelHeight * 1.25 + visible: true + + property var ledImages: ["qrc:/utmsp/yellow_led.png", + "qrc:/utmsp/orange_led.png", + "qrc:/utmsp/pale_green.png", + "qrc:/utmsp/parrot_green.png", + "qrc:/utmsp/green_led.png"] + + property var statusBarColor: ["#bcc21b", + "#f0a351", + "#2edbc1", + "#9cbf43", + "#31870f" ] + + property var flightState: ["IDLE", + "APPROVED", + "ACTIVATED", + "ON MISSION", + "COMPLETED"] + + property var progressPercentage: [0, 0.25, 0.50, 0.75, 1] + property int currentIndex: UTMSPStateStorage.currentStateIndex + + + Rectangle { + width: statusCircle.width + height: statusCircle.height + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + radius: width / 2 + color: qgcPal.window + border.color: "white" + border.width: 3 + opacity: .5 + } + + Text{ + text: "Flight Status" + color: "white" + y: 30 + font.bold: true + font.pointSize: 8 + anchors.horizontalCenter: parent.horizontalCenter + } + + + Rectangle { + width: ScreenTools.defaultFontPixelHeight * 5.5 + height: ScreenTools.defaultFontPixelHeight * 1.5 + color: statusBarColor[currentIndex] + border.color: "white" + radius: 10 + x: 17 + y: 50 + opacity: 0.9 + + Text { + text: flightState[currentIndex] + color: "white" + x: 17 + anchors.verticalCenter: parent.verticalCenter + font.pointSize: 9 + } + } + + Rectangle { + width: 50 + height: 10 + radius: 8 + color: "#2f2f2f" + x: 32 + y: 90 + border.color: "white" + + Rectangle { + width: parent.width * progressPercentage[currentIndex] + height: parent.height + radius: parent.radius + color: statusBarColor[currentIndex] + } + } + + Image { + width: 10 + height: 10 + source: ledImages[currentIndex] + x: 87 + y: 90 + } +} diff --git a/src/UTMSP/UTMSPLogger.h b/src/UTMSP/UTMSPLogger.h index 34a2945229a6..1858c868b248 100644 --- a/src/UTMSP/UTMSPLogger.h +++ b/src/UTMSP/UTMSPLogger.h @@ -9,7 +9,7 @@ #pragma once -#if defined (CONFIG_UTM_ADAPTER) +#if defined (QGC_UTM_ADAPTER) #include inline QDebug operator<<(QDebug debug, const std::string &s) { diff --git a/src/UTMSP/UTMSPManager.cpp b/src/UTMSP/UTMSPManager.cpp index d35956e53177..2b85be827185 100644 --- a/src/UTMSP/UTMSPManager.cpp +++ b/src/UTMSP/UTMSPManager.cpp @@ -9,10 +9,11 @@ #include "UTMSPManager.h" -#include "UTMSPVehicle.h" #include "UTMSPLogger.h" + #include "services/dispatcher.h" #include "Vehicle.h" +#include "qqml.h" UTMSPManager::UTMSPManager(QGCApplication* app, QGCToolbox* toolbox) : QGCTool(app, toolbox), diff --git a/src/UTMSP/UTMSPManager.h b/src/UTMSP/UTMSPManager.h index 3e061e4bc9ef..a11a63d1fc61 100644 --- a/src/UTMSP/UTMSPManager.h +++ b/src/UTMSP/UTMSPManager.h @@ -11,6 +11,8 @@ #include "QGCToolbox.h" +#include "UTMSPVehicle.h" + class UTMSPVehicle; class Vehicle; class Dispatcher; diff --git a/src/UTMSP/UTMSPMapPolygonVisuals.qml b/src/UTMSP/UTMSPMapPolygonVisuals.qml index 4225865c8313..84f298fb41b4 100644 --- a/src/UTMSP/UTMSPMapPolygonVisuals.qml +++ b/src/UTMSP/UTMSPMapPolygonVisuals.qml @@ -641,7 +641,7 @@ Item { availableWidth: mapControl.centerViewport.width QGCButton { - _horizontalPadding: 0 + _horizontalPadding: 2 text: qsTr("Automatic") visible: !mapPolygon.traceMode onClicked: _resetPolygon() @@ -649,7 +649,7 @@ Item { QGCButton { - _horizontalPadding: 0 + _horizontalPadding: 2 text: mapPolygon.traceMode ? qsTr("Done fencing") : qsTr("Mannual") onClicked: { if (mapPolygon.traceMode) { diff --git a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp index 3793f4eea833..d026c26b8635 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -9,7 +9,6 @@ #include "UTMSPNetworkRemoteIDManager.h" #include "UTMSPLogger.h" -#include "services/dispatcher.h" UTMSPNetworkRemoteIDManager::UTMSPNetworkRemoteIDManager(std::shared_ptr dispatcher): _dispatcher(dispatcher) @@ -24,8 +23,7 @@ UTMSPNetworkRemoteIDManager::~UTMSPNetworkRemoteIDManager() void UTMSPNetworkRemoteIDManager::getCapabilty(const std::string &token) { - connectNetwork(); - setBearerToken(token); + setBearerToken(token.c_str()); } void UTMSPNetworkRemoteIDManager::startTelemetry(const double &latitude, @@ -146,41 +144,31 @@ void UTMSPNetworkRemoteIDManager::startTelemetry(const double &latitude, final_format["observations"] = final_array; json data = final_format; - // Get the RID response - _dispatcher->add_task([data,this]() { - auto [statusCode, response] = requestTelemetry(data.dump(4)); - _statusCode = statusCode; - _response = response; - }); - - if(!_response.empty()){ - - if(_statusCode == 201) - { - try { - json responseJson = json::parse(_response); - _response.clear(); - if (responseJson.contains("message")){ - if(responseJson["message"] == "Telemetry data succesfully submitted"){ - - auto now = std::chrono::system_clock::now(); - std::time_t now_c = std::chrono::system_clock::to_time_t(now); - char buffer[20]; - std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&now_c)); - UTMSP_LOG_DEBUG() <<"The Telemetry RID data submitted at " << buffer; - UTMSP_LOG_DEBUG() << "--------------Telemetry Submitted Successfully---------------"; - } - } - } - catch (const json::parse_error& e) { - UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Error parsing the response: " << e.what(); - } + auto [statusCode, response] = requestTelemetry(data.dump(4)); + _statusCode = statusCode; + _response = response; + UTMSP_LOG_DEBUG()<< "Response " << _response; + UTMSP_LOG_DEBUG()<< "Status Code: " << _statusCode; + + if(_statusCode == 201) + { + try { + auto now = std::chrono::system_clock::now(); + std::time_t now_c = std::chrono::system_clock::to_time_t(now); + char buffer[20]; + std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&now_c)); + UTMSP_LOG_DEBUG() <<"The Telemetry RID data submitted at " << buffer; + UTMSP_LOG_DEBUG() << "--------------Telemetry Submitted Successfully---------------"; } - else - { - UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Invalid Status Code"; + catch (const json::parse_error& e) { + UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Error parsing the Telemetry response: " << e.what(); } } + else + { + UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Invalid Status Code"; + } + } bool UTMSPNetworkRemoteIDManager::stopTelemetry() diff --git a/src/UTMSP/UTMSPNetworkRemoteIDManager.h b/src/UTMSP/UTMSPNetworkRemoteIDManager.h index f7d1cee8f199..58174f589c4b 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.h +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.h @@ -10,6 +10,7 @@ #pragma once #include +#include "services/dispatcher.h" #include "UTMSPBlenderRestInterface.h" diff --git a/src/UTMSP/UTMSPNotificationSlider.qml b/src/UTMSP/UTMSPNotificationSlider.qml new file mode 100644 index 000000000000..dd039925e770 --- /dev/null +++ b/src/UTMSP/UTMSPNotificationSlider.qml @@ -0,0 +1,184 @@ +/**************************************************************************** + * + * (c) 2023 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick +import QtQuick.Layouts +import QtQuick.Dialogs +import QtQuick.Controls +import QtPositioning +import QtLocation + +import QGroundControl +import QGroundControl.FlightMap +import QGroundControl.ScreenTools +import QGroundControl.Controls +import QGroundControl.FactSystem +import QGroundControl.FactControls +import QGroundControl.Palette +import QGroundControl.Controllers +import QGroundControl.ShapeFileHelper +import QGroundControl.UTMSP +import QGroundControl.FlightDisplay +import QGroundControl.MultiVehicleManager + + +Rectangle { + id: _root + width: ScreenTools.defaultFontPixelHeight * 5.5 + height: ScreenTools.defaultFontPixelHeight * 3.2 + radius: 3 + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 0.3 + anchors.leftMargin: ScreenTools.defaultFontPixelHeight * 4.75 + color: qgcPal.window + opacity: 0.8 + clip: true + + property bool displayStatus: UTMSPStateStorage.indicatorDisplayStatus + property var overlay + property var indicatorTopText: ["No mission exist", + "You've logged in successfully!", + " Your Flight Plan is Approved!", + "Activation Time", + "Activated Successfully!", + "You've been logged out", + "You've deleted the flight plan", + "Hold Tight!", + "Mission Completed" + + + ] + property var indicatorBottomText: ["Login to Create a UTM Mission", + "Create a UTM Mission", + " Proceed to upload flight plan to vehcile", + UTMSPStateStorage.indicatorActivationTime, + "You are allowed to fly...", + "Login to Create a UTM Mission", + "Create a UTM Mission", + "Your Drone is on Mission" + ] + property int currentNotificationIndex: UTMSPStateStorage.currentNotificationIndex + + QGCMouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: overlay.visible = true + onExited: overlay.visible = false + + } + + Column { + spacing: 5 + anchors.centerIn: parent + + Text { + id: topNotificationText + color: "white" + visible: false + font.bold: true + font.pointSize: 10 + x: 10 + text : indicatorTopText[currentNotificationIndex] + } + + Text { + id: bottomNotificationText + color: "white" + visible: false + x: 10 + text : indicatorBottomText[currentNotificationIndex] + } + } + + QGCButton { + id: toggleButton + height: ScreenTools.defaultFontPixelHeight * 3.2 + width: 25 + + Text { + text: _root.width > ScreenTools.defaultFontPixelHeight * 5.5 ? "<<" : ">>" + font.bold: true + color: "white" + anchors.right: parent.right + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + } + + anchors.right: parent.right + onClicked: { + if (_root.width === ScreenTools.defaultFontPixelHeight * 5.5) { + expandAnimation.start(); + topNotificationText.visible = true + bottomNotificationText.visible = true + } else { + collapseAnimation.start(); + topNotificationText.visible = false + bottomNotificationText.visible = false + } + } + } + + onDisplayStatusChanged: { + if(displayStatus === true){ + topNotificationText.visible = true + bottomNotificationText.visible = true + expandAnimation.start(); + } + } + + + + Timer { + id: autoCollapseTimer + interval: 5000 + repeat: false + + onTriggered: { + if(UTMSPStateStorage.indicatorApprovedStatus === true){ + UTMSPStateStorage.indicatorDisplayStatus = true + } + + else{ + collapseAnimation.start(); + UTMSPStateStorage.indicatorDisplayStatus = false + topNotificationText.visible = false; + bottomNotificationText.visible = false; + } + + } + } + + + PropertyAnimation { + id: expandAnimation + target: _root + property: "width" + to: ScreenTools.defaultFontPixelHeight * 20 + duration: 1000 + onStopped: { + if (_root.width > ScreenTools.defaultFontPixelHeight * 5.5) { + topNotificationText.visible = true; + bottomNotificationText.visible = true; + autoCollapseTimer.start(); + } + } + } + + PropertyAnimation { + id: collapseAnimation + target: _root + property: "width" + to: ScreenTools.defaultFontPixelHeight * 5.5 + duration: 1000 + } + +} + + diff --git a/src/UTMSP/UTMSPRestInterface.cpp b/src/UTMSP/UTMSPRestInterface.cpp index 88a72501875d..8bac1a118bed 100644 --- a/src/UTMSP/UTMSPRestInterface.cpp +++ b/src/UTMSP/UTMSPRestInterface.cpp @@ -10,191 +10,100 @@ #include "UTMSPRestInterface.h" #include "UTMSPLogger.h" -#include -#include +#include +#include +#include "qeventloop.h" -UTMSPRestInterface::UTMSPRestInterface(std::string host, std::string port): - _ssl_ctx{boost::asio::ssl::context::tlsv13_client}, - _host(host), - _port(port) +UTMSPRestInterface::UTMSPRestInterface(QObject *parent): + QObject(parent) { - + _networkManager = new QNetworkAccessManager(this); } UTMSPRestInterface::~UTMSPRestInterface() { - + delete _networkManager; + _networkManager = nullptr; } -http::request UTMSPRestInterface::_request; - -bool isNetworkAvailable() +void UTMSPRestInterface::setHost(const QString &target) { - bool hasConnectivity = false; - - QList interfaces = QNetworkInterface::allInterfaces(); - for (const QNetworkInterface& interface : interfaces) { - - // Check if the interface is up and not loopback - if (interface.isValid() && interface.flags().testFlag(QNetworkInterface::IsUp) - && !interface.flags().testFlag(QNetworkInterface::IsLoopBack)) - { - hasConnectivity = true; - break; - } - } - - if (!hasConnectivity) - { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: No network/internet connectivity"; - } - return hasConnectivity; + if (target == "AuthClient") { + _currentURL = "https://id.openskies.sh"; + _currentRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + } else if (target == "BlenderClient") { + _currentURL = "https://testflight.flightblender.com"; + _currentRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + } + _currentRequest.setRawHeader("User-Agent", QString("Qt/%1").arg(QT_VERSION_STR).toUtf8()); + _currentRequest.setRawHeader("Accept", "*/*"); + _currentRequest.setRawHeader("Accept-Encoding", "gzip, deflate, br"); + _currentRequest.setRawHeader("Connection", "keep-alive"); + + QSslConfiguration sslConfig = QSslConfiguration::defaultConfiguration(); + sslConfig.setProtocol(QSsl::TlsV1_3); + _currentRequest.setSslConfiguration(sslConfig); } -void UTMSPRestInterface::setHost(std::string target) -{ - _request.set(http::field::content_length, 0); - _request.version(11); - _request.set(boost::beast::http::field::user_agent, BOOST_BEAST_VERSION_STRING); - - if(target == "AuthClient"){ - _request.set(http::field::host, "passport.utm.dev.airoplatform.com"); - _request.set(http::field::content_type, "application/x-www-form-urlencoded"); - } - else if(target == "BlenderClient"){ - _request.set(http::field::host, "blender.utm.dev.airoplatform.com"); - _request.set(http::field::content_type, "application/json"); - } - - _request.set(http::field::accept, "*/*"); - _request.set(http::field::accept_encoding, "gzip, deflate, br"); - _request.set(http::field::connection, "keep-alive"); -} - -void UTMSPRestInterface::setBasicToken(const std::string &basicToken){ +void UTMSPRestInterface::setBasicToken(const QString &basicToken){ _basicToken = basicToken; - _request.set(http::field::authorization, "Basic "+ _basicToken); + _currentRequest.setRawHeader("Authorization", ("Basic " + _basicToken).toUtf8()); } -bool UTMSPRestInterface::connectNetwork() +void UTMSPRestInterface::modifyRequest(const QString &target, QNetworkAccessManager::Operation method, const QString &body) { - if (!isNetworkAvailable()) - return ""; - - _ssl_ctx.set_default_verify_paths(); - _stream = QSharedPointer>::create(_ioc, _ssl_ctx); - - if (!SSL_set_tlsext_host_name(_stream->native_handle(), _host.c_str())) - { - boost::system::error_code ec{ static_cast(::ERR_get_error()), boost::asio::error::get_ssl_category() }; - throw boost::system::system_error{ ec }; - } - - boost::system::error_code ec; - - const auto results = _resolver.resolve(_host, _port, ec); - - if (ec) - { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during resolving: " << ec.message(); - return false; - } - else - { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: Resolving successfull"; - } - - boost::asio::connect(_stream->lowest_layer(), results.begin(), results.end(), ec); - - if (ec) - { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during connection: " << ec.message(); - return false; - } - else - { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: Connection successfull"; - } - - _stream->set_verify_mode(boost::asio::ssl::verify_peer, ec); - if (ec) - { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during set_verify_mode: " << ec.message(); - return false; - } - else - { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: set_verify_mode successfull"; - } - - _stream->handshake(boost::asio::ssl::stream_base::client, ec); - if (ec) - { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during handshake: " << ec.message(); - return false; - } - else - { - UTMSP_LOG_INFO() << "UTMSPRestInterfaceLog: Handshake successfull"; - } - - return true; - -} - -void UTMSPRestInterface::modifyRequest(std::string target, http::verb method, std::string body) -{ - _request.target(target); - _request.method(method); - _request.body() = body; - _request.prepare_payload(); + QUrl url(_currentURL+target); + _currentRequest.setUrl(url); + _currentMethod = method; + _currentBody = body; } -std::pair UTMSPRestInterface::executeRequest() +QPair UTMSPRestInterface::executeRequest() { - if (!isNetworkAvailable()) - return std::pair(0,""); - - // sendRequest - std::lock_guard lock_guard(_mutex); - boost::system::error_code ec; - beast::http::write(*_stream.data(), _request, ec); - - if (ec) { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during connection: " << ec.message(); - } else { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: Write successfull"; - } - - // ReceivedResponse - beast::flat_buffer buffer; - http::response response; - http::read(*_stream.data(), buffer, response, ec); - - if (ec) { - UTMSP_LOG_ERROR() << "UTMSPRestInterfaceLog: Error during connection: " << ec.message(); - } else { - UTMSP_LOG_DEBUG() << "UTMSPRestInterfaceLog: Read successfull"; - } - - if (response.result() == beast::http::status::ok) - { - // Handle successful response - UTMSP_LOG_INFO() << "UTMSPRestInterfaceLog: Received OK response."; - } - else - { - UTMSP_LOG_INFO() << "UTMSPRestInterfaceLog: Received response with status code: "<< response.result_int(); - } - if (response.body().size() == 0) { - return std::pair(response.result_int(),""); - } - - return std::pair(response.result_int(), boost::beast::buffers_to_string(response.body().data())); + if (!_networkManager) { + qDebug() << "Network manager is not initialized!"; + return qMakePair(0, "Network manager is not initialized"); + } + + QNetworkReply *reply = nullptr; + switch(_currentMethod) { + case QNetworkAccessManager::GetOperation: + reply = _networkManager->get(_currentRequest); + break; + case QNetworkAccessManager::PostOperation: + reply = _networkManager->post(_currentRequest, _currentBody.toUtf8()); + break; + case QNetworkAccessManager::PutOperation: + reply = _networkManager->put(_currentRequest, _currentBody.toUtf8()); + break; + case QNetworkAccessManager::DeleteOperation: + reply = _networkManager->deleteResource(_currentRequest); + break; + case QNetworkAccessManager::HeadOperation: + reply = _networkManager->head(_currentRequest); + break; + default: + qDebug() << "Unsupported HTTP method: " << _currentMethod; + return qMakePair(0, "Unsupported HTTP method"); + } + + if (!reply) return qMakePair(0, "Failed to create network reply"); + + QEventLoop loop; + connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + loop.exec(); + + auto response = reply->readAll(); + int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + reply->deleteLater(); + + return qMakePair(statusCode, (QString::fromUtf8(response)).toStdString()); } void UTMSPRestInterface::setBearerToken(const std::string& token) { - _request.set(http::field::authorization, "Bearer " + token); + QString Token = QString::fromStdString(token); + _currentRequest.setRawHeader("Authorization", ("Bearer " + Token).toUtf8()); } diff --git a/src/UTMSP/UTMSPRestInterface.h b/src/UTMSP/UTMSPRestInterface.h index 51a699bf56b5..07d08606191c 100644 --- a/src/UTMSP/UTMSPRestInterface.h +++ b/src/UTMSP/UTMSPRestInterface.h @@ -9,46 +9,32 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -namespace beast = boost::beast; -namespace http = beast::http; -namespace net = boost::asio; -using tcp = net::ip::tcp; - -class UTMSPRestInterface { +class UTMSPRestInterface : public QObject { + Q_OBJECT public: - UTMSPRestInterface(std::string host, std::string port = "443"); - virtual ~UTMSPRestInterface(); + UTMSPRestInterface(QObject *parent = nullptr); + ~UTMSPRestInterface(); - bool connectNetwork(); - void setBearerToken(const std::string& token); - std::pair executeRequest(); - void modifyRequest(std::string target, http::verb method, std::string body = ""); - void setBasicToken(const std::string& basicToken); - void setHost(std::string target); + void setBearerToken(const std::string &token); + QPair executeRequest(); + void modifyRequest(const QString &target, QNetworkAccessManager::Operation method, const QString &body = ""); + void setHost(const QString &target); + void setBasicToken(const QString &basicToken); private: - net::io_context _ioc; - net::ssl::context _ssl_ctx; - net::ip::tcp::resolver _resolver{_ioc}; - QSharedPointer> _stream; - std::mutex _mutex; - std::string _basicToken; - std::string _host; - std::string _port; - - static http::request _request; + QNetworkAccessManager * _networkManager = nullptr; + QNetworkRequest _currentRequest; + QString _currentBody; + QNetworkAccessManager::Operation _currentMethod; + QString _currentURL; + QString _basicToken; }; diff --git a/src/UTMSP/UTMSPServiceController.cpp b/src/UTMSP/UTMSPServiceController.cpp index abd60d4306b2..f62e8e0bb393 100644 --- a/src/UTMSP/UTMSPServiceController.cpp +++ b/src/UTMSP/UTMSPServiceController.cpp @@ -36,6 +36,7 @@ std::string UTMSPServiceController::flightPlanAuthorization() //Get the Token _blenderToken = _utmspAuthorizaton.getOAuth2Token(); + UTMSP_LOG_INFO() << "BlenderToken" + _blenderToken; // State 1 --> Register _utmspFlightPlanManager.getFlightPlanState(); @@ -54,15 +55,12 @@ std::string UTMSPServiceController::flightPlanAuthorization() QString _flightID = QString::fromStdString(flightID); _responseFlightID = _flightID; emit responseFlightIDChanged(); - _responseJson = _Json; - emit responseJsonChanged(); - _responseFlag = flag; - emit responseFlagChanged(); _utmspFlightPlanManager.updateFlightPlanState(_currentState); // State 2 --> Activate Flight Plan _utmspFlightPlanManager.getFlightPlanState(); - if(flag == true){ + bool activated_flag = _utmspFlightPlanManager.activateFlightPlan(_blenderToken); + if(activated_flag == true){ _currentState = UTMSPFlightPlanManager::FlightState::Activated; _activationFlag = true; emit activationFlagChanged(); diff --git a/src/UTMSP/UTMSPServiceController.h b/src/UTMSP/UTMSPServiceController.h index 1b177fdca2c4..2678799814e1 100644 --- a/src/UTMSP/UTMSPServiceController.h +++ b/src/UTMSP/UTMSPServiceController.h @@ -12,13 +12,12 @@ #include "UTMSPAuthorization.h" #include "UTMSPFlightPlanManager.h" #include "UTMSPNetworkRemoteIDManager.h" +#include "UTMSPAircraft.h" #include #include #include -struct mavlink_message_t; - class UTMSPServiceController : public QObject { Q_OBJECT @@ -27,9 +26,7 @@ class UTMSPServiceController : public QObject UTMSPServiceController(QObject *parent = nullptr); ~UTMSPServiceController(); - Q_PROPERTY(bool responseFlag READ responseFlag NOTIFY responseFlagChanged) Q_PROPERTY(QString responseFlightID READ responseFlightID NOTIFY responseFlightIDChanged) - Q_PROPERTY(QString responseJson READ responseJson NOTIFY responseJsonChanged) Q_PROPERTY(bool activationFlag READ activationFlag NOTIFY activationFlagChanged) std::string flightPlanAuthorization(); @@ -38,15 +35,11 @@ class UTMSPServiceController : public QObject const std::string& operatorID, const std::string& flightID); - bool responseFlag () const {return _responseFlag;}; QString responseFlightID() const {return _responseFlightID;}; - QString responseJson () const {return _responseJson;}; bool activationFlag () const {return _activationFlag;}; signals: - void responseFlagChanged (void); void responseFlightIDChanged (void); - void responseJsonChanged (void); void activationFlagChanged (void); void stopTelemetryFlagChanged (bool value); @@ -80,9 +73,7 @@ public slots: std::string _endDateTime; int _minAltitude; int _maxAltitude; - bool _responseFlag; QString _responseFlightID; - QString _responseJson; bool _activationFlag; std::string _clientID; std::string _clientPassword; diff --git a/src/UTMSP/UTMSPStateStorage.qml b/src/UTMSP/UTMSPStateStorage.qml index bea8530752ac..d55b766d3751 100644 --- a/src/UTMSP/UTMSPStateStorage.qml +++ b/src/UTMSP/UTMSPStateStorage.qml @@ -5,4 +5,18 @@ QtObject { property bool loginState: true property bool registerButtonState: true property bool removeFlightPlanState: false + property bool showActivationTab: false + property bool enableMissionUploadButton: false + property bool indicatorIdleStatus: true + property bool indicatorApprovedStatus: false + property bool indicatorActivatedStatus: false + property bool indicatorOnMissionStatus: false + property bool indicatorOnMissionCompleteStatus: false + property bool indicatorDisplayStatus: false + property int currentStateIndex: 0 + property int currentNotificationIndex: 0 + property string indicatorActivationTime: "" + property string startTimeStamp: "" + property string flightID: " - " + property string serialNumber: " - " } diff --git a/src/UTMSP/UTMSPVehicle.h b/src/UTMSP/UTMSPVehicle.h index 1de2f388b952..5a13ae9cbd4a 100644 --- a/src/UTMSP/UTMSPVehicle.h +++ b/src/UTMSP/UTMSPVehicle.h @@ -10,7 +10,6 @@ #pragma once #include "UTMSPServiceController.h" -#include "UTMSPAircraft.h" #include "UTMSPOperator.h" #include "UTMSPFlightDetails.h" diff --git a/src/UTMSP/qmldir b/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir similarity index 99% rename from src/UTMSP/qmldir rename to src/UTMSP/dummy/QGroundControl.UTMSP.qmldir index 33b57a3a7fcf..79c435ae1031 100644 --- a/src/UTMSP/qmldir +++ b/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir @@ -6,4 +6,3 @@ UTMSPActivationStatusBar 1.0 UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals 1.0 UTMSPMapPolygonVisuals.qml singleton UTMSPStateStorage 1.0 UTMSPStateStorage.qml - diff --git a/src/UTMSP/dummy/UTMSPFlightStatusIndicator.qml b/src/UTMSP/dummy/UTMSPFlightStatusIndicator.qml new file mode 100644 index 000000000000..4d577bf6afce --- /dev/null +++ b/src/UTMSP/dummy/UTMSPFlightStatusIndicator.qml @@ -0,0 +1,9 @@ +import QtQuick + +Item { + property var ledImages: [] + property var statusBarColor: [] + property var flightState: [] + property var progressPercentage: [] + property int currentIndex: false +} diff --git a/src/UTMSP/dummy/UTMSPNotificationSlider.qml b/src/UTMSP/dummy/UTMSPNotificationSlider.qml new file mode 100644 index 000000000000..30f31dbd3c64 --- /dev/null +++ b/src/UTMSP/dummy/UTMSPNotificationSlider.qml @@ -0,0 +1,9 @@ +import QtQuick + +Item { + property bool displayStatus: UTMSPStateStorage.indicatorDisplayStatus + property var overlay + property var indicatorTopText: [] + property var indicatorBottomText: [ ] + property int currentNotificationIndex: false +} diff --git a/src/UTMSP/dummy/UTMSPStateStorage.qml b/src/UTMSP/dummy/UTMSPStateStorage.qml new file mode 100644 index 000000000000..570055add26b --- /dev/null +++ b/src/UTMSP/dummy/UTMSPStateStorage.qml @@ -0,0 +1,31 @@ +/**************************************************************************** + * + * (c) 2024 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +pragma Singleton +import QtQuick + +QtObject { + property bool loginState: true + property bool registerButtonState: true + property bool removeFlightPlanState: false + property bool showActivationTab: false + property bool enableMissionUploadButton: false + property bool indicatorIdleStatus: true + property bool indicatorApprovedStatus: false + property bool indicatorActivatedStatus: false + property bool indicatorOnMissionStatus: false + property bool indicatorOnMissionCompleteStatus: false + property bool indicatorDisplayStatus: false + property int currentStateIndex: 0 + property int currentNotificationIndex: 0 + property string indicatorActivationTime: "" + property string startTimeStamp: "" + property string flightID: " - " + property string serialNumber: " - " +} diff --git a/src/UTMSP/dummy/utmsp_dummy.qrc b/src/UTMSP/dummy/utmsp_dummy.qrc index cf2f0c0c0765..75beb462b86f 100644 --- a/src/UTMSP/dummy/utmsp_dummy.qrc +++ b/src/UTMSP/dummy/utmsp_dummy.qrc @@ -2,8 +2,11 @@ UTMSPMapVisuals.qml UTMSPAdapterEditor.qml - qmldir + QGroundControl.UTMSP.qmldir UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals.qml + UTMSPStateStorage.qml + UTMSPNotificationSlider.qml + UTMSPFlightStatusIndicator.qml diff --git a/src/UTMSP/images/green_led.png b/src/UTMSP/images/green_led.png new file mode 100644 index 000000000000..cf31cd525d26 Binary files /dev/null and b/src/UTMSP/images/green_led.png differ diff --git a/src/UTMSP/images/orange_led.png b/src/UTMSP/images/orange_led.png new file mode 100644 index 000000000000..56cfcad016cb Binary files /dev/null and b/src/UTMSP/images/orange_led.png differ diff --git a/src/UTMSP/images/pale_green.png b/src/UTMSP/images/pale_green.png new file mode 100644 index 000000000000..2095a6e06232 Binary files /dev/null and b/src/UTMSP/images/pale_green.png differ diff --git a/src/UTMSP/images/parrot_green.png b/src/UTMSP/images/parrot_green.png new file mode 100644 index 000000000000..ebdce39e4398 Binary files /dev/null and b/src/UTMSP/images/parrot_green.png differ diff --git a/src/UTMSP/images/red_led.png b/src/UTMSP/images/red_led.png new file mode 100644 index 000000000000..26031ed09e49 Binary files /dev/null and b/src/UTMSP/images/red_led.png differ diff --git a/src/UTMSP/images/yellow_led.png b/src/UTMSP/images/yellow_led.png new file mode 100644 index 000000000000..84b4f73272e3 Binary files /dev/null and b/src/UTMSP/images/yellow_led.png differ diff --git a/src/UTMSP/utmsp.qrc b/src/UTMSP/utmsp.qrc index 78c2ae0f618b..9a466fa2deb2 100644 --- a/src/UTMSP/utmsp.qrc +++ b/src/UTMSP/utmsp.qrc @@ -2,10 +2,12 @@ UTMSPAdapterEditor.qml UTMSPMapVisuals.qml - qmldir + ../QmlControls/QGroundControl/UTMSP/qmldir UTMSPMapPolygonVisuals.qml UTMSPActivationStatusBar.qml UTMSPStateStorage.qml + UTMSPNotificationSlider.qml + UTMSPFlightStatusIndicator.qml images/red.png @@ -14,5 +16,11 @@ images/date.svg images/load.gif images/timer.gif + images/red_led.png + images/yellow_led.png + images/orange_led.png + images/green_led.png + images/pale_green.png + images/parrot_green.png diff --git a/src/Vehicle/CMakeLists.txt b/src/Vehicle/CMakeLists.txt index cd7cc6275cf7..92f73a452b91 100644 --- a/src/Vehicle/CMakeLists.txt +++ b/src/Vehicle/CMakeLists.txt @@ -4,6 +4,10 @@ add_subdirectory(FactGroups) find_package(Qt6 REQUIRED COMPONENTS Core Gui Positioning Qml) +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() + qt_add_library(Vehicle STATIC Autotune.cpp Autotune.h diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 4e10f9ea14fe..b98fad87e3ef 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -52,7 +52,7 @@ #include "VideoSettings.h" #include -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER #include "UTMSPVehicle.h" #include "UTMSPManager.h" #endif @@ -176,7 +176,7 @@ Vehicle::Vehicle(LinkInterface* link, _settingsManager->videoSettings()->lowLatencyMode()->setRawValue(true); } -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPManager* utmspManager = _toolbox->utmspManager(); if (utmspManager) { _utmspVehicle = utmspManager->instantiateVehicle(*this); @@ -478,7 +478,7 @@ Vehicle::~Vehicle() delete _autopilotPlugin; _autopilotPlugin = nullptr; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER delete _utmspVehicle; #endif } diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index 1ca555c0766b..63499f4f2329 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -43,6 +43,10 @@ #include "VehicleTemperatureFactGroup.h" #include "VehicleVibrationFactGroup.h" #include "VehicleWindFactGroup.h" +#ifdef QGC_UTM_ADAPTER +#include "UTMSPVehicle.h" +#include "UTMSPManager.h" +#endif class Actuators; class AutoPilotPlugin; @@ -77,7 +81,7 @@ class UASMessage; class VehicleBatteryFactGroup; class VehicleObjectAvoidance; class QGCToolbox; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER class UTMSPVehicle; #endif #ifndef OPAQUE_PTR_VEHICLE @@ -1181,7 +1185,7 @@ private slots: VehicleObjectAvoidance* _objectAvoidance = nullptr; Autotune* _autotune = nullptr; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPVehicle* _utmspVehicle = nullptr; #endif