Commit 887e51f1 authored by Valentin Platzgummer's avatar Valentin Platzgummer

hello

parent 56d4d813
optimize circular survey optimize circular survey
remove Reference artefacts remove Reference artefacts
solve Dijkstra issue (no path found, for some geometries) solve Dijkstra issue (path not found, or not minimal)
...@@ -225,6 +225,7 @@ ...@@ -225,6 +225,7 @@
<file alias="QGroundControl/Controls/DragCoordinate.qml">src/WimaView/DragCoordinate.qml</file> <file alias="QGroundControl/Controls/DragCoordinate.qml">src/WimaView/DragCoordinate.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicatorDrag.qml">src/WimaView/CoordinateIndicatorDrag.qml</file> <file alias="QGroundControl/Controls/CoordinateIndicatorDrag.qml">src/WimaView/CoordinateIndicatorDrag.qml</file>
<file alias="QGroundControl/Controls/CoordinateIndicator.qml">src/WimaView/CoordinateIndicator.qml</file> <file alias="QGroundControl/Controls/CoordinateIndicator.qml">src/WimaView/CoordinateIndicator.qml</file>
<file alias="QGroundControl/Controls/WimaJoinedAreaMapVisual.qml">src/WimaView/WimaJoinedAreaMapVisual.qml</file>
</qresource> </qresource>
<qresource prefix="/json"> <qresource prefix="/json">
<file alias="APMMavlinkStreamRate.SettingsGroup.json">src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file> <file alias="APMMavlinkStreamRate.SettingsGroup.json">src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file>
......
...@@ -81,15 +81,15 @@ Rectangle { ...@@ -81,15 +81,15 @@ Rectangle {
/*QGCSlider { /*QGCSlider {
id: rSlider id: rSlider
minimumValue: 0.1 minimumValue: 0.3
maximumValue: 5 maximumValue: 20
stepSize: 0.1 stepSize: 0.1
tickmarksEnabled: false tickmarksEnabled: false
Layout.fillWidth: true Layout.fillWidth: true
Layout.columnSpan: 2 Layout.columnSpan: 2
Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5 Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
onValueChanged: missionItem.deltaR.value = value onValueChanged: missionItem.deltaR.value = value
Component.onCompleted: value = missionItem.deltaR.value Component.onCompleted: value = missionItem.deltaR.defaultValue
updateValueWhileDragging: true updateValueWhileDragging: true
}*/ }*/
...@@ -110,7 +110,7 @@ Rectangle { ...@@ -110,7 +110,7 @@ Rectangle {
Layout.columnSpan: 2 Layout.columnSpan: 2
Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5 Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
onValueChanged: missionItem.deltaAlpha.value = value onValueChanged: missionItem.deltaAlpha.value = value
Component.onCompleted: value = missionItem.deltaAlpha.value Component.onCompleted: value = missionItem.deltaAlpha.defaultValue
updateValueWhileDragging: true updateValueWhileDragging: true
} }
} }
......
...@@ -87,6 +87,7 @@ FlyAreaItemEditor 1.0 FlyAreaItemEditor.qml ...@@ -87,6 +87,7 @@ FlyAreaItemEditor 1.0 FlyAreaItemEditor.qml
WimaMapVisual 1.0 WimaMapVisual.qml WimaMapVisual 1.0 WimaMapVisual.qml
WimaMeasurementAreaMapVisual 1.0 WimaMeasurementAreaMapVisual.qml WimaMeasurementAreaMapVisual 1.0 WimaMeasurementAreaMapVisual.qml
WimaJoinedAreaMapVisual 1.0 WimaJoinedAreaMapVisual.qml
WimaMeasurementAreaEditor 1.0 WimaMeasurementAreaEditor.qml WimaMeasurementAreaEditor 1.0 WimaMeasurementAreaEditor.qml
WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.qml WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.qml
WimaAreaMapVisual 1.0 WimaAreaMapVisual.qml WimaAreaMapVisual 1.0 WimaAreaMapVisual.qml
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
"units": "m", "units": "m",
"min": 0.3, "min": 0.3,
"decimalPlaces": 1, "decimalPlaces": 1,
"defaultValue": 3 "defaultValue": 20
}, },
{ {
"name": "DeltaAlpha", "name": "DeltaAlpha",
...@@ -15,6 +15,6 @@ ...@@ -15,6 +15,6 @@
"units": "Deg", "units": "Deg",
"min": 0.3, "min": 0.3,
"decimalPlaces": 1, "decimalPlaces": 1,
"defaultValue": 1 "defaultValue": 5
} }
] ]
...@@ -111,8 +111,10 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1() ...@@ -111,8 +111,10 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
return; return;
double dalpha = _deltaAlpha.rawValue().toDouble()/180*M_PI; // radiants double dalpha = _deltaAlpha.rawValue().toDouble()/180.0*M_PI; // radiants
double dr = _deltaR.rawValue().toDouble(); // meter double dr = _deltaR.rawValue().toDouble(); // meter
// double dalpha = 1.0/180.0*M_PI; // radiants
// double dr = 10.0; // meter
double r_min = dr; // meter double r_min = dr; // meter
double r_max = (*std::max_element(distances.begin(), distances.end())); // meter double r_max = (*std::max_element(distances.begin(), distances.end())); // meter
...@@ -230,42 +232,43 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1() ...@@ -230,42 +232,43 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
} }
} }
// optimize path to lawn pattern // // optimize path to lawn pattern
if (fullPath.size() == 0) // if (fullPath.size() == 0)
return; // return;
QList<QPointF> currentSection = fullPath.takeFirst(); // QList<QPointF> currentSection = fullPath.takeFirst();
QList<QList<QPointF>> optiPath; // optimized path // QList<QList<QPointF>> optiPath; // optimized path
while( !fullPath.empty() ) { // while( !fullPath.empty() ) {
optiPath.append(currentSection); // optiPath.append(currentSection);
QPointF endVertex = currentSection.last(); // QPointF endVertex = currentSection.last();
double minDist = std::numeric_limits<double>::infinity(); // double minDist = std::numeric_limits<double>::infinity();
int index = 0; // int index = 0;
bool reversePath = false; // bool reversePath = false;
// iterate over all paths in fullPath and assign the one with the shortest distance to endVertex to currentSection // // iterate over all paths in fullPath and assign the one with the shortest distance to endVertex to currentSection
for (int i = 0; i < fullPath.size(); i++) { // for (int i = 0; i < fullPath.size(); i++) {
auto iteratorPath = fullPath[i]; // auto iteratorPath = fullPath[i];
double dist = PlanimetryCalculus::distance(endVertex, iteratorPath.first()); // double dist = PlanimetryCalculus::distance(endVertex, iteratorPath.first());
if ( dist < minDist ) { // if ( dist < minDist ) {
minDist = dist; // minDist = dist;
index = i; // index = i;
} // }
dist = PlanimetryCalculus::distance(endVertex, iteratorPath.last()); // dist = PlanimetryCalculus::distance(endVertex, iteratorPath.last());
if (dist < minDist) { // if (dist < minDist) {
minDist = dist; // minDist = dist;
index = i; // index = i;
reversePath = true; // reversePath = true;
} // }
} // }
currentSection = fullPath.takeAt(index); // currentSection = fullPath.takeAt(index);
if (reversePath) { // if (reversePath) {
PolygonCalculus::reversePath(currentSection); // PolygonCalculus::reversePath(currentSection);
} // }
} // }
// convert to CoordInfo_t // convert to CoordInfo_t
for ( const QList<QPointF> &transect : optiPath) { // for ( const QList<QPointF> &transect : optiPath) {
for ( const QList<QPointF> &transect : fullPath) {
QList<QGeoCoordinate> geoPath = toGeo(transect, _referencePoint); QList<QGeoCoordinate> geoPath = toGeo(transect, _referencePoint);
QList<CoordInfo_t> transectList; QList<CoordInfo_t> transectList;
for ( const QGeoCoordinate &coordinate : geoPath) { for ( const QGeoCoordinate &coordinate : geoPath) {
......
...@@ -16,7 +16,7 @@ namespace OptimisationTools { ...@@ -16,7 +16,7 @@ namespace OptimisationTools {
* \sa QList * \sa QList
*/ */
template <class T> template <class T>
bool dijkstraAlgorithm(const QList<T> &elements, int startIndex, int endIndex, QList<T> &elementPath, std::function<double(const T &, const T &)> distance) bool dijkstraAlgorithm(const QList<T> &elements, int startIndex, int endIndex, QList<T> &elementPath, std::function<double(const T &, const T &)> distanceDij)
{ {
if ( elements.isEmpty() || startIndex < 0 if ( elements.isEmpty() || startIndex < 0
|| startIndex >= elements.size() || endIndex < 0 || startIndex >= elements.size() || endIndex < 0
...@@ -53,7 +53,7 @@ namespace OptimisationTools { ...@@ -53,7 +53,7 @@ namespace OptimisationTools {
while (workingSet.size() > 0) { while (workingSet.size() > 0) {
// serach Node with minimal distance // serach Node with minimal distance
double minDist = std::numeric_limits<qreal>::infinity(); double minDist = std::numeric_limits<qreal>::infinity();
int minDistIndex = 0; int minDistIndex = -1;
for (int i = 0; i < workingSet.size(); i++) { for (int i = 0; i < workingSet.size(); i++) {
Node* node = workingSet.value(i); Node* node = workingSet.value(i);
double dist = node->distance; double dist = node->distance;
...@@ -62,12 +62,15 @@ namespace OptimisationTools { ...@@ -62,12 +62,15 @@ namespace OptimisationTools {
minDistIndex = i; minDistIndex = i;
} }
} }
if (minDistIndex == -1)
return false;
Node* u = workingSet.takeAt(minDistIndex); Node* u = workingSet.takeAt(minDistIndex);
//update distance //update distance
for (int i = 0; i < workingSet.size(); i++) { for (int i = 0; i < workingSet.size(); i++) {
Node* v = workingSet[i]; Node* v = workingSet[i];
double dist = distance(u->element, v->element); double dist = distanceDij(u->element, v->element);
// is ther a alternative path which is shorter? // is ther a alternative path which is shorter?
double alternative = u->distance + dist; double alternative = u->distance + dist;
if (alternative < v->distance) { if (alternative < v->distance) {
......
...@@ -167,7 +167,7 @@ namespace PolygonCalculus { ...@@ -167,7 +167,7 @@ namespace PolygonCalculus {
int startIndex = 0; int startIndex = 0;
bool crossContainsWalker = true; bool crossContainsWalker = true;
for (int i = 0; i < walkerPoly->size(); i++) { for (int i = 0; i < walkerPoly->size(); i++) {
if ( !crossPoly->contains(walkerPoly->value(i)) ) { if ( !contains(*crossPoly, walkerPoly->at(i)) ) {
crossContainsWalker = false; crossContainsWalker = false;
startIndex = i; startIndex = i;
break; break;
...@@ -178,11 +178,10 @@ namespace PolygonCalculus { ...@@ -178,11 +178,10 @@ namespace PolygonCalculus {
joinedPolygon.append(*crossPoly); joinedPolygon.append(*crossPoly);
return JoinPolygonError::PolygonJoined; return JoinPolygonError::PolygonJoined;
} }
QPointF lastVertex = walkerPoly->last(); QPointF currentVertex = walkerPoly->at(startIndex);
QPointF currentVertex = walkerPoly->value(startIndex);
QPointF startVertex = currentVertex; QPointF startVertex = currentVertex;
// possible nextVertex (if no intersection between currentVertex and protoVertex with crossPoly) // possible nextVertex (if no intersection between currentVertex and protoVertex with crossPoly)
int nextVertexNumber = nextVertexIndex(walkerPoly->size(), startIndex); int nextVertexNumber = nextVertexIndex(walkerPoly->size(), startIndex);
QPointF protoNextVertex = walkerPoly->value(nextVertexNumber); QPointF protoNextVertex = walkerPoly->value(nextVertexNumber);
while (1) { while (1) {
//qDebug("nextVertexNumber: %i", nextVertexNumber); //qDebug("nextVertexNumber: %i", nextVertexNumber);
...@@ -206,14 +205,13 @@ namespace PolygonCalculus { ...@@ -206,14 +205,13 @@ namespace PolygonCalculus {
for (int i = 0; i < intersectionList.size(); i++) { for (int i = 0; i < intersectionList.size(); i++) {
double currentDist = PlanimetryCalculus::distance(currentVertex, intersectionList[i]); double currentDist = PlanimetryCalculus::distance(currentVertex, intersectionList[i]);
if ( minDist > currentDist && currentVertex != intersectionList[i]) { if ( minDist > currentDist && !qFuzzyIsNull(distance(currentVertex, intersectionList[i])) ) {
minDist = currentDist; minDist = currentDist;
minDistIndex = i; minDistIndex = i;
} }
} }
if (minDistIndex != -1){ if (minDistIndex != -1){
lastVertex = currentVertex;
currentVertex = intersectionList.value(minDistIndex); currentVertex = intersectionList.value(minDistIndex);
QPair<int, int> neighbours = neighbourList.value(minDistIndex); QPair<int, int> neighbours = neighbourList.value(minDistIndex);
protoNextVertex = crossPoly->value(neighbours.second); protoNextVertex = crossPoly->value(neighbours.second);
...@@ -224,14 +222,12 @@ namespace PolygonCalculus { ...@@ -224,14 +222,12 @@ namespace PolygonCalculus {
walkerPoly = crossPoly; walkerPoly = crossPoly;
crossPoly = temp; crossPoly = temp;
} else { } else {
lastVertex = currentVertex;
currentVertex = walkerPoly->value(nextVertexNumber); currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber); protoNextVertex = walkerPoly->value(nextVertexNumber);
} }
} else { } else {
lastVertex = currentVertex;
currentVertex = walkerPoly->value(nextVertexNumber); currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber); nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber); protoNextVertex = walkerPoly->value(nextVertexNumber);
...@@ -479,7 +475,7 @@ namespace PolygonCalculus { ...@@ -479,7 +475,7 @@ namespace PolygonCalculus {
return; return;
} }
bool shortestPath(QPolygonF polygon, QPointF startVertex, const QPointF &endVertex, QList<QPointF> &shortestPath) bool shortestPath(QPolygonF polygon,const QPointF &startVertex, const QPointF &endVertex, QList<QPointF> &shortestPath)
{ {
using namespace PlanimetryCalculus; using namespace PlanimetryCalculus;
offsetPolygon(polygon, 0.01); // solves numerical errors offsetPolygon(polygon, 0.01); // solves numerical errors
...@@ -488,7 +484,7 @@ namespace PolygonCalculus { ...@@ -488,7 +484,7 @@ namespace PolygonCalculus {
// lambda // lambda
QPolygonF polygon2 = polygon; QPolygonF polygon2 = polygon;
offsetPolygon(polygon2, 0.01); // solves numerical errors offsetPolygon(polygon2, 0.01); // solves numerical errors
std::function<double(const QPointF &, const QPointF &)> distance = [polygon2](const QPointF &p1, const QPointF &p2) -> double { std::function<double(const QPointF &, const QPointF &)> distanceDij = [polygon2](const QPointF &p1, const QPointF &p2) -> double {
if (containsPath(polygon2, p1, p2)){ if (containsPath(polygon2, p1, p2)){
double dx = p1.x()-p2.x(); double dx = p1.x()-p2.x();
double dy = p1.y()-p2.y(); double dy = p1.y()-p2.y();
...@@ -503,7 +499,7 @@ namespace PolygonCalculus { ...@@ -503,7 +499,7 @@ namespace PolygonCalculus {
for (int i = 0; i < polygon.size(); i++) { for (int i = 0; i < polygon.size(); i++) {
elementList.append(polygon[i]); elementList.append(polygon[i]);
} }
return OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distance); return OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distanceDij);
} else { } else {
return false; return false;
} }
......
...@@ -26,7 +26,7 @@ namespace PolygonCalculus { ...@@ -26,7 +26,7 @@ namespace PolygonCalculus {
void offsetPolygon (QPolygonF &polygon, double offset); void offsetPolygon (QPolygonF &polygon, double offset);
bool containsPath (QPolygonF polygon, const QPointF &c1, const QPointF &c2); bool containsPath (QPolygonF polygon, const QPointF &c1, const QPointF &c2);
void decomposeToConvex (const QPolygonF &polygon, QList<QPolygonF> &convexPolygons); void decomposeToConvex (const QPolygonF &polygon, QList<QPolygonF> &convexPolygons);
bool shortestPath (QPolygonF polygon, QPointF startVertex, const QPointF &endVertex, QList<QPointF> &shortestPath); bool shortestPath (QPolygonF polygon, const QPointF &startVertex, const QPointF &endVertex, QList<QPointF> &shortestPath);
QPolygonF toQPolygonF(const QVector3DList &polygon); QPolygonF toQPolygonF(const QVector3DList &polygon);
QPolygonF toQPolygonF(const QPointFList &polygon); QPolygonF toQPolygonF(const QPointFList &polygon);
......
...@@ -263,6 +263,9 @@ bool WimaPlaner::updateMission() ...@@ -263,6 +263,9 @@ bool WimaPlaner::updateMission()
} }
QGeoCoordinate start = _serviceArea.center(); QGeoCoordinate start = _serviceArea.center();
QGeoCoordinate end = survey->visualTransectPoints().first().value<QGeoCoordinate>(); QGeoCoordinate end = survey->visualTransectPoints().first().value<QGeoCoordinate>();
if (!_visualItems.contains(&_joinedArea))
_visualItems.append(&_joinedArea);
QList<QGeoCoordinate> path; QList<QGeoCoordinate> path;
if ( !calcShortestPath(start, end, path)) { if ( !calcShortestPath(start, end, path)) {
qgcApp()->showMessage( QString(tr("Not able to calculate the path from takeoff position to measurement area.")).toLocal8Bit().data()); qgcApp()->showMessage( QString(tr("Not able to calculate the path from takeoff position to measurement area.")).toLocal8Bit().data());
...@@ -576,10 +579,10 @@ bool WimaPlaner::calcShortestPath(const QGeoCoordinate &start, const QGeoCoordin ...@@ -576,10 +579,10 @@ bool WimaPlaner::calcShortestPath(const QGeoCoordinate &start, const QGeoCoordin
using namespace PolygonCalculus; using namespace PolygonCalculus;
QList<QPointF> path2D; QList<QPointF> path2D;
bool retVal = PolygonCalculus::shortestPath( bool retVal = PolygonCalculus::shortestPath(
toQPolygonF(toCartesian2D(_joinedArea.coordinateList(), /*origin*/start)), toQPolygonF(toCartesian2D(_joinedArea.coordinateList(), /*origin*/ start)),
/*start point*/ QPointF(0,0), /*start point*/ QPointF(0,0),
/*destination*/toCartesian2D(destination, start), /*destination*/ toCartesian2D(destination, start),
/*shortest path*/path2D); /*shortest path*/ path2D);
path.append(toGeo(path2D, /*origin*/start)); path.append(toGeo(path2D, /*origin*/start));
return retVal; return retVal;
......
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtLocation 5.3
import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FlightMap 1.0
/// Wima Global Measurement Area visuals
Item {
id: _root
property var map ///< Map control to place item in
property var qgcView ///< QGCView to use for popping dialogs
property var areaItem: object
property var _polygon: areaItem
//property var _polyline: areaItem.polyline
signal clicked(int sequenceNumber)
/// Add an initial 4 sided polygon if there is none
function _addInitialPolygon() {
if (_polygon.count < 3) {
// Initial polygon is inset to take 2/3rds space
var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height)
rect.x += (rect.width * 0.25) / 2
rect.y += (rect.height * 0.25) / 2
rect.width *= 0.25
rect.height *= 0.25
var centerCoord = map.toCoordinate(Qt.point(rect.x + (rect.width / 2), rect.y + (rect.height / 2)), false /* clipToViewPort */)
var topLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y), false /* clipToViewPort */)
var topRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y), false /* clipToViewPort */)
var bottomLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y + rect.height), false /* clipToViewPort */)
var bottomRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y + rect.height), false /* clipToViewPort */)
// Adjust polygon to max size
var maxSize = 100
var halfWidthMeters = Math.min(topLeftCoord.distanceTo(topRightCoord), maxSize) / 2
var halfHeightMeters = Math.min(topLeftCoord.distanceTo(bottomLeftCoord), maxSize) / 2
topLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 0)
topRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 0)
bottomLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 180)
bottomRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 180)
_polygon.appendVertex(topLeftCoord)
_polygon.appendVertex(topRightCoord)
_polygon.appendVertex(bottomRightCoord)
_polygon.appendVertex(bottomLeftCoord)
}
}
/*function _addInitialPolyline(){
_polyline.setStartVertexIndex(0);
_polyline.setEndVertexIndex(1);
}*/
Component.onCompleted: {
//_addInitialPolygon()
//_addInitialPolyline()
}
Component.onDestruction: {
}
WimaMapPolygonVisuals {
qgcView: _root.qgcView
mapControl: map
mapPolygon: _polygon
borderWidth: 1
borderColor: "black"
interiorColor: "blue"
interiorOpacity: 0.25
}
/*WimaMapPolylineVisuals {
qgcView: _root.qgcView
mapControl: map
mapPolyline: _polyline
lineWidth: 4
lineColor: interactive ? "white" : "yellow"
enableSplitHandels: false
enableDragHandels: true
edgeHandelsOnly: true
}*/
}
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