From aefe1d19df0ec260dd02f5ce5e64117c9091de74 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Sat, 15 Jun 2024 22:24:58 +0400 Subject: [PATCH 01/13] Rename the CONFIG_UTM_ADAPTER flag to QGC_UTM_ADAPTER --- QGCExternalLibs.pri | 2 +- qgroundcontrol.pro | 2 +- src/MissionManager/GeoFenceController.cc | 2 +- src/MissionManager/GeoFenceController.h | 4 ++-- src/QGCToolbox.cc | 6 +++--- src/QGCToolbox.h | 6 +++--- src/QmlControls/QGCPalette.cc | 2 +- src/QmlControls/QGCPalette.h | 2 +- src/QmlControls/QGroundControlQmlGlobal.cc | 2 +- src/QmlControls/QGroundControlQmlGlobal.h | 10 +++++----- src/UTMSP/UTMSPLogger.h | 2 +- src/Vehicle/Vehicle.cc | 6 +++--- src/Vehicle/Vehicle.h | 4 ++-- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index 390c347a5a35..95d83d693f74 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -227,7 +227,7 @@ contains (DEFINES, DISABLE_ZEROCONF) { } # UTM Adapter Enabled -contains (DEFINES, CONFIG_UTM_ADAPTER){ +contains (DEFINES, QGC_UTM_ADAPTER){ INCLUDEPATH += $$PWD/libs/libevents/libevents/libs/cpp/parse/nlohmann_json/include LIBS += -lboost_system -lboost_thread -lssl -lcrypto } 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/MissionManager/GeoFenceController.cc b/src/MissionManager/GeoFenceController.cc index 700e9ce01fe8..9e7a93b21808 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; diff --git a/src/MissionManager/GeoFenceController.h b/src/MissionManager/GeoFenceController.h index f375a0c377f7..84a8465ea5be 100644 --- a/src/MissionManager/GeoFenceController.h +++ b/src/MissionManager/GeoFenceController.h @@ -62,7 +62,7 @@ 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 @@ -98,7 +98,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/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/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/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/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/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..9eaf9dd17a66 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -77,7 +77,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 +1181,7 @@ private slots: VehicleObjectAvoidance* _objectAvoidance = nullptr; Autotune* _autotune = nullptr; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_UTM_ADAPTER UTMSPVehicle* _utmspVehicle = nullptr; #endif From 098c1d289e85d91205e023af19cafe1fa1737032 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Sat, 15 Jun 2024 22:52:32 +0400 Subject: [PATCH 02/13] Fix build issue --- src/UTMSP/UTMSPAircraft.h | 3 +-- src/UTMSP/UTMSPManager.cpp | 3 ++- src/UTMSP/UTMSPManager.h | 2 ++ src/UTMSP/UTMSPNetworkRemoteIDManager.cpp | 1 - src/UTMSP/UTMSPNetworkRemoteIDManager.h | 1 + src/UTMSP/UTMSPServiceController.h | 3 +-- src/UTMSP/UTMSPVehicle.h | 1 - 7 files changed, 7 insertions(+), 7 deletions(-) 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/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/UTMSPNetworkRemoteIDManager.cpp b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp index 3793f4eea833..bf4f3ecadb0f 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) 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/UTMSPServiceController.h b/src/UTMSP/UTMSPServiceController.h index 1b177fdca2c4..9462ee042331 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 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" From 5ea069cee16761bcfbcdcf8d55871c462fddf663 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Sun, 16 Jun 2024 00:01:51 +0400 Subject: [PATCH 03/13] Update CMakeLists to support cmake build for UTMSP --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 7 +++++++ src/MissionManager/CMakeLists.txt | 3 +++ src/PlanView/CMakeLists.txt | 4 ++++ src/QmlControls/CMakeLists.txt | 4 ++++ .../QGroundControl}/UTMSP/qmldir | 0 src/UTMSP/CMakeLists.txt | 20 +++++++++---------- .../{qmldir => QGroundControl.UTMSP.qmldir} | 0 src/UTMSP/dummy/utmsp_dummy.qrc | 2 +- src/UTMSP/utmsp.qrc | 2 +- src/Vehicle/CMakeLists.txt | 4 ++++ 11 files changed, 35 insertions(+), 13 deletions(-) rename src/{ => QmlControls/QGroundControl}/UTMSP/qmldir (100%) rename src/UTMSP/dummy/{qmldir => QGroundControl.UTMSP.qmldir} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f1aed2be392..9d0d870f43a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -206,7 +206,7 @@ set(QGC_RESOURCES ${CMAKE_SOURCE_DIR}/src/FirmwarePlugin/PX4/PX4Resources.qrc ) -if(CONFIG_UTM_ADAPTER) +if(QGC_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/src/CMakeLists.txt b/src/CMakeLists.txt index 0b39a53b1b97..db7318f7a504 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,13 @@ qt_add_library(QGC STATIC QGCToolbox.h ) +####################################################### +# UTMSP FLAG +####################################################### +if(QGC_UTM_ADAPTER) + add_definitions(-DQGC_UTM_ADAPTER) +endif() + add_subdirectory(ADSB) add_subdirectory(AirLink) add_subdirectory(AnalyzeView) 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/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/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/UTMSP/qmldir b/src/QmlControls/QGroundControl/UTMSP/qmldir similarity index 100% rename from src/UTMSP/qmldir rename to src/QmlControls/QGroundControl/UTMSP/qmldir diff --git a/src/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index d7e96cee36db..d227f7cef361 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -7,16 +7,16 @@ option(QGC_UTM_ADAPTER "Enable UTM Adapter" OFF) if(QGC_UTM_ADAPTER) message(STATUS "UTMSP is Initialized") - 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) diff --git a/src/UTMSP/dummy/qmldir b/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir similarity index 100% rename from src/UTMSP/dummy/qmldir rename to src/UTMSP/dummy/QGroundControl.UTMSP.qmldir diff --git a/src/UTMSP/dummy/utmsp_dummy.qrc b/src/UTMSP/dummy/utmsp_dummy.qrc index cf2f0c0c0765..e07901da1d33 100644 --- a/src/UTMSP/dummy/utmsp_dummy.qrc +++ b/src/UTMSP/dummy/utmsp_dummy.qrc @@ -2,7 +2,7 @@ UTMSPMapVisuals.qml UTMSPAdapterEditor.qml - qmldir + QGroundControl.UTMSP.qmldir UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals.qml diff --git a/src/UTMSP/utmsp.qrc b/src/UTMSP/utmsp.qrc index 78c2ae0f618b..a4f96406b31d 100644 --- a/src/UTMSP/utmsp.qrc +++ b/src/UTMSP/utmsp.qrc @@ -2,7 +2,7 @@ UTMSPAdapterEditor.qml UTMSPMapVisuals.qml - qmldir + ../QmlControls/QGroundControl/UTMSP/qmldir UTMSPMapPolygonVisuals.qml UTMSPActivationStatusBar.qml UTMSPStateStorage.qml 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 From 793d54e9c9f1d3f9c3c2e384f97ef1944c4717c2 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Sun, 16 Jun 2024 00:53:12 +0400 Subject: [PATCH 04/13] Remove boost dependency and update REST Interface with QTNetwork --- CMakeLists.txt | 1 + QGCExternalLibs.pri | 1 - src/CMakeLists.txt | 3 - src/UTMSP/CMakeLists.txt | 3 + src/UTMSP/UTMSPAuthorization.cpp | 55 ++--- src/UTMSP/UTMSPAuthorization.h | 15 +- src/UTMSP/UTMSPBlenderRestInterface.cpp | 24 +-- src/UTMSP/UTMSPBlenderRestInterface.h | 13 +- src/UTMSP/UTMSPFlightPlanManager.cpp | 10 +- src/UTMSP/UTMSPNetworkRemoteIDManager.cpp | 34 ++-- src/UTMSP/UTMSPRestInterface.cpp | 238 +++++++--------------- src/UTMSP/UTMSPRestInterface.h | 58 ++---- 12 files changed, 157 insertions(+), 298 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d0d870f43a6..0ca7fbcef173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,6 +207,7 @@ set(QGC_RESOURCES ) 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 95d83d693f74..2e69524320f2 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -229,7 +229,6 @@ contains (DEFINES, DISABLE_ZEROCONF) { # UTM Adapter Enabled contains (DEFINES, QGC_UTM_ADAPTER){ INCLUDEPATH += $$PWD/libs/libevents/libevents/libs/cpp/parse/nlohmann_json/include - LIBS += -lboost_system -lboost_thread -lssl -lcrypto } HEADERS += \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db7318f7a504..a6fa5ff513cf 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,9 +18,6 @@ qt_add_library(QGC STATIC QGCToolbox.h ) -####################################################### -# UTMSP FLAG -####################################################### if(QGC_UTM_ADAPTER) add_definitions(-DQGC_UTM_ADAPTER) endif() diff --git a/src/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index d227f7cef361..279ba8452cd0 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -6,6 +6,7 @@ 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") @@ -30,6 +31,8 @@ if(QGC_UTM_ADAPTER) UTMSPAuthorization.h UTMSPBlenderRestInterface.cpp UTMSPBlenderRestInterface.h + UTMSPFlightDetails.cpp + UTMSPFlightDetails.h UTMSPFlightPlanManager.cpp UTMSPFlightPlanManager.h UTMSPLogger.h diff --git a/src/UTMSP/UTMSPAuthorization.cpp b/src/UTMSP/UTMSPAuthorization.cpp index 35e9871048b4..8e2e31839876 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,43 +28,20 @@ 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=blender.utm.dev.airoplatform.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) { try { - json responseJson = json::parse(response); + json responseJson = json::parse(response.toStdString()); clientToken = responseJson["access_token"]; _isValidToken = true; } 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..30e062478bc7 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.cpp +++ b/src/UTMSP/UTMSPBlenderRestInterface.cpp @@ -9,34 +9,34 @@ #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 QString& 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, body); return executeRequest(); } -std::pair UTMSPBlenderRestInterface::requestTelemetry(const std::string& body) +QPair UTMSPBlenderRestInterface::requestTelemetry(const QString& body) { // Post RID data - const std::string target = "/flight_stream/set_telemetry"; - modifyRequest(target, http::verb::put, body); + QString target = "/flight_stream/set_telemetry"; + modifyRequest(target, QNetworkAccessManager::PutOperation, 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..693d1462c768 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.h +++ b/src/UTMSP/UTMSPBlenderRestInterface.h @@ -11,15 +11,16 @@ #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 QString& body); + QPair requestTelemetry(const QString& body); + QPair ping(); -private: - http::request _request; }; diff --git a/src/UTMSP/UTMSPFlightPlanManager.cpp b/src/UTMSP/UTMSPFlightPlanManager.cpp index e40a09f8a597..f2964fb6b960 100644 --- a/src/UTMSP/UTMSPFlightPlanManager.cpp +++ b/src/UTMSP/UTMSPFlightPlanManager.cpp @@ -95,20 +95,20 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, json data = _flightDataJson; + auto dataString = QString::fromStdString(data.dump(4)); setHost("BlenderClient"); - connectNetwork(); - setBearerToken(token); - auto [statusCode, response] = setFlightPlan(data.dump(4)); + setBearerToken(token.c_str()); + auto [statusCode, response] = setFlightPlan(dataString); UTMSP_LOG_INFO() << "UTMSPFlightPlanManager: Register Response -->" << response; if(statusCode == 201) { try { - json jsonData = json::parse(response); + json jsonData = json::parse(response.toStdString()); std::string flightID = jsonData["id"]; _flightResponseID = flightID; - _responseJSON = response; + _responseJSON = response.toStdString(); _responseStatus = true; } catch (const json::parse_error& e) { diff --git a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp index bf4f3ecadb0f..8ae1fbc8c00b 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -23,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, @@ -145,34 +144,25 @@ 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; - }); + auto [statusCode, response] = requestTelemetry( QString::fromStdString(data.dump(4))); + _statusCode = statusCode; + _response = response.toStdString(); + UTMSP_LOG_DEBUG()<< "Status Code: " << _statusCode; 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---------------"; - } - } + 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(); + UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Error parsing the Telemetry response: " << e.what(); } } else diff --git a/src/UTMSP/UTMSPRestInterface.cpp b/src/UTMSP/UTMSPRestInterface.cpp index 88a72501875d..a036ece9a00b 100644 --- a/src/UTMSP/UTMSPRestInterface.cpp +++ b/src/UTMSP/UTMSPRestInterface.cpp @@ -10,191 +10,99 @@ #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://passport.utm.dev.airoplatform.com"; + _currentRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + } else if (target == "BlenderClient") { + _currentURL = "https://blender.utm.dev.airoplatform.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, QString("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, QString("Unsupported HTTP method")); + } + + if (!reply) return qMakePair(0, QString("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)); } -void UTMSPRestInterface::setBearerToken(const std::string& token) +void UTMSPRestInterface::setBearerToken(const QString& token) { - _request.set(http::field::authorization, "Bearer " + token); + _currentRequest.setRawHeader("Authorization", ("Bearer " + token).toUtf8()); } diff --git a/src/UTMSP/UTMSPRestInterface.h b/src/UTMSP/UTMSPRestInterface.h index 51a699bf56b5..2f3396d45a27 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 QString &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; }; From 4fa98b22615e288a2ad0074ee3f119742050dee3 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 11:56:40 +0400 Subject: [PATCH 05/13] Remove unused code segments --- src/MissionManager/GeoFenceController.cc | 6 -- src/MissionManager/GeoFenceController.h | 1 - src/PlanView/PlanToolBarIndicators.qml | 15 +---- src/PlanView/PlanView.qml | 17 +++--- src/UI/MainRootWindow.qml | 19 ++---- src/UTMSP/UTMSPActivationStatusBar.qml | 15 +++++ src/UTMSP/UTMSPAdapterEditor.qml | 65 ++++++++++----------- src/UTMSP/UTMSPMapPolygonVisuals.qml | 4 +- src/UTMSP/UTMSPStateStorage.qml | 4 ++ src/UTMSP/dummy/QGroundControl.UTMSP.qmldir | 1 + src/UTMSP/dummy/UTMSPStateStorage.qml | 12 ++++ src/UTMSP/dummy/utmsp_dummy.qrc | 1 + 12 files changed, 81 insertions(+), 79 deletions(-) create mode 100644 src/UTMSP/dummy/UTMSPStateStorage.qml diff --git a/src/MissionManager/GeoFenceController.cc b/src/MissionManager/GeoFenceController.cc index 9e7a93b21808..744b3c5fe43e 100644 --- a/src/MissionManager/GeoFenceController.cc +++ b/src/MissionManager/GeoFenceController.cc @@ -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 84a8465ea5be..06e9130c543d 100644 --- a/src/MissionManager/GeoFenceController.h +++ b/src/MissionManager/GeoFenceController.h @@ -64,7 +64,6 @@ class GeoFenceController : public PlanElementController #ifdef QGC_UTM_ADAPTER Q_INVOKABLE void loadFlightPlanData(void); - Q_INVOKABLE bool loadUploadFlag(void); #endif double paramCircularFence (void); diff --git a/src/PlanView/PlanToolBarIndicators.qml b/src/PlanView/PlanToolBarIndicators.qml index 883abd2e757c..3f1b93494bb3 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,7 +214,7 @@ 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: { diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 53ade8a5d6c0..45acebe50014 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 @@ -919,7 +918,15 @@ 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;}}) } //- ToolStrip DropPanel Components @@ -1289,12 +1296,6 @@ Item { } } } - Connections{ - target: utmspEditor - function onTimeStampSent(timestamp, activateflag, id){ - activationParamsSent(timestamp,activateflag, id) - } - } Connections { target: utmspEditor 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/UTMSPActivationStatusBar.qml b/src/UTMSP/UTMSPActivationStatusBar.qml index e97e7b07d524..cc74da66d60c 100644 --- a/src/UTMSP/UTMSPActivationStatusBar.qml +++ b/src/UTMSP/UTMSPActivationStatusBar.qml @@ -42,7 +42,21 @@ Item { signal activationTriggered(bool value) + onActivationApprovalChanged: { + if(activationApproval === true){ + approvetag.visible = true + activatetag.visible = false + activationBar.visible = true + activationTriggered(false) + displayActivationTabTimer.start() + } + else{ + activationBar.visible = false + } + } + Timer { + id: displayActivationTabTimer interval: 1000 running: activationApproval repeat: activationApproval @@ -58,6 +72,7 @@ Item { approvetag.visible = false activatetag.visible = true activationTriggered(true) + displayActivationTabTimer.stop() hideTimer.start() }else{ approvetag.visible = false diff --git a/src/UTMSP/UTMSPAdapterEditor.qml b/src/UTMSP/UTMSPAdapterEditor.qml index ec7da943398e..89911e4c3b81 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -36,16 +36,10 @@ 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 @@ -57,7 +51,6 @@ QGCFlickable { 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 @@ -153,9 +146,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 @@ -177,7 +170,6 @@ QGCFlickable { Row{ spacing: _margin * 5 - visible: UTMSPStateStorage.loginState QGCLabel{ id: notifyText @@ -218,7 +210,7 @@ QGCFlickable { Column{ spacing:_margin * 1.667 - QGCLabel { text: qsTr("User ID") } + QGCTextField { text: qsTr("User ID") } FactTextField { id: userName width: ScreenTools.defaultFontPixelWidth * 50 @@ -234,7 +226,7 @@ QGCFlickable { Column{ spacing: _margin * 1.5 - QGCLabel { text: qsTr("Password:") } + QGCTextField { text: qsTr("Password:") } FactTextField { id: password width: ScreenTools.defaultFontPixelWidth * 50 @@ -571,9 +563,9 @@ QGCFlickable { model: myGeoFenceController.polygons delegate: QGCButton { text: qsTr("Delete") - width: ScreenTools.defaultFontPixelWidth * 6.667 + width: ScreenTools.defaultFontPixelWidth * 7.667 height: ScreenTools.defaultFontPixelHeight * 1.667 - x: ScreenTools.defaultFontPixelWidth * 43 + x: ScreenTools.defaultFontPixelWidth * 41 y: ScreenTools.defaultFontPixelHeight * 2 onClicked: { myGeoFenceController.deletePolygon(index) @@ -1285,24 +1277,24 @@ 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" + 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 = startYear + "-" + startMonth + "-" + startDay + "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() @@ -1315,6 +1307,9 @@ QGCFlickable { startTimeStamp = activateTD submissionFlag = responseFlag responseSent(responseJson,responseFlag) + UTMSPStateStorage.startTimeStamp = activateTD + UTMSPStateStorage.showActivationTab = responseFlag + UTMSPStateStorage.flightID = flightID } } @@ -1324,8 +1319,7 @@ QGCFlickable { onTriggered: { if(submissionFlag === true) { - approvalFlag = myGeoFenceController.loadUploadFlag() - timeStampSent(startTimeStamp,approvalFlag,flightID) + UTMSPStateStorage.enableMissionUploadButton = true submitFlightPlan.visible = false geoSwitch.checked = false deletePolygon.visible = false @@ -1349,6 +1343,11 @@ 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 } } } 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/UTMSPStateStorage.qml b/src/UTMSP/UTMSPStateStorage.qml index bea8530752ac..68432bb1eb84 100644 --- a/src/UTMSP/UTMSPStateStorage.qml +++ b/src/UTMSP/UTMSPStateStorage.qml @@ -5,4 +5,8 @@ QtObject { property bool loginState: true property bool registerButtonState: true property bool removeFlightPlanState: false + property bool showActivationTab: false + property bool enableMissionUploadButton: false + property string startTimeStamp: "" + property string flightID: "" } diff --git a/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir b/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir index aff750760dea..79c435ae1031 100644 --- a/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir +++ b/src/UTMSP/dummy/QGroundControl.UTMSP.qmldir @@ -5,3 +5,4 @@ UTMSPMapVisuals 1.0 UTMSPMapVisuals.qml UTMSPActivationStatusBar 1.0 UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals 1.0 UTMSPMapPolygonVisuals.qml +singleton UTMSPStateStorage 1.0 UTMSPStateStorage.qml diff --git a/src/UTMSP/dummy/UTMSPStateStorage.qml b/src/UTMSP/dummy/UTMSPStateStorage.qml new file mode 100644 index 000000000000..68432bb1eb84 --- /dev/null +++ b/src/UTMSP/dummy/UTMSPStateStorage.qml @@ -0,0 +1,12 @@ +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 string startTimeStamp: "" + property string flightID: "" +} diff --git a/src/UTMSP/dummy/utmsp_dummy.qrc b/src/UTMSP/dummy/utmsp_dummy.qrc index e07901da1d33..a1af153c4fc4 100644 --- a/src/UTMSP/dummy/utmsp_dummy.qrc +++ b/src/UTMSP/dummy/utmsp_dummy.qrc @@ -5,5 +5,6 @@ QGroundControl.UTMSP.qmldir UTMSPActivationStatusBar.qml UTMSPMapPolygonVisuals.qml + UTMSPStateStorage.qml From 996c305585bdc063b164ab98b0fe76e08934dce7 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 11:59:57 +0400 Subject: [PATCH 06/13] Move activation status bar to left --- src/UTMSP/UTMSPActivationStatusBar.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UTMSP/UTMSPActivationStatusBar.qml b/src/UTMSP/UTMSPActivationStatusBar.qml index cc74da66d60c..7d0d426911c4 100644 --- a/src/UTMSP/UTMSPActivationStatusBar.qml +++ b/src/UTMSP/UTMSPActivationStatusBar.qml @@ -100,10 +100,10 @@ Item { border.color: qgcPal.textFieldText width: ScreenTools.defaultFontPixelWidth * 83.33 height: ScreenTools.defaultFontPixelHeight * 8.33 - anchors.right: parent.right + anchors.left: parent.left anchors.bottom: parent.bottom opacity: 0.7 - visible: activationApproval + visible: false radius: ScreenTools.defaultFontPixelWidth * 0.833 QGCColoredImage { From ac49166099bfd0b2f5c3807bc0aa6b5bf5b6ab6a Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 14:44:05 +0400 Subject: [PATCH 07/13] Update libevent submodule with qmake run --- QGCExternalLibs.pri | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index 2e69524320f2..7cf69f1518d9 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -227,7 +227,10 @@ contains (DEFINES, DISABLE_ZEROCONF) { } # UTM Adapter Enabled -contains (DEFINES, QGC_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 } From 4b29f158c2333f80a976c418dbdb37aecf47be32 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 14:51:53 +0400 Subject: [PATCH 08/13] Fix minor nit picks --- src/UTMSP/UTMSPAdapterEditor.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/UTMSP/UTMSPAdapterEditor.qml b/src/UTMSP/UTMSPAdapterEditor.qml index 89911e4c3b81..1f49fede366a 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -210,8 +210,8 @@ QGCFlickable { Column{ spacing:_margin * 1.667 - QGCTextField { text: qsTr("User ID") } - FactTextField { + QGCLabel { text: qsTr("User ID") } + QGCTextField { id: userName width: ScreenTools.defaultFontPixelWidth * 50 height: ScreenTools.defaultFontPixelHeight * 1.667 @@ -226,8 +226,8 @@ QGCFlickable { Column{ spacing: _margin * 1.5 - QGCTextField { text: qsTr("Password:") } - FactTextField { + QGCLabel { text: qsTr("Password:") } + QGCTextField { id: password width: ScreenTools.defaultFontPixelWidth * 50 height: ScreenTools.defaultFontPixelHeight * 1.667 From 29f436204e42f393656c820692cdef4a3e90de23 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 15:48:39 +0400 Subject: [PATCH 09/13] Fix end datetime bug --- src/UTMSP/UTMSPAdapterEditor.qml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/UTMSP/UTMSPAdapterEditor.qml b/src/UTMSP/UTMSPAdapterEditor.qml index 1f49fede366a..5ee528696f64 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -42,6 +42,9 @@ QGCFlickable { property bool submissionFlag 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 @@ -61,6 +64,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 @@ -1277,6 +1292,7 @@ QGCFlickable { submissionTimer.interval = 2500 submissionTimer.repeat = false submissionTimer.start() + loadEndDateTime() var minAltitude = minSlider.value.toFixed(0) var maxAltitude = maxSlider.value.toFixed(0) var startDay = scrollDate.model[scrollDate.currentIndex] @@ -1289,7 +1305,7 @@ QGCFlickable { 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 = startYear + "-" + startMonth + "-" + startDay + "T" + endHour + ":" + endMinute + ":" + endSecond+ "." + "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() From f9ba45ed185e81b38f8efae63113ffa54e28a2bf Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Mon, 13 May 2024 23:20:45 +0400 Subject: [PATCH 10/13] Add mission state notification gui --- src/FlightDisplay/GuidedActionConfirm.qml | 5 + src/PlanView/MissionItemMapVisual.qml | 2 +- src/PlanView/PlanToolBarIndicators.qml | 1 + src/PlanView/PlanView.qml | 6 +- src/QmlControls/QGroundControl/UTMSP/qmldir | 2 + src/UTMSP/CMakeLists.txt | 1 - src/UTMSP/UTMSPActivationStatusBar.qml | 234 +++++++++--------- src/UTMSP/UTMSPAdapterEditor.qml | 21 ++ src/UTMSP/UTMSPFlightPlanManager.cpp | 5 + src/UTMSP/UTMSPFlightPlanManager.h | 2 + src/UTMSP/UTMSPFlightStatusIndicator.qml | 131 ++++++++++ src/UTMSP/UTMSPNetworkRemoteIDManager.cpp | 1 + src/UTMSP/UTMSPNotificationSlider.qml | 184 ++++++++++++++ src/UTMSP/UTMSPStateStorage.qml | 12 +- .../dummy/UTMSPFlightStatusIndicator.qml | 9 + src/UTMSP/dummy/UTMSPNotificationSlider.qml | 9 + src/UTMSP/dummy/UTMSPStateStorage.qml | 21 +- src/UTMSP/dummy/utmsp_dummy.qrc | 2 + src/UTMSP/images/green_led.png | Bin 0 -> 2289 bytes src/UTMSP/images/orange_led.png | Bin 0 -> 2189 bytes src/UTMSP/images/pale_green.png | Bin 0 -> 1997 bytes src/UTMSP/images/parrot_green.png | Bin 0 -> 2029 bytes src/UTMSP/images/red_led.png | Bin 0 -> 1985 bytes src/UTMSP/images/yellow_led.png | Bin 0 -> 1965 bytes src/UTMSP/utmsp.qrc | 8 + src/Vehicle/Vehicle.h | 4 + 26 files changed, 543 insertions(+), 117 deletions(-) create mode 100644 src/UTMSP/UTMSPFlightStatusIndicator.qml create mode 100644 src/UTMSP/UTMSPNotificationSlider.qml create mode 100644 src/UTMSP/dummy/UTMSPFlightStatusIndicator.qml create mode 100644 src/UTMSP/dummy/UTMSPNotificationSlider.qml create mode 100644 src/UTMSP/images/green_led.png create mode 100644 src/UTMSP/images/orange_led.png create mode 100644 src/UTMSP/images/pale_green.png create mode 100644 src/UTMSP/images/parrot_green.png create mode 100644 src/UTMSP/images/red_led.png create mode 100644 src/UTMSP/images/yellow_led.png 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/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 3f1b93494bb3..84c8ea73dad3 100644 --- a/src/PlanView/PlanToolBarIndicators.qml +++ b/src/PlanView/PlanToolBarIndicators.qml @@ -221,6 +221,7 @@ Item { 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 45acebe50014..3aa6918aa6ac 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -926,7 +926,11 @@ Item { UTMSPStateStorage.startTimeStamp = ""; UTMSPStateStorage.showActivationTab = false; UTMSPStateStorage.flightID = ""; - UTMSPStateStorage.enableMissionUploadButton = false;}}) + UTMSPStateStorage.enableMissionUploadButton = false; + UTMSPStateStorage.indicatorPendingStatus = true; + UTMSPStateStorage.indicatorApprovedStatus = false; + UTMSPStateStorage.indicatorActivatedStatus = false; + UTMSPStateStorage.currentStateIndex = 0}}) } //- ToolStrip DropPanel Components diff --git a/src/QmlControls/QGroundControl/UTMSP/qmldir b/src/QmlControls/QGroundControl/UTMSP/qmldir index 33b57a3a7fcf..a3ed2d38b103 100644 --- a/src/QmlControls/QGroundControl/UTMSP/qmldir +++ b/src/QmlControls/QGroundControl/UTMSP/qmldir @@ -4,6 +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/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index 279ba8452cd0..09d870f09262 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -53,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 7d0d426911c4..e4b4595450b8 100644 --- a/src/UTMSP/UTMSPActivationStatusBar.qml +++ b/src/UTMSP/UTMSPActivationStatusBar.qml @@ -40,19 +40,14 @@ Item { property string timeDifference property bool activationErrorFlag + signal activationTriggered(bool value) onActivationApprovalChanged: { if(activationApproval === true){ - approvetag.visible = true - activatetag.visible = false - activationBar.visible = true activationTriggered(false) displayActivationTabTimer.start() } - else{ - activationBar.visible = false - } } Timer { @@ -69,13 +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) + UTMSPStateStorage.indicatorActivatedStatus = true displayActivationTabTimer.stop() - hideTimer.start() + UTMSPStateStorage.currentStateIndex = 2 + UTMSPStateStorage.currentNotificationIndex = 4 + UTMSPStateStorage.indicatorDisplayStatus = false }else{ - approvetag.visible = false failtag.visible = true } } else { @@ -83,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.left: parent.left - anchors.bottom: parent.bottom - opacity: 0.7 - visible: false - 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.primaryButton + 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 5ee528696f64..9ed53c951a5d 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -173,6 +173,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 } } @@ -287,6 +294,8 @@ QGCFlickable { delayTimer.interval = 2500 delayTimer.repeat = false delayTimer.start() + UTMSPStateStorage.indicatorDisplayStatus = true + UTMSPStateStorage.currentNotificationIndex = 1 } else{ errorLogin.visible = true @@ -1326,6 +1335,7 @@ QGCFlickable { UTMSPStateStorage.startTimeStamp = activateTD UTMSPStateStorage.showActivationTab = responseFlag UTMSPStateStorage.flightID = flightID + UTMSPStateStorage.serialNumber = serialNumber } } @@ -1341,6 +1351,11 @@ QGCFlickable { 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 @@ -1364,6 +1379,12 @@ QGCFlickable { 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/UTMSPFlightPlanManager.cpp b/src/UTMSP/UTMSPFlightPlanManager.cpp index f2964fb6b960..24476e4758e1 100644 --- a/src/UTMSP/UTMSPFlightPlanManager.cpp +++ b/src/UTMSP/UTMSPFlightPlanManager.cpp @@ -51,6 +51,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 +64,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 +72,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; diff --git a/src/UTMSP/UTMSPFlightPlanManager.h b/src/UTMSP/UTMSPFlightPlanManager.h index b771283aec43..9c5a268688fe 100644 --- a/src/UTMSP/UTMSPFlightPlanManager.h +++ b/src/UTMSP/UTMSPFlightPlanManager.h @@ -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; 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/UTMSPNetworkRemoteIDManager.cpp b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp index 8ae1fbc8c00b..c952222352d1 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -147,6 +147,7 @@ void UTMSPNetworkRemoteIDManager::startTelemetry(const double &latitude, auto [statusCode, response] = requestTelemetry( QString::fromStdString(data.dump(4))); _statusCode = statusCode; _response = response.toStdString(); + UTMSP_LOG_DEBUG()<< "Response " << _response; UTMSP_LOG_DEBUG()<< "Status Code: " << _statusCode; if(!_response.empty()){ diff --git a/src/UTMSP/UTMSPNotificationSlider.qml b/src/UTMSP/UTMSPNotificationSlider.qml new file mode 100644 index 000000000000..30274a1b9174 --- /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/UTMSPStateStorage.qml b/src/UTMSP/UTMSPStateStorage.qml index 68432bb1eb84..d55b766d3751 100644 --- a/src/UTMSP/UTMSPStateStorage.qml +++ b/src/UTMSP/UTMSPStateStorage.qml @@ -7,6 +7,16 @@ QtObject { 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 flightID: " - " + property string serialNumber: " - " } 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 index 68432bb1eb84..570055add26b 100644 --- a/src/UTMSP/dummy/UTMSPStateStorage.qml +++ b/src/UTMSP/dummy/UTMSPStateStorage.qml @@ -1,3 +1,12 @@ +/**************************************************************************** + * + * (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 @@ -7,6 +16,16 @@ QtObject { 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 flightID: " - " + property string serialNumber: " - " } diff --git a/src/UTMSP/dummy/utmsp_dummy.qrc b/src/UTMSP/dummy/utmsp_dummy.qrc index a1af153c4fc4..75beb462b86f 100644 --- a/src/UTMSP/dummy/utmsp_dummy.qrc +++ b/src/UTMSP/dummy/utmsp_dummy.qrc @@ -6,5 +6,7 @@ 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 0000000000000000000000000000000000000000..cf31cd525d264dee8f98f527912da954511376fd GIT binary patch literal 2289 zcmVb$g8Gcrm*O$XB-G}9l%{n^fRYIoYE3~hl-(~b)b?o1~w zv>pSQhIHDF=(L^uEM%q~Xc90@oEiv7atIgq=qfN@1XT0_rkyrqf4` z963?!dPM;{di3ab1VQLd$O&6O@?lII!9;unqA7yvs%q3)>rqu^MTx-#F%d(6_v4X& z3bXzhaDonX`Ub2vtwpuI#%t7@x(^>d{MW?*E(ol*x7Wt={6B@bV1Fb|U_yQXlhufg zYd6Dg+lmJ3Dws{B&~d~G$AP0umSyFVWC_u@fGOW3Zj8F&x_1q}X&+W_Yp}}P=qlBh zeq$kt3j!lh_Ha0SaW?kQGR}>lsi$NN;LZFj19XE9XjO7$6j7wJv}`gAtCG-6FrDj1hKJs6YNdT zqrQ42%1jl|>&Ubh(}Fod3S`nLBt%3Wj{*-a+a4Ay!JUfHwq@xn&pH z*6k+w3`K~O?6Sc6dF=A>HksF69qGr%w=Q5wq}u!bn;$i%f%Tm1Ip7Ts_qw9}Fj_*l+KT5XWsN!Gm7#lPPKS4pXKtDv`-nF;@!zPf?^QP z(aQ?BviK5w$=cS)_59&jhdXr5aW(u2{FuWI+skx)1*N94qJn5Ht-0QrmwJs+@)UU8 zg8+Y%bg0$^H7|ug+WvUwZWhe-&|^h)wldv31Q$s5Dn)7_~O@D9jbnRCW|v z)cBW2-k=b`jR_|{pST85jG?)7(^>A9C%XDR3I2QM9br)M!qrQg(Yk5}YAfm}pcWT2 z*`i9|)Vg^#@N5Usc+E^`8eb4F@9b?vV-Yl%Y?rt!KHLzZ%@&DsmFxDdyq^LO$2_*F0`h)WXcObsq>|B2V+|Ajup1M!|RtwC=> z)3WtgzkDOvS$Q6C*`Z-^S#x@%7-mKsiSf8MGlYB7L*VJ2?Q^+t1-Kub{GL1z`UvAO zkFp~3lqKYmO*QLLU$qtn9hEjIHz-orB=WR$`GK>!5|q%Vf}^-kz*t$7kP^z!rN&xt z``-SpYao1K%Y^7n3!$T(SSd%Ywyr~USq*_(JOd~NVnHcWmapv~$(R?WG2*+6+0aZH zlmg7K+|B*?ogefK1V7w4Cf?5o;LH)MR4&(6u0)l&T47G9{rHK|L) zOjwvFwni|^&mxwPGR7@4)RFPO`;#;Mp>wZ#sQyxssq5>Ax{8uYRF~J1ycU@BX2n60 zO%r%ET&bZXS=nX+WA9=K5us=RbNnO%0?C)i<+;{Wf0pb1%P%@E2HtlJM{eX7g61zV zn6bocL4~Q3?#q&P#{i}YT)+WRXMngAr-Moaycj|-GM_Z`0@Bx)*gCmh$8T&O1kZYI z@Sl+}#tT{rBY@6`N;GUz!)S`(cg^$LUR96-5`1!V%0 zAckU+K+@3_CxB!|*+E~mOZHrSSFW#c55EzzEC0Xl*n8ko@O~0PI@^bX^oMopTef}Ro{N!@$HWO;C~!5@rR2nmHS$kV)ls#W(}y+SvrRf`c7v6 zWB=^_<962|e`U*)EWpTMlCT{zNuIV*)NoI~4&{fL9AF3D`=PDR_b=CkIGU_^ifnlc z2kqEY?k^M`$YlIAW{Z7jug{wo7<>4wf3({#`z|>7ctBx6dRpURENU`QW^B*gajBua z)w?fT_`s`nZ+EnHIKu-Dk$z%Q+u}7uetPqT2yIWJPTx7YFL641bU{A8?s&<5OK|o@ zq=+JGx}!E9YeqA6SW~|8ph+jF)H~|$CogRq--qIVR7o@UUYqS^(0wMD@Nbc+L{Zn% zW7C&ETnTX{!u(4Iej#-PY3-OqtV#s?JO)=A)x;U#L3ROp1a1!00000 LNkvXXu0mjf;{kC+ literal 0 HcmV?d00001 diff --git a/src/UTMSP/images/orange_led.png b/src/UTMSP/images/orange_led.png new file mode 100644 index 0000000000000000000000000000000000000000..56cfcad016cb093235136077f7d16bca641325aa GIT binary patch literal 2189 zcmV;82y*v{P)GQ;=ZIegIZ0njmB;^~eT8?}ZB&{`ew*d4cu!_d7zN(5E2AoyAcf zG_5^^gT*E&Yi$SHu~)%dSqGfSj4W~ZqNeBz<&^150x2GcxPJ$NbN3)H^Cc|p_`zdu zgdKaGOEOu0luzQEzz~!(91h*FMt92^eQszjHbV6qKY-$f!@w041826PY6ccn$Yf3e zD1&k=0#Y;#p;b3*O^(B}=WF1x)%gO&HQzhm)8o=xtZNZLbqL|$NcrwMGz**1)Y=C7 zT3-WWMGbHkYmyno91HmLploFUmC*qLQY;Fhe*=7vW?<#PJ(v$m;H_-x{8jfmqnY5c zfKjHzaB#ZPzXC@LQD{8%9Vk6|3Jm2{icq=3Lyb{mnM#{nhVSAo%DeCoy!R*J$%Y@6 zDv!2xWiY2%PRl^Zzdc>Gy;OFDk3eHf8cw3jMtZ0B;{q2?M@||VpE73J@9Bziv_U{8&I6^lgBD`g2%*Fa@*q?VUgC?HkqTFmR>M-MBXE zI2e5nHO|+;=6nNy=NYgQOoPVm+s36Ohy(pwTsHF3iv`8rWh$yI;2PlB9C1V z`1%fP*=t?j9r}A4p_#}Bx7}^-FQ7cQ4pszZJ$4G~l}!~mx%AMaUrszSo~e2Xpe&I0 zq7Yk}hv4V`02#yQ-q9a6k)ffXj@tFPk;BiwfudLttS8#R+}w&sjin&R^^&2Wg_L#0 z^*sS%-bDya{F4>ug#)df6xi5t&%|5%eM?{z_rQFp1uTb70FTE`_DE)70U?%_`^A%G zAqK+AJcRFm!M5}j*W4!8uMdsC_UN|q0~c~k%pQEFjUqeJ6z6cmZ^*e zqMDVABAsRqdp2ZCSX}@ym{3d^*M~hsrcAMR4gsz9wASej3FJ<4^X5&*iMfBf?V&B&{OZh8 zE#{5LToK-e%&07n8O$XBG9X$siB0h(;WiZ1-X81wX%=dFIh`Fv1J}f?Om7|93GbT_7nALimLc6e2$^a4 z;8Q2Fbm#XUo@?+v=(j|ZwM>sUbqkZ=BK22S4_zBN_Y~DUY7_nIs=s_I(e}{s@Y2sc z_TWaN(u(M9ruH|Zcx$H18BV0W)K+TdnAVQ`tp4)f9Exge-Q>{w9aUTNBPOh8`D84V z9XgLjZ2t1BwT8cUbk<+|)2Id*{V@CCFI}a9wUaN}ocXCak@M87oW>Nkl(>{<>M!2J zA7&Cm6Wd>o^gC+Sp1Q2DK;pi}$j(us6l|$k8I6MqkVF$VS?cuEz`XVIW}~yVd(@)~ zj6VG4#`{kD=HfJ;%+R#`mtiI8ToPC=@+6+L)%T2Qek#zd(X+$vb=Z9?Bb>CSZ|mhT zX4@msS=;jm7FX(#^YD0lqt{uo?HwnQ#AMazq!U=t$^CdCye$d{X$2DhhJ< z$YqCVYjw;J7t#rluTJFBD*O42B$KnX-5;l7s$j;{6PE|y?l8o5d-3wym{E8NgOYRx z-=1NQ(p!E0dX{uA1x#7AI(Yt^VK35w5@eN>T(vK8xMP0>WVGtnzZ)pblR|oA9ZTNf zw;lYRc!r4av$$y)meMl305h<7c+cRQ4_i$i7Napd>c`8w269T43+Vp=dzg`*LB_E( P00000NkvXXu0mjfiZwzU literal 0 HcmV?d00001 diff --git a/src/UTMSP/images/pale_green.png b/src/UTMSP/images/pale_green.png new file mode 100644 index 0000000000000000000000000000000000000000..2095a6e06232d9f478db95bd0dcb388b34f805e4 GIT binary patch literal 1997 zcmV;;2Qv7HP)XkfW1>^@SYEdtAJ1SG3aXcyhp0lMj;fY1Wz zB0-#H6QCQZ0h%t1)^dSXC<@f_qDkx~9;!uPq;euk6ea3K4k>at@9DY2hlZ3$j-=)c z2BXp3x%a#OIp^Lpq~I9#6X9-bTUD8`KcypNgedK1tySFxA2afc$j$5^@F86K+gJoie|jCfByROzi~U7 zE3hBl|J%z(wK}bX5mQYWN@fvH5lmVKp64ORhk@sKU}y#m(*Q+NprVvPk|m&Y3W9VP z`sfH=LutlKPyccJ+V6S+b_GkmKOYkf<+iTt@rqG~Jxc_}$G}kkFpNaTAcR0H%i5~g zPQ>0U^eZu*Vg1C~KIQ8dD|cF_Q}WE4Q>R2UiQanF`NzKCI;%_)fKcr*EOi971$Kl zVQni5w8Fv=AD#Ns`1RR#xC8wYrIfvbAR4=1`3x9~o`K=W2n4)AREV*ibP}`heOawS zu9QQ#RWKzBM*TyHTTfqaQLY7yECabpQON7t5sj1K^x#<->pug$$A?f<6RDG0Zjftj zEKqe7a$*+Nwll!W9x=w9PB>$(WsDd8c?Y2i@gkLn!GS@DMV|z}#}5=;3vQGnweZZ36OA#NV3QxsCrg#W%(l4>e2|9=!%snzli1zzV z5n692X%b`$E3jSMgaGuVgsVSGP$UzVrH$o``YDvG0-TM+;OwdMz_DDtJ7<7lPX{Qv z@gJ@e`7h;oq?jsf6xR@L6+9*fU-EtNJT)oICpRjY8B`2pkl;+@2|Uk%hxME&<{kNW zIC*n|0GgrUy0&4*8f5^C`OZyI*YDq+%c$vVTUr)O%7o$2D2ztV0?+a-ZgTECWUFyw zjWw&+noQQTt?~wJA)Jmyz#uzvhkE|Ot%VhN>B_F2LxpIF_y=GldT&6@sfq zou?w{X9`(Hk?+R)8aa`1Q>^;zntNd_i4Ep_;mF?>n0XP8BGtzsC zTa@##S;|5clfXo8gqU!OdiH~Ntc>~@l#IOH0oe};R5UmQ9@WzvWV1h z#C$Y@ee3>AYE4_dxTo)f5s`ejM}~a^xK{@3x~rFwgy^gtJ|V)lHIQ`)M08_SmB2D< zP{e|4V3B(EU+*krluxga+RJGKhWB9E>x3GBBbQ#qWLBbM< z#Ff(mbnqVa+=suPTU8%l6ZPE#J<|xnF+5hR0ffVvp2BaR_LyrIqFXN56|I3Kj{=gm zhgTWz4^Ak=gziv35N;=zQGe<%{Ig%&n2yktj(6Du|zLBml`#OMx1U ziQk(hf*2UsZWk3V#Vsy>?e(|~_I=^q8;_MwZWh}Tfb@1)K9WI*w&dmB`PzA^qz}>; znO4L4*uGaDUHVn6>>>7*4_`~?)XX{O%$$Y9af?{Hzj~*KB z6lRiXWobq-%Wl2dY=`;;a+E&o zwiGO`UwW(l!%W*Y{oz4azl~?b zC4r>&|I@ldU5|F1Is1 zR?OM(%fc^{1*LAo%VMF1NJY#M>nX5lDljR4t%>Z0hbHUb0*kQV*} zfs<8&Y@{HI0&Z%{1!@;TTFQ=U0bP{TB0=HE6(#FIQ4}?N59e{G=MFv8kRpeqeTm_a zGxzb$ch33Fxx>H{w56rrMI?FmY)#UpiLM5L=s^N{lupG0lLD3zS;B~%+d1!qp}Voz zTzb%Dm_Y`7``xAAE1D7~ni|!C7#|H(P;|vO>x>Tg1w3%TGd!Lh2$VCxI(csH!iB$n z*6(_K0ZZKd)q7G+yQ&d2B7p=&wE$&O0F_t3Be=oq9s+@P1JAOc=>+PE1Qn?awR#mm zWx>Y`L4Y3yFY8Nlg5&DzvA=xP3!p8qL?RxM74fEw3{|uel%N2di-qv;7>otS!S4ADW|P>Bj<1eh&mAd}w$sVcz`1R>}QraX?3x9m*Z6<8v1DOyvML`^LR zOCW;abHR9M0!I8{a64TH$O#-W)TP}NkBR0+g#9yW68P%4%wJTc@x5{t$Doa!`3 zM_>plUX|;!MNI_7DML6EhOrQ3$PYZ{Y+=V17`mLbDMUsSS0E#9!&YtsSc!)t?y;F) z#%|2D&vOVEWvZ&wlcJgf-9=y`JPAhwW8f8h!1lpVFQ7UySVJGo7BU8Vq)OnJ5IPl$ z-ELv71sIiq{YoaeFK2^_Ai>1w&tM`riKcU-8==`~?=}{Cney=chW{y=3|rzBZ0xQB zD?7wvj^`2FfvmIu`}Vu(WL_1cMRpHHL!&S?@*INlAfA4L_W-f^%kDX79~u2_eJ>3= zdl~Q%U+SF;i>J&7X|9;~*QNM=MV!s5Tj2J);JNS%5O4<@OkuM^qm%Ztct30wYa*m~ zSD=gmF)D;--irOx@VDlAxBqc*HLGkz3Xq56;Rr-RCx98mr)*8!e)HfliLRkZAHiB~ z72K*P{hME;rkcPKi@&~{tLCp|)OACrPJ~~CBi@mI9=OrRN}u(=xk3-W+^^+fb#Dcv zN)1L_6Ib4iegCNe{cq@78FekXM|M!BMh&(+PGA4P5ZPcc(b~HvS7Ae3ha3vAj|rrH z`}z;37#fM&m4~a3_f!dn&Hik41K@0vYK-)q0tKE~?cjUbRA zQ`|ssYv3RPJnMdWib*WJ9p5Z(&u%K~P=^{!29FyDRrV)q{c?BEPr=NvQ$p!LUjvPS zanHmI^Y?of=QpJEo9OsJ7!ATh<1i684o+UM!PW2L7TLog2D2TMr>@p9pKilWc^inT z!H8q*7IXXF8w;z|pU&>7JBG6R-60qcOoDeHA8POTgmT2?NiY0q|trW{x@p%EF$CsVQI0LB4`)VVOj4 zVciDI^@Vc=uo6}hrVBVRB15QSK4BPvaxGEUH^k=R-MGRU7;ly91rQM!EsF@ffX%~s z4PYq*cCthoz)Wy1%#lG?2wV;?mN~uau7R^V0jQ}JC`kE+2`x(KV|~lajqhU%YtqBB zwDz+4C(V&=hYQOcKe*8EScdCKR>Aw#@yHy{;kJx|LuwBgY%h!`AnG~zjV!5zf~wb>H4YkW z)MV{S*D1F;dDrrX=d)3x@6G$KU0#(RTq~#tk!eP!^=#rZOw)kT!{hAZ#pI59tqI!4 z4PALZw%I6qX!~;UrSz7x@l5+vwrR$G-GT4oc5v+v=fy}18P}Iyji>7?vsF?VctYyk z{U}|piCyf_%m=Z}xkFa^V)5sxjQr?iuL;`kn<4Ww;8`s2aKEXR50yt*HN$JQrE3{5W4H z(n+gqShJwXBx?fe!}M75E&I6O^p(@;rcd?Fn6=}zr4#WA$zN49?U2sd(QkbKBQKy% z@f>&cqtknbO!q{<%t4>rKX$oFs&U*s8w|FCY9Y(g0Rb)JG57JA{HNV~@u`5BgFjz- zF(Sg=IYQKFjnRV)0em@34E>{eq_g;@PbZ>-73Q&`Td*@(H=zFqG(~Ae{HDN+00000 LNkvXXu0mjfo~6uC literal 0 HcmV?d00001 diff --git a/src/UTMSP/images/red_led.png b/src/UTMSP/images/red_led.png new file mode 100644 index 0000000000000000000000000000000000000000..26031ed09e4976b49fd17a0bacd709c13655dc07 GIT binary patch literal 1985 zcmV;y2R`_TP)Ey)&6?vU~6Oo!|ML zbI)A@|6+XB+3By$X1g3L>$ll#z;T@4!dToO3h`V{7|moiAeBy!CIBvV4-Sq#s|ix> zgo}Yd<8ztJCtj5(viuh$09Z8^9-%kXu=S#Cj5z*Vf`o z>xsd|EdOcuz`#^F_O=9tVBB>)|H%%gBUtD4fvd3*Dt7M%4zC%j6$rs4=tmhM{YG%~ z!y~Bl+#IAHJb>l7Sy)(F?wuEePrE~*cqwotL46(wwCyC&zpH+S+wXbrUr41cHXtCU-w#Y>HQcK;q65{B8fuQkF7JH#WvD*h1%WZB0(dzdGO-veUiks0W~bYa3=OLqQ{KmNFJ&&`|BZ59hSkGv1| z7hhDo*Vs{r$b(X&N8Q>|-|_=_Li1%!DreaoB(H@b@ypLJz3)KN(Vu>rl9;;E(H`0v z8SQfIY6Rzp9|BufS7fPFVi~a~C}AKPz?z6}g5-JFn4EysZ@+^C$6b13Vj>`c3LkuD zx$gdbw|)NsaK3*8nChw`d7G25c}KpI6(JK#sVEUudP@)>J3j}j0|UUP((waxa~^Uz z5b!sQjz*kMpMtHq85}Jwz+j;)IZSAy%F$-4iIVh7BdFZWEUfmbla!kgi~aHVQy9$kSHYGqma2jDG6SY zOq@hoT15BEBb61xv0(9ffos|g1UF(4fo|rLNuahQu=oKXlLc{c5i;0oiR;*-Y6gk4 zw#Gd(kE*rX25nI+J|9@Nq2L|ZRTc=zkem{QO!vH0FtZ@6t^yyM2Y#9EEVQbr$+1Fi zz4u<&6OBrmQU`4&DKL)*NNp|Z%Lc^4D&dq9y{Nq?!It_whDZX0Iue!^@p~1;&Ff5~ zZ`VlV*s*Z!#DpG{LK|UOATE~_Mnd~={4MQ?2AzRf21@@^{ZQkW@~`r|2B!4pW`#%rLk&wUF&0KKodTfW$d+Lp zq=95DedM>ZXZ>|IZ$zv~L@v9fr!)TxH*2Xk=ddNFjIsEehLi$iD0Ol|h%~Jc2tg+$ zb||16fZr!@f;GU$mtQvsN6iy8Y9kcmxtLqXFD(&sQVT035-eC0P$zavPhZh-a zBmUDUCwAz$V6&a~4iB53`|==WJ32y+*_kee))mbtlvUBaayo|mBm~4)*e`j9ehm~l zZz|LIQx;>D&A5dnm-e0v&UvaTq1#8 zM41J!NHg*u@`)P5#jz_nuP@-ca^>0Ix~Lk%lQU}U0=u@_W5EQ_G-IV-7-)+r)ef@5 zS61{vz3YM}B%g%MM%m>ph6h&b!u$m`k!)i!*=i{fq+OmiNCwLz5E0*DQD#J|bx^4B zUhw>1Z}N=1d4k6>ZfPmNrq=y{FDh{Oi6~YhwiS#JzT-q+S#~t%aD+Vn;+^L|%)&~7 TJvi?^00000NkvXXu0mjfN?ySO literal 0 HcmV?d00001 diff --git a/src/UTMSP/images/yellow_led.png b/src/UTMSP/images/yellow_led.png new file mode 100644 index 0000000000000000000000000000000000000000..84b4f73272e3bf8a736704d60e82ad21ef245068 GIT binary patch literal 1965 zcmV;e2U7TnP)lyyW4eR2>Qm?S`4z63MnN`!@VyvJVS5r^(_B^}{x|ED^uV#C<4) zXp~KX#JFrGgT<*)K8TOG&0r*R>U3x^A_^+BAdk}Cd-p&0_Ho=7i} z4f}mwXMt^OZ(bf(pI=~gu&fcR)*R63azUf90wFm7gaJW_0ME|=#|0r23czGA6d0eF z>6x4e?AyG#XDFNV7KHNoybg;ku(!CF_m-B}AwRzejK){NU~nRg3C|!1M8(KO2?$4D zVTeQmFcDURQt$(IbK` z3X@s9K&J#wgyV$}%*~C!0*MHKvdU09`s{(ym{Y%y zKJ)x6g8hwP=Xckv>uHgLB|){deOd2xUFj}&*eQ_U)Z}s_nj*`+#{*|i+9K|JDz--!xK4g)R$WKH6NQt+^ z!c;01bK_K)8--xtm%zh`>*a5IhQz3hLmfW+MN3u9k4?)8^MPeQ#Qal+(~OD_2{aif zKxgl65-x}7;xbIUINMrPdDk0<^7-~VU8}D8%U$Qe;dmcRrgt$1+0&(GRFAqglG$;s znAhl#_RWXy!}QBvAvpf9+~avVB+ec=@^$BH8@_L_n8(0o-vK!}ZiQ%5OKFlhW4Bav ztGL0Xn~6K3BDu(On4US0IqXVTb>&>6`1MaGw@y^MI~{bX)wUD#`U-?fjkp996_|=B zfk-BeAxh>|)}rX{q7VUiOcArQ7toC70&7+SOWNBHxL2<^eWSGGlDNQP-G*6PJ?cWDeU0aXnC&ma9D;>I4i7ojv9IOz+9OS7^N6_1XsSo3YAhvK*RX!2sYK=r zDj}FeKD+PMp}&x8aR%>llU;1?lv)n8Dw|bl}K*wTv^$ z-n38^2&1EiLRZm@eyovjk^J1ftIzFetBYxbFol>j-@)ixjz?>j04Coe*HDHC#X>zF z{tLqM{b-me%72mkdgkMas`bZYYSDsD>%lx#iH>N^p!RH86PaGgfYdj6?kR-B1HeTd zpip#w0RrS)?>3=g?eU~j2+2pVwUV~55X<8(6({*Hxi*p`Pr#2vHcbOS;HR+Px(5+% z5VbTJ7fpJ5cLXXbe@Mxc8uY0`gjxYagZ&exhgkL&eKtN)O_CWZ`7#uUcBjL@@#shV z1Wr?*#&jYGL2~Z=uD+_O<8^5UA=t#Bvoo3^d}nbvf)R}vkjg_Pt0!&1rVoL5?m5DY zpuvJ@vPg6Vs#6dyk~3$%>Z^7its`RfP8kRRSdQhzQ8^Y|Rb6DbgCMyU*l%E0(z3?A|6`i&0)rOPkdr3|fB z@na!G0jU{drlew0+Zbvt9z`NV90Whhn*_NUq+^3cg(Fylaa_2tuXF9Xt_C0x$*LJf zdiXC?`O*a`r;xauu4Va;q%Ps?*$!t#WryEvd4w8}+d3m(v@X&sNPU6wpdqdzBV~$b zjOE4bKTm+=70e!7z@xQb?$A(=NhU6u1(;Ms~CIJDGp? z#rEDC{G`*t-fS@FQJX}p+=?U77B4;usX$)Pbg{OZjj6&jO1po5r`N{b@#*!bF-#Q; zHEL=`Qt~$JFn6<-fg}yZWT;+o(EoY8)q1Nl$MDR~U>W*9V6g+Sj08E(+{oH~U;Mu= zF(H0`v%_E*Y&KdRV||>)mS$e|vrXNvq*+-v#u-{8W@9r;`j-Cxl-wkK{~o8wJk)H+ z8Lii9=j{a32BGy#Epg%sPS6GgUf07jx@OkcH?&YJCSN0))zLM>W82+E-FTy3H;%tr zL#R2yjry>o<70C~r2jYt%>eMmPK#yn|9SogSAy|O=)A(-00000NkvXXu0mjft+CBO literal 0 HcmV?d00001 diff --git a/src/UTMSP/utmsp.qrc b/src/UTMSP/utmsp.qrc index a4f96406b31d..9a466fa2deb2 100644 --- a/src/UTMSP/utmsp.qrc +++ b/src/UTMSP/utmsp.qrc @@ -6,6 +6,8 @@ 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/Vehicle.h b/src/Vehicle/Vehicle.h index 9eaf9dd17a66..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; From c01b5bb7e0676d9e763a3d251202c10170f9c1d2 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Thu, 20 Jun 2024 17:40:40 +0400 Subject: [PATCH 11/13] Remove popup notification --- src/PlanView/PlanView.qml | 138 -------------------------------------- 1 file changed, 138 deletions(-) diff --git a/src/PlanView/PlanView.qml b/src/PlanView/PlanView.qml index 3aa6918aa6ac..825b3b7465a2 100644 --- a/src/PlanView/PlanView.qml +++ b/src/PlanView/PlanView.qml @@ -825,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 @@ -1183,124 +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 onVehicleIDSent(id) { From 92003e50a37a5b7dbd2580abbe326b1f7b778905 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Thu, 20 Jun 2024 17:42:17 +0400 Subject: [PATCH 12/13] Refactor UI and update flag for activate notification --- src/UTMSP/UTMSPActivationStatusBar.qml | 2 +- src/UTMSP/UTMSPAdapterEditor.qml | 30 +++++++------------------- src/UTMSP/UTMSPNotificationSlider.qml | 4 ++-- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/src/UTMSP/UTMSPActivationStatusBar.qml b/src/UTMSP/UTMSPActivationStatusBar.qml index e4b4595450b8..68343acdc601 100644 --- a/src/UTMSP/UTMSPActivationStatusBar.qml +++ b/src/UTMSP/UTMSPActivationStatusBar.qml @@ -115,7 +115,7 @@ Item { var centerY = parent.height - ScreenTools.defaultFontPixelHeight * 7.5 /2 - ScreenTools.defaultFontPixelHeight * 0.3 var ctx = getContext("2d") ctx.reset() - ctx.strokeStyle = qgcPal.primaryButton + ctx.strokeStyle = qgcPal.window ctx.lineWidth = ScreenTools.defaultFontPixelHeight * 0.75 ctx.beginPath() diff --git a/src/UTMSP/UTMSPAdapterEditor.qml b/src/UTMSP/UTMSPAdapterEditor.qml index 9ed53c951a5d..041786c18952 100644 --- a/src/UTMSP/UTMSPAdapterEditor.qml +++ b/src/UTMSP/UTMSPAdapterEditor.qml @@ -51,7 +51,6 @@ QGCFlickable { 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 removeFlightPlanTriggered() @@ -453,8 +452,15 @@ QGCFlickable { deletePolygon.visible = true deleteFlightPlan.visible = false } + }else { + myGeoFenceController.deletePolygon(0) } } + + ListView { + id: deletePolygon + model: myGeoFenceController.polygons + } } Row{ @@ -581,23 +587,6 @@ QGCFlickable { } } - Row { - ListView { - id: deletePolygon - model: myGeoFenceController.polygons - delegate: QGCButton { - text: qsTr("Delete") - width: ScreenTools.defaultFontPixelWidth * 7.667 - height: ScreenTools.defaultFontPixelHeight * 1.667 - x: ScreenTools.defaultFontPixelWidth * 41 - y: ScreenTools.defaultFontPixelHeight * 2 - onClicked: { - myGeoFenceController.deletePolygon(index) - geoSwitch.checked =false - } - } - } - } } // Date Interface @@ -1324,14 +1313,11 @@ QGCFlickable { 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 diff --git a/src/UTMSP/UTMSPNotificationSlider.qml b/src/UTMSP/UTMSPNotificationSlider.qml index 30274a1b9174..dd039925e770 100644 --- a/src/UTMSP/UTMSPNotificationSlider.qml +++ b/src/UTMSP/UTMSPNotificationSlider.qml @@ -45,7 +45,7 @@ Rectangle { property var overlay property var indicatorTopText: ["No mission exist", "You've logged in successfully!", - "Your Flight Plan is Approved!", + " Your Flight Plan is Approved!", "Activation Time", "Activated Successfully!", "You've been logged out", @@ -57,7 +57,7 @@ Rectangle { ] property var indicatorBottomText: ["Login to Create a UTM Mission", "Create a UTM Mission", - "Proceed to upload flight plan to vehcile", + " Proceed to upload flight plan to vehcile", UTMSPStateStorage.indicatorActivationTime, "You are allowed to fly...", "Login to Create a UTM Mission", From addab2ff037e76801dcf05afc896dded91a26511 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Thu, 20 Jun 2024 18:28:07 +0400 Subject: [PATCH 13/13] Refactor UTMSP service files --- src/UTMSP/UTMSPAuthorization.cpp | 4 +-- src/UTMSP/UTMSPBlenderRestInterface.cpp | 19 +++++++++--- src/UTMSP/UTMSPBlenderRestInterface.h | 7 +++-- src/UTMSP/UTMSPFlightPlanManager.cpp | 38 ++++++++++++++++++----- src/UTMSP/UTMSPFlightPlanManager.h | 3 +- src/UTMSP/UTMSPNetworkRemoteIDManager.cpp | 38 +++++++++++------------ src/UTMSP/UTMSPRestInterface.cpp | 19 ++++++------ src/UTMSP/UTMSPRestInterface.h | 4 +-- src/UTMSP/UTMSPServiceController.cpp | 8 ++--- src/UTMSP/UTMSPServiceController.h | 8 ----- 10 files changed, 86 insertions(+), 62 deletions(-) diff --git a/src/UTMSP/UTMSPAuthorization.cpp b/src/UTMSP/UTMSPAuthorization.cpp index 8e2e31839876..efd2c1d06401 100644 --- a/src/UTMSP/UTMSPAuthorization.cpp +++ b/src/UTMSP/UTMSPAuthorization.cpp @@ -33,7 +33,7 @@ bool UTMSPAuthorization::requestOAuth2Client(const QString &clientID, const QStr _utmspRestInterface.setBasicToken(encodedBasicToken); _utmspRestInterface.setHost("AuthClient"); const QString target = "/oauth/token/"; - QString 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"; + 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; @@ -41,7 +41,7 @@ bool UTMSPAuthorization::requestOAuth2Client(const QString &clientID, const QStr if(status == 200) { try { - json responseJson = json::parse(response.toStdString()); + json responseJson = json::parse(response); clientToken = responseJson["access_token"]; _isValidToken = true; } diff --git a/src/UTMSP/UTMSPBlenderRestInterface.cpp b/src/UTMSP/UTMSPBlenderRestInterface.cpp index 30e062478bc7..f5e17882b230 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.cpp +++ b/src/UTMSP/UTMSPBlenderRestInterface.cpp @@ -15,25 +15,34 @@ UTMSPBlenderRestInterface::UTMSPBlenderRestInterface(QObject *parent): setHost("BlenderClient"); } -QPair UTMSPBlenderRestInterface::setFlightPlan(const QString& body) +QPair UTMSPBlenderRestInterface::setFlightPlan(const std::string& body) { // Post Flight plan QString setFlightPlanTarget = "/flight_declaration_ops/set_flight_declaration"; - modifyRequest(setFlightPlanTarget, QNetworkAccessManager::PostOperation, body); + modifyRequest(setFlightPlanTarget, QNetworkAccessManager::PostOperation, QString::fromStdString(body)); return executeRequest(); } -QPair UTMSPBlenderRestInterface::requestTelemetry(const QString& body) +QPair UTMSPBlenderRestInterface::requestTelemetry(const std::string& body) { // Post RID data QString target = "/flight_stream/set_telemetry"; - modifyRequest(target, QNetworkAccessManager::PutOperation, body); + modifyRequest(target, QNetworkAccessManager::PutOperation, QString::fromStdString(body)); return executeRequest(); } -QPair UTMSPBlenderRestInterface::ping() +QPair UTMSPBlenderRestInterface::updateFlightState(const std::string& body, const std::string &flightID) +{ + // Post RID data + QString target = "/flight_declaration_ops/flight_declaration_state/" + QString::fromStdString(flightID); + modifyRequest(target, QNetworkAccessManager::PutOperation, QString::fromStdString(body)); + + return executeRequest(); +} + +QPair UTMSPBlenderRestInterface::ping() { QString target = "/ping"; modifyRequest(target, QNetworkAccessManager::GetOperation); diff --git a/src/UTMSP/UTMSPBlenderRestInterface.h b/src/UTMSP/UTMSPBlenderRestInterface.h index 693d1462c768..7f09e4214cc3 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.h +++ b/src/UTMSP/UTMSPBlenderRestInterface.h @@ -19,8 +19,9 @@ class UTMSPBlenderRestInterface: public UTMSPRestInterface public: UTMSPBlenderRestInterface(QObject *parent = nullptr); - QPair setFlightPlan(const QString& body); - QPair requestTelemetry(const QString& body); - QPair 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(); }; diff --git a/src/UTMSP/UTMSPFlightPlanManager.cpp b/src/UTMSP/UTMSPFlightPlanManager.cpp index 24476e4758e1..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), @@ -100,20 +101,19 @@ void UTMSPFlightPlanManager::registerFlightPlan(const std::string &token, json data = _flightDataJson; - auto dataString = QString::fromStdString(data.dump(4)); setHost("BlenderClient"); - setBearerToken(token.c_str()); - auto [statusCode, response] = setFlightPlan(dataString); + 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.toStdString()); + json jsonData = json::parse(response); std::string flightID = jsonData["id"]; _flightResponseID = flightID; - _responseJSON = response.toStdString(); + _responseJSON = response; _responseStatus = true; } catch (const json::parse_error& e) { @@ -135,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 9c5a268688fe..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(); @@ -98,4 +98,5 @@ class UTMSPFlightPlanManager: public UTMSPBlenderRestInterface std::string _responseJSON; bool _responseStatus; std::string _flightResponseID; + json _updateState; }; diff --git a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp index c952222352d1..d026c26b8635 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -144,33 +144,31 @@ void UTMSPNetworkRemoteIDManager::startTelemetry(const double &latitude, final_format["observations"] = final_array; json data = final_format; - auto [statusCode, response] = requestTelemetry( QString::fromStdString(data.dump(4))); + auto [statusCode, response] = requestTelemetry(data.dump(4)); _statusCode = statusCode; - _response = response.toStdString(); + _response = response; UTMSP_LOG_DEBUG()<< "Response " << _response; UTMSP_LOG_DEBUG()<< "Status Code: " << _statusCode; - if(!_response.empty()){ - - 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---------------"; - } - catch (const json::parse_error& e) { - UTMSP_LOG_ERROR() << "UTMSPNetworkRemoteManager: Error parsing the Telemetry response: " << e.what(); - } + 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/UTMSPRestInterface.cpp b/src/UTMSP/UTMSPRestInterface.cpp index a036ece9a00b..8bac1a118bed 100644 --- a/src/UTMSP/UTMSPRestInterface.cpp +++ b/src/UTMSP/UTMSPRestInterface.cpp @@ -30,10 +30,10 @@ UTMSPRestInterface::~UTMSPRestInterface() void UTMSPRestInterface::setHost(const QString &target) { if (target == "AuthClient") { - _currentURL = "https://passport.utm.dev.airoplatform.com"; + _currentURL = "https://id.openskies.sh"; _currentRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); } else if (target == "BlenderClient") { - _currentURL = "https://blender.utm.dev.airoplatform.com"; + _currentURL = "https://testflight.flightblender.com"; _currentRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); } _currentRequest.setRawHeader("User-Agent", QString("Qt/%1").arg(QT_VERSION_STR).toUtf8()); @@ -59,11 +59,11 @@ void UTMSPRestInterface::modifyRequest(const QString &target, QNetworkAccessMana _currentBody = body; } -QPair UTMSPRestInterface::executeRequest() +QPair UTMSPRestInterface::executeRequest() { if (!_networkManager) { qDebug() << "Network manager is not initialized!"; - return qMakePair(0, QString("Network manager is not initialized")); + return qMakePair(0, "Network manager is not initialized"); } QNetworkReply *reply = nullptr; @@ -85,10 +85,10 @@ QPair UTMSPRestInterface::executeRequest() break; default: qDebug() << "Unsupported HTTP method: " << _currentMethod; - return qMakePair(0, QString("Unsupported HTTP method")); + return qMakePair(0, "Unsupported HTTP method"); } - if (!reply) return qMakePair(0, QString("Failed to create network reply")); + if (!reply) return qMakePair(0, "Failed to create network reply"); QEventLoop loop; connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); @@ -99,10 +99,11 @@ QPair UTMSPRestInterface::executeRequest() reply->deleteLater(); - return qMakePair(statusCode, QString::fromUtf8(response)); + return qMakePair(statusCode, (QString::fromUtf8(response)).toStdString()); } -void UTMSPRestInterface::setBearerToken(const QString& token) +void UTMSPRestInterface::setBearerToken(const std::string& token) { - _currentRequest.setRawHeader("Authorization", ("Bearer " + token).toUtf8()); + QString Token = QString::fromStdString(token); + _currentRequest.setRawHeader("Authorization", ("Bearer " + Token).toUtf8()); } diff --git a/src/UTMSP/UTMSPRestInterface.h b/src/UTMSP/UTMSPRestInterface.h index 2f3396d45a27..07d08606191c 100644 --- a/src/UTMSP/UTMSPRestInterface.h +++ b/src/UTMSP/UTMSPRestInterface.h @@ -24,8 +24,8 @@ class UTMSPRestInterface : public QObject { UTMSPRestInterface(QObject *parent = nullptr); ~UTMSPRestInterface(); - void setBearerToken(const QString &token); - QPair executeRequest(); + 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); 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 9462ee042331..2678799814e1 100644 --- a/src/UTMSP/UTMSPServiceController.h +++ b/src/UTMSP/UTMSPServiceController.h @@ -26,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(); @@ -37,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); @@ -79,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;