QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
RemoteIDSettings.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.FactControls
8import QGroundControl.Controls
9
10SettingsPage {
11
12 // Visual properties
13 property real _margins: ScreenTools.defaultFontPixelWidth
14 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 28
15 property real _valueWidth: ScreenTools.defaultFontPixelWidth * 24
16 property real _columnSpacing: ScreenTools.defaultFontPixelHeight * 0.25
17 property real _comboFieldWidth: ScreenTools.defaultFontPixelWidth * 30
18 property real _valueFieldWidth: ScreenTools.defaultFontPixelWidth * 10
19 property int _borderWidth: 3
20 // Flags visual properties
21 property real flagsWidth: ScreenTools.defaultFontPixelWidth * 15
22 property real flagsHeight: ScreenTools.defaultFontPixelWidth * 7
23 property int radiusFlags: 5
24
25 // Flag to get active vehicle and active RID
26 property var _activeRID: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager : null
27
28 // Healthy connection with RID device
29 property bool commsGood: _activeVehicle && _activeVehicle.remoteIDManager ? _activeVehicle.remoteIDManager.commsGood : false
30
31 // General properties
32 property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
33 property var _offlineVehicle: QGroundControl.multiVehicleManager.offlineEditingVehicle
34 property int _regionOperation: QGroundControl.settingsManager.remoteIDSettings.region.value
35 property int _locationType: QGroundControl.settingsManager.remoteIDSettings.locationType.value
36 property int _classificationType: QGroundControl.settingsManager.remoteIDSettings.classificationType.value
37 property var _remoteIDManager: _activeVehicle ? _activeVehicle.remoteIDManager : null
38
39
40 property var remoteIDSettings:QGroundControl.settingsManager.remoteIDSettings
41 property Fact regionFact: remoteIDSettings.region
42 property Fact sendOperatorIdFact: remoteIDSettings.sendOperatorID
43 property Fact locationTypeFact: remoteIDSettings.locationType
44 property Fact operatorIDFact: remoteIDSettings.operatorID
45 property bool isEURegion: regionFact.rawValue === RemoteIDSettings.RegionOperation.EU
46 property bool isFAARegion: regionFact.rawValue === RemoteIDSettings.RegionOperation.FAA
47 property real textFieldWidth: ScreenTools.defaultFontPixelWidth * 24
48 property real textLabelWidth: ScreenTools.defaultFontPixelWidth * 30
49
50 // GPS properties
51 property var gcsPosition: QGroundControl.qgcPositionManger.gcsPosition
52 property real gcsHeading: QGroundControl.qgcPositionManger.gcsHeading
53 property real gcsHDOP: QGroundControl.qgcPositionManger.gcsPositionHorizontalAccuracy
54 property string gpsDisabled: "Disabled"
55 property string gpsUdpPort: "UDP Port"
56
57 QGCPalette { id: qgcPal }
58
59 // Function to get the corresponding Self ID label depending on the Self ID Type selected
60 function getSelfIdLabelText() {
61 switch (selfIDComboBox.currentIndex) {
62 case 0:
63 return QGroundControl.settingsManager.remoteIDSettings.selfIDFree.shortDescription
64 break
65 case 1:
66 return QGroundControl.settingsManager.remoteIDSettings.selfIDEmergency.shortDescription
67 break
68 case 2:
69 return QGroundControl.settingsManager.remoteIDSettings.selfIDExtended.shortDescription
70 break
71 default:
72 return QGroundControl.settingsManager.remoteIDSettings.selfIDFree.shortDescription
73 }
74 }
75
76 // Function to get the corresponding Self ID fact depending on the Self ID Type selected
77 function getSelfIDFact() {
78 switch (selfIDComboBox.currentIndex) {
79 case 0:
80 return QGroundControl.settingsManager.remoteIDSettings.selfIDFree
81 break
82 case 1:
83 return QGroundControl.settingsManager.remoteIDSettings.selfIDEmergency
84 break
85 case 2:
86 return QGroundControl.settingsManager.remoteIDSettings.selfIDExtended
87 break
88 default:
89 return QGroundControl.settingsManager.remoteIDSettings.selfIDFree
90 }
91 }
92
93
94 Item {
95 id: flagsItem
96 width: parent.width
97 height: flagsColumn.height
98 Layout.alignment: Qt.AlignHCenter
99
100 ColumnLayout {
101 id: flagsColumn
102 anchors.horizontalCenter: parent.horizontalCenter
103 spacing: _margins
104
105 // ---------------------------------------- STATUS -----------------------------------------
106 // Status flags. Visual representation for the state of all necesary information for remoteID
107 // to work propely.
108 Rectangle {
109 id: flagsRectangle
110 Layout.preferredHeight: statusGrid.height + (_margins * 2)
111 Layout.preferredWidth: statusGrid.width + (_margins * 2)
112 color: qgcPal.windowShade
113 visible: _activeVehicle
114 Layout.fillWidth: true
115
116 GridLayout {
117 id: statusGrid
118 anchors.margins: _margins
119 anchors.top: parent.top
120 anchors.horizontalCenter: parent.horizontalCenter
121 rows: 1
122 rowSpacing: _margins * 3
123 columnSpacing: _margins * 2
124
125 Rectangle {
126 id: armFlag
127 Layout.preferredHeight: flagsHeight
128 Layout.preferredWidth: flagsWidth
129 color: _activeRID ? (_remoteIDManager.armStatusGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey
130 radius: radiusFlags
131 visible: commsGood
132
133 QGCLabel {
134 anchors.fill: parent
135 text: qsTr("ARM STATUS")
136 wrapMode: Text.WordWrap
137 horizontalAlignment: Text.AlignHCenter
138 verticalAlignment: Text.AlignVCenter
139 font.bold: true
140 }
141 }
142
143 Rectangle {
144 id: commsFlag
145 Layout.preferredHeight: flagsHeight
146 Layout.preferredWidth: flagsWidth
147 color: _activeRID ? (_remoteIDManager.commsGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey
148 radius: radiusFlags
149
150 QGCLabel {
151 anchors.fill: parent
152 text: _activeRID && _remoteIDManager.commsGood ? qsTr("RID COMMS") : qsTr("NOT CONNECTED")
153 wrapMode: Text.WordWrap
154 horizontalAlignment: Text.AlignHCenter
155 verticalAlignment: Text.AlignVCenter
156 font.bold: true
157 }
158 }
159
160 Rectangle {
161 id: gpsFlag
162 Layout.preferredHeight: flagsHeight
163 Layout.preferredWidth: flagsWidth
164 color: _activeRID ? (_remoteIDManager.gcsGPSGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey
165 radius: radiusFlags
166 visible: commsGood
167
168 QGCLabel {
169 anchors.fill: parent
170 text: qsTr("GCS GPS")
171 wrapMode: Text.WordWrap
172 horizontalAlignment: Text.AlignHCenter
173 verticalAlignment: Text.AlignVCenter
174 font.bold: true
175 }
176 }
177
178 Rectangle {
179 id: basicIDFlag
180 Layout.preferredHeight: flagsHeight
181 Layout.preferredWidth: flagsWidth
182 color: _activeRID ? (_remoteIDManager.basicIDGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey
183 radius: radiusFlags
184 visible: commsGood
185
186 QGCLabel {
187 anchors.fill: parent
188 text: qsTr("BASIC ID")
189 wrapMode: Text.WordWrap
190 horizontalAlignment: Text.AlignHCenter
191 verticalAlignment: Text.AlignVCenter
192 font.bold: true
193 }
194 }
195
196 Rectangle {
197 id: operatorIDFlag
198 Layout.preferredHeight: flagsHeight
199 Layout.preferredWidth: flagsWidth
200 color: _activeRID ? (_remoteIDManager.operatorIDGood ? qgcPal.colorGreen : qgcPal.colorRed) : qgcPal.colorGrey
201 radius: radiusFlags
202 visible: commsGood && _activeRID ? (QGroundControl.settingsManager.remoteIDSettings.sendOperatorID.value || _regionOperation == RemoteIDSettings.RegionOperation.EU) : false
203
204 QGCLabel {
205 anchors.fill: parent
206 text: qsTr("OPERATOR ID")
207 wrapMode: Text.WordWrap
208 horizontalAlignment: Text.AlignHCenter
209 verticalAlignment: Text.AlignVCenter
210 font.bold: true
211 }
212 }
213 }
214 }
215 }
216 }
217
218 RowLayout {
219 spacing: ScreenTools.defaultFontPixelWidth
220
221 Connections {
222 target: regionFact
223 function onRawValueChanged(value) {
224 if (value === RemoteIDSettings.RegionOperation.EU) {
225 sendOperatorIdFact.rawValue = true
226 } else if (value === RemoteIDSettings.RegionOperation.FAA) {
227 locationTypeFact.value = RemoteIDSettings.LocationType.LIVE
228 }
229 }
230 }
231
232 ColumnLayout {
233 spacing: ScreenTools.defaultFontPixelHeight / 2
234 Layout.alignment: Qt.AlignTop
235
236 SettingsGroupLayout {
237 Layout.fillWidth: true
238
239 LabelledFactComboBox {
240 label: fact.shortDescription
241 fact: QGroundControl.settingsManager.remoteIDSettings.region
242 visible: QGroundControl.settingsManager.remoteIDSettings.region.visible
243 Layout.fillWidth: true
244 }
245 }
246 SettingsGroupLayout {
247 outerBorderColor: _activeRID ? (_remoteIDManager.armStatusGood ? defaultBorderColor : qgcPal.colorRed) : defaultBorderColor
248 visible: armStatusLabel.labelText !== ""
249 LabelledLabel {
250 id : armStatusLabel
251 label: qsTr("Arm Status Error")
252 labelText: _remoteIDManager?_remoteIDManager.armStatusError:"Vehicle Not Connected"
253 visible: labelText !== ""
254 Layout.fillWidth: true
255 }
256 }
257
258 SettingsGroupLayout {
259 heading: qsTr("Basic ID")
260 headingDescription: qsTr("If Basic ID is already set on the RID device, this will be registered as Basic ID 2")
261 Layout.fillWidth: true
262 Layout.preferredWidth: textLabelWidth
263 outerBorderColor: _activeRID ? (_remoteIDManager.basicIDGood ? defaultBorderColor : qgcPal.colorRed) : defaultBorderColor
264
265
266 FactCheckBoxSlider {
267 id: sendBasicIDSlider
268 text: qsTr("Broadcast")
269 fact: _fact
270 visible: _fact.visible
271 Layout.fillWidth: true
272
273 property Fact _fact: remoteIDSettings.sendBasicID
274 }
275
276 LabelledFactComboBox {
277 id: basicIDTypeCombo
278 label: _fact.shortDescription
279 fact: _fact
280 indexModel: false
281 visible: _fact.visible
282 enabled: sendBasicIDSlider._fact.rawValue
283 Layout.fillWidth: true
284
285 property Fact _fact: remoteIDSettings.basicIDType
286 }
287
288 LabelledFactComboBox {
289 label: _fact.shortDescription
290 fact: _fact
291 indexModel: false
292 visible: _fact.visible
293 enabled: sendBasicIDSlider._fact.rawValue
294 Layout.fillWidth: true
295
296 property Fact _fact: remoteIDSettings.basicIDUaType
297 }
298
299 LabelledFactTextField {
300 label: _fact.shortDescription
301 fact: _fact
302 visible: _fact.visible
303 enabled: sendBasicIDSlider._fact.rawValue
304 textField.maximumLength: 20
305 Layout.fillWidth: true
306 textFieldPreferredWidth: textFieldWidth
307
308 property Fact _fact: remoteIDSettings.basicID
309 }
310 }
311
312 SettingsGroupLayout {
313 heading: qsTr("Operator ID")
314 Layout.fillWidth: true
315
316 FactCheckBoxSlider {
317 text: qsTr("Broadcast%1").arg(isEURegion ? " (EU Required)" : "")
318 fact: sendOperatorIdFact
319 visible: sendOperatorIdFact.visible
320 enabled: isFAARegion
321 Layout.fillWidth: true
322
323 property Fact _fact: remoteIDSettings.sendOperatorID
324 }
325
326 LabelledFactComboBox {
327 id: regionOperationCombo
328 label: _fact.shortDescription
329 fact: _fact
330 indexModel: false
331 visible: _fact.visible && (_fact.enumValues.length > 1)
332 Layout.fillWidth: true
333
334 property Fact _fact: remoteIDSettings.operatorIDType
335 }
336
337 RowLayout {
338 spacing: ScreenTools.defaultFontPixelWidth * 2
339
340 QGCLabel {
341 Layout.fillWidth: true
342 text: operatorIDFact.shortDescription + (regionOperationCombo.visible ? "" : qsTr(" (%1)").arg(regionOperationCombo.comboBox.currentText))
343 }
344
345 QGCTextField {
346 id: operatorIDTextField
347 Layout.preferredWidth: textFieldWidth
348 Layout.fillWidth: true
349 text: operatorIDFact.valueString
350 visible: operatorIDFact.visible
351 maximumLength: 20 // Maximum defined by Mavlink definition of OPEN_DRONE_ID_OPERATOR_ID message
352
353 property bool operatorIDInvalid: ((_regionOperation === RemoteIDSettings.RegionOperation.EU || remoteIDSettings.sendOperatorID.value) &&
354 _activeRID && !_remoteIDManager.operatorIDGood)
355
356 onOperatorIDInvalidChanged: {
357 if (operatorIDInvalid) {
358 operatorIDTextField.showValidationError(qsTr("Invalid Operator ID"), operatorIDFact.valueString, false /* preventViewSwitch */)
359 } else {
360 operatorIDTextField.clearValidationError(false /* preventViewSwitch */)
361 }
362 }
363
364 onTextChanged: {
365 if (_activeVehicle) {
366 _remoteIDManager.checkOperatorID(text)
367 } else {
368 _offlineVehicle.remoteIDManager.checkOperatorID(text)
369 }
370 operatorIDFact.value = text
371 }
372
373 onEditingFinished: {
374 if (_activeVehicle) {
375 _remoteIDManager.setOperatorID()
376 } else {
377 _offlineVehicle.remoteIDManager.setOperatorID()
378 }
379 }
380 }
381 }
382 }
383
384 SettingsGroupLayout {
385 heading: qsTr("Self ID")
386 headingDescription: qsTr("If an emergency is declared, Emergency Text will be broadcast even if Broadcast setting is not enabled.")
387 Layout.fillWidth: true
388 Layout.preferredWidth: textLabelWidth
389
390 FactCheckBoxSlider {
391 id: sendSelfIDSlider
392 text: qsTr("Broadcast")
393 fact: _fact
394 visible: _fact.visible
395 Layout.fillWidth: true
396
397 property Fact _fact: remoteIDSettings.sendSelfID
398 }
399
400 LabelledFactComboBox {
401 id: selfIDTypeCombo
402 label: qsTr("Broadcast Message")
403 fact: _fact
404 indexModel: false
405 visible: _fact.visible
406 enabled: sendSelfIDSlider._fact.rawValue
407 Layout.fillWidth: true
408
409 property Fact _fact: remoteIDSettings.selfIDType
410 }
411
412 LabelledFactTextField {
413 label: _fact.shortDescription
414 fact: _fact
415 visible: _fact.visible
416 enabled: sendSelfIDSlider._fact.rawValue
417 textField.maximumLength: 23
418 Layout.fillWidth: true
419 textFieldPreferredWidth: textFieldWidth
420
421 property Fact _fact: remoteIDSettings.selfIDFree
422 }
423
424 LabelledFactTextField {
425 label: _fact.shortDescription
426 fact: _fact
427 visible: _fact.visible
428 enabled: sendSelfIDSlider._fact.rawValue
429 textField.maximumLength: 23
430 Layout.fillWidth: true
431 textFieldPreferredWidth: textFieldWidth
432
433 property Fact _fact: remoteIDSettings.selfIDExtended
434 }
435
436 LabelledFactTextField {
437 label: _fact.shortDescription
438 fact: _fact
439 visible: _fact.visible
440 textField.maximumLength: 23
441 Layout.fillWidth: true
442 textFieldPreferredWidth: textFieldWidth
443
444 property Fact _fact: remoteIDSettings.selfIDEmergency
445 }
446 }
447 }
448
449 ColumnLayout {
450 spacing: ScreenTools.defaultFontPixelHeight / 2
451 Layout.alignment: Qt.AlignTop
452 SettingsGroupLayout {
453 heading: qsTr("GroundStation Location")
454 Layout.fillWidth: true
455 outerBorderColor : _activeRID ? (_remoteIDManager.gcsGPSGood ? defaultBorderColor : qgcPal.colorRed) : defaultBorderColor
456 LabelledFactComboBox {
457 label: locationTypeFact.shortDescription
458 fact: locationTypeFact
459 indexModel: false
460 Layout.fillWidth: true
461 }
462
463 LabelledFactTextField {
464 label: _fact.shortDescription
465 fact: _fact
466 textField.maximumLength: 20
467 enabled: locationTypeFact.rawValue === RemoteIDSettings.LocationType.FIXED
468 Layout.fillWidth: true
469 textFieldPreferredWidth: textFieldWidth
470
471 property Fact _fact: remoteIDSettings.latitudeFixed
472 }
473
474 LabelledFactTextField {
475 label: _fact.shortDescription
476 fact: _fact
477 textField.maximumLength: 20
478 enabled: locationTypeFact.rawValue === RemoteIDSettings.LocationType.FIXED
479 Layout.fillWidth: true
480 textFieldPreferredWidth: textFieldWidth
481
482 property Fact _fact: remoteIDSettings.longitudeFixed
483 }
484
485 LabelledFactTextField {
486 label: _fact.shortDescription
487 fact: _fact
488 textField.maximumLength: 20
489 enabled: locationTypeFact.rawValue === RemoteIDSettings.LocationType.FIXED
490 Layout.fillWidth: true
491 textFieldPreferredWidth: textFieldWidth
492
493 property Fact _fact: remoteIDSettings.altitudeFixed
494 }
495
496 GridLayout {
497 id: gpsGrid
498 visible: !ScreenTools.isMobile
499 && QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.visible
500 && QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.visible
501 && _locationType !== RemoteIDSettings.LocationType.TAKEOFF
502 anchors.margins: _margins
503 rowSpacing: _margins * 3
504 columns: 2
505 columnSpacing: _margins * 2
506 Layout.alignment: Qt.AlignHCenter
507
508 QGCLabel {
509 text: qsTr("NMEA External GPS Device")
510 }
511 QGCComboBox {
512 id: nmeaPortCombo
513 Layout.preferredWidth: _comboFieldWidth
514
515 model: ListModel {
516 }
517
518 onActivated: (index) => {
519 if (index !== -1) {
520 QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.value = textAt(index);
521 }
522 }
523 Component.onCompleted: {
524 model.append({text: gpsDisabled})
525 model.append({text: gpsUdpPort})
526
527 for (var i in QGroundControl.linkManager.serialPorts) {
528 nmeaPortCombo.model.append({text:QGroundControl.linkManager.serialPorts[i]})
529 }
530 var index = nmeaPortCombo.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaPort.valueString);
531 nmeaPortCombo.currentIndex = index;
532 if (QGroundControl.linkManager.serialPorts.length === 0) {
533 nmeaPortCombo.model.append({text: "Serial <none available>"})
534 }
535 }
536 }
537
538 QGCLabel {
539 visible: nmeaPortCombo.currentText !== gpsUdpPort && nmeaPortCombo.currentText !== gpsDisabled
540 text: qsTr("NMEA GPS Baudrate")
541 }
542 QGCComboBox {
543 visible: nmeaPortCombo.currentText !== gpsUdpPort && nmeaPortCombo.currentText !== gpsDisabled
544 id: nmeaBaudCombo
545 Layout.preferredWidth: _comboFieldWidth
546 model: [1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600]
547
548 onActivated: (index) => {
549 if (index !== -1) {
550 QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.value = textAt(index);
551 }
552 }
553 Component.onCompleted: {
554 var index = nmeaBaudCombo.find(QGroundControl.settingsManager.autoConnectSettings.autoConnectNmeaBaud.valueString);
555 nmeaBaudCombo.currentIndex = index;
556 }
557 }
558
559 QGCLabel {
560 text: qsTr("NMEA stream UDP port")
561 visible: nmeaPortCombo.currentText === gpsUdpPort
562 }
563 FactTextField {
564 visible: nmeaPortCombo.currentText === gpsUdpPort
565 Layout.preferredWidth: _valueFieldWidth
566 fact: QGroundControl.settingsManager.autoConnectSettings.nmeaUdpPort
567 }
568 }
569 }
570
571
572 SettingsGroupLayout {
573 heading: qsTr("EU Vehicle Info")
574 visible: isEURegion
575 Layout.fillWidth: true
576
577 QGCCheckBoxSlider {
578 id: euProvideInfoSlider
579 text: qsTr("Provide Information")
580 checked: _fact.rawValue === RemoteIDSettings.ClassificationType.EU
581 visible: _fact.visible
582 Layout.fillWidth: true
583 onClicked: _fact.rawValue = !_fact.rawValue
584
585 property Fact _fact: remoteIDSettings.classificationType
586 }
587
588 LabelledFactComboBox {
589 id: euCategoryCombo
590 label: _fact.shortDescription
591 fact: _fact
592 indexModel: false
593 visible: _fact.visible
594 enabled: euProvideInfoSlider.checked
595 Layout.fillWidth: true
596
597 property Fact _fact: remoteIDSettings.categoryEU
598 }
599
600 LabelledFactComboBox {
601 label: _fact.shortDescription
602 fact: _fact
603 indexModel: false
604 visible: _fact.visible
605 enabled: euCategoryCombo.enabled
606 Layout.fillWidth: true
607
608 property Fact _fact: remoteIDSettings.classEU
609 }
610 }
611 }
612 }
613
614}