From 28ce0811c927bfcd8f96c79394f6ab2d225e5cd6 Mon Sep 17 00:00:00 2001 From: Gus Grubba Date: Sat, 27 Jul 2019 17:13:53 -0400 Subject: [PATCH] Custom gimbal control --- custom-example/res/CustomCameraControl.qml | 51 +++++++++++++++++++--- custom-example/res/CustomFlyView.qml | 38 +++++++++++++++- custom-example/src/CustomQuickInterface.cc | 22 +++++++++- custom-example/src/CustomQuickInterface.h | 10 ++++- src/FlightDisplay/VideoManager.cc | 2 + src/QmlControls/JoystickThumbPad.qml | 10 +++-- 6 files changed, 119 insertions(+), 14 deletions(-) diff --git a/custom-example/res/CustomCameraControl.qml b/custom-example/res/CustomCameraControl.qml index 0fa223559..7a0225d73 100644 --- a/custom-example/res/CustomCameraControl.qml +++ b/custom-example/res/CustomCameraControl.qml @@ -37,8 +37,9 @@ Item { readonly property string _commLostStr: qsTr("NO CAMERA") property real _spacers: ScreenTools.defaultFontPixelHeight - property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 28 - property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 28 + property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30 + property real _editFieldHeight: ScreenTools.defaultFontPixelHeight * 2 property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false @@ -364,6 +365,7 @@ Item { QGCComboBox { model: _isCamera ? _dynamicCameras.cameraLabels : [] width: _editFieldWidth + height: _editFieldHeight onActivated: _dynamicCameras.currentCamera = index currentIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0 } @@ -388,6 +390,7 @@ Item { QGCComboBox { model: _camera ? _camera.streamLabels : [] width: _editFieldWidth + height: _editFieldHeight onActivated: _camera.currentStream = index currentIndex: _camera ? _camera.currentStream : 0 } @@ -412,6 +415,7 @@ Item { } QGCComboBox { width: _editFieldWidth + height: _editFieldHeight model: parent.thermalModes currentIndex: _camera ? _camera.thermalMode : 0 onActivated: _camera.thermalMode = index @@ -436,6 +440,7 @@ Item { } Slider { width: _editFieldWidth + height: _editFieldHeight to: 100 from: 0 value: _camera ? _camera.thermalOpacity : 0 @@ -476,7 +481,8 @@ Item { anchors.verticalCenter: parent.verticalCenter } FactComboBox { - width: parent._isCombo ? _editFieldWidth : 0 + width: parent._isCombo ? _editFieldWidth : 0 + height: parent._isCombo ? _editFieldHeight : 0 fact: parent.parent._fact indexModel: false visible: parent._isCombo @@ -484,14 +490,16 @@ Item { } QGCButton { visible: parent._isEdit - width: parent._isEdit ? _editFieldWidth : 0 + width: parent._isEdit ? _editFieldWidth : 0 + height: parent._isEdit ? _editFieldHeight : 0 text: parent.parent._fact.valueString onClicked: { showEditFact(parent.parent._fact) } } QGCSlider { - width: parent._isSlider ? _editFieldWidth : 0 + width: parent._isSlider ? _editFieldWidth : 0 + height: parent._isSlider ? _editFieldHeight : 0 maximumValue: parent.parent._fact.max minimumValue: parent.parent._fact.min stepSize: parent.parent._fact.increment @@ -506,7 +514,8 @@ Item { } } CustomOnOffSwitch { - width: parent._isBool ? _editFieldWidth : 0 + width: parent._isBool ? _editFieldWidth : 0 + height: parent._isBool ? _editFieldHeight : 0 checked: parent.parent._fact ? parent.parent._fact.value : false onClicked: parent.parent._fact.value = checked ? 1 : 0 visible: parent._isBool @@ -535,6 +544,7 @@ Item { } QGCComboBox { width: _editFieldWidth + height: _editFieldHeight model: parent.photoModes currentIndex: _camera ? _camera.photoMode : 0 onActivated: _camera.photoMode = index @@ -559,6 +569,7 @@ Item { } QGCSlider { width: _editFieldWidth + height: _editFieldHeight maximumValue: 60 minimumValue: _camera ? (_camera.isE90 ? 3 : 5) : 5 stepSize: 1 @@ -579,6 +590,31 @@ Item { visible: _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE && !_noSdCard } //------------------------------------------- + //-- Gimbal Control + Row { + spacing: ScreenTools.defaultFontPixelWidth + visible: _camera && !_camera.isThermal + anchors.horizontalCenter: parent.horizontalCenter + QGCLabel { + text: qsTr("Show Gimbal Control") + width: _labelFieldWidth + anchors.verticalCenter: parent.verticalCenter + } + CustomOnOffSwitch { + checked: CustomQuickInterface.showGimbalControl + width: _editFieldWidth + height: _editFieldHeight + anchors.verticalCenter: parent.verticalCenter + onClicked: CustomQuickInterface.showGimbalControl = checked + } + } + Rectangle { + color: qgcPal.button + height: 1 + width: cameraSettingsCol.width + visible: _camera && !_camera.isThermal + } + //------------------------------------------- //-- Screen Grid Row { spacing: ScreenTools.defaultFontPixelWidth @@ -592,6 +628,7 @@ Item { CustomOnOffSwitch { checked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue width: _editFieldWidth + height: _editFieldHeight anchors.verticalCenter: parent.verticalCenter onClicked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue = checked } @@ -615,6 +652,7 @@ Item { } FactComboBox { width: _editFieldWidth + height: _editFieldHeight fact: QGroundControl.settingsManager.videoSettings.videoFit indexModel: false anchors.verticalCenter: parent.verticalCenter @@ -640,6 +678,7 @@ Item { text: qsTr("Reset") onClicked: resetPrompt.open() width: _editFieldWidth + height: _editFieldHeight enabled: !_recordingVideo anchors.verticalCenter: parent.verticalCenter MessageDialog { diff --git a/custom-example/res/CustomFlyView.qml b/custom-example/res/CustomFlyView.qml index 936159cd7..08d1155bb 100644 --- a/custom-example/res/CustomFlyView.qml +++ b/custom-example/res/CustomFlyView.qml @@ -60,7 +60,7 @@ Item { property real _distance: 0.0 property string _messageTitle: "" property string _messageText: "" - property bool _showAttitude: false + property bool _showAttitude: true function secondsToHHMMSS(timeS) { var sec_num = parseInt(timeS, 10); @@ -508,6 +508,42 @@ Item { } } + //-- Gimbal Control + Item { + id: gimbalControl + visible: camControlLoader.visible && CustomQuickInterface.showGimbalControl + anchors.top: camControlLoader.bottom + anchors.topMargin: height * -0.5 + anchors.right: camControlLoader.left + anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2 + height: parent.width * 0.125 + width: height + property real curPitch: 0 + property real curYaw: 0 + Timer { + interval: 100 //-- 10Hz + running: gimbalControl.visible && activeVehicle + repeat: true + onTriggered: { + if (activeVehicle) { + var p = Math.round(stick.yAxis * -90) + var y = Math.round(stick.xAxis * 180) + if(p !== gimbalControl.curPitch || y !== gimbalControl.curYaw) { + gimbalControl.curPitch = p + gimbalControl.curYaw = y + activeVehicle.gimbalControlValue(p, y) + } + } + } + } + JoystickThumbPad { + id: stick + anchors.fill: parent + lightColors: true + yAxisThrottleCentered: true + springYToCenter: false + } + } //-- Connection Lost While Armed Popup { id: connectionLostArmed diff --git a/custom-example/src/CustomQuickInterface.cc b/custom-example/src/CustomQuickInterface.cc index 1d1858310..790402d09 100644 --- a/custom-example/src/CustomQuickInterface.cc +++ b/custom-example/src/CustomQuickInterface.cc @@ -21,8 +21,10 @@ #include "CustomPlugin.h" #include "CustomQuickInterface.h" -#include -#include +#include + +static const char* kGroupName = "CustomSettings"; +static const char* kShowGimbalCtl = "ShowGimbalCtl"; //----------------------------------------------------------------------------- CustomQuickInterface::CustomQuickInterface(QObject* parent) @@ -41,4 +43,20 @@ CustomQuickInterface::~CustomQuickInterface() void CustomQuickInterface::init() { + QSettings settings; + settings.beginGroup(kGroupName); + _showGimbalControl = settings.value(kShowGimbalCtl, true).toBool(); +} + +//----------------------------------------------------------------------------- +void +CustomQuickInterface::setShowGimbalControl(bool set) +{ + if(_showGimbalControl != set) { + _showGimbalControl = set; + QSettings settings; + settings.beginGroup(kGroupName); + settings.setValue(kShowGimbalCtl,set); + emit showGimbalControlChanged(); + } } diff --git a/custom-example/src/CustomQuickInterface.h b/custom-example/src/CustomQuickInterface.h index 6c1d37cc5..9253fb8c2 100644 --- a/custom-example/src/CustomQuickInterface.h +++ b/custom-example/src/CustomQuickInterface.h @@ -28,5 +28,13 @@ class CustomQuickInterface : public QObject public: CustomQuickInterface(QObject* parent = nullptr); ~CustomQuickInterface(); - void init (); + Q_PROPERTY(bool showGimbalControl READ showGimbalControl WRITE setShowGimbalControl NOTIFY showGimbalControlChanged) + + bool showGimbalControl () { return _showGimbalControl; } + void setShowGimbalControl (bool set); + void init (); +signals: + void showGimbalControlChanged (); +private: + bool _showGimbalControl = true; }; diff --git a/src/FlightDisplay/VideoManager.cc b/src/FlightDisplay/VideoManager.cc index 1bacebb9d..bdb10e202 100644 --- a/src/FlightDisplay/VideoManager.cc +++ b/src/FlightDisplay/VideoManager.cc @@ -172,12 +172,14 @@ VideoManager::hasThermal() bool VideoManager::autoStreamConfigured() { +#if defined(QGC_GST_STREAMING) if(_activeVehicle && _activeVehicle->dynamicCameras()) { QGCVideoStreamInfo* pInfo = _activeVehicle->dynamicCameras()->currentStreamInstance(); if(pInfo) { return !pInfo->uri().isEmpty(); } } +#endif return false; } diff --git a/src/QmlControls/JoystickThumbPad.qml b/src/QmlControls/JoystickThumbPad.qml index 614595e76..589b5efc3 100644 --- a/src/QmlControls/JoystickThumbPad.qml +++ b/src/QmlControls/JoystickThumbPad.qml @@ -14,6 +14,7 @@ Item { property bool yAxisThrottleCentered: false ///< false: center yAxis in throttle for reverser and forward property real xPositionDelta: 0 ///< Amount to move the control on x axis property real yPositionDelta: 0 ///< Amount to move the control on y axis + property bool springYToCenter:true ///< true: Spring Y to center on release property real _centerXY: width / 2 property bool _processTouchPoints: false @@ -72,7 +73,6 @@ Item { } else { yPositionDelta = touchPoints[0].y - _centerXY } - // We need to wait until we move the control to the right position before we process touch points _processTouchPoints = true } @@ -199,8 +199,10 @@ Item { minimumTouchPoints: 1 maximumTouchPoints: 1 touchPoints: [ TouchPoint { id: touchPoint } ] - - onPressed: _joyRoot.thumbDown(touchPoints) - onReleased: _joyRoot.reCenter() + onPressed: _joyRoot.thumbDown(touchPoints) + onReleased: { + if(springYToCenter) + _joyRoot.reCenter() + } } } -- 2.22.0