diff --git a/src/FactSystem/Fact.cc b/src/FactSystem/Fact.cc index c0f58cc..02bc878 100644 --- a/src/FactSystem/Fact.cc +++ b/src/FactSystem/Fact.cc @@ -77,6 +77,7 @@ void Fact::forceSetRawValue(const QVariant& value) _rawValue.setValue(typedValue); _sendValueChangedSignal(cookedValue()); emit _containerRawValueChanged(rawValue()); + emit rawValueChanged(_rawValue); } } else { qWarning() << "Meta data pointer missing"; @@ -94,6 +95,7 @@ void Fact::setRawValue(const QVariant& value) _rawValue.setValue(typedValue); _sendValueChangedSignal(cookedValue()); emit _containerRawValueChanged(rawValue()); + emit rawValueChanged(_rawValue); } } } else { @@ -136,6 +138,7 @@ void Fact::_containerSetRawValue(const QVariant& value) _rawValue = value; _sendValueChangedSignal(cookedValue()); emit vehicleUpdated(_rawValue); + emit rawValueChanged(_rawValue); } QString Fact::name(void) const diff --git a/src/FactSystem/Fact.h b/src/FactSystem/Fact.h index 9d903fc..4d50786 100644 --- a/src/FactSystem/Fact.h +++ b/src/FactSystem/Fact.h @@ -58,6 +58,7 @@ public: Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT) Q_PROPERTY(QString units READ cookedUnits CONSTANT) Q_PROPERTY(QVariant value READ cookedValue WRITE setCookedValue NOTIFY valueChanged) + Q_PROPERTY(QVariant rawValue READ rawValue WRITE setRawValue NOTIFY rawValueChanged) Q_PROPERTY(bool valueEqualsDefault READ valueEqualsDefault NOTIFY valueChanged) Q_PROPERTY(QString valueString READ cookedValueString NOTIFY valueChanged) Q_PROPERTY(QString enumOrValueString READ enumOrValueString NOTIFY valueChanged) @@ -145,6 +146,7 @@ signals: /// /// This signal is only meant for use by the QT property system. It should not be connected to by client code. void valueChanged(QVariant value); + void rawValueChanged(QVariant value); /// Signalled when the param write ack comes back from the vehicle void vehicleUpdated(QVariant value); diff --git a/src/MissionEditor/SurveyItemEditor.qml b/src/MissionEditor/SurveyItemEditor.qml index 8a9e108..ca6e369 100644 --- a/src/MissionEditor/SurveyItemEditor.qml +++ b/src/MissionEditor/SurveyItemEditor.qml @@ -22,8 +22,45 @@ Rectangle { property real _margin: ScreenTools.defaultFontPixelWidth / 2 + property var _cameraInfoCanonSX260: { "focalLength": 4.5, "sensorHeight": 4.55, "sensorWidth": 6.17 } + + function recalcFromCameraValues() { + var focalLength = Number(focalLengthField.text) + var sensorWidth = Number(sensorWidthField.text) + var sensorHeight = Number(sensorHeightField.text) + var overlap = Number(imageOverlapField.text) + + if (focalLength <= 0.0 || sensorWidth <= 0.0 || sensorHeight <= 0.0) { + return + } + + var scaledFocalLengthMM = (1000.0 * missionItem.gridAltitude.rawValue) / focalLength + var imageWidthM = (sensorWidth * scaledFocalLengthMM) / 1000.0; + var imageHeightM = (sensorHeight * scaledFocalLengthMM) / 1000.0; + + var gridSpacing + var cameraTriggerDistance + if (cameraOrientationLandscape.checked) { + gridSpacing = imageWidthM + cameraTriggerDistance = imageHeightM + } else { + gridSpacing = imageHeightM + cameraTriggerDistance = imageWidthM + } + gridSpacing = (1.0 - (overlap / 100.0)) * gridSpacing + cameraTriggerDistance = (1.0 - (overlap / 100.0)) * cameraTriggerDistance + + missionItem.gridSpacing.rawValue = gridSpacing + missionItem.cameraTriggerDistance.rawValue = cameraTriggerDistance + } + QGCPalette { id: qgcPal; colorGroupEnabled: true } + ExclusiveGroup { + id: cameraOrientationGroup + onCurrentChanged: recalcFromCameraValues() + } + Column { id: editorColumn anchors.margins: _margin @@ -115,6 +152,79 @@ Rectangle { onPolygonAdjustVertex: missionItem.adjustPolygonCoordinate(vertexIndex, vertexCoordinate) } + QGCLabel { text: qsTr("Camera:") } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: qgcPal.text + } + + Row { + spacing: ScreenTools.defaultFontPixelWidth + + + QGCRadioButton { + id: cameraOrientationLandscape + text: "Landscape" + checked: true + exclusiveGroup: cameraOrientationGroup + } + + QGCRadioButton { + id: cameraOrientationPortrait + text: "Portrait" + exclusiveGroup: cameraOrientationGroup + } + } + + Grid { + columns: 2 + spacing: ScreenTools.defaultFontPixelWidth + verticalItemAlignment: Grid.AlignVCenter + + QGCLabel { text: qsTr("Focal length:") } + QGCTextField { + id: focalLengthField + unitsLabel: "mm" + showUnits: true + text: _cameraInfoCanonSX260.focalLength.toString() + + onEditingFinished: recalcFromCameraValues() + } + + QGCLabel { text: qsTr("Sensor Width:") } + QGCTextField { + id: sensorWidthField + unitsLabel: "mm" + showUnits: true + text: _cameraInfoCanonSX260.sensorWidth.toString() + + onEditingFinished: recalcFromCameraValues() + } + + QGCLabel { text: qsTr("Sensor height:") } + QGCTextField { + id: sensorHeightField + unitsLabel: "mm" + showUnits: true + text: _cameraInfoCanonSX260.sensorHeight.toString() + + onEditingFinished: recalcFromCameraValues() + } + + QGCLabel { text: qsTr("Image overlap:") } + QGCTextField { + id: imageOverlapField + unitsLabel: "%" + showUnits: true + text: "0" + + onEditingFinished: recalcFromCameraValues() + } + } + QGCLabel { text: qsTr("Polygon:") } Rectangle { diff --git a/src/MissionManager/ComplexMissionItemTest.cc b/src/MissionManager/ComplexMissionItemTest.cc index 5d74978..af87091 100644 --- a/src/MissionManager/ComplexMissionItemTest.cc +++ b/src/MissionManager/ComplexMissionItemTest.cc @@ -170,7 +170,7 @@ void ComplexMissionItemTest::_testClearPolygon(void) void ComplexMissionItemTest::_testCameraTrigger(void) { - QVERIFY(!_complexItem->property("cameraTrigger").toBool()); + QCOMPARE(_complexItem->property("cameraTrigger").toBool(), true); // Turning on/off camera triggering while there is no grid should trigger: // cameraTriggerChanged @@ -178,17 +178,18 @@ void ComplexMissionItemTest::_testCameraTrigger(void) // lastSequenceNumber should not change int lastSeq = _complexItem->lastSequenceNumber(); - _complexItem->setProperty("cameraTrigger", true); + + _complexItem->setProperty("cameraTrigger", false); QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask | cameraTriggerChangedMask)); - QVERIFY(_multiSpy->pullBoolFromSignalIndex(cameraTriggerChangedIndex)); + QVERIFY(!_multiSpy->pullBoolFromSignalIndex(cameraTriggerChangedIndex)); QCOMPARE(_complexItem->lastSequenceNumber(), lastSeq); _complexItem->setDirty(false); _multiSpy->clearAllSignals(); - _complexItem->setProperty("cameraTrigger", false); + _complexItem->setProperty("cameraTrigger", true); QVERIFY(_multiSpy->checkOnlySignalByMask(dirtyChangedMask | cameraTriggerChangedMask)); - QVERIFY(!_multiSpy->pullBoolFromSignalIndex(cameraTriggerChangedIndex)); + QVERIFY(_multiSpy->pullBoolFromSignalIndex(cameraTriggerChangedIndex)); QCOMPARE(_complexItem->lastSequenceNumber(), lastSeq); // Set up a grid @@ -203,20 +204,20 @@ void ComplexMissionItemTest::_testCameraTrigger(void) lastSeq = _complexItem->lastSequenceNumber(); QVERIFY(lastSeq > 0); - // Turning on camera triggering should add two more mission items, this should trigger: + // Turning off camera triggering should remove two camera trigger mission items, this should trigger: // lastSequenceNumberChanged // dirtyChanged - _complexItem->setProperty("cameraTrigger", true); + _complexItem->setProperty("cameraTrigger", false); QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask)); - QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq + 2); + QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq - 2); _complexItem->setDirty(false); _multiSpy->clearAllSignals(); - // Turn off camera triggering and make sure things go back to previous count + // Turn on camera triggering and make sure things go back to previous count - _complexItem->setProperty("cameraTrigger", false); + _complexItem->setProperty("cameraTrigger", true); QVERIFY(_multiSpy->checkOnlySignalByMask(lastSequenceNumberChangedMask | dirtyChangedMask | cameraTriggerChangedMask)); QCOMPARE(_multiSpy->pullIntFromSignalIndex(lastSequenceNumberChangedIndex), lastSeq); } diff --git a/src/MissionManager/SurveyMissionItem.cc b/src/MissionManager/SurveyMissionItem.cc index e1d6ccc..f9406e6 100644 --- a/src/MissionManager/SurveyMissionItem.cc +++ b/src/MissionManager/SurveyMissionItem.cc @@ -34,16 +34,16 @@ SurveyMissionItem::SurveyMissionItem(Vehicle* vehicle, QObject* parent) : ComplexMissionItem(vehicle, parent) , _sequenceNumber(0) , _dirty(false) - , _cameraTrigger(false) + , _cameraTrigger(true) , _gridAltitudeRelative(true) , _surveyDistance(0.0) , _cameraShots(0) , _coveredArea(0.0) - , _gridAltitudeFact (0, "Altitude:", FactMetaData::valueTypeDouble) - , _gridAngleFact (0, "Grid angle:", FactMetaData::valueTypeDouble) - , _gridSpacingFact (0, "Grid spacing:", FactMetaData::valueTypeDouble) - , _cameraTriggerDistanceFact(0, "Camera trigger distance", FactMetaData::valueTypeDouble) + , _gridAltitudeFact (0, "Altitude:", FactMetaData::valueTypeDouble) + , _gridAngleFact (0, "Grid angle:", FactMetaData::valueTypeDouble) + , _gridSpacingFact (0, "Grid spacing:", FactMetaData::valueTypeDouble) + , _cameraTriggerDistanceFact(0, "Camera trigger distance", FactMetaData::valueTypeDouble) , _gridAltitudeMetaData (FactMetaData::valueTypeDouble) , _gridAngleMetaData (FactMetaData::valueTypeDouble)