Commit 5d24e39c authored by DonLakeFlyer's avatar DonLakeFlyer

Support for flying alternate transects

parent 117e3dde
[
{
"name": "ManualGrid",
"shortDescription": "Specify all parameters for grid generation.",
"type": "bool",
"defaultValue": 1
},
{
"name": "GridAltitude",
"shortDescription": "Altitude for all waypoints within the grid.",
"type": "double",
"units": "m",
"decimalPlaces": 1,
"defaultValue": 50
},
{
"name": "GridAltitudeRelative",
"shortDescription": "Altitude for all waypoints within the grid is relative to home.",
"type": "bool",
"defaultValue": 1
},
{
"name": "GridAngle",
"shortDescription": "Angle for parallel lines of grid.",
......@@ -30,140 +10,9 @@
"defaultValue": 0
},
{
"name": "GridSpacing",
"shortDescription": "Amount of spacing in between parallel grid lines.",
"type": "double",
"decimalPlaces": 2,
"min": 0.1,
"units": "m",
"defaultValue": 30
},
{
"name": "TurnaroundDist",
"shortDescription": "Amount of additional distance to add outside the grid area for vehicle turnaround.",
"type": "double",
"decimalPlaces": 2,
"min": 0,
"units": "m",
"defaultValue": 30
},
{
"name": "GroundResolution",
"shortDescription": "Resolution of image in relationship to ground distance.",
"type": "double",
"decimalPlaces": 2,
"min": 0,
"units": "cm/px",
"defaultValue": 3
},
{
"name": "FrontalOverlap",
"shortDescription": "Amount of overlap between images in the forward facing direction.",
"type": "double",
"decimalPlaces": 0,
"min": 0,
"max": 85,
"units": "%",
"defaultValue": 70
},
{
"name": "SideOverlap",
"shortDescription": "Amount of overlap between images in the side facing direction.",
"type": "double",
"decimalPlaces": 0,
"min": 0,
"max": 85,
"units": "%",
"defaultValue": 70
},
{
"name": "CameraSensorWidth",
"shortDescription": "Amount of overlap between images in the side facing direction.",
"type": "double",
"decimalPlaces": 2,
"min": 1,
"units": "mm",
"defaultValue": 6.17
},
{
"name": "CameraSensorHeight",
"shortDescription": "Amount of overlap between images in the side facing direction.",
"type": "double",
"decimalPlaces": 2,
"min": 1,
"units": "mm",
"defaultValue": 4.55
},
{
"name": "CameraResolutionWidth",
"shortDescription": "Camera resolution width.",
"type": "uint32",
"min": 1,
"units": "px",
"defaultValue": 4000
},
{
"name": "CameraResolutionHeight",
"shortDescription": "Camera resolution height.",
"type": "uint32",
"min": 1,
"units": "px",
"defaultValue": 3000
},
{
"name": "CameraFocalLength",
"shortDescription": "Focal length of camera lens.",
"type": "double",
"decimalPlaces": 1,
"min": 1,
"units": "mm",
"defaultValue": 4.5
},
{
"name": "CameraTriggerDistance",
"shortDescription": "Distance between each triggering of the camera. 0 specifies not camera trigger.",
"type": "double",
"decimalPlaces": 2,
"min": 0,
"units": "m",
"defaultValue": 25
},
{
"name": "CameraTriggerInTurnaround",
"shortDescription": "Camera continues taking images in turnarounds.",
"type": "bool",
"defaultValue": true
},
{
"name": "HoverAndCapture",
"shortDescription": "Hover at each image point and take image",
"type": "bool",
"defaultValue": false
},
{
"name": "CameraOrientationLandscape",
"shortDescription": "Camera on vehicle is in landscape orientation.",
"type": "bool",
"defaultValue": 1
},
{
"name": "FixedValueIsAltitude",
"shortDescription": "The altitude is kep constant while ground resolution changes.",
"name": "FlyAlternateTransects",
"shortDescription": "Fly every other transect in each pass.",
"type": "bool",
"defaultValue": false
},
{
"name": "Camera",
"shortDescription": "Camera selected for Survey.",
"type": "string",
"defaultValue": ""
},
{
"name": "GridEntryLocation",
"shortDescription": "Location for entry point into survey area",
"type": "uint32",
"enumStrings": "Position 1,Position 2,Position 3,Position 4",
"enumValues": "0,1,2,3",
"defaultValue": 0
}
]
......@@ -27,6 +27,7 @@ const char* SurveyComplexItem::jsonV3ComplexItemTypeValue = "survey";
const char* SurveyComplexItem::settingsGroup = "Survey";
const char* SurveyComplexItem::gridAngleName = "GridAngle";
const char* SurveyComplexItem::gridEntryLocationName = "GridEntryLocation";
const char* SurveyComplexItem::flyAlternateTransectsName = "FlyAlternateTransects";
const char* SurveyComplexItem::_jsonGridAngleKey = "angle";
const char* SurveyComplexItem::_jsonEntryPointKey = "entryLocation";
......@@ -56,12 +57,13 @@ const char* SurveyComplexItem::_jsonV3ManualGridKey = "manualG
const char* SurveyComplexItem::_jsonV3CameraOrientationLandscapeKey = "orientationLandscape";
const char* SurveyComplexItem::_jsonV3FixedValueIsAltitudeKey = "fixedValueIsAltitude";
const char* SurveyComplexItem::_jsonV3Refly90DegreesKey = "refly90Degrees";
const char* SurveyComplexItem::_jsonFlyAlternateTransectsKey = "flyAlternateTransects";
SurveyComplexItem::SurveyComplexItem(Vehicle* vehicle, bool flyView, QObject* parent)
: TransectStyleComplexItem (vehicle, flyView, settingsGroup, parent)
, _metaDataMap (FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/Survey.SettingsGroup.json"), this))
, _gridAngleFact (settingsGroup, _metaDataMap[gridAngleName])
, _flyAlternateTransectsFact(settingsGroup, _metaDataMap[flyAlternateTransectsName])
, _entryPoint (EntryLocationTopLeft)
{
_editorQml = "qrc:/qml/SurveyItemEditor.qml";
......@@ -79,9 +81,11 @@ SurveyComplexItem::SurveyComplexItem(Vehicle* vehicle, bool flyView, QObject* pa
}
connect(&_gridAngleFact, &Fact::valueChanged, this, &SurveyComplexItem::_setDirty);
connect(&_flyAlternateTransectsFact,&Fact::valueChanged, this, &SurveyComplexItem::_setDirty);
connect(this, &SurveyComplexItem::refly90DegreesChanged, this, &SurveyComplexItem::_setDirty);
connect(&_gridAngleFact, &Fact::valueChanged, this, &SurveyComplexItem::_rebuildTransects);
connect(&_flyAlternateTransectsFact,&Fact::valueChanged, this, &SurveyComplexItem::_rebuildTransects);
connect(this, &SurveyComplexItem::refly90DegreesChanged, this, &SurveyComplexItem::_rebuildTransects);
// FIXME: Shouldn't these be in TransectStyleComplexItem? They are also in CorridorScanComplexItem constructur
......@@ -99,6 +103,7 @@ void SurveyComplexItem::save(QJsonArray& planItems)
saveObject[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeComplexItemValue;
saveObject[ComplexMissionItem::jsonComplexItemTypeKey] = jsonComplexItemTypeValue;
saveObject[_jsonGridAngleKey] = _gridAngleFact.rawValue().toDouble();
saveObject[_jsonFlyAlternateTransectsKey] = _flyAlternateTransectsFact.rawValue().toBool();
saveObject[_jsonEntryPointKey] = _entryPoint;
// Polygon shape
......@@ -152,8 +157,9 @@ bool SurveyComplexItem::_loadV4(const QJsonObject& complexObject, int sequenceNu
QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ VisualMissionItem::jsonTypeKey, QJsonValue::String, true },
{ ComplexMissionItem::jsonComplexItemTypeKey, QJsonValue::String, true },
{ _jsonEntryPointKey, QJsonValue::Double, true },
{ _jsonEntryPointKey, QJsonValue::Double, true },
{ _jsonGridAngleKey, QJsonValue::Double, true },
{ _jsonFlyAlternateTransectsKey, QJsonValue::Double, false },
};
if (!JsonHelper::validateKeys(complexObject, keyInfoList, errorString)) {
return false;
......@@ -180,7 +186,9 @@ bool SurveyComplexItem::_loadV4(const QJsonObject& complexObject, int sequenceNu
return false;
}
_gridAngleFact.setRawValue(complexObject[_jsonGridAngleKey].toDouble());
_gridAngleFact.setRawValue (complexObject[_jsonGridAngleKey].toDouble());
_flyAlternateTransectsFact.setRawValue (complexObject[_jsonFlyAlternateTransectsKey].toBool(false));
_entryPoint = complexObject[_jsonEntryPointKey].toInt();
_ignoreRecalc = false;
......@@ -1274,6 +1282,21 @@ void SurveyComplexItem::_rebuildTransectsPhase1Worker(bool refly)
_optimizeTransectsForShortestDistance(_transects.last().last().coord, transects);
}
if (_flyAlternateTransectsFact.rawValue().toBool()) {
QList<QList<QGeoCoordinate>> alternatingTransects;
for (int i=0; i<transects.count(); i++) {
if (!(i & 1)) {
alternatingTransects.append(transects[i]);
}
}
for (int i=transects.count()-1; i>0; i--) {
if (i & 1) {
alternatingTransects.append(transects[i]);
}
}
transects = alternatingTransects;
}
// Adjust to lawnmower pattern
bool reverseVertices = false;
for (int i=0; i<transects.count(); i++) {
......
......@@ -23,9 +23,11 @@ class SurveyComplexItem : public TransectStyleComplexItem
public:
SurveyComplexItem(Vehicle* vehicle, bool flyView, QObject* parent);
Q_PROPERTY(Fact* gridAngle READ gridAngle CONSTANT)
Q_PROPERTY(Fact* gridAngle READ gridAngle CONSTANT)
Q_PROPERTY(Fact* flyAlternateTransects READ flyAlternateTransects CONSTANT)
Fact* gridAngle(void) { return &_gridAngleFact; }
Fact* gridAngle (void) { return &_gridAngleFact; }
Fact* flyAlternateTransects (void) { return &_flyAlternateTransectsFact; }
Q_INVOKABLE void rotateEntryPoint(void);
......@@ -59,6 +61,7 @@ public:
static const char* settingsGroup;
static const char* gridAngleName;
static const char* gridEntryLocationName;
static const char* flyAlternateTransectsName;
static const char* jsonV3ComplexItemTypeValue;
......@@ -108,10 +111,12 @@ private:
QMap<QString, FactMetaData*> _metaDataMap;
SettingsFact _gridAngleFact;
SettingsFact _flyAlternateTransectsFact;
int _entryPoint;
static const char* _jsonGridAngleKey;
static const char* _jsonEntryPointKey;
static const char* _jsonFlyAlternateTransectsKey;
static const char* _jsonV3GridObjectKey;
static const char* _jsonV3GridAltitudeKey;
......
......@@ -70,7 +70,7 @@ void SurveyComplexItemTest::_testDirty(void)
// These facts should set dirty when changed
QList<Fact*> rgFacts;
rgFacts << _surveyItem->gridAngle();
rgFacts << _surveyItem->gridAngle() << _surveyItem->flyAlternateTransects();
foreach(Fact* fact, rgFacts) {
qDebug() << fact->name();
QVERIFY(!_surveyItem->dirty());
......
......@@ -130,6 +130,13 @@ Rectangle {
Layout.columnSpan: 2
}
FactCheckBox {
text: qsTr("Fly alternate transects")
fact: missionItem.flyAlternateTransects
visible: _vehicle.fixedWing
Layout.columnSpan: 2
}
QGCCheckBox {
id: relAlt
anchors.left: parent.left
......
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