From 8a973ac531a4e078e67532c2b2c2beb87a339db5 Mon Sep 17 00:00:00 2001 From: Valentin Platzgummer Date: Fri, 13 Dec 2019 16:56:53 +0100 Subject: [PATCH] wima settings and reverse (wima menu) added --- qgroundcontrol.pro | 7 +- qgroundcontrol.qrc | 1 + src/FlightDisplay/FlightDisplayWimaMenu.qml | 14 ++- src/Settings/CMakeLists.txt | 1 + src/Settings/FlyViewSettings.cc | 1 + src/Settings/SettingsManager.cc | 2 + src/Settings/SettingsManager.h | 4 + src/Settings/Wima.SettingsGroup.json | 15 +++ src/Settings/WimaSettings.cc | 12 +++ src/Settings/WimaSettings.h | 15 +++ src/Wima/WimaController.SettingsGroup.json | 6 ++ src/Wima/WimaController.cc | 107 +++++++++++++++----- src/Wima/WimaController.h | 11 +- src/ui/preferences/GeneralSettings.qml | 37 +++++++ 14 files changed, 205 insertions(+), 28 deletions(-) create mode 100644 src/Settings/Wima.SettingsGroup.json create mode 100644 src/Settings/WimaSettings.cc create mode 100644 src/Settings/WimaSettings.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 14e815b24..ddfef7c56 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -432,7 +432,8 @@ HEADERS += \ src/Wima/OptimisationTools.h \ src/Wima/GeoUtilities.h \ src/Wima/TestPolygonCalculus.h \ - src/Wima/testplanimetrycalculus.h + src/Wima/testplanimetrycalculus.h \ + src/Settings/WimaSettings.h SOURCES += \ src/api/QGCCorePlugin.cc \ src/api/QGCOptions.cc \ @@ -463,7 +464,8 @@ SOURCES += \ src/Wima/GeoUtilities.cc \ src/Wima/PolygonCalculus.cc \ src/Wima/TestPolygonCalculus.cpp \ - src/Wima/testplanimetrycalculus.cpp + src/Wima/testplanimetrycalculus.cpp \ + src/Settings/WimaSettings.cc # # Unit Test specific configuration goes here (requires full debug build with all plugins) @@ -1346,3 +1348,4 @@ contains (CONFIG, QGC_DISABLE_INSTALLER_SETUP) { DISTFILES += \ src/WimaView/WimaMeasurementAreaEditor.qml \ + src/Settings/Wima.SettingsGroup.json diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 192af4aab..91d97879e 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -278,6 +278,7 @@ src/Wima/CircularSurvey.SettingsGroup.json src/Wima/WimaArea.SettingsGroup.json src/Wima/WimaController.SettingsGroup.json + src/Settings/Wima.SettingsGroup.json src/comm/APMArduCopterMockLink.params diff --git a/src/FlightDisplay/FlightDisplayWimaMenu.qml b/src/FlightDisplay/FlightDisplayWimaMenu.qml index d8a6851b2..352dd7d0d 100644 --- a/src/FlightDisplay/FlightDisplayWimaMenu.qml +++ b/src/FlightDisplay/FlightDisplayWimaMenu.qml @@ -107,7 +107,7 @@ Item { Column { id: mainColumn anchors.horizontalCenter: parent.horizontalCenter - spacing: 4 + spacing: ScreenTools.defaultFontPixelHeight * 0.3 SectionHeader{ id: settingsHeader @@ -145,6 +145,12 @@ Item { fact: wimaController.overlapWaypoints Layout.fillWidth: true } + } + GridLayout { + columns: 2 + rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 + columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5 + visible: settingsHeader.checked FactCheckBox { text: qsTr("Show All") @@ -157,6 +163,12 @@ Item { fact: wimaController.showCurrentMissionItems Layout.fillWidth: true } + + FactCheckBox { + text: qsTr("Reverse") + fact: wimaController.reverse + Layout.fillWidth: true + } } // Grid SectionHeader{ diff --git a/src/Settings/CMakeLists.txt b/src/Settings/CMakeLists.txt index 504e532ea..fad461a2a 100644 --- a/src/Settings/CMakeLists.txt +++ b/src/Settings/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(Settings SettingsManager.cc UnitsSettings.cc VideoSettings.cc + WimaSettings.cc ) target_link_libraries(Settings diff --git a/src/Settings/FlyViewSettings.cc b/src/Settings/FlyViewSettings.cc index ad04e35e2..70c3fd7cc 100644 --- a/src/Settings/FlyViewSettings.cc +++ b/src/Settings/FlyViewSettings.cc @@ -20,3 +20,4 @@ DECLARE_SETTINGGROUP(FlyView, "FlyView") DECLARE_SETTINGSFACT(FlyViewSettings, guidedMinimumAltitude) DECLARE_SETTINGSFACT(FlyViewSettings, guidedMaximumAltitude) + diff --git a/src/Settings/SettingsManager.cc b/src/Settings/SettingsManager.cc index 8bb7bf94d..e84cc92e5 100644 --- a/src/Settings/SettingsManager.cc +++ b/src/Settings/SettingsManager.cc @@ -26,6 +26,7 @@ SettingsManager::SettingsManager(QGCApplication* app, QGCToolbox* toolbox) , _flyViewSettings (nullptr) , _planViewSettings (nullptr) , _brandImageSettings (nullptr) + , _wimaSettings (nullptr) #if !defined(NO_ARDUPILOT_DIALECT) , _apmMavlinkStreamRateSettings (nullptr) #endif @@ -48,6 +49,7 @@ void SettingsManager::setToolbox(QGCToolbox *toolbox) _flyViewSettings = new FlyViewSettings (this); _planViewSettings = new PlanViewSettings (this); _brandImageSettings = new BrandImageSettings (this); + _wimaSettings = new WimaSettings (this); #if !defined(NO_ARDUPILOT_DIALECT) _apmMavlinkStreamRateSettings = new APMMavlinkStreamRateSettings (this); #endif diff --git a/src/Settings/SettingsManager.h b/src/Settings/SettingsManager.h index c0dd63c4f..6b55132b9 100644 --- a/src/Settings/SettingsManager.h +++ b/src/Settings/SettingsManager.h @@ -24,6 +24,7 @@ #include "PlanViewSettings.h" #include "BrandImageSettings.h" #include "APMMavlinkStreamRateSettings.h" +#include "WimaSettings.h" #if defined(QGC_AIRMAP_ENABLED) #include "AirMapSettings.h" #endif @@ -49,6 +50,7 @@ public: Q_PROPERTY(QObject* flyViewSettings READ flyViewSettings CONSTANT) Q_PROPERTY(QObject* planViewSettings READ planViewSettings CONSTANT) Q_PROPERTY(QObject* brandImageSettings READ brandImageSettings CONSTANT) + Q_PROPERTY(QObject* wimaSettings READ wimaSettings CONSTANT) #if !defined(NO_ARDUPILOT_DIALECT) Q_PROPERTY(QObject* apmMavlinkStreamRateSettings READ apmMavlinkStreamRateSettings CONSTANT) #endif @@ -67,6 +69,7 @@ public: FlyViewSettings* flyViewSettings (void) { return _flyViewSettings; } PlanViewSettings* planViewSettings (void) { return _planViewSettings; } BrandImageSettings* brandImageSettings (void) { return _brandImageSettings; } + WimaSettings* wimaSettings (void) { return _wimaSettings; } #if !defined(NO_ARDUPILOT_DIALECT) APMMavlinkStreamRateSettings* apmMavlinkStreamRateSettings(void) { return _apmMavlinkStreamRateSettings; } #endif @@ -83,6 +86,7 @@ private: FlyViewSettings* _flyViewSettings; PlanViewSettings* _planViewSettings; BrandImageSettings* _brandImageSettings; + WimaSettings* _wimaSettings; #if !defined(NO_ARDUPILOT_DIALECT) APMMavlinkStreamRateSettings* _apmMavlinkStreamRateSettings; #endif diff --git a/src/Settings/Wima.SettingsGroup.json b/src/Settings/Wima.SettingsGroup.json new file mode 100644 index 000000000..076a37f0c --- /dev/null +++ b/src/Settings/Wima.SettingsGroup.json @@ -0,0 +1,15 @@ +[ +{ + "name": "lowBatteryThreshold", + "shortDescription": "The battery threshold in percents, for which low battery handling measures get triggered.", + "type": "double", + "units": "%", + "defaultValue": 40 +}, +{ + "name": "enableLowBatteryHandling", + "shortDescription": "Enables or disables low battery handling measures.", + "type": "bool", + "defaultValue": true +} +] diff --git a/src/Settings/WimaSettings.cc b/src/Settings/WimaSettings.cc new file mode 100644 index 000000000..7028cb8ba --- /dev/null +++ b/src/Settings/WimaSettings.cc @@ -0,0 +1,12 @@ +#include "WimaSettings.h" +#include +#include + +DECLARE_SETTINGGROUP(Wima, "Wima") +{ + QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); \ + qmlRegisterUncreatableType("QGroundControl.SettingsManager", 1, 0, "WimaSettings", "Reference only"); \ +} + +DECLARE_SETTINGSFACT(WimaSettings, lowBatteryThreshold) +DECLARE_SETTINGSFACT(WimaSettings, enableLowBatteryHandling) diff --git a/src/Settings/WimaSettings.h b/src/Settings/WimaSettings.h new file mode 100644 index 000000000..6ef43a4d8 --- /dev/null +++ b/src/Settings/WimaSettings.h @@ -0,0 +1,15 @@ +#pragma once + +#include "SettingsGroup.h" + +class WimaSettings : public SettingsGroup +{ + Q_OBJECT +public: + WimaSettings(QObject* parent = nullptr); + + DEFINE_SETTING_NAME_GROUP() + + DEFINE_SETTINGFACT(lowBatteryThreshold) + DEFINE_SETTINGFACT(enableLowBatteryHandling) +}; diff --git a/src/Wima/WimaController.SettingsGroup.json b/src/Wima/WimaController.SettingsGroup.json index e807483e8..de38c201b 100644 --- a/src/Wima/WimaController.SettingsGroup.json +++ b/src/Wima/WimaController.SettingsGroup.json @@ -51,5 +51,11 @@ "type": "double", "min" : 1, "defaultValue": 5 +}, +{ + "name": "Reverse", + "shortDescription": "Reverses the phase direction. Phases go from high to low waypoint numbers, if checked.", + "type": "bool", + "defaultValue": false } ] diff --git a/src/Wima/WimaController.cc b/src/Wima/WimaController.cc index a82b88eed..aa7c9ceea 100644 --- a/src/Wima/WimaController.cc +++ b/src/Wima/WimaController.cc @@ -12,6 +12,7 @@ const char* WimaController::showAllMissionItemsName = "ShowAllMissionItems"; const char* WimaController::showCurrentMissionItemsName = "ShowCurrentMissionItems"; const char* WimaController::flightSpeedName = "FlightSpeed"; const char* WimaController::altitudeName = "Altitude"; +const char* WimaController::reverseName = "Reverse"; WimaController::WimaController(QObject *parent) : QObject (parent) @@ -30,29 +31,32 @@ WimaController::WimaController(QObject *parent) , _showCurrentMissionItems (settingsGroup, _metaDataMap[showCurrentMissionItemsName]) , _flightSpeed (settingsGroup, _metaDataMap[flightSpeedName]) , _altitude (settingsGroup, _metaDataMap[altitudeName]) + , _reverse (settingsGroup, _metaDataMap[reverseName]) , _startWaypointIndex (0) , _lastMissionPhaseReached (false) , _uploadOverrideRequired (false) - , _phaseDistance(-1) - , _phaseDuration(-1) - , _vehicleHasLowBattery(false) + , _phaseDistance (-1) + , _phaseDuration (-1) + , _vehicleHasLowBattery (false) , _lowBatteryHandlingTriggered(false) - , _executingSmartRTL(false) + , _executingSmartRTL (false) { _nextPhaseStartWaypointIndex.setRawValue(int(1)); _showAllMissionItems.setRawValue(true); _showCurrentMissionItems.setRawValue(true); - connect(&_overlapWaypoints, &Fact::rawValueChanged, this, &WimaController::updateNextWaypoint); - connect(&_maxWaypointsPerPhase, &Fact::rawValueChanged, this, &WimaController::recalcCurrentPhase); - connect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase); - connect(&_flightSpeed, &Fact::rawValueChanged, this, &WimaController::updateSpeed); - connect(&_altitude, &Fact::rawValueChanged, this, &WimaController::updateAltitude); + connect(&_overlapWaypoints, &Fact::rawValueChanged, this, &WimaController::updateNextWaypoint); + connect(&_maxWaypointsPerPhase, &Fact::rawValueChanged, this, &WimaController::recalcCurrentPhase); + connect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase); + connect(&_flightSpeed, &Fact::rawValueChanged, this, &WimaController::updateSpeed); + connect(&_altitude, &Fact::rawValueChanged, this, &WimaController::updateAltitude); - // battery timer + // setup low battery handling connect(&_checkBatteryTimer, &QTimer::timeout, this, &WimaController::checkBatteryLevel); _checkBatteryTimer.setInterval(500); - _checkBatteryTimer.start(); + Fact *enableLowBatteryHandling = qgcApp()->toolbox()->settingsManager()->wimaSettings()->enableLowBatteryHandling(); + connect(enableLowBatteryHandling, &Fact::rawValueChanged, this, &WimaController::enableDisableLowBatteryHandling); + enableDisableLowBatteryHandling(enableLowBatteryHandling->rawValue()); } QmlObjectListModel* WimaController::visualItems() @@ -137,6 +141,11 @@ Fact *WimaController::altitude() return &_altitude; } +Fact *WimaController::reverse() +{ + return &_reverse; +} + bool WimaController::uploadOverrideRequired() const { return _uploadOverrideRequired; @@ -553,31 +562,70 @@ bool WimaController::calcNextPhase() emit currentMissionItemsChanged(); emit currentWaypointPathChanged(); + bool reverseBool = _reverse.rawValue().toBool(); // Reverses the phase direction. Phases go from high to low waypoint numbers, if true. _startWaypointIndex = _nextPhaseStartWaypointIndex.rawValue().toInt()-1; - if (_startWaypointIndex > _missionItems.count()-1) - return false; + if (!reverseBool) { + if (_startWaypointIndex > _missionItems.count()-1) + return false; + } + else { + if (_startWaypointIndex < 0) + return false; + } + int maxWaypointsPerPhaseInt = _maxWaypointsPerPhase.rawValue().toInt(); // determine end waypoint index - _endWaypointIndex = std::min(_startWaypointIndex + maxWaypointsPerPhaseInt - 1, _missionItems.count()-1); - if (_endWaypointIndex == _missionItems.count() - 1) - _lastMissionPhaseReached = true; + if (!reverseBool) { + _endWaypointIndex = std::min(_startWaypointIndex + maxWaypointsPerPhaseInt - 1, _missionItems.count()-1); + if (_endWaypointIndex == _missionItems.count() - 1) + _lastMissionPhaseReached = true; + } + else { + _endWaypointIndex = std::max(_startWaypointIndex - maxWaypointsPerPhaseInt + 1, 0); + if (_endWaypointIndex == 0) + _lastMissionPhaseReached = true; + } + // extract waypoints QList geoCoordinateList; // list with potential waypoints (from _missionItems), for _currentMissionItems - if (!extractCoordinateList(_missionItems, geoCoordinateList, _startWaypointIndex, _endWaypointIndex)) { - qWarning("WimaController::calcNextPhase(): error on waypoint extraction."); - return false; + + if (!reverseBool) { + if (!extractCoordinateList(_missionItems, geoCoordinateList, _startWaypointIndex, _endWaypointIndex)) { + qWarning("WimaController::calcNextPhase(): error on waypoint extraction."); + return false; + } + } else { + if (!extractCoordinateList(_missionItems, geoCoordinateList, _endWaypointIndex, _startWaypointIndex)) { + qWarning("WimaController::calcNextPhase(): error on waypoint extraction."); + return false; + } + + // reverse path + QList reversePath; + for (QGeoCoordinate c : geoCoordinateList) + reversePath.prepend(c); + geoCoordinateList.clear(); + geoCoordinateList.append(reversePath); } + // set start waypoint index for next phase if (!_lastMissionPhaseReached) { disconnect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase); - int untruncated = std::max(_endWaypointIndex + 1 - _overlapWaypoints.rawValue().toInt(), 0); - int truncated = std::min(untruncated , _missionItems.count()-1); - _nextPhaseStartWaypointIndex.setRawValue(truncated + 1); + if (!reverseBool) { + int untruncated = std::max(_endWaypointIndex + 1 - _overlapWaypoints.rawValue().toInt(), 0); + int truncated = std::min(untruncated , _missionItems.count()-1); + _nextPhaseStartWaypointIndex.setRawValue(truncated + 1); + } + else { + int untruncated = std::min(_endWaypointIndex - 1 + _overlapWaypoints.rawValue().toInt(), _missionItems.count()-1); + int truncated = std::max(untruncated , 0); + _nextPhaseStartWaypointIndex.setRawValue(truncated + 1); + } connect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase); } @@ -742,7 +790,9 @@ void WimaController::updateAltitude() void WimaController::checkBatteryLevel() { Vehicle *managerVehicle = masterController()->managerVehicle(); - int batteryThreshold = 94; // percent + WimaSettings* wimaSettings = qgcApp()->toolbox()->settingsManager()->wimaSettings(); + int batteryThreshold = wimaSettings->lowBatteryThreshold()->rawValue().toInt(); + if (managerVehicle != nullptr) { Fact *battery1percentRemaining = managerVehicle->battery1FactGroup()->getFact(VehicleBatteryFactGroup::_percentRemainingFactName); Fact *battery2percentRemaining = managerVehicle->battery2FactGroup()->getFact(VehicleBatteryFactGroup::_percentRemainingFactName); @@ -786,6 +836,15 @@ void WimaController::smartRTLCleanUp(bool flying) } } +void WimaController::enableDisableLowBatteryHandling(QVariant enable) +{ + if (enable.toBool()) { + _checkBatteryTimer.start(); + } else { + _checkBatteryTimer.stop(); + } +} + void WimaController::_setPhaseDistance(double distance) { if (!qFuzzyCompare(distance, _phaseDistance)) { @@ -952,6 +1011,8 @@ void WimaController::_loadCurrentMissionItemsFromBuffer() int numItems = _missionItemsBuffer.count(); for (int i = 0; i < numItems; i++) _currentMissionItems.append(_missionItemsBuffer.removeAt(0)); + + updateCurrentPath(); } diff --git a/src/Wima/WimaController.h b/src/Wima/WimaController.h index 7f94f8952..2d4a061d8 100644 --- a/src/Wima/WimaController.h +++ b/src/Wima/WimaController.h @@ -21,6 +21,8 @@ #include "JsonHelper.h" #include "QGCApplication.h" #include "SettingsFact.h" +#include "WimaSettings.h" +#include "SettingsManager.h" class WimaController : public QObject @@ -53,6 +55,7 @@ public: Q_PROPERTY(Fact* showCurrentMissionItems READ showCurrentMissionItems CONSTANT) Q_PROPERTY(Fact* flightSpeed READ flightSpeed CONSTANT) Q_PROPERTY(Fact* altitude READ altitude CONSTANT) + Q_PROPERTY(Fact* reverse READ reverse CONSTANT) Q_PROPERTY(bool uploadOverrideRequired READ uploadOverrideRequired WRITE setUploadOverrideRequired NOTIFY uploadOverrideRequiredChanged) Q_PROPERTY(double phaseDistance READ phaseDistance NOTIFY phaseDistanceChanged) Q_PROPERTY(double phaseDuration READ phaseDuration NOTIFY phaseDurationChanged) @@ -81,7 +84,8 @@ public: Fact* showAllMissionItems (void); Fact* showCurrentMissionItems(void); Fact* flightSpeed (void); - Fact* altitude (void); + Fact* altitude (void); + Fact* reverse (void); bool uploadOverrideRequired (void) const; double phaseDistance (void) const; double phaseDuration (void) const; @@ -126,7 +130,8 @@ public: static const char* showAllMissionItemsName; static const char* showCurrentMissionItemsName; static const char* flightSpeedName; - static const char* altitudeName; + static const char* altitudeName; + static const char* reverseName; // Member Methodes QJsonDocument saveToJson(FileType fileType); @@ -171,6 +176,7 @@ private slots: void updateAltitude (void); void checkBatteryLevel (void); void smartRTLCleanUp (bool flying); // cleans up after successfull smart RTL + void enableDisableLowBatteryHandling (QVariant enable); private: void _setPhaseDistance(double distance); @@ -212,6 +218,7 @@ private: SettingsFact _showCurrentMissionItems; // bool value, Determines whether the mission items of the current mission phase are displayed or not. SettingsFact _flightSpeed; // mission flight speed SettingsFact _altitude; // mission altitude + SettingsFact _reverse; // Reverses the phase direction. Phases go from high to low waypoint numbers, if true. int _endWaypointIndex; // indes of the mission item stored in _missionItems defining the last element // (which is not part of the return path) of _currentMissionItem diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index 783ad7293..9cb0af4a7 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -929,6 +929,43 @@ QGCView { } } + QGCLabel { + id: wimaSectionLabel + text: qsTr("WiMA") + visible: QGroundControl.settingsManager.wimaSettings.visible + } + Rectangle { + Layout.preferredWidth: wimaGrid.width + (_margins * 2) + Layout.preferredHeight: wimaGrid.height + (_margins * 2) + Layout.fillWidth: true + color: qgcPal.windowShade + visible: wimaSectionLabel.visible + + GridLayout { + id: wimaGrid + anchors.margins: _margins + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + columns: 4 + + QGCLabel { + text: qsTr("Low Battery Threshold") + visible: _userBrandImageIndoor.visible + } + FactTextField { + Layout.preferredWidth: _valueFieldWidth + fact: QGroundControl.settingsManager.wimaSettings.lowBatteryThreshold + } + + FactCheckBox { + text: "Enable low battery handling" + fact: QGroundControl.settingsManager.wimaSettings.enableLowBatteryHandling + Layout.columnSpan: 2 + } + } + } + Item { width: 1; height: _margins } QGCLabel { -- 2.22.0