QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
GimbalIndicator.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Layouts
4
5import QGroundControl
6import QGroundControl.Controls
7import QGroundControl.FactControls
8
9Item {
10 id: control
11 objectName: "toolbar_gimbalIndicator"
12 anchors.top: parent.top
13 anchors.bottom: parent.bottom
14 width: gimbalIndicatorRow.width
15
16 property bool showIndicator: gimbalController.gimbals.count
17
18 property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
19 property var gimbalController: activeVehicle.gimbalController
20 property var gimbals: gimbalController.gimbals
21 property var activeGimbal: gimbalController.activeGimbal
22 property var multiGimbalSetup: gimbalController.gimbals.count > 1
23 property bool joystickButtonsAvailable: activeVehicle ? joystickManager.activeJoystickEnabledForActiveVehicle : false
24 property bool showAzimuth: QGroundControl.settingsManager.gimbalControllerSettings.toolbarIndicatorShowAzimuth.rawValue
25
26 property var margins: ScreenTools.defaultFontPixelWidth
27 property var panelRadius: ScreenTools.defaultFontPixelWidth * 0.5
28 property var buttonHeight: height * 1.6
29 property var squareButtonPadding: ScreenTools.defaultFontPixelWidth
30 property var separatorHeight: buttonHeight * 0.9
31 property var settingsPanelVisible: false
32
33 property var _gimbalControllerSettings: QGroundControl.settingsManager.gimbalControllerSettings
34
35 QGCPalette { id: qgcPal }
36
37 Row {
38 id: gimbalIndicatorRow
39 anchors.top: parent.top
40 anchors.bottom: parent.bottom
41 spacing: ScreenTools.defaultFontPixelWidth / 2
42
43 Column {
44 anchors.top: parent.top
45 anchors.bottom: parent.bottom
46 spacing: 0
47
48 QGCColoredImage {
49 id: gimbalIndicatorIcon
50 anchors.horizontalCenter: parent.horizontalCenter
51 width: height
52 height: multiGimbalSetup ? parent.height - gimbalIdLabel.contentHeight : parent.height
53 source: "/res/CameraGimbal.png"
54 fillMode: Image.PreserveAspectFit
55 sourceSize.height: height
56 color: qgcPal.text
57
58 }
59
60 QGCLabel {
61 id: gimbalIdLabel
62 anchors.horizontalCenter: parent.horizontalCenter
63 font.pointSize: ScreenTools.smallFontPointSize
64 text: activeGimbal ? activeGimbal.deviceId.rawValue : ""
65 color: qgcPal.text
66 visible: multiGimbalSetup
67 }
68 }
69
70 // Telemetry and status indicator
71 GridLayout {
72 anchors.verticalCenter: parent.verticalCenter
73 columns: 2
74 rows: 2
75 rowSpacing: 0
76 columnSpacing: margins / 2
77
78 QGCLabel {
79 id: statusLabel
80 font.pointSize: ScreenTools.smallFontPointSize
81 text: activeGimbal && activeGimbal.retracted ?
82 qsTr("Retracted") :
83 (activeGimbal && activeGimbal.yawLock ? qsTr("Yaw locked") : qsTr("Yaw follow"))
84 color: qgcPal.text
85 Layout.columnSpan: 2
86 Layout.alignment: Qt.AlignHCenter
87 }
88 QGCLabel {
89 id: pitchLabel
90 font.pointSize: ScreenTools.smallFontPointSize
91 text: activeGimbal ? qsTr("P: ") + activeGimbal.absolutePitch.valueString : ""
92 color: qgcPal.text
93 }
94 QGCLabel {
95 id: panLabel
96 font.pointSize: ScreenTools.smallFontPointSize
97 text: activeGimbal ?
98 (showAzimuth ?
99 (qsTr("Az: ") + activeGimbal.absoluteYaw.valueString) :
100 (qsTr("Y: ") + activeGimbal.bodyYaw.valueString)) :
101 ""
102 color: qgcPal.text
103 }
104 }
105 }
106
107 MouseArea {
108 anchors.fill: parent
109 onClicked: mainWindow.showIndicatorDrawer(gimbalPopup, control)
110 }
111
112 Component {
113 id: gimbalPopup
114
115 ToolIndicatorPage {
116 showExpand: true
117 waitForParameters: false
118 contentComponent: gimbalContentComponent
119 expandedComponent: gimbalExpandedComponent
120 }
121 }
122
123 Component {
124 id: gimbalContentComponent
125
126 ColumnLayout {
127 spacing: ScreenTools.defaultFontPixelWidth / 2
128
129 SettingsGroupLayout {
130 heading: qsTr("Active Gimbal")
131 visible: multiGimbalSetup
132
133 QGCComboBox {
134 id: gimbalSelectorCombo
135 Layout.fillWidth: true
136 visible: multiGimbalSetup
137 onCurrentIndexChanged: gimbalController.activeGimbal = gimbalController.gimbals.get(currentIndex)
138
139 function _updateComboModel() {
140 let gimbalModel = []
141 let activeIndex = -1
142 for (var i = 0; i < gimbals.count; i++) {
143 var gimbal = gimbals.get(i)
144 gimbalModel.push(qsTr("Gimbal %1").arg(gimbal.deviceId.valueString))
145 if (gimbal === activeGimbal) {
146 activeIndex = i
147 }
148 }
149 gimbalSelectorCombo.model = gimbalModel
150 gimbalSelectorCombo.currentIndex = activeIndex
151 }
152
153 Component.onCompleted: _updateComboModel()
154 Connections {
155 target: gimbals
156 function onCountChanged(count) { _updateComboModel() }
157 }
158 }
159 }
160
161 SettingsGroupLayout {
162 heading: qsTr("Commands")
163 showDividers: false
164
165 QGCButton {
166 Layout.fillWidth: true
167 text: activeGimbal.yawLock ? qsTr("Yaw Follow") : qsTr("Yaw Lock")
168 visible: activeGimbal.supportsYawLock
169 onClicked: {
170 gimbalController.setGimbalYawLock(!activeGimbal.yawLock)
171 mainWindow.closeIndicatorDrawer()
172 }
173 }
174
175 QGCButton {
176 Layout.fillWidth: true
177 text: qsTr("Center")
178 onClicked: {
179 gimbalController.centerGimbal()
180 mainWindow.closeIndicatorDrawer()
181 }
182 }
183
184 QGCButton {
185 Layout.fillWidth: true
186 text: qsTr("Tilt 90")
187 onClicked: {
188 gimbalController.sendPitchBodyYaw(-90, 0)
189 mainWindow.closeIndicatorDrawer()
190 }
191 }
192
193 QGCButton {
194 Layout.fillWidth: true
195 text: qsTr("Point Home")
196 onClicked: {
197 activeVehicle.guidedModeROI(activeVehicle.homePosition)
198 mainWindow.closeIndicatorDrawer()
199 }
200 }
201
202 QGCButton {
203 Layout.fillWidth: true
204 text: qsTr("Retract")
205 visible: activeGimbal.supportsRetract
206 onClicked: {
207 gimbalController.setGimbalRetract(true)
208 mainWindow.closeIndicatorDrawer()
209 }
210 }
211
212 QGCButton {
213 Layout.fillWidth: true
214 text: activeGimbal.gimbalHaveControl ? qsTr("Release Control") : qsTr("Acquire Control")
215 visible: _gimbalControllerSettings.toolbarIndicatorShowAcquireReleaseControl.rawValue
216 onClicked: {
217 activeGimbal.gimbalHaveControl ? gimbalController.releaseGimbalControl() : gimbalController.acquireGimbalControl()
218 mainWindow.closeIndicatorDrawer()
219 }
220 }
221 }
222 }
223 }
224
225 Component {
226 id: gimbalExpandedComponent
227
228 ColumnLayout {
229 spacing: ScreenTools.defaultFontPixelWidth / 2
230
231 SettingsGroupLayout {
232 heading: qsTr("On-Screen Control")
233 showDividers: false
234
235 FactCheckBoxSlider {
236 id: enableOnScreenControlCheckbox
237 Layout.fillWidth: true
238 text: qsTr("Enabled")
239 fact: _gimbalControllerSettings.enableOnScreenControl
240 }
241
242 FactCheckBoxSlider {
243 Layout.fillWidth: true
244 text: qsTr("Click and drag")
245 fact: _gimbalControllerSettings.clickAndDrag
246 visible: enableOnScreenControlCheckbox.checked
247 }
248
249 LabelledFactTextField {
250 label: qsTr("Horizontal FOV")
251 fact: _gimbalControllerSettings.cameraHFov
252 visible: enableOnScreenControlCheckbox.checked && !_gimbalControllerSettings.clickAndDrag.rawValue
253 }
254
255 LabelledFactTextField {
256 label: qsTr("Vertical FOV")
257 fact: _gimbalControllerSettings.cameraVFov
258 visible: enableOnScreenControlCheckbox.checked && !_gimbalControllerSettings.clickAndDrag.rawValue
259 }
260
261 LabelledFactTextField {
262 label: qsTr("Max speed")
263 fact: _gimbalControllerSettings.cameraSlideSpeed
264 visible: enableOnScreenControlCheckbox.checked && _gimbalControllerSettings.clickAndDrag.rawValue
265 }
266 }
267
268 SettingsGroupLayout {
269 heading: qsTr("Zoom speed")
270 showDividers: false
271
272 LabelledFactTextField {
273 label: qsTr("Max speed (min zoom)")
274 fact: _gimbalControllerSettings.zoomMaxSpeed
275 }
276
277 LabelledFactTextField {
278 label: qsTr("Min speed (max zoom)")
279 fact: _gimbalControllerSettings.zoomMinSpeed
280 }
281
282 }
283
284 SettingsGroupLayout {
285 LabelledFactTextField {
286 label: qsTr("Joystick buttons speed:")
287 fact: _gimbalControllerSettings.joystickButtonsSpeed
288 enabled: joystickButtonsAvailable && _gimbalControllerSettings.userVisible
289 }
290
291 FactCheckBoxSlider {
292 Layout.fillWidth: true
293 text: qsTr("Show gimbal Azimuth indicator in map")
294 fact: _gimbalControllerSettings.showAzimuthIndicatorOnMap
295 }
296
297 FactCheckBoxSlider {
298 Layout.fillWidth: true
299 text: qsTr("Use Azimuth instead of local yaw on top toolbar indicator")
300 fact: _gimbalControllerSettings.toolbarIndicatorShowAzimuth
301 }
302
303 FactCheckBoxSlider {
304 Layout.fillWidth: true
305 text: qsTr("Show Acquire/Release control button")
306 fact: _gimbalControllerSettings.toolbarIndicatorShowAcquireReleaseControl
307 }
308 }
309 }
310 }
311
312 Connections {
313 id: acquirePopupConnection
314 property bool isPopupOpen: false
315 target: gimbalController
316 function onShowAcquireGimbalControlPopup() {
317 if(!acquirePopupConnection.isPopupOpen){
318 acquirePopupConnection.isPopupOpen = true;
319 QGroundControl.showMessageDialog(
320 control,
321 "Request Gimbal Control?",
322 "Command not sent. Another user has control of the gimbal.",
323 Dialog.Yes | Dialog.No,
324 gimbalController.acquireGimbalControl,
325 function() { acquirePopupConnection.isPopupOpen = false }
326 )
327 }
328 }
329 }
330}