Commit 01c12f05 authored by Valentin Platzgummer's avatar Valentin Platzgummer

circular survey: runs working

parent 9282a10c
This diff is collapsed.
...@@ -130,7 +130,7 @@ Rectangle { ...@@ -130,7 +130,7 @@ Rectangle {
columnSpacing: _margin columnSpacing: _margin
rowSpacing: _margin rowSpacing: _margin
columns: 4 columns: 6
Repeater{ Repeater{
id: variantRepeater id: variantRepeater
...@@ -141,9 +141,9 @@ Rectangle { ...@@ -141,9 +141,9 @@ Rectangle {
property int len: missionItem.variantNames.length property int len: missionItem.variantNames.length
model: len model: len
QGCRadioButton { delegate: QGCRadioButton {
checked: index === variantRepeater.variant checked: index === variantRepeater.variant
text: variantRepeater.names[index] text: variantRepeater.names[index]
onCheckedChanged: { onCheckedChanged: {
if (checked){ if (checked){
...@@ -154,6 +154,44 @@ Rectangle { ...@@ -154,6 +154,44 @@ Rectangle {
} }
} }
} }
QGCLabel {
text: qsTr("Runs")
}
FactTextField {
fact: missionItem.numRuns
}
GridLayout{
Layout.columnSpan: 2
columnSpacing: _margin
rowSpacing: _margin
columns: 6
Repeater{
id: runRepeater
property var fact: missionItem.run
property int run: fact.value
property var names: missionItem.runNames
property int len: missionItem.runNames.length
model: len > 1 ? len : 0
QGCRadioButton {
checked: index === runRepeater.run
text: runRepeater.names[index]
onCheckedChanged: {
if (checked){
missionItem.run.value = index
}
checked = Qt.binding(function(){ return index === runRepeater.run})
}
}
}
}
} }
SectionHeader { SectionHeader {
...@@ -171,8 +209,8 @@ Rectangle { ...@@ -171,8 +209,8 @@ Rectangle {
QGCLabel { text: qsTr("Distance") } QGCLabel { text: qsTr("Distance") }
FactTextField { FactTextField {
fact: missionItem.transectDistance fact: missionItem.transectDistance
Layout.fillWidth: true Layout.fillWidth: true
} }
/*QGCSlider { /*QGCSlider {
......
This diff is collapsed.
...@@ -35,11 +35,14 @@ public: ...@@ -35,11 +35,14 @@ public:
Q_PROPERTY(Fact *minLength READ minLength CONSTANT) Q_PROPERTY(Fact *minLength READ minLength CONSTANT)
Q_PROPERTY(Fact *type READ type CONSTANT) Q_PROPERTY(Fact *type READ type CONSTANT)
Q_PROPERTY(Fact *variant READ variant CONSTANT) Q_PROPERTY(Fact *variant READ variant CONSTANT)
Q_PROPERTY(Fact *numRuns READ numRuns CONSTANT)
Q_PROPERTY(Fact *run READ run CONSTANT)
Q_PROPERTY(int typeCount READ typeCount CONSTANT) Q_PROPERTY(int typeCount READ typeCount CONSTANT)
Q_PROPERTY(bool calculating READ calculating NOTIFY calculatingChanged) Q_PROPERTY(bool calculating READ calculating NOTIFY calculatingChanged)
Q_PROPERTY(bool hidePolygon READ hidePolygon NOTIFY hidePolygonChanged) Q_PROPERTY(bool hidePolygon READ hidePolygon NOTIFY hidePolygonChanged)
Q_PROPERTY( Q_PROPERTY(
QList<QString> variantNames READ variantNames NOTIFY variantNamesChanged) QList<QString> variantNames READ variantNames NOTIFY variantNamesChanged)
Q_PROPERTY(QList<QString> runNames READ runNames NOTIFY runNamesChanged)
Q_INVOKABLE void resetReference(void); Q_INVOKABLE void resetReference(void);
Q_INVOKABLE void reverse(void); Q_INVOKABLE void reverse(void);
...@@ -57,10 +60,13 @@ public: ...@@ -57,10 +60,13 @@ public:
Fact *minLength(); Fact *minLength();
Fact *type(); Fact *type();
Fact *variant(); Fact *variant();
Fact *numRuns();
Fact *run();
int typeCount() const; int typeCount() const;
bool calculating() const; bool calculating() const;
bool hidePolygon() const; bool hidePolygon() const;
QList<QString> variantNames() const; QList<QString> variantNames() const;
QList<QString> runNames() const;
QGeoCoordinate depot() const; QGeoCoordinate depot() const;
QList<QGeoCoordinate> safeArea() const; QList<QGeoCoordinate> safeArea() const;
const QList<QList<QGeoCoordinate>> &rawTransects() const; const QList<QList<QGeoCoordinate>> &rawTransects() const;
...@@ -87,6 +93,8 @@ public: ...@@ -87,6 +93,8 @@ public:
static const char *minLengthName; static const char *minLengthName;
static const char *typeName; static const char *typeName;
static const char *variantName; static const char *variantName;
static const char *numRunsName;
static const char *runName;
static const char *CircularSurveyName; static const char *CircularSurveyName;
static const char *refPointLongitudeName; static const char *refPointLongitudeName;
static const char *refPointLatitudeName; static const char *refPointLatitudeName;
...@@ -99,6 +107,7 @@ signals: ...@@ -99,6 +107,7 @@ signals:
void depotChanged(); void depotChanged();
void safeAreaChanged(); void safeAreaChanged();
void variantNamesChanged(); void variantNamesChanged();
void runNamesChanged();
private slots: private slots:
// Overrides from TransectStyleComplexItem // Overrides from TransectStyleComplexItem
...@@ -113,10 +122,13 @@ private: ...@@ -113,10 +122,13 @@ private:
void _buildAndAppendMissionItems(QList<MissionItem *> &items, void _buildAndAppendMissionItems(QList<MissionItem *> &items,
QObject *missionItemParent); QObject *missionItemParent);
void _changeVariant(); void _changeVariant();
void _changeRun();
void _updateWorker(); void _updateWorker();
void _changeVariantWorker(); void _changeVariantRunWorker();
void _reverseWorker(); void _reverseWorker();
void _storeWorker(); void _storeWorker();
void _changeRunWorker();
// center of the circular lanes, e.g. base station // center of the circular lanes, e.g. base station
QGeoCoordinate _referencePoint; QGeoCoordinate _referencePoint;
...@@ -131,22 +143,29 @@ private: ...@@ -131,22 +143,29 @@ private:
SettingsFact _type; SettingsFact _type;
SettingsFact _variant; SettingsFact _variant;
QList<QString> _variantNames; QList<QString> _variantNames;
SettingsFact _numRuns;
SettingsFact _run;
QList<QString> _runNames;
// Worker // Worker
using PtrWorker = std::shared_ptr<RoutingThread>; using PtrWorker = std::shared_ptr<RoutingThread>;
PtrWorker _pWorker; PtrWorker _pWorker;
PtrRoutingData _workerOutput; PtrRoutingData _pRoutingData;
// Data and State. // Routing data.
QGeoCoordinate _depot; QGeoCoordinate _depot;
QList<QGeoCoordinate> _safeArea; QList<QGeoCoordinate> _safeArea;
QList<QList<QGeoCoordinate>> _rawTransects; QList<QList<QGeoCoordinate>> _rawTransects;
QVector<Transects> _routes; using Runs = QVector<Transects>;
QVector<Runs> _variantVector;
// State.
enum class STATE { enum class STATE {
DEFAULT, DEFAULT,
STORE, STORE,
REVERSE, REVERSE,
VARIANT_CHANGE, VARIANT_CHANGE,
RUN_CHANGE,
}; };
STATE _state; STATE _state;
......
...@@ -73,10 +73,13 @@ void RoutingThread::run() { ...@@ -73,10 +73,13 @@ void RoutingThread::run() {
#endif #endif
} else { } else {
// Prepare data for routing. // Prepare data for routing.
auto &routeInfoVector = pRouteData->routeInfoVector; auto &solutionVector = pRouteData->solutionVector;
auto &routeVector = pRouteData->routeVector;
snake::RouteParameter snakePar; snake::RouteParameter snakePar;
snakePar.numSolutionsPerRun = numSolutionsPerRun; snakePar.numSolutionsPerRun = numSolutionsPerRun;
snakePar.numRuns = numRuns;
// Set time limit to 10 min.
const auto maxRoutingTime = std::chrono::minutes(10); const auto maxRoutingTime = std::chrono::minutes(10);
const auto routingEnd = const auto routingEnd =
std::chrono::high_resolution_clock::now() + maxRoutingTime; std::chrono::high_resolution_clock::now() + maxRoutingTime;
...@@ -87,11 +90,11 @@ void RoutingThread::run() { ...@@ -87,11 +90,11 @@ void RoutingThread::run() {
}; };
// Route transects. // Route transects.
bool success = snake::route(safeAreaENU, transectsENU, routeInfoVector, bool success =
routeVector, snakePar); snake::route(safeAreaENU, transectsENU, solutionVector, snakePar);
// Check if routing was successful. // Check if routing was successful.
if ((!success || routeVector.size() < 1) && !this->_restart) { if ((!success || solutionVector.size() < 1) && !this->_restart) {
#ifdef DEBUG_CIRCULAR_SURVEY #ifdef DEBUG_CIRCULAR_SURVEY
qWarning() << "RoutingWorker::run(): " qWarning() << "RoutingWorker::run(): "
"routing failed."; "routing failed.";
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
struct RoutingData { struct RoutingData {
snake::Transects transects; snake::Transects transects;
std::vector<snake::Route> routeVector; std::vector<snake::Solution> solutionVector;
std::vector<snake::RouteInfo> routeInfoVector;
std::string errorString; std::string errorString;
}; };
......
This diff is collapsed.
...@@ -215,7 +215,6 @@ bool tiles(const FPolygon &area, Length tileHeight, Length tileWidth, ...@@ -215,7 +215,6 @@ bool tiles(const FPolygon &area, Length tileHeight, Length tileWidth,
using Transects = vector<FLineString>; using Transects = vector<FLineString>;
using Progress = vector<int>; using Progress = vector<int>;
using Route = FLineString;
bool transectsFromScenario(Length distance, Length minLength, Angle angle, bool transectsFromScenario(Length distance, Length minLength, Angle angle,
const FPolygon &mArea, const FPolygon &mArea,
...@@ -228,27 +227,26 @@ struct TransectInfo { ...@@ -228,27 +227,26 @@ struct TransectInfo {
size_t index; size_t index;
bool reversed; bool reversed;
}; };
using RouteInfo = std::vector<TransectInfo>; struct Route {
FLineString path;
std::vector<TransectInfo> info;
};
using Solution =
std::vector<Route>; // Every route corresponds to one run/vehicle
struct RouteParameter { struct RouteParameter {
RouteParameter() RouteParameter()
: numSolutionsPerRun(1), numRuns(1), stop([] { return false; }) {} : numSolutionsPerRun(1), numRuns(1), minNumTransectsPerRun(5),
stop([] { return false; }) {}
std::size_t numSolutionsPerRun; std::size_t numSolutionsPerRun;
std::size_t numRuns; std::size_t numRuns;
std::size_t minNumTransectsPerRun;
std::function<bool(void)> stop; std::function<bool(void)> stop;
mutable std::string errorString; mutable std::string errorString;
}; };
bool route(const FPolygon &area, const Transects &transects, bool route(const FPolygon &area, const Transects &transects,
std::vector<RouteInfo> &routeInfoVector, std::vector<Solution> &solutionVector,
std::vector<Route> &routeVector,
const RouteParameter &par = RouteParameter()); const RouteParameter &par = RouteParameter());
bool route_old(const FPolygon &area, const Transects &transects,
std::vector<TransectInfo> &transectInfo, Route &r,
string &errorString);
bool route_old(const FPolygon &area, const Transects &transects,
std::vector<TransectInfo> &transectInfo, Route &r,
std::function<bool(void)> stop, string &errorString);
namespace detail { namespace detail {
const double offsetConstant = const double offsetConstant =
0.1; // meter, polygon offset to compenstate for numerical inaccurracies. 0.1; // meter, polygon offset to compenstate for numerical inaccurracies.
......
...@@ -798,34 +798,36 @@ void WimaController::_storeRoute(RoutingThread::PtrRoutingData data) { ...@@ -798,34 +798,36 @@ void WimaController::_storeRoute(RoutingThread::PtrRoutingData data) {
// Copy waypoints to waypoint manager. // Copy waypoints to waypoint manager.
_snakeWM.clear(); _snakeWM.clear();
if (data->routeVector.size() > 0 && data->routeVector.front().size() > 0 && if (data->solutionVector.size() > 0 &&
data->routeInfoVector.size() > 0) { data->solutionVector.front().size() > 0) {
// Store route. // Store route.
const auto &transectsENU = data->transects; const auto &transectsENU = data->transects;
const auto &routeInfo = data->routeInfoVector.front(); const auto &solution = data->solutionVector.front();
const auto &route = data->routeVector.front(); const auto &route = solution.front();
const auto &path = route.path;
const auto &info = route.info;
// Find index of first waypoint. // Find index of first waypoint.
std::size_t idxFirst = 0; std::size_t idxFirst = 0;
const auto &infoFirst = routeInfo.front(); const auto &infoFirst = info.front();
const auto &firstTransect = transectsENU[infoFirst.index]; const auto &firstTransect = transectsENU[infoFirst.index];
const auto &firstWaypoint = const auto &firstWaypoint =
infoFirst.reversed ? firstTransect.back() : firstTransect.front(); infoFirst.reversed ? firstTransect.back() : firstTransect.front();
double th = 0.001; double th = 0.001;
for (std::size_t i = 0; i < route.size(); ++i) { for (std::size_t i = 0; i < path.size(); ++i) {
auto dist = bg::distance(route[i], firstWaypoint); auto dist = bg::distance(path[i], firstWaypoint);
if (dist < th) { if (dist < th) {
idxFirst = i; idxFirst = i;
break; break;
} }
} }
// Find index of last waypoint. // Find index of last waypoint.
std::size_t idxLast = route.size() - 1; std::size_t idxLast = path.size() - 1;
const auto &infoLast = routeInfo.back(); const auto &infoLast = info.back();
const auto &lastTransect = transectsENU[infoLast.index]; const auto &lastTransect = transectsENU[infoLast.index];
const auto &lastWaypoint = const auto &lastWaypoint =
infoLast.reversed ? lastTransect.front() : lastTransect.back(); infoLast.reversed ? lastTransect.front() : lastTransect.back();
for (long i = route.size() - 1; i >= 0; --i) { for (long i = path.size() - 1; i >= 0; --i) {
auto dist = bg::distance(route[i], lastWaypoint); auto dist = bg::distance(path[i], lastWaypoint);
if (dist < th) { if (dist < th) {
idxLast = i; idxLast = i;
break; break;
...@@ -834,7 +836,7 @@ void WimaController::_storeRoute(RoutingThread::PtrRoutingData data) { ...@@ -834,7 +836,7 @@ void WimaController::_storeRoute(RoutingThread::PtrRoutingData data) {
// Convert to geo coordinates and append to waypoint manager. // Convert to geo coordinates and append to waypoint manager.
const auto &ori = this->_origin; const auto &ori = this->_origin;
for (std::size_t i = idxFirst; i <= idxLast; ++i) { for (std::size_t i = idxFirst; i <= idxLast; ++i) {
auto &vertex = route[i]; auto &vertex = path[i];
QGeoCoordinate c; QGeoCoordinate c;
snake::fromENU(ori, vertex, c); snake::fromENU(ori, vertex, c);
_snakeWM.push_back(c); _snakeWM.push_back(c);
......
...@@ -38,5 +38,18 @@ ...@@ -38,5 +38,18 @@
"shortDescription": "Route variant.", "shortDescription": "Route variant.",
"type": "uint64", "type": "uint64",
"defaultValue": 0 "defaultValue": 0
},
{
"name": "NumRuns",
"shortDescription": "The number of runs.",
"type": "uint64",
"min": 1,
"defaultValue": 1
},
{
"name": "Run",
"shortDescription": "The current run.",
"type": "uint64",
"defaultValue": 0
} }
] ]
...@@ -128,40 +128,6 @@ Rectangle { ...@@ -128,40 +128,6 @@ Rectangle {
} // Tile Column } // Tile Column
SectionHeader {
id: transectsHeader
text: qsTr("Transects")
}
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: _margin
visible: transectsHeader.checked
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
columnSpacing: _margin
rowSpacing: _margin
columns: 2
QGCLabel { text: qsTr("Distance") }
FactTextField {
fact: areaItem.transectDistance
Layout.fillWidth: true
}
QGCLabel { text: qsTr("Min. Length") }
FactTextField {
fact: areaItem.minTransectLength
Layout.fillWidth: true
}
} // Transects GridLayout
} // Transects Column
SectionHeader { SectionHeader {
id: statsHeader id: statsHeader
text: qsTr("Statistics") text: qsTr("Statistics")
......
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