Commit c0f4f735 authored by Valentin Platzgummer's avatar Valentin Platzgummer

various bugs solved, rebuildTransectsPhase1 profiled

parent 9a220b94
......@@ -2,7 +2,7 @@
\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {2}Documentation}{1}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Structure of QGroundControl with WiMA-Extension}{1}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}WiMA Main Window}{1}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Detail view of the QGC window, which appears after start-up. Marked in red is the button for switching to the plan view window, green indicates the flight view button (current window) and marked in magenta is the button for switching to the WiMA main window.}}{2}}
\newlabel{fig:QGCMainButtonExplain}{{1}{2}}
\@writefile{toc}{\contentsline {section}{\numberline {3}WiMA Main Window}{2}}
\@writefile{toc}{\contentsline {section}{\numberline {4}ArduPilot Simulator}{2}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}ArduPilot Simulator}{2}}
No preview for this file type
No preview for this file type
......@@ -21,9 +21,11 @@
\maketitle
\section{Introduction}
WiMA is a abbreviation for \textbf{Wi}reless \textbf{M}easurement \textbf{A}pplication.
Dieses Dokument soll einerseits die Funktionen der WiMA-Erweiterung dokumentieren und andererseits den Leser dazu anregen Fehler im Programm zu finden. Das Dokument ist in zwei abschnitte unterteilt. Die eigentliche Dokumentation und Vorschläge welche Funktionen getestet werden sollen. Da die WiMA-Erweiterung noch weiterentwickelt wird, können die Funktionen und das Aussehen des Programms von der in dieser Dokumentation dargestellten Inhalten abweichen.
Der Ordner deploy enthält eine unter Linux ausführbare Datei des Programms, mit dem nahmen "QGroundControl.AppImage".
This document was created to explain the functionality of the WiMA-Extension at one hand and to encourage the reader to find bugs inside the program. Hence the document is split in two parts. The first part contains instructions on how to use WiMA and the second part gives some suggestions for testing. As the extension is still beeing developed the contents demonstrated inside this document may differ from those ones in the program.
The folder "deploy" in the QGroundControl root directory (can be cloned from Gitlab) contains a AppImage of the program. QGroundControl can be launched by double-clicking the AppImage. Currently only a Linux version is available.
\section{Documentation}
\subsection{Structure of QGroundControl with WiMA-Extension}
......@@ -43,8 +45,9 @@ The \textbf{WiMA main window} is used to automatically generate flight paths on
\end{figure}
\section{WiMA Main Window}
\section{ArduPilot Simulator}
\subsection{WiMA Main Window}
By clicking the wave symbol (see fig. \ref{fig:QGCMainButtonExplain}; magenta square) the WiMA main window appears. After entering, at the left edge the WiMA toolstrip will appear
\subsection{ArduPilot Simulator}
For tasks like debugging, program verification or flight plan testing a simulated vehicle can be very useful. It can save time, money and prevent you from any excessive sunburns, if you forgot that you are actually outside, starring on your screen, exposed to the hot summer sun.
For this task the ArduPilot simulator can be used. It simulates a vehicle runnig the ArduPilot flight stack (firmware) on your local machine. Data is beeing published by the simulator via UDP and should ideally connect to QGroundControl without any further tweaks.
......
This diff is collapsed.
# callgrind format
version: 1
creator: callgrind-3.13.0
pid: 24465
cmd: ./QGroundControl.AppImage
part: 1
desc: I1 cache:
desc: D1 cache:
desc: LL cache:
desc: Timerange: Basic block 0 - 206412
desc: Trigger: Program termination
positions: line
events: Ir
summary: 0
totals: 0
# callgrind format
version: 1
creator: callgrind-3.13.0
pid: 24468
cmd: ./QGroundControl.AppImage
part: 1
desc: I1 cache:
desc: D1 cache:
desc: LL cache:
desc: Timerange: Basic block 0 - 366088887
desc: Trigger: Program termination
positions: line
events: Ir
summary: 0
totals: 0
......@@ -16,6 +16,7 @@
#include "SettingsManager.h"
#include "AppSettings.h"
#include "QGCQGeoCoordinate.h"
#include <valgrind/callgrind.h>
#include <QPolygonF>
......@@ -350,7 +351,10 @@ void TransectStyleComplexItem::_rebuildTransects(void)
return;
}
CALLGRIND_START_INSTRUMENTATION;
CALLGRIND_TOGGLE_COLLECT;
_rebuildTransectsPhase1();
CALLGRIND_TOGGLE_COLLECT;
if (_followTerrain) {
// Query the terrain data. Once available terrain heights will be calculated
......
......@@ -57,20 +57,19 @@ Rectangle {
anchors.right: parent.right
spacing: _margin
SectionHeader {
id: transectsHeader
text: qsTr("Transects")
id: generalHeader
text: qsTr("General")
}
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: _margin
rowSpacing: _margin
columns: 2
visible: transectsHeader.checked
visible: generalHeader.checked
QGCLabel { text: qsTr("Altitude") }
FactTextField {
......@@ -78,6 +77,23 @@ Rectangle {
Layout.fillWidth: true
//onUpdated: rSlider.value = missionItem.deltaR.value
}
}
SectionHeader {
id: transectsHeader
text: qsTr("Transects")
}
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: _margin
rowSpacing: _margin
columns: 2
visible: transectsHeader.checked
QGCLabel { text: qsTr("Delta R") }
FactTextField {
......@@ -107,6 +123,13 @@ Rectangle {
//onUpdated: angleSlider.value = missionItem.deltaAlpha.value
}
QGCLabel { text: qsTr("Min. Length") }
FactTextField {
fact: missionItem.transectMinLength
Layout.fillWidth: true
//onUpdated: angleSlider.value = missionItem.deltaAlpha.value
}
/*QGCSlider {
id: angleSlider
minimumValue: 0.3
......
......@@ -17,5 +17,14 @@
"max": 90,
"decimalPlaces": 1,
"defaultValue": 5.0
},
{
"name": "TransectMinLength",
"shortDescription": "The minimal length transects must have to be accepted.",
"type": "double",
"units": "m",
"min": 0.3,
"decimalPlaces": 1,
"defaultValue": 5.0
}
]
......@@ -2,13 +2,17 @@
#include "JsonHelper.h"
#include "QGCApplication.h"
const char* CircularSurveyComplexItem::settingsGroup = "CircularSurvey";
const char* CircularSurveyComplexItem::deltaRName = "DeltaR";
const char* CircularSurveyComplexItem::deltaAlphaName = "DeltaAlpha";
const char* CircularSurveyComplexItem::transectMinLengthName = "TransectMinLength";
const char* CircularSurveyComplexItem::jsonComplexItemTypeValue = "circularSurvey";
const char* CircularSurveyComplexItem::jsonDeltaRKey = "deltaR";
const char* CircularSurveyComplexItem::jsonDeltaAlphaKey = "deltaAlpha";
const char* CircularSurveyComplexItem::jsonTransectMinLengthKey = "transectMinLength";
const char* CircularSurveyComplexItem::jsonReferencePointLatKey = "referencePointLat";
const char* CircularSurveyComplexItem::jsonReferencePointLongKey = "referencePointLong";
const char* CircularSurveyComplexItem::jsonReferencePointAltKey = "referencePointAlt";
......@@ -19,15 +23,15 @@ CircularSurveyComplexItem::CircularSurveyComplexItem(Vehicle *vehicle, bool flyV
, _metaDataMap (FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/CircularSurvey.SettingsGroup.json"), this))
, _deltaR (settingsGroup, _metaDataMap[deltaRName])
, _deltaAlpha (settingsGroup, _metaDataMap[deltaAlphaName])
, _transectMinLength (settingsGroup, _metaDataMap[transectMinLengthName])
, _autoGenerated (false)
{
_editorQml = "qrc:/qml/CircularSurveyItemEditor.qml";
connect(&_deltaR, &Fact::valueChanged, this, &CircularSurveyComplexItem::_setDirty);
connect(&_deltaAlpha, &Fact::valueChanged, this, &CircularSurveyComplexItem::_setDirty);
connect(this, &CircularSurveyComplexItem::refPointChanged, this, &CircularSurveyComplexItem::_setDirty);
connect(&_deltaR, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_deltaAlpha, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_transectMinLength, &Fact::valueChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(this, &CircularSurveyComplexItem::refPointChanged, this, &CircularSurveyComplexItem::_rebuildTransects);
connect(&_updateTimer, &QTimer::timeout, this, &CircularSurveyComplexItem::_updateItem);
_updateTimer.start(100);
}
void CircularSurveyComplexItem::setRefPoint(const QGeoCoordinate &refPt)
......@@ -90,6 +94,7 @@ bool CircularSurveyComplexItem::load(const QJsonObject &complexObject, int seque
{ ComplexMissionItem::jsonComplexItemTypeKey, QJsonValue::String, true },
{ jsonDeltaRKey, QJsonValue::Double, true },
{ jsonDeltaAlphaKey, QJsonValue::Double, true },
{ jsonTransectMinLengthKey, QJsonValue::Double, true },
{ jsonReferencePointLatKey, QJsonValue::Double, true },
{ jsonReferencePointLongKey, QJsonValue::Double, true },
{ jsonReferencePointAltKey, QJsonValue::Double, true },
......@@ -123,6 +128,7 @@ bool CircularSurveyComplexItem::load(const QJsonObject &complexObject, int seque
_deltaR.setRawValue (complexObject[jsonDeltaRKey].toDouble());
_deltaAlpha.setRawValue (complexObject[jsonDeltaAlphaKey].toDouble());
_transectMinLength.setRawValue (complexObject[jsonTransectMinLengthKey].toDouble());
_referencePoint.setLongitude (complexObject[jsonReferencePointLongKey].toDouble());
_referencePoint.setLatitude (complexObject[jsonReferencePointLatKey].toDouble());
_referencePoint.setAltitude (complexObject[jsonReferencePointAltKey].toDouble());
......@@ -151,6 +157,7 @@ void CircularSurveyComplexItem::save(QJsonArray &planItems)
saveObject[jsonDeltaRKey] = _deltaR.rawValue().toDouble();
saveObject[jsonDeltaAlphaKey] = _deltaAlpha.rawValue().toDouble();
saveObject[jsonTransectMinLengthKey] = _transectMinLength.rawValue().toDouble();
saveObject[jsonReferencePointLongKey] = _referencePoint.longitude();
saveObject[jsonReferencePointLatKey] = _referencePoint.latitude();
saveObject[jsonReferencePointAltKey] = _referencePoint.altitude();
......@@ -332,13 +339,25 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
using namespace PlanimetryCalculus;
if ( _surveyAreaPolygon.count() < 3)
// check if input is valid
if ( _surveyAreaPolygon.count() < 3) {
_transects.clear();
return;
}
_transects.clear();
QPolygonF surveyPolygon = toQPolygonF(toCartesian2D(_surveyAreaPolygon.coordinateList(), _referencePoint));
// some more checks
if (!PolygonCalculus::isSimplePolygon(surveyPolygon)) {
_transects.clear();
return;
}
// even more checks
if (!PolygonCalculus::hasClockwiseWinding(surveyPolygon))
PolygonCalculus::reversePath(surveyPolygon);
QVector<double> distances;
for (const QPointF &p : surveyPolygon) distances.append(norm(p));
......@@ -351,10 +370,10 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
return;
// fetch input data
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 lmin = _transectMinLength.rawValue().toDouble();
double r_min = dr; // meter
double r_max = (*std::max_element(distances.begin(), distances.end())); // meter
......@@ -380,13 +399,11 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
originInside = false;
}
// qWarning("r_min, r_max:");
// qWarning() << r_min;
// qWarning() << r_max;
QList<QPolygonF> convexPolygons;
decomposeToConvex(surveyPolygon, convexPolygons);
// generate transects
QList<QList<QPointF>> fullPath;
for (int i = 0; i < convexPolygons.size(); i++) {
const QPolygonF &polygon = convexPolygons[i];
......@@ -471,10 +488,25 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
fullPath.append(currPolyPath);
}
}
if (fullPath.size() == 0)
return;
// optimize path to lawn pattern
// remove short transects
for (int i = 0; i < fullPath.size(); i++) {
auto transect = fullPath[i];
double len = 0;
for (int j = 0; j < transect.size()-1; ++j) {
len += PlanimetryCalculus::distance(transect[j], transect[j+1]);
}
if (len < lmin)
fullPath.removeAt(i--);
}
if (fullPath.size() == 0)
return;
// optimize path to lawn pattern
QList<QPointF> currentSection = fullPath.takeFirst();
if ( currentSection.isEmpty() )
return;
......@@ -493,6 +525,7 @@ void CircularSurveyComplexItem::_rebuildTransectsPhase1()
if ( dist < minDist ) {
minDist = dist;
index = i;
reversePath = false;
}
dist = PlanimetryCalculus::distance(endVertex, iteratorPath.last());
if (dist < minDist) {
......@@ -539,16 +572,15 @@ void CircularSurveyComplexItem::_recalcCameraShots()
_cameraShots = 0;
}
void CircularSurveyComplexItem::_updateItem()
{
if (_dirty) {
_rebuildTransects();
qDebug() << "CircularSurveyComplexItem::_updateItem()";
setDirty(false);
}
Fact *CircularSurveyComplexItem::transectMinLength()
{
return &_transectMinLength;
}
/*!
\class CircularSurveyComplexItem
\inmodule Wima
......@@ -560,3 +592,5 @@ void CircularSurveyComplexItem::_updateItem()
\sa WimaArea
*/
......@@ -21,6 +21,7 @@ public:
Q_PROPERTY(QGeoCoordinate refPoint READ refPoint WRITE setRefPoint NOTIFY refPointChanged)
Q_PROPERTY(Fact* deltaR READ deltaR CONSTANT)
Q_PROPERTY(Fact* deltaAlpha READ deltaAlpha CONSTANT)
Q_PROPERTY(Fact* transectMinLength READ transectMinLength CONSTANT)
Q_PROPERTY(bool autoGenerated READ autoGenerated NOTIFY autoGeneratedChanged)
// Property setters
......@@ -32,6 +33,7 @@ public:
QGeoCoordinate refPoint() const;
Fact *deltaR();
Fact *deltaAlpha();
Fact *transectMinLength();
// Is true if survey was automatically generated, prevents initialisation from gui.
bool autoGenerated();
......@@ -56,10 +58,12 @@ public:
static const char* settingsGroup;
static const char* deltaRName;
static const char* deltaAlphaName;
static const char* transectMinLengthName;
static const char* jsonComplexItemTypeValue;
static const char* jsonDeltaRKey;
static const char* jsonDeltaAlphaKey;
static const char* jsonTransectMinLengthKey;
static const char* jsonReferencePointLongKey;
static const char* jsonReferencePointLatKey;
static const char* jsonReferencePointAltKey;
......@@ -73,7 +77,6 @@ private slots:
void _rebuildTransectsPhase1 (void) final;
void _recalcComplexDistance (void) final;
void _recalcCameraShots (void) final;
void _updateItem (void);
signals:
......@@ -89,6 +92,7 @@ private:
SettingsFact _deltaR;
SettingsFact _deltaAlpha;
SettingsFact _transectMinLength;
QTimer _updateTimer;
......
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