From c91ddb8ad8300b3e49911a967c64e2b91aa11832 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 31 Jan 2024 17:45:53 +0400 Subject: [PATCH 01/38] Update CMakeLists to support cmake build for UTMSP --- CMakeLists.txt | 2 +- QGCExternalLibs.pri | 2 +- qgroundcontrol.pro | 2 +- src/CMakeLists.txt | 9 +++++++++ src/MissionManager/CMakeLists.txt | 4 ++++ src/MissionManager/GeoFenceController.cc | 2 +- src/MissionManager/GeoFenceController.h | 4 ++-- src/PlanView/CMakeLists.txt | 4 ++++ src/QGCToolbox.cc | 6 +++--- src/QGCToolbox.h | 6 +++--- src/QmlControls/CMakeLists.txt | 4 ++++ src/QmlControls/QGCPalette.cc | 2 +- src/QmlControls/QGCPalette.h | 2 +- src/{ => QmlControls/QGroundControl}/UTMSP/qmldir | 0 src/QmlControls/QGroundControlQmlGlobal.cc | 2 +- src/QmlControls/QGroundControlQmlGlobal.h | 10 +++++----- src/UTMSP/CMakeLists.txt | 4 ++++ src/UTMSP/UTMSPLogger.h | 4 ++-- .../dummy/{qmldir => QGroundControl.UTMSP.qmldir} | 0 src/UTMSP/dummy/utmsp_dummy.qrc | 2 +- src/UTMSP/utmsp.qrc | 2 +- src/Vehicle/CMakeLists.txt | 4 ++++ src/Vehicle/Vehicle.cc | 4 ++-- src/Vehicle/Vehicle.h | 9 ++++++--- 24 files changed, 61 insertions(+), 29 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 5f1aed2be39..f6a29cba556 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_CONFIG_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 390c347a5a3..b52e78c7e0c 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_CONFIG_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 8d73cab9c0d..be4018c55a4 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -1300,7 +1300,7 @@ LinuxBuild { } # UTM Adapter Enabled -contains (DEFINES, CONFIG_UTM_ADAPTER) { +contains (DEFINES, QGC_CONFIG_UTM_ADAPTER) { message("UTM enabled") #-- To test with UTM Adapter Enabled Flag diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b39a53b1b9..0dd3888afd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,6 +18,15 @@ qt_add_library(QGC STATIC QGCToolbox.h ) +####################################################### +# UTMSP FLAG +####################################################### +if(QGC_CONFIG_UTM_ADAPTER) + add_definitions(-DQGC_CONFIG_UTM_ADAPTER) +endif() + +set_source_files_properties(QGCApplication.cc PROPERTIES COMPILE_DEFINITIONS APP_VERSION_STR="${APP_VERSION_STR}") + add_subdirectory(ADSB) add_subdirectory(AirLink) add_subdirectory(AnalyzeView) diff --git a/src/MissionManager/CMakeLists.txt b/src/MissionManager/CMakeLists.txt index 70eea93b379..d951612f2c5 100644 --- a/src/MissionManager/CMakeLists.txt +++ b/src/MissionManager/CMakeLists.txt @@ -1,5 +1,9 @@ find_package(Qt6 REQUIRED COMPONENTS Core Gui Positioning Qml Xml) +if(QGC_CONFIG_UTM_ADAPTER) + add_definitions(-DQGC_CONFIG_UTM_ADAPTER) +endif() + qt_add_library(MissionManager STATIC BlankPlanCreator.cc BlankPlanCreator.h diff --git a/src/MissionManager/GeoFenceController.cc b/src/MissionManager/GeoFenceController.cc index 700e9ce01fe..8ae9a4b9618 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_CONFIG_UTM_ADAPTER void GeoFenceController::loadFlightPlanData() { QJsonArray jsonPolygonArray; diff --git a/src/MissionManager/GeoFenceController.h b/src/MissionManager/GeoFenceController.h index f375a0c377f..791cea85300 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_CONFIG_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_CONFIG_UTM_ADAPTER void uploadFlagSent (bool flag); void polygonBoundarySent (QList coords); #endif diff --git a/src/PlanView/CMakeLists.txt b/src/PlanView/CMakeLists.txt index 1709a033392..3cd71dae35c 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_CONFIG_UTM_ADAPTER) + add_definitions(-DQGC_CONFIG_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/QGCToolbox.cc b/src/QGCToolbox.cc index 4c552d850e6..eed1b025557 100644 --- a/src/QGCToolbox.cc +++ b/src/QGCToolbox.cc @@ -36,7 +36,7 @@ #include CUSTOMHEADER #endif -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_CONFIG_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_CONFIG_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_CONFIG_UTM_ADAPTER _utmspManager->setToolbox(this); #endif } diff --git a/src/QGCToolbox.h b/src/QGCToolbox.h index 78c80304911..37908e26f15 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_CONFIG_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_CONFIG_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_CONFIG_UTM_ADAPTER UTMSPManager* _utmspManager = nullptr; #endif friend class QGCApplication; diff --git a/src/QmlControls/CMakeLists.txt b/src/QmlControls/CMakeLists.txt index 5bffc60942b..e7a61875f38 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_CONFIG_UTM_ADAPTER) + add_definitions(-DQGC_CONFIG_UTM_ADAPTER) +endif() + qt_add_library(QmlControls STATIC AppMessages.cc AppMessages.h diff --git a/src/QmlControls/QGCPalette.cc b/src/QmlControls/QGCPalette.cc index fedfa73b488..14f91daf292 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_CONFIG_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 ceb860a7196..21d316f7ce1 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_CONFIG_UTM_ADAPTER DEFINE_QGC_COLOR(switchUTMSP, setSwitchUTMSP) DEFINE_QGC_COLOR(sliderUTMSP, setSliderUTMSP) DEFINE_QGC_COLOR(successNotifyUTMSP, setSuccessNotifyUTMSP) 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/QmlControls/QGroundControlQmlGlobal.cc b/src/QmlControls/QGroundControlQmlGlobal.cc index a47391a8034..c927bed5df3 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_CONFIG_UTM_ADAPTER _utmspManager = toolbox->utmspManager(); #endif } diff --git a/src/QmlControls/QGroundControlQmlGlobal.h b/src/QmlControls/QGroundControlQmlGlobal.h index e934c581a6a..86d867c0935 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_CONFIG_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_CONFIG_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_CONFIG_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_CONFIG_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_CONFIG_UTM_ADAPTER UTMSPManager* _utmspManager; #endif diff --git a/src/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index d7e96cee36d..6d28d8282dc 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -1,7 +1,11 @@ find_package(Qt6 REQUIRED COMPONENTS Core) +find_package(Threads REQUIRED) +find_package(Boost REQUIRED COMPONENTS system thread) +find_package(OpenSSL REQUIRED) set(UTMSP_RESOURCES) qt_add_library(UTMSP STATIC) +option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) # TODO: Make this QGC_CONFIG_UTM_ADAPTER option(QGC_UTM_ADAPTER "Enable UTM Adapter" OFF) if(QGC_UTM_ADAPTER) diff --git a/src/UTMSP/UTMSPLogger.h b/src/UTMSP/UTMSPLogger.h index 34a2945229a..ec4d9126ec7 100644 --- a/src/UTMSP/UTMSPLogger.h +++ b/src/UTMSP/UTMSPLogger.h @@ -9,8 +9,8 @@ #pragma once -#if defined (CONFIG_UTM_ADAPTER) -#include +#if defined (QGC_CONFIG_UTM_ADAPTER) +#include inline QDebug operator<<(QDebug debug, const std::string &s) { return debug << QString::fromStdString(s); 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 cf2f0c0c076..e07901da1d3 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 78c2ae0f618..a4f96406b31 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 cd7cc6275cf..2a46c7d8db5 100644 --- a/src/Vehicle/CMakeLists.txt +++ b/src/Vehicle/CMakeLists.txt @@ -1,3 +1,7 @@ +if(QGC_CONFIG_UTM_ADAPTER) + add_definitions(-DQGC_CONFIG_UTM_ADAPTER) +endif() + add_subdirectory(Actuators) add_subdirectory(Components) add_subdirectory(FactGroups) diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 68f10959614..9bcb744b8d5 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -169,7 +169,7 @@ Vehicle::Vehicle(LinkInterface* link, _settingsManager->videoSettings()->lowLatencyMode()->setRawValue(true); } -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_CONFIG_UTM_ADAPTER UTMSPManager* utmspManager = _toolbox->utmspManager(); if (utmspManager) { _utmspVehicle = utmspManager->instantiateVehicle(*this); @@ -471,7 +471,7 @@ Vehicle::~Vehicle() delete _autopilotPlugin; _autopilotPlugin = nullptr; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_CONFIG_UTM_ADAPTER delete _utmspVehicle; #endif } diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index fb2d0f1d9a8..c9ba52e9a01 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -42,7 +42,10 @@ #include "VehicleSetpointFactGroup.h" #include "VehicleTemperatureFactGroup.h" #include "VehicleVibrationFactGroup.h" -#include "VehicleWindFactGroup.h" +#ifdef QGC_CONFIG_UTM_ADAPTER +#include "UTMSPVehicle.h" +#include "UTMSPManager.h" +#endif class Actuators; class AutoPilotPlugin; @@ -77,7 +80,7 @@ class UASMessage; class VehicleBatteryFactGroup; class VehicleObjectAvoidance; class QGCToolbox; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_CONFIG_UTM_ADAPTER class UTMSPVehicle; #endif #ifndef OPAQUE_PTR_VEHICLE @@ -1173,7 +1176,7 @@ private slots: VehicleObjectAvoidance* _objectAvoidance = nullptr; Autotune* _autotune = nullptr; -#ifdef CONFIG_UTM_ADAPTER +#ifdef QGC_CONFIG_UTM_ADAPTER UTMSPVehicle* _utmspVehicle = nullptr; #endif From 1274b384f88e0f271dd56f934cfcb2a8649b8e7e Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Tue, 19 Mar 2024 13:34:50 +0400 Subject: [PATCH 02/38] Remove boost dependency and update REST Interface with QTNetwork --- QGCExternalLibs.pri | 1 - src/UTMSP/CMakeLists.txt | 4 +- src/UTMSP/UTMSPAuthorization.cpp | 55 ++--- src/UTMSP/UTMSPAuthorization.h | 15 +- src/UTMSP/UTMSPBlenderRestInterface.cpp | 24 +-- src/UTMSP/UTMSPBlenderRestInterface.h | 15 +- src/UTMSP/UTMSPFlightPlanManager.cpp | 10 +- src/UTMSP/UTMSPNetworkRemoteIDManager.cpp | 34 ++- src/UTMSP/UTMSPRestInterface.cpp | 244 +++++++--------------- src/UTMSP/UTMSPRestInterface.h | 58 ++--- 10 files changed, 158 insertions(+), 302 deletions(-) diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index b52e78c7e0c..d435f873cca 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -229,7 +229,6 @@ contains (DEFINES, DISABLE_ZEROCONF) { # UTM Adapter Enabled contains (DEFINES, QGC_CONFIG_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/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index 6d28d8282dc..7fbd80d1b97 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -1,11 +1,11 @@ -find_package(Qt6 REQUIRED COMPONENTS Core) +find_package(Qt6 REQUIRED COMPONENTS Core Network) find_package(Threads REQUIRED) find_package(Boost REQUIRED COMPONENTS system thread) find_package(OpenSSL REQUIRED) set(UTMSP_RESOURCES) qt_add_library(UTMSP STATIC) -option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) # TODO: Make this QGC_CONFIG_UTM_ADAPTER +option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) option(QGC_UTM_ADAPTER "Enable UTM Adapter" OFF) if(QGC_UTM_ADAPTER) diff --git a/src/UTMSP/UTMSPAuthorization.cpp b/src/UTMSP/UTMSPAuthorization.cpp index 35e9871048b..8e2e3183987 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 852ee17c4b4..de82af82575 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 68c02b456ed..30e062478bc 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 841d65dcdd1..c0e631ed812 100644 --- a/src/UTMSP/UTMSPBlenderRestInterface.h +++ b/src/UTMSP/UTMSPBlenderRestInterface.h @@ -10,16 +10,17 @@ #pragma once #include "UTMSPRestInterface.h" +#include +#include -class UTMSPBlenderRestInterface: public UTMSPRestInterface +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 e40a09f8a59..f2964fb6b96 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 3793f4eea83..336310610d0 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -24,8 +24,7 @@ UTMSPNetworkRemoteIDManager::~UTMSPNetworkRemoteIDManager() void UTMSPNetworkRemoteIDManager::getCapabilty(const std::string &token) { - connectNetwork(); - setBearerToken(token); + setBearerToken(token.c_str()); } void UTMSPNetworkRemoteIDManager::startTelemetry(const double &latitude, @@ -146,34 +145,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 88a72501875..9030e80a668 100644 --- a/src/UTMSP/UTMSPRestInterface.cpp +++ b/src/UTMSP/UTMSPRestInterface.cpp @@ -7,194 +7,100 @@ * ****************************************************************************/ +#include +#include +#include "qeventloop.h" + #include "UTMSPRestInterface.h" #include "UTMSPLogger.h" -#include -#include - -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() -{ - +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; - + QUrl url(_currentURL+target); + _currentRequest.setUrl(url); + _currentMethod = method; + _currentBody = body; } -void UTMSPRestInterface::modifyRequest(std::string target, http::verb method, std::string body) +QPair UTMSPRestInterface::executeRequest() { - _request.target(target); - _request.method(method); - _request.body() = body; - _request.prepare_payload(); -} - -std::pair 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 51a699bf56b..2f3396d45a2 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 be2561a1b521eb4a1a942767f3c71c738ab2fa20 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 11:56:40 +0400 Subject: [PATCH 03/38] 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 8ae9a4b9618..1c0e1f3232e 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 791cea85300..bb0a8f2e7d2 100644 --- a/src/MissionManager/GeoFenceController.h +++ b/src/MissionManager/GeoFenceController.h @@ -64,7 +64,6 @@ class GeoFenceController : public PlanElementController #ifdef QGC_CONFIG_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 883abd2e757..3f1b93494bb 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 53ade8a5d6c..45acebe5001 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 fe604cfc2b2..4053305ec69 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 e97e7b07d52..cc74da66d60 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 ec7da943398..89911e4c3b8 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 4225865c831..84f298fb41b 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 bea8530752a..68432bb1eb8 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 aff750760de..79c435ae103 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 00000000000..68432bb1eb8 --- /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 e07901da1d3..a1af153c4fc 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 e01f9ff580343ccced9ad88ee6ef53d552182bf3 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 11:59:57 +0400 Subject: [PATCH 04/38] 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 cc74da66d60..7d0d426911c 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 cd27add601e6fd13927dd2217ab838c741e30920 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 14:44:05 +0400 Subject: [PATCH 05/38] Update libevent submodule with qmake run --- QGCExternalLibs.pri | 3 +++ 1 file changed, 3 insertions(+) diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index d435f873cca..7cf69f1518d 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -228,6 +228,9 @@ contains (DEFINES, DISABLE_ZEROCONF) { # UTM Adapter Enabled 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 a6bf9c3e81c0146d271ac9284f3aa43169698ace Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 14:51:53 +0400 Subject: [PATCH 06/38] 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 89911e4c3b8..1f49fede366 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 e32ec2d2dc6346b6b7ddd99d6c690044c50a787e Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 27 Mar 2024 15:48:39 +0400 Subject: [PATCH 07/38] 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 1f49fede366..5ee528696f6 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 71efca99daff2fdc3d4b405a2fc191264872dffd Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Mon, 13 May 2024 17:23:22 -0700 Subject: [PATCH 08/38] QtAndroidSerialPort: Rebase on Latest QSerialPortInfo (#11525) --- libs/qtandroidserialport/CMakeLists.txt | 3 + libs/qtandroidserialport/qserialportglobal.h | 12 ++ libs/qtandroidserialport/qserialportinfo.cpp | 121 ++++------- libs/qtandroidserialport/qserialportinfo.h | 49 +---- .../qserialportinfo_android.cpp | 201 ++++++++---------- libs/qtandroidserialport/qserialportinfo_p.h | 59 +---- .../qtandroidserialport.pri | 5 +- .../qtandroidserialport/qtserialportexports.h | 50 +++++ .../qtandroidserialport/qtserialportversion.h | 9 + 9 files changed, 225 insertions(+), 284 deletions(-) create mode 100644 libs/qtandroidserialport/qserialportglobal.h create mode 100644 libs/qtandroidserialport/qtserialportexports.h create mode 100644 libs/qtandroidserialport/qtserialportversion.h diff --git a/libs/qtandroidserialport/CMakeLists.txt b/libs/qtandroidserialport/CMakeLists.txt index a985b6c1ca2..7730017cc31 100644 --- a/libs/qtandroidserialport/CMakeLists.txt +++ b/libs/qtandroidserialport/CMakeLists.txt @@ -10,10 +10,13 @@ qt_add_library(qtandroidserialport STATIC qserialport_p.h qserialport_android.cpp qserialport_android_p.h + qserialportglobal.h qserialportinfo.cpp qserialportinfo.h qserialportinfo_p.h qserialportinfo_android.cpp + qtserialportexports.h + qtserialportversion.h ) target_link_libraries(qtandroidserialport diff --git a/libs/qtandroidserialport/qserialportglobal.h b/libs/qtandroidserialport/qserialportglobal.h new file mode 100644 index 00000000000..6ed2cbdc1c6 --- /dev/null +++ b/libs/qtandroidserialport/qserialportglobal.h @@ -0,0 +1,12 @@ +// Copyright (C) 2012 Denis Shienkov +// Copyright (C) 2012 Laszlo Papp +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QSERIALPORTGLOBAL_H +#define QSERIALPORTGLOBAL_H + +#include +#include +#include "qtserialportexports.h" + +#endif // QSERIALPORTGLOBAL_H diff --git a/libs/qtandroidserialport/qserialportinfo.cpp b/libs/qtandroidserialport/qserialportinfo.cpp index be3eed17c55..24f88ae4664 100644 --- a/libs/qtandroidserialport/qserialportinfo.cpp +++ b/libs/qtandroidserialport/qserialportinfo.cpp @@ -1,44 +1,21 @@ -/**************************************************************************** -** -** Copyright (C) 2011-2012 Denis Shienkov -** Copyright (C) 2011 Sergey Belyashov -** Copyright (C) 2012 Laszlo Papp -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialPort module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2011-2012 Denis Shienkov +// Copyright (C) 2011 Sergey Belyashov +// Copyright (C) 2012 Laszlo Papp +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qserialportinfo.h" #include "qserialportinfo_p.h" #include "qserialport.h" +#include "qserialport_android_p.h" QT_BEGIN_NAMESPACE +// We changed from QScopedPointer to std::unique_ptr, make sure it's +// binary compatible. The QScopedPointer had a non-default deleter, but +// the deleter just provides a static function to use for deletion so we don't +// include it in this template definition (the deleter-class was deleted). +static_assert(sizeof(std::unique_ptr) + == sizeof(QScopedPointer)); /*! \class QSerialPortInfo @@ -49,12 +26,20 @@ QT_BEGIN_NAMESPACE \inmodule QtSerialPort \since 5.1 - Use the static functions to generate a list of QSerialPortInfo - objects. Each QSerialPortInfo object in the list represents a single - serial port and can be queried for the port name, system location, - description, and manufacturer. The QSerialPortInfo class can also be - used as an input parameter for the setPort() method of the QSerialPort - class. + Use the static \l availablePorts() function to generate a list of + QSerialPortInfo objects. Each QSerialPortInfo object in the list represents + a single serial port and can be queried for the \l {portName}{port name}, + \l {systemLocation}{system location}, \l description, \l manufacturer, and + some other hardware parameters. The QSerialPortInfo class can also be + used as an input parameter for the \l {QSerialPort::}{setPort()} method of + the QSerialPort class. + + \section1 Example Usage + + The example code enumerates all available serial ports and prints their + parameters to console: + + \snippet doc_src_serialport.cpp enumerate_ports \sa QSerialPort */ @@ -72,7 +57,7 @@ QSerialPortInfo::QSerialPortInfo() Constructs a copy of \a other. */ QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other) - : d_ptr(other.d_ptr ? new QSerialPortInfoPrivate(*other.d_ptr) : Q_NULLPTR) + : d_ptr(other.d_ptr ? new QSerialPortInfoPrivate(*other.d_ptr) : nullptr) { } @@ -80,13 +65,8 @@ QSerialPortInfo::QSerialPortInfo(const QSerialPortInfo &other) Constructs a QSerialPortInfo object from serial \a port. */ QSerialPortInfo::QSerialPortInfo(const QSerialPort &port) + : QSerialPortInfo(port.portName()) { - foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) { - if (port.portName() == serialPortInfo.portName()) { - *this = serialPortInfo; - break; - } - } } /*! @@ -98,9 +78,10 @@ QSerialPortInfo::QSerialPortInfo(const QSerialPort &port) */ QSerialPortInfo::QSerialPortInfo(const QString &name) { - foreach (const QSerialPortInfo &serialPortInfo, availablePorts()) { - if (name == serialPortInfo.portName()) { - *this = serialPortInfo; + const auto infos = QSerialPortInfo::availablePorts(); + for (const QSerialPortInfo &info : infos) { + if (name == info.portName()) { + *this = info; break; } } @@ -119,8 +100,7 @@ QSerialPortInfo::~QSerialPortInfo() { } -/*! \fn void QSerialPortInfo::swap(QSerialPortInfo &other) - +/*! Swaps QSerialPortInfo \a other with this QSerialPortInfo. This operation is very fast and never fails. */ @@ -225,8 +205,8 @@ quint16 QSerialPortInfo::productIdentifier() const } /*! - Returns true if there is a valid 16-bit vendor number present; otherwise - returns false. + Returns \c true if there is a valid \c 16-bit vendor number present; otherwise + returns \c false. \sa vendorIdentifier(), productIdentifier(), hasProductIdentifier() */ @@ -237,8 +217,8 @@ bool QSerialPortInfo::hasVendorIdentifier() const } /*! - Returns true if there is a valid 16-bit product number present; otherwise - returns false. + Returns \c true if there is a valid \c 16-bit product number present; otherwise + returns \c false. \sa productIdentifier(), vendorIdentifier(), hasVendorIdentifier() */ @@ -253,35 +233,18 @@ bool QSerialPortInfo::hasProductIdentifier() const Returns whether this QSerialPortInfo object holds a serial port definition. - - \sa isBusy() -*/ - -/*! - \fn bool QSerialPortInfo::isBusy() const - - Returns true if serial port is busy; - otherwise returns false. - - \sa isNull() -*/ - -/*! - \fn bool QSerialPortInfo::isValid() const - \obsolete - - Returns true if serial port is present on system; - otherwise returns false. - - \sa isNull(), isBusy() */ /*! \fn QList QSerialPortInfo::standardBaudRates() - Returns a list of available standard baud rates supported by - the current serial port. + Returns a list of available standard baud rates supported + by the target platform. */ +QList QSerialPortInfo::standardBaudRates() +{ + return QSerialPortPrivate::standardBaudRates(); +} /*! \fn QList QSerialPortInfo::availablePorts() diff --git a/libs/qtandroidserialport/qserialportinfo.h b/libs/qtandroidserialport/qserialportinfo.h index dde6909e749..8b5b6543f2a 100644 --- a/libs/qtandroidserialport/qserialportinfo.h +++ b/libs/qtandroidserialport/qserialportinfo.h @@ -1,36 +1,6 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Denis Shienkov -** Copyright (C) 2012 Laszlo Papp -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialPort module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2012 Denis Shienkov +// Copyright (C) 2012 Laszlo Papp +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QSERIALPORTINFO_H #define QSERIALPORTINFO_H @@ -38,12 +8,14 @@ #include #include +#include "qserialportglobal.h" + QT_BEGIN_NAMESPACE class QSerialPort; class QSerialPortInfoPrivate; -class QSerialPortInfo +class Q_SERIALPORT_EXPORT QSerialPortInfo { Q_DECLARE_PRIVATE(QSerialPortInfo) public: @@ -69,21 +41,16 @@ class QSerialPortInfo bool hasProductIdentifier() const; bool isNull() const; - bool isBusy() const; -#if QT_DEPRECATED_SINCE(5, 2) - QT_DEPRECATED bool isValid() const; -#endif static QList standardBaudRates(); static QList availablePorts(); - std::unique_ptr d_ptr; - private: QSerialPortInfo(const QSerialPortInfoPrivate &dd); friend QList availablePortsByUdev(bool &ok); friend QList availablePortsBySysfs(bool &ok); - friend QList availablePortsByFiltersOfDevices(); + friend QList availablePortsByFiltersOfDevices(bool &ok); + std::unique_ptr d_ptr; }; inline bool QSerialPortInfo::isNull() const diff --git a/libs/qtandroidserialport/qserialportinfo_android.cpp b/libs/qtandroidserialport/qserialportinfo_android.cpp index 75a0f0306d8..344e66fed98 100644 --- a/libs/qtandroidserialport/qserialportinfo_android.cpp +++ b/libs/qtandroidserialport/qserialportinfo_android.cpp @@ -1,158 +1,133 @@ -/**************************************************************************** -** -** Copyright (C) 2011-2012 Denis Shienkov -** Copyright (C) 2011 Sergey Belyashov -** Copyright (C) 2012 Laszlo Papp -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialPort module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2011-2012 Denis Shienkov +// Copyright (C) 2011 Sergey Belyashov +// Copyright (C) 2012 Laszlo Papp +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qserialportinfo.h" #include "qserialportinfo_p.h" -#include "qserialport_android_p.h" +#include "qserialport_p.h" -#include -#include +#include #include #include -#include +#include -QT_BEGIN_NAMESPACE -static const char V_jniClassName[] {"org/mavlink/qgroundcontrol/QGCActivity"}; -static const char V_TAG[] {"QGC_QSerialPortInfo"}; +QGC_LOGGING_CATEGORY(QSerialPortInfo_AndroidLog, "qgc.libs.qtandroidserialport.qserialportinfo_android") + +static constexpr const char* jniClassName = "org/mavlink/qgroundcontrol/QGCActivity"; -extern void cleanJavaException(); +QT_BEGIN_NAMESPACE -QList availablePortsByFiltersOfDevices() +QList availablePortsByFiltersOfDevices(bool &ok) { - QList serialPortInfoList; + QJniEnvironment env; + if (!env.isValid()) { + qCWarning(QSerialPortInfo_AndroidLog) << "Invalid QJniEnvironment"; + return QList(); + } - QJniObject resultL = QJniObject::callStaticObjectMethod( - V_jniClassName, - "availableDevicesInfo", - "()[Ljava/lang/String;"); - - if (!resultL.isValid()) { - // No devices found - return serialPortInfoList; + if (!QJniObject::isClassAvailable(jniClassName)) { + qCWarning(QSerialPortInfo_AndroidLog) << "Class Not Available"; + return QList(); + } + + jclass javaClass = env.findClass(jniClassName); + if (!javaClass) { + ok = false; + qCWarning(QSerialPortInfo_AndroidLog) << "Class Not Found"; + return QList(); } - QJniEnvironment envL; - jobjectArray objArrayL = resultL.object(); - int countL = envL->GetArrayLength(objArrayL); + jmethodID methodId = env.findStaticMethod(javaClass, "availableDevicesInfo"); + if (!methodId) { + ok = false; + qCWarning(QSerialPortInfo_AndroidLog) << "Method Not Found"; + return QList(); + } + + const QJniObject result = QJniObject::callStaticMethod(javaClass, methodId); + if (!result.isValid()) { + ok = false; + qCWarning(QSerialPortInfo_AndroidLog) << "Method Call Failed"; + return QList(); + } + + QList serialPortInfoList; + + const jobjectArray objArray = result.object(); + const jsize count = env->GetArrayLength(objArray); + + for (jsize i = 0; i < count; i++) { + jobject obj = env->GetObjectArrayElement(objArray, i); + jstring string = static_cast(obj); + const char *rawString = env->GetStringUTFChars(string, 0); + qCDebug(QSerialPortInfo_AndroidLog) << "Adding device" << rawString; + + const QStringList strList = QString::fromUtf8(rawString).split(QStringLiteral(":")); + env->ReleaseStringUTFChars(string, rawString); + env->DeleteLocalRef(string); + + if (strList.size() < 4) { + qCWarning(QSerialPortInfo_AndroidLog) << "Invalid device info"; + continue; + } - for (int iL = 0; iL < countL; iL++) - { QSerialPortInfoPrivate priv; - jstring stringL = (jstring)(envL->GetObjectArrayElement(objArrayL, iL)); - const char *rawStringL = envL->GetStringUTFChars(stringL, 0); - __android_log_print(ANDROID_LOG_INFO, V_TAG, "Adding device: %s", rawStringL); - QStringList strListL = QString::fromUtf8(rawStringL).split(QStringLiteral(":")); - envL->ReleaseStringUTFChars(stringL, rawStringL); - envL->DeleteLocalRef(stringL); - - priv.portName = strListL[0]; - priv.device = strListL[0]; - priv.manufacturer = strListL[1]; - priv.productIdentifier = strListL[2].toInt(); - priv.hasProductIdentifier = (priv.productIdentifier != 0) ? true: false; - priv.vendorIdentifier = strListL[3].toInt(); - priv.hasVendorIdentifier = (priv.vendorIdentifier != 0) ? true: false; + + priv.portName = strList.at(0); + priv.device = strList.at(0); + // priv.description = strList.at(); + priv.manufacturer = strList.at(1); + // priv.serialNumber = strList.at(); + priv.productIdentifier = strList.at(2).toInt(); + priv.hasProductIdentifier = (priv.productIdentifier != 0); + priv.vendorIdentifier = strList.at(3).toInt(); + priv.hasVendorIdentifier = (priv.vendorIdentifier != 0); serialPortInfoList.append(priv); } + ok = true; return serialPortInfoList; } -QList availablePortsBySysfs() +QList availablePortsBySysfs(bool &ok) { - return availablePortsByFiltersOfDevices(); + ok = false; + return QList(); } -QList availablePortsByUdev() +QList availablePortsByUdev(bool &ok) { - return availablePortsByFiltersOfDevices(); + ok = false; + return QList(); } QList QSerialPortInfo::availablePorts() { - return availablePortsByFiltersOfDevices(); -} - -QList QSerialPortInfo::standardBaudRates() -{ - return QSerialPortPrivate::standardBaudRates(); -} - -bool QSerialPortInfo::isBusy() const -{ - QJniObject jstrL = QJniObject::fromString(d_ptr->portName); - cleanJavaException(); - jboolean resultL = QJniObject::callStaticMethod( - V_jniClassName, - "isDeviceNameOpen", - "(Ljava/lang/String;)Z", - jstrL.object()); - cleanJavaException(); - return resultL; -} + bool ok = false; + const QList serialPortInfoList = availablePortsByFiltersOfDevices(ok); -#if QT_DEPRECATED_SINCE(5, 2) -bool QSerialPortInfo::isValid() const -{ - QJniObject jstrL = QJniObject::fromString(d_ptr->portName); - cleanJavaException(); - jboolean resultL = QJniObject::callStaticMethod( - V_jniClassName, - "isDeviceNameValid", - "(Ljava/lang/String;)Z", - jstrL.object()); - cleanJavaException(); - return resultL; + if (ok) { + return serialPortInfoList; + } else { + return QList(); + } } -#endif QString QSerialPortInfoPrivate::portNameToSystemLocation(const QString &source) { return (source.startsWith(QLatin1Char('/')) - || source.startsWith(QStringLiteral("./")) - || source.startsWith(QStringLiteral("../"))) - ? source : (QStringLiteral("/dev/") + source); + || source.startsWith(QLatin1String("./")) + || source.startsWith(QLatin1String("../"))) + ? source : (QLatin1String("/dev/") + source); } QString QSerialPortInfoPrivate::portNameFromSystemLocation(const QString &source) { - return source.startsWith(QStringLiteral("/dev/")) + return source.startsWith(QLatin1String("/dev/")) ? source.mid(5) : source; } QT_END_NAMESPACE - diff --git a/libs/qtandroidserialport/qserialportinfo_p.h b/libs/qtandroidserialport/qserialportinfo_p.h index 4ca97f96f25..1a949f08e57 100644 --- a/libs/qtandroidserialport/qserialportinfo_p.h +++ b/libs/qtandroidserialport/qserialportinfo_p.h @@ -1,37 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2011-2012 Denis Shienkov -** Copyright (C) 2011 Sergey Belyashov -** Copyright (C) 2012 Laszlo Papp -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtSerialPort module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2011-2012 Denis Shienkov +// Copyright (C) 2017 Sergey Belyashov +// Copyright (C) 2013 Laszlo Papp +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QSERIALPORTINFO_P_H #define QSERIALPORTINFO_P_H @@ -48,24 +18,13 @@ // #include +#include QT_BEGIN_NAMESPACE class Q_AUTOTEST_EXPORT QSerialPortInfoPrivate { public: - QSerialPortInfoPrivate() - : vendorIdentifier(0) - , productIdentifier(0) - , hasVendorIdentifier(false) - , hasProductIdentifier(false) - { - } - - ~QSerialPortInfoPrivate() - { - } - static QString portNameToSystemLocation(const QString &source); static QString portNameFromSystemLocation(const QString &source); @@ -75,11 +34,11 @@ class Q_AUTOTEST_EXPORT QSerialPortInfoPrivate QString manufacturer; QString serialNumber; - quint16 vendorIdentifier; - quint16 productIdentifier; + quint16 vendorIdentifier = 0; + quint16 productIdentifier = 0; - bool hasVendorIdentifier; - bool hasProductIdentifier; + bool hasVendorIdentifier = false; + bool hasProductIdentifier = false; }; QT_END_NAMESPACE diff --git a/libs/qtandroidserialport/qtandroidserialport.pri b/libs/qtandroidserialport/qtandroidserialport.pri index e4d8248c25a..8c8effc4ca4 100644 --- a/libs/qtandroidserialport/qtandroidserialport.pri +++ b/libs/qtandroidserialport/qtandroidserialport.pri @@ -6,7 +6,10 @@ android { PUBLIC_HEADERS += \ $$PWD/qserialport.h \ - $$PWD/qserialportinfo.h + $$PWD/qserialportinfo.h \ + $$PWD/qserialportglobal.h \ + $$PWD/qtserialportexports.h \ + $$PWD/qtserialportversion.h PRIVATE_HEADERS += \ $$PWD/qserialport_p.h \ diff --git a/libs/qtandroidserialport/qtserialportexports.h b/libs/qtandroidserialport/qtserialportexports.h new file mode 100644 index 00000000000..1d995f2999c --- /dev/null +++ b/libs/qtandroidserialport/qtserialportexports.h @@ -0,0 +1,50 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QTSERIALPORTEXPORTS_H +#define QTSERIALPORTEXPORTS_H + +#include +#include // Q_SERIALPORT_EXPORT +#include // QT_IF_DEPRECATED_SINCE + +#if defined(QT_SHARED) || !defined(QT_STATIC) +# if defined(QT_BUILD_SERIALPORT_LIB) +# define Q_SERIALPORT_EXPORT Q_DECL_EXPORT +# else +# define Q_SERIALPORT_EXPORT Q_DECL_IMPORT +# endif +#else +# define Q_SERIALPORT_EXPORT +#endif + +#if !defined(QT_BUILD_SERIALPORT_LIB) && !defined(QT_STATIC) +/* outside library -> inline decl + defi */ +/* static builds treat everything as part of the library, so they never inline */ +# define QT_SERIALPORT_INLINE_SINCE(major, minor) inline +# define QT_SERIALPORT_INLINE_IMPL_SINCE(major, minor) 1 +#elif defined(QT_SERIALPORT_BUILD_REMOVED_API) +/* inside library, inside removed_api.cpp: + * keep deprecated API -> non-inline decl; + * remove deprecated API -> inline decl; + * definition is always available */ +# define QT_SERIALPORT_INLINE_SINCE(major, minor) \ + QT_IF_DEPRECATED_SINCE(major, minor, inline, /* not inline */) +# define QT_SERIALPORT_INLINE_IMPL_SINCE(major, minor) 1 +#else +/* inside library, outside removed_api.cpp: + * keep deprecated API -> non-inline decl, no defi; + * remove deprecated API -> inline decl, defi */ +# define QT_SERIALPORT_INLINE_SINCE(major, minor) \ + QT_IF_DEPRECATED_SINCE(major, minor, inline, /* not inline */) +# define QT_SERIALPORT_INLINE_IMPL_SINCE(major, minor) \ + QT_IF_DEPRECATED_SINCE(major, minor, 1, 0) +#endif + +#ifdef QT_SERIALPORT_BUILD_REMOVED_API +# define QT_SERIALPORT_REMOVED_SINCE(major, minor) QT_DEPRECATED_SINCE(major, minor) +#else +# define QT_SERIALPORT_REMOVED_SINCE(major, minor) 0 +#endif + +#endif // QTSERIALPORTEXPORTS_H diff --git a/libs/qtandroidserialport/qtserialportversion.h b/libs/qtandroidserialport/qtserialportversion.h new file mode 100644 index 00000000000..e5984dd54e6 --- /dev/null +++ b/libs/qtandroidserialport/qtserialportversion.h @@ -0,0 +1,9 @@ +/* This file was generated by syncqt. */ +#ifndef QT_QTSERIALPORT_VERSION_H +#define QT_QTSERIALPORT_VERSION_H + +#define QTSERIALPORT_VERSION_STR "6.6.3" + +#define QTSERIALPORT_VERSION 0x060603 + +#endif // QT_QTSERIALPORT_VERSION_H From 5463123141add7c20bd88d0d4a1d82dd04168b89 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Mon, 13 May 2024 23:20:45 +0400 Subject: [PATCH 09/38] 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 | 6 +- 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 | 1 + 26 files changed, 541 insertions(+), 121 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 d6d92dc0ccc..1578b966326 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 e3eb848abb5..72f64f30f7a 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 3f1b93494bb..84c8ea73dad 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 45acebe5001..3aa6918aa6a 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 33b57a3a7fc..a3ed2d38b10 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 7fbd80d1b97..9e68c17fccb 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -1,9 +1,6 @@ find_package(Qt6 REQUIRED COMPONENTS Core Network) -find_package(Threads REQUIRED) -find_package(Boost REQUIRED COMPONENTS system thread) -find_package(OpenSSL REQUIRED) -set(UTMSP_RESOURCES) +# set(UTMSP_RESOURCES) qt_add_library(UTMSP STATIC) option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) @@ -54,7 +51,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 7d0d426911c..e4b4595450b 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 5ee528696f6..9ed53c951a5 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 f2964fb6b96..24476e4758e 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 b771283aec4..9c5a268688f 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 00000000000..af641b61dd8 --- /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 336310610d0..ee9de90ac47 100644 --- a/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp +++ b/src/UTMSP/UTMSPNetworkRemoteIDManager.cpp @@ -148,6 +148,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 00000000000..30274a1b917 --- /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 68432bb1eb8..d55b766d375 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 00000000000..4d577bf6afc --- /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 00000000000..30f31dbd3c6 --- /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 68432bb1eb8..570055add26 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 a1af153c4fc..75beb462b86 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 a4f96406b31..9a466fa2deb 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 c9ba52e9a01..ebf4ffab87d 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -42,6 +42,7 @@ #include "VehicleSetpointFactGroup.h" #include "VehicleTemperatureFactGroup.h" #include "VehicleVibrationFactGroup.h" +#include "VehicleWindFactGroup.h" #ifdef QGC_CONFIG_UTM_ADAPTER #include "UTMSPVehicle.h" #include "UTMSPManager.h" From ac5c650f939259999837cec86c2dbfcdb39641a3 Mon Sep 17 00:00:00 2001 From: rpashchapur Date: Wed, 15 May 2024 10:09:53 +0400 Subject: [PATCH 10/38] Fix minor nit picks --- src/UTMSP/CMakeLists.txt | 6 +++--- src/Vehicle/Vehicle.h | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/UTMSP/CMakeLists.txt b/src/UTMSP/CMakeLists.txt index 9e68c17fccb..e7c75754146 100644 --- a/src/UTMSP/CMakeLists.txt +++ b/src/UTMSP/CMakeLists.txt @@ -1,11 +1,11 @@ find_package(Qt6 REQUIRED COMPONENTS Core Network) -# set(UTMSP_RESOURCES) +set(UTMSP_RESOURCES) qt_add_library(UTMSP STATIC) option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) -option(QGC_UTM_ADAPTER "Enable UTM Adapter" OFF) -if(QGC_UTM_ADAPTER) +option(QGC_CONFIG_UTM_ADAPTER "Enable UTM Adapter" OFF) +if(QGC_CONFIG_UTM_ADAPTER) message(STATUS "UTMSP is Initialized") if(NOT nlohmann_json_FOUND) diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index ebf4ffab87d..2a63069208f 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -43,6 +43,8 @@ #include "VehicleTemperatureFactGroup.h" #include "VehicleVibrationFactGroup.h" #include "VehicleWindFactGroup.h" +#include "VehicleWindFactGroup.h" + #ifdef QGC_CONFIG_UTM_ADAPTER #include "UTMSPVehicle.h" #include "UTMSPManager.h" From a886d301c8bee6595ef43f3d9d58b07e32c73676 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Thu, 16 May 2024 10:00:20 -0700 Subject: [PATCH 11/38] CI: Fix linux Installing Build Tools (#11539) --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index d31f91a5be4..c21553794c0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -63,7 +63,7 @@ jobs: tar -xvf ccache-*-linux-x86_64.tar.xz cd ccache-*-linux-x86_64 sudo make install - sudo add-apt-repository ppa:ubuntu-toolchain-r/ppa + sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt install gcc-13 g++-13 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100 --slave /usr/bin/g++ g++ /usr/bin/g++-13 --slave /usr/bin/gcov gcov /usr/bin/gcov-13 sudo update-alternatives --set gcc /usr/bin/gcc-13 From 3f5d83ec7332bb4d95d6960d04e85a3270e17ca0 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Thu, 16 May 2024 10:07:11 -0700 Subject: [PATCH 12/38] CI: Android Remove Ignore Path (#11537) --- .github/workflows/android.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 3a33bc336e4..1385c21b4ec 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -8,12 +8,10 @@ on: tags: - 'v*' paths-ignore: - - 'android/**' - 'deploy/**' - 'docs/**' pull_request: paths-ignore: - - 'android/**' - 'deploy/**' - 'docs/**' - '.github/workflows/docs_deploy.yml' From c15cad59228e55bed82aee04b4f1174d5bc49f04 Mon Sep 17 00:00:00 2001 From: Holden Date: Mon, 13 May 2024 18:59:30 -0400 Subject: [PATCH 13/38] Android: Fix Checking Storage Permissions --- android/src/AndroidInit.cpp | 2 -- src/main.cc | 8 ++++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/android/src/AndroidInit.cpp b/android/src/AndroidInit.cpp index 69a9f978af1..85ce40bc294 100644 --- a/android/src/AndroidInit.cpp +++ b/android/src/AndroidInit.cpp @@ -141,8 +141,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) JoystickAndroid::setNativeMethods(); - AndroidInterface::checkStoragePermissions(); - QNativeInterface::QAndroidApplication::hideSplashScreen(333); return JNI_VERSION_1_6; diff --git a/src/main.cc b/src/main.cc index f094ce06c8b..36d74662037 100644 --- a/src/main.cc +++ b/src/main.cc @@ -21,6 +21,10 @@ #include "RunGuard.h" #endif +#ifdef Q_OS_ANDROID + #include "AndroidInterface.h" +#endif + #ifdef QT_DEBUG #include "CmdLineOptParser.h" @@ -208,6 +212,10 @@ int main(int argc, char *argv[]) } else #endif { + #ifdef Q_OS_ANDROID + AndroidInterface::checkStoragePermissions(); + #endif + exitCode = app.exec(); } From 3ac70cd795109dcc8516be6c5ed2dd503e0efb27 Mon Sep 17 00:00:00 2001 From: Holden Date: Mon, 13 May 2024 21:19:06 -0400 Subject: [PATCH 14/38] Android: Fix Java Return Type --- libs/qtandroidserialport/qserialportinfo_android.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/qtandroidserialport/qserialportinfo_android.cpp b/libs/qtandroidserialport/qserialportinfo_android.cpp index 344e66fed98..91adea1b5fc 100644 --- a/libs/qtandroidserialport/qserialportinfo_android.cpp +++ b/libs/qtandroidserialport/qserialportinfo_android.cpp @@ -23,11 +23,13 @@ QList availablePortsByFiltersOfDevices(bool &ok) { QJniEnvironment env; if (!env.isValid()) { + ok = false; qCWarning(QSerialPortInfo_AndroidLog) << "Invalid QJniEnvironment"; return QList(); } if (!QJniObject::isClassAvailable(jniClassName)) { + ok = false; qCWarning(QSerialPortInfo_AndroidLog) << "Class Not Available"; return QList(); } @@ -39,14 +41,14 @@ QList availablePortsByFiltersOfDevices(bool &ok) return QList(); } - jmethodID methodId = env.findStaticMethod(javaClass, "availableDevicesInfo"); + jmethodID methodId = env.findStaticMethod(javaClass, "availableDevicesInfo", "()[Ljava/lang/String;"); if (!methodId) { ok = false; qCWarning(QSerialPortInfo_AndroidLog) << "Method Not Found"; return QList(); } - const QJniObject result = QJniObject::callStaticMethod(javaClass, methodId); + const QJniObject result = QJniObject::callStaticObjectMethod(javaClass, methodId); if (!result.isValid()) { ok = false; qCWarning(QSerialPortInfo_AndroidLog) << "Method Call Failed"; @@ -88,7 +90,7 @@ QList availablePortsByFiltersOfDevices(bool &ok) serialPortInfoList.append(priv); } - ok = true; + ok = !serialPortInfoList.isEmpty(); return serialPortInfoList; } From af1df0289769c432d60b4a2296db41e8fd9a525b Mon Sep 17 00:00:00 2001 From: ivanzivotic <112751953+ivanzivotic@users.noreply.github.com> Date: Sat, 18 May 2024 09:31:56 +0200 Subject: [PATCH 15/38] JoystickAndroid: hat button reading (#11266) --- src/Joystick/JoystickAndroid.cc | 33 ++++++++++++++++++++++++++++++--- src/Joystick/JoystickAndroid.h | 3 ++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/Joystick/JoystickAndroid.cc b/src/Joystick/JoystickAndroid.cc index cd69b3d727d..75f77194129 100644 --- a/src/Joystick/JoystickAndroid.cc +++ b/src/Joystick/JoystickAndroid.cc @@ -10,6 +10,8 @@ int JoystickAndroid::_androidBtnListCount; int *JoystickAndroid::_androidBtnList; int JoystickAndroid::ACTION_DOWN; int JoystickAndroid::ACTION_UP; +int JoystickAndroid::AXIS_HAT_X; +int JoystickAndroid::AXIS_HAT_Y; QMutex JoystickAndroid::m_mutex; static void clear_jni_exception() @@ -202,10 +204,33 @@ int JoystickAndroid::_getAxis(int i) { return axisValue[ i ]; } +int JoystickAndroid::_getAndroidHatAxis(int axisHatCode) { + for(int i = 0; i < _axisCount; i++) { + if (axisCode[i] == axisHatCode) { + return _getAxis(i); + } + } + return 0; +} + bool JoystickAndroid::_getHat(int hat,int i) { - Q_UNUSED(hat); - Q_UNUSED(i); - return false; + // Android supports only one hat button + if (hat != 0) { + return false; + } + + switch (i) { + case 0: + return _getAndroidHatAxis(AXIS_HAT_Y) < 0; + case 1: + return _getAndroidHatAxis(AXIS_HAT_Y) > 0; + case 2: + return _getAndroidHatAxis(AXIS_HAT_X) < 0; + case 3: + return _getAndroidHatAxis(AXIS_HAT_X) > 0; + default: + return false; + } } static JoystickManager *_manager = nullptr; @@ -249,6 +274,8 @@ bool JoystickAndroid::init(JoystickManager *manager) { ACTION_DOWN = QJniObject::getStaticField("android/view/KeyEvent", "ACTION_DOWN"); ACTION_UP = QJniObject::getStaticField("android/view/KeyEvent", "ACTION_UP"); + AXIS_HAT_X = QJniObject::getStaticField("android/view/MotionEvent", "AXIS_HAT_X"); + AXIS_HAT_Y = QJniObject::getStaticField("android/view/MotionEvent", "AXIS_HAT_Y"); return true; } diff --git a/src/Joystick/JoystickAndroid.h b/src/Joystick/JoystickAndroid.h index 7df4e9f4e64..a99071001b1 100644 --- a/src/Joystick/JoystickAndroid.h +++ b/src/Joystick/JoystickAndroid.h @@ -22,6 +22,7 @@ class JoystickAndroid : public Joystick, public QtAndroidPrivate::GenericMotionE private: bool handleKeyEvent(jobject event); bool handleGenericMotionEvent(jobject event); + int _getAndroidHatAxis(int axisHatCode); virtual bool _open (); virtual void _close (); @@ -39,7 +40,7 @@ class JoystickAndroid : public Joystick, public QtAndroidPrivate::GenericMotionE static int * _androidBtnList; //list of all possible android buttons static int _androidBtnListCount; - static int ACTION_DOWN, ACTION_UP; + static int ACTION_DOWN, ACTION_UP, AXIS_HAT_X, AXIS_HAT_Y; static QMutex m_mutex; int deviceId; From 30d3491f7203e0dc13d699bf07702b400f510bc8 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Mon, 20 May 2024 18:40:18 +0000 Subject: [PATCH 16/38] Update PX4 Firmware metadata Mon May 20 18:40:18 UTC 2024 --- .../PX4/PX4ParameterFactMetaData.xml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index e699b8a3071..af0faf345d4 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -730,6 +730,36 @@ 8 + + + Enable USB autostart + true + + Disabled + Auto-detect + MAVLink + + + + Specify USB MAVLink mode + true + + normal + custom + onboard + osd + magic + config + iridium + minimal + extvision + extvisionmin + gimbal + onboard_low_bandwidth + uavionix + + + Camera strobe delay From 2ab9e1259e3a38bd3411d8e2e3465960029878fa Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Mon, 20 May 2024 18:41:22 +0000 Subject: [PATCH 17/38] Update PX4 Firmware metadata Mon May 20 18:41:22 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index af0faf345d4..a409a60618e 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -7604,6 +7604,16 @@ PX4 Flow Optical Flow true + + Murata SCH16T IMU (external SPI) + 0 + 1 + true + + Disabled + Enabled + + Sensirion SDP3X differential pressure sensor (external I2C) true From de7afb0924d24b007018e1fd90c7d77090429d72 Mon Sep 17 00:00:00 2001 From: Holden Date: Tue, 14 May 2024 11:48:38 -0400 Subject: [PATCH 18/38] Ardupilot: Add Baro Alt Offset Compensation --- .github/workflows/android-macos.yml | 10 +- .github/workflows/android-windows.yml | 10 +- .github/workflows/android.yml | 10 +- .github/workflows/ios.yml | 4 +- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows-arm.yml | 4 +- .github/workflows/windows.yml | 2 +- deploy/docker/Dockerfile-build-ubuntu | 2 +- deploy/vagrant/Vagrantfile | 2 +- src/FirmwarePlugin/APM/APMFirmwarePlugin.cc | 116 ++++++++ src/FirmwarePlugin/APM/APMFirmwarePlugin.h | 8 + src/Utilities/CMakeLists.txt | 3 +- src/Utilities/DeviceInfo.cc | 281 ++++++++++++++++++-- src/Utilities/DeviceInfo.h | 101 ++++++- src/Vehicle/Vehicle.cc | 7 + src/Vehicle/Vehicle.h | 8 + tools/setup/install-qt-debian.sh | 2 +- 18 files changed, 525 insertions(+), 49 deletions(-) diff --git a/.github/workflows/android-macos.yml b/.github/workflows/android-macos.yml index 33b0c75274f..c1af701a51a 100644 --- a/.github/workflows/android-macos.yml +++ b/.github/workflows/android-macos.yml @@ -62,7 +62,7 @@ jobs: host: mac target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' @@ -76,7 +76,7 @@ jobs: arch: android_armv7 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (arm64_v8a) @@ -89,7 +89,7 @@ jobs: arch: android_arm64_v8a dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86) @@ -102,7 +102,7 @@ jobs: arch: android_x86 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86_64) @@ -115,7 +115,7 @@ jobs: arch: android_x86_64 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Dependencies diff --git a/.github/workflows/android-windows.yml b/.github/workflows/android-windows.yml index 7e72746aec6..0caaa000cf9 100644 --- a/.github/workflows/android-windows.yml +++ b/.github/workflows/android-windows.yml @@ -63,7 +63,7 @@ jobs: host: windows target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' @@ -77,7 +77,7 @@ jobs: arch: android_armv7 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (arm64_v8a) @@ -90,7 +90,7 @@ jobs: arch: android_arm64_v8a dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86) @@ -103,7 +103,7 @@ jobs: arch: android_x86 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86_64) @@ -116,7 +116,7 @@ jobs: arch: android_x86_64 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Dependencies diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 1385c21b4ec..c21fcc5114d 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -105,7 +105,7 @@ jobs: host: linux target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' @@ -119,7 +119,7 @@ jobs: arch: android_armv7 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (arm64_v8a) @@ -132,7 +132,7 @@ jobs: arch: android_arm64_v8a dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86) @@ -145,7 +145,7 @@ jobs: arch: android_x86 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Android (x86_64) @@ -158,7 +158,7 @@ jobs: arch: android_x86_64 dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Cleanup diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index b1b9caf8ba0..54e7a30f341 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -52,7 +52,7 @@ jobs: host: mac target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' @@ -64,7 +64,7 @@ jobs: target: ios dir: ${{ runner.temp }} extra: --autodesktop - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Dependencies diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c21553794c0..2560cc59314 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -94,7 +94,7 @@ jobs: host: linux target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors setup-python: true cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index cc6bc14b740..bcf9e8709fd 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -77,7 +77,7 @@ jobs: host: mac target: desktop dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors setup-python: true cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' diff --git a/.github/workflows/windows-arm.yml b/.github/workflows/windows-arm.yml index fae605ceb40..4e6b6418125 100644 --- a/.github/workflows/windows-arm.yml +++ b/.github/workflows/windows-arm.yml @@ -67,7 +67,7 @@ jobs: target: desktop arch: win64_msvc2019_64 dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Qt6 for Windows (ARM64) @@ -78,7 +78,7 @@ jobs: target: desktop arch: win64_msvc2019_arm64 dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} - name: Install Dependencies diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index fd3feefe21b..08ec2ee00c7 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -84,7 +84,7 @@ jobs: target: desktop arch: win64_msvc2019_64 dir: ${{ runner.temp }} - modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors setup-python: true cache: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }} tools: 'tools_cmake' diff --git a/deploy/docker/Dockerfile-build-ubuntu b/deploy/docker/Dockerfile-build-ubuntu index 62571d5f220..1896e408ed3 100644 --- a/deploy/docker/Dockerfile-build-ubuntu +++ b/deploy/docker/Dockerfile-build-ubuntu @@ -6,7 +6,7 @@ FROM ubuntu:22.04 LABEL authors="Daniel Agar , Patrick José Pereira " ARG QT_VERSION=6.6.3 -ARG QT_MODULES="qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d" +ARG QT_MODULES="qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors" ENV DEBIAN_FRONTEND noninteractive diff --git a/deploy/vagrant/Vagrantfile b/deploy/vagrant/Vagrantfile index 2b21623e3b2..7568b366105 100644 --- a/deploy/vagrant/Vagrantfile +++ b/deploy/vagrant/Vagrantfile @@ -94,7 +94,7 @@ Vagrant.configure(2) do |config| version="6.6" host="linux" target="desktop" - modules="qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d" + modules="qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors" su - vagrant -c "rm -rf ${dir}" su - vagrant -c "mkdir -p ${dir}" su - vagrant -c "python3 -m aqt install-qt -O ${dir} ${host} ${target} ${version} -m ${modules}" diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc index 4fff703aa67..532b419488c 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.cc @@ -31,6 +31,7 @@ #include "Vehicle.h" #include "MAVLinkProtocol.h" #include "QGCLoggingCategory.h" +#include #include #include @@ -1207,3 +1208,118 @@ QVariant APMFirmwarePlugin::mainStatusIndicatorContentItem(const Vehicle*) const { return QVariant::fromValue(QUrl::fromUserInput("qrc:/APM/Indicators/APMMainStatusIndicatorContentItem.qml")); } + +void APMFirmwarePlugin::_setBaroGndTemp(Vehicle* vehicle, qreal temp) +{ + if (!vehicle) { + return; + } + + const QString bareGndTemp("BARO_GND_TEMP"); + + if (vehicle->parameterManager()->parameterExists(FactSystem::defaultComponentId, bareGndTemp)) { + Fact* const param = vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, bareGndTemp); + param->setRawValue(temp); + } +} + +void APMFirmwarePlugin::_setBaroAltOffset(Vehicle* vehicle, qreal offset) +{ + if (!vehicle) { + return; + } + + const QString baroAltOffset("BARO_ALT_OFFSET"); + + if (vehicle->parameterManager()->parameterExists(FactSystem::defaultComponentId, baroAltOffset)) { + Fact* const param = vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, baroAltOffset); + param->setRawValue(offset); + } +} + +#define ALT_METERS (145366.45 * 0.3048) +#define ALT_EXP (1. / 5.225) +#define SEA_PRESSURE 101325. +#define CELSIUS_TO_KELVIN(celsius) (celsius + 273.15) +#define ALT_OFFSET_P(pressure) (1. - pow((pressure / SEA_PRESSURE), ALT_EXP)) +#define ALT_OFFSET_PT(pressure,temperature) ((ALT_OFFSET_P(pressure) * CELSIUS_TO_KELVIN(temperature)) / 0.0065) + +qreal APMFirmwarePlugin::calcAltOffsetPT(uint32_t atmospheric1, qreal temperature1, uint32_t atmospheric2, qreal temperature2) +{ + const qreal alt1 = ALT_OFFSET_PT(atmospheric1, temperature1); + const qreal alt2 = ALT_OFFSET_PT(atmospheric2, temperature2); + const qreal offset = alt1 - alt2; + return offset; +} + +qreal APMFirmwarePlugin::calcAltOffsetP(uint32_t atmospheric1, uint32_t atmospheric2) +{ + const qreal alt1 = ALT_OFFSET_P(atmospheric1) * ALT_METERS; + const qreal alt2 = ALT_OFFSET_P(atmospheric2) * ALT_METERS; + const qreal offset = alt1 - alt2; + return offset; +} + +QPair APMFirmwarePlugin::startCompensatingBaro(Vehicle* vehicle) +{ + // TODO: Running Average? + const QMetaObject::Connection baroPressureUpdater = QObject::connect(QGCDeviceInfo::QGCPressure::instance(), &QGCDeviceInfo::QGCPressure::pressureUpdated, vehicle, [vehicle](qreal pressure, qreal temperature){ + if (!vehicle || !vehicle->flying()) { + return; + } + + if (qFuzzyIsNull(pressure)) { + return; + } + + const qreal initialPressure = vehicle->getInitialGCSPressure(); + if (qFuzzyIsNull(initialPressure)) { + return; + } + + const qreal initialTemperature = vehicle->getInitialGCSTemperature(); + + qreal offset = 0.; + if (!qFuzzyIsNull(temperature) && !qFuzzyIsNull(initialTemperature)) { + offset = APMFirmwarePlugin::calcAltOffsetPT(initialPressure, initialTemperature, pressure, temperature); + } else { + offset = APMFirmwarePlugin::calcAltOffsetP(initialPressure, pressure); + } + + APMFirmwarePlugin::_setBaroAltOffset(vehicle, offset); + }); + + const QMetaObject::Connection baroTempUpdater = connect(QGCDeviceInfo::QGCAmbientTemperature::instance(), &QGCDeviceInfo::QGCAmbientTemperature::temperatureUpdated, vehicle, [vehicle](qreal temperature){ + if (!vehicle || !vehicle->flying()) { + return; + } + + if (qFuzzyIsNull(temperature)) { + return; + } + + APMFirmwarePlugin::_setBaroGndTemp(vehicle, temperature); + }); + + return QPair(baroPressureUpdater, baroTempUpdater); +} + +bool APMFirmwarePlugin::stopCompensatingBaro(const Vehicle* vehicle, QPair updaters) +{ + Q_UNUSED(vehicle); + /*if (!vehicle) { + return false; + }*/ + + bool result = false; + + if (updaters.first) { + result |= QObject::disconnect(updaters.first); + } + + if (updaters.second) { + result |= QObject::disconnect(updaters.second); + } + + return result; +} diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h index ffc3e658712..a8a4c61aa39 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h @@ -92,6 +92,11 @@ class APMFirmwarePlugin : public FirmwarePlugin double maximumHorizontalSpeedMultirotor(Vehicle* vehicle); void guidedModeChangeGroundSpeedMetersSecond(Vehicle *vehicle, double speed); + static QPair startCompensatingBaro(Vehicle* vehicle); + static bool stopCompensatingBaro(const Vehicle* vehicle, QPair updaters); + static qreal calcAltOffsetPT(uint32_t atmospheric1, qreal temperature1, uint32_t atmospheric2, qreal temperature2); + static qreal calcAltOffsetP(uint32_t atmospheric1, uint32_t atmospheric2); + protected: /// All access to singleton is through stack specific implementation APMFirmwarePlugin(void); @@ -99,6 +104,9 @@ class APMFirmwarePlugin : public FirmwarePlugin void setSupportedModes (QList supportedModes); void _sendGCSMotionReport(Vehicle* vehicle, FollowMe::GCSMotionReport& motionReport, uint8_t estimatationCapabilities); + static void _setBaroGndTemp(Vehicle* vehicle, qreal temperature); + static void _setBaroAltOffset(Vehicle* vehicle, qreal offset); + bool _coaxialMotors; private slots: diff --git a/src/Utilities/CMakeLists.txt b/src/Utilities/CMakeLists.txt index 167375a0c46..b3c7a09b63f 100644 --- a/src/Utilities/CMakeLists.txt +++ b/src/Utilities/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(Compression) -find_package(Qt6 REQUIRED COMPONENTS Bluetooth Core Gui Network Positioning Qml Xml) +find_package(Qt6 REQUIRED COMPONENTS Bluetooth Core Gui Network Positioning Sensors Qml Xml) qt_add_library(Utilities STATIC DeviceInfo.cc @@ -68,6 +68,7 @@ target_link_libraries(Utilities Qt6::Gui Qt6::Network Qt6::Positioning + Qt6::Sensors Qt6::Xml ) diff --git a/src/Utilities/DeviceInfo.cc b/src/Utilities/DeviceInfo.cc index 2f12e2afd27..5f906902924 100644 --- a/src/Utilities/DeviceInfo.cc +++ b/src/Utilities/DeviceInfo.cc @@ -1,38 +1,279 @@ #include "DeviceInfo.h" +#include +#include #include #ifdef QGC_ENABLE_BLUETOOTH # include #endif -namespace QGCDeviceInfo { +QGC_LOGGING_CATEGORY(QGCDeviceInfoLog, "qgc.utilities.deviceinfo") - // TODO: - // - reachabilityChanged() - // - Allow to select by transportMedium() +namespace QGCDeviceInfo +{ - bool isInternetAvailable() { - if(QNetworkInformation::availableBackends().isEmpty()) return false; +// TODO: +// - reachabilityChanged() +// - Allow to select by transportMedium() - if(!QNetworkInformation::loadDefaultBackend()) return false; +bool isInternetAvailable() { + if(QNetworkInformation::availableBackends().isEmpty()) return false; - // Note: Qt6.7 will do this automatically - if(!QNetworkInformation::instance()->supports(QNetworkInformation::Feature::Reachability)) - { - if(!QNetworkInformation::loadBackendByFeatures(QNetworkInformation::Feature::Reachability)) return false; + if(!QNetworkInformation::loadDefaultBackend()) return false; + + // Note: Qt6.7 will do this automatically + if(!QNetworkInformation::instance()->supports(QNetworkInformation::Feature::Reachability)) + { + if(!QNetworkInformation::loadBackendByFeatures(QNetworkInformation::Feature::Reachability)) return false; + } + + const QNetworkInformation::Reachability reachability = QNetworkInformation::instance()->reachability(); + + return (reachability == QNetworkInformation::Reachability::Online); +} + +bool isBluetoothAvailable() { + #ifdef QGC_ENABLE_BLUETOOTH + const QList devices = QBluetoothLocalDevice::allDevices(); + return !devices.isEmpty(); + #else + return false; + #endif +} + +//////////////////////////////////////////////////////////////////// + +Q_APPLICATION_STATIC(QGCAmbientTemperature, s_ambientTemperature); + +QGCAmbientTemperature* QGCAmbientTemperature::instance() +{ + return s_ambientTemperature(); +} + +QGCAmbientTemperature::QGCAmbientTemperature(QObject* parent) + : QObject(parent) + , _ambientTemperature(new QAmbientTemperatureSensor(this)) + , _ambientTemperatureFilter(std::make_shared()) +{ + connect(_ambientTemperature, &QAmbientTemperatureSensor::sensorError, this, [](int error) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "QAmbientTemperature error:" << error; + }); + + if (!init()) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Error Initializing Ambient Temperature Sensor"; + } + + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +QGCAmbientTemperature::~QGCAmbientTemperature() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +bool QGCAmbientTemperature::init() +{ + _ambientTemperature->addFilter(_ambientTemperatureFilter.get()); + + const bool connected = _ambientTemperature->connectToBackend(); + if(!connected) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Failed to connect to ambient temperature backend"; + return false; + } else { + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Connected to ambient temperature backend:" << _ambientTemperature->identifier(); + } + + if (_ambientTemperature->isFeatureSupported(QSensor::SkipDuplicates)) { + _ambientTemperature->setSkipDuplicates(true); + } + + const qrangelist dataRates = _ambientTemperature->availableDataRates(); + if (!dataRates.isEmpty()) { + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Available Data Rates:" << dataRates; + // _ambientTemperature->setDataRate(dataRates.first().first); + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Selected Data Rate:" << _ambientTemperature->dataRate(); + } + + const qoutputrangelist outputRanges = _ambientTemperature->outputRanges(); + if (!outputRanges.isEmpty()) { + // qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Output Ranges:" << outputRanges; + // _ambientTemperature->setOutputRange(outputRanges.first().first); + const int outputRangeIndex = _ambientTemperature->outputRange(); + if (outputRangeIndex < outputRanges.size()) { + const qoutputrange outputRange = outputRanges.at(_ambientTemperature->outputRange()); + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Selected Output Range:" << outputRange.minimum << outputRange.maximum << outputRange.accuracy; } + } - const QNetworkInformation::Reachability reachability = QNetworkInformation::instance()->reachability(); + _readingChangedConnection = connect(_ambientTemperature, &QAmbientTemperatureSensor::readingChanged, this, [this]() { + QAmbientTemperatureReading* reading = _ambientTemperature->reading(); + if (!reading) { + return; + } + + _temperatureC = reading->temperature(); + + emit temperatureUpdated(_temperatureC); + }); - return (reachability == QNetworkInformation::Reachability::Online); + // _ambientTemperature->setActive(true); + const bool started = _ambientTemperature->start(); + if (!started) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Failed to start ambient temperature"; + return false; } - bool isBluetoothAvailable() { - #ifdef QGC_ENABLE_BLUETOOTH - const QList devices = QBluetoothLocalDevice::allDevices(); - return !devices.isEmpty(); - #else - return false; - #endif + return true; +} + +void QGCAmbientTemperature::quit() +{ + // _ambientTemperature->setActive(false); + _ambientTemperature->stop(); + _ambientTemperature->disconnect(_readingChangedConnection); +} + +QGCAmbientTemperatureFilter::QGCAmbientTemperatureFilter() + : QAmbientTemperatureFilter() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +QGCAmbientTemperatureFilter::~QGCAmbientTemperatureFilter() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +bool QGCAmbientTemperatureFilter::filter(QAmbientTemperatureReading *reading) +{ + if (!reading) { + return false; } + + const qreal temperature = reading->temperature(); + return ((temperature >= s_minValidTemperatureC) && (temperature <= s_maxValidTemperatureC)); +} + +//////////////////////////////////////////////////////////////////// + +Q_APPLICATION_STATIC(QGCPressure, s_pressure); + +QGCPressure* QGCPressure::instance() +{ + return s_pressure(); +} + +QGCPressure::QGCPressure(QObject* parent) + : QObject(parent) + , _pressure(new QPressureSensor(this)) + , _pressureFilter(std::make_shared()) +{ + connect(_pressure, &QPressureSensor::sensorError, this, [](int error) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "QPressure error:" << error; + }); + + if (!init()) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Error Initializing Pressure Sensor"; + } + + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +QGCPressure::~QGCPressure() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +bool QGCPressure::init() +{ + _pressure->addFilter(_pressureFilter.get()); + + const bool connected = _pressure->connectToBackend(); + if(!connected) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Failed to connect to pressure backend"; + return false; + } else { + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Connected to pressure backend:" << _pressure->identifier(); + } + + if (_pressure->isFeatureSupported(QSensor::SkipDuplicates)) { + _pressure->setSkipDuplicates(true); + } + + const qrangelist dataRates = _pressure->availableDataRates(); + if (!dataRates.isEmpty()) { + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Available Data Rates:" << dataRates; + // _pressure->setDataRate(dataRates.first().first); + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Selected Data Rate:" << _pressure->dataRate(); + } + + const qoutputrangelist outputRanges = _pressure->outputRanges(); + if (!outputRanges.isEmpty()) { + // qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Output Ranges:" << outputRanges; + // _pressure->setOutputRange(outputRanges.first().first); + const int outputRangeIndex = _pressure->outputRange(); + if (outputRangeIndex < outputRanges.size()) { + const qoutputrange outputRange = outputRanges.at(_pressure->outputRange()); + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << "Selected Output Range:" << outputRange.minimum << outputRange.maximum << outputRange.accuracy; + } + } + + _readingChangedConnection = connect(_pressure, &QPressureSensor::readingChanged, this, [this]() { + QPressureReading* reading = _pressure->reading(); + if (!reading) { + return; + } + + _temperatureC = reading->temperature(); + _pressurePa = reading->pressure(); + emit pressureUpdated(_pressurePa, _temperatureC); + }); + + // _pressure->setActive(true); + const bool started = _pressure->start(); + if (!started) { + qCWarning(QGCDeviceInfoLog) << Q_FUNC_INFO << "Failed to start pressure"; + return false; + } + + return true; +} + +void QGCPressure::quit() +{ + // _pressure->setActive(false); + _pressure->stop(); + _pressure->disconnect(_readingChangedConnection); +} + +QGCPressureFilter::QGCPressureFilter() + : QPressureFilter() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +QGCPressureFilter::~QGCPressureFilter() +{ + qCDebug(QGCDeviceInfoLog) << Q_FUNC_INFO << this; +} + +bool QGCPressureFilter::filter(QPressureReading *reading) +{ + if (!reading) { + return false; + } + + const qreal temperature = reading->temperature(); + if ((temperature < s_minValidTemperatureC) || (temperature > s_maxValidTemperatureC)) { + return false; + } + + const qreal pressure = reading->pressure(); + if ((pressure < s_minValidPressurePa) || (pressure > s_maxValidPressurePa)) { + return false; + } + + return true; +} + } diff --git a/src/Utilities/DeviceInfo.h b/src/Utilities/DeviceInfo.h index 122daa6e438..2491b195bbc 100644 --- a/src/Utilities/DeviceInfo.h +++ b/src/Utilities/DeviceInfo.h @@ -1,6 +1,101 @@ #pragma once -namespace QGCDeviceInfo { - bool isInternetAvailable(); - bool isBluetoothAvailable(); +#include +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(QGCDeviceInfoLog) + +namespace QGCDeviceInfo +{ + +bool isInternetAvailable(); +bool isBluetoothAvailable(); + +class QGCAmbientTemperatureFilter : public QAmbientTemperatureFilter +{ +public: + QGCAmbientTemperatureFilter(); + ~QGCAmbientTemperatureFilter(); + + bool filter(QAmbientTemperatureReading *reading) final; + +private: + static constexpr const qreal s_minValidTemperatureC = -40.; + static constexpr const qreal s_maxValidTemperatureC = 85.; +}; + +class QGCAmbientTemperature : public QObject +{ + Q_OBJECT + +public: + QGCAmbientTemperature(QObject* parent = nullptr); + ~QGCAmbientTemperature(); + + static QGCAmbientTemperature* instance(); + + qreal temperature() const { return _temperatureC; } + + bool init(); + void quit(); + +signals: + void temperatureUpdated(qreal temperature); + +private: + std::shared_ptr _ambientTemperatureFilter = nullptr; + QAmbientTemperatureSensor* _ambientTemperature = nullptr; + + QMetaObject::Connection _readingChangedConnection; + + qreal _temperatureC = 0; +}; + + +class QGCPressureFilter : public QPressureFilter +{ +public: + QGCPressureFilter(); + ~QGCPressureFilter(); + + bool filter(QPressureReading *reading) final; + +private: + static constexpr const qreal s_minValidPressurePa = 45000.; + static constexpr const qreal s_maxValidPressurePa = 110000.; + + static constexpr const qreal s_minValidTemperatureC = -40.; + static constexpr const qreal s_maxValidTemperatureC = 85.; +}; + +class QGCPressure : public QObject +{ + Q_OBJECT + +public: + QGCPressure(QObject* parent = nullptr); + ~QGCPressure(); + + static QGCPressure* instance(); + + qreal pressure() const { return _pressurePa; } + qreal temperature() const { return _temperatureC; } + + bool init(); + void quit(); + +signals: + void pressureUpdated(qreal pressure, qreal temperature); + +private: + std::shared_ptr _pressureFilter = nullptr; + QPressureSensor* _pressure = nullptr; + + QMetaObject::Connection _readingChangedConnection; + + qreal _temperatureC = 0; + qreal _pressurePa = 0; +}; + } diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 68f10959614..4e10f9ea14f 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -50,6 +50,7 @@ #include "VideoManager.h" #include "VideoReceiver.h" #include "VideoSettings.h" +#include #ifdef CONFIG_UTM_ADAPTER #include "UTMSPVehicle.h" @@ -154,6 +155,12 @@ Vehicle::Vehicle(LinkInterface* link, connect(this, &Vehicle::flightModeChanged, this, &Vehicle::_handleFlightModeChanged); connect(this, &Vehicle::armedChanged, this, &Vehicle::_announceArmedChanged); + connect(this, &Vehicle::flyingChanged, this, [this](bool flying){ + if (flying) { + setInitialGCSPressure(QGCDeviceInfo::QGCPressure::instance()->pressure()); + setInitialGCSTemperature(QGCDeviceInfo::QGCPressure::instance()->temperature()); + } + }); connect(_toolbox->multiVehicleManager(), &MultiVehicleManager::parameterReadyVehicleAvailableChanged, this, &Vehicle::_vehicleParamLoaded); diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index fb2d0f1d9a8..1ca555c0766 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -476,6 +476,11 @@ class Vehicle : public FactGroup QGeoCoordinate coordinate() { return _coordinate; } QGeoCoordinate armedPosition () { return _armedPosition; } + qreal getInitialGCSPressure() const { return _initialGCSPressure; } + qreal getInitialGCSTemperature() const { return _initialGCSTemperature; } + void setInitialGCSPressure(qreal pressure) { _initialGCSPressure = pressure; } + void setInitialGCSTemperature(qreal temperature) { _initialGCSTemperature = temperature; } + void updateFlightDistance(double distance); bool joystickEnabled () const; @@ -1115,6 +1120,9 @@ private slots: QGeoCoordinate _homePosition; QGeoCoordinate _armedPosition; + qreal _initialGCSPressure = 0.; + qreal _initialGCSTemperature = 0.; + int _currentMessageCount = 0; int _messageCount = 0; int _currentErrorCount = 0; diff --git a/tools/setup/install-qt-debian.sh b/tools/setup/install-qt-debian.sh index d5628ba0c3f..af09634aa4a 100755 --- a/tools/setup/install-qt-debian.sh +++ b/tools/setup/install-qt-debian.sh @@ -5,7 +5,7 @@ QT_VERSION="${QT_VERSION:-6.6.3}" QT_PATH="${QT_PATH:-/opt/Qt}" QT_HOST="${QT_HOST:-linux}" QT_TARGET="${QT_TARGET:-desktop}" -QT_MODULES="${QT_MODULES:-qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d}" +QT_MODULES="${QT_MODULES:-qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors}" # Exit immediately if a command exits with a non-zero status set -e From 32eed9ecef16eadf217ff271b9041b3fea44e94c Mon Sep 17 00:00:00 2001 From: Julian Oes Date: Thu, 30 May 2024 16:17:13 +1200 Subject: [PATCH 19/38] Utilities: fixup warnings and linking (#11572) This fixes: - tabs instead of spaces - reordering of variables - linking in qmake --- qgroundcontrol.pro | 3 ++- src/Utilities/DeviceInfo.cc | 40 ++++++++++++++++++------------------- src/Utilities/DeviceInfo.h | 34 +++++++++++++++---------------- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 8d73cab9c0d..30725ecb679 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -258,7 +258,8 @@ QT += \ texttospeech \ core-private \ core5compat \ - quick3d + quick3d \ + sensors # Multimedia only used if QVC is enabled !contains (DEFINES, QGC_DISABLE_UVC) { diff --git a/src/Utilities/DeviceInfo.cc b/src/Utilities/DeviceInfo.cc index 5f906902924..41a4784d8b0 100644 --- a/src/Utilities/DeviceInfo.cc +++ b/src/Utilities/DeviceInfo.cc @@ -4,7 +4,7 @@ #include #include #ifdef QGC_ENABLE_BLUETOOTH -# include +# include #endif QGC_LOGGING_CATEGORY(QGCDeviceInfoLog, "qgc.utilities.deviceinfo") @@ -13,8 +13,8 @@ namespace QGCDeviceInfo { // TODO: -// - reachabilityChanged() -// - Allow to select by transportMedium() +// - reachabilityChanged() +// - Allow to select by transportMedium() bool isInternetAvailable() { if(QNetworkInformation::availableBackends().isEmpty()) return false; @@ -51,7 +51,7 @@ QGCAmbientTemperature* QGCAmbientTemperature::instance() } QGCAmbientTemperature::QGCAmbientTemperature(QObject* parent) - : QObject(parent) + : QObject(parent) , _ambientTemperature(new QAmbientTemperatureSensor(this)) , _ambientTemperatureFilter(std::make_shared()) { @@ -146,11 +146,11 @@ QGCAmbientTemperatureFilter::~QGCAmbientTemperatureFilter() bool QGCAmbientTemperatureFilter::filter(QAmbientTemperatureReading *reading) { - if (!reading) { - return false; - } + if (!reading) { + return false; + } - const qreal temperature = reading->temperature(); + const qreal temperature = reading->temperature(); return ((temperature >= s_minValidTemperatureC) && (temperature <= s_maxValidTemperatureC)); } @@ -164,7 +164,7 @@ QGCPressure* QGCPressure::instance() } QGCPressure::QGCPressure(QObject* parent) - : QObject(parent) + : QObject(parent) , _pressure(new QPressureSensor(this)) , _pressureFilter(std::make_shared()) { @@ -259,21 +259,21 @@ QGCPressureFilter::~QGCPressureFilter() bool QGCPressureFilter::filter(QPressureReading *reading) { - if (!reading) { - return false; - } + if (!reading) { + return false; + } - const qreal temperature = reading->temperature(); - if ((temperature < s_minValidTemperatureC) || (temperature > s_maxValidTemperatureC)) { - return false; - } + const qreal temperature = reading->temperature(); + if ((temperature < s_minValidTemperatureC) || (temperature > s_maxValidTemperatureC)) { + return false; + } - const qreal pressure = reading->pressure(); + const qreal pressure = reading->pressure(); if ((pressure < s_minValidPressurePa) || (pressure > s_maxValidPressurePa)) { - return false; - } + return false; + } - return true; + return true; } } diff --git a/src/Utilities/DeviceInfo.h b/src/Utilities/DeviceInfo.h index 2491b195bbc..0d3269b0322 100644 --- a/src/Utilities/DeviceInfo.h +++ b/src/Utilities/DeviceInfo.h @@ -18,7 +18,7 @@ class QGCAmbientTemperatureFilter : public QAmbientTemperatureFilter QGCAmbientTemperatureFilter(); ~QGCAmbientTemperatureFilter(); - bool filter(QAmbientTemperatureReading *reading) final; + bool filter(QAmbientTemperatureReading *reading) final; private: static constexpr const qreal s_minValidTemperatureC = -40.; @@ -27,15 +27,15 @@ class QGCAmbientTemperatureFilter : public QAmbientTemperatureFilter class QGCAmbientTemperature : public QObject { - Q_OBJECT + Q_OBJECT public: - QGCAmbientTemperature(QObject* parent = nullptr); - ~QGCAmbientTemperature(); + QGCAmbientTemperature(QObject* parent = nullptr); + ~QGCAmbientTemperature(); - static QGCAmbientTemperature* instance(); + static QGCAmbientTemperature* instance(); - qreal temperature() const { return _temperatureC; } + qreal temperature() const { return _temperatureC; } bool init(); void quit(); @@ -44,12 +44,12 @@ class QGCAmbientTemperature : public QObject void temperatureUpdated(qreal temperature); private: - std::shared_ptr _ambientTemperatureFilter = nullptr; QAmbientTemperatureSensor* _ambientTemperature = nullptr; + std::shared_ptr _ambientTemperatureFilter = nullptr; QMetaObject::Connection _readingChangedConnection; - qreal _temperatureC = 0; + qreal _temperatureC = 0; }; @@ -59,7 +59,7 @@ class QGCPressureFilter : public QPressureFilter QGCPressureFilter(); ~QGCPressureFilter(); - bool filter(QPressureReading *reading) final; + bool filter(QPressureReading *reading) final; private: static constexpr const qreal s_minValidPressurePa = 45000.; @@ -71,16 +71,16 @@ class QGCPressureFilter : public QPressureFilter class QGCPressure : public QObject { - Q_OBJECT + Q_OBJECT public: - QGCPressure(QObject* parent = nullptr); - ~QGCPressure(); + QGCPressure(QObject* parent = nullptr); + ~QGCPressure(); static QGCPressure* instance(); - qreal pressure() const { return _pressurePa; } - qreal temperature() const { return _temperatureC; } + qreal pressure() const { return _pressurePa; } + qreal temperature() const { return _temperatureC; } bool init(); void quit(); @@ -89,13 +89,13 @@ class QGCPressure : public QObject void pressureUpdated(qreal pressure, qreal temperature); private: - std::shared_ptr _pressureFilter = nullptr; QPressureSensor* _pressure = nullptr; + std::shared_ptr _pressureFilter = nullptr; QMetaObject::Connection _readingChangedConnection; - qreal _temperatureC = 0; - qreal _pressurePa = 0; + qreal _temperatureC = 0; + qreal _pressurePa = 0; }; } From fe3b5f2a1fccc48f27d3917fc50781480eb658f4 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Thu, 30 May 2024 03:22:40 -0400 Subject: [PATCH 20/38] CI: Create Temporary QMake Build (#11573) --- .github/workflows/android.yml | 2 +- .github/workflows/qmake.yml | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/qmake.yml diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index c21fcc5114d..71bec80561e 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -38,7 +38,7 @@ jobs: QT_ANDROID_KEYSTORE_ALIAS: QGCAndroidKeyStore QT_ANDROID_KEYSTORE_STORE_PASS: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} QT_ANDROID_KEYSTORE_KEY_PASS: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} - QT_ANDROID_ABIS: "armeabi-v7a;arm64-v8a" + QT_ANDROID_ABIS: ${{ matrix.BuildType == 'Release' && 'armeabi-v7a;arm64-v8a' || 'arm64-v8a' }} GST_VERSION: 1.22.11 steps: diff --git a/.github/workflows/qmake.yml b/.github/workflows/qmake.yml new file mode 100644 index 00000000000..5a29445c9d4 --- /dev/null +++ b/.github/workflows/qmake.yml @@ -0,0 +1,64 @@ +name: Linux-QMake + +on: + push: + branches: + - master + - 'Stable*' + tags: + - 'v*' + paths-ignore: + - 'android/**' + - 'deploy/**' + - 'docs/**' + pull_request: + paths-ignore: + - 'android/**' + - 'deploy/**' + - 'docs/**' + - '.github/workflows/docs_deploy.yml' + - '.github/workflows/android.yml' + - '.github/workflows/macos.yml' + - '.github/workflows/windows.yml' + +jobs: + build: + runs-on: ubuntu-20.04 + + defaults: + run: + shell: bash + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-tags: true + + - name: Install Dependencies + run: | + chmod a+x ./tools/setup/install-dependencies-debian.sh + sudo ./tools/setup/install-dependencies-debian.sh + sudo apt clean + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: 6.6.3 + aqtversion: ==3.1.* + host: linux + target: desktop + dir: ${{ runner.temp }} + modules: qtcharts qtlocation qtpositioning qtspeech qt5compat qtmultimedia qtserialport qtimageformats qtshadertools qtconnectivity qtquick3d qtsensors + setup-python: true + cache: false + + - name: Create build directory + run: mkdir ${{ runner.temp }}/shadow_build_dir + + - name: Build + working-directory: ${{ runner.temp }}/shadow_build_dir + run: | + qmake -r ${{ github.workspace }}/qgroundcontrol.pro CONFIG+=debug CONFIG+=DailyBuild + make -j2 From 301f5f00b5fa77e72628065ff64382cb98669893 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Thu, 30 May 2024 09:20:02 +0000 Subject: [PATCH 21/38] Update PX4 Firmware metadata Thu May 30 09:20:02 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index a409a60618e..f77bd45bc6e 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -3591,7 +3591,7 @@ 1 0.5 - + Maximal horizontal distance from current position to first waypoint Failsafe check to prevent running mission stored from previous flight at a new takeoff location. Set a value of zero or less to disable. The mission will not be started if the current waypoint is more distant than MIS_DIST_1WP from the current position. -1 From 7c429785abbf914de784442cd47c766923500984 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Thu, 30 May 2024 15:01:09 -0400 Subject: [PATCH 22/38] Ardupilot: Fix Overrides (#11548) --- src/FirmwarePlugin/APM/APMFirmwarePlugin.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h index a8a4c61aa39..19d750add08 100644 --- a/src/FirmwarePlugin/APM/APMFirmwarePlugin.h +++ b/src/FirmwarePlugin/APM/APMFirmwarePlugin.h @@ -88,9 +88,9 @@ class APMFirmwarePlugin : public FirmwarePlugin QVariant mainStatusIndicatorContentItem (const Vehicle* vehicle) const override; // support for changing speed in Copter guide mode: - bool mulirotorSpeedLimitsAvailable(Vehicle* vehicle); - double maximumHorizontalSpeedMultirotor(Vehicle* vehicle); - void guidedModeChangeGroundSpeedMetersSecond(Vehicle *vehicle, double speed); + bool mulirotorSpeedLimitsAvailable(Vehicle* vehicle) override; + double maximumHorizontalSpeedMultirotor(Vehicle* vehicle) override; + void guidedModeChangeGroundSpeedMetersSecond(Vehicle *vehicle, double speed) override; static QPair startCompensatingBaro(Vehicle* vehicle); static bool stopCompensatingBaro(const Vehicle* vehicle, QPair updaters); From 8a20ac66e502748c80588cf3526e5e3fff2c9e1a Mon Sep 17 00:00:00 2001 From: JAE AEROSPACE <113963003+jfbblue0922@users.noreply.github.com> Date: Fri, 31 May 2024 18:36:29 +0900 Subject: [PATCH 23/38] add support for JFB110 (#11515) --- src/Comms/USBBoardInfo.json | 4 ++++ src/VehicleSetup/FirmwareUpgradeController.cc | 1 + 2 files changed, 5 insertions(+) diff --git a/src/Comms/USBBoardInfo.json b/src/Comms/USBBoardInfo.json index 813a5cb0893..6d0a8ecb494 100644 --- a/src/Comms/USBBoardInfo.json +++ b/src/Comms/USBBoardInfo.json @@ -40,6 +40,8 @@ { "vendorID": 11694, "productID": 0, "boardClass": "Pixhawk", "name": "CubePilot" }, + { "vendorID": 2702, "productID": 110, "boardClass": "Pixhawk", "name": "JFB JFB110" }, + { "vendorID": 13735, "productID": 1, "boardClass": "Pixhawk", "name": "ThePeach FCC-K1" }, { "vendorID": 13735, "productID": 2, "boardClass": "Pixhawk", "name": "ThePeach FCC-R1" }, @@ -86,6 +88,8 @@ { "regExp": "^PX4 BL ASC v1.x$", "boardClass": "Pixhawk" }, { "regExp": "^PX4 FMU", "boardClass": "Pixhawk" }, { "regExp": "^PX4 Crazyflie v2.0", "boardClass": "Pixhawk" }, + { "regExp": "^JFB JFB110$", "boardClass": "Pixhawk" }, + { "regExp": "^JFB BL JFB110$", "boardClass": "Pixhawk" }, { "regExp": "^Crazyflie BL", "boardClass": "Pixhawk" }, { "regExp": "^PX4 OmnibusF4SD", "boardClass": "Pixhawk" }, { "regExp": "^fmuv[2345]$", "boardClass": "Pixhawk" }, diff --git a/src/VehicleSetup/FirmwareUpgradeController.cc b/src/VehicleSetup/FirmwareUpgradeController.cc index 13b081b2d60..26b8a31a6e5 100644 --- a/src/VehicleSetup/FirmwareUpgradeController.cc +++ b/src/VehicleSetup/FirmwareUpgradeController.cc @@ -99,6 +99,7 @@ static QMap px4_board_name_map { {1048, "holybro_kakuteh7_default"}, {1053, "holybro_kakuteh7v2_default"}, {1054, "holybro_kakuteh7mini_default"}, + {1110, "jfb_jfb110_default"}, }; uint qHash(const FirmwareUpgradeController::FirmwareIdentifier& firmwareId) From b6dd438cfe43b674b3536c4ae53fe4aefa34cba4 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Fri, 31 May 2024 11:36:47 -0400 Subject: [PATCH 24/38] QtLocationPlugin: Remove Unused Geocoding (#11575) --- src/QtLocationPlugin/CMakeLists.txt | 4 - src/QtLocationPlugin/QGCLocationPlugin.pri | 4 - src/QtLocationPlugin/QGeoCodeReplyQGC.cpp | 297 ------------------ src/QtLocationPlugin/QGeoCodeReplyQGC.h | 68 ---- .../QGeoCodingManagerEngineQGC.cpp | 176 ----------- .../QGeoCodingManagerEngineQGC.h | 78 ----- .../QGeoServiceProviderPluginQGC.cpp | 126 ++++---- .../QGeoServiceProviderPluginQGC.h | 65 +--- src/QtLocationPlugin/qgc_maps_plugin.json | 3 +- 9 files changed, 72 insertions(+), 749 deletions(-) delete mode 100644 src/QtLocationPlugin/QGeoCodeReplyQGC.cpp delete mode 100644 src/QtLocationPlugin/QGeoCodeReplyQGC.h delete mode 100644 src/QtLocationPlugin/QGeoCodingManagerEngineQGC.cpp delete mode 100644 src/QtLocationPlugin/QGeoCodingManagerEngineQGC.h diff --git a/src/QtLocationPlugin/CMakeLists.txt b/src/QtLocationPlugin/CMakeLists.txt index 1185445ffe2..68259bc29cd 100644 --- a/src/QtLocationPlugin/CMakeLists.txt +++ b/src/QtLocationPlugin/CMakeLists.txt @@ -29,10 +29,6 @@ qt_add_plugin(QGCLocation STATIC QGCTileCacheWorker.cpp QGCTileCacheWorker.h QGCTileSet.h - QGeoCodeReplyQGC.cpp - QGeoCodeReplyQGC.h - QGeoCodingManagerEngineQGC.cpp - QGeoCodingManagerEngineQGC.h QGeoMapReplyQGC.cpp QGeoMapReplyQGC.h QGeoServiceProviderPluginQGC.cpp diff --git a/src/QtLocationPlugin/QGCLocationPlugin.pri b/src/QtLocationPlugin/QGCLocationPlugin.pri index a9735970b94..9c6d62d0278 100644 --- a/src/QtLocationPlugin/QGCLocationPlugin.pri +++ b/src/QtLocationPlugin/QGCLocationPlugin.pri @@ -17,8 +17,6 @@ HEADERS += \ $$PWD/QGCMapTileSet.h \ $$PWD/QGCMapUrlEngine.h \ $$PWD/QGCTileCacheWorker.h \ - $$PWD/QGeoCodeReplyQGC.h \ - $$PWD/QGeoCodingManagerEngineQGC.h \ $$PWD/QGeoMapReplyQGC.h \ $$PWD/QGeoServiceProviderPluginQGC.h \ $$PWD/QGeoTileFetcherQGC.h \ @@ -38,8 +36,6 @@ SOURCES += \ $$PWD/QGCMapTileSet.cpp \ $$PWD/QGCMapUrlEngine.cpp \ $$PWD/QGCTileCacheWorker.cpp \ - $$PWD/QGeoCodeReplyQGC.cpp \ - $$PWD/QGeoCodingManagerEngineQGC.cpp \ $$PWD/QGeoMapReplyQGC.cpp \ $$PWD/QGeoServiceProviderPluginQGC.cpp \ $$PWD/QGeoTileFetcherQGC.cpp \ diff --git a/src/QtLocationPlugin/QGeoCodeReplyQGC.cpp b/src/QtLocationPlugin/QGeoCodeReplyQGC.cpp deleted file mode 100644 index 851f5d64dc2..00000000000 --- a/src/QtLocationPlugin/QGeoCodeReplyQGC.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - -#include "QGeoCodeReplyQGC.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -enum QGCGeoCodeType { - GeoCodeTypeUnknown, - StreetAddress, // indicates a precise street address. - Route, // indicates a named route (such as "US 101"). - Intersection, // indicates a major intersection, usually of two major roads. - Political, // indicates a political entity. Usually, this type indicates a polygon of some civil administration. - Country, // indicates the national political entity, and is typically the highest order type returned by the Geocoder. - AdministrativeAreaLevel1, // indicates a first-order civil entity below the country level. Within the United States, these administrative levels are states. - AdministrativeAreaLevel2, // indicates a second-order civil entity below the country level. Within the United States, these administrative levels are counties. - AdministrativeAreaLevel3, // indicates a third-order civil entity below the country level. This type indicates a minor civil division. - ColloquialArea, // indicates a commonly-used alternative name for the entity. - Locality, // indicates an incorporated city or town political entity. - Sublocality, // indicates a first-order civil entity below a locality. For some locations may receive one of the additional types: sublocality_level_1 through to sublocality_level_5. Each sublocality level is a civil entity. Larger numbers indicate a smaller geographic area. - SublocalityLevel1, - SublocalityLevel2, - SublocalityLevel3, - SublocalityLevel4, - SublocalityLevel5, - Neighborhood, // indicates a named neighborhood - Premise, // indicates a named location, usually a building or collection of buildings with a common name - Subpremise, // indicates a first-order entity below a named location, usually a singular building within a collection of buildings with a common name - PostalCode, // indicates a postal code as used to address postal mail within the country. - NaturalFeature, // indicates a prominent natural feature. - Airport, // indicates an airport. - Park, // indicates a named park. - PointOfInterest, // indicates a named point of interest. Typically, these "POI"s are prominent local entities that don't easily fit in another category such as "Empire State Building" or "Statue of Liberty." - Floor, // indicates the floor of a building address. - Establishment, // typically indicates a place that has not yet been categorized. - Parking, // indicates a parking lot or parking structure. - PostBox, // indicates a specific postal box. - PostalTown, // indicates a grouping of geographic areas, such as locality and sublocality, used for mailing addresses in some countries. - RoomIndicates, // the room of a building address. - StreetNumber, // indicates the precise street number. - BusStation, // indicate the location of a bus stop. - TrainStation, // indicate the location of a train stop. - TransitStation, // indicate the location of a public transit stop. -}; - -class JasonMonger { -public: - JasonMonger(); - QSet json2QGCGeoCodeType(const QJsonArray &types); -private: - int _getCode(const QString &key); - QMap _m; -}; - -JasonMonger::JasonMonger() -{ - _m[QStringLiteral("street_address")] = StreetAddress; - _m[QStringLiteral("route")] = Route; - _m[QStringLiteral("intersection")] = Intersection; - _m[QStringLiteral("political")] = Political; - _m[QStringLiteral("country")] = Country; - _m[QStringLiteral("administrative_area_level_1")] = AdministrativeAreaLevel1; - _m[QStringLiteral("administrative_area_level_2")] = AdministrativeAreaLevel2; - _m[QStringLiteral("administrative_area_level_3")] = AdministrativeAreaLevel3; - _m[QStringLiteral("colloquial_area")] = ColloquialArea; - _m[QStringLiteral("locality")] = Locality; - _m[QStringLiteral("sublocality")] = Sublocality; - _m[QStringLiteral("sublocality_level_1")] = SublocalityLevel1; - _m[QStringLiteral("sublocality_level_2")] = SublocalityLevel2; - _m[QStringLiteral("sublocality_level_3")] = SublocalityLevel3; - _m[QStringLiteral("sublocality_level_4")] = SublocalityLevel4; - _m[QStringLiteral("sublocality_level_5")] = SublocalityLevel5; - _m[QStringLiteral("neighborhood")] = Neighborhood; - _m[QStringLiteral("premise")] = Premise; - _m[QStringLiteral("subpremise")] = Subpremise; - _m[QStringLiteral("postal_code")] = PostalCode; - _m[QStringLiteral("natural_feature")] = NaturalFeature; - _m[QStringLiteral("airport")] = Airport; - _m[QStringLiteral("park")] = Park; - _m[QStringLiteral("point_of_interest")] = PointOfInterest; - _m[QStringLiteral("floor")] = Floor; - _m[QStringLiteral("establishment")] = Establishment; - _m[QStringLiteral("parking")] = Parking; - _m[QStringLiteral("post_box")] = PostBox; - _m[QStringLiteral("postal_town")] = PostalTown; - _m[QStringLiteral("room indicates")] = RoomIndicates; - _m[QStringLiteral("street_number")] = StreetNumber; - _m[QStringLiteral("bus_station")] = BusStation; - _m[QStringLiteral("train_station")] = TrainStation; - _m[QStringLiteral("transit_station")] = TransitStation; -} - -int JasonMonger::_getCode(const QString &key) { - return _m.value(key, GeoCodeTypeUnknown); -} - -QSet JasonMonger::json2QGCGeoCodeType(const QJsonArray &types) { - QSet result; - for (int i=0; ideleteLater(); -} - -void QGeoCodeReplyQGC::abort() -{ - if (!m_reply) - return; - - m_reply->abort(); - - m_reply->deleteLater(); - m_reply = 0; -} - -void QGeoCodeReplyQGC::networkReplyFinished() -{ - if (!m_reply) - return; - - if (m_reply->error() != QNetworkReply::NoError) - return; - - QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll()); - QJsonObject object = document.object(); - - if (object.value(QStringLiteral("status")) != QStringLiteral("OK")) { - QString error = object.value(QStringLiteral("status")).toString(); - qWarning() << m_reply->url() << "returned" << error; - setError(QGeoCodeReply::CommunicationError, error); - m_reply->deleteLater(); - m_reply = 0; - return; - } - - QList locations; - QJsonArray results = object.value(QStringLiteral("results")).toArray(); - for (int i=0; i types = kMonger.json2QGCGeoCodeType(c[QStringLiteral("types")].toArray()); - QString long_name = c[QStringLiteral("long_name")].toString(); - QString short_name = c[QStringLiteral("short_name")].toString(); - if (types.contains(Country)) { - address.setCountry(long_name); - address.setCountryCode(short_name); - } else if (types.contains(AdministrativeAreaLevel1)) { - address.setState(long_name); - } else if (types.contains(AdministrativeAreaLevel2)) { - address.setCounty(long_name); - } else if (types.contains(Locality)) { - address.setCity(long_name); - } else if (types.contains(Sublocality)) { - address.setDistrict(long_name); - } else if (types.contains(PostalCode)) { - address.setPostalCode(long_name); - } else if (types.contains(StreetAddress) || types.contains(Route) || types.contains(Intersection)) { - address.setStreet(long_name); - } - } - } - - QGeoCoordinate coordinate; - QGeoRectangle boundingBox; - if (geocode.contains(QStringLiteral("geometry"))) { - QJsonObject geom = geocode.value(QStringLiteral("geometry")).toObject(); - if (geom.contains(QStringLiteral("location"))) { - QJsonObject location = geom.value(QStringLiteral("location")).toObject(); - coordinate.setLatitude(location.value(QStringLiteral("lat")).toDouble()); - coordinate.setLongitude(location.value(QStringLiteral("lng")).toDouble()); - } - if (geom.contains(QStringLiteral("bounds"))) { - QJsonObject bounds = geom.value(QStringLiteral("bounds")).toObject(); - QJsonObject northeast = bounds.value(QStringLiteral("northeast")).toObject(); - QJsonObject southwest = bounds.value(QStringLiteral("southwest")).toObject(); - QGeoCoordinate topRight(northeast.value(QStringLiteral("lat")).toDouble(), - northeast.value(QStringLiteral("lng")).toDouble()); - QGeoCoordinate bottomLeft(southwest.value(QStringLiteral("lat")).toDouble(), - southwest.value(QStringLiteral("lng")).toDouble()); - boundingBox.setTopRight(topRight); - boundingBox.setBottomLeft(bottomLeft); - } - } - - QGeoLocation location; - location.setAddress(address); - location.setCoordinate(coordinate); - location.setBoundingShape(boundingBox); - - locations << location; - } - - setLocations(locations); - setFinished(true); - - m_reply->deleteLater(); - m_reply = 0; -} - -void QGeoCodeReplyQGC::networkReplyError(QNetworkReply::NetworkError error) -{ - Q_UNUSED(error) - if (!m_reply) - return; - setError(QGeoCodeReply::CommunicationError, m_reply->errorString()); - m_reply->deleteLater(); - m_reply = 0; -} diff --git a/src/QtLocationPlugin/QGeoCodeReplyQGC.h b/src/QtLocationPlugin/QGeoCodeReplyQGC.h deleted file mode 100644 index 3325dc20f44..00000000000 --- a/src/QtLocationPlugin/QGeoCodeReplyQGC.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - -#pragma once - -#include -#include - -class QGeoCodeReplyQGC : public QGeoCodeReply -{ - Q_OBJECT - -public: - explicit QGeoCodeReplyQGC(QNetworkReply *reply, QObject *parent = 0); - ~QGeoCodeReplyQGC(); - - void abort(); - -private Q_SLOTS: - void networkReplyFinished(); - void networkReplyError(QNetworkReply::NetworkError error); - -private: - QNetworkReply *m_reply; -}; diff --git a/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.cpp b/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.cpp deleted file mode 100644 index c4f1ea7f48d..00000000000 --- a/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - -#include "QGeoCodingManagerEngineQGC.h" -#include "QGeoCodeReplyQGC.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static QString addressToQuery(const QGeoAddress &address) -{ - return address.street() + QStringLiteral(", ") + - address.district() + QStringLiteral(", ") + - address.city() + QStringLiteral(", ") + - address.state() + QStringLiteral(", ") + - address.country(); -} - -static QString boundingBoxToLtrb(const QGeoRectangle &rect) -{ - return QString::number(rect.topLeft().longitude()) + QLatin1Char(',') + - QString::number(rect.topLeft().latitude()) + QLatin1Char(',') + - QString::number(rect.bottomRight().longitude()) + QLatin1Char(',') + - QString::number(rect.bottomRight().latitude()); -} - -QGeoCodingManagerEngineQGC::QGeoCodingManagerEngineQGC( - const QVariantMap ¶meters, - QGeoServiceProvider::Error *error, - QString *errorString) - : QGeoCodingManagerEngine(parameters), m_networkManager(new QNetworkAccessManager(this)) -{ - if (parameters.contains(QStringLiteral("useragent"))) - m_userAgent = parameters.value(QStringLiteral("useragent")).toString().toLatin1(); - else - m_userAgent = "Qt Location based application"; - *error = QGeoServiceProvider::NoError; - errorString->clear(); -} - -QGeoCodingManagerEngineQGC::~QGeoCodingManagerEngineQGC() -{ -} - -QGeoCodeReply *QGeoCodingManagerEngineQGC::geocode(const QGeoAddress &address, const QGeoShape &bounds) -{ - return geocode(addressToQuery(address), -1, -1, bounds); -} - -QGeoCodeReply *QGeoCodingManagerEngineQGC::geocode(const QString &address, int limit, int offset, const QGeoShape &bounds) -{ - Q_UNUSED(limit); - Q_UNUSED(offset); - - QNetworkRequest request; - request.setRawHeader("User-Agent", m_userAgent); - - QUrl url(QStringLiteral("http://maps.googleapis.com/maps/api/geocode/json")); - QUrlQuery query; - query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("false")); - query.addQueryItem(QStringLiteral("language"), locale().name().left(2)); - query.addQueryItem(QStringLiteral("address"), address); - if (bounds.type() == QGeoShape::RectangleType) { - query.addQueryItem(QStringLiteral("bounds"), boundingBoxToLtrb(bounds)); - } - - url.setQuery(query); - request.setUrl(url); - //qDebug() << url; - - QNetworkReply *reply = m_networkManager->get(request); - reply->setParent(0); - - QGeoCodeReplyQGC *geocodeReply = new QGeoCodeReplyQGC(reply); - - connect(geocodeReply, &QGeoCodeReply::finished, this, &QGeoCodingManagerEngineQGC::replyFinished); - connect(geocodeReply, SIGNAL(error(QGeoCodeReply::Error,QString)), - this, SLOT(replyError(QGeoCodeReply::Error,QString))); - - return geocodeReply; -} - -QGeoCodeReply *QGeoCodingManagerEngineQGC::reverseGeocode(const QGeoCoordinate &coordinate, const QGeoShape &bounds) -{ - Q_UNUSED(bounds) - - QNetworkRequest request; - request.setRawHeader("User-Agent", m_userAgent); - - QUrl url(QStringLiteral("http://maps.googleapis.com/maps/api/geocode/json")); - QUrlQuery query; - query.addQueryItem(QStringLiteral("sensor"), QStringLiteral("false")); - query.addQueryItem(QStringLiteral("language"), locale().name().left(2)); - query.addQueryItem(QStringLiteral("latlng"), QStringLiteral("%1,%2") - .arg(coordinate.latitude()) - .arg(coordinate.longitude())); - - url.setQuery(query); - request.setUrl(url); - //qDebug() << url; - - QNetworkReply *reply = m_networkManager->get(request); - reply->setParent(0); - - QGeoCodeReplyQGC *geocodeReply = new QGeoCodeReplyQGC(reply); - - connect(geocodeReply, &QGeoCodeReply::finished, this, &QGeoCodingManagerEngineQGC::replyFinished); - connect(geocodeReply, SIGNAL(error(QGeoCodeReply::Error,QString)), - this, SLOT(replyError(QGeoCodeReply::Error,QString))); - - return geocodeReply; -} - -void QGeoCodingManagerEngineQGC::replyFinished() -{ - QGeoCodeReply *reply = qobject_cast(sender()); - if (reply) - emit finished(reply); -} - -void QGeoCodingManagerEngineQGC::replyError(QGeoCodeReply::Error errorCode, const QString &errorString) -{ - QGeoCodeReply *reply = qobject_cast(sender()); - if (reply) - emit errorOccurred(reply, errorCode, errorString); -} diff --git a/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.h b/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.h deleted file mode 100644 index 3cbebebfee1..00000000000 --- a/src/QtLocationPlugin/QGeoCodingManagerEngineQGC.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - -#pragma once - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QNetworkAccessManager; - -class QGeoCodingManagerEngineQGC : public QGeoCodingManagerEngine -{ - Q_OBJECT - -public: - QGeoCodingManagerEngineQGC(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString); - ~QGeoCodingManagerEngineQGC(); - - QGeoCodeReply* geocode (const QGeoAddress &address, const QGeoShape &bounds) Q_DECL_OVERRIDE; - QGeoCodeReply* geocode (const QString &address, int limit, int offset, const QGeoShape &bounds) Q_DECL_OVERRIDE; - QGeoCodeReply* reverseGeocode (const QGeoCoordinate &coordinate, const QGeoShape &bounds) Q_DECL_OVERRIDE; - -private Q_SLOTS: - void replyFinished (); - void replyError (QGeoCodeReply::Error errorCode, const QString &errorString); - -private: - QNetworkAccessManager *m_networkManager; - QByteArray m_userAgent; -}; - -QT_END_NAMESPACE diff --git a/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.cpp b/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.cpp index 2648710de3f..c75a8261d54 100644 --- a/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.cpp +++ b/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.cpp @@ -1,96 +1,82 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - #include "QGeoServiceProviderPluginQGC.h" #include "QGeoTiledMappingManagerEngineQGC.h" -#include "QGeoCodingManagerEngineQGC.h" +#include -#include +QGC_LOGGING_CATEGORY(QGeoServiceProviderFactoryQGCLog, "qgc.qtlocationplugin.qgeoserviceproviderfactoryqgc") #ifndef CMAKE_LOCATION_PLUGIN extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QPluginMetaData) qt_plugin_query_metadata_v2(); extern "C" Q_DECL_EXPORT QT_PREPEND_NAMESPACE(QObject) *qt_plugin_instance(); -//----------------------------------------------------------------------------- const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_QGeoServiceProviderFactoryQGC() { - QT_PREPEND_NAMESPACE(QStaticPlugin) plugin = { qt_plugin_instance, qt_plugin_query_metadata_v2}; - return plugin; + QT_PREPEND_NAMESPACE(QStaticPlugin) plugin = { qt_plugin_instance, qt_plugin_query_metadata_v2}; + return plugin; } #endif -//----------------------------------------------------------------------------- -QGeoCodingManagerEngine* -QGeoServiceProviderFactoryQGC::createGeocodingManagerEngine( - const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const + +QGeoServiceProviderFactoryQGC::QGeoServiceProviderFactoryQGC() +{ + qCDebug(QGeoServiceProviderFactoryQGCLog) << Q_FUNC_INFO << this; +} + +QGeoServiceProviderFactoryQGC::~QGeoServiceProviderFactoryQGC() +{ + qCDebug(QGeoServiceProviderFactoryQGCLog) << Q_FUNC_INFO << this; +} + +QGeoCodingManagerEngine* QGeoServiceProviderFactoryQGC::createGeocodingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const { - return new QGeoCodingManagerEngineQGC(parameters, error, errorString); + Q_UNUSED(parameters); + if (error) { + *error = QGeoServiceProvider::NotSupportedError; + } + if (errorString) { + *errorString = "Geocoding Not Supported"; + } + return nullptr; } -//----------------------------------------------------------------------------- -QGeoMappingManagerEngine* -QGeoServiceProviderFactoryQGC::createMappingManagerEngine( - const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const +QGeoMappingManagerEngine* QGeoServiceProviderFactoryQGC::createMappingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const { + if (error) { + *error = QGeoServiceProvider::NoError; + } + if (errorString) { + *errorString = ""; + } return new QGeoTiledMappingManagerEngineQGC(parameters, error, errorString); } -//----------------------------------------------------------------------------- -QGeoRoutingManagerEngine* -QGeoServiceProviderFactoryQGC::createRoutingManagerEngine( - const QVariantMap &, QGeoServiceProvider::Error *, QString *) const +QGeoRoutingManagerEngine* QGeoServiceProviderFactoryQGC::createRoutingManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const { - // Not implemented for QGC + Q_UNUSED(parameters); + if (error) { + *error = QGeoServiceProvider::NotSupportedError; + } + if (errorString) { + *errorString = "Routing Not Supported"; + } return nullptr; } -//----------------------------------------------------------------------------- -QPlaceManagerEngine* -QGeoServiceProviderFactoryQGC::createPlaceManagerEngine( - const QVariantMap &, QGeoServiceProvider::Error *, QString *) const +QPlaceManagerEngine* QGeoServiceProviderFactoryQGC::createPlaceManagerEngine( + const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const { - // Not implemented for QGC + Q_UNUSED(parameters); + if (error) { + *error = QGeoServiceProvider::NotSupportedError; + } + if (errorString) { + *errorString = "Place Not Supported"; + } return nullptr; } + +void QGeoServiceProviderFactoryQGC::setQmlEngine(QQmlEngine *engine) +{ + m_engine = engine; +} diff --git a/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.h b/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.h index 2e86e8d66f7..18ab5410130 100644 --- a/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.h +++ b/src/QtLocationPlugin/QGeoServiceProviderPluginQGC.h @@ -1,55 +1,12 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Aaron McCarthy -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtLocation module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -** 2015.4.4 -** Adapted for use with QGroundControl -** -** Gus Grubba -** -****************************************************************************/ - #pragma once #include #include +#include #include +Q_DECLARE_LOGGING_CATEGORY(QGeoServiceProviderFactoryQGCLog) + class QGeoServiceProviderFactoryQGC: public QObject, public QGeoServiceProviderFactory { Q_OBJECT @@ -57,8 +14,16 @@ class QGeoServiceProviderFactoryQGC: public QObject, public QGeoServiceProviderF Q_PLUGIN_METADATA(IID "org.qt-project.qt.geoservice.serviceproviderfactory/6.0" FILE "qgc_maps_plugin.json") public: - QGeoCodingManagerEngine* createGeocodingManagerEngine (const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const override; - QGeoMappingManagerEngine* createMappingManagerEngine (const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const override; - QGeoRoutingManagerEngine* createRoutingManagerEngine (const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const override; - QPlaceManagerEngine* createPlaceManagerEngine (const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const override; + QGeoServiceProviderFactoryQGC(); + ~QGeoServiceProviderFactoryQGC(); + + QGeoCodingManagerEngine* createGeocodingManagerEngine(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const final; + QGeoMappingManagerEngine* createMappingManagerEngine(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const final; + QGeoRoutingManagerEngine* createRoutingManagerEngine(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const final; + QPlaceManagerEngine* createPlaceManagerEngine(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString) const final; + + void setQmlEngine(QQmlEngine* engine) final; + +private: + QQmlEngine* m_engine = nullptr; }; diff --git a/src/QtLocationPlugin/qgc_maps_plugin.json b/src/QtLocationPlugin/qgc_maps_plugin.json index dd52d9feede..b76be9c71c7 100644 --- a/src/QtLocationPlugin/qgc_maps_plugin.json +++ b/src/QtLocationPlugin/qgc_maps_plugin.json @@ -5,7 +5,6 @@ "Experimental": false, "Features": [ "OnlineMappingFeature", - "OnlineGeocodingFeature", - "ReverseGeocodingFeature" + "OfflineMappingFeature" ] } From 955efaf88309c561c8e74bbd051571611794e809 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Tue, 4 Jun 2024 14:00:14 +0000 Subject: [PATCH 25/38] Update PX4 Firmware metadata Tue Jun 4 14:00:14 UTC 2024 --- .../PX4/PX4ParameterFactMetaData.xml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index f77bd45bc6e..8f7b6d1cbbd 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -10172,6 +10172,43 @@ + + Accel filter settings + true + + 13 Hz + 30 Hz + 68 Hz + 235 Hz + 280 Hz + 370 Hz + No filter + + + + Gyro and Accel decimation settings + true + + None + 5900 Hz + 2950 Hz + 1475 Hz + 738 Hz + + + + Gyro filter settings + true + + 13 Hz + 30 Hz + 68 Hz + 235 Hz + 280 Hz + 370 Hz + No filter + + Lightware SF1xx/SF20/LW20 Operation Mode 0 From 7ffedb89faf2871b86d75b87d23578c7e4f6bcf9 Mon Sep 17 00:00:00 2001 From: Holden <68555040+HTRamsey@users.noreply.github.com> Date: Tue, 4 Jun 2024 17:30:52 -0700 Subject: [PATCH 26/38] QtLocationPlugin: Make MapProvider Functions Const (#11583) --- src/QtLocationPlugin/BingMapProvider.cpp | 29 +-- src/QtLocationPlugin/BingMapProvider.h | 60 +++-- src/QtLocationPlugin/ElevationMapProvider.cpp | 54 +++-- src/QtLocationPlugin/ElevationMapProvider.h | 40 ++-- src/QtLocationPlugin/EsriMapProvider.cpp | 31 +-- src/QtLocationPlugin/EsriMapProvider.h | 45 ++-- src/QtLocationPlugin/GenericMapProvider.cpp | 141 +++-------- src/QtLocationPlugin/GenericMapProvider.h | 225 +++++++++++------- src/QtLocationPlugin/GoogleMapProvider.cpp | 221 +---------------- src/QtLocationPlugin/GoogleMapProvider.h | 137 ++++------- src/QtLocationPlugin/MapProvider.cpp | 105 ++++---- src/QtLocationPlugin/MapProvider.h | 78 +++--- src/QtLocationPlugin/MapboxMapProvider.cpp | 16 +- src/QtLocationPlugin/MapboxMapProvider.h | 46 ++-- src/QtLocationPlugin/QGCMapTileSet.cpp | 2 +- src/QtLocationPlugin/QGCMapUrlEngine.cpp | 12 +- src/QtLocationPlugin/QGCMapUrlEngine.h | 4 +- src/QtLocationPlugin/QGeoMapReplyQGC.cpp | 2 +- src/QtLocationPlugin/QGeoTileFetcherQGC.cpp | 2 +- src/Terrain/TerrainTileManager.cc | 3 +- src/Viewer3D/Viewer3DTileReply.cc | 4 +- 21 files changed, 504 insertions(+), 753 deletions(-) diff --git a/src/QtLocationPlugin/BingMapProvider.cpp b/src/QtLocationPlugin/BingMapProvider.cpp index 0cdd4e95bda..7ef025aa75c 100644 --- a/src/QtLocationPlugin/BingMapProvider.cpp +++ b/src/QtLocationPlugin/BingMapProvider.cpp @@ -9,31 +9,8 @@ #include "BingMapProvider.h" -BingMapProvider::BingMapProvider(const QString &imageFormat, const quint32 averageSize, - const QGeoMapType::MapStyle mapType, QObject* parent) - : MapProvider(QStringLiteral("https://www.bing.com/maps/"), imageFormat, averageSize, mapType, parent) {} - -static const QString RoadMapUrl = QStringLiteral("http://ecn.t%1.tiles.virtualearth.net/tiles/r%2.png?g=%3&mkt=%4"); - -QString BingRoadMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - const QString key = _tileXYToQuadKey(x, y, zoom); - return RoadMapUrl.arg(QString::number(_getServerNum(x, y, 4)), key, _versionBingMaps, _language); -} - -static const QString SatteliteMapUrl = QStringLiteral("http://ecn.t%1.tiles.virtualearth.net/tiles/a%2.jpeg?g=%3&mkt=%4"); - -QString BingSatelliteMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) +QString BingMapProvider::_getURL(int x, int y, int zoom) const +{ const QString key = _tileXYToQuadKey(x, y, zoom); - return SatteliteMapUrl.arg(QString::number(_getServerNum(x, y, 4)) ,key ,_versionBingMaps ,_language); + return _mapUrl.arg(_getServerNum(x, y, 4)).arg(_mapName, key, _imageFormat, _versionBingMaps, _language); } - -static const QString HybridMapUrl = QStringLiteral("http://ecn.t%1.tiles.virtualearth.net/tiles/h%2.jpeg?g=%3&mkt=%4"); - -QString BingHybridMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - const QString key = _tileXYToQuadKey(x, y, zoom); - return HybridMapUrl.arg(QString::number(_getServerNum(x, y, 4)), key, _versionBingMaps, _language); -} - diff --git a/src/QtLocationPlugin/BingMapProvider.h b/src/QtLocationPlugin/BingMapProvider.h index 5ae9ac72cc3..23f0bd0fea0 100644 --- a/src/QtLocationPlugin/BingMapProvider.h +++ b/src/QtLocationPlugin/BingMapProvider.h @@ -11,59 +11,53 @@ #include "MapProvider.h" -class BingMapProvider : public MapProvider { - Q_OBJECT +static constexpr const quint32 AVERAGE_BING_STREET_MAP = 1297; +static constexpr const quint32 AVERAGE_BING_SAT_MAP = 19597; -public: - BingMapProvider(const QString &imageFormat, const quint32 averageSize, - const QGeoMapType::MapStyle mapType, QObject* parent = nullptr); +class BingMapProvider : public MapProvider +{ + Q_OBJECT - ~BingMapProvider() = default; +protected: + BingMapProvider(const QString &mapName, const QString &imageFormat, quint32 averageSize, + QGeoMapType::MapStyle mapType, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://www.bing.com/maps/"), imageFormat, averageSize, mapType, parent) + , _mapName(mapName) {} - bool _isBingProvider() const override { return true; } +public: + bool isBingProvider() const final { return true; } +private: + QString _getURL(int x, int y, int zoom) const final; -protected: - const QString _versionBingMaps = QStringLiteral("563"); + const QString _mapName; + const QString _mapUrl = QStringLiteral("http://ecn.t%1.tiles.virtualearth.net/tiles/%2%3.%4?g=%5&mkt=%6"); + const QString _versionBingMaps = QStringLiteral("2981"); }; -static const quint32 AVERAGE_BING_STREET_MAP = 1297; -static const quint32 AVERAGE_BING_SAT_MAP = 19597; - -// ----------------------------------------------------------- -// Bing Road Map - -class BingRoadMapProvider : public BingMapProvider { +class BingRoadMapProvider : public BingMapProvider +{ Q_OBJECT public: BingRoadMapProvider(QObject* parent = nullptr) - : BingMapProvider(QStringLiteral("png"), AVERAGE_BING_STREET_MAP, QGeoMapType::StreetMap, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : BingMapProvider(QStringLiteral("r"), QStringLiteral("png"), AVERAGE_BING_STREET_MAP, QGeoMapType::StreetMap, parent) {} }; -// ----------------------------------------------------------- -// Bing Satellite Map - -class BingSatelliteMapProvider : public BingMapProvider { +class BingSatelliteMapProvider : public BingMapProvider +{ Q_OBJECT public: BingSatelliteMapProvider(QObject* parent = nullptr) - : BingMapProvider(QStringLiteral("jpg"), AVERAGE_BING_SAT_MAP, QGeoMapType::SatelliteMapDay, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : BingMapProvider(QStringLiteral("a"), QStringLiteral("jpg"), AVERAGE_BING_SAT_MAP, QGeoMapType::SatelliteMapDay, parent) {} }; -// ----------------------------------------------------------- -// Bing Hybrid Map - -class BingHybridMapProvider : public BingMapProvider { +class BingHybridMapProvider : public BingMapProvider +{ Q_OBJECT + public: BingHybridMapProvider(QObject* parent = nullptr) - : BingMapProvider(QStringLiteral("jpg"),AVERAGE_BING_SAT_MAP, QGeoMapType::HybridMap, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : BingMapProvider(QStringLiteral("h"), QStringLiteral("jpg"),AVERAGE_BING_SAT_MAP, QGeoMapType::HybridMap, parent) {} }; diff --git a/src/QtLocationPlugin/ElevationMapProvider.cpp b/src/QtLocationPlugin/ElevationMapProvider.cpp index bb9693ecd04..9fae779d4db 100644 --- a/src/QtLocationPlugin/ElevationMapProvider.cpp +++ b/src/QtLocationPlugin/ElevationMapProvider.cpp @@ -1,42 +1,46 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + * License for the COPERNICUS dataset hosted on https://terrain-ce.suite.auterion.com/: + * + * © DLR e.V. 2010-2014 and © Airbus Defence and Space GmbH 2014-2018 provided under + * COPERNICUS by the European Union and ESA; all rights reserved. + * + ****************************************************************************/ + #include "ElevationMapProvider.h" #include "TerrainTile.h" -/* -License for the COPERNICUS dataset hosted on https://terrain-ce.suite.auterion.com/: - -© DLR e.V. 2010-2014 and © Airbus Defence and Space GmbH 2014-2018 provided under COPERNICUS -by the European Union and ESA; all rights reserved. - -*/ - -ElevationProvider::ElevationProvider(const QString& imageFormat, quint32 averageSize, QGeoMapType::MapStyle mapType, QObject* parent) - : MapProvider(QStringLiteral("https://terrain-ce.suite.auterion.com/"), imageFormat, averageSize, mapType, parent) {} - -//----------------------------------------------------------------------------- -int CopernicusElevationProvider::long2tileX(const double lon, const int z) const { +int CopernicusElevationProvider::long2tileX(double lon, int z) const +{ Q_UNUSED(z) return static_cast(floor((lon + 180.0) / TerrainTile::tileSizeDegrees)); } -//----------------------------------------------------------------------------- -int CopernicusElevationProvider::lat2tileY(const double lat, const int z) const { +int CopernicusElevationProvider::lat2tileY(double lat, int z) const +{ Q_UNUSED(z) return static_cast(floor((lat + 90.0) / TerrainTile::tileSizeDegrees)); } -QString CopernicusElevationProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) +QString CopernicusElevationProvider::_getURL(int x, int y, int zoom) const +{ Q_UNUSED(zoom) - return QString("https://terrain-ce.suite.auterion.com/api/v1/carpet?points=%1,%2,%3,%4") - .arg(static_cast(y) * TerrainTile::tileSizeDegrees - 90.0) - .arg(static_cast(x) * TerrainTile::tileSizeDegrees - 180.0) - .arg(static_cast(y + 1) * TerrainTile::tileSizeDegrees - 90.0) - .arg(static_cast(x + 1) * TerrainTile::tileSizeDegrees - 180.0); + return QStringLiteral("https://terrain-ce.suite.auterion.com/api/v1/carpet?points=%1,%2,%3,%4") + .arg((static_cast(y) * TerrainTile::tileSizeDegrees) - 90.0) + .arg((static_cast(x) * TerrainTile::tileSizeDegrees) - 180.0) + .arg((static_cast(y + 1) * TerrainTile::tileSizeDegrees) - 90.0) + .arg((static_cast(x + 1) * TerrainTile::tileSizeDegrees) - 180.0); } -QGCTileSet CopernicusElevationProvider::getTileCount(const int zoom, const double topleftLon, - const double topleftLat, const double bottomRightLon, - const double bottomRightLat) const { +QGCTileSet CopernicusElevationProvider::getTileCount(int zoom, double topleftLon, + double topleftLat, double bottomRightLon, + double bottomRightLat) const +{ QGCTileSet set; set.tileX0 = long2tileX(topleftLon, zoom); set.tileY0 = lat2tileY(bottomRightLat, zoom); diff --git a/src/QtLocationPlugin/ElevationMapProvider.h b/src/QtLocationPlugin/ElevationMapProvider.h index 51a28ed628a..2196123f0a1 100644 --- a/src/QtLocationPlugin/ElevationMapProvider.h +++ b/src/QtLocationPlugin/ElevationMapProvider.h @@ -2,37 +2,37 @@ #include "MapProvider.h" -#include +static constexpr const quint32 AVERAGE_AIRMAP_ELEV_SIZE = 2786; -static const quint32 AVERAGE_AIRMAP_ELEV_SIZE = 2786; - -class ElevationProvider : public MapProvider { +class ElevationProvider : public MapProvider +{ Q_OBJECT - public: + +protected: ElevationProvider(const QString& imageFormat, quint32 averageSize, - QGeoMapType::MapStyle mapType, QObject* parent = nullptr); + QGeoMapType::MapStyle mapType, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://terrain-ce.suite.auterion.com/"), imageFormat, averageSize, mapType, parent) {} - virtual bool _isElevationProvider() const override { return true; } +public: + bool isElevationProvider() const final { return true; } }; -// ----------------------------------------------------------- -// Airmap Elevation - -class CopernicusElevationProvider : public ElevationProvider { +class CopernicusElevationProvider : public ElevationProvider +{ Q_OBJECT - public: + +public: CopernicusElevationProvider(QObject* parent = nullptr) : ElevationProvider(QStringLiteral("bin"), AVERAGE_AIRMAP_ELEV_SIZE, QGeoMapType::StreetMap, parent) {} - int long2tileX(const double lon, const int z) const override; - - int lat2tileY(const double lat, const int z) const override; + int long2tileX(double lon, int z) const final; + int lat2tileY(double lat, int z) const final; - QGCTileSet getTileCount(const int zoom, const double topleftLon, - const double topleftLat, const double bottomRightLon, - const double bottomRightLat) const override; + QGCTileSet getTileCount(int zoom, double topleftLon, + double topleftLat, double bottomRightLon, + double bottomRightLat) const final; - protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +private: + QString _getURL(int x, int y, int zoom) const final; }; diff --git a/src/QtLocationPlugin/EsriMapProvider.cpp b/src/QtLocationPlugin/EsriMapProvider.cpp index 71a439ad4c1..132776ee203 100644 --- a/src/QtLocationPlugin/EsriMapProvider.cpp +++ b/src/QtLocationPlugin/EsriMapProvider.cpp @@ -13,13 +13,10 @@ #include -EsriMapProvider::EsriMapProvider(const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject *parent) - : MapProvider(QString(), QString(), averageSize, mapType, parent) {} - -QNetworkRequest EsriMapProvider::getTileURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - //-- Build URL +QNetworkRequest EsriMapProvider::getTileURL(int x, int y, int zoom) const +{ QNetworkRequest request; - const QString url = _getURL(x, y, zoom, networkManager); + const QString url = _getURL(x, y, zoom); if (url.isEmpty()) { return request; } @@ -31,23 +28,7 @@ QNetworkRequest EsriMapProvider::getTileURL(const int x, const int y, const int return request; } -static const QString WorldStreetMapUrl = QStringLiteral("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/%1/%2/%3"); - -QString EsriWorldStreetMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return WorldStreetMapUrl.arg(zoom).arg(y).arg(x); -} - -static const QString WorldSatelliteMapUrl = QStringLiteral("http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/%1/%2/%3"); - -QString EsriWorldSatelliteMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return WorldSatelliteMapUrl.arg(zoom).arg(y).arg(x); -} - -static const QString TerrainMapUrl = QStringLiteral("http://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/%1/%2/%3"); - -QString EsriTerrainMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return TerrainMapUrl.arg(zoom).arg(y).arg(x); +QString EsriMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(_mapName).arg(zoom).arg(y).arg(x); } diff --git a/src/QtLocationPlugin/EsriMapProvider.h b/src/QtLocationPlugin/EsriMapProvider.h index edf0ab4f81b..4de3971eaa8 100644 --- a/src/QtLocationPlugin/EsriMapProvider.h +++ b/src/QtLocationPlugin/EsriMapProvider.h @@ -11,41 +11,48 @@ #include "MapProvider.h" -class EsriMapProvider : public MapProvider { +class EsriMapProvider : public MapProvider +{ Q_OBJECT - public: - EsriMapProvider(const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject* parent = nullptr); +protected: + EsriMapProvider(const QString &mapName, quint32 averageSize, QGeoMapType::MapStyle mapType, QObject* parent = nullptr) + : MapProvider(QString(), QString(), averageSize, mapType, parent) + , _mapName(mapName) {} - QNetworkRequest getTileURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + QNetworkRequest getTileURL(int x, int y, int zoom) const final; + +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapName; + const QString _mapUrl = QStringLiteral("http://services.arcgisonline.com/ArcGIS/rest/services/%1/MapServer/tile/%2/%3/%4"); }; -class EsriWorldStreetMapProvider : public EsriMapProvider { +class EsriWorldStreetMapProvider : public EsriMapProvider +{ Q_OBJECT - public: +public: EsriWorldStreetMapProvider(QObject* parent = nullptr) - : EsriMapProvider(AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : EsriMapProvider(QStringLiteral("World_Street_Map"), AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} }; -class EsriWorldSatelliteMapProvider : public EsriMapProvider { +class EsriWorldSatelliteMapProvider : public EsriMapProvider +{ Q_OBJECT - public: +public: EsriWorldSatelliteMapProvider(QObject* parent = nullptr) - : EsriMapProvider(AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : EsriMapProvider(QStringLiteral("World_Imagery"), AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} }; -class EsriTerrainMapProvider : public EsriMapProvider { +class EsriTerrainMapProvider : public EsriMapProvider +{ Q_OBJECT - public: +public: EsriTerrainMapProvider(QObject* parent = nullptr) - : EsriMapProvider(AVERAGE_TILE_SIZE, QGeoMapType::TerrainMap, parent) {} - - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : EsriMapProvider(QStringLiteral("World_Terrain_Base"), AVERAGE_TILE_SIZE, QGeoMapType::TerrainMap, parent) {} }; diff --git a/src/QtLocationPlugin/GenericMapProvider.cpp b/src/QtLocationPlugin/GenericMapProvider.cpp index e7a03d19170..30d02124cad 100644 --- a/src/QtLocationPlugin/GenericMapProvider.cpp +++ b/src/QtLocationPlugin/GenericMapProvider.cpp @@ -11,128 +11,61 @@ #include "QGCApplication.h" #include "SettingsManager.h" -static const QString JapanStdMapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/std/%1/%2/%3.png"); - -QString JapanStdMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return JapanStdMapUrl.arg(zoom).arg(x).arg(y); -} - -static const QString JapanSeamlessMapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/%1/%2/%3.jpg"); - -QString JapanSeamlessMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return JapanSeamlessMapUrl.arg(zoom).arg(x).arg(y); -} - -static const QString JapanAnaglyphMapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/anaglyphmap_color/%1/%2/%3.png"); - -QString JapanAnaglyphMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return JapanAnaglyphMapUrl.arg(zoom).arg(x).arg(y); -} - -static const QString JapanSlopeMapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/slopemap/%1/%2/%3.png"); - -QString JapanSlopeMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return JapanSlopeMapUrl.arg(zoom).arg(x).arg(y); -} - -static const QString JapanReliefMapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/relief/%1/%2/%3.png"); - -QString JapanReliefMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return JapanReliefMapUrl.arg(zoom).arg(x).arg(y); -} - -static const QString LINZBasemapMapUrl = QStringLiteral("https://basemaps.linz.govt.nz/v1/tiles/aerial/EPSG:3857/%1/%2/%3.png?api=d01ev80nqcjxddfvc6amyvkk1ka"); - -QString LINZBasemapMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return LINZBasemapMapUrl.arg(zoom).arg(x).arg(y); -} - -QString CustomURLMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) +QString CustomURLMapProvider::_getURL(int x, int y, int zoom) const +{ QString url = qgcApp()->toolbox()->settingsManager()->appSettings()->customURL()->rawValue().toString(); - return url.replace("{x}",QString::number(x)).replace("{y}",QString::number(y)).replace(QRegularExpression("\\{(z|zoom)\\}"),QString::number(zoom)); + (void) url.replace("{x}", QString::number(x)); + (void) url.replace("{y}", QString::number(y)); + static const QRegularExpression zoomRegExp("\\{(z|zoom)\\}"); + (void) url.replace(zoomRegExp, QString::number(zoom)); + return url; } -static const QString StatkartMapUrl = QStringLiteral("http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=topo4&zoom=%1&x=%2&y=%3"); - -QString StatkartMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return StatkartMapUrl.arg(zoom).arg(x).arg(y); +QString CyberJapanMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(_mapName).arg(zoom).arg(x).arg(y).arg(_imageFormat); } -static const QString StatkartBaseMapUrl = QStringLiteral("http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=norgeskart_bakgrunn&zoom=%1&x=%2&y=%3"); - -QString StatkartBaseMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return StatkartBaseMapUrl.arg(zoom).arg(x).arg(y); +QString LINZBasemapMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(zoom).arg(x).arg(y).arg(_imageFormat); } - -static const QString EniroMapUrl = QStringLiteral("http://map.eniro.com/geowebcache/service/tms1.0.0/map/%1/%2/%3.png"); - -QString EniroMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return EniroMapUrl.arg(zoom).arg(x).arg((1 << zoom) - 1 - y); +QString StatkartMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(_mapName).arg(zoom).arg(x).arg(y); } -static const QString MapQuestMapUrl = QStringLiteral("http://otile%1.mqcdn.com/tiles/1.0.0/map/%2/%3/%4.jpg"); - -QString MapQuestMapMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return MapQuestMapUrl.arg(_getServerNum(x, y, 4)).arg(zoom).arg(x).arg(y); +QString EniroMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(zoom).arg(x).arg((1 << zoom) - 1 - y).arg(_imageFormat); } -static const QString MapQuestSatUrl = QStringLiteral("http://otile%1.mqcdn.com/tiles/1.0.0/sat/%2/%3/%4.jpg"); - -QString MapQuestSatMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - return MapQuestSatUrl.arg(_getServerNum(x, y, 4)).arg(zoom).arg(x).arg(y); +QString MapQuestMapProvider::_getURL(int x, int y, int zoom) const +{ + return _mapUrl.arg(_getServerNum(x, y, 4)).arg(_mapName).arg(zoom).arg(x).arg(y).arg(_imageFormat); } -QString VWorldStreetMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - const int gap = zoom - 6; - const int x_min = int(53 * pow(2, gap)); - const int x_max = int(55 * pow(2, gap) + (2 * gap - 1)); - const int y_min = int(22 * pow(2, gap)); - const int y_max = int(26 * pow(2, gap) + (2 * gap - 1)); - - const QString VWorldMapToken = qgcApp()->toolbox()->settingsManager()->appSettings()->vworldToken()->rawValue().toString(); - - if (zoom > 19) { +QString VWorldMapProvider::_getURL(int x, int y, int zoom) const +{ + if ((zoom < 5) || (zoom > 19)) { return QString(); - } else if (zoom > 5 && x >= x_min && x <= x_max && y >= y_min && y <= y_max) { - return QString("http://api.vworld.kr/req/wmts/1.0.0/%1/Base/%2/%3/%4.png").arg(VWorldMapToken).arg(zoom).arg(y).arg(x); - } else { - const QString key = _tileXYToQuadKey(x, y, zoom); - return QString(QStringLiteral("http://ecn.t%1.tiles.virtualearth.net/tiles/r%2.png?g=%3&mkt=%4")) - .arg(_getServerNum(x, y, 4)).arg(key, _versionBingMaps, _language); } -} -QString VWorldSatMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) - const int gap = zoom - 6; - const int x_min = int(53 * pow(2, gap)); - const int x_max = int(55 * pow(2, gap) + (2 * gap - 1)); - const int y_min = int(22 * pow(2, gap)); - const int y_max = int(26 * pow(2, gap) + (2 * gap - 1)); + const int gap = zoom - 6; - const QString VWorldMapToken = qgcApp()->toolbox()->settingsManager()->appSettings()->vworldToken()->rawValue().toString(); + const int x_min = 53 * pow(2, gap); + const int x_max = (55 * pow(2, gap)) + (2 * gap - 1); + if ((x < x_min) || (x > x_max)) { + return QString(); + } - if (zoom > 19) { + const int y_min = 22 * pow(2, gap); + const int y_max = (26 * pow(2, gap)) + (2 * gap - 1); + if ((y < y_min) || (y > y_max)) { return QString(); - } else if (zoom > 5 && x >= x_min && x <= x_max && y >= y_min && y <= y_max) { - return QString("http://api.vworld.kr/req/wmts/1.0.0/%1/Satellite/%2/%3/%4.jpeg").arg(VWorldMapToken).arg(zoom).arg(y).arg(x); - } else { - const QString key = _tileXYToQuadKey(x, y, zoom); - return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/a%2.jpeg?g=%3&mkt=%4") - .arg(_getServerNum(x, y, 4)).arg(key, _versionBingMaps, _language); } + + const QString VWorldMapToken = qgcApp()->toolbox()->settingsManager()->appSettings()->vworldToken()->rawValue().toString(); + return _mapUrl.arg(VWorldMapToken, _mapName).arg(zoom).arg(y).arg(x).arg(_imageFormat); } diff --git a/src/QtLocationPlugin/GenericMapProvider.h b/src/QtLocationPlugin/GenericMapProvider.h index 2dfbe1d7f2a..55cc7d77947 100644 --- a/src/QtLocationPlugin/GenericMapProvider.h +++ b/src/QtLocationPlugin/GenericMapProvider.h @@ -10,148 +10,211 @@ #include "MapProvider.h" -class JapanStdMapProvider : public MapProvider { +class CustomURLMapProvider : public MapProvider +{ Q_OBJECT - public: - JapanStdMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/std"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + CustomURLMapProvider(QObject* parent = nullptr) + : MapProvider(QStringLiteral(""), QStringLiteral(""), + AVERAGE_TILE_SIZE, QGeoMapType::CustomMap, parent) {} + +private: + QString _getURL(int x, int y, int zoom) const final; }; -class JapanSeamlessMapProvider : public MapProvider { +class CyberJapanMapProvider : public MapProvider +{ Q_OBJECT - public: - JapanSeamlessMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto"), QStringLiteral("jpg"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +protected: + CyberJapanMapProvider(const QString &mapName, const QString& imageFormat, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/std"), imageFormat, + AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) + , _mapName(mapName) {} + +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapName; + const QString _mapUrl = QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/%1/%2/%3/%4.%5"); }; -class JapanAnaglyphMapProvider : public MapProvider { +class JapanStdMapProvider : public CyberJapanMapProvider +{ Q_OBJECT - public: - JapanAnaglyphMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/anaglyphmap_color"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + JapanStdMapProvider(QObject* parent = nullptr) + : CyberJapanMapProvider(QStringLiteral("std"), QStringLiteral("png"), parent) {} }; -class JapanSlopeMapProvider : public MapProvider { +class JapanSeamlessMapProvider : public CyberJapanMapProvider +{ Q_OBJECT - public: - JapanSlopeMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/slopemap"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + JapanSeamlessMapProvider(QObject* parent = nullptr) + : CyberJapanMapProvider(QStringLiteral("seamlessphoto"), QStringLiteral("jpg"), parent) {} }; -class JapanReliefMapProvider : public MapProvider { +class JapanAnaglyphMapProvider : public CyberJapanMapProvider +{ Q_OBJECT - public: - JapanReliefMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://cyberjapandata.gsi.go.jp/xyz/relief"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + JapanAnaglyphMapProvider(QObject* parent = nullptr) + : CyberJapanMapProvider(QStringLiteral("anaglyphmap_color"), QStringLiteral("png"), parent) {} }; -class LINZBasemapMapProvider : public MapProvider { +class JapanSlopeMapProvider : public CyberJapanMapProvider +{ Q_OBJECT - public: + +public: + JapanSlopeMapProvider(QObject* parent = nullptr) + : CyberJapanMapProvider(QStringLiteral("slopemap"), QStringLiteral("png"), parent) {} +}; + +class JapanReliefMapProvider : public CyberJapanMapProvider +{ + Q_OBJECT + +public: + JapanReliefMapProvider(QObject* parent = nullptr) + : CyberJapanMapProvider(QStringLiteral("relief"), QStringLiteral("png"), parent) {} +}; + +class LINZBasemapMapProvider : public MapProvider +{ + Q_OBJECT + +public: LINZBasemapMapProvider(QObject* parent = nullptr) : MapProvider(QStringLiteral("https://basemaps.linz.govt.nz/v1/tiles/aerial"), QStringLiteral("png"), AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapUrl = QStringLiteral("https://basemaps.linz.govt.nz/v1/tiles/aerial/EPSG:3857/%1/%2/%3.%4?api=d01ev80nqcjxddfvc6amyvkk1ka"); }; -class CustomURLMapProvider : public MapProvider { +class StatkartMapProvider : public MapProvider +{ Q_OBJECT - public: - CustomURLMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral(""), QStringLiteral(""), - AVERAGE_TILE_SIZE, QGeoMapType::CustomMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +protected: + StatkartMapProvider(const QString &mapName, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://norgeskart.no/"), QStringLiteral("png"), + AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) + , _mapName(mapName) {} + +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapName; + const QString _mapUrl = QStringLiteral("http://opencache.statkart.no/gatekeeper/gk/gk.open_gmaps?layers=%1&zoom=%2&x=%3&y=%4"); }; -class StatkartMapProvider : public MapProvider { +class StatkartTopoMapProvider : public StatkartMapProvider +{ Q_OBJECT - public: - StatkartMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://norgeskart.no/"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + StatkartTopoMapProvider(QObject* parent = nullptr) + : StatkartMapProvider(QStringLiteral("topo4"), parent) {} }; -class StatkartBaseMapProvider : public MapProvider { +class StatkartBaseMapProvider : public StatkartMapProvider +{ Q_OBJECT - public: - StatkartBaseMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://norgeskart.no/"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + StatkartBaseMapProvider(QObject* parent = nullptr) + : StatkartMapProvider(QStringLiteral("norgeskart_bakgrunn"), parent) {} }; -class EniroMapProvider : public MapProvider { +class EniroMapProvider : public MapProvider +{ Q_OBJECT - public: + +public: EniroMapProvider(QObject* parent = nullptr) : MapProvider(QStringLiteral("https://www.eniro.se/"), QStringLiteral("png"), AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapUrl = QStringLiteral("http://map.eniro.com/geowebcache/service/tms1.0.0/map/%1/%2/%3.%4"); }; -class MapQuestMapMapProvider : public MapProvider { +class MapQuestMapProvider : public MapProvider +{ Q_OBJECT - public: - MapQuestMapMapProvider(QObject* parent = nullptr) + +protected: + MapQuestMapProvider(const QString &mapName, QGeoMapType::MapStyle mapType, QObject* parent = nullptr) : MapProvider(QStringLiteral("https://mapquest.com"), QStringLiteral("jpg"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} + AVERAGE_TILE_SIZE, mapType, parent) + , _mapName(mapName) {} + +private: + QString _getURL(int x, int y, int zoom) const final; - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + const QString _mapName; + const QString _mapUrl = QStringLiteral("http://otile%1.mqcdn.com/tiles/1.0.0/%2/%3/%4/%5.%6"); }; -class MapQuestSatMapProvider : public MapProvider { +class MapQuestMapMapProvider : public MapQuestMapProvider +{ Q_OBJECT - public: - MapQuestSatMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("https://mapquest.com"), QStringLiteral("jpg"), - AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + MapQuestMapMapProvider(QObject* parent = nullptr) + : MapQuestMapProvider(QStringLiteral("map"), QGeoMapType::StreetMap, parent) {} }; -class VWorldStreetMapProvider : public MapProvider { +class MapQuestSatMapProvider : public MapQuestMapProvider +{ + Q_OBJECT + +public: + MapQuestSatMapProvider(QObject* parent = nullptr) + : MapQuestMapProvider(QStringLiteral("sat"), QGeoMapType::SatelliteMapDay, parent) {} +}; + +class VWorldMapProvider : public MapProvider +{ Q_OBJECT - public: - VWorldStreetMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("www.vworld.kr"), QStringLiteral("png"), - AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +protected: + VWorldMapProvider(const QString &mapName, const QString& imageFormat, quint32 averageSize, QGeoMapType::MapStyle mapStyle, QObject* parent = nullptr) + : MapProvider(QStringLiteral("www.vworld.kr"), imageFormat, averageSize, mapStyle, parent) + , _mapName(mapName) {} - private: - const QString _versionBingMaps = QStringLiteral("563"); +private: + QString _getURL(int x, int y, int zoom) const final; + + const QString _mapName; + const QString _mapUrl = QStringLiteral("http://api.vworld.kr/req/wmts/1.0.0/%1/%2/%3/%4/%5.%6"); }; -class VWorldSatMapProvider : public MapProvider { +class VWorldStreetMapProvider : public VWorldMapProvider +{ Q_OBJECT - public: - VWorldSatMapProvider(QObject* parent = nullptr) - : MapProvider(QStringLiteral("www.vworld.kr"), QStringLiteral("jpeg"), - AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; +public: + VWorldStreetMapProvider(QObject* parent = nullptr) + : VWorldMapProvider(QStringLiteral("Base"), QStringLiteral("png"), AVERAGE_TILE_SIZE, QGeoMapType::StreetMap, parent) {} +}; + +class VWorldSatMapProvider : public VWorldMapProvider +{ + Q_OBJECT - private: - const QString _versionBingMaps = QStringLiteral("563"); +public: + VWorldSatMapProvider(QObject* parent = nullptr) + : VWorldMapProvider(QStringLiteral("Satellite"), QStringLiteral("jpeg"), AVERAGE_TILE_SIZE, QGeoMapType::SatelliteMapDay, parent) {} }; diff --git a/src/QtLocationPlugin/GoogleMapProvider.cpp b/src/QtLocationPlugin/GoogleMapProvider.cpp index 59ae94a9c2c..1db60a601c3 100644 --- a/src/QtLocationPlugin/GoogleMapProvider.cpp +++ b/src/QtLocationPlugin/GoogleMapProvider.cpp @@ -8,224 +8,29 @@ ****************************************************************************/ #include "GoogleMapProvider.h" -#include "QGCMapEngine.h" -#if defined(DEBUG_GOOGLE_MAPS) -#include -#include -#endif -#include -#include -#include - -GoogleMapProvider::GoogleMapProvider(const QString &imageFormat, const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject* parent) - : MapProvider(QStringLiteral("https://www.google.com/maps/preview"), imageFormat, averageSize, mapType, parent) - , _googleVersionRetrieved(false) - , _googleReply(nullptr) +void GoogleMapProvider::_getSecGoogleWords(int x, int y, QString& sec1, QString& sec2) const { - // Google version strings - _versionGoogleMap = QStringLiteral("m@354000000"); - _versionGoogleSatellite = QStringLiteral("692"); - _versionGoogleLabels = QStringLiteral("h@336"); - _versionGoogleTerrain = QStringLiteral("t@354,r@354000000"); - _versionGoogleHybrid = QStringLiteral("y"); - _secGoogleWord = QStringLiteral("Galileo"); -} - -GoogleMapProvider::~GoogleMapProvider() { - if (_googleReply) - _googleReply->deleteLater(); -} - -//----------------------------------------------------------------------------- -void GoogleMapProvider::_getSecGoogleWords(const int x, const int y, QString& sec1, QString& sec2) const { - sec1 = QStringLiteral(""); // after &x=... - sec2 = QStringLiteral(""); // after &zoom=... - int seclen = ((x * 3) + y) % 8; - sec2 = _secGoogleWord.left(seclen); - if (y >= 10000 && y < 100000) { + sec1 = QStringLiteral(""); // after &x=... + sec2 = QStringLiteral(""); // after &zoom=... + const int seclen = ((x * 3) + y) % 8; + sec2 = _secGoogleWord.left(seclen); + if ((y >= 10000) && (y < 100000)) { sec1 = QStringLiteral("&s="); } } -//----------------------------------------------------------------------------- -void GoogleMapProvider::_networkReplyError(QNetworkReply::NetworkError error) { - qWarning() << "Could not connect to google maps. Error:" << error; - if (_googleReply) { - _googleReply->deleteLater(); - _googleReply = nullptr; - } -} -//----------------------------------------------------------------------------- -void GoogleMapProvider::_replyDestroyed() { - _googleReply = nullptr; -} - -void GoogleMapProvider::_googleVersionCompleted() { - if (!_googleReply || (_googleReply->error() != QNetworkReply::NoError)) { - qDebug() << "Error collecting Google maps version info"; - return; - } - const QString html = QString(_googleReply->readAll()); - -#if defined(DEBUG_GOOGLE_MAPS) - QString filename = QStandardPaths::writableLocation(QStandardPaths::HomeLocation); - filename += QStringLiteral("/google.output"); - QFile file(filename); - if (file.open(QIODevice::ReadWrite)) { - QTextStream stream(&file); - stream << html << endl; - } -#endif - - static const QRegularExpression regMap("\"*https?://mt\\D?\\d..*/vt\\?lyrs=m@(\\d*)", QRegularExpression::CaseInsensitiveOption); - const QRegularExpressionMatch matchMap = regMap.match(html); - if (matchMap.hasMatch()) { - _versionGoogleMap = QString("m@%1").arg(matchMap.captured(1)); - } - - static const QRegularExpression regSatellite( "\"*https?://khm\\D?\\d.googleapis.com/kh\\?v=(\\d*)", QRegularExpression::CaseInsensitiveOption); - const QRegularExpressionMatch matchSatellite = regSatellite.match( html ); - if (matchSatellite.hasMatch()) { - _versionGoogleSatellite = matchSatellite.captured(1); - } - - static const QRegularExpression regTerrain( "\"*https?://mt\\D?\\d..*/vt\\?lyrs=t@(\\d*),r@(\\d*)", QRegularExpression::CaseInsensitiveOption); - const QRegularExpressionMatch matchTerrain = regTerrain.match(html); - if (matchTerrain.hasMatch()) { - _versionGoogleTerrain = QString("t@%1,r@%2").arg( matchTerrain.captured(1), matchTerrain.captured(2)); - } - - _googleReply->deleteLater(); - _googleReply = nullptr; -} - -void GoogleMapProvider::_tryCorrectGoogleVersions(QNetworkAccessManager* networkManager) { - QMutexLocker locker(&_googleVersionMutex); - if (_googleVersionRetrieved) { - return; - } - _googleVersionRetrieved = true; - if (networkManager) { - QNetworkRequest qheader; - QNetworkProxy proxy = networkManager->proxy(); - QNetworkProxy tProxy; - tProxy.setType(QNetworkProxy::DefaultProxy); - networkManager->setProxy(tProxy); - QSslConfiguration conf = qheader.sslConfiguration(); - conf.setPeerVerifyMode(QSslSocket::VerifyNone); - qheader.setSslConfiguration(conf); - const QString url = QStringLiteral("http://maps.google.com/maps/api/js?v=3.2&sensor=false"); - qheader.setUrl(QUrl(url)); - QByteArray ua; - ua.append(getQGCMapEngine()->userAgent().toLatin1()); - qheader.setRawHeader("User-Agent", ua); - _googleReply = networkManager->get(qheader); - connect(_googleReply, &QNetworkReply::finished, this, &GoogleMapProvider::_googleVersionCompleted); - connect(_googleReply, &QNetworkReply::destroyed, this, &GoogleMapProvider::_replyDestroyed); - connect(_googleReply, &QNetworkReply::errorOccurred, this, &GoogleMapProvider::_networkReplyError); - networkManager->setProxy(proxy); - } -} - -QString GoogleStreetMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - // http://mt1.google.com/vt/lyrs=m - QString server = QStringLiteral("mt"); - QString request = QStringLiteral("vt"); - QString sec1; // after &x=... - QString sec2; // after &zoom=... - _getSecGoogleWords(x, y, sec1, sec2); - _tryCorrectGoogleVersions(networkManager); - return QString(QStringLiteral("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")) - .arg(server) - .arg(_getServerNum(x, y, 4)) - .arg(request) - .arg(_versionGoogleMap) - .arg(_language) - .arg(x) - .arg(sec1) - .arg(y) - .arg(zoom) - .arg(sec2); -} - -QString GoogleSatelliteMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - // http://mt1.google.com/vt/lyrs=s - QString server = QStringLiteral("khm"); - QString request = QStringLiteral("kh"); - QString sec1; // after &x=... - QString sec2; // after &zoom=... - _getSecGoogleWords(x, y, sec1, sec2); - _tryCorrectGoogleVersions(networkManager); - return QString(QStringLiteral("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")) - .arg(server) - .arg(_getServerNum(x, y, 4)) - .arg(request) - .arg(_versionGoogleSatellite) - .arg(_language) - .arg(x) - .arg(sec1) - .arg(y) - .arg(zoom) - .arg(sec2); -} - -QString GoogleLabelsMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - QString server = "mts"; - QString request = "vt"; - QString sec1; // after &x=... - QString sec2; // after &zoom=... - _getSecGoogleWords(x, y, sec1, sec2); - _tryCorrectGoogleVersions(networkManager); - return QString(QStringLiteral("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")) - .arg(server) - .arg(_getServerNum(x, y, 4)) - .arg(request) - .arg(_versionGoogleLabels) - .arg(_language) - .arg(x) - .arg(sec1) - .arg(y) - .arg(zoom) - .arg(sec2); -} - -QString GoogleTerrainMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - QString server = QStringLiteral("mt"); - QString request = QStringLiteral("vt"); - QString sec1; // after &x=... - QString sec2; // after &zoom=... - _getSecGoogleWords(x, y, sec1, sec2); - _tryCorrectGoogleVersions(networkManager); - return QString(QStringLiteral("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")) - .arg(server) - .arg(_getServerNum(x, y, 4)) - .arg(request) - .arg(_versionGoogleTerrain) - .arg(_language) - .arg(x) - .arg(sec1) - .arg(y) - .arg(zoom) - .arg(sec2); -} - -QString GoogleHybridMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - QString server = QStringLiteral("mt"); - QString request = QStringLiteral("vt"); - QString sec1; // after &x=... - QString sec2; // after &zoom=... +QString GoogleMapProvider::_getURL(int x, int y, int zoom) const +{ + QString sec1; + QString sec2; _getSecGoogleWords(x, y, sec1, sec2); - _tryCorrectGoogleVersions(networkManager); - return QString(QStringLiteral("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10")) - .arg(server) + return _mapUrl .arg(_getServerNum(x, y, 4)) - .arg(request) - .arg(_versionGoogleHybrid) - .arg(_language) + .arg(_versionRequest, _version, _language) .arg(x) .arg(sec1) .arg(y) .arg(zoom) - .arg(sec2); + .arg(sec2, _scale); } diff --git a/src/QtLocationPlugin/GoogleMapProvider.h b/src/QtLocationPlugin/GoogleMapProvider.h index cda15585bcc..c1cd6827040 100644 --- a/src/QtLocationPlugin/GoogleMapProvider.h +++ b/src/QtLocationPlugin/GoogleMapProvider.h @@ -11,125 +11,88 @@ #include "MapProvider.h" -#include -#include - -class GoogleMapProvider : public MapProvider { +// h: roads only +// m: standard roadmap +// p: terrain +// r: somehow altered roadmap +// s: satellite only +// t: terrain only +// y: hybrid (s,h) +// traffic +// transit +// bike +// mt.google.com: mt0, mt1, mt2 mt3 +// size: 256x256 +// maxZoom: 20 + +static constexpr const quint32 AVERAGE_GOOGLE_STREET_MAP = 4913; +static constexpr const quint32 AVERAGE_GOOGLE_SAT_MAP = 56887; +static constexpr const quint32 AVERAGE_GOOGLE_TERRAIN_MAP = 19391; + +class GoogleMapProvider : public MapProvider +{ Q_OBJECT -public: - GoogleMapProvider(const QString& imageFormat, const quint32 averageSize, - const QGeoMapType::MapStyle _mapType, QObject* parent = nullptr); - - ~GoogleMapProvider(); - - // Google Specific private slots -private slots: - void _networkReplyError(QNetworkReply::NetworkError error); - void _googleVersionCompleted(); - void _replyDestroyed(); - protected: - // Google Specific private methods - void _getSecGoogleWords(const int x, const int y, QString& sec1, QString& sec2) const; - void _tryCorrectGoogleVersions(QNetworkAccessManager* networkManager); - - // Google Specific attributes - bool _googleVersionRetrieved; - QNetworkReply* _googleReply; - QMutex _googleVersionMutex; - QString _versionGoogleMap; - QString _versionGoogleSatellite; - QString _versionGoogleLabels; - QString _versionGoogleTerrain; - QString _versionGoogleHybrid; - QString _secGoogleWord; + GoogleMapProvider(const QString& versionRequest, const QString& version, const QString& imageFormat, quint32 averageSize, + QGeoMapType::MapStyle mapType, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://www.google.com/maps/preview"), imageFormat, averageSize, mapType, parent) + , _versionRequest(versionRequest) + , _version(version) {} + +private: + void _getSecGoogleWords(int x, int y, QString& sec1, QString& sec2) const; + QString _getURL(int x, int y, int zoom) const final; + + const QString _versionRequest; + const QString _version; + const QString _mapUrl = QStringLiteral("http://mt%1.google.com/vt/%2=%3&hl=%4&x=%5%6&y=%7&z=%8&s=%9&scale=%10"); + const QString _secGoogleWord = QStringLiteral("Galileo"); + const QString _scale = QStringLiteral("1"); }; -// NoMap = 0, -// StreetMap, -// SatelliteMapDay, -// SatelliteMapNight, -// TerrainMap, -// HybridMap, -// TransitMap, -// GrayStreetMap, -// PedestrianMap, -// CarNavigationMap, -// CycleMap, -// CustomMap = 100 - -static const quint32 AVERAGE_GOOGLE_STREET_MAP = 4913; -static const quint32 AVERAGE_GOOGLE_SAT_MAP = 56887; -static const quint32 AVERAGE_GOOGLE_TERRAIN_MAP = 19391; - -// ----------------------------------------------------------- -// Google Street Map - -class GoogleStreetMapProvider : public GoogleMapProvider { +class GoogleStreetMapProvider : public GoogleMapProvider +{ Q_OBJECT public: GoogleStreetMapProvider(QObject* parent = nullptr) - : GoogleMapProvider(QStringLiteral("png"), AVERAGE_GOOGLE_STREET_MAP, QGeoMapType::StreetMap, parent) {} - -protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : GoogleMapProvider(QStringLiteral("lyrs"), QStringLiteral("m"), QStringLiteral("png"), AVERAGE_GOOGLE_STREET_MAP, QGeoMapType::StreetMap, parent) {} }; -// ----------------------------------------------------------- -// Google Street Map - -class GoogleSatelliteMapProvider : public GoogleMapProvider { +class GoogleSatelliteMapProvider : public GoogleMapProvider +{ Q_OBJECT public: GoogleSatelliteMapProvider(QObject* parent = nullptr) - : GoogleMapProvider(QStringLiteral("jpg"), AVERAGE_GOOGLE_SAT_MAP, + : GoogleMapProvider(QStringLiteral("lyrs"), QStringLiteral("s"), QStringLiteral("jpg"), AVERAGE_GOOGLE_SAT_MAP, QGeoMapType::SatelliteMapDay, parent) {} - -protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; }; -// ----------------------------------------------------------- -// Google Labels Map - -class GoogleLabelsMapProvider : public GoogleMapProvider { +class GoogleLabelsMapProvider : public GoogleMapProvider +{ Q_OBJECT public: GoogleLabelsMapProvider(QObject* parent = nullptr) - : GoogleMapProvider(QStringLiteral("png"), AVERAGE_TILE_SIZE, QGeoMapType::CustomMap, parent) {} - -protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : GoogleMapProvider(QStringLiteral("lyrs"), QStringLiteral("h"), QStringLiteral("png"), AVERAGE_TILE_SIZE, QGeoMapType::CustomMap, parent) {} }; -// ----------------------------------------------------------- -// Google Terrain Map - -class GoogleTerrainMapProvider : public GoogleMapProvider { +class GoogleTerrainMapProvider : public GoogleMapProvider +{ Q_OBJECT public: GoogleTerrainMapProvider(QObject* parent = nullptr) - : GoogleMapProvider(QStringLiteral("png"), AVERAGE_GOOGLE_TERRAIN_MAP, QGeoMapType::TerrainMap, parent) {} - -protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : GoogleMapProvider(QStringLiteral("v"), QStringLiteral("t,r"), QStringLiteral("png"), AVERAGE_GOOGLE_TERRAIN_MAP, QGeoMapType::TerrainMap, parent) {} }; -// ----------------------------------------------------------- -// Google Hybrid Map - -class GoogleHybridMapProvider : public GoogleMapProvider { +class GoogleHybridMapProvider : public GoogleMapProvider +{ Q_OBJECT public: GoogleHybridMapProvider(QObject* parent = nullptr) - : GoogleMapProvider(QStringLiteral("png"), AVERAGE_GOOGLE_SAT_MAP, QGeoMapType::HybridMap, parent) {} - -protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + : GoogleMapProvider(QStringLiteral("lyrs"), QStringLiteral("y"), QStringLiteral("png"), AVERAGE_GOOGLE_SAT_MAP, QGeoMapType::HybridMap, parent) {} }; diff --git a/src/QtLocationPlugin/MapProvider.cpp b/src/QtLocationPlugin/MapProvider.cpp index 82e2bb31a8a..48cadf29f0b 100644 --- a/src/QtLocationPlugin/MapProvider.cpp +++ b/src/QtLocationPlugin/MapProvider.cpp @@ -8,94 +8,103 @@ ****************************************************************************/ #include "MapProvider.h" +#include -#include +#include #include +QGC_LOGGING_CATEGORY(MapProviderLog, "qgc.qtlocationplugin.mapprovider") + MapProvider::MapProvider( - const QString &referrer, + const QString &referrer, const QString &imageFormat, - const quint32 averageSize, - const QGeoMapType::MapStyle mapStyle, + quint32 averageSize, + QGeoMapType::MapStyle mapStyle, QObject* parent) - : QObject (parent) - , _referrer (referrer) - , _imageFormat (imageFormat) - , _averageSize (averageSize) - , _mapStyle (mapStyle) -{ - const QStringList langs = QLocale::system().uiLanguages(); - if (langs.length() > 0) { - _language = langs[0]; - } -} + : QObject(parent) + , _referrer(referrer) + , _imageFormat(imageFormat) + , _averageSize(averageSize) + , _mapStyle(mapStyle) + , _language(!QLocale::system().uiLanguages().isEmpty() ? QLocale::system().uiLanguages().constFirst() : "en") {} -QNetworkRequest MapProvider::getTileURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - //-- Build URL +QNetworkRequest MapProvider::getTileURL(int x, int y, int zoom) const +{ QNetworkRequest request; - const QString url = _getURL(x, y, zoom, networkManager); + const QString url = _getURL(x, y, zoom); if (url.isEmpty()) { return request; } request.setUrl(QUrl(url)); request.setRawHeader(QByteArrayLiteral("Accept"), QByteArrayLiteral("*/*")); request.setRawHeader(QByteArrayLiteral("Referrer"), _referrer.toUtf8()); - request.setRawHeader(QByteArrayLiteral("User-Agent"), _userAgent); + request.setRawHeader(QByteArrayLiteral("User-Agent"), QByteArrayLiteral("Qt Location based application")); return request; } -QString MapProvider::getImageFormat(const QByteArray& image) const { - QString format; - if (image.size() > 2) { - if (image.startsWith(reinterpret_cast(pngSignature))) - format = QStringLiteral("png"); - else if (image.startsWith(reinterpret_cast(jpegSignature))) - format = QStringLiteral("jpg"); - else if (image.startsWith(reinterpret_cast(gifSignature))) - format = QStringLiteral("gif"); - else { - return _imageFormat; - } +QString MapProvider::getImageFormat(QByteArrayView image) const +{ + if (image.size() < 3) { + return QString(); + } + + static constexpr QByteArrayView pngSignature("\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"); + if (image.startsWith(pngSignature)) { + return QStringLiteral("png"); + } + + static constexpr QByteArrayView jpegSignature("\xFF\xD8\xFF"); + if (image.startsWith(jpegSignature)) { + return QStringLiteral("jpg"); + } + + static constexpr QByteArrayView gifSignature("\x47\x49\x46\x38"); + if (image.startsWith(gifSignature)) { + return QStringLiteral("gif"); } - return format; + + return _imageFormat; } -QString MapProvider::_tileXYToQuadKey(const int tileX, const int tileY, const int levelOfDetail) const { +QString MapProvider::_tileXYToQuadKey(int tileX, int tileY, int levelOfDetail) const +{ QString quadKey; for (int i = levelOfDetail; i > 0; i--) { char digit = '0'; - const int mask = 1 << (i - 1); + const int mask = 1 << (i - 1); + if ((tileX & mask) != 0) { digit++; } if ((tileY & mask) != 0) { - digit++; - digit++; + digit += 2; } - quadKey.append(digit); + + (void) quadKey.append(digit); } + return quadKey; } -int MapProvider::_getServerNum(const int x, const int y, const int max) const { +int MapProvider::_getServerNum(int x, int y, int max) const +{ return (x + 2 * y) % max; } -int MapProvider::long2tileX(const double lon, const int z) const { +int MapProvider::long2tileX(double lon, int z) const +{ return static_cast(floor((lon + 180.0) / 360.0 * pow(2.0, z))); } -//----------------------------------------------------------------------------- -int MapProvider::lat2tileY(const double lat, const int z) const { - return static_cast(floor( - (1.0 - - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / - 2.0 * pow(2.0, z))); +int MapProvider::lat2tileY(double lat, int z) const +{ + return static_cast(floor((1.0 - log(tan(lat * M_PI / 180.0) + 1.0 / cos(lat * M_PI / 180.0)) / M_PI) / 2.0 * pow(2.0, z))); } -QGCTileSet MapProvider::getTileCount(const int zoom, const double topleftLon, - const double topleftLat, const double bottomRightLon, - const double bottomRightLat) const { +QGCTileSet MapProvider::getTileCount(int zoom, double topleftLon, + double topleftLat, double bottomRightLon, + double bottomRightLat) const +{ QGCTileSet set; set.tileX0 = long2tileX(topleftLon, zoom); set.tileY0 = lat2tileY(topleftLat, zoom); diff --git a/src/QtLocationPlugin/MapProvider.h b/src/QtLocationPlugin/MapProvider.h index ca0e70378b0..8c5c0c4a9ff 100644 --- a/src/QtLocationPlugin/MapProvider.h +++ b/src/QtLocationPlugin/MapProvider.h @@ -9,59 +9,69 @@ #pragma once -#include "QGCTileSet.h" #include - #include #include +#include -static const unsigned char pngSignature[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00}; -static const unsigned char jpegSignature[] = {0xFF, 0xD8, 0xFF, 0x00}; -static const unsigned char gifSignature[] = {0x47, 0x49, 0x46, 0x38, 0x00}; +#include "QGCTileSet.h" -static const quint32 AVERAGE_TILE_SIZE = 13652; +Q_DECLARE_LOGGING_CATEGORY(MapProviderLog) + +// qgeomaptype_p.h +/*enum MapStyle { + NoMap = 0, + StreetMap, + SatelliteMapDay, + SatelliteMapNight, + TerrainMap, + HybridMap, + TransitMap, + GrayStreetMap, + PedestrianMap, + CarNavigationMap, + CycleMap, + CustomMap = 100 +};*/ + +static constexpr const quint32 AVERAGE_TILE_SIZE = 13652; class QNetworkRequest; -class QNetworkAccessManager; -class MapProvider : public QObject { +class MapProvider : public QObject +{ Q_OBJECT public: - MapProvider(const QString& referrer, const QString& imageFormat, const quint32 averageSize, - const QGeoMapType::MapStyle mapStyle = QGeoMapType::CustomMap, QObject* parent = nullptr); + MapProvider(const QString& referrer, const QString& imageFormat, quint32 averageSize = AVERAGE_TILE_SIZE, + QGeoMapType::MapStyle mapStyle = QGeoMapType::CustomMap, QObject* parent = nullptr); - virtual QNetworkRequest getTileURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager); - - QString getImageFormat(const QByteArray& image) const; + QString getImageFormat(QByteArrayView image) const; quint32 getAverageSize() const { return _averageSize; } + QGeoMapType::MapStyle getMapStyle() const { return _mapStyle; } - QGeoMapType::MapStyle getMapStyle() { return _mapStyle; } - - virtual int long2tileX(const double lon, const int z) const; + virtual QNetworkRequest getTileURL(int x, int y, int zoom) const; - virtual int lat2tileY(const double lat, const int z) const; + virtual int long2tileX(double lon, int z) const; + virtual int lat2tileY(double lat, int z) const; - virtual bool _isElevationProvider() const { return false; } - virtual bool _isBingProvider() const { return false; } + virtual bool isElevationProvider() const { return false; } + virtual bool isBingProvider() const { return false; } - virtual QGCTileSet getTileCount(const int zoom, const double topleftLon, - const double topleftLat, const double bottomRightLon, - const double bottomRightLat) const; + virtual QGCTileSet getTileCount(int zoom, double topleftLon, + double topleftLat, double bottomRightLon, + double bottomRightLat) const; protected: - QString _tileXYToQuadKey(const int tileX, const int tileY, const int levelOfDetail) const; - int _getServerNum(const int x, const int y, const int max) const; - // Define the url to Request - virtual QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) = 0; - - // Define Referrer for Request RawHeader - QString _referrer; - QString _imageFormat; - quint32 _averageSize; - QByteArray _userAgent; - QString _language; - QGeoMapType::MapStyle _mapStyle; + QString _tileXYToQuadKey(int tileX, int tileY, int levelOfDetail) const; + int _getServerNum(int x, int y, int max) const; + + virtual QString _getURL(int x, int y, int zoom) const = 0; + const QString _referrer; + const QString _imageFormat; + const quint32 _averageSize; + const QGeoMapType::MapStyle _mapStyle; + const QString _language; }; diff --git a/src/QtLocationPlugin/MapboxMapProvider.cpp b/src/QtLocationPlugin/MapboxMapProvider.cpp index 64f140d7c6e..e573518a7d1 100644 --- a/src/QtLocationPlugin/MapboxMapProvider.cpp +++ b/src/QtLocationPlugin/MapboxMapProvider.cpp @@ -2,24 +2,18 @@ #include "QGCApplication.h" #include "SettingsManager.h" -static const QString MapBoxUrl = QStringLiteral("https://api.mapbox.com/styles/v1/mapbox/%1/tiles/%2/%3/%4?access_token=%5"); -static const QString MapBoxUrlCustom = QStringLiteral("https://api.mapbox.com/styles/v1/%1/%2/tiles/256/%3/%4/%5?access_token=%6"); - -MapboxMapProvider::MapboxMapProvider(const QString &mapName, const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject* parent) - : MapProvider(QStringLiteral("https://www.mapbox.com/"), QStringLiteral("jpg"), averageSize, mapType, parent) - , _mapboxName(mapName) +QString MapboxMapProvider::_getURL(int x, int y, int zoom) const { -} - -QString MapboxMapProvider::_getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) { - Q_UNUSED(networkManager) const QString mapBoxToken = qgcApp()->toolbox()->settingsManager()->appSettings()->mapboxToken()->rawValue().toString(); if (!mapBoxToken.isEmpty()) { - if (_mapboxName == QString("mapbox.custom")) { + if (_mapboxName == QStringLiteral("mapbox.custom")) { + static const QString MapBoxUrlCustom = QStringLiteral("https://api.mapbox.com/styles/v1/%1/%2/tiles/256/%3/%4/%5?access_token=%6"); const QString mapBoxAccount = qgcApp()->toolbox()->settingsManager()->appSettings()->mapboxAccount()->rawValue().toString(); const QString mapBoxStyle = qgcApp()->toolbox()->settingsManager()->appSettings()->mapboxStyle()->rawValue().toString(); return MapBoxUrlCustom.arg(mapBoxAccount).arg(mapBoxStyle).arg(zoom).arg(x).arg(y).arg(mapBoxToken); } + + static const QString MapBoxUrl = QStringLiteral("https://api.mapbox.com/styles/v1/mapbox/%1/tiles/%2/%3/%4?access_token=%5"); return MapBoxUrl.arg(_mapboxName).arg(zoom).arg(x).arg(y).arg(mapBoxToken); } return QString(); diff --git a/src/QtLocationPlugin/MapboxMapProvider.h b/src/QtLocationPlugin/MapboxMapProvider.h index 6f595384793..242992eb515 100644 --- a/src/QtLocationPlugin/MapboxMapProvider.h +++ b/src/QtLocationPlugin/MapboxMapProvider.h @@ -11,22 +11,26 @@ #include "MapProvider.h" -static const quint32 AVERAGE_MAPBOX_SAT_MAP = 15739; -static const quint32 AVERAGE_MAPBOX_STREET_MAP = 5648; +static constexpr const quint32 AVERAGE_MAPBOX_SAT_MAP = 15739; +static constexpr const quint32 AVERAGE_MAPBOX_STREET_MAP = 5648; -class MapboxMapProvider : public MapProvider { +class MapboxMapProvider : public MapProvider +{ Q_OBJECT -public: - MapboxMapProvider(const QString& mapName, const quint32 averageSize, const QGeoMapType::MapStyle mapType, QObject* parent = nullptr); - protected: - QString _getURL(const int x, const int y, const int zoom, QNetworkAccessManager* networkManager) override; + MapboxMapProvider(const QString& mapName, quint32 averageSize, QGeoMapType::MapStyle mapType, QObject* parent = nullptr) + : MapProvider(QStringLiteral("https://www.mapbox.com/"), QStringLiteral("jpg"), averageSize, mapType, parent) + , _mapboxName(mapName) {} + +private: + QString _getURL(int x, int y, int zoom) const final; - QString _mapboxName; + const QString _mapboxName; }; -class MapboxStreetMapProvider : public MapboxMapProvider { +class MapboxStreetMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -35,7 +39,8 @@ class MapboxStreetMapProvider : public MapboxMapProvider { QGeoMapType::StreetMap, parent) {} }; -class MapboxLightMapProvider : public MapboxMapProvider { +class MapboxLightMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -44,7 +49,8 @@ class MapboxLightMapProvider : public MapboxMapProvider { QGeoMapType::CustomMap, parent) {} }; -class MapboxDarkMapProvider : public MapboxMapProvider { +class MapboxDarkMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -53,7 +59,8 @@ class MapboxDarkMapProvider : public MapboxMapProvider { QGeoMapType::CustomMap, parent) {} }; -class MapboxSatelliteMapProvider : public MapboxMapProvider { +class MapboxSatelliteMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -62,7 +69,8 @@ class MapboxSatelliteMapProvider : public MapboxMapProvider { QGeoMapType::SatelliteMapDay, parent) {} }; -class MapboxHybridMapProvider : public MapboxMapProvider { +class MapboxHybridMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -71,7 +79,8 @@ class MapboxHybridMapProvider : public MapboxMapProvider { QGeoMapType::HybridMap, parent) {} }; -class MapboxBrightMapProvider : public MapboxMapProvider { +class MapboxBrightMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -80,7 +89,8 @@ class MapboxBrightMapProvider : public MapboxMapProvider { QGeoMapType::CustomMap, parent) {} }; -class MapboxStreetsBasicMapProvider : public MapboxMapProvider { +class MapboxStreetsBasicMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -89,7 +99,8 @@ class MapboxStreetsBasicMapProvider : public MapboxMapProvider { QGeoMapType::StreetMap, parent) {} }; -class MapboxOutdoorsMapProvider : public MapboxMapProvider { +class MapboxOutdoorsMapProvider : public MapboxMapProvider +{ Q_OBJECT public: @@ -98,7 +109,8 @@ class MapboxOutdoorsMapProvider : public MapboxMapProvider { QGeoMapType::CustomMap, parent) {} }; -class MapboxCustomMapProvider : public MapboxMapProvider { +class MapboxCustomMapProvider : public MapboxMapProvider +{ Q_OBJECT public: diff --git a/src/QtLocationPlugin/QGCMapTileSet.cpp b/src/QtLocationPlugin/QGCMapTileSet.cpp index c93ba966dce..5e914f51b60 100644 --- a/src/QtLocationPlugin/QGCMapTileSet.cpp +++ b/src/QtLocationPlugin/QGCMapTileSet.cpp @@ -241,7 +241,7 @@ void QGCCachedTileSet::_prepareDownload() if(_tilesToDownload.count()) { QGCTile* tile = _tilesToDownload.first(); _tilesToDownload.removeFirst(); - QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(tile->type(), tile->x(), tile->y(), tile->z(), _networkManager); + QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(tile->type(), tile->x(), tile->y(), tile->z()); request.setAttribute(QNetworkRequest::User, tile->hash()); #if !defined(__mobile__) QNetworkProxy proxy = _networkManager->proxy(); diff --git a/src/QtLocationPlugin/QGCMapUrlEngine.cpp b/src/QtLocationPlugin/QGCMapUrlEngine.cpp index 530750da486..c85ada8a505 100644 --- a/src/QtLocationPlugin/QGCMapUrlEngine.cpp +++ b/src/QtLocationPlugin/QGCMapUrlEngine.cpp @@ -51,7 +51,7 @@ UrlFactory::UrlFactory() : _providers.append(ProviderPair("Bing Satellite", new BingSatelliteMapProvider(this))); _providers.append(ProviderPair("Bing Hybrid", new BingHybridMapProvider(this))); - _providers.append(ProviderPair("Statkart Topo", new StatkartMapProvider(this))); + _providers.append(ProviderPair("Statkart Topo", new StatkartTopoMapProvider(this))); _providers.append(ProviderPair("Statkart Basemap", new StatkartBaseMapProvider(this))); _providers.append(ProviderPair("Eniro Topo", new EniroMapProvider(this))); @@ -113,11 +113,11 @@ QString UrlFactory::getImageFormat(const QString& type, const QByteArray& image) return ""; } } -QNetworkRequest UrlFactory::getTileURL(int qtMapId, int x, int y, int zoom, QNetworkAccessManager* networkManager) +QNetworkRequest UrlFactory::getTileURL(int qtMapId, int x, int y, int zoom) { MapProvider* provider = getMapProviderFromQtMapId(qtMapId); if (provider) { - return provider->getTileURL(x, y, zoom, networkManager); + return provider->getTileURL(x, y, zoom); } else { qCWarning(QGCMapUrlEngineLog) << "getTileURL : map id not found:" << qtMapId; return QNetworkRequest(QUrl()); @@ -125,11 +125,11 @@ QNetworkRequest UrlFactory::getTileURL(int qtMapId, int x, int y, int zoom, QNet } //----------------------------------------------------------------------------- -QNetworkRequest UrlFactory::getTileURL(const QString& type, int x, int y, int zoom, QNetworkAccessManager* networkManager) +QNetworkRequest UrlFactory::getTileURL(const QString& type, int x, int y, int zoom) { MapProvider* provider = getMapProviderFromProviderType(type); if (provider) { - return provider->getTileURL(x, y, zoom, networkManager); + return provider->getTileURL(x, y, zoom); } else { qCWarning(QGCMapUrlEngineLog) << "getTileURL : type not found:" << type; return QNetworkRequest(QUrl()); @@ -225,7 +225,7 @@ bool UrlFactory::isElevation(int qtMapId) { MapProvider* provider = getMapProviderFromQtMapId(qtMapId); if (provider) { - return provider->_isElevationProvider(); + return provider->isElevationProvider(); } else { qCWarning(QGCMapUrlEngineLog) << "isElevation : map id not found:" << qtMapId; return false; diff --git a/src/QtLocationPlugin/QGCMapUrlEngine.h b/src/QtLocationPlugin/QGCMapUrlEngine.h index e453d9c5787..fa434f577a6 100644 --- a/src/QtLocationPlugin/QGCMapUrlEngine.h +++ b/src/QtLocationPlugin/QGCMapUrlEngine.h @@ -39,8 +39,8 @@ class UrlFactory : public QObject { typedef QPair ProviderPair; - QNetworkRequest getTileURL (const QString& type, int x, int y, int zoom, QNetworkAccessManager* networkManager); - QNetworkRequest getTileURL (int qtMapId, int x, int y, int zoom, QNetworkAccessManager* networkManager); + QNetworkRequest getTileURL (const QString& type, int x, int y, int zoom); + QNetworkRequest getTileURL (int qtMapId, int x, int y, int zoom); QString getImageFormat (const QString& type, const QByteArray& image); QString getImageFormat (int qtMapId, const QByteArray& image); diff --git a/src/QtLocationPlugin/QGeoMapReplyQGC.cpp b/src/QtLocationPlugin/QGeoMapReplyQGC.cpp index 401c88411fe..407dd176436 100644 --- a/src/QtLocationPlugin/QGeoMapReplyQGC.cpp +++ b/src/QtLocationPlugin/QGeoMapReplyQGC.cpp @@ -147,7 +147,7 @@ QGeoTiledMapReplyQGC::networkReplyFinished() emit terrainDone(a, QNetworkReply::NoError); } else { MapProvider* mapProvider = urlFactory->getMapProviderFromQtMapId(tileSpec().mapId()); - if (mapProvider && mapProvider->_isBingProvider() && a.size() && _bingNoTileImage.size() && a == _bingNoTileImage) { + if (mapProvider && mapProvider->isBingProvider() && a.size() && _bingNoTileImage.size() && a == _bingNoTileImage) { // Bing doesn't return an error if you request a tile above supported zoom level // It instead returns an image of a missing tile graphic. We need to detect that // and error out so Qt will deal with zooming correctly even if it doesn't have the tile. diff --git a/src/QtLocationPlugin/QGeoTileFetcherQGC.cpp b/src/QtLocationPlugin/QGeoTileFetcherQGC.cpp index 7d22c5da2c1..35feb7ca399 100644 --- a/src/QtLocationPlugin/QGeoTileFetcherQGC.cpp +++ b/src/QtLocationPlugin/QGeoTileFetcherQGC.cpp @@ -72,7 +72,7 @@ QGeoTiledMapReply* QGeoTileFetcherQGC::getTileImage(const QGeoTileSpec &spec) { //-- Build URL - QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(spec.mapId(), spec.x(), spec.y(), spec.zoom(), _networkManager); + QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(spec.mapId(), spec.x(), spec.y(), spec.zoom()); if ( ! request.url().isEmpty() ) { return new QGeoTiledMapReplyQGC(_networkManager, request, spec); } diff --git a/src/Terrain/TerrainTileManager.cc b/src/Terrain/TerrainTileManager.cc index 281e6fb69e3..8f4181082ea 100644 --- a/src/Terrain/TerrainTileManager.cc +++ b/src/Terrain/TerrainTileManager.cc @@ -146,8 +146,7 @@ bool TerrainTileManager::getAltitudesForCoordinates(const QList& QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL( kMapType, getQGCMapEngine()->urlFactory()->long2tileX(kMapType, coordinate.longitude(), 1), getQGCMapEngine()->urlFactory()->lat2tileY(kMapType, coordinate.latitude(), 1), - 1, - &_networkManager); + 1); qCDebug(TerrainTileManagerLog) << "TerrainTileManager::getAltitudesForCoordinates query from database" << request.url(); QGeoTileSpec spec; spec.setX(getQGCMapEngine()->urlFactory()->long2tileX(kMapType, coordinate.longitude(), 1)); diff --git a/src/Viewer3D/Viewer3DTileReply.cc b/src/Viewer3D/Viewer3DTileReply.cc index fcf9d3a3a6f..a016887ba58 100644 --- a/src/Viewer3D/Viewer3DTileReply.cc +++ b/src/Viewer3D/Viewer3DTileReply.cc @@ -47,7 +47,7 @@ Viewer3DTileReply::~Viewer3DTileReply() void Viewer3DTileReply::prepareDownload() { - QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(_mapId, _tile.x, _tile.y, _tile.zoomLevel, _networkManager); + QNetworkRequest request = getQGCMapEngine()->urlFactory()->getTileURL(_mapId, _tile.x, _tile.y, _tile.zoomLevel); _reply = _networkManager->get(request); connect(_reply, &QNetworkReply::finished, this, &Viewer3DTileReply::requestFinished); connect(_reply, &QNetworkReply::errorOccurred, this, &Viewer3DTileReply::requestError); @@ -64,7 +64,7 @@ void Viewer3DTileReply::requestFinished() disconnect(_reply, &QNetworkReply::errorOccurred, this, &Viewer3DTileReply::requestError); disconnect(_timeoutTimer, &QTimer::timeout, this, &Viewer3DTileReply::timeoutTimerEvent); - if(mapProvider && mapProvider->_isBingProvider() && _tile.data.size() && _tile.data == _bingNoTileImage){ + if(mapProvider && mapProvider->isBingProvider() && _tile.data.size() && _tile.data == _bingNoTileImage){ // Bing doesn't return an error if you request a tile above supported zoom level // It instead returns an image of a missing tile graphic. We need to detect that // and error out so 3D View will deal with zooming correctly even if it doesn't have the tile. From 461bd92d414e806d6d2d70cd5c07a968ba8950ec Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Fri, 7 Jun 2024 08:46:33 +0000 Subject: [PATCH 27/38] Update PX4 Firmware metadata Fri Jun 7 08:46:33 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index 8f7b6d1cbbd..b871580ad5d 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -1971,7 +1971,7 @@ Path navigation roll slew rate limit - The maximum change in roll angle setpoint per second. + The maximum change in roll angle setpoint per second. This limit is applied in all Auto modes, plus manual Position and Altitude modes. 0 deg/s 0 From f86ef709b677d632e27993ac7d0df14da6f23909 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Fri, 7 Jun 2024 16:01:45 +0000 Subject: [PATCH 28/38] Update PX4 Firmware metadata Fri Jun 7 16:01:45 UTC 2024 --- src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml b/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml index 1d3a33225f7..80d66d2fcb8 100644 --- a/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml +++ b/src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml @@ -289,6 +289,10 @@ Speed of left wheels Steering servo + + Rover + Rover + From 70a0594f17a7573563c92b0357378b83dcd55995 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Mon, 10 Jun 2024 11:29:57 +0000 Subject: [PATCH 29/38] Update PX4 Firmware metadata Mon Jun 10 11:29:57 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index b871580ad5d..1217ea8dec3 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -407,19 +407,19 @@ m 1 - + Airspeed failsafe start delay Delay before switching back to using airspeed sensor if checks indicate sensor is good. Set to a negative value to disable the re-enabling in flight. - -1 - 1000 + -1.0 s + 1 - + Airspeed failsafe stop delay Delay before stopping use of airspeed sensor if checks indicate sensor is bad. - 1 - 10 + 0.0 s + 1 Index or primary airspeed measurement source From 9edeaa14a3a9f3de64b77b204bbb08eccec11eaa Mon Sep 17 00:00:00 2001 From: Holden Date: Sun, 2 Jun 2024 01:50:42 -0400 Subject: [PATCH 30/38] Docs: Add Qt Sensors --- docs/en/qgc-dev-guide/getting_started/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/qgc-dev-guide/getting_started/index.md b/docs/en/qgc-dev-guide/getting_started/index.md index 093f7ea3e39..d0e7af46991 100644 --- a/docs/en/qgc-dev-guide/getting_started/index.md +++ b/docs/en/qgc-dev-guide/getting_started/index.md @@ -98,6 +98,7 @@ To see a complete list of all available components in the installer _Select Comp - _Qt Location (TP)_ - _Qt Multimedia_ - _Qt Positioning_ + - _Qt Sensors_ - _Qt Serial Port_ - _Qt Speech_ From da57eee41bb4b825f63b161ed2a867e63758c3db Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Tue, 11 Jun 2024 07:38:50 -0700 Subject: [PATCH 31/38] Rework PX4 airspeed cal due to parameter name/functionality changes --- src/AutoPilotPlugins/APM/APMRadioComponent.cc | 2 +- src/AutoPilotPlugins/AutoPilotPlugin.cc | 2 +- src/AutoPilotPlugins/AutoPilotPlugin.h | 4 +- src/AutoPilotPlugins/PX4/SensorsComponent.cc | 57 ++++++++++++++----- src/AutoPilotPlugins/PX4/SensorsComponent.h | 11 ++-- .../PX4/SensorsComponentSummaryFixedWing.qml | 10 +--- src/AutoPilotPlugins/PX4/SensorsSetup.qml | 10 ++-- src/VehicleSetup/VehicleComponent.cc | 2 +- src/VehicleSetup/VehicleComponent.h | 4 +- src/VehicleSetup/VehicleSummary.qml | 2 + 10 files changed, 66 insertions(+), 38 deletions(-) diff --git a/src/AutoPilotPlugins/APM/APMRadioComponent.cc b/src/AutoPilotPlugins/APM/APMRadioComponent.cc index 99c8086402f..6a033e098ad 100644 --- a/src/AutoPilotPlugins/APM/APMRadioComponent.cc +++ b/src/AutoPilotPlugins/APM/APMRadioComponent.cc @@ -125,7 +125,7 @@ void APMRadioComponent::_connectSetupTriggers(void) void APMRadioComponent::_triggerChanged(void) { - emit setupCompleteChanged(setupComplete()); + emit setupCompleteChanged(); // Control mapping may have changed so we need to reset triggers _connectSetupTriggers(); diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.cc b/src/AutoPilotPlugins/AutoPilotPlugin.cc index 881ba6491b6..6c4b9dc9b6e 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/AutoPilotPlugin.cc @@ -50,7 +50,7 @@ void AutoPilotPlugin::_recalcSetupComplete(void) if (_setupComplete != newSetupComplete) { _setupComplete = newSetupComplete; - emit setupCompleteChanged(_setupComplete); + emit setupCompleteChanged(); } } diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h index cf35a871d7b..bb928399a52 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/AutoPilotPlugin.h @@ -49,8 +49,8 @@ class AutoPilotPlugin : public QObject bool setupComplete(void) const; signals: - void setupCompleteChanged(bool setupComplete); - void vehicleComponentsChanged(void); + void setupCompleteChanged (void); + void vehicleComponentsChanged (void); protected: /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.cc b/src/AutoPilotPlugins/PX4/SensorsComponent.cc index ee44b2ca13c..91c0f6178e0 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.cc +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.cc @@ -7,19 +7,11 @@ * ****************************************************************************/ - -/// @file -/// @author Don Gagne - #include "SensorsComponent.h" #include "FactSystem.h" #include "ParameterManager.h" #include "Vehicle.h" -const char* SensorsComponent::_airspeedBreakerParam = "CBRK_AIRSPD_CHK"; -const char* SensorsComponent::_airspeedDisabledParam = "FW_ARSP_MODE"; -const char* SensorsComponent::_airspeedCalParam = "SENS_DPRES_OFF"; - const char* SensorsComponent::_magEnabledParam = "SYS_HAS_MAG"; const char* SensorsComponent::_magCalParam = "CAL_MAG0_ID"; @@ -28,6 +20,15 @@ SensorsComponent::SensorsComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, _name(tr("Sensors")) { _deviceIds = QStringList({QStringLiteral("CAL_GYRO0_ID"), QStringLiteral("CAL_ACC0_ID") }); + + if (_vehicle->fixedWing() || _vehicle->vtol() || _vehicle->airship()) { + _airspeedCalTriggerParams << "SENS_DPRES_OFF"; + if (_vehicle->firmwareMajorVersion() >= 1 && _vehicle->firmwareMinorVersion() >= 14) { + _airspeedCalTriggerParams << "SYS_HAS_NUM_ASPD"; + } else { + _airspeedCalTriggerParams << "FW_ARSP_MODE" << "CBRK_AIRSPD_CHK"; + } + } } QString SensorsComponent::name(void) const @@ -67,10 +68,17 @@ bool SensorsComponent::setupComplete(void) const } if (_vehicle->fixedWing() || _vehicle->vtol() || _vehicle->airship()) { - if (!_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _airspeedDisabledParam)->rawValue().toBool() && - _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _airspeedBreakerParam)->rawValue().toInt() != 162128 && - _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, _airspeedCalParam)->rawValue().toFloat() == 0.0f) { - return false; + if (_vehicle->firmwareMajorVersion() >= 1 && _vehicle->firmwareMinorVersion() >= 14) { + if (_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "SYS_HAS_NUM_ASPD")->rawValue().toBool() && + _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "SENS_DPRES_OFF")->rawValue().toFloat() == 0.0f) { + return false; + } + } else { + if (!_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "FW_ARSP_MODE")->rawValue().toBool() && + _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "CBRK_AIRSPD_CHK")->rawValue().toInt() != 162128 && + _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "SENS_DPRES_OFF")->rawValue().toFloat() == 0.0f) { + return false; + } } } @@ -83,7 +91,7 @@ QStringList SensorsComponent::setupCompleteChangedTriggerList(void) const triggers << _deviceIds << _magCalParam << _magEnabledParam; if (_vehicle->fixedWing() || _vehicle->vtol() || _vehicle->airship()) { - triggers << _airspeedCalParam << _airspeedBreakerParam; + triggers << _airspeedCalTriggerParams; } return triggers; @@ -106,3 +114,26 @@ QUrl SensorsComponent::summaryQmlSource(void) const return QUrl::fromUserInput(summaryQml); } + + bool SensorsComponent::_airspeedCalSupported(void) const + { + if (_vehicle->fixedWing() || _vehicle->vtol() || _vehicle->airship()) { + if (_vehicle->firmwareMajorVersion() >= 1 && _vehicle->firmwareMinorVersion() >= 14) { + if (_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "SYS_HAS_NUM_ASPD")->rawValue().toBool()) { + return true; + } + } else { + if (!_vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "FW_ARSP_MODE")->rawValue().toBool() && + _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "CBRK_AIRSPD_CHK")->rawValue().toInt() != 162128) { + return true; + } + } + } + + return false; + } + + bool SensorsComponent::_airspeedCalRequired(void) const + { + return _airspeedCalSupported() && _vehicle->parameterManager()->getParameter(FactSystem::defaultComponentId, "SENS_DPRES_OFF")->rawValue().toFloat() == 0.0f; + } diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.h b/src/AutoPilotPlugins/PX4/SensorsComponent.h index 09b5fba8667..d0d01ef13a5 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.h +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.h @@ -23,6 +23,9 @@ class SensorsComponent : public VehicleComponent public: SensorsComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = nullptr); + Q_PROPERTY(bool airspeedCalSupported READ _airspeedCalSupported STORED false NOTIFY setupCompleteChanged) + Q_PROPERTY(bool airspeedCalRequired READ _airspeedCalRequired STORED false NOTIFY setupCompleteChanged) + // Virtuals from VehicleComponent QStringList setupCompleteChangedTriggerList(void) const override; @@ -36,13 +39,13 @@ class SensorsComponent : public VehicleComponent virtual QUrl summaryQmlSource(void) const override; private: + bool _airspeedCalSupported (void) const; + bool _airspeedCalRequired (void) const; + const QString _name; QVariantList _summaryItems; QStringList _deviceIds; - - static const char* _airspeedDisabledParam; - static const char* _airspeedBreakerParam; - static const char* _airspeedCalParam; + QStringList _airspeedCalTriggerParams; static const char* _magEnabledParam; static const char* _magCalParam; diff --git a/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml b/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml index f6d3ac3eb5f..523857fea55 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml +++ b/src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml @@ -18,12 +18,6 @@ Item { property Fact mag0IdFact: controller.getParameterFact(-1, "CAL_MAG0_ID") property Fact gyro0IdFact: controller.getParameterFact(-1, "CAL_GYRO0_ID") property Fact accel0IdFact: controller.getParameterFact(-1, "CAL_ACC0_ID") - property Fact dpressOffFact: controller.getParameterFact(-1, "SENS_DPRES_OFF") - property Fact airspeedDisabledFact: controller.getParameterFact(-1, "FW_ARSP_MODE") - property Fact airspeedBreakerFact: controller.getParameterFact(-1, "CBRK_AIRSPD_CHK") - - property bool _airspeedVisible: airspeedDisabledFact.value == 0 && airspeedBreakerFact.value !== 162128 - property bool _airspeedCalRequired: _airspeedVisible && dpressOffFact.value === 0 Column { anchors.fill: parent @@ -45,8 +39,8 @@ Item { VehicleSummaryRow { labelText: qsTr("Airspeed:") - visible: _airspeedVisible - valueText: _airspeedCalRequired ? qsTr("Setup required") : qsTr("Ready") + visible: vehicleComponent.airspeedCalSupported + valueText: vehicleComponent.airspeedCalRequired ? qsTr("Setup required") : qsTr("Ready") } } } diff --git a/src/AutoPilotPlugins/PX4/SensorsSetup.qml b/src/AutoPilotPlugins/PX4/SensorsSetup.qml index a30231c9acd..7cbfef11b09 100644 --- a/src/AutoPilotPlugins/PX4/SensorsSetup.qml +++ b/src/AutoPilotPlugins/PX4/SensorsSetup.qml @@ -450,11 +450,9 @@ Item { id: airspeedButton width: _buttonWidth text: qsTr("Airspeed") - visible: (controller.vehicle.fixedWing || controller.vehicle.vtol || controller.vehicle.airship) && - controller.getParameterFact(-1, "FW_ARSP_MODE").value == 0 && - controller.getParameterFact(-1, "CBRK_AIRSPD_CHK").value !== 162128 && - QGroundControl.corePlugin.options.showSensorCalibrationAirspeed && - showSensorCalibrationAirspeed + visible: vehicleComponent.airspeedCalSupported && + QGroundControl.corePlugin.options.showSensorCalibrationAirspeed && + showSensorCalibrationAirspeed indicatorGreen: sens_dpres_off.value !== 0 onClicked: { @@ -522,7 +520,7 @@ Item { height: parent.height readOnly: true text: statusTextAreaDefaultText - color: qgcPal.Text + color: qgcPal.text background: Rectangle { color: qgcPal.windowShade } } diff --git a/src/VehicleSetup/VehicleComponent.cc b/src/VehicleSetup/VehicleComponent.cc index 54ff5a7902e..b953b8a948f 100644 --- a/src/VehicleSetup/VehicleComponent.cc +++ b/src/VehicleSetup/VehicleComponent.cc @@ -68,5 +68,5 @@ void VehicleComponent::setupTriggerSignals(void) void VehicleComponent::_triggerUpdated(QVariant /*value*/) { - emit setupCompleteChanged(setupComplete()); + emit setupCompleteChanged(); } diff --git a/src/VehicleSetup/VehicleComponent.h b/src/VehicleSetup/VehicleComponent.h index 2a39f2e51fc..3e54b93fab3 100644 --- a/src/VehicleSetup/VehicleComponent.h +++ b/src/VehicleSetup/VehicleComponent.h @@ -69,8 +69,8 @@ class VehicleComponent : public QObject virtual void setupTriggerSignals(void); signals: - void setupCompleteChanged(bool setupComplete); - void setupSourceChanged(void); + void setupCompleteChanged (void); + void setupSourceChanged (void); protected slots: void _triggerUpdated(QVariant value); diff --git a/src/VehicleSetup/VehicleSummary.qml b/src/VehicleSetup/VehicleSummary.qml index 7b8a29bae59..8fae5067680 100644 --- a/src/VehicleSetup/VehicleSummary.qml +++ b/src/VehicleSetup/VehicleSummary.qml @@ -145,6 +145,8 @@ Rectangle { anchors.fill: parent anchors.margins: ScreenTools.defaultFontPixelWidth source: modelData.summaryQmlSource + + property var vehicleComponent: modelData } } } From b1fc541c7e27c5f3334d0862a80f919bb0d1c379 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Wed, 12 Jun 2024 09:44:37 +1000 Subject: [PATCH 32/38] Remove gitter/slack links. Add top bar quick download links (#11612) --- docs/.vitepress/config.mjs | 12 +++++++++++- docs/en/qgc-user-guide/index.md | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/.vitepress/config.mjs b/docs/.vitepress/config.mjs index a461cf5b306..b9315fcdc5e 100644 --- a/docs/.vitepress/config.mjs +++ b/docs/.vitepress/config.mjs @@ -86,6 +86,16 @@ export default defineConfig({ link: "http://qgroundcontrol.com/", ariaLabel: "QGC website link", }, + { + text: "Download QGC (stable)", + link: "https://docs.qgroundcontrol.com/master/en/qgc-user-guide/getting_started/download_and_install.html", + ariaLabel: "Download stable QGC", + }, + { + text: "Download QGC (daily build)", + link: "https://docs.qgroundcontrol.com/master/en/qgc-user-guide/releases/daily_builds.html", + ariaLabel: "Download stable QGC", + }, { text: "Source Code", link: "https://github.com/mavlink/qgroundcontrol", @@ -139,7 +149,7 @@ export default defineConfig({ }, { text: "Support", - link: "https://docs.qgroundcontrol.com/master/en/support/support.html", + link: "https://docs.qgroundcontrol.com/master/en/qgc-user-guide/support/support.html", }, { text: "Version", diff --git a/docs/en/qgc-user-guide/index.md b/docs/en/qgc-user-guide/index.md index bc606211e3f..f951d5e482c 100644 --- a/docs/en/qgc-user-guide/index.md +++ b/docs/en/qgc-user-guide/index.md @@ -1,6 +1,6 @@ # QGroundControl User Guide -[![Releases](https://img.shields.io/github/release/mavlink/QGroundControl.svg)](https://github.com/mavlink/QGroundControl/releases) [![Discuss](https://img.shields.io/badge/discuss-px4-ff69b4.svg)](http://discuss.px4.io/c/qgroundcontrol/qgroundcontrol-usage) [![Discuss](https://img.shields.io/badge/discuss-ardupilot-ff69b4.svg)](http://discuss.ardupilot.org/c/ground-control-software/qgroundcontrol) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mavlink/qgroundcontrol?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Slack](../../assets/site/slack.svg)](https://join.slack.com/t/px4/shared_invite/zt-si4xo5qs-R4baYFmMjlrT4rQK5yUnaA) +[![Releases](https://img.shields.io/github/release/mavlink/QGroundControl.svg)](https://github.com/mavlink/QGroundControl/releases) [![Discuss](https://img.shields.io/badge/discuss-px4-ff69b4.svg)](http://discuss.px4.io/c/qgroundcontrol/qgroundcontrol-usage) [![Discuss](https://img.shields.io/badge/discuss-ardupilot-ff69b4.svg)](http://discuss.ardupilot.org/c/ground-control-software/qgroundcontrol) _QGroundControl_ provides full flight control and vehicle setup for PX4 or ArduPilot powered vehicles. It provides easy and straightforward usage for beginners, while still delivering high end feature support for experienced users. From 1cd55296d889f3b201e32a321f5293d70526a649 Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Thu, 13 Jun 2024 08:58:00 +1000 Subject: [PATCH 33/38] Release note restructure (#11613) --- docs/en/SUMMARY.md | 6 +- docs/en/qgc-user-guide/plan_view/plan_view.md | 4 +- .../releases/release_note_stable_v3.md | 559 ++++++++++++++++++ .../releases/release_note_stable_v4.md | 58 ++ .../qgc-user-guide/releases/release_notes.md | 245 +------- .../releases/stable_v3.2_long.md | 265 --------- .../releases/stable_v3.3_long.md | 96 --- .../releases/stable_v4.0_additional.md | 13 - 8 files changed, 623 insertions(+), 623 deletions(-) create mode 100644 docs/en/qgc-user-guide/releases/release_note_stable_v3.md create mode 100644 docs/en/qgc-user-guide/releases/release_note_stable_v4.md delete mode 100644 docs/en/qgc-user-guide/releases/stable_v3.2_long.md delete mode 100644 docs/en/qgc-user-guide/releases/stable_v3.3_long.md delete mode 100644 docs/en/qgc-user-guide/releases/stable_v4.0_additional.md diff --git a/docs/en/SUMMARY.md b/docs/en/SUMMARY.md index 0efead645c6..8742b8706a2 100644 --- a/docs/en/SUMMARY.md +++ b/docs/en/SUMMARY.md @@ -58,14 +58,12 @@ - [MAVLink Inspector](qgc-user-guide/analyze_view/mavlink_inspector.md) - [Releases](qgc-user-guide/releases/index.md) - [Release Notes](qgc-user-guide/releases/release_notes.md) - - [v4.0 (Additional Notes)](qgc-user-guide/releases/stable_v4.0_additional.md) - - [v3.3 (Detailed)](qgc-user-guide/releases/stable_v3.3_long.md) - - [v3.2 (Detailed)](qgc-user-guide/releases/stable_v3.2_long.md) + - [QGC v4 Release Notes](qgc-user-guide/releases/release_note_stable_v4.md) + - [QGC v3 Release Notes](qgc-user-guide/releases/release_note_stable_v3.md) - [Daily Builds](qgc-user-guide/releases/daily_builds.md) - [Daily Build New Features](qgc-user-guide/releases/daily_build_new_features.md) - [Privacy Policy](qgc-user-guide/releases/privacy_policy.md) - [Troubleshooting](qgc-user-guide/troubleshooting/index.md) - - [Setup Problems](qgc-user-guide/troubleshooting/qgc_setup.md) - [Usage Problems](qgc-user-guide/troubleshooting/qgc_usage.md) - [Connection problems](qgc-user-guide/troubleshooting/vehicle_connection.md) diff --git a/docs/en/qgc-user-guide/plan_view/plan_view.md b/docs/en/qgc-user-guide/plan_view/plan_view.md index b93a32585b5..8a57f444384 100644 --- a/docs/en/qgc-user-guide/plan_view/plan_view.md +++ b/docs/en/qgc-user-guide/plan_view/plan_view.md @@ -201,5 +201,5 @@ To analyse this possibility you can turn on [Console Logging](../settings_view/c ## Further Info -- New Plan View features for [QGC release v3.2](../releases/stable_v3.2_long.md#plan_view) -- New Plan View features for [QGC release v3.3](../releases/stable_v3.3_long.md#plan_view) +- New Plan View features for [QGC release v3.2](../qgc-user-guide/releases/release_note_stable_v3.md#plan_view) +- New Plan View features for [QGC release v3.3](../qgc-user-guide/releases/release_note_stable_v3.md#plan-view-1) diff --git a/docs/en/qgc-user-guide/releases/release_note_stable_v3.md b/docs/en/qgc-user-guide/releases/release_note_stable_v3.md new file mode 100644 index 00000000000..4a44d404c44 --- /dev/null +++ b/docs/en/qgc-user-guide/releases/release_note_stable_v3.md @@ -0,0 +1,559 @@ +# QGC v3 Release Notes + +This topic contains the cumulative release notes for _QGroundControl v3.x_. + + +## Stable Version 3.5 + +This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.5. + +- **Overall** + - Added Airmap integration to QGC. OSX build only. + - Bumped settings version (now 8). + This will cause all settings to be reset to defaults. + - Added Chinese and Turkish localization and partial German localization. + - Added support for the Taisync 2.4GHz ViUlinx digital HD wireless link. + - Fix loading of parameters from multiple components. + This especially affected WiFi connections. + - **ArduPilot** Support for ChibiOS firmware connect and flash. +- **Settings** + - **RTK** Add support for specifying fixed RTK based station location in Settings/General. + - **GCS Location** + - Added UDP Port option for NMEA GPS Device. + - GCS heading shown if available +- **Plan** + - **Polygons** Support loading polygons from SHP files. + - **Fixed Wing Landing Pattern** Add stop photo/video support. + Defaults to on such that doing an RTL will stop camera. + - **Edit Position dialog** Available on polygon vertices. +- **Fly** + - **Camera Page** Updated support for new MAVLInk camera messages. + Camera select, camera mode, start/stop photo/video, storage mangement... + - **Orbit** Support for changing rotation direction. + - **Instrument Panel** + - Added ESTIMATOR_STATUS values to new estimatorStatus Vehicle FactGroup. + These are now available to display in instrument panel. + - Make Distance to GCS available for display from instrument panel. + - Make Heading to Home available for display from instrument panel. + +## Stable Version 3.4 + +This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.4. Not to mention the large number of bug fixes in each stable release. + +- **Settings** + - **Offline Maps** + - Center Tool allows you to specify a map location in lat/lon or UTM coordinates. Making it easier to get to the location you want to create an offline map for. + - Ability to pre-download terrain heights for offline use. + - **Help** Provides links to QGC user guide and forums. +- **Setup** + - **Firmware** Ability to flash either PX4 or ArduPilot Flow firmware. + - PX4 Pro Firmware + - **Flight Modes** Specify channels for all available transmitter switches. + - **Tuning: Advanced** Initial implementation of vehicle PID tuning support. Note that this is a work in progress that will improve in 3.5 daily builds. + - ArduPilot Firmware + - **Power/Safety** Support for new multi-battery setup. + - **Trad Heli** New setup page. +- **Plan** + + - **File Load/Save** New model for Plan file loading which matches a standard File Load/Save/Save As user model. + - **Load KML** Ability to load a KML file directly from the Sync menu. You will be prompted for what type of Pattern you want to create from the KML if needed. + - **Survey** Better support for irregular shaped polygons. + - **[Corridor Scan](../plan_view/pattern_corridor_scan.md)** - Create a flight pattern which follows a poly-line. For example can be used to survey a road. + - **[Fixed Wing Landing Pattern](../plan_view/pattern_fixed_wing_landing.md)** + - Landing area visually represented in Plan. + - Landing position/heading can be copied from Vehicle position/heading. + - **Terrain** + + - Height of mission items can be specified as height above terrain. + - Survey and Corridor Scan can generate flight plans which follow terrain. + + ::: info + This feature does not support [ArduPilot terrain following](http://ardupilot.org/copter/docs/common-terrain-following.html). + ::: + + - **Edit Position** Set item position from vehicle position. + +- **Fly** + - **Pre-Flight Checklist** You can turn this on from Settings. It provides a generic checklist to follow prior to flight. Expect more feature to appear for this in 3.5 daily builds. + - **Instrument Panel** + - Many new values available for display. + - New Camera page which provides full camera control. Requires a camera which support new MavLink camera specification. + - **ArduPlane** Much better support for guided commands including QuadPlane support. + - **High Latency Links** Support for high latency links such as satellite connections. + Limits the traffic from QGC up to Vehicle on these links to reduce cost. + Supports HIGH_LATENCY MavLink message. + Supports failover back/forth from high latency to normal link with dual link setup. + +## Stable Version 3.3 (Summary) + +:::tip +More detailed release notes for version 3.3 can be found in the next section. +::: + +This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.3. Not to mention the large number of bug fixes of this release. + +- **Settings** + - Local NMEA GPS device support. + - Video Recording save settings. +- **Setup** + - **Parameter Editor** - Searching updates as you type characters for near immediate response to searches. + - **Joystick** - Android joystick support. +- **Plan** + - **NEW - Structure Scan Pattern** - Create a multi-layered flight pattern that captures images over vertical surfaces (polygonal or circular). Used for 3d model generation or vertical surface inspection. + - **Fixed Wing Landing Pattern** - You can now adjust the distance from the loiter to land point by either distance or glide slope fall rate. + - PX4 GeoFence and Rally Point support. + - Terrain height display in lower Mission Item altitude display +- **Fly** + - Start/Stop video recording. + - Better display of vehicle icons when connected to multiple vehicles. + - Multi-Vehicle View supports commands which apply to all vehicles. + - Displays vehicles reported from ADS-B sensor. +- **Analyze** + - **Mavlink console** - New support for communicating with Mavlink console. + - **Log Download** - Moved from Menu to Analyze view. + + +## Stable Version 3.3 (Detailed) + +### Settings View + +#### NMEA GPS Device support + +![NMEA GPS Device support](../../../assets/settings/general/NMEADevice.jpg) + +You can specify a connection to one of these devices on the General page. +The GPS information will then be used for ground station location and in turn follow me support. + +For more information see [Settings > General (AutoConnect to the following devices)](../settings_view/general.md#auto_connect). + +#### Video Recording + +![Video Recording](../../../assets/settings/video_recording.jpg) + +Videos will be saved to the Video directory of your QGC file save path. +You can also specify the maximum amount of space you want video files to consume. +After that size if exceeded the oldest video files will be removed. +Video Recording is turned on/off from the Video widget in the Fly View. + +For more information see [Settings > General (Video / Video Recording)](../settings_view/general.md#video). + +### Plan View + +#### Structure Scan + +A Structure Scan allows you to create a grid flight pattern that captures images over vertical surfaces (polygonal or circular). +These are typically used for the visual inspection or creation of 3d models of structures. + +Details [here](../plan_view/pattern_structure_scan_v2.md). + +#### New MAVLink GeoFence, Rally Point support + +![](../../../assets/plan/geofence_rally.jpg) + +QGC supports the new MAVLink GeoFence and Rally Point specification/protocol. This new system supports multiple polygonal and/or circular fences which can be specified as an exclusion or an inclusion fence. + +The fence which is currently selected by the "Edit" radio button will show the on screen editing controls such as the drag points for polygon editing. + +**Note** Only PX4 Pro firmware supports the new specification. ArduPilot does not yet support the new spec. Support for GeoFence/Rally is temporarily disabled in QGC until QGC ArduPilot code is reworked to the new architecture. + +#### Edit Position Dialog + +![](../../../assets/plan/edit_position_dialog.jpg) + +The Edit Position Dialog allows you to specify a detailed position for an item in either Geographic or UTM coordinate systems. It is available from the Polygon Tools menu as well as the hamburger menu of any mission item which specifies a coordinate: + +![](../../../assets/plan/mission_item_editor_hamburger.jpg) + +#### Polygon Tools + +![](../../../assets/plan/polygon_tools.jpg) + +You can now also click on the polygon center drag handle to bring up a set of polygon manipulation tools. The tools are available anywhere polygon editing is supported: Survey, Structure Scan, GeoFence, ... + +- Circle - Converts the polygon to a circular polygon. +- Polygon - Changes a circular polygon back to a rectangular polygon. +- Set radius - Set radius for circular polygons. +- Edit position - Displays the edit position dialog to specify a detailed position for the circular center. +- Load KML - Set polygon to polygon loaded from KML file. + +Circular polygon example: + + + +### Fly View + +#### Start/Stop Video Recording + +This is now a video record button in the video window. Settings for saved videos are available from General Page of Setup view. + +#### Multi-Vehicle vehicle indicators + +When you are connected to multiple vehicles the vehicle id will be shown below the vehicle icon. The active vehicle will be opaque and the inactive vehicles will be semi-transparent. + +![](../../../assets/fly/multi_vehicle_indicators.jpg) + +#### Multi-Vehicle View supports batch commands + +The multi-vehicle list now supports commands which apply to all vehicles. + +![](../../../assets/fly/multi_vehicle_list.jpg) + +The current list of available commands are Pause and Start Mission but that will be exapanded upon with further development. + +#### ADS-B sensor vehicle display + +Vehicle reported by ADS-B sensor on vehicle are shown on map as smaller blue icons with altitude and callsign below the icon. + +![](../../../assets/fly/adsb_vehicle.jpg) + +## Stable Version 3.2 (Summary) + +:::tip +More detailed release notes for version 3.2 can be found in the next section. +::: + +This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.2. + +- **Settings** + + - **File Save path** - Specify a save path for all files used by QGC. + - **Telemetry log auto-save** - Telemetry logs are now automatically saved without prompting. + - **AutoLoad Plans** - Used to automatically load a Plan onto a vehicle when it first connects. + - **RTK GPS** - Specify the Survey in accuracy and Minimum observation duration. + +- **Setup** + + - ArduPilot only + - **Pre-Flight Barometer and Airspeed calibration** - Now supported + - **Copy RC Trims** - Now supported + +- **Plan View** + + - **Plan files** - Missions are now saved as .plan files which include the mission, geo-fence and rally points. + - **Plan Toolbar** - New toolbar which shows you mission statistics and Upload button. + - **Mission Start** - Allows you to specify values such as flight speed and camera settings to start the mission with. + - **New Waypoint features** - Adjust heading and flight speed for each waypoint as well as camera settings. + - **Visual Gimbal direction** - Gimbal direction is shown on waypoint indicators. + - **Pattern tool** - Allows you to add complex patterns to a mission. + - Fixed Wing Landing (new) + - Survey (many new features) + - **Fixed Wing Landing Pattern** - Adds a landing pattern for fixed wings to your mission. + - **Survey** - New features + - **Take Images in Turnarounds** - Specify whether to take images through entire survey or just within each transect segment. + - **Hover and Capture** - Stop vehicle at each image location and take photo. + - **Refly at 90 degree offset** - Add additional pattern at 90 degree offset to original so get better image coverage. + - **Entry location** - Specify entry point for survey. + - **Polygon editing** - Simple on screen mechanism to drag, resize, add/remove points. Much better touch support. + +- **Fly View** + + - **Arm/Disarm** - Available from toolbar. + - **Guided Actions** - New action toolbar on the left. Supports: + - Takeoff + - Land + - RTL + - Pause + - Start Mission + - Resume Mission - after battery change + - Change Altitude + - Land Abort + - Set Waypoint + - Goto Location + - **Remove mission after vehicle lands** - Prompt to remove mission from vehicle after landing. + - **Flight Time** - Flight time is shown in instrument panel. + - **Multi-Vehicle View** - Better control of multiple vehicles. + +- **Analyze View** - New + + - **Log Download** - Moved to Analyze view from menu + - **Mavlink Console** - NSH shell access + +- **Support for third-party customized QGroundControl** + - Standard QGC supports multiple firmware types and multiple vehicle types. There is now support in QGC which allows a third-party to create their own custom version of QGC which is targeted specifically to their custom vehicle. They can then release their own version of QGC with their vehicle. + +## Stable Version 3.2 (Detailed) + +This is a more detailed high level (but still _non-exhaustive_) list of new features added to _QGroundControl_ in version 3.2. + +### Settings + +#### Telemetry log auto-save + +If you have _Save telemetry log after each flight_ turned on you will no longer be prompted as to where to save the log each time the vehicle disarms. +Logs will automatically be saved to the [Application Load/Save Path](../settings_view/general.md#load_save_path) + +For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#autosave_log). + +#### AutoLoad plans + +If this setting is turned on, _QGroundControl_ will automatically upload a plan to the vehicle when it connects. +The plan file must be named **AutoLoad#.plan** where the `#` is replaced with the vehicle id. +The plan file must be located in the [Application Load/Save Path](../settings_view/general.md#load_save_path). + +For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#autoload_missions). + +#### Application Load/Save Path + +You can now specify a save path which QGC will use as the default location to save files such as Parameters, Telemetry or Mission Plans. + +For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#load_save_path). + +#### RTK GPS + +You can now specify the _Survey in accuracy_ and _Minimum observation duration_ for use with a connected RTK GPS. + +For more information see [Settings > General (RTK GPS)](../settings_view/general.md#rtk_gps). + +### Setup + +#### ArduPilot - Pre-Flight Barometer and Airspeed calibration + +This is now supported from the Sensors page. + +#### ArduPilot - Copy RC Trims + +This is now supported from the Copy Trims button on the Radio setup page. + +### Plan View + +#### Plan Files + +Previous version of _QGroundControl_ saved missions, geo-fences and rally points in separate files (**.mission**, **.fence**, **.rally**). QGC now save all information related to a flight plan into a single file called a _Plan File_ with a file extension of **.plan**. + +Information about the format can be found in [Plan File Format](../../qgc-dev-guide/file_formats/plan.md) (QGC Developer Guide). + +#### Plan Toolbar + +![Plan Toolbar](../../../assets/plan/plan_toolbar.jpg) + +The new _Plan Toolbar_ is displayed at the top of the [PlanView](../plan_view/plan_view.md). +It shows you information related to the currently selected waypoint as well as statistics for the entire mission. + +When connected to a vehicle it also shows an **Upload** button, which can be used to upload the plan to the vehicle. + +#### Mission Settings + +The [Mission Settings](../plan_view/plan_view.md#mission_settings) panel allows you to specify values which apply to the entire mission, or settings you want to control right at the beginning of a mission. +This is the first item in the mission list on the right of the screen. + + + +##### Mission Defaults + +###### Waypoint alt + +This specifies the default altitude for newly added mission items. +If you update this value while you have a mission loaded it will prompt you to update all the the waypoints to this new altitude. + +###### Flight speed + +This allows you to set the flight speed for the mission to be different than the default mission speed. + +###### RTL after mission end + +Check this if you want your vehicle to RTL after the final mission item. + +##### Camera section + + + +The camera section allows you to specify a camera action to take, control the gimbal and set your camera into photo or video mode. + +The camera actions available are: + +- Continue current action +- Take photos (time) +- Take photos (distance) +- Stop taking photos +- Start recording video +- Stop recording video + +##### Vehicle Info section + + + +When planning a mission the firmware being run on the vehicle as well as the vehicle type must be known in order for QGroundControl to show you the mission commands which are appropriate for your vehicle. + +If you are planning a mission while you are connected to your vehicle the Firmware and Vehicle Type will be determined from the vehicle. If you are planning a mission while not connected to a vehicle you will need to specify this information yourself. + +The additional value that can be specified when planning a mission is the vehicle flight speed. By specifying this value, total mission or survey times can be approximated even when not connected to a vehicle. + +##### Planned Home Position + + + +The planned home position allows you to simulate the vehicle's home position while planning a mission. This way you see the waypoint trajectory for your vehicle from takeoff to mission completion. Keep in mind that this is only the "planned" home position and you should place it where you plan to start the vehicle from. It has no actual impact on flying the mission. The actual home position of a vehicle is set by the vehicle itself when arming. + +#### New Waypoint features + + + +- You can now adjust heading and flight speed for each waypoint. +- There is a camera section available for camera changes on each waypoint. Explanation of Camera Section can be read under Mission Settings above. + +#### Visual Gimbal direction + + + +If you specify gimbal yaw changes on waypoints, both the plan and fly views will show you a visual representation of the gimbal direction. + +#### Pattern tool + +There is a new _Pattern tool_. The following patterns are supported: + +- Fixed Wing Landing (new) +- Survey (with new features) + +##### Fixed Wing Landing Pattern + +![Fixed Wing Landing Pattern](../../../assets/plan/pattern/fixed_wing_landing_pattern.jpg) + +This adds a landing pattern for fixed wings to your mission. +The first point of the pattern is the loiter point which commands to vehicle to loiter to a specific altitude. +Once that altitude is reached, the vehicle will begin the landing sequence and fly down to the specified landing spot. + +Both the loiter and land points can be dragged to adjust. +Also all the various values associated with the pattern can be adjusted. + +For more information see [Fixed Wing Landing Pattern](../plan_view/pattern_fixed_wing_landing.md). + +##### Survey (new features) + +- Images are not automatically taken in the turnaround zone outside of the polygonal survey area. +- There is a new _Hover and Capture_ option which can be used to capture the highest quality image at each image location. The vehicle will stop at each image location prior to taking the image such that the vehicle is stable while the image is taken. +- There is a new option to re-fly the survey grid at a 90 degree angle to the previous pass. This allows you to generate much denser coverage for the images. + +![](../../../assets/plan/polygon_edit.jpg) + +Manipulating the survey area polygon is now easier to use on tablets with touch screens: + +- You can drag the entire polygon to a new location by dragging the center point handle. +- Each polygon vertex can be dragged to a new location. +- To remove a polygon vertex, simple click on the drag handle for it. +- Click on the **+** handles to add a new vertex between two existing vertices. + +### Fly View + +#### RTK GPS + +RTK status is now shown in the toolbar. + +#### Arm/Disarm + +There is an armed/disarmed indicator in the toolbar. You can click it to arm/disarm your vehicle. If you click Disarm in the toolbar while your vehicle is flying you will provided the option to Emergency Stop your vehicle. + +#### Guided Actions + +- Takeoff +- Land +- RTL +- Pause +- Actions + - Start Mission + - Resume Mission + - Change Altitude + - Land Abort +- Direct interaction with map + - Set Waypoint + - Goto Location + +##### Resume Mission + +The Resume Mission guided action is used to resume a mission after performing an RTL from within the mission to perform a battery change. +After the vehicle lands from RTL and you have disconnected the battery **do not** disconnect QGC from the Vehicle. +Put in your new battery and QGC will detect the vehicle again and automatically restore the connection. +Once this happens you will be prompted with a Resume Mission confirmation slider. +If you want to resume the mission, confirm this and the mission will be rebuilt from your last waypoint traveled through. +Once the mission is rebuilt you will be presented with another Resume Mission slide which allows you to review the rebuilt mission before starting it again. +Confirm this Resume Mission slider to continue on with the mission. + +####### How resume mission rebuilding works + +In order to resume a mission you cannot simply continue it from the last mission item the vehicle ran. +The reason is is that may skip over important change speed commands or camera control commands which are prior to that item in the mission. +If you skipped over those the remainder of the mission will not run correctly. +In order to make resume mission work correctly QGC rebuilds the mission looking backwards from the last mission item flown and automatically appends relevant commands to the front of the mission. +By doing this the state of the mission prior to the resume point is restore. +The following mission commands are the ones scanned for: + +- `MAV_CMD_DO_CONTROL_VIDEO` +- `MAV_CMD_DO_SET_ROI` +- `MAV_CMD_DO_DIGICAM_CONFIGURE` +- `MAV_CMD_DO_DIGICAM_CONTROL` +- `MAV_CMD_DO_MOUNT_CONFIGURE` +- `MAV_CMD_DO_MOUNT_CONTROL` +- `MAV_CMD_DO_SET_CAM_TRIGG_DIST` +- `MAV_CMD_DO_FENCE_ENABLE` +- `MAV_CMD_IMAGE_START_CAPTURE` +- `MAV_CMD_IMAGE_STOP_CAPTURE` +- `MAV_CMD_VIDEO_START_CAPTURE` +- `MAV_CMD_VIDEO_STOP_CAPTURE` +- `MAV_CMD_DO_CHANGE_SPEED` +- `MAV_CMD_NAV_TAKEOFF` + +#### Remove mission after vehicle lands + +You will be prompted to remove the mission from the vehicle after the mission completes and the vehicle lands and disarms. +This is meant to prevent issues where stale missions are unknowingly left on a vehicle cause unexpected behavior. + +#### Instrument panel + +##### Camera trigger + +##### Flight Time + +Flight time is now available for display in the instrument panel. +For new users, flight time will be shown by default. +For existing users who have already modified their instrument panel values you will have to add it yourself if you want to use it. + +### [Analyze View](../analyze_view/index.md) + +- [Log Download](../analyze_view/log_download.md) moved to _Analyze View_ from menu. +- New [GeoTag Images](../analyze_view/geotag_images.md) support for PX4 Pro firmware +- New [MAVLink Console](../analyze_view/mavlink_console.md) which provides access the the _nsh shell_ running on the vehicle. + +### Multi-Vehicle View + +There is a new view available when you have multiple vehicles connected to QGC. It will only show up when more than one vehicle is connected. When that happens you will see an additional set of radio button at the top right of the Plan view. + + + +Click the **Multi-Vehicle** radio button to replace the instrument panel with the multi-vehicle list: + + + +The example above shows three vehicles. The numbers are the vehicle id. In the large font is the current flight mode. You can click the flight mode name to change to a different flight mode. To the right are small version of the instruments for each vehicle. You can command the vehicle to do the following actions from the control panel: + +- Arm/Disarm +- Start/Stop a mission +- Return to Launch +- Take Control back of the vehicle by returning to manual control from a mission. + +#### Multi-Vehicle Gotchas - Unique vehicle ids + +Each vehicle connected to QGC must have a unique id. Otherwise QGC will think the vehicles are actually the same vehicle. The symptom of this is the Plan view jerking around as it tries to position itself to one vehicle and then the next. For PX4 Pro firmwares this is the `MAV_SYS_ID` parameter. For ArduPilot firmwares it is the `SYSID_THISMAV` parameter. + +### Support for third-party customized QGroundControl + +Standard QGC supports multiple firmware types and multiple vehicle types. There is now support in QGC which allows a third-party to create their own custom version of QGC which is targeted specifically to their custom vehicle. They can then release their own version of QGC with their vehicle. + +## Stable Version 3.1 + +New Features + +- [Survey](../plan_view/pattern_survey.md) mission support +- [GeoFence](../plan_view/plan_geofence.md) support in Plan View +- [Rally Point](../plan_view/plan_rally_points.md) support in Plan View (ArduPilot only) +- ArduPilot onboard compass calibration +- Parameter editor search will now search as you type for quicker access +- Parameter display now supports unit conversion +- GeoTag images from log files (PX4 only) +- System health in instrument panel +- MAVLink 2.0 support (no signing yet) + +Major Bug Fixes + +- Fixed crash after disconnect from Vehicle +- Fixed android crash when using SiK Radios +- Many multi-vehicle fixes +- Bluetooth fixes diff --git a/docs/en/qgc-user-guide/releases/release_note_stable_v4.md b/docs/en/qgc-user-guide/releases/release_note_stable_v4.md new file mode 100644 index 00000000000..ac488b0de80 --- /dev/null +++ b/docs/en/qgc-user-guide/releases/release_note_stable_v4.md @@ -0,0 +1,58 @@ +# QGC v4 Release Notes + +::: warning +Release notes are now tracked in the [Github release page](https://github.com/mavlink/qgroundcontrol/releases). +See that page for information about changes after v4.0.0. +::: + +## Stable Version 4.0 + +::: info +The format for Settings in QGC had to change in this release. Which means all QGC settings will be reset to defaults. +::: + +- Settings + - Language: Allow selection of language + - Optional [CSV Logging](../settings_view/csv.md) of telemetry data for improved accessibility. + - ArduPilot + - Support configurable mavlink stream rates. Available from Settings/Mavlink page. + ![Stream Rates JPG](../../../assets/daily_build_changes/arducopter_stream_rates.jpg) + - Improved support for flashing ChibiOS firmware + - Improved support for connecting to ChibiOS bootloader boards +- Setup + - Joystick + - New joystick setup ui + - Ability to configure held button to single or repeated action + - ArduPilot + - Motor Test + - ArduSub + - Automatic motor direction detection + - ArduCopter + - PID Tuning support ![PID Tuning JPG](../../../assets/daily_build_changes/arducopter_pid_tuning.jpg) + - Additional Basic Tuning options ![Basic Tuning JPG](../../../assets/daily_build_changes/arducopter_basic_tuning.jpg) + - Copter/Rover - Frame setup ui ![Setup Frame Copter JPG](../../../assets/daily_build_changes/arducopter_setup_frame.jpg) +- Plan + - Create Plan from template with wizard like progression for completing full Plan. + - Survey: Save commonly used settings as a Preset + - Polygon editing + - New editing tools ui + - Support for tracing a polygon from map locations + - ArduPilot + - Support for GeoFence and Rally Points using latest firmwares and mavlink v2 + - [Pattern Presets](../plan_view/pattern_presets.md) + - Allows you to save settings for a Pattern item (Survey, Corridor Scan, ...) into a named preset. You can then use this preset over and over again as you create new Pattern. +- Fly + - Click to ROI support + - Added support for connecting to ADSB SBS server. Adds support for ADSB data from USB SDR Dongle running 'dump1090 --net' for example. + - Ability to turn on Heading to home, COG and Next Waypoint heading indicators in Compass. + - Video + - Add support for h.265 video streams + - Automatically add a [Video Overlay](../fly_view/video_overlay.md) with flight data as a subtitle for locally-recorded videos + - Vehicle type specific pre-flight checklists. Turn on from Settings. +- Analyze + - New Mavlink Inspector which includes charting support. Supported on all builds including Android and iOS. +- General + - Released Windows build are now 64 bit only + - Log Replay: Ability to specify replay speed + - ArduPilot + - Improved support for chibios firmwares and ArduPilot bootloader with respect to flashing and auto-connect. diff --git a/docs/en/qgc-user-guide/releases/release_notes.md b/docs/en/qgc-user-guide/releases/release_notes.md index b108169b5cc..c37c85ee1d5 100644 --- a/docs/en/qgc-user-guide/releases/release_notes.md +++ b/docs/en/qgc-user-guide/releases/release_notes.md @@ -1,248 +1,7 @@ # Release Notes -This topic contains the cumulative release notes for _QGroundControl_. +Releases and their associated release notes can be found in the [Github releases page](https://github.com/mavlink/qgroundcontrol/releases). ::: info -Stable build major/minor numbers are listed below. -_Patch_ release numbers are not listed, but can be found on the [Github release page](https://github.com/mavlink/qgroundcontrol/releases). +Release information about QGC v4.0.0 and earlier can be found in the sub pages. ::: - -## Stable Version 4.0 (current) - -::: info -The format for Settings in QGC had to change in this release. Which means all QGC settings will be reset to defaults. -::: - -- Settings - - Language: Allow selection of language - - Optional [CSV Logging](../settings_view/csv.md) of telemetry data for improved accessibility. - - ArduPilot - - Mavlink: Configurable stream rate settings -- Setup - - Joystick - - New joystick setup ui - - Ability to configure held button to single or repeated action - - ArduPilot - - Motor Test - - ArduSub - - Automatic motor direction detection -- Plan - - Create Plan from template with wizard like progression for completing full Plan. - - Survey: Save commonly used settings as a Preset - - Polygon editing - - New editing tools ui - - Support for tracing a polygon from map locations - - ArduPilot - - Support for GeoFence and Rally Points using latest firmwares and mavlink v2 -- Fly - - Click to ROI support - - Added support for connecting to ADSB SBS server. Adds support for ADSB data from USB SDR Dongle running 'dump1090 --net' for example. - - Ability to turn on Heading to home, COG and Next Waypoint heading indicators in Compass. - - Video - - Add support for h.265 video streams - - Automatically add a [Video Overlay](../fly_view/video_overlay.md) with flight data as a subtitle for locally-recorded videos - - Vehicle type specific pre-flight checklists. Turn on from Settings. -- Analyze - - New Mavlink Inspector which includes charting support. Supported on all builds including Android and iOS. -- General - - Released Windows build are now 64 bit only - - Log Replay: Ability to specify replay speed - - ArduPilot - - Improved support for chibios firmwares and ArduPilot bootloader with respect to flashing and auto-connect. - -Additional notes for some features can be found here: [v4.0 (Additional Notes)](../releases/stable_v4.0_additional.md). - -## Stable Version 3.5 - -This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.5. - -- **Overall** - - Added Airmap integration to QGC. OSX build only. - - Bumped settings version (now 8). - This will cause all settings to be reset to defaults. - - Added Chinese and Turkish localization and partial German localization. - - Added support for the Taisync 2.4GHz ViUlinx digital HD wireless link. - - Fix loading of parameters from multiple components. - This especially affected WiFi connections. - - **ArduPilot** Support for ChibiOS firmware connect and flash. -- **Settings** - - **RTK** Add support for specifying fixed RTK based station location in Settings/General. - - **GCS Location** - - Added UDP Port option for NMEA GPS Device. - - GCS heading shown if available -- **Plan** - - **Polygons** Support loading polygons from SHP files. - - **Fixed Wing Landing Pattern** Add stop photo/video support. - Defaults to on such that doing an RTL will stop camera. - - **Edit Position dialog** Available on polygon vertices. -- **Fly** - - **Camera Page** Updated support for new MAVLInk camera messages. - Camera select, camera mode, start/stop photo/video, storage mangement... - - **Orbit** Support for changing rotation direction. - - **Instrument Panel** - - Added ESTIMATOR_STATUS values to new estimatorStatus Vehicle FactGroup. - These are now available to display in instrument panel. - - Make Distance to GCS available for display from instrument panel. - - Make Heading to Home available for display from instrument panel. - -## Stable Version 3.4 - -This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.4. Not to mention the large number of bug fixes in each stable release. - -- **Settings** - - **Offline Maps** - - Center Tool allows you to specify a map location in lat/lon or UTM coordinates. Making it easier to get to the location you want to create an offline map for. - - Ability to pre-download terrain heights for offline use. - - **Help** Provides links to QGC user guide and forums. -- **Setup** - - **Firmware** Ability to flash either PX4 or ArduPilot Flow firmware. - - PX4 Pro Firmware - - **Flight Modes** Specify channels for all available transmitter switches. - - **Tuning: Advanced** Initial implementation of vehicle PID tuning support. Note that this is a work in progress that will improve in 3.5 daily builds. - - ArduPilot Firmware - - **Power/Safety** Support for new multi-battery setup. - - **Trad Heli** New setup page. -- **Plan** - - - **File Load/Save** New model for Plan file loading which matches a standard File Load/Save/Save As user model. - - **Load KML** Ability to load a KML file directly from the Sync menu. You will be prompted for what type of Pattern you want to create from the KML if needed. - - **Survey** Better support for irregular shaped polygons. - - **[Corridor Scan](../plan_view/pattern_corridor_scan.md)** - Create a flight pattern which follows a poly-line. For example can be used to survey a road. - - **[Fixed Wing Landing Pattern](../plan_view/pattern_fixed_wing_landing.md)** - - Landing area visually represented in Plan. - - Landing position/heading can be copied from Vehicle position/heading. - - **Terrain** - - - Height of mission items can be specified as height above terrain. - - Survey and Corridor Scan can generate flight plans which follow terrain. - - ::: info - This feature does not support [ArduPilot terrain following](http://ardupilot.org/copter/docs/common-terrain-following.html). - ::: - - - **Edit Position** Set item position from vehicle position. - -- **Fly** - - **Pre-Flight Checklist** You can turn this on from Settings. It provides a generic checklist to follow prior to flight. Expect more feature to appear for this in 3.5 daily builds. - - **Instrument Panel** - - Many new values available for display. - - New Camera page which provides full camera control. Requires a camera which support new MavLink camera specification. - - **ArduPlane** Much better support for guided commands including QuadPlane support. - - **High Latency Links** Support for high latency links such as satellite connections. - Limits the traffic from QGC up to Vehicle on these links to reduce cost. - Supports HIGH_LATENCY MavLink message. - Supports failover back/forth from high latency to normal link with dual link setup. - -## Stable Version 3.3 - -:::tip -More detailed release notes for version 3.3 can be found [here](../releases/stable_v3.3_long.md). -::: - -This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.3. Not to mention the large number of bug fixes of this release. - -- **Settings** - - Local NMEA GPS device support. - - Video Recording save settings. -- **Setup** - - **Parameter Editor** - Searching updates as you type characters for near immediate response to searches. - - **Joystick** - Android joystick support. -- **Plan** - - **NEW - Structure Scan Pattern** - Create a multi-layered flight pattern that captures images over vertical surfaces (polygonal or circular). Used for 3d model generation or vertical surface inspection. - - **Fixed Wing Landing Pattern** - You can now adjust the distance from the loiter to land point by either distance or glide slope fall rate. - - PX4 GeoFence and Rally Point support. - - Terrain height display in lower Mission Item altitude display -- **Fly** - - Start/Stop video recording. - - Better display of vehicle icons when connected to multiple vehicles. - - Multi-Vehicle View supports commands which apply to all vehicles. - - Displays vehicles reported from ADS-B sensor. -- **Analyze** - - **Mavlink console** - New support for communicating with Mavlink console. - - **Log Download** - Moved from Menu to Analyze view. - -## Stable Version 3.2 - -:::tip -More detailed release notes for version 3.2 can be found [here](../releases/stable_v3.2_long.md). -::: - -This section contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.2. - -- **Settings** - - - **File Save path** - Specify a save path for all files used by QGC. - - **Telemetry log auto-save** - Telemetry logs are now automatically saved without prompting. - - **AutoLoad Plans** - Used to automatically load a Plan onto a vehicle when it first connects. - - **RTK GPS** - Specify the Survey in accuracy and Minimum observation duration. - -- **Setup** - - - ArduPilot only - - **Pre-Flight Barometer and Airspeed calibration** - Now supported - - **Copy RC Trims** - Now supported - -- **Plan View** - - - **Plan files** - Missions are now saved as .plan files which include the mission, geo-fence and rally points. - - **Plan Toolbar** - New toolbar which shows you mission statistics and Upload button. - - **Mission Start** - Allows you to specify values such as flight speed and camera settings to start the mission with. - - **New Waypoint features** - Adjust heading and flight speed for each waypoint as well as camera settings. - - **Visual Gimbal direction** - Gimbal direction is shown on waypoint indicators. - - **Pattern tool** - Allows you to add complex patterns to a mission. - - Fixed Wing Landing (new) - - Survey (many new features) - - **Fixed Wing Landing Pattern** - Adds a landing pattern for fixed wings to your mission. - - **Survey** - New features - - **Take Images in Turnarounds** - Specify whether to take images through entire survey or just within each transect segment. - - **Hover and Capture** - Stop vehicle at each image location and take photo. - - **Refly at 90 degree offset** - Add additional pattern at 90 degree offset to original so get better image coverage. - - **Entry location** - Specify entry point for survey. - - **Polygon editing** - Simple on screen mechanism to drag, resize, add/remove points. Much better touch support. - -- **Fly View** - - - **Arm/Disarm** - Available from toolbar. - - **Guided Actions** - New action toolbar on the left. Supports: - - Takeoff - - Land - - RTL - - Pause - - Start Mission - - Resume Mission - after battery change - - Change Altitude - - Land Abort - - Set Waypoint - - Goto Location - - **Remove mission after vehicle lands** - Prompt to remove mission from vehicle after landing. - - **Flight Time** - Flight time is shown in instrument panel. - - **Multi-Vehicle View** - Better control of multiple vehicles. - -- **Analyze View** - New - - - **Log Download** - Moved to Analyze view from menu - - **Mavlink Console** - NSH shell access - -- **Support for third-party customized QGroundControl** - - Standard QGC supports multiple firmware types and multiple vehicle types. There is now support in QGC which allows a third-party to create their own custom version of QGC which is targeted specifically to their custom vehicle. They can then release their own version of QGC with their vehicle. - -## Stable Version 3.1 - -New Features - -- [Survey](../plan_view/pattern_survey.md) mission support -- [GeoFence](../plan_view/plan_geofence.md) support in Plan View -- [Rally Point](../plan_view/plan_rally_points.md) support in Plan View (ArduPilot only) -- ArduPilot onboard compass calibration -- Parameter editor search will now search as you type for quicker access -- Parameter display now supports unit conversion -- GeoTag images from log files (PX4 only) -- System health in instrument panel -- MAVLink 2.0 support (no signing yet) - -Major Bug Fixes - -- Fixed crash after disconnect from Vehicle -- Fixed android crash when using SiK Radios -- Many multi-vehicle fixes -- Bluetooth fixes diff --git a/docs/en/qgc-user-guide/releases/stable_v3.2_long.md b/docs/en/qgc-user-guide/releases/stable_v3.2_long.md deleted file mode 100644 index bc3b1a04b57..00000000000 --- a/docs/en/qgc-user-guide/releases/stable_v3.2_long.md +++ /dev/null @@ -1,265 +0,0 @@ -# QGroundControl v3.2 Release Notes (Detailed) - -This topic contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.2. - -## Settings - -### Telemetry log auto-save - -If you have _Save telemetry log after each flight_ turned on you will no longer be prompted as to where to save the log each time the vehicle disarms. -Logs will automatically be saved to the [Application Load/Save Path](../settings_view/general.md#load_save_path) - -For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#autosave_log). - -### AutoLoad plans - -If this setting is turned on, _QGroundControl_ will automatically upload a plan to the vehicle when it connects. -The plan file must be named **AutoLoad#.plan** where the `#` is replaced with the vehicle id. -The plan file must be located in the [Application Load/Save Path](../settings_view/general.md#load_save_path). - -For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#autoload_missions). - -### Application Load/Save Path - -You can now specify a save path which QGC will use as the default location to save files such as Parameters, Telemetry or Mission Plans. - -For more information see [Settings > General (Miscellaneous)](../settings_view/general.md#load_save_path). - -### RTK GPS - -You can now specify the _Survey in accuracy_ and _Minimum observation duration_ for use with a connected RTK GPS. - -For more information see [Settings > General (RTK GPS)](../settings_view/general.md#rtk_gps). - -## Setup - -### ArduPilot - Pre-Flight Barometer and Airspeed calibration - -This is now supported from the Sensors page. - -### ArduPilot - Copy RC Trims - -This is now supported from the Copy Trims button on the Radio setup page. - -## Plan View {#plan_view} - -### Plan Files - -Previous version of _QGroundControl_ saved missions, geo-fences and rally points in separate files (**.mission**, **.fence**, **.rally**). QGC now save all information related to a flight plan into a single file called a _Plan File_ with a file extension of **.plan**. - -Information about the format can be found in [Plan File Format](../../qgc-dev-guide/file_formats/plan.md) (QGC Developer Guide). - -### Plan Toolbar - -![Plan Toolbar](../../../assets/plan/plan_toolbar.jpg) - -The new _Plan Toolbar_ is displayed at the top of the [PlanView](../plan_view/plan_view.md). -It shows you information related to the currently selected waypoint as well as statistics for the entire mission. - -When connected to a vehicle it also shows an **Upload** button, which can be used to upload the plan to the vehicle. - -### Mission Settings - -The [Mission Settings](../plan_view/plan_view.md#mission_settings) panel allows you to specify values which apply to the entire mission, or settings you want to control right at the beginning of a mission. -This is the first item in the mission list on the right of the screen. - - - -#### Mission Defaults - -##### Waypoint alt - -This specifies the default altitude for newly added mission items. -If you update this value while you have a mission loaded it will prompt you to update all the the waypoints to this new altitude. - -##### Flight speed - -This allows you to set the flight speed for the mission to be different than the default mission speed. - -##### RTL after mission end - -Check this if you want your vehicle to RTL after the final mission item. - -#### Camera section - - - -The camera section allows you to specify a camera action to take, control the gimbal and set your camera into photo or video mode. - -The camera actions available are: - -- Continue current action -- Take photos (time) -- Take photos (distance) -- Stop taking photos -- Start recording video -- Stop recording video - -#### Vehicle Info section - - - -When planning a mission the firmware being run on the vehicle as well as the vehicle type must be known in order for QGroundControl to show you the mission commands which are appropriate for your vehicle. - -If you are planning a mission while you are connected to your vehicle the Firmware and Vehicle Type will be determined from the vehicle. If you are planning a mission while not connected to a vehicle you will need to specify this information yourself. - -The additional value that can be specified when planning a mission is the vehicle flight speed. By specifying this value, total mission or survey times can be approximated even when not connected to a vehicle. - -#### Planned Home Position - - - -The planned home position allows you to simulate the vehicle's home position while planning a mission. This way you see the waypoint trajectory for your vehicle from takeoff to mission completion. Keep in mind that this is only the "planned" home position and you should place it where you plan to start the vehicle from. It has no actual impact on flying the mission. The actual home position of a vehicle is set by the vehicle itself when arming. - -### New Waypoint features - - - -- You can now adjust heading and flight speed for each waypoint. -- There is a camera section available for camera changes on each waypoint. Explanation of Camera Section can be read under Mission Settings above. - -### Visual Gimbal direction - - - -If you specify gimbal yaw changes on waypoints, both the plan and fly views will show you a visual representation of the gimbal direction. - -### Pattern tool - -There is a new _Pattern tool_. The following patterns are supported: - -- Fixed Wing Landing (new) -- Survey (with new features) - -#### Fixed Wing Landing Pattern - -![Fixed Wing Landing Pattern](../../../assets/plan/pattern/fixed_wing_landing_pattern.jpg) - -This adds a landing pattern for fixed wings to your mission. -The first point of the pattern is the loiter point which commands to vehicle to loiter to a specific altitude. -Once that altitude is reached, the vehicle will begin the landing sequence and fly down to the specified landing spot. - -Both the loiter and land points can be dragged to adjust. -Also all the various values associated with the pattern can be adjusted. - -For more information see [Fixed Wing Landing Pattern](../plan_view/pattern_fixed_wing_landing.md). - -#### Survey (new features) - -- Images are not automatically taken in the turnaround zone outside of the polygonal survey area. -- There is a new _Hover and Capture_ option which can be used to capture the highest quality image at each image location. The vehicle will stop at each image location prior to taking the image such that the vehicle is stable while the image is taken. -- There is a new option to re-fly the survey grid at a 90 degree angle to the previous pass. This allows you to generate much denser coverage for the images. - -![](../../../assets/plan/polygon_edit.jpg) - -Manipulating the survey area polygon is now easier to use on tablets with touch screens: - -- You can drag the entire polygon to a new location by dragging the center point handle. -- Each polygon vertex can be dragged to a new location. -- To remove a polygon vertex, simple click on the drag handle for it. -- Click on the **+** handles to add a new vertex between two existing vertices. - -## Fly View - -### RTK GPS - -RTK status is now shown in the toolbar. - -### Arm/Disarm - -There is an armed/disarmed indicator in the toolbar. You can click it to arm/disarm your vehicle. If you click Disarm in the toolbar while your vehicle is flying you will provided the option to Emergency Stop your vehicle. - -### Guided Actions - -- Takeoff -- Land -- RTL -- Pause -- Actions - - Start Mission - - Resume Mission - - Change Altitude - - Land Abort -- Direct interaction with map - - Set Waypoint - - Goto Location - -#### Resume Mission - -The Resume Mission guided action is used to resume a mission after performing an RTL from within the mission to perform a battery change. -After the vehicle lands from RTL and you have disconnected the battery **do not** disconnect QGC from the Vehicle. -Put in your new battery and QGC will detect the vehicle again and automatically restore the connection. -Once this happens you will be prompted with a Resume Mission confirmation slider. -If you want to resume the mission, confirm this and the mission will be rebuilt from your last waypoint traveled through. -Once the mission is rebuilt you will be presented with another Resume Mission slide which allows you to review the rebuilt mission before starting it again. -Confirm this Resume Mission slider to continue on with the mission. - -###### How resume mission rebuilding works - -In order to resume a mission you cannot simply continue it from the last mission item the vehicle ran. -The reason is is that may skip over important change speed commands or camera control commands which are prior to that item in the mission. -If you skipped over those the remainder of the mission will not run correctly. -In order to make resume mission work correctly QGC rebuilds the mission looking backwards from the last mission item flown and automatically appends relevant commands to the front of the mission. -By doing this the state of the mission prior to the resume point is restore. -The following mission commands are the ones scanned for: - -- `MAV_CMD_DO_CONTROL_VIDEO` -- `MAV_CMD_DO_SET_ROI` -- `MAV_CMD_DO_DIGICAM_CONFIGURE` -- `MAV_CMD_DO_DIGICAM_CONTROL` -- `MAV_CMD_DO_MOUNT_CONFIGURE` -- `MAV_CMD_DO_MOUNT_CONTROL` -- `MAV_CMD_DO_SET_CAM_TRIGG_DIST` -- `MAV_CMD_DO_FENCE_ENABLE` -- `MAV_CMD_IMAGE_START_CAPTURE` -- `MAV_CMD_IMAGE_STOP_CAPTURE` -- `MAV_CMD_VIDEO_START_CAPTURE` -- `MAV_CMD_VIDEO_STOP_CAPTURE` -- `MAV_CMD_DO_CHANGE_SPEED` -- `MAV_CMD_NAV_TAKEOFF` - -### Remove mission after vehicle lands - -You will be prompted to remove the mission from the vehicle after the mission completes and the vehicle lands and disarms. -This is meant to prevent issues where stale missions are unknowingly left on a vehicle cause unexpected behavior. - -### Instrument panel - -#### Camera trigger - -#### Flight Time - -Flight time is now available for display in the instrument panel. -For new users, flight time will be shown by default. -For existing users who have already modified their instrument panel values you will have to add it yourself if you want to use it. - -## [Analyze View](../analyze_view/index.md) - -- [Log Download](../analyze_view/log_download.md) moved to _Analyze View_ from menu. -- New [GeoTag Images](../analyze_view/geotag_images.md) support for PX4 Pro firmware -- New [MAVLink Console](../analyze_view/mavlink_console.md) which provides access the the _nsh shell_ running on the vehicle. - -## Multi-Vehicle View - -There is a new view available when you have multiple vehicles connected to QGC. It will only show up when more than one vehicle is connected. When that happens you will see an additional set of radio button at the top right of the Plan view. - - - -Click the **Multi-Vehicle** radio button to replace the instrument panel with the multi-vehicle list: - - - -The example above shows three vehicles. The numbers are the vehicle id. In the large font is the current flight mode. You can click the flight mode name to change to a different flight mode. To the right are small version of the instruments for each vehicle. You can command the vehicle to do the following actions from the control panel: - -- Arm/Disarm -- Start/Stop a mission -- Return to Launch -- Take Control back of the vehicle by returning to manual control from a mission. - -### Multi-Vehicle Gotchas - Unique vehicle ids - -Each vehicle connected to QGC must have a unique id. Otherwise QGC will think the vehicles are actually the same vehicle. The symptom of this is the Plan view jerking around as it tries to position itself to one vehicle and then the next. For PX4 Pro firmwares this is the `MAV_SYS_ID` parameter. For ArduPilot firmwares it is the `SYSID_THISMAV` parameter. - -## Support for third-party customized QGroundControl - -Standard QGC supports multiple firmware types and multiple vehicle types. There is now support in QGC which allows a third-party to create their own custom version of QGC which is targeted specifically to their custom vehicle. They can then release their own version of QGC with their vehicle. diff --git a/docs/en/qgc-user-guide/releases/stable_v3.3_long.md b/docs/en/qgc-user-guide/releases/stable_v3.3_long.md deleted file mode 100644 index 4d48878d9e6..00000000000 --- a/docs/en/qgc-user-guide/releases/stable_v3.3_long.md +++ /dev/null @@ -1,96 +0,0 @@ -# QGroundControl v3.3 Release Notes (Detailed) - -This topic contains a high level and _non-exhaustive_ list of new features added to _QGroundControl_ in version 3.3. - -## Detailed Notes - -### Settings View - -#### NMEA GPS Device support - -![NMEA GPS Device support](../../../assets/settings/general/NMEADevice.jpg) - -You can specify a connection to one of these devices on the General page. -The GPS information will then be used for ground station location and in turn follow me support. - -For more information see [Settings > General (AutoConnect to the following devices)](../settings_view/general.md#auto_connect). - -#### Video Recording - -![Video Recording](../../../assets/settings/video_recording.jpg) - -Videos will be saved to the Video directory of your QGC file save path. -You can also specify the maximum amount of space you want video files to consume. -After that size if exceeded the oldest video files will be removed. -Video Recording is turned on/off from the Video widget in the Fly View. - -For more information see [Settings > General (Video / Video Recording)](../settings_view/general.md#video). - -### Plan View {#plan_view} - -#### Structure Scan - -A Structure Scan allows you to create a grid flight pattern that captures images over vertical surfaces (polygonal or circular). -These are typically used for the visual inspection or creation of 3d models of structures. - -Details [here](../plan_view/pattern_structure_scan_v2.md). - -#### New MAVLink GeoFence, Rally Point support - -![](../../../assets/plan/geofence_rally.jpg) - -QGC supports the new MAVLink GeoFence and Rally Point specification/protocol. This new system supports multiple polygonal and/or circular fences which can be specified as an exclusion or an inclusion fence. - -The fence which is currently selected by the "Edit" radio button will show the on screen editing controls such as the drag points for polygon editing. - -**Note** Only PX4 Pro firmware supports the new specification. ArduPilot does not yet support the new spec. Support for GeoFence/Rally is temporarily disabled in QGC until QGC ArduPilot code is reworked to the new architecture. - -#### Edit Position Dialog - -![](../../../assets/plan/edit_position_dialog.jpg) - -The Edit Position Dialog allows you to specify a detailed position for an item in either Geographic or UTM coordinate systems. It is available from the Polygon Tools menu as well as the hamburger menu of any mission item which specifies a coordinate: - -![](../../../assets/plan/mission_item_editor_hamburger.jpg) - -#### Polygon Tools - -![](../../../assets/plan/polygon_tools.jpg) - -You can now also click on the polygon center drag handle to bring up a set of polygon manipulation tools. The tools are available anywhere polygon editing is supported: Survey, Structure Scan, GeoFence, ... - -- Circle - Converts the polygon to a circular polygon. -- Polygon - Changes a circular polygon back to a rectangular polygon. -- Set radius - Set radius for circular polygons. -- Edit position - Displays the edit position dialog to specify a detailed position for the circular center. -- Load KML - Set polygon to polygon loaded from KML file. - -Circular polygon example: - - - -### Fly View - -#### Start/Stop Video Recording - -This is now a video record button in the video window. Settings for saved videos are available from General Page of Setup view. - -#### Multi-Vehicle vehicle indicators - -When you are connected to multiple vehicles the vehicle id will be shown below the vehicle icon. The active vehicle will be opaque and the inactive vehicles will be semi-transparent. - -![](../../../assets/fly/multi_vehicle_indicators.jpg) - -#### Multi-Vehicle View supports batch commands - -The multi-vehicle list now supports commands which apply to all vehicles. - -![](../../../assets/fly/multi_vehicle_list.jpg) - -The current list of available commands are Pause and Start Mission but that will be exapanded upon with further development. - -#### ADS-B sensor vehicle display - -Vehicle reported by ADS-B sensor on vehicle are shown on map as smaller blue icons with altitude and callsign below the icon. - -![](../../../assets/fly/adsb_vehicle.jpg) diff --git a/docs/en/qgc-user-guide/releases/stable_v4.0_additional.md b/docs/en/qgc-user-guide/releases/stable_v4.0_additional.md deleted file mode 100644 index 9399f0d3702..00000000000 --- a/docs/en/qgc-user-guide/releases/stable_v4.0_additional.md +++ /dev/null @@ -1,13 +0,0 @@ -# QGroundControl v4.0 Release Notes (Additional) - -This topic contains additional notes about QGroundControl 4.0. -These should be integrated into main documentation in coming months (and this document deleted). - -- [Pattern Presets](../plan_view/pattern_presets.md) - Allows you to save settings for a Pattern item (Survey, Corridor Scan, ...) into a named preset. You can then use this preset over and over again as you create new Pattern. -- ArduPilot: - - Copter - PID Tuning support ![PID Tuning JPG](../../../assets/daily_build_changes/arducopter_pid_tuning.jpg) - - Copter - Additional Basic Tuning options ![Basic Tuning JPG](../../../assets/daily_build_changes/arducopter_basic_tuning.jpg) - - Copter/Rover - Frame setup ui ![Setup Frame Copter JPG](../../../assets/daily_build_changes/arducopter_setup_frame.jpg) - - Improved support for flashing ChibiOS firmware - - Improved support for connecting to ChibiOS bootloader boards - - Support configurable mavlink stream rates. Available from Settings/Mavlink page. ![Stream Rates JPG](../../../assets/daily_build_changes/arducopter_stream_rates.jpg) From 49424a35c5337391e41c1cd1e7bbd4b7ee7bc330 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Fri, 14 Jun 2024 13:25:09 +0000 Subject: [PATCH 34/38] Update PX4 Firmware metadata Fri Jun 14 13:25:09 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index 1217ea8dec3..f57ba78e5f5 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -712,18 +712,6 @@ 2 0.01 - - This parameter is deprecated. Please use BAT1_N_CELLS instead - - - This parameter is deprecated. Please use BAT1_V_CHARGED instead - - - This parameter is deprecated. Please use BAT1_V_EMPTY instead - - - This parameter is deprecated. Please use BAT1_V_LOAD_DROP instead - Offset in volt as seen by the ADC input of the current sensor This offset will be subtracted before calculating the battery current based on the voltage. From 5ecc4cacc2a2e70522e30afc1347f2f042c8dbc1 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Mon, 17 Jun 2024 19:48:36 +0000 Subject: [PATCH 35/38] Update PX4 Firmware metadata Mon Jun 17 19:48:36 UTC 2024 --- .../PX4/PX4ParameterFactMetaData.xml | 140 ------------------ 1 file changed, 140 deletions(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index f57ba78e5f5..e0977719664 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -2753,7 +2753,6 @@ Emlid Reach Femtomes NMEA (generic) - Septentrio (SBF) @@ -2798,15 +2797,6 @@ RTCM output (PPK) - - Pitch offset for dual antenna GPS - Vertical offsets can be compensated for by adjusting the Pitch offset (Septentrio). Note that this can be interpreted as the "roll" angle in case the antennas are aligned along the perpendicular axis. This occurs in situations where the two antenna ARPs may not be exactly at the same height in the vehicle reference frame. Since pitch is defined as the right-handed rotation about the vehicle Y axis, a situation where the main antenna is mounted lower than the aux antenna (assuming the default antenna setup) will result in a positive pitch. - -90 - 90 - deg - 3 - true - Enable sat info (if available) Enable publication of satellite info (ORB_ID(satellite_info)) if possible. Not available on MTK. @@ -6085,32 +6075,6 @@ -1 1 - - Acro switch channel (deprecated) - 0 - 18 - - Unassigned - Channel 1 - Channel 2 - Channel 3 - Channel 4 - Channel 5 - Channel 6 - Channel 7 - Channel 8 - Channel 9 - Channel 10 - Channel 11 - Channel 12 - Channel 13 - Channel 14 - Channel 15 - Channel 16 - Channel 17 - Channel 18 - - Arm switch channel Use it to arm/disarm via switch instead of default throttle stick. If this is assigned, arming and disarming via stick is disabled. @@ -6295,32 +6259,6 @@ Channel 18 - - Manual switch channel mapping (deprecated) - 0 - 18 - - Unassigned - Channel 1 - Channel 2 - Channel 3 - Channel 4 - Channel 5 - Channel 6 - Channel 7 - Channel 8 - Channel 9 - Channel 10 - Channel 11 - Channel 12 - Channel 13 - Channel 14 - Channel 15 - Channel 16 - Channel 17 - Channel 18 - - Mode switch channel mapping (deprecated) This is the main flight mode selector. The channel index (starting from 1 for channel 1) indicates which channel should be used for deciding about the main mode. A value of zero indicates the switch is not assigned. @@ -6374,58 +6312,6 @@ Channel 18 - - Position Control switch channel (deprecated) - 0 - 18 - - Unassigned - Channel 1 - Channel 2 - Channel 3 - Channel 4 - Channel 5 - Channel 6 - Channel 7 - Channel 8 - Channel 9 - Channel 10 - Channel 11 - Channel 12 - Channel 13 - Channel 14 - Channel 15 - Channel 16 - Channel 17 - Channel 18 - - - - Rattitude switch channel (deprecated) - 0 - 18 - - Unassigned - Channel 1 - Channel 2 - Channel 3 - Channel 4 - Channel 5 - Channel 6 - Channel 7 - Channel 8 - Channel 9 - Channel 10 - Channel 11 - Channel 12 - Channel 13 - Channel 14 - Channel 15 - Channel 16 - Channel 17 - Channel 18 - - Return switch channel 0 @@ -6452,32 +6338,6 @@ Channel 18 - - Stabilize switch channel mapping (deprecated) - 0 - 18 - - Unassigned - Channel 1 - Channel 2 - Channel 3 - Channel 4 - Channel 5 - Channel 6 - Channel 7 - Channel 8 - Channel 9 - Channel 10 - Channel 11 - Channel 12 - Channel 13 - Channel 14 - Channel 15 - Channel 16 - Channel 17 - Channel 18 - - VTOL transition switch channel mapping 0 From 42817c55c5f326314348d1129764a5a1694a391b Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Mon, 17 Jun 2024 22:35:24 +0000 Subject: [PATCH 36/38] Update PX4 Firmware metadata Mon Jun 17 22:35:24 UTC 2024 --- .../PX4/PX4ParameterFactMetaData.xml | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index e0977719664..f83684343fa 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -9301,6 +9301,28 @@ bit/s true + + UAVCAN fuel tank fuel type + This parameter defines the type of fuel used in the vehicle's fuel tank. 0: Unknown 1: Liquid (e.g., gasoline, diesel) 2: Gas (e.g., hydrogen, methane, propane) + 0 + 2 + true + + Unknown + Liquid + Gas + + + + UAVCAN fuel tank maximum capacity + This parameter defines the maximum fuel capacity of the vehicle's fuel tank. + 0.0 + 100000.0 + liters + 1 + 0.1 + true + UAVCAN mode 0 - UAVCAN disabled. 1 - Enables support for UAVCAN sensors without dynamic node ID allocation and firmware update. 2 - Enables support for UAVCAN sensors with dynamic node ID allocation and firmware update. 3 - Enables support for UAVCAN sensors and actuators with dynamic node ID allocation and firmware update. Also sets the motor control outputs to UAVCAN. @@ -9435,6 +9457,11 @@ Enable UAVCAN optical flow subscription. true + + subscription fuel tank + Enable UAVCAN fuel tank status subscription. + true + subscription GPS Enable UAVCAN GPS subscriptions. uavcan::equipment::gnss::Fix uavcan::equipment::gnss::Fix2 uavcan::equipment::gnss::Auxiliary From f6127fc8d550e2bb419be5bef5f48820ff878da7 Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Tue, 18 Jun 2024 08:17:34 +0000 Subject: [PATCH 37/38] Update PX4 Firmware metadata Tue Jun 18 08:17:34 UTC 2024 --- src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index f83684343fa..80a0052fa4a 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -8449,6 +8449,11 @@ SIH enabled + + Parameter version + This is used internally only: an airframe configuration might set an expected parameter version value via PARAM_DEFAULTS_VER. This is checked on bootup against SYS_PARAM_VER, and if they do not match, parameters are reset and reloaded from the airframe configuration. + 0 + RGB Led brightness limit Set to 0 to disable, 1 for maximum brightness From 2439911ca1c9fb04df9f69d881d51f9c3b1c9b0c Mon Sep 17 00:00:00 2001 From: PX4BuildBot Date: Tue, 18 Jun 2024 17:06:47 +0000 Subject: [PATCH 38/38] Update PX4 Firmware metadata Tue Jun 18 17:06:47 UTC 2024 --- .../PX4/PX4ParameterFactMetaData.xml | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml index 80a0052fa4a..9ec2756203a 100644 --- a/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml +++ b/src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml @@ -4356,9 +4356,19 @@ Disable to use the fixed parameter MPC_THR_HOVER Enable to use the hover thrust estimator - Numerical velocity derivative low pass cutoff frequency + Velocity derivative low pass cutoff frequency + A value of 0 disables the filter. 0 - 10 + 50 + Hz + 1 + 0.5 + + + Velocity low pass cutoff frequency + A value of 0 disables the filter. + 0 + 50 Hz 1 0.5 @@ -4390,6 +4400,24 @@ 1 1 + + Velocity notch filter bandwidth + A value of 0 disables the filter. + 0 + 50 + Hz + 1 + 0.5 + + + Velocity notch filter frequency + The center frequency for the 2nd order notch filter on the velocity. A value of 0 disables the filter. + 0 + 50 + Hz + 1 + 0.5 + Default horizontal velocity in autonomous modes e.g. in Missions, RTL, Goto if the waypoint does not specify differently