6import QGroundControl.FactControls
7import QGroundControl.Controls
11 pageComponent: safetyPageComponent
14 id: safetyPageComponent
21 FactPanelController { id: controller; }
23 QGCPalette { id: qgcPal; colorGroupEnabled: true }
25 property Fact _batt1Monitor: controller.getParameterFact(-1, "BATT_MONITOR")
26 property Fact _batt2Monitor: controller.getParameterFact(-1, "BATT2_MONITOR", false /* reportMissing */)
27 property bool _batt2MonitorAvailable: controller.parameterExists(-1, "BATT2_MONITOR")
28 property bool _batt1MonitorEnabled: _batt1Monitor.rawValue !== 0
29 property bool _batt2MonitorEnabled: _batt2MonitorAvailable ? _batt2Monitor.rawValue !== 0 : false
30 property bool _batt1ParamsAvailable: controller.parameterExists(-1, "BATT_CAPACITY")
31 property bool _batt2ParamsAvailable: controller.parameterExists(-1, "BATT2_CAPACITY")
33 property Fact _failsafeBatt1LowAct: controller.getParameterFact(-1, "BATT_FS_LOW_ACT", false /* reportMissing */)
34 property Fact _failsafeBatt2LowAct: controller.getParameterFact(-1, "BATT2_FS_LOW_ACT", false /* reportMissing */)
35 property Fact _failsafeBatt1CritAct: controller.getParameterFact(-1, "BATT_FS_CRT_ACT", false /* reportMissing */)
36 property Fact _failsafeBatt2CritAct: controller.getParameterFact(-1, "BATT2_FS_CRT_ACT", false /* reportMissing */)
37 property Fact _failsafeBatt1LowMah: controller.getParameterFact(-1, "BATT_LOW_MAH", false /* reportMissing */)
38 property Fact _failsafeBatt2LowMah: controller.getParameterFact(-1, "BATT2_LOW_MAH", false /* reportMissing */)
39 property Fact _failsafeBatt1CritMah: controller.getParameterFact(-1, "BATT_CRT_MAH", false /* reportMissing */)
40 property Fact _failsafeBatt2CritMah: controller.getParameterFact(-1, "BATT2_CRT_MAH", false /* reportMissing */)
41 property Fact _failsafeBatt1LowVoltage: controller.getParameterFact(-1, "BATT_LOW_VOLT", false /* reportMissing */)
42 property Fact _failsafeBatt2LowVoltage: controller.getParameterFact(-1, "BATT2_LOW_VOLT", false /* reportMissing */)
43 property Fact _failsafeBatt1CritVoltage: controller.getParameterFact(-1, "BATT_CRT_VOLT", false /* reportMissing */)
44 property Fact _failsafeBatt2CritVoltage: controller.getParameterFact(-1, "BATT2_CRT_VOLT", false /* reportMissing */)
46 // Older firmwares use ARMING_CHECK. Newer firmwares use ARMING_SKIPCHK.
47 property Fact _armingCheck: controller.getParameterFact(-1, "ARMING_CHECK", false /* reportMissing */)
48 property Fact _armingSkipCheck: controller.getParameterFact(-1, "ARMING_SKIPCHK", false /* reportMissing */)
50 property real _margins: ScreenTools.defaultFontPixelHeight
51 property real _innerMargin: _margins / 2
52 property bool _showIcon: !ScreenTools.isTinyScreen
53 property bool _roverFirmware: controller.parameterExists(-1, "MODE1") // This catches all usage of ArduRover firmware vehicle types: Rover, Boat...
56 property string _restartRequired: qsTr("Requires vehicle reboot")
59 id: batteryFailsafeComponent
66 columnSpacing: _margins
69 QGCLabel { text: qsTr("Low action:") }
71 fact: failsafeBattLowAct
73 Layout.fillWidth: true
76 QGCLabel { text: qsTr("Critical action:") }
78 fact: failsafeBattCritAct
80 Layout.fillWidth: true
83 QGCLabel { text: qsTr("Low voltage threshold:") }
85 fact: failsafeBattLowVoltage
87 Layout.fillWidth: true
91 QGCLabel { text: qsTr("Critical voltage threshold:") }
93 fact: failsafeBattCritVoltage
95 Layout.fillWidth: true
98 QGCLabel { text: qsTr("Low mAh threshold:") }
100 fact: failsafeBattLowMah
102 Layout.fillWidth: true
105 QGCLabel { text: qsTr("Critical mAh threshold:") }
107 fact: failsafeBattCritMah
109 Layout.fillWidth: true
116 id: restartRequiredComponent
119 spacing: ScreenTools.defaultFontPixelWidth
122 text: _restartRequired
126 text: qsTr("Reboot vehicle")
127 onClicked: controller.vehicle.rebootVehicle()
133 spacing: _margins / 2
134 visible: _batt1MonitorEnabled
137 text: qsTr("Battery1 Failsafe Triggers")
142 width: battery1FailsafeLoader.x + battery1FailsafeLoader.width + _margins
143 height: battery1FailsafeLoader.y + battery1FailsafeLoader.height + _margins
144 color: qgcPal.windowShade
147 id: battery1FailsafeLoader
148 anchors.margins: _margins
149 anchors.top: parent.top
150 anchors.left: parent.left
151 sourceComponent: _batt1ParamsAvailable ? batteryFailsafeComponent : restartRequiredComponent
153 property Fact battMonitor: _batt1Monitor
154 property bool battParamsAvailable: _batt1ParamsAvailable
155 property Fact failsafeBattLowAct: _failsafeBatt1LowAct
156 property Fact failsafeBattCritAct: _failsafeBatt1CritAct
157 property Fact failsafeBattLowMah: _failsafeBatt1LowMah
158 property Fact failsafeBattCritMah: _failsafeBatt1CritMah
159 property Fact failsafeBattLowVoltage: _failsafeBatt1LowVoltage
160 property Fact failsafeBattCritVoltage: _failsafeBatt1CritVoltage
163 } // Column - Battery Failsafe Settings
167 spacing: _margins / 2
168 visible: _batt2MonitorEnabled
171 text: qsTr("Battery2 Failsafe Triggers")
176 width: battery2FailsafeLoader.x + battery2FailsafeLoader.width + _margins
177 height: battery2FailsafeLoader.y + battery2FailsafeLoader.height + _margins
178 color: qgcPal.windowShade
181 id: battery2FailsafeLoader
182 anchors.margins: _margins
183 anchors.top: parent.top
184 anchors.left: parent.left
185 sourceComponent: _batt2ParamsAvailable ? batteryFailsafeComponent : restartRequiredComponent
187 property Fact battMonitor: _batt2Monitor
188 property bool battParamsAvailable: _batt2ParamsAvailable
189 property Fact failsafeBattLowAct: _failsafeBatt2LowAct
190 property Fact failsafeBattCritAct: _failsafeBatt2CritAct
191 property Fact failsafeBattLowMah: _failsafeBatt2LowMah
192 property Fact failsafeBattCritMah: _failsafeBatt2CritMah
193 property Fact failsafeBattLowVoltage: _failsafeBatt2LowVoltage
194 property Fact failsafeBattCritVoltage: _failsafeBatt2CritVoltage
197 } // Column - Battery Failsafe Settings
203 spacing: _margins / 2
205 property Fact _failsafeThrEnable: controller.getParameterFact(-1, "THR_FAILSAFE")
206 property Fact _failsafeThrValue: controller.getParameterFact(-1, "THR_FS_VALUE")
207 property Fact _failsafeGCSEnable: controller.getParameterFact(-1, "FS_GCS_ENABL")
210 text: qsTr("Failsafe Triggers")
215 width: fsColumn.x + fsColumn.width + _margins
216 height: fsColumn.y + fsColumn.height + _margins
217 color: qgcPal.windowShade
221 anchors.margins: _margins
222 anchors.left: parent.left
223 anchors.top: parent.top
227 id: throttleEnableCheckBox
228 text: qsTr("Throttle PWM threshold:")
229 checked: _failsafeThrEnable.value === 1
231 onClicked: _failsafeThrEnable.value = (checked ? 1 : 0)
235 fact: _failsafeThrValue
237 enabled: throttleEnableCheckBox.checked
242 text: qsTr("GCS failsafe")
243 checked: _failsafeGCSEnable.value != 0
244 onClicked: _failsafeGCSEnable.value = checked ? 1 : 0
247 } // Rectangle - Failsafe trigger settings
248 } // Column - Failsafe trigger settings
252 sourceComponent: controller.vehicle.fixedWing ? planeGeneralFS : undefined
259 spacing: _margins / 2
261 property Fact _failsafeGCSEnable: controller.getParameterFact(-1, "FS_GCS_ENABLE")
262 property Fact _failsafeThrEnable: controller.getParameterFact(-1, "FS_THR_ENABLE")
263 property Fact _failsafeThrValue: controller.getParameterFact(-1, "FS_THR_VALUE")
264 property Fact _failsafeAction: controller.getParameterFact(-1, "FS_ACTION")
265 property Fact _failsafeCrashCheck: controller.getParameterFact(-1, "FS_CRASH_CHECK")
269 text: qsTr("Failsafe Triggers")
275 width: fsGrid.x + fsGrid.width + _margins
276 height: fsGrid.y + fsGrid.height + _margins
277 color: qgcPal.windowShade
281 anchors.margins: _margins
282 anchors.left: parent.left
283 anchors.top: parent.top
286 QGCLabel { text: qsTr("Ground Station failsafe:") }
288 Layout.fillWidth: true
289 fact: _failsafeGCSEnable
293 QGCLabel { text: qsTr("Throttle failsafe:") }
295 Layout.fillWidth: true
296 fact: _failsafeThrEnable
300 QGCLabel { text: qsTr("PWM threshold:") }
302 Layout.fillWidth: true
303 fact: _failsafeThrValue
306 QGCLabel { text: qsTr("Failsafe Crash Check:") }
308 Layout.fillWidth: true
309 fact: _failsafeCrashCheck
313 } // Rectangle - Failsafe Settings
314 } // Column - Failsafe Settings
318 sourceComponent: _roverFirmware ? roverGeneralFS : undefined
325 spacing: _margins / 2
327 property Fact _failsafeGCSEnable: controller.getParameterFact(-1, "FS_GCS_ENABLE")
328 property Fact _failsafeBattLowAct: controller.getParameterFact(-1, "r.BATT_FS_LOW_ACT", false /* reportMissing */)
329 property Fact _failsafeBattMah: controller.getParameterFact(-1, "r.BATT_LOW_MAH", false /* reportMissing */)
330 property Fact _failsafeBattVoltage: controller.getParameterFact(-1, "r.BATT_LOW_VOLT", false /* reportMissing */)
331 property Fact _failsafeThrEnable: controller.getParameterFact(-1, "FS_THR_ENABLE")
332 property Fact _failsafeThrValue: controller.getParameterFact(-1, "FS_THR_VALUE")
335 text: qsTr("General Failsafe Triggers")
340 width: generalFailsafeColumn.x + generalFailsafeColumn.width + _margins
341 height: generalFailsafeColumn.y + generalFailsafeColumn.height + _margins
342 color: qgcPal.windowShade
345 id: generalFailsafeColumn
346 anchors.margins: _margins
347 anchors.top: parent.top
348 anchors.left: parent.left
352 columnSpacing: _margins
356 QGCLabel { text: qsTr("Ground Station failsafe:") }
358 fact: _failsafeGCSEnable
360 Layout.fillWidth: true
363 QGCLabel { text: qsTr("Throttle failsafe:") }
365 model: [qsTr("Disabled"), qsTr("Always RTL"),
366 qsTr("Continue with Mission in Auto Mode"), qsTr("Always Land")]
367 currentIndex: _failsafeThrEnable.value
368 Layout.fillWidth: true
370 onActivated: (index) => { _failsafeThrEnable.value = index }
373 QGCLabel { text: qsTr("PWM threshold:") }
375 fact: _failsafeThrValue
377 Layout.fillWidth: true
381 } // Rectangle - Failsafe Settings
382 } // Column - General Failsafe Settings
386 sourceComponent: controller.vehicle.multiRotor ? copterGeneralFS : undefined
393 spacing: _margins / 2
395 property Fact _fenceAction: controller.getParameterFact(-1, "FENCE_ACTION")
396 property Fact _fenceAltMax: controller.getParameterFact(-1, "FENCE_ALT_MAX")
397 property Fact _fenceEnable: controller.getParameterFact(-1, "FENCE_ENABLE")
398 property Fact _fenceMargin: controller.getParameterFact(-1, "FENCE_MARGIN")
399 property Fact _fenceRadius: controller.getParameterFact(-1, "FENCE_RADIUS")
400 property Fact _fenceType: controller.getParameterFact(-1, "FENCE_TYPE")
402 readonly property int _maxAltitudeFenceBitMask: 1
403 readonly property int _circleFenceBitMask: 2
404 readonly property int _polygonFenceBitMask: 4
407 text: qsTr("GeoFence")
412 width: mainLayout.width + (_margins * 2)
413 height: mainLayout.height + (_margins * 2)
414 color: qgcPal.windowShade
420 spacing: ScreenTools.defaultFontPixellHeight / 2
424 text: qsTr("Enabled")
430 enabled: enabledCheckBox.checked
433 text: qsTr("Maximum Altitude")
434 checked: _fenceType.rawValue & _maxAltitudeFenceBitMask
438 _fenceType.rawValue |= _maxAltitudeFenceBitMask
440 _fenceType.value &= ~_maxAltitudeFenceBitMask
450 text: qsTr("Circle centered on Home")
451 checked: _fenceType.rawValue & _circleFenceBitMask
455 _fenceType.rawValue |= _circleFenceBitMask
457 _fenceType.value &= ~_circleFenceBitMask
468 text: qsTr("Inclusion/Exclusion Circles+Polygons")
469 checked: _fenceType.rawValue & _polygonFenceBitMask
473 _fenceType.rawValue |= _polygonFenceBitMask
475 _fenceType.value &= ~_polygonFenceBitMask
493 enabled: enabledCheckBox.checked
496 text: qsTr("Breach action")
505 text: qsTr("Fence margin")
513 } // Rectangle - GeoFence Settings
514 } // Column - GeoFence Settings
518 sourceComponent: controller.vehicle.multiRotor ? copterGeoFence : undefined
525 spacing: _margins / 2
527 property Fact _landSpeedFact: controller.getParameterFact(-1, "LAND_SPEED")
528 property Fact _rtlAltFact: controller.getParameterFact(-1, "RTL_ALT")
529 property Fact _rtlLoitTimeFact: controller.getParameterFact(-1, "RTL_LOIT_TIME")
530 property Fact _rtlAltFinalFact: controller.getParameterFact(-1, "RTL_ALT_FINAL")
534 text: qsTr("Return to Launch")
540 width: landSpeedField.x + landSpeedField.width + _margins
541 height: landSpeedField.y + landSpeedField.height + _margins
542 color: qgcPal.windowShade
547 anchors.margins: _margins
548 anchors.left: parent.left
549 anchors.top: parent.top
550 height: ScreenTools.defaultFontPixelWidth * 20
551 width: ScreenTools.defaultFontPixelWidth * 20
553 sourceSize.width: width
555 fillMode: Image.PreserveAspectFit
556 source: "/qmlimages/ReturnToHomeAltitude.svg"
560 id: returnAtCurrentRadio
561 anchors.margins: _innerMargin
562 anchors.left: _showIcon ? icon.right : parent.left
563 anchors.top: parent.top
564 text: qsTr("Return at current altitude")
565 checked: _rtlAltFact.value == 0
567 onClicked: _rtlAltFact.value = 0
572 anchors.topMargin: _innerMargin
573 anchors.top: returnAtCurrentRadio.bottom
574 anchors.left: returnAtCurrentRadio.left
575 text: qsTr("Return at specified altitude:")
576 checked: _rtlAltFact.value != 0
578 onClicked: _rtlAltFact.value = 1500
583 anchors.leftMargin: _margins
584 anchors.left: returnAltRadio.right
585 anchors.baseline: returnAltRadio.baseline
588 enabled: returnAltRadio.checked
592 id: homeLoiterCheckbox
593 anchors.left: returnAtCurrentRadio.left
594 anchors.baseline: landDelayField.baseline
595 checked: _rtlLoitTimeFact.value > 0
596 text: qsTr("Loiter above Home for:")
598 onClicked: _rtlLoitTimeFact.value = (checked ? 60 : 0)
603 anchors.topMargin: _innerMargin
604 anchors.left: rltAltField.left
605 anchors.top: rltAltField.bottom
606 fact: _rtlLoitTimeFact
608 enabled: homeLoiterCheckbox.checked === true
612 anchors.left: returnAtCurrentRadio.left
613 anchors.baseline: rltAltFinalField.baseline
614 text: qsTr("Final land stage altitude:")
619 anchors.topMargin: _innerMargin
620 anchors.left: rltAltField.left
621 anchors.top: landDelayField.bottom
622 fact: _rtlAltFinalFact
627 anchors.left: returnAtCurrentRadio.left
628 anchors.baseline: landSpeedField.baseline
629 text: qsTr("Final land stage descent speed:")
634 anchors.topMargin: _innerMargin
635 anchors.left: rltAltField.left
636 anchors.top: rltAltFinalField.bottom
640 } // Rectangle - RTL Settings
641 } // Column - RTL Settings
645 sourceComponent: controller.vehicle.multiRotor ? copterRTL : undefined
652 spacing: _margins / 2
654 property Fact _rtlAltFact: controller.getParameterFact(-1, "r.RTL_ALTITUDE")
657 text: qsTr("Return to Launch")
662 width: rltAltField.x + rltAltField.width + _margins
663 height: rltAltField.y + rltAltField.height + _margins
664 color: qgcPal.windowShade
667 id: returnAtCurrentRadio
668 anchors.margins: _margins
669 anchors.left: parent.left
670 anchors.top: parent.top
671 text: qsTr("Return at current altitude")
672 checked: _rtlAltFact.value < 0
674 onClicked: _rtlAltFact.value = -1
679 anchors.topMargin: _margins / 2
680 anchors.left: returnAtCurrentRadio.left
681 anchors.top: returnAtCurrentRadio.bottom
682 text: qsTr("Return at specified altitude:")
683 checked: _rtlAltFact.value >= 0
685 onClicked: _rtlAltFact.value = 10000
690 anchors.leftMargin: _margins
691 anchors.left: returnAltRadio.right
692 anchors.baseline: returnAltRadio.baseline
695 enabled: returnAltRadio.checked
697 } // Rectangle - RTL Settings
698 } // Column - RTL Settings
702 sourceComponent: controller.vehicle.fixedWing ? planeRTL : undefined
706 spacing: _margins / 2
709 text: _armingCheck ? qsTr("Arming Checks") : qsTr("Skip Arming Checks")
714 width: flowLayout.width
715 height: armingCheckInnerColumn.height + (_margins * 2)
716 color: qgcPal.windowShade
719 id: armingCheckInnerColumn
720 anchors.margins: _margins
721 anchors.top: parent.top
722 anchors.left: parent.left
723 anchors.right: parent.right
727 id: armingCheckBitmask
728 anchors.left: parent.left
729 anchors.right: parent.right
730 firstEntryIsAll: _armingCheck ? true : false
731 fact: _armingCheck ? _armingCheck : _armingSkipCheck
735 id: armingCheckWarning
736 anchors.left: parent.left
737 anchors.right: parent.right
738 wrapMode: Text.WordWrap
739 color: qgcPal.warningText
740 text: qsTr("Warning: Turning off arming checks can lead to loss of Vehicle control.")
741 visible: _armingCheck ? _armingCheck.value != 1 : _armingSkipCheck.value != 0
744 } // Rectangle - Arming checks
745 } // Column - Arming Checks
747 } // Component - safetyPageComponent