From f0df0818aec9c29b3a289ed941585517fed504ac Mon Sep 17 00:00:00 2001 From: DonLakeFlyer Date: Wed, 5 Aug 2020 10:47:45 -0700 Subject: [PATCH] Camera brand/model support. Use canonical camera names in Plan files. --- src/FirmwarePlugin/CameraMetaData.cc | 28 +- src/FirmwarePlugin/CameraMetaData.h | 61 +- src/FirmwarePlugin/FirmwarePlugin.cc | 628 ++++++++++-------- .../CameraCalc.FactMetaData.json | 40 +- src/MissionManager/CameraCalc.cc | 226 +++++-- src/MissionManager/CameraCalc.h | 50 +- src/MissionManager/CameraCalcTest.cc | 4 +- .../StructureScanComplexItemTest.cc | 2 +- src/MissionManager/SurveyComplexItem.cc | 4 +- .../TransectStyleComplexItemTest.cc | 6 +- src/PlanView/CameraCalcCamera.qml | 75 ++- 11 files changed, 682 insertions(+), 442 deletions(-) diff --git a/src/FirmwarePlugin/CameraMetaData.cc b/src/FirmwarePlugin/CameraMetaData.cc index d7cffb5fa..1347caf6b 100644 --- a/src/FirmwarePlugin/CameraMetaData.cc +++ b/src/FirmwarePlugin/CameraMetaData.cc @@ -9,7 +9,9 @@ #include "CameraMetaData.h" -CameraMetaData::CameraMetaData(const QString& name, +CameraMetaData::CameraMetaData(const QString& canonicalName, + const QString& brand, + const QString& model, double sensorWidth, double sensorHeight, double imageWidth, @@ -18,17 +20,21 @@ CameraMetaData::CameraMetaData(const QString& name, bool landscape, bool fixedOrientation, double minTriggerInterval, + const QString& deprecatedTranslatedName, QObject* parent) - : QObject (parent) - , _name (name) - , _sensorWidth (sensorWidth) - , _sensorHeight (sensorHeight) - , _imageWidth (imageWidth) - , _imageHeight (imageHeight) - , _focalLength (focalLength) - , _landscape (landscape) - , _fixedOrientation (fixedOrientation) - , _minTriggerInterval (minTriggerInterval) + : QObject (parent) + , canonicalName (canonicalName) + , brand (brand) + , model (model) + , sensorWidth (sensorWidth) + , sensorHeight (sensorHeight) + , imageWidth (imageWidth) + , imageHeight (imageHeight) + , focalLength (focalLength) + , landscape (landscape) + , fixedOrientation (fixedOrientation) + , minTriggerInterval (minTriggerInterval) + , deprecatedTranslatedName (deprecatedTranslatedName) { } diff --git a/src/FirmwarePlugin/CameraMetaData.h b/src/FirmwarePlugin/CameraMetaData.h index 66dfd87b0..748cca1ce 100644 --- a/src/FirmwarePlugin/CameraMetaData.h +++ b/src/FirmwarePlugin/CameraMetaData.h @@ -17,7 +17,9 @@ class CameraMetaData : public QObject Q_OBJECT public: - CameraMetaData(const QString& name, + CameraMetaData(const QString& canonicalName, + const QString& brand, + const QString& model, double sensorWidth, double sensorHeight, double imageWidth, @@ -26,36 +28,37 @@ public: bool landscape, bool fixedOrientation, double minTriggerInterval, + const QString& deprecatedTranslatedName, QObject* parent = nullptr); - Q_PROPERTY(QString name READ name CONSTANT) ///< Camera name - Q_PROPERTY(double sensorWidth READ sensorWidth CONSTANT) ///< Sensor size in millimeters - Q_PROPERTY(double sensorHeight READ sensorHeight CONSTANT) ///< Sensor size in millimeters - Q_PROPERTY(double imageWidth READ imageWidth CONSTANT) ///< Image size in pixels - Q_PROPERTY(double imageHeight READ imageHeight CONSTANT) ///< Image size in pixels - Q_PROPERTY(double focalLength READ focalLength CONSTANT) ///< Focal length in millimeters - Q_PROPERTY(bool landscape READ landscape CONSTANT) ///< true: camera is in landscape orientation - Q_PROPERTY(bool fixedOrientation READ fixedOrientation CONSTANT) ///< true: camera is in fixed orientation - Q_PROPERTY(double minTriggerInterval READ minTriggerInterval CONSTANT) ///< Minimum time in seconds between each photo taken, 0 for not specified + Q_PROPERTY(QString canonicalName MEMBER canonicalName CONSTANT) + Q_PROPERTY(QString deprecatedTranslatedName MEMBER deprecatedTranslatedName CONSTANT) + Q_PROPERTY(QString brand MEMBER brand CONSTANT) + Q_PROPERTY(QString model MEMBER model CONSTANT) + Q_PROPERTY(double sensorWidth MEMBER sensorWidth CONSTANT) + Q_PROPERTY(double sensorHeight MEMBER sensorHeight CONSTANT) + Q_PROPERTY(double imageWidth MEMBER imageWidth CONSTANT) + Q_PROPERTY(double imageHeight MEMBER imageHeight CONSTANT) + Q_PROPERTY(double focalLength MEMBER focalLength CONSTANT) + Q_PROPERTY(bool landscape MEMBER landscape CONSTANT) + Q_PROPERTY(bool fixedOrientation MEMBER fixedOrientation CONSTANT) + Q_PROPERTY(double minTriggerInterval MEMBER minTriggerInterval CONSTANT) - QString name (void) const { return _name; } - double sensorWidth (void) const { return _sensorWidth; } - double sensorHeight (void) const { return _sensorHeight; } - double imageWidth (void) const { return _imageWidth; } - double imageHeight (void) const { return _imageHeight; } - double focalLength (void) const { return _focalLength; } - bool landscape (void) const { return _landscape; } - bool fixedOrientation (void) const { return _fixedOrientation; } - double minTriggerInterval (void) const { return _minTriggerInterval; } + QString canonicalName; ///< Canonical name saved in plan files. Not translated. + QString brand; ///< Camera brand. Used for grouping. + QString model; ///< Camerar model + double sensorWidth; ///< Sensor size in millimeters + double sensorHeight; ///< Sensor size in millimeters + double imageWidth; ///< Image size in pixels + double imageHeight; ///< Image size in pixels + double focalLength; ///< Focal length in millimeters + bool landscape; ///< true: camera is in landscape orientation + bool fixedOrientation; ///< true: camera is in fixed orientation + double minTriggerInterval; ///< Minimum time in seconds between each photo taken, 0 for not specified -private: - QString _name; - double _sensorWidth; - double _sensorHeight; - double _imageWidth; - double _imageHeight; - double _focalLength; - bool _landscape; - bool _fixedOrientation; - double _minTriggerInterval; + /// In older builds camera names were incorrect marked for translation. This leads to plan files which have are language + /// dependant which is not a good thing. Newer plan files use the canonical name which is not translated. In order to support + /// loading older plan files we continue to include the incorrect translation so we can match against them as needed. + /// Newly added CameraMetaData entries should leave this value empty. + QString deprecatedTranslatedName; }; diff --git a/src/FirmwarePlugin/FirmwarePlugin.cc b/src/FirmwarePlugin/FirmwarePlugin.cc index 71c44e703..5f038bf51 100644 --- a/src/FirmwarePlugin/FirmwarePlugin.cc +++ b/src/FirmwarePlugin/FirmwarePlugin.cc @@ -174,7 +174,7 @@ bool FirmwarePlugin::sendHomePositionToVehicle(void) return false; } -QList FirmwarePlugin::supportedMissionCommands(QGCMAVLink::VehicleClass_t vehicleClass) +QList FirmwarePlugin::supportedMissionCommands(QGCMAVLink::VehicleClass_t /* vehicleClass */) { // Generic supports all commands return QList(); @@ -336,356 +336,432 @@ const QVariantList& FirmwarePlugin::cameraList(const Vehicle*) CameraMetaData* metaData; metaData = new CameraMetaData( - //tr("Canon S100 @ 5.2mm f/2"), - tr("Canon S100 PowerShot"), - 7.6, // sensorWidth - 5.7, // sensorHeight - 4000, // imageWidth - 3000, // imageHeight - 5.2, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + // Canon S100 @ 5.2mm f/2 + "Canon S100 PowerShot", // canonical name saved in plan file + tr("Canon"), // brand + tr("S100 PowerShot"), // model + 7.6, // sensorWidth + 5.7, // sensorHeight + 4000, // imageWidth + 3000, // imageHeight + 5.2, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Canon S100 PowerShot"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Canon EOS-M 22mm f/2"), - tr("Canon EOS-M 22mm"), - 22.3, // sensorWidth - 14.9, // sensorHeight - 5184, // imageWidth - 3456, // imageHeight - 22, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + //tr("Canon EOS-M 22mm f/2"), + "Canon EOS-M 22mm", + tr("Canon"), + tr("EOS-M 22mm"), + 22.3, // sensorWidth + 14.9, // sensorHeight + 5184, // imageWidth + 3456, // imageHeight + 22, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Canon EOS-M 22mm"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Canon G9X @ 10.2mm f/2"), - tr("Canon G9 X PowerShot"), - 13.2, // sensorWidth - 8.8, // sensorHeight - 5488, // imageWidth - 3680, // imageHeight - 10.2, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + // Canon G9X @ 10.2mm f/2 + "Canon G9 X PowerShot", + tr("Canon"), + tr("G9 X PowerShot"), + 13.2, // sensorWidth + 8.8, // sensorHeight + 5488, // imageWidth + 3680, // imageHeight + 10.2, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Canon G9 X PowerShot"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Canon SX260 HS @ 4.5mm f/3.5"), - tr("Canon SX260 HS PowerShot"), - 6.17, // sensorWidth - 4.55, // sensorHeight - 4000, // imageWidth - 3000, // imageHeight - 4.5, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + // Canon SX260 HS @ 4.5mm f/3.5 + "Canon SX260 HS PowerShot", + tr("Canon"), + tr("SX260 HS PowerShot"), + 6.17, // sensorWidth + 4.55, // sensorHeight + 4000, // imageWidth + 3000, // imageHeight + 4.5, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Canon SX260 HS PowerShot"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("GoPro Hero 4"), - 6.17, // sensorWidth - 4.55, // sendsorHeight - 4000, // imageWidth - 3000, // imageHeight - 2.98, // focalLength - true, // landscape - false, // fixedOrientation - 0, // minTriggerInterval - this); + "GoPro Hero 4", + tr("GoPro"), + tr("Hero 4"), + 6.17, // sensorWidth + 4.55, // sendsorHeight + 4000, // imageWidth + 3000, // imageHeight + 2.98, // focalLength + true, // landscape + false, // fixedOrientation + 0, // minTriggerInterval + tr("GoPro Hero 4"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Parrot Sequoia RGB"), - tr("Parrot Sequioa RGB"), - 6.17, // sensorWidth - 4.63, // sendsorHeight - 4608, // imageWidth - 3456, // imageHeight - 4.9, // focalLength - true, // landscape - false, // fixedOrientation - 1, // minTriggerInterval - this); + "Parrot Sequioa RGB", + tr("Parrot"), + tr("Sequioa RGB"), + 6.17, // sensorWidth + 4.63, // sendsorHeight + 4608, // imageWidth + 3456, // imageHeight + 4.9, // focalLength + true, // landscape + false, // fixedOrientation + 1, // minTriggerInterval + tr("Parrot Sequioa RGB"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Parrot Sequoia Monochrome"), - tr("Parrot Sequioa Monochrome"), - 4.8, // sensorWidth - 3.6, // sendsorHeight - 1280, // imageWidth - 960, // imageHeight - 4.0, // focalLength - true, // landscape - false, // fixedOrientation - 0.8, // minTriggerInterval - this); + "Parrot Sequioa Monochrome", + tr("Parrot"), + tr("Sequioa Monochrome"), + 4.8, // sensorWidth + 3.6, // sendsorHeight + 1280, // imageWidth + 960, // imageHeight + 4.0, // focalLength + true, // landscape + false, // fixedOrientation + 0.8, // minTriggerInterval + tr("Parrot Sequioa Monochrome"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("RedEdge"), - 4.8, // sensorWidth - 3.6, // sendsorHeight - 1280, // imageWidth - 960, // imageHeight - 5.5, // focalLength - true, // landscape - false, // fixedOrientation - 0, // minTriggerInterval - this); + "RedEdge", + tr("RedEdge"), + tr("RedEdge"), + 4.8, // sensorWidth + 3.6, // sendsorHeight + 1280, // imageWidth + 960, // imageHeight + 5.5, // focalLength + true, // landscape + false, // fixedOrientation + 0, // minTriggerInterval + tr("RedEdge"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Ricoh GR II 18.3mm f/2.8"), - tr("Ricoh GR II"), - 23.7, // sensorWidth - 15.7, // sendsorHeight - 4928, // imageWidth - 3264, // imageHeight - 18.3, // focalLength - true, // landscape - false, // fixedOrientation - 0, // minTriggerInterval - this); + // Ricoh GR II 18.3mm f/2.8 + "Ricoh GR II", + tr("Ricoh"), + tr("GR II"), + 23.7, // sensorWidth + 15.7, // sendsorHeight + 4928, // imageWidth + 3264, // imageHeight + 18.3, // focalLength + true, // landscape + false, // fixedOrientation + 0, // minTriggerInterval + tr("Ricoh GR II"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sentera Double 4K Sensor"), - 6.2, // sensorWidth - 4.65, // sendsorHeight - 4000, // imageWidth - 3000, // imageHeight - 5.4, // focalLength - true, // landscape - false, // fixedOrientation - 0, // minTriggerInterval - this); + "Sentera Double 4K Sensor", + tr("Sentera"), + tr("Double 4K Sensor"), + 6.2, // sensorWidth + 4.65, // sendsorHeight + 4000, // imageWidth + 3000, // imageHeight + 5.4, // focalLength + true, // landscape + false, // fixedOrientation + 0, // minTriggerInterval + tr("Sentera Double 4K Sensor"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sentera NDVI Single Sensor"), - 4.68, // sensorWidth - 3.56, // sendsorHeight - 1248, // imageWidth - 952, // imageHeight - 4.14, // focalLength - true, // landscape - false, // fixedOrientation - 0, // minTriggerInterval - this); + "Sentera NDVI Single Sensor", + tr("Sentera"), + tr("NDVI Single Sensor"), + 4.68, // sensorWidth + 3.56, // sendsorHeight + 1248, // imageWidth + 952, // imageHeight + 4.14, // focalLength + true, // landscape + false, // fixedOrientation + 0, // minTriggerInterval + tr("Sentera NDVI Single Sensor"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-6000-body-kit#product_details_default - //tr("Sony a6000 Sony 16mm f/2.8"), - tr("Sony a6000 16mm"), - 23.5, // sensorWidth - 15.6, // sensorHeight - 6000, // imageWidth - 4000, // imageHeight - 16, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-6000-body-kit#product_details_default + // Sony a6000 Sony 16mm f/2.8" + "Sony a6000 16mm", + tr("Sony"), + tr("a6000 16mm"), + 23.5, // sensorWidth + 15.6, // sensorHeight + 6000, // imageWidth + 4000, // imageHeight + 16, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony a6000 16mm"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony a6300 Zeiss 21mm f/2.8"), - 23.5, // sensorWidth - 15.6, // sensorHeight - 6000, // imageWidth - 4000, // imageHeight - 21, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + "Sony a6300 Zeiss 21mm f/2.8", + tr("Sony"), + tr("a6300 Zeiss 21mm f/2.8"), + 23.5, // sensorWidth + 15.6, // sensorHeight + 6000, // imageWidth + 4000, // imageHeight + 21, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony a6300 Zeiss 21mm f/2.8"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony a6300 Sony 28mm f/2.0"), - 23.5, // sensorWidth - 15.6, // sensorHeight - 6000, // imageWidth - 4000, // imageHeight - 28, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + "Sony a6300 Sony 28mm f/2.0", + tr("Sony"), + tr("a6300 Sony 28mm f/2.0"), + 23.5, // sensorWidth + 15.6, // sensorHeight + 6000, // imageWidth + 4000, // imageHeight + 28, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony a6300 Sony 28mm f/2.0"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony a7R II Zeiss 21mm f/2.8"), - 35.814, // sensorWidth - 23.876, // sensorHeight - 7952, // imageWidth - 5304, // imageHeight - 21, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + "Sony a7R II Zeiss 21mm f/2.8", + tr("Sony"), + tr("a7R II Zeiss 21mm f/2.8"), + 35.814, // sensorWidth + 23.876, // sensorHeight + 7952, // imageWidth + 5304, // imageHeight + 21, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony a7R II Zeiss 21mm f/2.8"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony a7R II Sony 28mm f/2.0"), - 35.814, // sensorWidth - 23.876, // sensorHeight - 7952, // imageWidth - 5304, // imageHeight - 28, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + "Sony a7R II Sony 28mm f/2.0", + tr("Sony"), + tr("a7R II Sony 28mm f/2.0"), + 35.814, // sensorWidth + 23.876, // sensorHeight + 7952, // imageWidth + 5304, // imageHeight + 28, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony a7R II Sony 28mm f/2.0"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony DSC-QX30U @ 4.3mm f/3.5"), - 7.82, // sensorWidth - 5.865, // sensorHeight - 5184, // imageWidth - 3888, // imageHeight - 4.3, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 2.0, // minimum trigger interval - this); // parent + "Sony DSC-QX30U @ 4.3mm f/3.5", + tr("Sony"), + tr("DSC-QX30U @ 4.3mm f/3.5"), + 7.82, // sensorWidth + 5.865, // sensorHeight + 5184, // imageWidth + 3888, // imageHeight + 4.3, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 2.0, // minimum trigger interval + tr("Sony DSC-QX30U @ 4.3mm f/3.5"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Sony DSC-RX0"), - 13.2, // sensorWidth - 8.8, // sensorHeight - 4800, // imageWidth - 3200, // imageHeight - 7.7, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + "Sony DSC-RX0", + tr("Sony"), + tr("DSC-RX0"), + 13.2, // sensorWidth + 8.8, // sensorHeight + 4800, // imageWidth + 3200, // imageHeight + 7.7, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Sony DSC-RX0"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-qx1-body-kit/specifications - //-- http://www.sony.com/electronics/camera-lenses/sel16f28/specifications - //tr("Sony ILCE-QX1 Sony 16mm f/2.8"), - tr("Sony ILCE-QX1"), - 23.2, // sensorWidth - 15.4, // sensorHeight - 5456, // imageWidth - 3632, // imageHeight - 16, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-qx1-body-kit/specifications + //-- http://www.sony.com/electronics/camera-lenses/sel16f28/specifications + //tr("Sony ILCE-QX1 Sony 16mm f/2.8"), + "Sony ILCE-QX1", + tr("Sony"), + tr("ILCE-QX1"), + 23.2, // sensorWidth + 15.4, // sensorHeight + 5456, // imageWidth + 3632, // imageHeight + 16, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Sony ILCE-QX1"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-qx1-body-kit/specifications - //tr("Sony NEX-5R Sony 20mm f/2.8"), - tr("Sony NEX-5R 20mm"), - 23.2, // sensorWidth - 15.4, // sensorHeight - 4912, // imageWidth - 3264, // imageHeight - 20, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 1, // minimum trigger interval - this); // parent + //-- http://www.sony.co.uk/electronics/interchangeable-lens-cameras/ilce-qx1-body-kit/specifications + // Sony NEX-5R Sony 20mm f/2.8" + "Sony NEX-5R 20mm", + tr("Sony"), + tr("NEX-5R 20mm"), + 23.2, // sensorWidth + 15.4, // sensorHeight + 4912, // imageWidth + 3264, // imageHeight + 20, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 1, // minimum trigger interval + tr("Sony NEX-5R 20mm"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - //tr("Sony RX100 II @ 10.4mm f/1.8"), - tr("Sony RX100 II 28mm"), - 13.2, // sensorWidth - 8.8, // sensorHeight - 5472, // imageWidth - 3648, // imageHeight - 10.4, // focalLength - true, // true: landscape orientation - false, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + // Sony RX100 II @ 10.4mm f/1.8 + "Sony RX100 II 28mm", + tr("Sony"), + tr("RX100 II 28mm"), + 13.2, // sensorWidth + 8.8, // sensorHeight + 5472, // imageWidth + 3648, // imageHeight + 10.4, // focalLength + true, // true: landscape orientation + false, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Sony RX100 II 28mm"),// SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Yuneec CGOET"), - 5.6405, // sensorWidth - 3.1813, // sensorHeight - 1920, // imageWidth - 1080, // imageHeight - 3.5, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 1.3, // minimum trigger interval - this); // parent + "Yuneec CGOET", + tr("Yuneec"), + tr("CGOET"), + 5.6405, // sensorWidth + 3.1813, // sensorHeight + 1920, // imageWidth + 1080, // imageHeight + 3.5, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 1.3, // minimum trigger interval + tr("Yuneec CGOET"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Yuneec E10T"), - 5.6405, // sensorWidth - 3.1813, // sensorHeight - 1920, // imageWidth - 1080, // imageHeight - 23, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 1.3, // minimum trigger interval - this); // parent + "Yuneec E10T", + tr("Yuneec"), + tr("E10T"), + 5.6405, // sensorWidth + 3.1813, // sensorHeight + 1920, // imageWidth + 1080, // imageHeight + 23, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 1.3, // minimum trigger interval + tr("Yuneec E10T"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Yuneec E50"), - 6.2372, // sensorWidth - 4.7058, // sensorHeight - 4000, // imageWidth - 3000, // imageHeight - 7.2, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 1.3, // minimum trigger interval - this); // parent + "Yuneec E50", + tr("Yuneec"), + tr("E50"), + 6.2372, // sensorWidth + 4.7058, // sensorHeight + 4000, // imageWidth + 3000, // imageHeight + 7.2, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 1.3, // minimum trigger interval + tr("Yuneec E50"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Yuneec E90"), - 13.3056, // sensorWidth - 8.656, // sensorHeight - 5472, // imageWidth - 3648, // imageHeight - 8.29, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 1.3, // minimum trigger interval - this); // parent + "Yuneec E90", + tr("Yuneec"), + tr("E90"), + 13.3056, // sensorWidth + 8.656, // sensorHeight + 5472, // imageWidth + 3648, // imageHeight + 8.29, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 1.3, // minimum trigger interval + tr("Yuneec E90"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); metaData = new CameraMetaData( - tr("Flir Duo R"), - 160, // sensorWidth - 120, // sensorHeight - 1920, // imageWidth - 1080, // imageHeight - 1.9, // focalLength - true, // true: landscape orientation - true, // true: camera is fixed orientation - 0, // minimum trigger interval - this); // parent + "Flir Duo R", + tr("Flir"), + tr("Duo R"), + 160, // sensorWidth + 120, // sensorHeight + 1920, // imageWidth + 1080, // imageHeight + 1.9, // focalLength + true, // true: landscape orientation + true, // true: camera is fixed orientation + 0, // minimum trigger interval + tr("Flir Duo R"), // SHOULD BE BLANK FOR NEWLY ADDED CAMERAS. Deprecated translation from older builds. + this); // parent _cameraList.append(QVariant::fromValue(metaData)); } diff --git a/src/MissionManager/CameraCalc.FactMetaData.json b/src/MissionManager/CameraCalc.FactMetaData.json index 5149d444a..358acd791 100644 --- a/src/MissionManager/CameraCalc.FactMetaData.json +++ b/src/MissionManager/CameraCalc.FactMetaData.json @@ -1,57 +1,57 @@ { - "version": 1, - "fileType": "FactMetaData", + "version": 1, + "fileType": "FactMetaData", "QGC.MetaData.Facts": [ { - "name": "CameraName", - "shortDesc": "Camera name.", - "type": "string", - "default": "Manual (no camera specs)" + "name": "CameraName", + "shortDesc": "Camera name.", + "type": "string", + "default": "Manual (no camera specs)" }, { - "name": "ValueSetIsDistance", - "shortDesc": "Value specified is distance to surface.", - "type": "bool", - "default": 1 + "name": "ValueSetIsDistance", + "shortDesc": "Value specified is distance to surface.", + "type": "bool", + "default": 1 }, { "name": "DistanceToSurface", - "shortDesc": "Distance vehicle is away from surface.", + "shortDesc": "Distance vehicle is away from surface.", "type": "double", "min": 0.1, "units": "m", "decimalPlaces": 2, - "default": 50.0 + "default": 50.0 }, { "name": "ImageDensity", - "shortDesc": "Image desity at surface.", + "shortDesc": "Image desity at surface.", "type": "double", "min": 0, "units": "cm/px", "decimalPlaces": 1, - "default": 1.2 + "default": 1.2 }, { "name": "FrontalOverlap", - "shortDesc": "Amount of overlap between images in the forward facing direction.", + "shortDesc": "Amount of overlap between images in the forward facing direction.", "type": "double", "decimalPlaces": 0, "min": 0, "max": 85, "units": "%", - "default": 70 + "default": 70 }, { "name": "SideOverlap", - "shortDesc": "Amount of overlap between images in the side facing direction.", + "shortDesc": "Amount of overlap between images in the side facing direction.", "type": "double", "decimalPlaces": 0, "min": 0, "max": 85, "units": "%", - "default": 70 + "default": 70 }, { "name": "AdjustedFootprintFrontal", @@ -59,7 +59,7 @@ "decimalPlaces": 2, "min": 0, "units": "m", - "default": 25 + "default": 25 }, { "name": "AdjustedFootprintSide", @@ -67,7 +67,7 @@ "decimalPlaces": 2, "min": 0, "units": "m", - "default": 25 + "default": 25 } ] } diff --git a/src/MissionManager/CameraCalc.cc b/src/MissionManager/CameraCalc.cc index 39a9719d9..e2afd649b 100644 --- a/src/MissionManager/CameraCalc.cc +++ b/src/MissionManager/CameraCalc.cc @@ -29,9 +29,7 @@ const char* CameraCalc::_jsonCameraSpecTypeKey = "CameraSpecType"; CameraCalc::CameraCalc(PlanMasterController* masterController, const QString& settingsGroup, QObject* parent) : CameraSpec (settingsGroup, parent) - , _dirty (false) - , _disableRecalc (false) - , _distanceToSurfaceRelative (true) + , _knownCameraList (masterController->controllerVehicle()->staticCameraList()) , _metaDataMap (FactMetaData::createMapFromJsonFile(QStringLiteral(":/json/CameraCalc.FactMetaData.json"), this)) , _cameraNameFact (settingsGroup, _metaDataMap[cameraNameName]) , _valueSetIsDistanceFact (settingsGroup, _metaDataMap[valueSetIsDistanceName]) @@ -41,9 +39,6 @@ CameraCalc::CameraCalc(PlanMasterController* masterController, const QString& se , _sideOverlapFact (settingsGroup, _metaDataMap[sideOverlapName]) , _adjustedFootprintSideFact (settingsGroup, _metaDataMap[adjustedFootprintSideName]) , _adjustedFootprintFrontalFact (settingsGroup, _metaDataMap[adjustedFootprintFrontalName]) - , _imageFootprintSide (0) - , _imageFootprintFrontal (0) - , _knownCameraList (masterController->controllerVehicle()->staticCameraList()) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); @@ -72,7 +67,18 @@ CameraCalc::CameraCalc(PlanMasterController* masterController, const QString& se connect(focalLength(), &Fact::rawValueChanged, this, &CameraCalc::_recalcTriggerDistance); connect(landscape(), &Fact::rawValueChanged, this, &CameraCalc::_recalcTriggerDistance); + // Build the brand list from known cameras + _cameraBrandList.append(xlatManualCameraName()); + _cameraBrandList.append(xlatCustomCameraName()); + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (!_cameraBrandList.contains(cameraMetaData->brand)) { + _cameraBrandList.append(cameraMetaData->brand); + } + } + _cameraNameChanged(); + _setBrandModelFromCanonicalName(_cameraNameFact.rawValue().toString()); setDirty(false); } @@ -93,48 +99,43 @@ void CameraCalc::_cameraNameChanged(void) QString cameraName = _cameraNameFact.rawValue().toString(); - // Validate known camera name - bool foundKnownCamera = false; - CameraMetaData* cameraMetaData = nullptr; - if (!isManualCamera() && !isCustomCamera()) { + if (isManualCamera() || isCustomCamera()) { + fixedOrientation()->setRawValue(false); + minTriggerInterval()->setRawValue(0); + if (isManualCamera() && !valueSetIsDistance()->rawValue().toBool()) { + valueSetIsDistance()->setRawValue(true); + } + } else { + // Look for known camera + CameraMetaData* knownCameraMetaData = nullptr; for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { - cameraMetaData = _knownCameraList[cameraIndex].value(); - if (cameraName == cameraMetaData->name()) { - foundKnownCamera = true; + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (cameraName == cameraMetaData->canonicalName) { + knownCameraMetaData = cameraMetaData; break; } } - if (!foundKnownCamera) { - // This will cause another camera changed signal which will recurse back to this routine - _cameraNameFact.setRawValue(customCameraName()); + if (!knownCameraMetaData) { + // Lookup failed. Force to custom as fallback. + // This will cause another camera changed signal which will recurse back into this routine + _cameraNameFact.setRawValue(canonicalCustomCameraName()); return; } - } - _disableRecalc = true; - if (foundKnownCamera) { - sensorWidth()->setRawValue (cameraMetaData->sensorWidth()); - sensorHeight()->setRawValue (cameraMetaData->sensorHeight()); - imageWidth()->setRawValue (cameraMetaData->imageWidth()); - imageHeight()->setRawValue (cameraMetaData->imageHeight()); - focalLength()->setRawValue (cameraMetaData->focalLength()); - landscape()->setRawValue (cameraMetaData->landscape()); - fixedOrientation()->setRawValue (cameraMetaData->fixedOrientation()); - minTriggerInterval()->setRawValue (cameraMetaData->minTriggerInterval()); - } else { - if (isManualCamera() || isCustomCamera()) { - // These values are unknown for these types - fixedOrientation()->setRawValue(false); - minTriggerInterval()->setRawValue(0); - if (isManualCamera() && !valueSetIsDistance()->rawValue().toBool()) { - valueSetIsDistance()->setRawValue(true); - } - } else { - qWarning() << "Internal Error: Not known camera, but now manual or custom either"; - } + _disableRecalc = true; + + sensorWidth()->setRawValue (knownCameraMetaData->sensorWidth); + sensorHeight()->setRawValue (knownCameraMetaData->sensorHeight); + imageWidth()->setRawValue (knownCameraMetaData->imageWidth); + imageHeight()->setRawValue (knownCameraMetaData->imageHeight); + focalLength()->setRawValue (knownCameraMetaData->focalLength); + landscape()->setRawValue (knownCameraMetaData->landscape); + fixedOrientation()->setRawValue (knownCameraMetaData->fixedOrientation); + minTriggerInterval()->setRawValue (knownCameraMetaData->minTriggerInterval); + + _disableRecalc = false; } - _disableRecalc = false; _recalcTriggerDistance(); _adjustDistanceToSurfaceRelative(); @@ -212,9 +213,9 @@ bool CameraCalc::load(const QJsonObject& json, QString& errorString) // _jsonCameraNameKey only set if CameraSpecKnown int cameraSpec = v1Json[_jsonCameraSpecTypeKey].toInt(CameraSpecNone); if (cameraSpec == CameraSpecCustom) { - v1Json[cameraNameName] = customCameraName(); + v1Json[cameraNameName] = canonicalCustomCameraName(); } else if (cameraSpec == CameraSpecNone) { - v1Json[cameraNameName] = manualCameraName(); + v1Json[cameraNameName] = canonicalManualCameraName(); } v1Json.remove(_jsonCameraSpecTypeKey); v1Json[JsonHelper::jsonVersionKey] = 1; @@ -241,11 +242,15 @@ bool CameraCalc::load(const QJsonObject& json, QString& errorString) _distanceToSurfaceRelative = v1Json[distanceToSurfaceRelativeName].toBool(); - _cameraNameFact.setRawValue (v1Json[cameraNameName].toString()); _adjustedFootprintSideFact.setRawValue (v1Json[adjustedFootprintSideName].toDouble()); _adjustedFootprintFrontalFact.setRawValue (v1Json[adjustedFootprintFrontalName].toDouble()); _distanceToSurfaceFact.setRawValue (v1Json[distanceToSurfaceName].toDouble()); + // We have to clean up camera names. Older builds incorrectly used translated the camera names in the persisted plan file. + // Newer builds use a canonical english camera name in plan files. + QString canonicalCameraName = _validCanonicalCameraName(v1Json[cameraNameName].toString()); + _cameraNameFact.setRawValue(canonicalCameraName); + if (!isManualCamera()) { QList keyInfoList2 = { { valueSetIsDistanceName, QJsonValue::Bool, true }, @@ -271,15 +276,29 @@ bool CameraCalc::load(const QJsonObject& json, QString& errorString) _disableRecalc = false; + _setBrandModelFromCanonicalName(canonicalCameraName); + return true; } -QString CameraCalc::customCameraName(void) +QString CameraCalc::canonicalCustomCameraName(void) +{ + // This string should NOT be translated + return "Custom Camera"; +} + +QString CameraCalc::canonicalManualCameraName(void) +{ + // This string should NOT be translated + return "Manual (no camera specs)"; +} + +QString CameraCalc::xlatCustomCameraName(void) { return tr("Custom Camera"); } -QString CameraCalc::manualCameraName(void) +QString CameraCalc::xlatManualCameraName(void) { return tr("Manual (no camera specs)"); } @@ -303,3 +322,122 @@ void CameraCalc::_setDirty(void) { setDirty(true); } + +void CameraCalc::setCameraBrand(const QString& cameraBrand) +{ + // Note that cameraBrand can also be manual or custom camera + + if (cameraBrand != _cameraBrand) { + QString newCameraName = cameraBrand; + + _cameraBrand = cameraBrand; + _cameraModel.clear(); + + if (_cameraBrand != xlatManualCameraName() && _cameraBrand != xlatCustomCameraName()) { + CameraMetaData* firstCameraMetaData = nullptr; + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + firstCameraMetaData = _knownCameraList[cameraIndex].value(); + if (firstCameraMetaData->brand == _cameraBrand) { + break; + } + } + newCameraName = firstCameraMetaData->canonicalName; + _cameraModel = firstCameraMetaData->model; + } + emit cameraBrandChanged(); + emit cameraModelChanged(); + + _rebuildCameraModelList(); + + _cameraNameFact.setRawValue(newCameraName); + } +} + +void CameraCalc::setCameraModel(const QString& cameraModel) +{ + if (cameraModel != _cameraModel) { + _cameraModel = cameraModel; + emit cameraModelChanged(); + + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (cameraMetaData->brand == _cameraBrand && cameraMetaData->model == _cameraModel) { + _cameraNameFact.setRawValue(cameraMetaData->canonicalName); + break; + } + } + + } +} + +void CameraCalc::_setBrandModelFromCanonicalName(const QString& cameraName) +{ + _cameraBrand = cameraName; + _cameraModel.clear(); + _cameraModelList.clear(); + + if (cameraName != canonicalManualCameraName() && cameraName != canonicalCustomCameraName()) { + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (cameraMetaData->canonicalName == cameraName) { + _cameraBrand = cameraMetaData->brand; + _cameraModel = cameraMetaData->model; + break; + } + } + } + emit cameraBrandChanged(); + emit cameraModelChanged(); + + _rebuildCameraModelList(); +} + +void CameraCalc::_rebuildCameraModelList(void) +{ + _cameraModelList.clear(); + + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (cameraMetaData->brand == _cameraBrand) { + _cameraModelList.append(cameraMetaData->model); + } + } + + emit cameraModelListChanged(); +} + +void CameraCalc::_setCameraNameFromV3TransectLoad(const QString& cameraName) +{ + // We don't recalc here since the rest of the camera values are already loaded from the json + _disableRecalc = true; + QString canonicalCameraName = _validCanonicalCameraName(cameraName); + _cameraNameFact.setRawValue(cameraName); + _disableRecalc = true; + + _setBrandModelFromCanonicalName(canonicalCameraName); +} + +QString CameraCalc::_validCanonicalCameraName(const QString& cameraName) +{ + QString canonicalCameraName = cameraName; + + if (canonicalCameraName != canonicalCustomCameraName() && canonicalCameraName != canonicalManualCameraName()) { + if (cameraName == xlatManualCameraName()) { + canonicalCameraName = canonicalManualCameraName(); + } else if (cameraName == xlatCustomCameraName()) { + canonicalCameraName = canonicalCustomCameraName(); + } else { + // Look for known camera + for (int cameraIndex=0; cameraIndex<_knownCameraList.count(); cameraIndex++) { + CameraMetaData* cameraMetaData = _knownCameraList[cameraIndex].value(); + if (cameraName == cameraMetaData->canonicalName || cameraName == cameraMetaData->deprecatedTranslatedName) { + return cameraMetaData->canonicalName; + } + } + + canonicalCameraName = canonicalCustomCameraName(); + } + } + + return canonicalCameraName; +} diff --git a/src/MissionManager/CameraCalc.h b/src/MissionManager/CameraCalc.h index 054160cf7..04e601960 100644 --- a/src/MissionManager/CameraCalc.h +++ b/src/MissionManager/CameraCalc.h @@ -21,11 +21,14 @@ class CameraCalc : public CameraSpec public: CameraCalc(PlanMasterController* masterController, const QString& settingsGroup, QObject* parent = nullptr); - Q_PROPERTY(QString customCameraName READ customCameraName CONSTANT) ///< Camera name for custom camera setting - Q_PROPERTY(QString manualCameraName READ manualCameraName CONSTANT) ///< Camera name for manual camera setting + Q_PROPERTY(QString xlatCustomCameraName READ xlatCustomCameraName CONSTANT) ///< User visible camera name for custom camera setting + Q_PROPERTY(QString xlatManualCameraName READ xlatManualCameraName CONSTANT) ///< User visible camera name for manual camera setting Q_PROPERTY(bool isManualCamera READ isManualCamera NOTIFY isManualCameraChanged) Q_PROPERTY(bool isCustomCamera READ isCustomCamera NOTIFY isCustomCameraChanged) - Q_PROPERTY(Fact* cameraName READ cameraName CONSTANT) + Q_PROPERTY(QString cameraBrand MEMBER _cameraBrand WRITE setCameraBrand NOTIFY cameraBrandChanged) + Q_PROPERTY(QString cameraModel MEMBER _cameraModel WRITE setCameraModel NOTIFY cameraModelChanged) + Q_PROPERTY(QStringList cameraBrandList MEMBER _cameraBrandList CONSTANT) + Q_PROPERTY(QStringList cameraModelList MEMBER _cameraModelList NOTIFY cameraModelListChanged) Q_PROPERTY(Fact* valueSetIsDistance READ valueSetIsDistance CONSTANT) ///< true: distance specified, resolution calculated Q_PROPERTY(Fact* distanceToSurface READ distanceToSurface CONSTANT) ///< Distance to surface for image foot print calculation Q_PROPERTY(Fact* imageDensity READ imageDensity CONSTANT) ///< Image density on surface (cm/px) @@ -46,10 +49,11 @@ public: Q_PROPERTY(double imageFootprintSide READ imageFootprintSide NOTIFY imageFootprintSideChanged) ///< Size of image size side in meters Q_PROPERTY(double imageFootprintFrontal READ imageFootprintFrontal NOTIFY imageFootprintFrontalChanged) ///< Size of image size frontal in meters - static QString customCameraName(void); - static QString manualCameraName(void); + static QString xlatCustomCameraName (void); + static QString xlatManualCameraName (void); + static QString canonicalCustomCameraName(void); + static QString canonicalManualCameraName(void); - Fact* cameraName (void) { return &_cameraNameFact; } Fact* valueSetIsDistance (void) { return &_valueSetIsDistanceFact; } Fact* distanceToSurface (void) { return &_distanceToSurfaceFact; } Fact* imageDensity (void) { return &_imageDensityFact; } @@ -67,18 +71,22 @@ public: const Fact* adjustedFootprintFrontal (void) const { return &_adjustedFootprintFrontalFact; } bool dirty (void) const { return _dirty; } - bool isManualCamera (void) const { return _cameraNameFact.rawValue().toString() == manualCameraName(); } - bool isCustomCamera (void) const { return _cameraNameFact.rawValue().toString() == customCameraName(); } + bool isManualCamera (void) const { return _cameraNameFact.rawValue().toString() == canonicalManualCameraName(); } + bool isCustomCamera (void) const { return _cameraNameFact.rawValue().toString() == canonicalCustomCameraName(); } double imageFootprintSide (void) const { return _imageFootprintSide; } double imageFootprintFrontal (void) const { return _imageFootprintFrontal; } bool distanceToSurfaceRelative (void) const { return _distanceToSurfaceRelative; } void setDirty (bool dirty); void setDistanceToSurfaceRelative (bool distanceToSurfaceRelative); + void setCameraBrand (const QString& cameraBrand); + void setCameraModel (const QString& cameraModel); void save(QJsonObject& json) const; bool load(const QJsonObject& json, QString& errorString); + void _setCameraNameFromV3TransectLoad (const QString& cameraName); + static const char* cameraNameName; static const char* valueSetIsDistanceName; static const char* distanceToSurfaceName; @@ -96,6 +104,10 @@ signals: void distanceToSurfaceRelativeChanged (bool distanceToSurfaceRelative); void isManualCameraChanged (void); void isCustomCameraChanged (void); + void cameraBrandChanged (void); + void cameraModelChanged (void); + void cameraModelListChanged (void); + void updateCameraStats (void); private slots: void _recalcTriggerDistance (void); @@ -104,9 +116,20 @@ private slots: void _cameraNameChanged (void); private: - bool _dirty; - bool _disableRecalc; - bool _distanceToSurfaceRelative; + void _setBrandModelFromCanonicalName (const QString& cameraName); + void _rebuildCameraModelList (void); + QString _validCanonicalCameraName (const QString& cameraName); + + bool _dirty = false; + bool _disableRecalc = false; + QString _cameraBrand; + QString _cameraModel; + QStringList _cameraBrandList; + QStringList _cameraModelList; + bool _distanceToSurfaceRelative = true; + double _imageFootprintSide = 0; + double _imageFootprintFrontal = 0; + QVariantList _knownCameraList; QMap _metaDataMap; @@ -119,11 +142,6 @@ private: SettingsFact _adjustedFootprintSideFact; SettingsFact _adjustedFootprintFrontalFact; - double _imageFootprintSide; - double _imageFootprintFrontal; - - QVariantList _knownCameraList; - // The following are deprecated usage and only included in order to convert older formats enum CameraSpecType { diff --git a/src/MissionManager/CameraCalcTest.cc b/src/MissionManager/CameraCalcTest.cc index 6ceccbbe3..e2742f833 100644 --- a/src/MissionManager/CameraCalcTest.cc +++ b/src/MissionManager/CameraCalcTest.cc @@ -23,7 +23,7 @@ void CameraCalcTest::init(void) _masterController = new PlanMasterController(this); _controllerVehicle = _masterController->controllerVehicle(); _cameraCalc = new CameraCalc(_masterController, "CameraCalcUnitTest" /* settingsGroup */, this); - _cameraCalc->cameraName()->setRawValue(_cameraCalc->customCameraName()); + _cameraCalc->setCameraBrand(CameraCalc::canonicalCustomCameraName()); _cameraCalc->setDirty(false); _rgSignals[dirtyChangedIndex] = SIGNAL(dirtyChanged(bool)); @@ -87,7 +87,7 @@ void CameraCalcTest::_testDirty(void) QVERIFY(_cameraCalc->dirty()); _multiSpy->clearAllSignals(); - _cameraCalc->cameraName()->setRawValue(_cameraCalc->manualCameraName()); + _cameraCalc->setCameraBrand(CameraCalc::canonicalManualCameraName()); QVERIFY(_cameraCalc->dirty()); _multiSpy->clearAllSignals(); } diff --git a/src/MissionManager/StructureScanComplexItemTest.cc b/src/MissionManager/StructureScanComplexItemTest.cc index 6cc31e91e..db3c06e9a 100644 --- a/src/MissionManager/StructureScanComplexItemTest.cc +++ b/src/MissionManager/StructureScanComplexItemTest.cc @@ -85,7 +85,7 @@ void StructureScanComplexItemTest::_initItem(void) mapPolygon->appendVertex(vertex); } - _structureScanItem->cameraCalc()->cameraName()->setRawValue(CameraCalc::manualCameraName()); + _structureScanItem->cameraCalc()->setCameraBrand(CameraCalc::canonicalManualCameraName()); _structureScanItem->layers()->setCookedValue(2); _structureScanItem->setDirty(false); diff --git a/src/MissionManager/SurveyComplexItem.cc b/src/MissionManager/SurveyComplexItem.cc index e2d2d0e7c..3096dab60 100644 --- a/src/MissionManager/SurveyComplexItem.cc +++ b/src/MissionManager/SurveyComplexItem.cc @@ -324,7 +324,7 @@ bool SurveyComplexItem::_loadV3(const QJsonObject& complexObject, int sequenceNu _cameraCalc.adjustedFootprintFrontal()->setRawValue (complexObject[_jsonV3CameraTriggerDistanceKey].toDouble()); if (manualGrid) { - _cameraCalc.cameraName()->setRawValue(_cameraCalc.manualCameraName()); + _cameraCalc.setCameraBrand(CameraCalc::canonicalManualCameraName()); } else { if (!complexObject.contains(_jsonV3CameraObjectKey)) { errorString = tr("%1 but %2 object is missing").arg("manualGrid = false").arg("camera"); @@ -359,7 +359,6 @@ bool SurveyComplexItem::_loadV3(const QJsonObject& complexObject, int sequenceNu return false; } - _cameraCalc.cameraName()->setRawValue (cameraObject[_jsonV3CameraNameKey].toString()); _cameraCalc.landscape()->setRawValue (cameraObject[_jsonV3CameraOrientationLandscapeKey].toBool(true)); _cameraCalc.frontalOverlap()->setRawValue (cameraObject[_jsonV3FrontalOverlapKey].toInt()); _cameraCalc.sideOverlap()->setRawValue (cameraObject[_jsonV3SideOverlapKey].toInt()); @@ -371,6 +370,7 @@ bool SurveyComplexItem::_loadV3(const QJsonObject& complexObject, int sequenceNu _cameraCalc.minTriggerInterval()->setRawValue (cameraObject[_jsonV3CameraMinTriggerIntervalKey].toDouble(0)); _cameraCalc.imageDensity()->setRawValue (cameraObject[_jsonV3GroundResolutionKey].toDouble()); _cameraCalc.fixedOrientation()->setRawValue (false); + _cameraCalc._setCameraNameFromV3TransectLoad (cameraObject[_jsonV3CameraNameKey].toString()); } // Polygon shape diff --git a/src/MissionManager/TransectStyleComplexItemTest.cc b/src/MissionManager/TransectStyleComplexItemTest.cc index 48524eb71..63143e6b8 100644 --- a/src/MissionManager/TransectStyleComplexItemTest.cc +++ b/src/MissionManager/TransectStyleComplexItemTest.cc @@ -20,7 +20,7 @@ void TransectStyleComplexItemTest::init(void) _transectStyleItem = new TestTransectStyleItem(_masterController, this); _transectStyleItem->cameraTriggerInTurnAround()->setRawValue(false); - _transectStyleItem->cameraCalc()->cameraName()->setRawValue(_transectStyleItem->cameraCalc()->customCameraName()); + _transectStyleItem->cameraCalc()->setCameraBrand(CameraCalc::canonicalCustomCameraName()); _transectStyleItem->cameraCalc()->valueSetIsDistance()->setRawValue(true); _transectStyleItem->cameraCalc()->distanceToSurface()->setRawValue(100); _transectStyleItem->setDirty(false); @@ -192,9 +192,9 @@ void TransectStyleComplexItemTest::_testAltMode(void) // Manual camera allows non-relative altitudes, validate that changing back to known // camera switches back to relative - _transectStyleItem->cameraCalc()->cameraName()->setRawValue(_transectStyleItem->cameraCalc()->manualCameraName()); + _transectStyleItem->cameraCalc()->setCameraBrand(CameraCalc::canonicalManualCameraName()); _transectStyleItem->cameraCalc()->setDistanceToSurfaceRelative(false); - _transectStyleItem->cameraCalc()->cameraName()->setRawValue(_transectStyleItem->cameraCalc()->customCameraName()); + _transectStyleItem->cameraCalc()->setCameraBrand(CameraCalc::canonicalCustomCameraName()); QVERIFY(_transectStyleItem->cameraCalc()->distanceToSurfaceRelative()); // When you turn off terrain following mode make sure that the altitude mode changed back to relative altitudes diff --git a/src/PlanView/CameraCalcCamera.qml b/src/PlanView/CameraCalcCamera.qml index 4f74ade24..ba069e82b 100644 --- a/src/PlanView/CameraCalcCamera.qml +++ b/src/PlanView/CameraCalcCamera.qml @@ -17,42 +17,13 @@ Column { property var cameraCalc property real _margin: ScreenTools.defaultFontPixelWidth / 2 - property string _cameraName: cameraCalc.cameraName.value property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5 - property var _cameraList: [ ] property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle property var _vehicleCameraList: _vehicle ? _vehicle.staticCameraList : [] - property bool _cameraComboFilled: false - readonly property int _gridTypeManual: 0 - readonly property int _gridTypeCustomCamera: 1 - readonly property int _gridTypeCamera: 2 - - Component.onCompleted: _fillCameraCombo() - - on_CameraNameChanged: _updateSelectedCamera() - - function _fillCameraCombo() { - _cameraComboFilled = true - _cameraList.push(cameraCalc.manualCameraName) - _cameraList.push(cameraCalc.customCameraName) - for (var i=0; i<_vehicle.staticCameraList.length; i++) { - _cameraList.push(_vehicle.staticCameraList[i].name) - } - gridTypeCombo.model = _cameraList - _updateSelectedCamera() - } - - function _updateSelectedCamera() { - if (_cameraComboFilled) { - var knownCameraIndex = gridTypeCombo.find(_cameraName) - if (knownCameraIndex !== -1) { - gridTypeCombo.currentIndex = knownCameraIndex - } else { - console.log("Internal error: Known camera not found", _cameraName) - gridTypeCombo.currentIndex = _gridTypeCustomCamera - } - } + Component.onCompleted:{ + cameraBrandCombo.selectCurrentBrand() + cameraModelCombo.selectCurrentModel() } QGCPalette { id: qgcPal; colorGroupEnabled: true } @@ -67,13 +38,41 @@ Column { spacing: _margin QGCComboBox { - id: gridTypeCombo + id: cameraBrandCombo anchors.left: parent.left anchors.right: parent.right - model: _cameraList - currentIndex: -1 - onActivated: cameraCalc.cameraName.value = gridTypeCombo.textAt(index) - } // QGCComboxBox + model: cameraCalc.cameraBrandList + onModelChanged: selectCurrentBrand() + onActivated: cameraCalc.cameraBrand = currentText + + Connections { + target: cameraCalc + onCameraBrandChanged: cameraBrandCombo.selectCurrentBrand() + } + + function selectCurrentBrand() { + currentIndex = cameraBrandCombo.find(cameraCalc.cameraBrand) + } + } + + QGCComboBox { + id: cameraModelCombo + anchors.left: parent.left + anchors.right: parent.right + model: cameraCalc.cameraModelList + visible: !cameraCalc.isManualCamera && !cameraCalc.isCustomCamera + onModelChanged: selectCurrentModel() + onActivated: cameraCalc.cameraModel = currentText + + Connections { + target: cameraCalc + onCameraModelChanged: cameraModelCombo.selectCurrentModel() + } + + function selectCurrentModel() { + currentIndex = cameraModelCombo.find(cameraCalc.cameraModel) + } + } // Camera based grid ui Column { @@ -108,7 +107,7 @@ Column { anchors.left: parent.left anchors.right: parent.right spacing: _margin - visible: cameraCalc.isCustomCamera + enabled: cameraCalc.isCustomCamera RowLayout { anchors.left: parent.left -- 2.22.0