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