Commit 404c65ce authored by Valentin Platzgummer's avatar Valentin Platzgummer

WimaMenu edited, upload progress bar added, guided action for override upload added.

parent 1f7fc4d2
This diff is collapsed.
This diff is collapsed.
...@@ -548,6 +548,7 @@ QGCView { ...@@ -548,6 +548,7 @@ QGCView {
wimaController: wimaController wimaController: wimaController
planMasterController: masterController
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
...@@ -689,12 +690,21 @@ QGCView { ...@@ -689,12 +690,21 @@ QGCView {
GuidedActionsController { GuidedActionsController {
id: guidedActionsController id: guidedActionsController
wimaController: wimaController
missionController: _missionController missionController: _missionController
confirmDialog: guidedActionConfirm confirmDialog: guidedActionConfirm
actionList: guidedActionList actionList: guidedActionList
altitudeSlider: _altitudeSlider altitudeSlider: _altitudeSlider
z: _flightVideoPipControl.z + 1 z: _flightVideoPipControl.z + 1
property bool uploadOverrideRequired: wimaController.uploadOverrideRequired
onUploadOverrideRequiredChanged: {
if (uploadOverrideRequired) {
confirmAction(actionOverrideUpload)
}
}
onShowStartMissionChanged: { onShowStartMissionChanged: {
if (showStartMission) { if (showStartMission) {
confirmAction(actionStartMission) confirmAction(actionStartMission)
......
...@@ -23,6 +23,21 @@ Item { ...@@ -23,6 +23,21 @@ Item {
width: 300 width: 300
property var wimaController // must be provided by the user property var wimaController // must be provided by the user
property var planMasterController // must be provided by the user
property bool _controllerValid: planMasterController !== undefined
property real _controllerProgressPct: _controllerValid ? planMasterController.missionController.progressPct : 0
// Progress bar visibility
on_ControllerProgressPctChanged: {
if (_controllerProgressPct === 1) {
uploadCompleteText.visible = true
progressBar.visible = false
} else if (_controllerProgressPct > 0) {
progressBar.visible = true
uploadCompleteText.visible = false
}
}
// box containing all items // box containing all items
Rectangle { Rectangle {
...@@ -73,9 +88,12 @@ Item { ...@@ -73,9 +88,12 @@ Item {
} }
GridLayout { GridLayout {
columns: 2 columns: 2
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5
visible: settingsHeader.checked anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5
anchors.left: parent.left
anchors.right: parent.right
visible: settingsHeader.checked
// Settings // Settings
QGCLabel { text: qsTr("Next Waypoint") } QGCLabel { text: qsTr("Next Waypoint") }
...@@ -109,50 +127,90 @@ Item { ...@@ -109,50 +127,90 @@ Item {
} }
SectionHeader{ SectionHeader{
id: commandHeader id: missionHeader
text: qsTr("Commands") text: qsTr("Mission")
} }
GridLayout { GridLayout {
columns: 2 columns: 2
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.25 columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5
visible: commandHeader.checked anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5
anchors.left: parent.left
anchors.right: parent.right
visible: missionHeader.checked
// Buttons // Buttons
QGCButton { QGCButton {
id: buttonPreviousMissionPhase id: buttonPreviousMissionPhase
text: qsTr("Reverse") text: qsTr("Reverse")
onClicked: wimaController.previousPhase(); onClicked: wimaController.previousPhase();
Layout.fillWidth: true Layout.fillWidth: true
} }
QGCButton { QGCButton {
id: buttonNextMissionPhase id: buttonNextMissionPhase
text: qsTr("Forward") text: qsTr("Forward")
onClicked: wimaController.nextPhase(); onClicked: wimaController.nextPhase();
Layout.fillWidth: true Layout.fillWidth: true
} }
QGCButton { QGCButton {
id: buttonResetPhase id: buttonResetPhase
text: qsTr("Reset Phase") text: qsTr("Reset Phase")
onClicked: wimaController.resetPhase(); onClicked: wimaController.resetPhase();
Layout.fillWidth: true Layout.fillWidth: true
Layout.rowSpan: 2
} }
}
SectionHeader{
id: vehicleHeader
text: qsTr("Vehicle")
}
GridLayout {
columns: 2
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.5
columnSpacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5
anchors.left: parent.left
anchors.right: parent.right
visible: vehicleHeader.checked
QGCButton { QGCButton {
id: buttonUpload id: buttonUpload
text: qsTr("Upload") text: qsTr("Upload")
onClicked: wimaController.uploadToVehicle(); onClicked: wimaController.uploadToVehicle();
Layout.fillWidth: true Layout.fillWidth: true
} }
QGCButton { QGCButton {
id: buttonRemoveFromVehicle id: buttonRemoveFromVehicle
text: qsTr("Remove") text: qsTr("Remove")
onClicked: wimaController.removeFromVehicle(); onClicked: wimaController.removeFromVehicle();
Layout.fillWidth: true Layout.fillWidth: true
} }
// progess bar
Rectangle {
id: progressBar
height: 4
width: _controllerProgressPct * parent.width
color: qgcPal.colorGreen
visible: false
}
QGCLabel {
id: uploadCompleteText
font.pointSize: ScreenTools.largeFontPointSize
Layout.columnSpan: 2
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: "Done"
visible: false
}
} }
SectionHeader { SectionHeader {
...@@ -166,8 +224,6 @@ Item { ...@@ -166,8 +224,6 @@ Item {
visible: statsHeader.checked visible: statsHeader.checked
QGCLabel { QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Phase Length: ") text: qsTr("Phase Length: ")
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.pointSize: ScreenTools.smallFontPointSize font.pointSize: ScreenTools.smallFontPointSize
......
...@@ -27,6 +27,7 @@ import QGroundControl.FlightMap 1.0 ...@@ -27,6 +27,7 @@ import QGroundControl.FlightMap 1.0
Item { Item {
id: _root id: _root
property var wimaController
property var missionController property var missionController
property var confirmDialog property var confirmDialog
property var actionList property var actionList
...@@ -50,7 +51,8 @@ Item { ...@@ -50,7 +51,8 @@ Item {
readonly property string landAbortTitle: qsTr("Land Abort") readonly property string landAbortTitle: qsTr("Land Abort")
readonly property string setWaypointTitle: qsTr("Set Waypoint") readonly property string setWaypointTitle: qsTr("Set Waypoint")
readonly property string gotoTitle: qsTr("Goto Location") readonly property string gotoTitle: qsTr("Goto Location")
readonly property string vtolTransitionTitle: qsTr("VTOL Transition") readonly property string vtolTransitionTitle: qsTr("VTOL Transition")
readonly property string overrideUploadTitle: qsTr("Override Lock")
readonly property string armMessage: qsTr("Arm the vehicle.") readonly property string armMessage: qsTr("Arm the vehicle.")
readonly property string disarmMessage: qsTr("Disarm the vehicle") readonly property string disarmMessage: qsTr("Disarm the vehicle")
...@@ -70,6 +72,7 @@ Item { ...@@ -70,6 +72,7 @@ Item {
readonly property string mvPauseMessage: qsTr("Pause all vehicles at their current position.") readonly property string mvPauseMessage: qsTr("Pause all vehicles at their current position.")
readonly property string vtolTransitionFwdMessage: qsTr("Transition VTOL to fixed wing flight.") readonly property string vtolTransitionFwdMessage: qsTr("Transition VTOL to fixed wing flight.")
readonly property string vtolTransitionMRMessage: qsTr("Transition VTOL to multi-rotor flight.") readonly property string vtolTransitionMRMessage: qsTr("Transition VTOL to multi-rotor flight.")
readonly property string overrideUploadMessage: qsTr("Vehicle is not inside service area. Override upload lock?")
readonly property int actionRTL: 1 readonly property int actionRTL: 1
readonly property int actionLand: 2 readonly property int actionLand: 2
...@@ -92,6 +95,7 @@ Item { ...@@ -92,6 +95,7 @@ Item {
readonly property int actionMVStartMission: 19 readonly property int actionMVStartMission: 19
readonly property int actionVtolTransitionToFwdFlight: 20 readonly property int actionVtolTransitionToFwdFlight: 20
readonly property int actionVtolTransitionToMRFlight: 21 readonly property int actionVtolTransitionToMRFlight: 21
readonly property int actionOverrideUpload: 22
property bool showEmergenyStop: _guidedActionsEnabled && !_hideEmergenyStop && _vehicleArmed && _vehicleFlying property bool showEmergenyStop: _guidedActionsEnabled && !_hideEmergenyStop && _vehicleArmed && _vehicleFlying
property bool showArm: _guidedActionsEnabled && !_vehicleArmed property bool showArm: _guidedActionsEnabled && !_vehicleArmed
...@@ -331,6 +335,11 @@ Item { ...@@ -331,6 +335,11 @@ Item {
confirmDialog.message = vtolTransitionMRMessage confirmDialog.message = vtolTransitionMRMessage
confirmDialog.hideTrigger = true confirmDialog.hideTrigger = true
break break
case actionOverrideUpload:
confirmDialog.title = overrideUploadTitle
confirmDialog.message = overrideUploadMessage
confirmDialog.hideTrigger = true
break
default: default:
console.warn("Unknown actionCode", actionCode) console.warn("Unknown actionCode", actionCode)
return return
...@@ -406,6 +415,9 @@ Item { ...@@ -406,6 +415,9 @@ Item {
case actionVtolTransitionToMRFlight: case actionVtolTransitionToMRFlight:
_activeVehicle.vtolInFwdFlight = false _activeVehicle.vtolInFwdFlight = false
break break
case actionOverrideUpload:
wimaController.forceUploadToVehicle()
break
default: default:
console.warn(qsTr("Internal error: unknown actionCode"), actionCode) console.warn(qsTr("Internal error: unknown actionCode"), actionCode)
break break
......
#include "WimaArea.h" #include "WimaArea.h"
/*! /*!
* \variable WimaArea::epsilonMeter * \variable WimaArea::epsilonMeter
* \brief The accuracy used for distance calculations (unit: m). * \brief The accuracy used for distance calculations (unit: m).
...@@ -378,7 +377,7 @@ int WimaArea::previousVertexIndex(int index) const ...@@ -378,7 +377,7 @@ int WimaArea::previousVertexIndex(int index) const
* Returns \c true if the calling area is self intersecting, \c false else. * Returns \c true if the calling area is self intersecting, \c false else.
* \note If the calling area is self intersecting, it's not a \l {Simple Polygon}. * \note If the calling area is self intersecting, it's not a \l {Simple Polygon}.
*/ */
bool WimaArea::isSimplePolygon() bool WimaArea::isSimplePolygon() const
{ {
using namespace PolygonCalculus; using namespace PolygonCalculus;
using namespace GeoUtilities; using namespace GeoUtilities;
...@@ -391,6 +390,19 @@ bool WimaArea::isSimplePolygon() ...@@ -391,6 +390,19 @@ bool WimaArea::isSimplePolygon()
} }
bool WimaArea::containsCoordinate(const QGeoCoordinate &coordinate) const
{
using namespace PlanimetryCalculus;
using namespace PolygonCalculus;
using namespace GeoUtilities;
if (this->count() > 2) {
QPolygonF polygon = toQPolygonF(toCartesian2D(this->coordinateList(), coordinate));
return PlanimetryCalculus::contains(polygon, QPointF(0,0));
} else
return false;
}
/*! /*!
* \fn void WimaArea::saveToJson(QJsonObject &json) * \fn void WimaArea::saveToJson(QJsonObject &json)
* Saves the calling area to \c QJsonObject object and stores it inside \a json. * Saves the calling area to \c QJsonObject object and stores it inside \a json.
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "GeoUtilities.h" #include "GeoUtilities.h"
#include "PolygonCalculus.h" #include "PolygonCalculus.h"
#include "PlanimetryCalculus.h"
class WimaArea : public QGCMapPolygon //abstract base class for all WimaAreas class WimaArea : public QGCMapPolygon //abstract base class for all WimaAreas
{ {
...@@ -54,6 +55,8 @@ public: ...@@ -54,6 +55,8 @@ public:
bool join (WimaArea &area, QString &errorString); bool join (WimaArea &area, QString &errorString);
int nextVertexIndex (int index) const; int nextVertexIndex (int index) const;
int previousVertexIndex (int index) const; int previousVertexIndex (int index) const;
bool isSimplePolygon () const;
bool containsCoordinate (const QGeoCoordinate &coordinate) const;
void saveToJson (QJsonObject& jsonObject); void saveToJson (QJsonObject& jsonObject);
...@@ -63,7 +66,7 @@ public: ...@@ -63,7 +66,7 @@ public:
static QGCMapPolygon toQGCPolygon (const WimaArea& area); static QGCMapPolygon toQGCPolygon (const WimaArea& area);
static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea, QString &errorString); static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea, QString &errorString);
static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea); static bool join (const WimaArea &area1, const WimaArea &area2, WimaArea& joinedArea);
bool isSimplePolygon ();
// Friends // Friends
friend void print(const WimaArea& area, QString& outputString); friend void print(const WimaArea& area, QString& outputString);
......
...@@ -41,6 +41,20 @@ QList<QGeoCoordinate> WimaAreaData::coordinateList() const ...@@ -41,6 +41,20 @@ QList<QGeoCoordinate> WimaAreaData::coordinateList() const
return coordinateList; return coordinateList;
} }
bool WimaAreaData::containsCoordinate(const QGeoCoordinate &coordinate) const
{
using namespace PlanimetryCalculus;
using namespace PolygonCalculus;
using namespace GeoUtilities;
if (_path.size() > 2) {
QPolygonF polygon = toQPolygonF(toCartesian2D(this->coordinateList(), coordinate));
return PlanimetryCalculus::contains(polygon, QPointF(0,0));
} else
return false;
}
/*! /*!
* \fn void WimaAreaData::setMaxAltitude(double maxAltitude) * \fn void WimaAreaData::setMaxAltitude(double maxAltitude)
* *
......
...@@ -19,10 +19,11 @@ public: ...@@ -19,10 +19,11 @@ public:
//WimaAreaData(const WimaArea &other, QObject *parent = nullptr); //WimaAreaData(const WimaArea &other, QObject *parent = nullptr);
WimaAreaData& operator=(const WimaAreaData& otherData) = delete; // avoid slicing WimaAreaData& operator=(const WimaAreaData& otherData) = delete; // avoid slicing
double maxAltitude() const; double maxAltitude() const;
QVariantList path() const; QVariantList path() const;
QGeoCoordinate center() const; QGeoCoordinate center() const;
QList<QGeoCoordinate> coordinateList() const; QList<QGeoCoordinate> coordinateList() const;
bool containsCoordinate(const QGeoCoordinate &coordinate) const;
virtual QString type() const = 0; virtual QString type() const = 0;
......
...@@ -26,7 +26,10 @@ WimaController::WimaController(QObject *parent) ...@@ -26,7 +26,10 @@ WimaController::WimaController(QObject *parent)
, _nextPhaseStartWaypointIndex (settingsGroup, _metaDataMap[startWaypointIndexName]) , _nextPhaseStartWaypointIndex (settingsGroup, _metaDataMap[startWaypointIndexName])
, _showAllMissionItems (settingsGroup, _metaDataMap[showAllMissionItemsName]) , _showAllMissionItems (settingsGroup, _metaDataMap[showAllMissionItemsName])
, _showCurrentMissionItems (settingsGroup, _metaDataMap[showCurrentMissionItemsName]) , _showCurrentMissionItems (settingsGroup, _metaDataMap[showCurrentMissionItemsName])
, _startWaypointIndex (0)
, _lastMissionPhaseReached (false) , _lastMissionPhaseReached (false)
, _uploadOverrideRequired (false)
{ {
_nextPhaseStartWaypointIndex.setRawValue(int(1)); _nextPhaseStartWaypointIndex.setRawValue(int(1));
_showAllMissionItems.setRawValue(true); _showAllMissionItems.setRawValue(true);
...@@ -108,6 +111,11 @@ Fact *WimaController::showCurrentMissionItems() ...@@ -108,6 +111,11 @@ Fact *WimaController::showCurrentMissionItems()
return &_showCurrentMissionItems; return &_showCurrentMissionItems;
} }
bool WimaController::uploadOverrideRequired() const
{
return _uploadOverrideRequired;
}
Fact *WimaController::startWaypointIndex() Fact *WimaController::startWaypointIndex()
{ {
return &_nextPhaseStartWaypointIndex; return &_nextPhaseStartWaypointIndex;
...@@ -145,6 +153,15 @@ void WimaController::setDataContainer(WimaDataContainer *container) ...@@ -145,6 +153,15 @@ void WimaController::setDataContainer(WimaDataContainer *container)
} }
} }
void WimaController::setUploadOverrideRequired(bool overrideRequired)
{
if (_uploadOverrideRequired != overrideRequired) {
_uploadOverrideRequired = overrideRequired;
emit uploadOverrideRequiredChanged();
}
}
void WimaController::nextPhase() void WimaController::nextPhase()
{ {
calcNextPhase(); calcNextPhase();
...@@ -154,9 +171,9 @@ void WimaController::previousPhase() ...@@ -154,9 +171,9 @@ void WimaController::previousPhase()
{ {
if (_nextPhaseStartWaypointIndex.rawValue().toInt() > 0) { if (_nextPhaseStartWaypointIndex.rawValue().toInt() > 0) {
_lastMissionPhaseReached = false; _lastMissionPhaseReached = false;
_nextPhaseStartWaypointIndex.setRawValue( 1 + std::max(_startWaypointIndex _nextPhaseStartWaypointIndex.setRawValue(std::max(_startWaypointIndex
- _maxWaypointsPerPhase.rawValue().toInt() - _maxWaypointsPerPhase.rawValue().toInt()
+ _overlapWaypoints.rawValue().toInt(), 0)); + _overlapWaypoints.rawValue().toInt(), 1));
} }
} }
...@@ -168,6 +185,18 @@ void WimaController::resetPhase() ...@@ -168,6 +185,18 @@ void WimaController::resetPhase()
bool WimaController::uploadToVehicle() bool WimaController::uploadToVehicle()
{ {
if (!_serviceArea.containsCoordinate(_masterController->managerVehicle()->coordinate())) {
qgcApp()->showMessage(tr("Vehicle is not inside service area."));
setUploadOverrideRequired(true);
return false;
}
return forceUploadToVehicle();
}
bool WimaController::forceUploadToVehicle()
{
setUploadOverrideRequired(false);
if (_currentMissionItems.count() < 1) if (_currentMissionItems.count() < 1)
return false; return false;
...@@ -187,23 +216,6 @@ bool WimaController::uploadToVehicle() ...@@ -187,23 +216,6 @@ bool WimaController::uploadToVehicle()
_missionController->insertSimpleMissionItem(*item, visuals->count()); _missionController->insertSimpleMissionItem(*item, visuals->count());
} }
// // set land command for last mission item
// SimpleMissionItem *landItem = visuals->value<SimpleMissionItem*>(visuals->count()-1);
// if (landItem == nullptr) {
// qWarning("WimaController::uploadToVehicle(): nullptr");
// _missionController->removeAll();
// return;
// }
// // check vehicle type, before setting land command
// Vehicle* controllerVehicle = _masterController->controllerVehicle();
// MAV_CMD landCmd = controllerVehicle->vtol() ? MAV_CMD_NAV_VTOL_LAND : MAV_CMD_NAV_LAND;
// if (controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(landCmd)) {
// landItem->setCommand(landCmd);
// } else {
// _missionController->removeAll();
// return;
// }
_masterController->sendToVehicle(); _masterController->sendToVehicle();
return true; return true;
...@@ -584,7 +596,10 @@ void WimaController::updateNextWaypoint() ...@@ -584,7 +596,10 @@ void WimaController::updateNextWaypoint()
void WimaController::recalcCurrentPhase() void WimaController::recalcCurrentPhase()
{ {
_lastMissionPhaseReached = false; _lastMissionPhaseReached = false;
_nextPhaseStartWaypointIndex.setRawValue(_startWaypointIndex + 1); disconnect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase);
_nextPhaseStartWaypointIndex.setRawValue(_startWaypointIndex + 1);
connect(&_nextPhaseStartWaypointIndex, &Fact::rawValueChanged, this, &WimaController::calcNextPhase);
calcNextPhase();
} }
bool WimaController::setTakeoffLandPosition() bool WimaController::setTakeoffLandPosition()
......
...@@ -51,6 +51,7 @@ public: ...@@ -51,6 +51,7 @@ public:
Q_PROPERTY(Fact* startWaypointIndex READ startWaypointIndex CONSTANT) Q_PROPERTY(Fact* startWaypointIndex READ startWaypointIndex CONSTANT)
Q_PROPERTY(Fact* showAllMissionItems READ showAllMissionItems CONSTANT) Q_PROPERTY(Fact* showAllMissionItems READ showAllMissionItems CONSTANT)
Q_PROPERTY(Fact* showCurrentMissionItems READ showCurrentMissionItems CONSTANT) Q_PROPERTY(Fact* showCurrentMissionItems READ showCurrentMissionItems CONSTANT)
Q_PROPERTY(bool uploadOverrideRequired READ uploadOverrideRequired WRITE setUploadOverrideRequired NOTIFY uploadOverrideRequiredChanged)
...@@ -72,20 +73,23 @@ public: ...@@ -72,20 +73,23 @@ public:
Fact* overlapWaypoints (void); Fact* overlapWaypoints (void);
Fact* maxWaypointsPerPhase (void); Fact* maxWaypointsPerPhase (void);
Fact* startWaypointIndex (void); Fact* startWaypointIndex (void);
Fact* showAllMissionItems (void); Fact* showAllMissionItems (void);
Fact* showCurrentMissionItems (void); Fact* showCurrentMissionItems(void);
bool uploadOverrideRequired (void) const;
// Property setters // Property setters
void setMasterController (PlanMasterController* masterController); void setMasterController (PlanMasterController* masterController);
void setMissionController (MissionController* missionController); void setMissionController (MissionController* missionController);
void setDataContainer (WimaDataContainer* container); void setDataContainer (WimaDataContainer* container);
void setUploadOverrideRequired (bool overrideRequired);
// Member Methodes // Member Methodes
Q_INVOKABLE void nextPhase(); Q_INVOKABLE void nextPhase();
Q_INVOKABLE void previousPhase(); Q_INVOKABLE void previousPhase();
Q_INVOKABLE void resetPhase(); Q_INVOKABLE void resetPhase();
Q_INVOKABLE bool uploadToVehicle(); Q_INVOKABLE bool uploadToVehicle();
Q_INVOKABLE bool forceUploadToVehicle();
Q_INVOKABLE void removeFromVehicle(); Q_INVOKABLE void removeFromVehicle();
Q_INVOKABLE void saveToCurrent (); Q_INVOKABLE void saveToCurrent ();
...@@ -131,6 +135,7 @@ signals: ...@@ -131,6 +135,7 @@ signals:
void currentMissionItemsChanged (void); void currentMissionItemsChanged (void);
void waypointPathChanged (void); void waypointPathChanged (void);
void currentWaypointPathChanged (void); void currentWaypointPathChanged (void);
void uploadOverrideRequiredChanged (void);
private slots: private slots:
bool fetchContainerData(); bool fetchContainerData();
...@@ -175,4 +180,6 @@ private: ...@@ -175,4 +180,6 @@ private:
int _startWaypointIndex; // indes of the mission item stored in _missionItems defining the first element int _startWaypointIndex; // indes of the mission item stored in _missionItems defining the first element
// (which is not part of the arrival path) of _currentMissionItem // (which is not part of the arrival path) of _currentMissionItem
bool _lastMissionPhaseReached; bool _lastMissionPhaseReached;
bool _uploadOverrideRequired; // Is set to true if uploadToVehicle() did not suceed because the vehicle is not inside the service area.
// The user can override the upload lock with a slider, this will reset this variable to false.
}; };
...@@ -19,12 +19,20 @@ WimaPlaner::WimaPlaner(QObject *parent) ...@@ -19,12 +19,20 @@ WimaPlaner::WimaPlaner(QObject *parent)
, _corridor (this) , _corridor (this)
, _circularSurvey (nullptr) , _circularSurvey (nullptr)
, _surveyRefChanging (false) , _surveyRefChanging (false)
, _measurementAreaChanging (false)
, _corridorChanging (false)
, _serviceAreaChanging (false)
, _syncronizedWithController (false) , _syncronizedWithController (false)
, _readyForSync (false) , _readyForSync (false)
{ {
_lastMeasurementAreaPath = _measurementArea.path();
_lastServiceAreaPath = _serviceArea.path();
_lastCorridorPath = _corridor.path();
connect(this, &WimaPlaner::currentPolygonIndexChanged, this, &WimaPlaner::recalcPolygonInteractivity); connect(this, &WimaPlaner::currentPolygonIndexChanged, this, &WimaPlaner::recalcPolygonInteractivity);
connect(&_updateTimer, &QTimer::timeout, this, &WimaPlaner::updateTimerSlot); connect(&_updateTimer, &QTimer::timeout, this, &WimaPlaner::updateTimerSlot);
connect(this, &WimaPlaner::joinedAreaValidChanged, this, &WimaPlaner::updateMission); connect(this, &WimaPlaner::joinedAreaValidChanged, this, &WimaPlaner::updateMission);
_updateTimer.setInterval(500); // 250 ms means: max update time 2*250 ms _updateTimer.setInterval(500); // 250 ms means: max update time 2*250 ms
_updateTimer.start(); _updateTimer.start();
} }
...@@ -199,11 +207,8 @@ bool WimaPlaner::updateMission() ...@@ -199,11 +207,8 @@ bool WimaPlaner::updateMission()
setReadyForSync(false); setReadyForSync(false);
if ( !_joinedAreaValid) { if ( !_joinedAreaValid)
if (_joinedAreaErrorString.size() > 0)
qgcApp()->showMessage(_joinedAreaErrorString);
return false; return false;
}
// extract old survey data // extract old survey data
...@@ -339,6 +344,7 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -339,6 +344,7 @@ bool WimaPlaner::loadFromFile(const QString &filename)
return false; return false;
} }
_lastMeasurementAreaPath = _measurementArea.path(); // prevents error messages at this point
validAreaCounter++; validAreaCounter++;
_visualItems.append(&_measurementArea); _visualItems.append(&_measurementArea);
emit visualItemsChanged(); emit visualItemsChanged();
...@@ -350,6 +356,7 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -350,6 +356,7 @@ bool WimaPlaner::loadFromFile(const QString &filename)
return false; return false;
} }
_lastServiceAreaPath = _serviceArea.path(); // prevents error messages at this point
validAreaCounter++; validAreaCounter++;
_visualItems.append(&_serviceArea); _visualItems.append(&_serviceArea);
emit visualItemsChanged(); emit visualItemsChanged();
...@@ -361,6 +368,7 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -361,6 +368,7 @@ bool WimaPlaner::loadFromFile(const QString &filename)
return false; return false;
} }
_lastCorridorPath = _corridor.path(); // prevents error messages at this point
validAreaCounter++; validAreaCounter++;
_visualItems.append(&_corridor); _visualItems.append(&_corridor);
emit visualItemsChanged(); emit visualItemsChanged();
...@@ -373,18 +381,12 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -373,18 +381,12 @@ bool WimaPlaner::loadFromFile(const QString &filename)
errorString += QString(tr("Invalid or non existing entry for %s.\n").arg(WimaArea::areaTypeName)); errorString += QString(tr("Invalid or non existing entry for %s.\n").arg(WimaArea::areaTypeName));
return false; return false;
} }
} }
recalcJoinedArea();
_currentFile.sprintf("%s/%s.%s", fileInfo.path().toLocal8Bit().data(), fileInfo.completeBaseName().toLocal8Bit().data(), wimaFileExtension); _currentFile.sprintf("%s/%s.%s", fileInfo.path().toLocal8Bit().data(), fileInfo.completeBaseName().toLocal8Bit().data(), wimaFileExtension);
emit currentFileChanged(); emit currentFileChanged();
//recalcJoinedArea();
// MissionItems
// extrac MissionItems part
// bool ret = json.contains(missionItemsName);
// qWarning() << ret;
QJsonObject missionObject = json[missionItemsName].toObject(); QJsonObject missionObject = json[missionItemsName].toObject();
...@@ -429,11 +431,6 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -429,11 +431,6 @@ bool WimaPlaner::loadFromFile(const QString &filename)
_circularSurvey = missionItems->value<CircularSurveyComplexItem *>(i); _circularSurvey = missionItems->value<CircularSurveyComplexItem *>(i);
if (_circularSurvey != nullptr) { if (_circularSurvey != nullptr) {
if ( !recalcJoinedArea()) {
qgcApp()->showMessage(_joinedAreaErrorString);
return false;
}
_lastSurveyRefPoint = _circularSurvey->refPoint(); _lastSurveyRefPoint = _circularSurvey->refPoint();
_surveyRefChanging = false; _surveyRefChanging = false;
_circularSurvey->setAutoGenerated(true); // prevents reinitialisation from gui _circularSurvey->setAutoGenerated(true); // prevents reinitialisation from gui
...@@ -445,16 +442,15 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -445,16 +442,15 @@ bool WimaPlaner::loadFromFile(const QString &filename)
} }
} }
if (_circularSurvey == nullptr) //if (_circularSurvey == nullptr)
updateMission(); updateMission();
// remove temporary file // remove temporary file
if ( !temporaryFile.remove() ){ if ( !temporaryFile.remove() ){
qWarning("WimaPlaner::loadFromFile(): not able to remove temporary file."); qWarning("WimaPlaner::loadFromFile(): not able to remove temporary file.");
} }
_syncronizedWithController = false; setSyncronizedWithController(false);
_readyForSync = false;
return true; return true;
...@@ -465,7 +461,6 @@ bool WimaPlaner::loadFromFile(const QString &filename) ...@@ -465,7 +461,6 @@ bool WimaPlaner::loadFromFile(const QString &filename)
} else { } else {
errorString += QString(tr("File extension not supported.\n")); errorString += QString(tr("File extension not supported.\n"));
qgcApp()->showMessage(errorMessage.arg(errorString)); qgcApp()->showMessage(errorMessage.arg(errorString));
return false; return false;
} }
} }
...@@ -600,31 +595,31 @@ bool WimaPlaner::calcArrivalAndReturnPath() ...@@ -600,31 +595,31 @@ bool WimaPlaner::calcArrivalAndReturnPath()
bool WimaPlaner::recalcJoinedArea() bool WimaPlaner::recalcJoinedArea()
{ {
_joinedAreaErrorString.clear();
setJoinedAreaValid(false); setJoinedAreaValid(false);
// check if area paths form simple polygons // check if area paths form simple polygons
if ( !_serviceArea.isSimplePolygon() ) { if ( !_serviceArea.isSimplePolygon() ) {
_joinedAreaErrorString.append(tr("Service area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); qgcApp()->showMessage(tr("Service area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
return false; return false;
} }
if ( !_corridor.isSimplePolygon() && _corridor.count() > 0) { if ( !_corridor.isSimplePolygon() && _corridor.count() > 0) {
_joinedAreaErrorString.append(tr("Corridor is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); qgcApp()->showMessage(tr("Corridor is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
return false; return false;
} }
if ( !_measurementArea.isSimplePolygon() ) { if ( !_measurementArea.isSimplePolygon() ) {
_joinedAreaErrorString.append(tr("Measurement area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n")); qgcApp()->showMessage(tr("Measurement area is self intersecting and thus not a simple polygon. Only simple polygons allowed.\n"));
return false; return false;
} }
_joinedArea.setPath(_serviceArea.path()); _joinedArea.setPath(_serviceArea.path());
_joinedArea.join(_corridor); _joinedArea.join(_corridor);
if ( !_joinedArea.join(_measurementArea) ) { if ( !_joinedArea.join(_measurementArea) ) {
_joinedAreaErrorString.append(tr("Not able to join areas. Service area and measurement" qgcApp()->showMessage(tr("Not able to join areas. Service area and measurement"
" must have a overlapping section, or be connected through a corridor.")); " must have a overlapping section, or be connected through a corridor."));
return false; // this happens if all areas are pairwise disjoint return false; // this happens if all areas are pairwise disjoint
} }
// join service area, op area and corridor // join service area, op area and corridor
setJoinedAreaValid(true); setJoinedAreaValid(true);
return true; return true;
...@@ -640,6 +635,8 @@ bool WimaPlaner::recalcJoinedArea() ...@@ -640,6 +635,8 @@ bool WimaPlaner::recalcJoinedArea()
void WimaPlaner::pushToContainer() void WimaPlaner::pushToContainer()
{ {
if (_container != nullptr) { if (_container != nullptr) {
if (!_readyForSync)
return;
WimaPlanData planData = toPlanData(); WimaPlanData planData = toPlanData();
_container->push(planData); _container->push(planData);
setSyncronizedWithController(true); setSyncronizedWithController(true);
......
...@@ -151,7 +151,6 @@ private: ...@@ -151,7 +151,6 @@ private:
WimaDataContainer *_container; // container for data exchange with WimaController WimaDataContainer *_container; // container for data exchange with WimaController
QmlObjectListModel _visualItems; // contains all visible areas QmlObjectListModel _visualItems; // contains all visible areas
WimaJoinedArea _joinedArea; // joined area fromed by _measurementArea, _serviceArea, _corridor WimaJoinedArea _joinedArea; // joined area fromed by _measurementArea, _serviceArea, _corridor
QString _joinedAreaErrorString; // contains errors which appeared in recalcJoinedArea
bool _joinedAreaValid; bool _joinedAreaValid;
WimaMeasurementArea _measurementArea; // measurement area WimaMeasurementArea _measurementArea; // measurement area
WimaServiceArea _serviceArea; // area for supplying WimaServiceArea _serviceArea; // area for supplying
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment