diff --git a/src/MissionManager/StructureScan.SettingsGroup.json b/src/MissionManager/StructureScan.SettingsGroup.json index 3a0fbbcd158abe88b97ec74b108d99d50d144c94..8439fa69dccd3d144ed7cf526707fc641b4c8c8a 100644 --- a/src/MissionManager/StructureScan.SettingsGroup.json +++ b/src/MissionManager/StructureScan.SettingsGroup.json @@ -23,6 +23,15 @@ "units": "m", "defaultValue": 25 }, +{ + "name": "Scan distance", + "shortDescription": "Scan distance away from structure.", + "type": "double", + "decimalPlaces": 2, + "min": 0, + "units": "m", + "defaultValue": 25 +}, { "name": "Trigger distance", "shortDescription": "Distance between each triggering of the camera. 0 specifies not camera trigger.", diff --git a/src/MissionManager/StructureScanComplexItem.cc b/src/MissionManager/StructureScanComplexItem.cc index 5c0257e375aaada626180baebd231b618847709d..2407ea35a7c05fceee926ad1d5b7b948c249c08c 100644 --- a/src/MissionManager/StructureScanComplexItem.cc +++ b/src/MissionManager/StructureScanComplexItem.cc @@ -23,36 +23,11 @@ QGC_LOGGING_CATEGORY(StructureScanComplexItemLog, "StructureScanComplexItemLog") const char* StructureScanComplexItem::jsonComplexItemTypeValue = "StructureScan-WIP"; -const char* StructureScanComplexItem::_jsonGridObjectKey = "grid"; -const char* StructureScanComplexItem::_jsonGridAltitudeKey = "altitude"; -const char* StructureScanComplexItem::_jsonGridAltitudeRelativeKey = "relativeAltitude"; -const char* StructureScanComplexItem::_jsonGridAngleKey = "angle"; -const char* StructureScanComplexItem::_jsonGridSpacingKey = "spacing"; -const char* StructureScanComplexItem::_jsonGridEntryLocationKey = "entryLocation"; -const char* StructureScanComplexItem::_jsonTurnaroundDistKey = "turnAroundDistance"; -const char* StructureScanComplexItem::_jsonCameraTriggerDistanceKey = "cameraTriggerDistance"; -const char* StructureScanComplexItem::_jsonCameraTriggerInTurnaroundKey = "cameraTriggerInTurnaround"; -const char* StructureScanComplexItem::_jsonHoverAndCaptureKey = "hoverAndCapture"; -const char* StructureScanComplexItem::_jsonGroundResolutionKey = "groundResolution"; -const char* StructureScanComplexItem::_jsonFrontalOverlapKey = "imageFrontalOverlap"; -const char* StructureScanComplexItem::_jsonSideOverlapKey = "imageSideOverlap"; -const char* StructureScanComplexItem::_jsonCameraSensorWidthKey = "sensorWidth"; -const char* StructureScanComplexItem::_jsonCameraSensorHeightKey = "sensorHeight"; -const char* StructureScanComplexItem::_jsonCameraResolutionWidthKey = "resolutionWidth"; -const char* StructureScanComplexItem::_jsonCameraResolutionHeightKey = "resolutionHeight"; -const char* StructureScanComplexItem::_jsonCameraFocalLengthKey = "focalLength"; -const char* StructureScanComplexItem::_jsonCameraMinTriggerIntervalKey = "minTriggerInterval"; -const char* StructureScanComplexItem::_jsonCameraObjectKey = "camera"; -const char* StructureScanComplexItem::_jsonCameraNameKey = "name"; -const char* StructureScanComplexItem::_jsonManualGridKey = "manualGrid"; -const char* StructureScanComplexItem::_jsonCameraOrientationLandscapeKey = "orientationLandscape"; -const char* StructureScanComplexItem::_jsonFixedValueIsAltitudeKey = "fixedValueIsAltitude"; -const char* StructureScanComplexItem::_jsonRefly90DegreesKey = "refly90Degrees"; - const char* StructureScanComplexItem::_altitudeFactName = "Altitude"; const char* StructureScanComplexItem::_layersFactName = "Layers"; const char* StructureScanComplexItem::_layerDistanceFactName = "Layer distance"; const char* StructureScanComplexItem::_cameraTriggerDistanceFactName = "Trigger distance"; +const char* StructureScanComplexItem::_scanDistanceFactName = "Scan distance"; QMap StructureScanComplexItem::_metaDataMap; @@ -70,22 +45,26 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, QObject* pa , _layersFact (0, _layersFactName, FactMetaData::valueTypeUint32) , _layerDistanceFact (0, _layerDistanceFactName, FactMetaData::valueTypeDouble) , _cameraTriggerDistanceFact(0, _cameraTriggerDistanceFactName, FactMetaData::valueTypeDouble) + , _scanDistanceFact (0, _scanDistanceFactName, FactMetaData::valueTypeDouble) { _editorQml = "qrc:/qml/StructureScanEditor.qml"; if (_metaDataMap.isEmpty()) { - _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/StructureScan.SettingsGroup.json"), this); + _metaDataMap = FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/StructureScan.SettingsGroup.json"), NULL /* QObject parent */); } + qDebug() << _metaDataMap[_altitudeFactName]; _altitudeFact.setMetaData (_metaDataMap[_altitudeFactName]); _layersFact.setMetaData (_metaDataMap[_layersFactName]); _layerDistanceFact.setMetaData (_metaDataMap[_layerDistanceFactName]); _cameraTriggerDistanceFact.setMetaData (_metaDataMap[_cameraTriggerDistanceFactName]); + _scanDistanceFact.setMetaData (_metaDataMap[_scanDistanceFactName]); _altitudeFact.setRawValue (_altitudeFact.rawDefaultValue()); _layersFact.setRawValue (_layersFact.rawDefaultValue()); _layerDistanceFact.setRawValue (_layerDistanceFact.rawDefaultValue()); _cameraTriggerDistanceFact.setRawValue (_cameraTriggerDistanceFact.rawDefaultValue()); + _scanDistanceFact.setRawValue (_scanDistanceFact.rawDefaultValue()); _altitudeFact.setRawValue(qgcApp()->toolbox()->settingsManager()->appSettings()->defaultMissionItemAltitude()->rawValue()); @@ -93,6 +72,7 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, QObject* pa connect(&_layersFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty); connect(&_layerDistanceFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty); connect(&_cameraTriggerDistanceFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty); + connect(&_scanDistanceFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty); connect(this, &StructureScanComplexItem::altitudeRelativeChanged, this, &StructureScanComplexItem::_setDirty); connect(this, &StructureScanComplexItem::altitudeRelativeChanged, this, &StructureScanComplexItem::coordinateHasRelativeAltitudeChanged); @@ -100,9 +80,13 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, QObject* pa connect(&_altitudeFact, &Fact::valueChanged, this, &StructureScanComplexItem::_updateCoordinateAltitudes); - connect(&_mapPolygon, &QGCMapPolygon::dirtyChanged, this, &StructureScanComplexItem::_polygonDirtyChanged); - connect(&_mapPolygon, &QGCMapPolygon::countChanged, this, &StructureScanComplexItem::_polygonCountChanged); - connect(&_mapPolygon, &QGCMapPolygon::pathChanged, this, &StructureScanComplexItem::_polygonPathChanged); + connect(&_structurePolygon, &QGCMapPolygon::dirtyChanged, this, &StructureScanComplexItem::_polygonDirtyChanged); + connect(&_structurePolygon, &QGCMapPolygon::countChanged, this, &StructureScanComplexItem::_polygonCountChanged); + connect(&_structurePolygon, &QGCMapPolygon::pathChanged, this, &StructureScanComplexItem::_rebuildFlightPolygon); + + connect(&_flightPolygon, &QGCMapPolygon::pathChanged, this, &StructureScanComplexItem::_flightPathChanged); + + connect(&_scanDistanceFact, &Fact::valueChanged, this, &StructureScanComplexItem::_rebuildFlightPolygon); } void StructureScanComplexItem::_setScanDistance(double scanDistance) @@ -138,7 +122,7 @@ void StructureScanComplexItem::_polygonCountChanged(int count) int StructureScanComplexItem::lastSequenceNumber(void) const { return _sequenceNumber + - ((_mapPolygon.count() + 1) * _layersFact.rawValue().toInt()) + // 1 waypoint for each polygon vertex + 1 to go back to first polygon vertex + ((_flightPolygon.count() + 1) * _layersFact.rawValue().toInt()) + // 1 waypoint for each polygon vertex + 1 to go back to first polygon vertex 1; // Gimbal yaw command } @@ -193,7 +177,7 @@ void StructureScanComplexItem::save(QJsonArray& missionItems) } // Polygon shape - _mapPolygon.saveToJson(saveObject); + _structurePolygon.saveToJson(saveObject); missionItems.append(saveObject); #endif @@ -260,7 +244,7 @@ bool StructureScanComplexItem::load(const QJsonObject& complexObject, int sequen _ignoreRecalc = true; - _mapPolygon.clear(); + _structurePolygon.clear(); setSequenceNumber(sequenceNumber); @@ -346,8 +330,8 @@ bool StructureScanComplexItem::load(const QJsonObject& complexObject, int sequen /// @param required true: no polygon in object will generate error /// @param errorString Error string if return is false /// @return true: success, false: failure (errorString set) - if (!_mapPolygon.loadFromJson(v2Object, true /* required */, errorString)) { - _mapPolygon.clear(); + if (!_structurePolygon.loadFromJson(v2Object, true /* required */, errorString)) { + _structurePolygon.clear(); return false; } @@ -364,7 +348,7 @@ bool StructureScanComplexItem::load(const QJsonObject& complexObject, int sequen #endif } -void StructureScanComplexItem::_polygonPathChanged(void) +void StructureScanComplexItem::_flightPathChanged(void) { emit coordinateChanged(coordinate()); emit exitCoordinateChanged(exitCoordinate()); @@ -374,7 +358,7 @@ void StructureScanComplexItem::_polygonPathChanged(void) double StructureScanComplexItem::greatestDistanceTo(const QGeoCoordinate &other) const { double greatestDistance = 0.0; - QList vertices = _mapPolygon.coordinateList(); + QList vertices = _flightPolygon.coordinateList(); for (int i=0; i 2; + return _flightPolygon.count() > 2; } void StructureScanComplexItem::appendMissionItems(QList& items, QObject* missionItemParent) @@ -413,8 +397,8 @@ void StructureScanComplexItem::appendMissionItems(QList& items, QO for (int layer=0; layer<_layersFact.rawValue().toInt(); layer++) { double layerAltitude = baseAltitude + (layer * _layerDistanceFact.rawValue().toDouble()); - for (int i=0; i<_mapPolygon.count(); i++) { - QGeoCoordinate vertexCoord = _mapPolygon.pathModel().value(i)->coordinate(); + for (int i=0; i<_flightPolygon.count(); i++) { + QGeoCoordinate vertexCoord = _flightPolygon.vertexCoordinate(i); MissionItem* item = new MissionItem(seqNum++, MAV_CMD_NAV_WAYPOINT, @@ -432,7 +416,7 @@ void StructureScanComplexItem::appendMissionItems(QList& items, QO items.append(item); } - QGeoCoordinate vertexCoord = _mapPolygon.pathModel().value(0)->coordinate(); + QGeoCoordinate vertexCoord = _flightPolygon.vertexCoordinate(0); MissionItem* item = new MissionItem(seqNum++, MAV_CMD_NAV_WAYPOINT, @@ -489,9 +473,9 @@ double StructureScanComplexItem::timeBetweenShots(void) const QGeoCoordinate StructureScanComplexItem::coordinate(void) const { - if (_mapPolygon.count() > 0) { - int entryVertex = qMax(qMin(_entryVertex, _mapPolygon.count() - 1), 0); - return _mapPolygon.vertexCoordinate(entryVertex); + if (_flightPolygon.count() > 0) { + int entryVertex = qMax(qMin(_entryVertex, _flightPolygon.count() - 1), 0); + return _flightPolygon.vertexCoordinate(entryVertex); } else { return QGeoCoordinate(); } @@ -511,9 +495,15 @@ void StructureScanComplexItem::_updateCoordinateAltitudes(void) void StructureScanComplexItem::rotateEntryPoint(void) { _entryVertex++; - if (_entryVertex >= _mapPolygon.count()) { + if (_entryVertex >= _flightPolygon.count()) { _entryVertex = 0; } emit coordinateChanged(coordinate()); emit exitCoordinateChanged(exitCoordinate()); } + +void StructureScanComplexItem::_rebuildFlightPolygon(void) +{ + _flightPolygon = _structurePolygon; + _flightPolygon.offset(_scanDistanceFact.rawValue().toDouble()); +} diff --git a/src/MissionManager/StructureScanComplexItem.h b/src/MissionManager/StructureScanComplexItem.h index 342874301a251777608922f68122495c2fee87c3..22dd53de67455ddaed5354e9a9b922a08354ef97 100644 --- a/src/MissionManager/StructureScanComplexItem.h +++ b/src/MissionManager/StructureScanComplexItem.h @@ -30,20 +30,24 @@ public: Q_PROPERTY(Fact* layers READ layers CONSTANT) Q_PROPERTY(Fact* layerDistance READ layerDistance CONSTANT) Q_PROPERTY(Fact* cameraTriggerDistance READ cameraTriggerDistance CONSTANT) + Q_PROPERTY(Fact* scanDistance READ scanDistance CONSTANT) Q_PROPERTY(bool altitudeRelative MEMBER _altitudeRelative NOTIFY altitudeRelativeChanged) Q_PROPERTY(int cameraShots READ cameraShots NOTIFY cameraShotsChanged) Q_PROPERTY(double timeBetweenShots READ timeBetweenShots NOTIFY timeBetweenShotsChanged) Q_PROPERTY(double cameraMinTriggerInterval MEMBER _cameraMinTriggerInterval NOTIFY cameraMinTriggerIntervalChanged) - Q_PROPERTY(QGCMapPolygon* mapPolygon READ mapPolygon CONSTANT) + Q_PROPERTY(QGCMapPolygon* structurePolygon READ structurePolygon CONSTANT) + Q_PROPERTY(QGCMapPolygon* flightPolygon READ flightPolygon CONSTANT) Fact* altitude (void) { return &_altitudeFact; } Fact* layers (void) { return &_layersFact; } Fact* layerDistance (void) { return &_layerDistanceFact; } Fact* cameraTriggerDistance (void) { return &_cameraTriggerDistanceFact; } + Fact* scanDistance (void) { return &_scanDistanceFact; } int cameraShots (void) const; double timeBetweenShots(void) const; - QGCMapPolygon* mapPolygon (void) { return &_mapPolygon; } + QGCMapPolygon* structurePolygon(void) { return &_structurePolygon; } + QGCMapPolygon* flightPolygon (void) { return &_flightPolygon; } Q_INVOKABLE void rotateEntryPoint(void); @@ -95,9 +99,10 @@ private slots: void _setDirty(void); void _polygonDirtyChanged(bool dirty); void _polygonCountChanged(int count); - void _polygonPathChanged(void); + void _flightPathChanged(void); void _clearInternal(void); void _updateCoordinateAltitudes(void); + void _rebuildFlightPolygon(void); private: void _setExitCoordinate(const QGeoCoordinate& coordinate); @@ -107,7 +112,8 @@ private: int _sequenceNumber; bool _dirty; - QGCMapPolygon _mapPolygon; + QGCMapPolygon _structurePolygon; + QGCMapPolygon _flightPolygon; bool _altitudeRelative; int _entryVertex; // Polygon vertext which is used as the mission entry point @@ -124,39 +130,13 @@ private: Fact _layersFact; Fact _layerDistanceFact; Fact _cameraTriggerDistanceFact; + Fact _scanDistanceFact; static const char* _altitudeFactName; static const char* _layersFactName; static const char* _layerDistanceFactName; static const char* _cameraTriggerDistanceFactName; - - static const char* _jsonGridObjectKey; - static const char* _jsonGridAltitudeKey; - static const char* _jsonGridAltitudeRelativeKey; - static const char* _jsonGridAngleKey; - static const char* _jsonGridSpacingKey; - static const char* _jsonGridEntryLocationKey; - static const char* _jsonTurnaroundDistKey; - static const char* _jsonCameraTriggerDistanceKey; - static const char* _jsonCameraTriggerInTurnaroundKey; - static const char* _jsonHoverAndCaptureKey; - static const char* _jsonGroundResolutionKey; - static const char* _jsonFrontalOverlapKey; - static const char* _jsonSideOverlapKey; - static const char* _jsonCameraSensorWidthKey; - static const char* _jsonCameraSensorHeightKey; - static const char* _jsonCameraResolutionWidthKey; - static const char* _jsonCameraResolutionHeightKey; - static const char* _jsonCameraFocalLengthKey; - static const char* _jsonCameraMinTriggerIntervalKey; - static const char* _jsonManualGridKey; - static const char* _jsonCameraObjectKey; - static const char* _jsonCameraNameKey; - static const char* _jsonCameraOrientationLandscapeKey; - static const char* _jsonFixedValueIsAltitudeKey; - static const char* _jsonRefly90DegreesKey; - - static const int _hoverAndCaptureDelaySeconds = 1; + static const char* _scanDistanceFactName; }; #endif diff --git a/src/PlanView/StructureScanEditor.qml b/src/PlanView/StructureScanEditor.qml index a23009bce6c9061e49fff318f18f1b1183d89452..34301478849f0288c291312ac436d07b5093c3f6 100644 --- a/src/PlanView/StructureScanEditor.qml +++ b/src/PlanView/StructureScanEditor.qml @@ -60,11 +60,19 @@ Rectangle { QGCLabel { anchors.left: parent.left anchors.right: parent.right - text: qsTr("WARNING: WORK IN PROGRESS. USE AT YOUR OWN RISK.") + text: qsTr("WARNING: WORK IN PROGRESS. USE AT YOUR OWN RISK. MEANT FOR DISCUSSION ONLY. DO NOT REPORT BUGS.") wrapMode: Text.WordWrap color: qgcPal.warningText } + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Note: Polygon respresents structure surface not vehicle flight path.") + wrapMode: Text.WordWrap + font.pointSize: ScreenTools.smallFontPointSize + } + QGCLabel { anchors.left: parent.left anchors.right: parent.right @@ -99,6 +107,12 @@ Rectangle { Layout.fillWidth: true } + QGCLabel { text: qsTr("Scan distance") } + FactTextField { + fact: missionItem.scanDistance + Layout.fillWidth: true + } + QGCLabel { text: qsTr("Trigger Distance") } FactTextField { fact: missionItem.cameraTriggerDistance diff --git a/src/PlanView/StructureScanMapVisual.qml b/src/PlanView/StructureScanMapVisual.qml index 4110ddcbe9e0c675ab50c70c9ac8175c7582400f..7d12f9135915df654c91e9e027046c3e3aed7acd 100644 --- a/src/PlanView/StructureScanMapVisual.qml +++ b/src/PlanView/StructureScanMapVisual.qml @@ -25,31 +25,28 @@ Item { property var map ///< Map control to place item in property var _missionItem: object - property var _mapPolygon: object.mapPolygon - property var _gridComponent + property var _structurePolygon: object.structurePolygon + property var _flightPolygon: object.flightPolygon property var _entryCoordinate property var _exitCoordinate signal clicked(int sequenceNumber) function _addVisualElements() { - _gridComponent = gridComponent.createObject(map) _entryCoordinate = entryPointComponent.createObject(map) _exitCoordinate = exitPointComponent.createObject(map) - map.addMapItem(_gridComponent) map.addMapItem(_entryCoordinate) map.addMapItem(_exitCoordinate) } function _destroyVisualElements() { - _gridComponent.destroy() _entryCoordinate.destroy() _exitCoordinate.destroy() } /// Add an initial 4 sided polygon if there is none function _addInitialPolygon() { - if (_mapPolygon.count < 3) { + if (_structurePolygon.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 @@ -71,10 +68,10 @@ Item { bottomLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 180) bottomRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 180) - _mapPolygon.appendVertex(topLeftCoord) - _mapPolygon.appendVertex(topRightCoord) - _mapPolygon.appendVertex(bottomRightCoord) - _mapPolygon.appendVertex(bottomLeftCoord) + _structurePolygon.appendVertex(topLeftCoord) + _structurePolygon.appendVertex(topRightCoord) + _structurePolygon.appendVertex(bottomRightCoord) + _structurePolygon.appendVertex(bottomLeftCoord) } } @@ -88,9 +85,8 @@ Item { } QGCMapPolygonVisuals { - id: mapPolygonVisuals mapControl: map - mapPolygon: _mapPolygon + mapPolygon: _structurePolygon interactive: _missionItem.isCurrentItem borderWidth: 1 borderColor: "black" @@ -98,15 +94,12 @@ Item { interiorOpacity: 0.5 } - // Survey grid lines - Component { - id: gridComponent - - MapPolyline { - line.color: "white" - line.width: 2 - path: _missionItem.gridPoints - } + QGCMapPolygonVisuals { + mapControl: map + mapPolygon: _flightPolygon + interactive: false + borderWidth: 2 + borderColor: "white" } // Entry point