From 27b0db4e6a92bc406de3b3eb8d6897083d96cb21 Mon Sep 17 00:00:00 2001 From: Gus Grubba <gus@auterion.com> Date: Sun, 28 Jul 2019 01:00:01 -0400 Subject: [PATCH] Quick access to thermal modes --- custom-example/custom.qrc | 4 + custom-example/res/CustomCameraControl.qml | 487 +++++++++++++-------- custom-example/res/CustomFlyView.qml | 5 +- custom-example/res/Images/thermal-brightness.svg | 19 + custom-example/res/Images/thermal-palette.svg | 17 + custom-example/res/Images/thermal-pip.svg | 11 + custom-example/res/Images/thermal-standard.svg | 9 + custom-example/src/CustomPlugin.cc | 4 +- .../src/FirmwarePlugin/CustomCameraControl.cc | 40 +- .../src/FirmwarePlugin/CustomCameraControl.h | 28 +- 10 files changed, 376 insertions(+), 248 deletions(-) create mode 100644 custom-example/res/Images/thermal-brightness.svg create mode 100644 custom-example/res/Images/thermal-palette.svg create mode 100644 custom-example/res/Images/thermal-pip.svg create mode 100644 custom-example/res/Images/thermal-standard.svg diff --git a/custom-example/custom.qrc b/custom-example/custom.qrc index 8b2ffc7..ad84746 100644 --- a/custom-example/custom.qrc +++ b/custom-example/custom.qrc @@ -27,6 +27,10 @@ <file alias="horizontal_speed.svg">res/Images/horizontal_speed.svg</file> <file alias="microSD.svg">res/Images/microSD.svg</file> <file alias="odometer.svg">res/Images/odometer.svg</file> + <file alias="thermal-brightness.svg">res/images/thermal-brightness.svg</file> + <file alias="thermal-palette.svg">res/images/thermal-palette.svg</file> + <file alias="thermal-pip.svg">res/images/thermal-pip.svg</file> + <file alias="thermal-standard.svg">res/images/thermal-standard.svg</file> <file alias="vertical_speed.svg">res/Images/vertical_speed.svg</file> <file alias="void.png">res/Images/void.png</file> </qresource> diff --git a/custom-example/res/CustomCameraControl.qml b/custom-example/res/CustomCameraControl.qml index 7a0225d..aa767e9 100644 --- a/custom-example/res/CustomCameraControl.qml +++ b/custom-example/res/CustomCameraControl.qml @@ -30,11 +30,14 @@ import CustomQuickInterface 1.0 import Custom.Widgets 1.0 Item { - height: cameraRect.height - width: cameraRect.width + (ScreenTools.defaultFontPixelWidth * 2) + height: mainColumn.height + width: mainColumn.width + (ScreenTools.defaultFontPixelWidth * 2) visible: !QGroundControl.videoManager.fullScreen - readonly property string _commLostStr: qsTr("NO CAMERA") + readonly property string _commLostStr: qsTr("NO CAMERA") + readonly property real buttonSize: ScreenTools.defaultFontPixelWidth * 4 + readonly property real buttonRadius: ScreenTools.defaultFontPixelWidth * 0.5 + readonly property real iconRatio: 0.666 property real _spacers: ScreenTools.defaultFontPixelHeight property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 28 @@ -56,6 +59,8 @@ Item { property bool _recordingVideo: _cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING property bool _settingsEnabled: !_communicationLost && _camera && _camera.cameraMode !== QGCCameraControl.CAM_MODE_UNDEFINED && _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE && !_recordingVideo property bool _hasZoom: _camera && _camera.hasZoom + property Fact _evFact: _camera ? _camera.ev : null + property Fact _irPaletteFact: _camera ? _camera.irPalette : null Connections { target: QGroundControl.multiVehicleManager.activeVehicle @@ -70,234 +75,348 @@ Item { anchors.fill: parent } - Rectangle { - id: cameraRect - height: cameraCol.height - width: cameraCol.width + (ScreenTools.defaultFontPixelWidth * 4) - color: qgcPal.windowShade - radius: ScreenTools.defaultFontPixelWidth * 0.5 - Column { - id: cameraCol - spacing: _spacers - anchors.centerIn: parent - Item { - height: 1 - width: 1 - } - //----------------------------------------------------------------- - //-- Camera Name - QGCLabel { - text: activeVehicle ? (_camera && _camera.modelName !== "" ? _camera.modelName : _commLostStr) : _commLostStr - font.pointSize: ScreenTools.smallFontPointSize - anchors.horizontalCenter: parent.horizontalCenter + //------------------------------------------------------------------------- + //-- Main Column + Column { + id: mainColumn + spacing: ScreenTools.defaultFontPixelHeight + anchors.centerIn: parent + //--------------------------------------------------------------------- + //-- Quick Thermal Modes + Rectangle { + id: backgroundRect + width: buttonsRow.width + (ScreenTools.defaultFontPixelWidth * 4) + height: buttonsRow.height + (ScreenTools.defaultFontPixelHeight) + color: qgcPal.windowShade + radius: height * 0.5 + visible: _camera && _camera.modelName === "DSC-QX30" && QGroundControl.videoManager.hasThermal + anchors.horizontalCenter: parent.horizontalCenter + ButtonGroup { + id: buttonGroup + exclusive: true + buttons: buttonsRow.children } - //----------------------------------------------------------------- - //-- Camera Mode - Item { - width: modeCol.width - height: modeCol.height - anchors.horizontalCenter: parent.horizontalCenter - Column { - id: modeCol - spacing: _spacers * 0.5 + Row { + id: buttonsRow + spacing: ScreenTools.defaultFontPixelWidth * 0.25 + anchors.centerIn: parent + //-- Standard + QGCHoverButton { + width: buttonSize + height: width + checkable: true + radius: buttonRadius + onClicked: { + _camera.thermalMode = QGCCameraControl.THERMAL_OFF + //-- Restore EV to 0 + if(_evFact) { + _evFact.value = 6 + } + } QGCColoredImage { - height: ScreenTools.defaultFontPixelHeight * 1.25 - width: height - source: (_cameraModeUndefined || _cameraPhotoMode) ? "/custom/img/camera_photo.svg" : "/custom/img/camera_video.svg" - color: qgcPal.text - fillMode: Image.PreserveAspectFit + source: "/custom/img/thermal-standard.svg" + color: parent.checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + width: parent.width * iconRatio + height: width + anchors.centerIn: parent sourceSize.height: height - anchors.horizontalCenter: parent.horizontalCenter - } - QGCLabel { - text: _cameraVideoMode ? qsTr("Video") : qsTr("Photo") - font.pointSize: ScreenTools.smallFontPointSize - anchors.horizontalCenter: parent.horizontalCenter } } - MouseArea { - anchors.fill: parent - enabled: !_cameraModeUndefined && _camera && _camera.videoStatus !== QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING && _cameraPhotoIdle - onClicked: { - _camera.toggleMode() + //-- PIP + QGCHoverButton { + width: buttonSize + height: width + checkable: true + radius: buttonRadius + onClicked: _camera.thermalMode = QGCCameraControl.THERMAL_PIP + QGCColoredImage { + source: "/custom/img/thermal-pip.svg" + color: parent.checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + width: parent.width * iconRatio + height: width + anchors.centerIn: parent + sourceSize.height: height } } - } - //----------------------------------------------------------------- - //-- Shutter - Rectangle { - color: Qt.rgba(0,0,0,0) - width: height - height: ScreenTools.defaultFontPixelHeight * 4 - radius: width * 0.5 - border.color: qgcPal.buttonText - border.width: 2 - anchors.horizontalCenter: parent.horizontalCenter - Rectangle { - width: parent.width * 0.75 + // Visual with high brightness + QGCHoverButton { + width: buttonSize height: width - radius: width * 0.5 - color: _cameraModeUndefined ? qgcPal.colorGrey : ( _cameraVideoMode ? qgcPal.colorRed : qgcPal.text ) - visible: !pauseVideo.visible - anchors.centerIn: parent + checkable: true + radius: buttonRadius + onClicked: { + _camera.thermalMode = QGCCameraControl.THERMAL_OFF + //-- Set EV to +1.3 + if(_evFact) { + _evFact.value = 10 + } + } QGCColoredImage { - id: busyIndicator - height: parent.height * 0.75 - width: height - source: "/qmlimages/MapSync.svg" + source: "/custom/img/thermal-brightness.svg" + color: parent.checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + width: parent.width * iconRatio + height: width + anchors.centerIn: parent sourceSize.height: height - fillMode: Image.PreserveAspectFit - mipmap: true - smooth: true - color: qgcPal.windowShade - visible: { - if(_cameraPhotoMode && !_cameraPhotoIdle && !_cameraElapsedMode) { - return true + } + } + // Thermal with color-map + QGCHoverButton { + width: buttonSize + height: width + checkable: true + radius: buttonRadius + onClicked: { + if(_irPaletteFact) { + var entryIdx = _irPaletteFact.enumStrings.find("Rainbow") + if(entryIdx !== undefined) { + _irPaletteFact.value = entryIdx; } - return false + _camera.thermalMode = QGCCameraControl.THERMAL_FULL } + } + QGCColoredImage { + source: "/custom/img/thermal-palette.svg" + color: parent.checked ? qgcPal.buttonHighlightText : qgcPal.buttonText + width: parent.width * iconRatio + height: width anchors.centerIn: parent - RotationAnimation on rotation { - loops: Animation.Infinite - from: 360 - to: 0 - duration: 740 - running: busyIndicator.visible + sourceSize.height: height + } + } + } + } + //--------------------------------------------------------------------- + //-- Main Camera Control + Rectangle { + id: cameraRect + height: cameraCol.height + width: cameraCol.width + (ScreenTools.defaultFontPixelWidth * 4) + color: qgcPal.windowShade + radius: ScreenTools.defaultFontPixelWidth * 0.5 + anchors.horizontalCenter: parent.horizontalCenter + Column { + id: cameraCol + spacing: _spacers + anchors.centerIn: parent + Item { + height: 1 + width: 1 + } + //----------------------------------------------------------------- + //-- Camera Name + QGCLabel { + text: activeVehicle ? (_camera && _camera.modelName !== "" ? _camera.modelName : _commLostStr) : _commLostStr + font.pointSize: ScreenTools.smallFontPointSize + anchors.horizontalCenter: parent.horizontalCenter + } + //----------------------------------------------------------------- + //-- Camera Mode + Item { + width: modeCol.width + height: modeCol.height + anchors.horizontalCenter: parent.horizontalCenter + Column { + id: modeCol + spacing: _spacers * 0.5 + QGCColoredImage { + height: ScreenTools.defaultFontPixelHeight * 1.25 + width: height + source: (_cameraModeUndefined || _cameraPhotoMode) ? "/custom/img/camera_photo.svg" : "/custom/img/camera_video.svg" + color: qgcPal.text + fillMode: Image.PreserveAspectFit + sourceSize.height: height + anchors.horizontalCenter: parent.horizontalCenter + } + QGCLabel { + text: _cameraVideoMode ? qsTr("Video") : qsTr("Photo") + font.pointSize: ScreenTools.smallFontPointSize + anchors.horizontalCenter: parent.horizontalCenter } } - QGCLabel { - text: _camera ? _camera.photoLapse.toFixed(0) + 's' : qsTr('N/A') - font.family: ScreenTools.demiboldFontFamily - color: qgcPal.colorBlue - visible: _cameraElapsedMode - anchors.centerIn: parent + MouseArea { + anchors.fill: parent + enabled: !_cameraModeUndefined && _camera && _camera.videoStatus !== QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING && _cameraPhotoIdle + onClicked: { + _camera.toggleMode() + } } } + //----------------------------------------------------------------- + //-- Shutter Rectangle { - id: pauseVideo - width: parent.width * 0.5 - height: width - color: _cameraModeUndefined ? qgcPal.colorGrey : qgcPal.colorRed - visible: { - if(_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) { - return true - } - if(_cameraPhotoMode) { - if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) { + color: Qt.rgba(0,0,0,0) + width: height + height: ScreenTools.defaultFontPixelHeight * 4 + radius: width * 0.5 + border.color: qgcPal.buttonText + border.width: 2 + anchors.horizontalCenter: parent.horizontalCenter + Rectangle { + width: parent.width * 0.75 + height: width + radius: width * 0.5 + color: _cameraModeUndefined ? qgcPal.colorGrey : ( _cameraVideoMode ? qgcPal.colorRed : qgcPal.text ) + visible: !pauseVideo.visible + anchors.centerIn: parent + QGCColoredImage { + id: busyIndicator + height: parent.height * 0.75 + width: height + source: "/qmlimages/MapSync.svg" + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + color: qgcPal.windowShade + visible: { + if(_cameraPhotoMode && !_cameraPhotoIdle && !_cameraElapsedMode) { + return true + } + return false + } + anchors.centerIn: parent + RotationAnimation on rotation { + loops: Animation.Infinite + from: 360 + to: 0 + duration: 740 + running: busyIndicator.visible + } + } + QGCLabel { + text: _camera ? _camera.photoLapse.toFixed(0) + 's' : qsTr('N/A') + font.family: ScreenTools.demiboldFontFamily + color: qgcPal.colorBlue + visible: _cameraElapsedMode + anchors.centerIn: parent + } + } + Rectangle { + id: pauseVideo + width: parent.width * 0.5 + height: width + color: _cameraModeUndefined ? qgcPal.colorGrey : qgcPal.colorRed + visible: { + if(_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) { return true } - } - return false + if(_cameraPhotoMode) { + if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) { + return true + } + } + return false + } + anchors.centerIn: parent } - anchors.centerIn: parent - } - MouseArea { - anchors.fill: parent - enabled: !_noSdCard - onClicked: { - if(_cameraVideoMode) { - if(_camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) { - _camera.stopVideo() - } else { - if(!_fullSD) { - _camera.startVideo() + MouseArea { + anchors.fill: parent + enabled: !_noSdCard + onClicked: { + if(_cameraVideoMode) { + if(_camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) { + _camera.stopVideo() + } else { + if(!_fullSD) { + _camera.startVideo() + } } - } - } else { - if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) { - _camera.stopTakePhoto() } else { - if(!_fullSD) { - _camera.takePhoto() + if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) { + _camera.stopTakePhoto() + } else { + if(!_fullSD) { + _camera.takePhoto() + } } } } } } - } - //----------------------------------------------------------------- - //-- Settings - Item { - width: settingsCol.width - height: settingsCol.height - anchors.horizontalCenter: parent.horizontalCenter - Column { - id: settingsCol - spacing: _spacers * 0.5 + //----------------------------------------------------------------- + //-- Settings + Item { + width: settingsCol.width + height: settingsCol.height anchors.horizontalCenter: parent.horizontalCenter + Column { + id: settingsCol + spacing: _spacers * 0.5 + anchors.horizontalCenter: parent.horizontalCenter + QGCColoredImage { + width: ScreenTools.defaultFontPixelHeight * 1.25 + height: width + sourceSize.width: width + source: "qrc:/custom/img/camera_settings.svg" + color: qgcPal.text + fillMode: Image.PreserveAspectFit + opacity: _settingsEnabled ? 1 : 0.5 + anchors.horizontalCenter: parent.horizontalCenter + } + QGCLabel { + text: qsTr("Settings") + font.pointSize: ScreenTools.smallFontPointSize + anchors.horizontalCenter: parent.horizontalCenter + } + } + MouseArea { + anchors.fill: parent + enabled: _settingsEnabled + onClicked: { + cameraSettings.open() + } + } + } + //----------------------------------------------------------------- + //-- microSD Card + Column { + spacing: _spacers * 0.5 + anchors.horizontalCenter: parent.horizontalCenter QGCColoredImage { width: ScreenTools.defaultFontPixelHeight * 1.25 height: width sourceSize.width: width - source: "qrc:/custom/img/camera_settings.svg" + source: "qrc:/custom/img/microSD.svg" color: qgcPal.text fillMode: Image.PreserveAspectFit opacity: _settingsEnabled ? 1 : 0.5 anchors.horizontalCenter: parent.horizontalCenter } QGCLabel { - text: qsTr("Settings") - font.pointSize: ScreenTools.smallFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - } - } - MouseArea { - anchors.fill: parent - enabled: _settingsEnabled - onClicked: { - cameraSettings.open() + text: { + if(_noSdCard) return qsTr("NONE") + if(_fullSD) return qsTr("FULL") + return _camera ? _camera.storageFreeStr : "" + } + color: (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text + font.pointSize: ScreenTools.smallFontPointSize + anchors.horizontalCenter: parent.horizontalCenter } } - } - //----------------------------------------------------------------- - //-- microSD Card - Column { - spacing: _spacers * 0.5 - anchors.horizontalCenter: parent.horizontalCenter - QGCColoredImage { - width: ScreenTools.defaultFontPixelHeight * 1.25 - height: width - sourceSize.width: width - source: "qrc:/custom/img/microSD.svg" - color: qgcPal.text - fillMode: Image.PreserveAspectFit - opacity: _settingsEnabled ? 1 : 0.5 - anchors.horizontalCenter: parent.horizontalCenter + /* + //----------------------------------------------------------------- + //-- Recording Time / Images Captured + CustomLabel { + text: (_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00" + visible: _cameraVideoMode + pointSize: ScreenTools.smallFontPointSize + anchors.horizontalCenter: parent.horizontalCenter } - QGCLabel { - text: { - if(_noSdCard) return qsTr("NONE") - if(_fullSD) return qsTr("FULL") - return _camera ? _camera.storageFreeStr : "" - } - color: (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text - font.pointSize: ScreenTools.smallFontPointSize + CustomLabel { + text: activeVehicle && _cameraPhotoMode ? ('00000' + activeVehicle.cameraTriggerPoints.count).slice(-5) : "00000" + visible: _cameraPhotoMode + pointSize: ScreenTools.smallFontPointSize anchors.horizontalCenter: parent.horizontalCenter } - } - /* - //----------------------------------------------------------------- - //-- Recording Time / Images Captured - CustomLabel { - text: (_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00" - visible: _cameraVideoMode - pointSize: ScreenTools.smallFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - } - CustomLabel { - text: activeVehicle && _cameraPhotoMode ? ('00000' + activeVehicle.cameraTriggerPoints.count).slice(-5) : "00000" - visible: _cameraPhotoMode - pointSize: ScreenTools.smallFontPointSize - anchors.horizontalCenter: parent.horizontalCenter - } - */ - Item { - height: 1 - width: 1 + */ + Item { + height: 1 + width: 1 + } } } } - //------------------------------------------------------------------------- //-- Camera Settings Popup { diff --git a/custom-example/res/CustomFlyView.qml b/custom-example/res/CustomFlyView.qml index 08d1155..548aafd 100644 --- a/custom-example/res/CustomFlyView.qml +++ b/custom-example/res/CustomFlyView.qml @@ -512,10 +512,9 @@ Item { Item { id: gimbalControl visible: camControlLoader.visible && CustomQuickInterface.showGimbalControl - anchors.top: camControlLoader.bottom - anchors.topMargin: height * -0.5 + anchors.bottom: camControlLoader.bottom anchors.right: camControlLoader.left - anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2 + anchors.rightMargin: ScreenTools.defaultFontPixelWidth * (QGroundControl.videoManager.hasThermal ? -4 : 2) height: parent.width * 0.125 width: height property real curPitch: 0 diff --git a/custom-example/res/Images/thermal-brightness.svg b/custom-example/res/Images/thermal-brightness.svg new file mode 100644 index 0000000..7319222 --- /dev/null +++ b/custom-example/res/Images/thermal-brightness.svg @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#FFFFFF;} +</style> +<g> + <path class="st0" d="M53.3,245.5c-3.1,3.1-7.7,3.1-10.8,0c-3.1-3.1-3.1-7.7,0-10.8l17-17C44,200,34,176.8,32.4,151.3H7.7 + c-4.6,0-7.7-3.1-7.7-7.7c0-3.9,3.1-7.7,7.7-7.7h24.7C34,111.2,44,88,59.5,70.3l-17-17c-3.1-3.1-3.1-7.7,0-10.8 + c3.1-3.1,7.7-3.1,10.8,0l17,17C88,44,111.2,34,135.9,32.4V7.7c0-4.6,3.9-7.7,7.7-7.7c4.6,0,7.7,3.1,7.7,7.7v24.7 + c25.5,1.5,48.6,11.6,66.4,27l17-17c3.1-3.1,7.7-3.1,10.8,0c3.1,3.1,3.1,7.7,0,10.8l-17,17c15.4,17.8,25.5,40.9,27,65.6h24.7 + c3.9,0,7.7,3.9,7.7,7.7c0,4.6-3.9,7.7-7.7,7.7h-24.7c-1.5,25.5-11.6,48.6-27,66.4l17,17c3.1,3.1,3.1,7.7,0,10.8 + c-3.1,3.1-7.7,3.1-10.8,0l-17-17c-17.8,15.4-40.9,25.5-66.4,27v24.7c0,3.9-3.1,7.7-7.7,7.7c-3.9,0-7.7-3.9-7.7-7.7v-24.7 + c-24.7-1.5-47.9-11.6-65.6-27L53.3,245.5z M143.6,47.9c-53.3,0-96.5,42.5-96.5,95.7c0,54,43.2,96.5,96.5,96.5 + c54,0,96.5-42.5,96.5-96.5C240.1,90.3,197.7,47.9,143.6,47.9z"/> + <circle class="st0" cx="144" cy="144" r="72"/> +</g> +</svg> diff --git a/custom-example/res/Images/thermal-palette.svg b/custom-example/res/Images/thermal-palette.svg new file mode 100644 index 0000000..8615431 --- /dev/null +++ b/custom-example/res/Images/thermal-palette.svg @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#FFFFFF;} +</style> +<path class="st0" d="M79.2,0h-72C5.3,0,3.5,0.8,2.1,2.1C0.8,3.5,0,5.3,0,7.2v273.6c0,1.9,0.8,3.8,2.1,5.1c1.4,1.4,3.2,2.1,5.1,2.1 + h72c1.9,0,3.7-0.8,5.1-2.1c1.4-1.3,2.1-3.2,2.1-5.1V7.2c0-1.9-0.8-3.8-2.1-5.1C82.9,0.8,81.1,0,79.2,0z M43.2,259.2 + c-5.8,0-11.1-3.5-13.3-8.9c-2.2-5.4-1-11.6,3.1-15.7c4.1-4.1,10.3-5.3,15.7-3.1c5.4,2.2,8.9,7.5,8.9,13.3 + C57.6,252.7,51.2,259.2,43.2,259.2L43.2,259.2z"/> +<path class="st0" d="M280.8,201.6h-63l-117,67.6V288h180c1.9,0,3.8-0.8,5.1-2.1c1.4-1.4,2.1-3.2,2.1-5.1v-72c0-1.9-0.8-3.7-2.1-5.1 + C284.5,202.4,282.7,201.6,280.8,201.6L280.8,201.6z"/> +<path class="st0" d="M130.3,235.5L278,150.2c3.4-2,4.6-6.4,2.6-9.8l-36-62.4v0c-2-3.4-6.4-4.6-9.8-2.6l-18.1,10.4L130.3,235.5z"/> +<path class="st0" d="M219.6,37.6l-62.4-36c-3.4-2-7.8-0.8-9.8,2.6L100.8,85v172.8L222.2,47.5c1-1.6,1.2-3.6,0.7-5.5 + C222.5,40.1,221.3,38.6,219.6,37.6L219.6,37.6z"/> +</svg> diff --git a/custom-example/res/Images/thermal-pip.svg b/custom-example/res/Images/thermal-pip.svg new file mode 100644 index 0000000..22518b1 --- /dev/null +++ b/custom-example/res/Images/thermal-pip.svg @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:none;stroke:#FFFFFF;stroke-width:8;} + .st1{fill:#FFFFFF;stroke:#FFFFFF;} +</style> +<rect x="3.6" y="40.7" class="st0" width="280.8" height="206.6"/> +<rect x="122.3" y="144.5" class="st1" width="162.1" height="102.8"/> +</svg> diff --git a/custom-example/res/Images/thermal-standard.svg b/custom-example/res/Images/thermal-standard.svg new file mode 100644 index 0000000..b5ecc3c --- /dev/null +++ b/custom-example/res/Images/thermal-standard.svg @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:none;stroke:#FFFFFF;stroke-width:8;} +</style> +<rect x="3.6" y="40.7" class="st0" width="280.8" height="206.6"/> +</svg> diff --git a/custom-example/src/CustomPlugin.cc b/custom-example/src/CustomPlugin.cc index d09e09f..748cdbd 100644 --- a/custom-example/src/CustomPlugin.cc +++ b/custom-example/src/CustomPlugin.cc @@ -395,8 +395,8 @@ CustomPlugin::paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo[QGCPalette::Light][QGCPalette::ColorGroupDisabled] = QColor("#585858"); } else if (colorName == QStringLiteral("hoverColor")) { - colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupEnabled] = QColor("#E7D8AE"); - colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupDisabled] = QColor("#E7D8AE"); + colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupEnabled] = QColor("#746D59"); + colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupDisabled] = QColor("#746D59"); colorInfo[QGCPalette::Light][QGCPalette::ColorGroupEnabled] = QColor("#464f5a"); colorInfo[QGCPalette::Light][QGCPalette::ColorGroupDisabled] = QColor("#464f5a"); } diff --git a/custom-example/src/FirmwarePlugin/CustomCameraControl.cc b/custom-example/src/FirmwarePlugin/CustomCameraControl.cc index ff67b4d..cbb7422 100644 --- a/custom-example/src/FirmwarePlugin/CustomCameraControl.cc +++ b/custom-example/src/FirmwarePlugin/CustomCameraControl.cc @@ -17,11 +17,12 @@ QGC_LOGGING_CATEGORY(CustomCameraLog, "CustomCameraLog") QGC_LOGGING_CATEGORY(CustomCameraVerboseLog, "CustomCameraVerboseLog") +static const char* kCAM_IRPALETTE = "CAM_IRPALETTE"; + //----------------------------------------------------------------------------- CustomCameraControl::CustomCameraControl(const mavlink_camera_information_t *info, Vehicle* vehicle, int compID, QObject* parent) : QGCCameraControl(info, vehicle, compID, parent) { - connect(_vehicle, &Vehicle::mavlinkMessageReceived, this, &CustomCameraControl::_mavlinkMessageReceived); } //----------------------------------------------------------------------------- @@ -94,42 +95,15 @@ CustomCameraControl::_setVideoStatus(VideoStatus status) //----------------------------------------------------------------------------- void -CustomCameraControl::_mavlinkMessageReceived(const mavlink_message_t& message) +CustomCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap) { - switch (message.msgid) { - case MAVLINK_MSG_ID_MOUNT_ORIENTATION: - _handleGimbalOrientation(message); - break; - } + QGCCameraControl::handleCaptureStatus(cap); } //----------------------------------------------------------------------------- -void -CustomCameraControl::_handleGimbalOrientation(const mavlink_message_t& message) +Fact* +CustomCameraControl::irPalette() { - mavlink_mount_orientation_t o; - mavlink_msg_mount_orientation_decode(&message, &o); - if(fabsf(_gimbalRoll - o.roll) > 0.5f) { - _gimbalRoll = o.roll; - emit gimbalRollChanged(); - } - if(fabsf(_gimbalPitch - o.pitch) > 0.5f) { - _gimbalPitch = o.pitch; - emit gimbalPitchChanged(); - } - if(fabsf(_gimbalYaw - o.yaw) > 0.5f) { - _gimbalYaw = o.yaw; - emit gimbalYawChanged(); - } - if(!_gimbalData) { - _gimbalData = true; - emit gimbalDataChanged(); - } + return (_paramComplete && _activeSettings.contains(kCAM_IRPALETTE)) ? getFact(kCAM_IRPALETTE) : nullptr; } -//----------------------------------------------------------------------------- -void -CustomCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap) -{ - QGCCameraControl::handleCaptureStatus(cap); -} diff --git a/custom-example/src/FirmwarePlugin/CustomCameraControl.h b/custom-example/src/FirmwarePlugin/CustomCameraControl.h index b159c66..42ead7c 100644 --- a/custom-example/src/FirmwarePlugin/CustomCameraControl.h +++ b/custom-example/src/FirmwarePlugin/CustomCameraControl.h @@ -28,11 +28,9 @@ class CustomCameraControl : public QGCCameraControl public: CustomCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr); - Q_PROPERTY(qreal gimbalRoll READ gimbalRoll NOTIFY gimbalRollChanged) - Q_PROPERTY(qreal gimbalPitch READ gimbalPitch NOTIFY gimbalPitchChanged) - Q_PROPERTY(qreal gimbalYaw READ gimbalYaw NOTIFY gimbalYawChanged) - Q_PROPERTY(bool gimbalData READ gimbalData NOTIFY gimbalDataChanged) + Q_PROPERTY(Fact* irPalette READ irPalette NOTIFY parametersReady) + Fact* irPalette (); bool takePhoto () override; bool stopTakePhoto () override; bool startVideo () override; @@ -41,29 +39,7 @@ public: void setPhotoMode () override; void handleCaptureStatus (const mavlink_camera_capture_status_t& capStatus) override; - qreal gimbalRoll () { return static_cast<qreal>(_gimbalRoll);} - qreal gimbalPitch () { return static_cast<qreal>(_gimbalPitch); } - qreal gimbalYaw () { return static_cast<qreal>(_gimbalYaw); } - bool gimbalData () { return _gimbalData; } - -private slots: - void _mavlinkMessageReceived (const mavlink_message_t& message); - -signals: - void gimbalRollChanged (); - void gimbalPitchChanged (); - void gimbalYawChanged (); - void gimbalDataChanged (); - protected: void _setVideoStatus (VideoStatus status) override; -private: - void _handleGimbalOrientation(const mavlink_message_t& message); - -private: - float _gimbalRoll = 0.0; - float _gimbalPitch = 0.0; - float _gimbalYaw = 0.0; - bool _gimbalData = false; };