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