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

hello

parent 56d4d813
optimize circular survey
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 @@
<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/CoordinateIndicator.qml">src/WimaView/CoordinateIndicator.qml</file>
<file alias="QGroundControl/Controls/WimaJoinedAreaMapVisual.qml">src/WimaView/WimaJoinedAreaMapVisual.qml</file>
</qresource>
<qresource prefix="/json">
<file alias="APMMavlinkStreamRate.SettingsGroup.json">src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file>
......
......@@ -81,15 +81,15 @@ Rectangle {
/*QGCSlider {
id: rSlider
minimumValue: 0.1
maximumValue: 5
minimumValue: 0.3
maximumValue: 20
stepSize: 0.1
tickmarksEnabled: false
Layout.fillWidth: true
Layout.columnSpan: 2
Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
onValueChanged: missionItem.deltaR.value = value
Component.onCompleted: value = missionItem.deltaR.value
Component.onCompleted: value = missionItem.deltaR.defaultValue
updateValueWhileDragging: true
}*/
......@@ -110,7 +110,7 @@ Rectangle {
Layout.columnSpan: 2
Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
onValueChanged: missionItem.deltaAlpha.value = value
Component.onCompleted: value = missionItem.deltaAlpha.value
Component.onCompleted: value = missionItem.deltaAlpha.defaultValue
updateValueWhileDragging: true
}
}
......
......@@ -87,6 +87,7 @@ FlyAreaItemEditor 1.0 FlyAreaItemEditor.qml
WimaMapVisual 1.0 WimaMapVisual.qml
WimaMeasurementAreaMapVisual 1.0 WimaMeasurementAreaMapVisual.qml
WimaJoinedAreaMapVisual 1.0 WimaJoinedAreaMapVisual.qml
WimaMeasurementAreaEditor 1.0 WimaMeasurementAreaEditor.qml
WimaServiceAreaMapVisual 1.0 WimaServiceAreaMapVisual.qml
WimaAreaMapVisual 1.0 WimaAreaMapVisual.qml
......
......@@ -6,7 +6,7 @@
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 3
"defaultValue": 20
},
{
"name": "DeltaAlpha",
......@@ -15,6 +15,6 @@
"units": "Deg",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 1
"defaultValue": 5
}
]
......@@ -111,8 +111,10 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
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 dalpha = 1.0/180.0*M_PI; // radiants
// double dr = 10.0; // meter
double r_min = dr; // meter
double r_max = (*std::max_element(distances.begin(), distances.end())); // meter
......@@ -230,42 +232,43 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
}
}
// optimize path to lawn pattern
if (fullPath.size() == 0)
return;
QList<QPointF> currentSection = fullPath.takeFirst();
QList<QList<QPointF>> optiPath; // optimized path
while( !fullPath.empty() ) {
optiPath.append(currentSection);
QPointF endVertex = currentSection.last();
double minDist = std::numeric_limits<double>::infinity();
int index = 0;
bool reversePath = false;
// 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++) {
auto iteratorPath = fullPath[i];
double dist = PlanimetryCalculus::distance(endVertex, iteratorPath.first());
if ( dist < minDist ) {
minDist = dist;
index = i;
}
dist = PlanimetryCalculus::distance(endVertex, iteratorPath.last());
if (dist < minDist) {
minDist = dist;
index = i;
reversePath = true;
}
}
currentSection = fullPath.takeAt(index);
if (reversePath) {
PolygonCalculus::reversePath(currentSection);
}
}
// // optimize path to lawn pattern
// if (fullPath.size() == 0)
// return;
// QList<QPointF> currentSection = fullPath.takeFirst();
// QList<QList<QPointF>> optiPath; // optimized path
// while( !fullPath.empty() ) {
// optiPath.append(currentSection);
// QPointF endVertex = currentSection.last();
// double minDist = std::numeric_limits<double>::infinity();
// int index = 0;
// bool reversePath = false;
// // 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++) {
// auto iteratorPath = fullPath[i];
// double dist = PlanimetryCalculus::distance(endVertex, iteratorPath.first());
// if ( dist < minDist ) {
// minDist = dist;
// index = i;
// }
// dist = PlanimetryCalculus::distance(endVertex, iteratorPath.last());
// if (dist < minDist) {
// minDist = dist;
// index = i;
// reversePath = true;
// }
// }
// currentSection = fullPath.takeAt(index);
// if (reversePath) {
// PolygonCalculus::reversePath(currentSection);
// }
// }
// 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<CoordInfo_t> transectList;
for ( const QGeoCoordinate &coordinate : geoPath) {
......
......@@ -16,7 +16,7 @@ namespace OptimisationTools {
* \sa QList
*/
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
|| startIndex >= elements.size() || endIndex < 0
......@@ -53,7 +53,7 @@ namespace OptimisationTools {
while (workingSet.size() > 0) {
// serach Node with minimal distance
double minDist = std::numeric_limits<qreal>::infinity();
int minDistIndex = 0;
int minDistIndex = -1;
for (int i = 0; i < workingSet.size(); i++) {
Node* node = workingSet.value(i);
double dist = node->distance;
......@@ -62,12 +62,15 @@ namespace OptimisationTools {
minDistIndex = i;
}
}
if (minDistIndex == -1)
return false;
Node* u = workingSet.takeAt(minDistIndex);
//update distance
for (int i = 0; i < workingSet.size(); 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?
double alternative = u->distance + dist;
if (alternative < v->distance) {
......
......@@ -167,7 +167,7 @@ namespace PolygonCalculus {
int startIndex = 0;
bool crossContainsWalker = true;
for (int i = 0; i < walkerPoly->size(); i++) {
if ( !crossPoly->contains(walkerPoly->value(i)) ) {
if ( !contains(*crossPoly, walkerPoly->at(i)) ) {
crossContainsWalker = false;
startIndex = i;
break;
......@@ -178,11 +178,10 @@ namespace PolygonCalculus {
joinedPolygon.append(*crossPoly);
return JoinPolygonError::PolygonJoined;
}
QPointF lastVertex = walkerPoly->last();
QPointF currentVertex = walkerPoly->value(startIndex);
QPointF currentVertex = walkerPoly->at(startIndex);
QPointF startVertex = currentVertex;
// 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);
while (1) {
//qDebug("nextVertexNumber: %i", nextVertexNumber);
......@@ -206,14 +205,13 @@ namespace PolygonCalculus {
for (int i = 0; i < intersectionList.size(); i++) {
double currentDist = PlanimetryCalculus::distance(currentVertex, intersectionList[i]);
if ( minDist > currentDist && currentVertex != intersectionList[i]) {
if ( minDist > currentDist && !qFuzzyIsNull(distance(currentVertex, intersectionList[i])) ) {
minDist = currentDist;
minDistIndex = i;
}
}
if (minDistIndex != -1){
lastVertex = currentVertex;
currentVertex = intersectionList.value(minDistIndex);
QPair<int, int> neighbours = neighbourList.value(minDistIndex);
protoNextVertex = crossPoly->value(neighbours.second);
......@@ -224,14 +222,12 @@ namespace PolygonCalculus {
walkerPoly = crossPoly;
crossPoly = temp;
} else {
lastVertex = currentVertex;
currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber);
}
} else {
lastVertex = currentVertex;
currentVertex = walkerPoly->value(nextVertexNumber);
nextVertexNumber = nextVertexIndex(walkerPoly->size(), nextVertexNumber);
protoNextVertex = walkerPoly->value(nextVertexNumber);
......@@ -479,7 +475,7 @@ namespace PolygonCalculus {
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;
offsetPolygon(polygon, 0.01); // solves numerical errors
......@@ -488,7 +484,7 @@ namespace PolygonCalculus {
// lambda
QPolygonF polygon2 = polygon;
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)){
double dx = p1.x()-p2.x();
double dy = p1.y()-p2.y();
......@@ -503,7 +499,7 @@ namespace PolygonCalculus {
for (int i = 0; i < polygon.size(); i++) {
elementList.append(polygon[i]);
}
return OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distance);
return OptimisationTools::dijkstraAlgorithm<QPointF>(elementList, 0, 1, shortestPath, distanceDij);
} else {
return false;
}
......
......@@ -26,7 +26,7 @@ namespace PolygonCalculus {
void offsetPolygon (QPolygonF &polygon, double offset);
bool containsPath (QPolygonF polygon, const QPointF &c1, const QPointF &c2);
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 QPointFList &polygon);
......
......@@ -263,6 +263,9 @@ bool WimaPlaner::updateMission()
}
QGeoCoordinate start = _serviceArea.center();
QGeoCoordinate end = survey->visualTransectPoints().first().value<QGeoCoordinate>();
if (!_visualItems.contains(&_joinedArea))
_visualItems.append(&_joinedArea);
QList<QGeoCoordinate> path;
if ( !calcShortestPath(start, end, path)) {
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
using namespace PolygonCalculus;
QList<QPointF> path2D;
bool retVal = PolygonCalculus::shortestPath(
toQPolygonF(toCartesian2D(_joinedArea.coordinateList(), /*origin*/start)),
toQPolygonF(toCartesian2D(_joinedArea.coordinateList(), /*origin*/ start)),
/*start point*/ QPointF(0,0),
/*destination*/toCartesian2D(destination, start),
/*shortest path*/path2D);
/*destination*/ toCartesian2D(destination, start),
/*shortest path*/ path2D);
path.append(toGeo(path2D, /*origin*/start));
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