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.windowTransparentText
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.windowTransparentText
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.windowTransparentText
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.windowTransparentText
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.windowTransparentText
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 LabelledFactComboBox {
242 label: qsTr("Control type")
243 fact: _gimbalControllerSettings.ControlType
244 visible: enableOnScreenControlCheckbox.checked
245 }
246
247 LabelledFactTextField {
248 label: qsTr("Horizontal FOV")
249 fact: _gimbalControllerSettings.CameraHFov
250 visible: enableOnScreenControlCheckbox.checked && _gimbalControllerSettings.ControlType.rawValue === 0
251 }
252
253 LabelledFactTextField {
254 label: qsTr("Vertical FOV")
255 fact: _gimbalControllerSettings.CameraVFov
256 visible: enableOnScreenControlCheckbox.checked && _gimbalControllerSettings.ControlType.rawValue === 0
257 }
258
259 LabelledFactTextField {
260 label: qsTr("Max speed")
261 fact: _gimbalControllerSettings.CameraSlideSpeed
262 visible: enableOnScreenControlCheckbox.checked && _gimbalControllerSettings.ControlType.rawValue === 1
263 }
264 }
265
266 SettingsGroupLayout {
267 heading: qsTr("Zoom speed")
268 showDividers: false
269
270 LabelledFactTextField {
271 label: qsTr("Max speed (min zoom)")
272 fact: _gimbalControllerSettings.zoomMaxSpeed
273 }
274
275 LabelledFactTextField {
276 label: qsTr("Min speed (max zoom)")
277 fact: _gimbalControllerSettings.zoomMinSpeed
278 }
279
280 }
281
282 SettingsGroupLayout {
283 LabelledFactTextField {
284 label: qsTr("Joystick buttons speed:")
285 fact: _gimbalControllerSettings.joystickButtonsSpeed
286 enabled: joystickButtonsAvailable && _gimbalControllerSettings.visible
287 }
288
289 FactCheckBoxSlider {
290 Layout.fillWidth: true
291 text: qsTr("Show gimbal Azimuth indicator in map")
292 fact: _gimbalControllerSettings.showAzimuthIndicatorOnMap
293 }
294
295 FactCheckBoxSlider {
296 Layout.fillWidth: true
297 text: qsTr("Use Azimuth instead of local yaw on top toolbar indicator")
298 fact: _gimbalControllerSettings.toolbarIndicatorShowAzimuth
299 }
300
301 FactCheckBoxSlider {
302 Layout.fillWidth: true
303 text: qsTr("Show Acquire/Release control button")
304 fact: _gimbalControllerSettings.toolbarIndicatorShowAcquireReleaseControl
305 }
306 }
307 }
308 }
309
310 Connections {
311 id: acquirePopupConnection
312 property bool isPopupOpen: false
313 target: gimbalController
314 function onShowAcquireGimbalControlPopup() {
315 if(!acquirePopupConnection.isPopupOpen){
316 acquirePopupConnection.isPopupOpen = true;
317 QGroundControl.showMessageDialog(
318 control,
319 "Request Gimbal Control?",
320 "Command not sent. Another user has control of the gimbal.",
321 Dialog.Yes | Dialog.No,
322 gimbalController.acquireGimbalControl,
323 function() { acquirePopupConnection.isPopupOpen = false }
324 )
325 }
326 }
327 }
328}