Commit 07975ff6 authored by Valentin Platzgummer's avatar Valentin Platzgummer

auto vehicle corridor implemented

parent 6c9cee43
......@@ -218,6 +218,8 @@
<file alias="QGroundControl/Controls/WimaGOperationAreaMapVisual.qml">src/WimaView/WimaGOperationAreaMapVisual.qml</file>
<file alias="QGroundControl/Controls/WimaServiceAreaMapVisual.qml">src/WimaView/WimaServiceAreaMapVisual.qml</file>
<file alias="QGroundControl/Controls/WimaGOperationAreaEditor.qml">src/WimaView/WimaGOperationAreaEditor.qml</file>
<file alias="QGroundControl/Controls/WimaServiceAreaEditor.qml">src/WimaView/WimaServiceAreaEditor.qml</file>
<file alias="QGroundControl/Controls/WimaVCorridorMapVisual.qml">src/WimaView/WimaVCorridorMapVisual.qml</file>
</qresource>
<qresource prefix="/json">
<file alias="APMMavlinkStreamRate.SettingsGroup.json">src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file>
......
......@@ -89,6 +89,9 @@ WimaMapVisual 1.0 WimaMapVisual.qml
WimaGOperationAreaMapVisual 1.0 WimaGOperationAreaMapVisual.qml
WimaGOperationAreaEditor 1.0 WimaGOperationAreaEditor.qml
WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.qml
WimaServiceAreaEditor 1.0 WimaServiceAreaEditor.qml
WimaVCorridorMapVisual 1.0 WimaVCorridorMapVisual.qml
WimaItemEditor 1.0 WimaItemEditor.qml
WimaMapPolygonVisuals 1.0 WimaMapPolygonVisuals.qml
WimaMapPolylineVisuals 1.0 WimaMapPolylineVisuals.qml
#include "WimaController.h"
#include "MissionController.h"
WimaController::WimaController(QObject *parent) :
QObject (parent)
,_planView (true)
,_visualItems (new QmlObjectListModel(parent))
,_currentPolygonIndex (-1)
{
connect(this, &WimaController::currentPolygonIndexChanged, this, &WimaController::recalcPolygonInteractivity);
}
......@@ -30,17 +30,6 @@ void WimaController::setCurrentPolygonIndex(int index)
}
}
void WimaController::addGOperationArea()
{
WimaGOperationArea* newPoly = new WimaGOperationArea(this);
_visualItems->append(newPoly);
int newIndex = _visualItems->count()-1;
_currentPolygonIndex = newIndex;
emit currentPolygonIndexChanged(newIndex);
emit visualItemsChanged();
}
void WimaController::removeArea(int index)
{
if(index >= 0 && index < _visualItems->count()){
......@@ -48,6 +37,13 @@ void WimaController::removeArea(int index)
emit visualItemsChanged();
if (_visualItems->count() == 0) {
// this branch is reached if all items are removed
// to guarentee proper behavior, _currentPolygonIndex must be set to a invalid value, as on constructor init.
_currentPolygonIndex = -1;
return;
}
if(_currentPolygonIndex >= _visualItems->count()){
setCurrentPolygonIndex(_visualItems->count() - 1);
}else{
......@@ -59,16 +55,75 @@ void WimaController::removeArea(int index)
}
void WimaController::addGOperationArea()
{
WimaGOperationArea* newPoly = new WimaGOperationArea(this);
_visualItems->append(newPoly);
int newIndex = _visualItems->count()-1;
setCurrentPolygonIndex(newIndex);
emit visualItemsChanged();
}
void WimaController::addServiceArea()
{
resetAllIsCurrentPolygon();
WimaServiceArea* newPoly = new WimaServiceArea(this);
newPoly->setInteractive(true);
_visualItems->append(newPoly);
int newIndex = _visualItems->count()-1;
setCurrentPolygonIndex(newIndex);
emit visualItemsChanged();
}
bool WimaController::addVehicleCorridor(WimaGOperationArea *opArea, WimaServiceArea *serviceArea)
{
WimaVCorridor* corridor = nullptr;
if (opArea != nullptr && serviceArea != nullptr){
for (int i = 0; i < _visualItems->count(); i++) {
corridor = qobject_cast<WimaVCorridor*>(_visualItems->get(i));
if (corridor != nullptr){
if (corridor->serviceArea() == serviceArea && corridor->opArea() == opArea){
break;
}else {
corridor = nullptr;
}
}
}
bool newCorridorCreated = false;
if(corridor == nullptr){
corridor = new WimaVCorridor(this);
newCorridorCreated = true;
}else {
corridor->clear();
}
QList<QGeoCoordinate> opAreaPolyline = opArea->polyline()->coordinateList();
QList<QGeoCoordinate> serAreaPolyline = serviceArea->polyline()->coordinateList();
if (opAreaPolyline.size() > 1 && serAreaPolyline.size() > 1){
corridor->appendVertices(opAreaPolyline);
corridor->appendVertices(serAreaPolyline);
if (newCorridorCreated){
corridor->setServiceArea(serviceArea);
corridor->setOpArea(opArea);
serviceArea->setVehicleCorridor(corridor);
opArea->setVehicleCorridor(corridor);
_visualItems->append(corridor);
emit visualItemsChanged();
}
return true;
}else {
qWarning("WimaController::addVehicleCorridor(): OpArea or serviceArea polyline size <= 1!");
if (newCorridorCreated){
corridor->deleteLater();
}
return false;
}
}else {
return false;
}
}
void WimaController::startMission()
{
......@@ -89,6 +144,33 @@ void WimaController::resumeMission()
}
bool WimaController::updateMission()
{
WimaGOperationArea* opArea = nullptr;
for (int i = 0; i < _visualItems->count(); i++) {
WimaGOperationArea* currentArea = qobject_cast<WimaGOperationArea*>(_visualItems->get(i));
if (currentArea != nullptr){
opArea = currentArea;
break;
}
}
WimaServiceArea* serArea = nullptr;
for (int i = 0; i < _visualItems->count(); i++) {
WimaServiceArea* currentArea = qobject_cast<WimaServiceArea*>(_visualItems->get(i));
if (currentArea != nullptr){
serArea = currentArea;
break;
}
}
if (opArea != nullptr && serArea != nullptr){
return addVehicleCorridor(opArea, serArea);
}else{
return false;
}
}
void WimaController::saveMission()
{
......
......@@ -7,6 +7,7 @@
#include "WimaArea.h"
#include "WimaGOperationArea.h"
#include "WimaServiceArea.h"
#include "WimaVCorridor.h"
#include "PlanMasterController.h"
#include "MissionController.h"
......@@ -37,16 +38,23 @@ public:
// Property setters
void setMasterController (PlanMasterController* masterController);
void setMissionController (MissionController* missionController);
/// Sets the integer index pointing to the current polygon. Current polygon is set interactive.
void setCurrentPolygonIndex (int index);
Q_INVOKABLE void addGOperationArea();
/// Removes an area from _visualItems
/// @param index Index of the area to be removed
Q_INVOKABLE void removeArea(int index);
Q_INVOKABLE void addServiceArea();
/// @return true if a vehicle corridor was added sucessfully and false otherwise.
bool addVehicleCorridor(WimaGOperationArea* opArea, WimaServiceArea* serviceArea);
Q_INVOKABLE void startMission();
Q_INVOKABLE void abortMission();
Q_INVOKABLE void pauseMission();
Q_INVOKABLE void resumeMission();
/// Recalculates vehicle corridor, flight path, etc.
Q_INVOKABLE bool updateMission();
Q_INVOKABLE void saveMission();
Q_INVOKABLE void loadMission();
......
......@@ -42,6 +42,21 @@ void WimaGOperationArea::removeVehicle(int vehicleIndex)
}
}
void WimaGOperationArea::setVehicleCorridor(WimaVCorridor *corridor)
{
if(corridor != nullptr){
if (corridor != _vehicleCorridor){
_vehicleCorridor = corridor;
emit vehicleCorridorChanged(_vehicleCorridor);
}
else {
qWarning("WimaGOperationArea::setVehicleCorridor(): new corridor equals old _vehicleCorridor!");
}
}else{
qWarning("WimaGOperationArea::setVehicleCorridor(): corridor == nullptr!");
}
}
/*void WimaGOperationArea::recalculatesubPolygons()
{
int vehicleCount = _vehicleList->count();
......
......@@ -4,6 +4,7 @@
#include "WimaArea.h"
#include "SettingsFact.h"
#include "WimaTrackerPolyline.h"
#include "WimaGOperationArea.h"
#include "QScopedPointer"
......@@ -14,16 +15,17 @@ public:
WimaGOperationArea(QObject* parent = nullptr);
WimaGOperationArea(WimaArea* other, QObject* parent = nullptr);
Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitude CONSTANT)
Q_PROPERTY(Fact* numberOfLayers READ numberOfLayers CONSTANT)
Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT)
Q_PROPERTY(Fact* bottomLayerAltitude READ bottomLayerAltitude CONSTANT)
Q_PROPERTY(Fact* numberOfLayers READ numberOfLayers CONSTANT)
Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT)
/*Q_PROPERTY(QmlObjectListModel* vehicleList READ vehicleList NOTIFY vehicleListChanged)
Q_PROPERTY(QmlObjectListModel* vehiclePolygons READ vehiclePolygons NOTIFY vehiclePolygonsChanged)*/
Q_PROPERTY(WimaTrackerPolyline* polyline READ polyline CONSTANT)
Q_PROPERTY(WimaTrackerPolyline* polyline READ polyline CONSTANT)
Q_INVOKABLE void addVehicle (WimaVehicle *vehicle);
Q_INVOKABLE void removeVehicle (int vehicleIndex);
void setVehicleCorridor (WimaVCorridor* corridor);
/*Q_INVOKABLE void recalculatesubPolygons ();
Q_INVOKABLE void removeAllVehicles ();
Q_INVOKABLE void addVehiclePolygon ();
......@@ -42,6 +44,7 @@ public:
/*QmlObjectListModel* vehicleList (void) const { return _vehicleList;}
QmlObjectListModel* vehiclePolygons (void) const { return _vehiclePolygons;}*/
WimaTrackerPolyline* polyline (void) { return &_polyline;}
WimaVCorridor* vehicleCorridor (void) { return _vehicleCorridor;}
static const char* settingsGroup;
......@@ -57,7 +60,7 @@ signals:
//void vehicleListChanged (void);
void polylineChanged (void);
//void vehiclePolygonsChanged (void);
void vehicleCorridorChanged (WimaVCorridor* corridor);
private:
QMap<QString, FactMetaData*> _metaDataMap;
......@@ -69,7 +72,9 @@ private:
/*QmlObjectListModel* _vehicleList;
QmlObjectListModel* _vehiclePolygons;*/
WimaTrackerPolyline _polyline;
WimaTrackerPolyline _polyline;
WimaVCorridor* _vehicleCorridor;
......
......@@ -9,6 +9,7 @@ WimaServiceArea::WimaServiceArea(QObject *parent):
WimaServiceArea::WimaServiceArea(WimaArea *other, QObject *parent):
WimaArea (other, parent)
{
_polyline.bindPolygon(this);
this->setObjectName("Service Area");
}
......@@ -28,3 +29,18 @@ void WimaServiceArea::setLandPosition(QGeoCoordinate* coordinate)
}
}
void WimaServiceArea::setVehicleCorridor(WimaVCorridor *corridor)
{
if(corridor != nullptr){
if (corridor != _vehicleCorridor){
_vehicleCorridor = corridor;
emit vehicleCorridorChanged(_vehicleCorridor);
}
else {
qWarning("WimaServiceArea::setVehicleCorridor(): new corridor equals old _vehicleCorridor!");
}
}else{
qWarning("WimaServiceArea::setVehicleCorridor(): corridor == nullptr!");
}
}
......@@ -2,6 +2,7 @@
#include <QObject>
#include "WimaArea.h"
#include "WimaTrackerPolyline.h"
class WimaServiceArea : public WimaArea
{
......@@ -10,8 +11,10 @@ public:
WimaServiceArea(QObject* parent = nullptr);
WimaServiceArea(WimaArea* other = nullptr, QObject* parent = nullptr);
Q_PROPERTY(QGeoCoordinate* takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged)
Q_PROPERTY(QGeoCoordinate* landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged)
Q_PROPERTY(QGeoCoordinate* takeOffPosition READ takeOffPosition WRITE setTakeOffPosition NOTIFY takeOffPositionChanged)
Q_PROPERTY(QGeoCoordinate* landPosition READ landPosition WRITE setLandPosition NOTIFY landPositionChanged)
Q_PROPERTY(WimaTrackerPolyline* polyline READ polyline CONSTANT)
// Overrides from WimaPolygon
QString mapVisualQML (void) const { return "WimaServiceAreaMapVisual.qml";}
......@@ -20,16 +23,23 @@ public:
// Property acessors
QGeoCoordinate* takeOffPosition (void) { return &_takeOffPosition;}
QGeoCoordinate* landPosition (void) { return &_landPosition;}
WimaTrackerPolyline* polyline (void) { return &_polyline;}
WimaVCorridor* vehicleCorridor (void) { return _vehicleCorridor;}
// Property setters
void setTakeOffPosition (QGeoCoordinate* coordinate);
void setLandPosition (QGeoCoordinate* coordinate);
void setVehicleCorridor (WimaVCorridor* corridor);
signals:
void takeOffPositionChanged (void);
void landPositionChanged (void);
void vehicleCorridorChanged (WimaVCorridor* corridor);
private:
WimaTrackerPolyline _polyline;
QGeoCoordinate _takeOffPosition;
QGeoCoordinate _landPosition;
WimaVCorridor* _vehicleCorridor;
};
......@@ -33,11 +33,12 @@ void WimaTrackerPolyline::unbindPolygon()
}
}
void WimaTrackerPolyline::swapLimits()
void WimaTrackerPolyline::swapEndPoints()
{
int storage = _startVertexIndex;
_startVertexIndex = _endVertexIndex;
_endVertexIndex = storage;
recalcPolyline();
}
......@@ -115,7 +116,7 @@ void WimaTrackerPolyline::snapStartVertex()
void WimaTrackerPolyline::recalcPolyline()
{
qWarning("WimaTrackerPolyline::recalcPolyline()");
//qWarning("WimaTrackerPolyline::recalcPolyline()");
if (_boundArea != nullptr && _boundArea->count() > 0){
if (_startVertexIndex >= _boundArea->count()){
_startVertexIndex = 0;
......@@ -124,10 +125,10 @@ void WimaTrackerPolyline::recalcPolyline()
_endVertexIndex = _boundArea->count()-1;
}
_polyline.clear();
this->clear();
int i = _startVertexIndex;
while(1){
_polyline.appendVertex(_boundArea->vertexCoordinate(i));
this->appendVertex(_boundArea->vertexCoordinate(i));
if (i == _boundArea->count()-1 && i != _endVertexIndex){
i = 0;
}else if (i == _endVertexIndex) {
......
......@@ -23,7 +23,7 @@ public:
//Property setters
Q_INVOKABLE void bindPolygon (WimaArea* polygon);
Q_INVOKABLE void unbindPolygon ();
Q_INVOKABLE void swapLimits ();
Q_INVOKABLE void swapEndPoints ();
Q_INVOKABLE void setStartVertexIndex (int PolygonVertexIndex);
Q_INVOKABLE void setEndVertexIndex (int PolygonVertexIndex);
......@@ -48,7 +48,6 @@ public slots:
void recalcPolyline(void);
private:
QGCMapPolyline _polyline;
WimaArea* _boundArea;
// this->vertexCoordinate(this->count()-1) and _boundArea->vertexCoordinate(_startVertexIndex) are linked
int _startVertexIndex;
......
......@@ -7,7 +7,39 @@ WimaVCorridor::WimaVCorridor(QObject *parent):
}
WimaVCorridor::WimaVCorridor(WimaArea *other, QObject *parent):
WimaArea (other, parent)
WimaArea (other, parent)
,_serviceArea (nullptr)
,_opArea (nullptr)
{
this->setObjectName("Corridor");
}
void WimaVCorridor::setServiceArea(WimaServiceArea *serviceArea)
{
if (serviceArea != nullptr){
if(serviceArea != _serviceArea){
_serviceArea = serviceArea;
emit serviceAreaChanged(_serviceArea);
}else {
qWarning("WimaVCorridor::setServiceArea(): new serviceArea does not differ from old _serviceArea!");
}
}else {
qWarning("WimaVCorridor::setServiceArea(): serviceArea == nullptr!");
}
}
void WimaVCorridor::setOpArea(WimaGOperationArea *opArea)
{
if (opArea != nullptr){
if(&opArea != &_opArea){
_opArea = opArea;
emit opAreaChanged(_opArea);
}else {
qWarning("WimaVCorridor::setOpArea(): new opArea does not differ from old _opArea!");
}
}else {
qWarning("WimaVCorridor::setOpArea(): opArea == nullptr!");
}
}
......@@ -2,6 +2,8 @@
#include <QObject>
#include "WimaArea.h"
#include "WimaServiceArea.h"
#include "WimaGOperationArea.h"
class WimaVCorridor : public WimaArea
{
......@@ -13,5 +15,20 @@ public:
// Overrides from WimaPolygon
QString mapVisualQML (void) const { return "WimaVCorridorMapVisual.qml";}
QString editorQML (void) const { return "WimaVCorridorEditor.qml";}
// Methodes
void setServiceArea (WimaServiceArea* serviceArea);
void setOpArea (WimaGOperationArea* opArea);
WimaServiceArea* serviceArea (void) const {return _serviceArea;}
WimaGOperationArea* opArea (void) const {return _opArea;}
signals:
void serviceAreaChanged (WimaServiceArea* serviceArea);
void opAreaChanged (WimaGOperationArea* opArea);
private:
WimaServiceArea* _serviceArea;
WimaGOperationArea* _opArea;
};
......@@ -28,11 +28,29 @@ Rectangle {
property real _margin: ScreenTools.defaultFontPixelWidth / 2
property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5
property var polyline: areaItem.polyline
property var operatingPolygon: areaItem
property bool polylineInteractive: polyline.interactive
property bool polygonInteractive: areaItem.interactive
property var polygon: areaItem
property bool initNecesarry: true
onPolylineInteractiveChanged: {
polyline.interactive = polylineInteractive;
}
onPolygonInteractiveChanged: {
polygon.interactive = polygonInteractive;
}
function editPolyline(){
polyline.interactive = true;
if (polylineInteractive){
//polyline.interactive = false;
polylineInteractive = false;
//polygonInteractive = true;
}else{
//polyline.interactive = true;
polylineInteractive = true;
//polygonInteractive = false;
}
}
......@@ -74,7 +92,7 @@ Rectangle {
Layout.fillWidth: true
}
/*QGCLabel { text: qsTr("Number of Layers") }
QGCLabel { text: qsTr("Number of Layers") }
FactTextField {
fact: areaItem.numberOfLayers
Layout.fillWidth: true
......@@ -84,7 +102,7 @@ Rectangle {
FactTextField {
fact: areaItem.layerDistance
Layout.fillWidth: true
}*/
}
}
......@@ -104,11 +122,21 @@ Rectangle {
anchors.topMargin: _margin / 2
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
text: "Edit Polyline"
text: polylineInteractive ? "Done" : "Edit"
onClicked: editPolyline()
}
QGCButton {
id: swapEndpoints
anchors.topMargin: _margin / 2
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
text: "Swap End-Points"
onClicked: polyline.swapEndPoints()
}
SectionHeader {
id: statsHeader
text: qsTr("Statistics")
......
......@@ -65,7 +65,7 @@ Item {
function _addInitialPolyline(){
_polyline.setStartVertexIndex(0);
_polyline.setEndVertexIndex(2);
_polyline.setEndVertexIndex(1);
}
......@@ -95,22 +95,10 @@ Item {
mapControl: map
mapPolyline: _polyline
lineWidth: 4
lineColor: interactive ? "yellow" : "green"
lineColor: interactive ? "white" : "green"
enableSplitHandels: false
enableDragHandels: true
edgeHandelsOnly: true
}
/*QGCMapPolylineVisuals {
id: mapPolylineVisuals
qgcView: _root.qgcView
mapControl: map
mapPolyline: _polyline
lineWidth: 3
lineColor: "#be781c"
}*/
}
......@@ -108,6 +108,7 @@ Item {
}
Component.onCompleted: {
addInitialPolyline()
addVisuals()
if (interactive) {
addHandles()
......@@ -151,6 +152,11 @@ Item {
text: qsTr("Remove vertex" )
onTriggered: mapPolyline.removeVertex(menu._removeVertexIndex)
}
MenuItem {
id: swapEndPoints
text: qsTr("Swap End-Points" )
onTriggered: mapPolyline.swapEndPoints()
}
MenuSeparator {
visible: removeVertexItem.visible
......@@ -283,7 +289,7 @@ Item {
onDragStop: {
if (_creationComplete) {
// During component creation some bad coordinate values got through which screws up draw
mapPolyline.snapVertices(polylineVertex)
mapPolyline.snapVertex(polylineVertex)
}
}
......
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Extras 1.4
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0
// Editor for Operating Area items
Rectangle {
id: _root
height: visible ? (editorColumn.height + (_margin * 2)) : 0
width: availableWidth
color: qgcPal.windowShadeDark
radius: _radius
// The following properties must be available up the hierarchy chain
//property real availableWidth ///< Width for control
//property var areaItem ///< Mission Item for editor
property real _margin: ScreenTools.defaultFontPixelWidth / 2
property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5
property var polyline: areaItem.polyline
property bool polylineInteractive: polyline.interactive
property bool polygonInteractive: areaItem.interactive
property var polygon: areaItem
property bool initNecesarry: true
onPolylineInteractiveChanged: {
polyline.interactive = polylineInteractive;
}
onPolygonInteractiveChanged: {
polygon.interactive = polygonInteractive;
}
function editPolyline(){
if (polylineInteractive){
//polyline.interactive = false;
polylineInteractive = false;
//polygonInteractive = true;
}else{
//polyline.interactive = true;
polylineInteractive = true;
//polygonInteractive = false;
}
}
QGCPalette { id: qgcPal; colorGroupEnabled: true }
Column {
id: editorColumn
anchors.margins: _margin
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
SectionHeader {
id: scanHeader
text: qsTr("Settings")
}
Column {
anchors.left: parent.left
anchors.right: parent.rightsetI
spacing: _margin
visible: scanHeader.checked
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: _margin
rowSpacing: _margin
columns: 2
/*QGCLabel {
text: qsTr("Bottom Layer Altitude")
}
FactTextField {
fact: areaItem.bottomLayerAltitude
Layout.fillWidth: true
}
QGCLabel { text: qsTr("Number of Layers") }
FactTextField {
fact: areaItem.numberOfLayers
Layout.fillWidth: true
}
QGCLabel { text: qsTr("Layer Distance") }
FactTextField {
fact: areaItem.layerDistance
Layout.fillWidth: true
}*/
}
Item {
height: ScreenTools.defaultFontPixelHeight / 2
width: 1
}
} // Column - Scan
SectionHeader {
id: polylineHeader