QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
APMSensorsComponent.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
10SetupPage {
11 id: sensorsPage
12 pageComponent: sensorsPageComponent
13
14 Component {
15 id: sensorsPageComponent
16
17 Item {
18 width: availableWidth
19 height: availableHeight
20
21 // Help text which is shown both in the status text area prior to pressing a cal button and in the
22 // pre-calibration dialog.
23
24 readonly property string orientationHelpSet: qsTr("If mounted in the direction of flight, select None.")
25 readonly property string orientationHelpCal: qsTr("Before calibrating make sure rotation settings are correct. ") + orientationHelpSet
26 readonly property string compassRotationText: qsTr("If the compass or GPS module is mounted in flight direction, leave the default value (None)")
27
28 readonly property string compassHelp: qsTr("For Compass calibration you will need to rotate your vehicle through a number of positions.")
29 readonly property string gyroHelp: qsTr("For Gyroscope calibration you will need to place your vehicle on a surface and leave it still.")
30 readonly property string accelHelp: qsTr("For Accelerometer calibration you will need to place your vehicle on all six sides on a perfectly level surface and hold it still in each orientation for a few seconds.")
31 readonly property string levelHelp: qsTr("To level the horizon you need to place the vehicle in its level flight position and press OK.")
32
33 readonly property string statusTextAreaDefaultText: qsTr("Start the individual calibration steps by clicking one of the buttons to the left.")
34
35 // Used to pass help text to the preCalibrationDialog dialog
36 property string preCalibrationDialogHelp
37
38 property string _postCalibrationDialogText
39 property var _postCalibrationDialogParams
40
41 readonly property string _badCompassCalText: qsTr("The calibration for Compass %1 appears to be poor. ") +
42 qsTr("Check the compass position within your vehicle and re-do the calibration.")
43
44 readonly property int sideBarH1PointSize: ScreenTools.mediumFontPointSize
45 readonly property int mainTextH1PointSize: ScreenTools.mediumFontPointSize // Seems to be unused
46
47 readonly property int rotationColumnWidth: 250
48
49 property Fact noFact: Fact { }
50
51 property bool accelCalNeeded: controller.accelSetupNeeded
52 property bool compassCalNeeded: controller.compassSetupNeeded
53
54 property Fact boardRot: controller.getParameterFact(-1, "AHRS_ORIENTATION")
55
56 readonly property int _calTypeCompass: 1 ///< Calibrate compass
57 readonly property int _calTypeAccel: 2 ///< Calibrate accel
58 readonly property int _calTypeSet: 3 ///< Set orientations only
59 readonly property int _buttonWidth: ScreenTools.defaultFontPixelWidth * 15
60
61 property bool _orientationsDialogShowCompass: true
62 property string _orientationDialogHelp: orientationHelpSet
63 property int _orientationDialogCalType
64 property real _margins: ScreenTools.defaultFontPixelHeight / 2
65 property bool _compassAutoRotAvailable: controller.parameterExists(-1, "COMPASS_AUTO_ROT")
66 property Fact _compassAutoRotFact: controller.getParameterFact(-1, "COMPASS_AUTO_ROT", false /* reportMissing */)
67 property bool _compassAutoRot: _compassAutoRotAvailable ? _compassAutoRotFact.rawValue == 2 : false
68 property bool _showSimpleAccelCalOption: false
69 property bool _doSimpleAccelCal: false
70 property var _gcsPosition: QGroundControl.qgcPositionManger.gcsPosition
71 property var _mapPosition: QGroundControl.flightMapPosition
72
73 function showOrientationsDialog(calType) {
74 let dialogTitle
75 let dialogButtons = Dialog.Ok
76 _showSimpleAccelCalOption = false
77
78 _orientationDialogCalType = calType
79 switch (calType) {
80 case _calTypeCompass:
81 _orientationsDialogShowCompass = true
82 _orientationDialogHelp = orientationHelpCal
83 dialogTitle = qsTr("Calibrate Compass")
84 dialogButtons |= Dialog.Cancel
85 break
86 case _calTypeAccel:
87 _orientationsDialogShowCompass = false
88 _orientationDialogHelp = orientationHelpCal
89 dialogTitle = qsTr("Calibrate Accelerometer")
90 dialogButtons |= Dialog.Cancel
91 break
92 case _calTypeSet:
93 _orientationsDialogShowCompass = true
94 _orientationDialogHelp = orientationHelpSet
95 dialogTitle = qsTr("Sensor Settings")
96 break
97 }
98
99 orientationsDialogFactory.open({ title: dialogTitle, buttons: dialogButtons })
100 }
101
102 function showSimpleAccelCalOption() {
103 _showSimpleAccelCalOption = true
104 }
105
106 // Maps the APM controller per-side done/inProgress bools to a VehicleRotationCal.CalState
107 function sideCalState(done, inProgress) {
108 if (inProgress) {
109 return VehicleRotationCal.CalState.InProgress
110 }
111 return done ? VehicleRotationCal.CalState.Completed : VehicleRotationCal.CalState.Incomplete
112 }
113
114 function compassLabel(index) {
115 let label = qsTr("Compass %1 ").arg(index+1)
116 let addOpenParan = true
117 let addComma = false
118 if (sensorParams.compassPrimaryFactAvailable) {
119 label += sensorParams.rgCompassPrimary[index] ? qsTr("(primary") : qsTr("(secondary")
120 addComma = true
121 addOpenParan = false
122 }
123 if (sensorParams.rgCompassExternalParamAvailable[index]) {
124 if (addOpenParan) {
125 label += "("
126 }
127 if (addComma) {
128 label += qsTr(", ")
129 }
130 label += sensorParams.rgCompassExternal[index] ? qsTr("external") : qsTr("internal")
131 }
132 label += ")"
133 return label
134 }
135
136 APMSensorParams {
137 id: sensorParams
138 factPanelController: controller
139 }
140
141 APMSensorsComponentController {
142 id: controller
143 statusLog: statusTextArea
144 progressBar: progressBar
145 nextButton: nextButton
146 cancelButton: cancelButton
147 orientationCalAreaHelpText: orientationCalAreaHelpText
148
149 property var rgCompassCalFitness: [ controller.compass1CalFitness, controller.compass2CalFitness, controller.compass3CalFitness ]
150
151 onResetStatusTextArea: statusLog.text = statusTextAreaDefaultText
152
153 onWaitingForCancelChanged: {
154 if (controller.waitingForCancel) {
155 waitForCancelDialogFactory.open()
156 }
157 }
158
159 onCalibrationComplete: (calType) => {
160 switch (calType) {
161 case MAVLink.CalibrationAccel:
162 case MAVLink.CalibrationMag:
163 _singleCompassSettingsComponentShowPriority = true
164 postOnboardCompassCalibrationFactory.open()
165 break
166 }
167 }
168
169 onSetAllCalButtonsEnabled: (enabled) => {
170 buttonColumn.enabled = enabled
171 }
172
173 onCalibrationActiveChanged: {
174 if (controller.calibrationActive) {
175 globals.navigationBlockedReason = qsTr("Complete or cancel the current calibration first")
176 } else {
177 globals.navigationBlockedReason = ""
178 }
179 }
180 }
181
182 Component.onDestruction: globals.navigationBlockedReason = ""
183
184 QGCPalette { id: qgcPal; colorGroupEnabled: true }
185
186 QGCPopupDialogFactory {
187 id: waitForCancelDialogFactory
188
189 dialogComponent: waitForCancelDialogComponent
190 }
191
192 Component {
193 id: waitForCancelDialogComponent
194
195 QGCSimpleMessageDialog {
196 title: qsTr("Calibration Cancel")
197 text: qsTr("Waiting for Vehicle to response to Cancel. This may take a few seconds.")
198 buttons: 0
199
200 Connections {
201 target: controller
202
203 onWaitingForCancelChanged: {
204 if (!controller.waitingForCancel) {
205 close()
206 }
207 }
208 }
209 }
210 }
211
212 Component {
213 id: singleCompassOnboardResultsComponent
214
215 Column {
216 anchors.left: parent ? parent.left : undefined
217 anchors.right: parent ? parent.right : undefined
218 spacing: Math.round(ScreenTools.defaultFontPixelHeight / 2)
219 visible: sensorParams.rgCompassAvailable[index] && sensorParams.rgCompassUseFact[index].value
220
221 property int _index: index
222
223 property real greenMaxThreshold: 8 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
224 property real yellowMaxThreshold: 15 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
225 property real fitnessRange: 25 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
226
227 Item {
228 anchors.left: parent.left
229 anchors.right: parent.right
230 height: ScreenTools.defaultFontPixelHeight
231
232 Row {
233 id: fitnessRow
234 anchors.fill: parent
235
236 Rectangle {
237 width: parent.width * (greenMaxThreshold / fitnessRange)
238 height: parent.height
239 color: "green"
240 }
241 Rectangle {
242 width: parent.width * ((yellowMaxThreshold - greenMaxThreshold) / fitnessRange)
243 height: parent.height
244 color: "yellow"
245 }
246 Rectangle {
247 width: parent.width * ((fitnessRange - yellowMaxThreshold) / fitnessRange)
248 height: parent.height
249 color: "red"
250 }
251 }
252
253 Rectangle {
254 height: fitnessRow.height * 0.66
255 width: height
256 anchors.verticalCenter: fitnessRow.verticalCenter
257 x: (fitnessRow.width * (Math.min(Math.max(controller.rgCompassCalFitness[index], 0.0), fitnessRange) / fitnessRange)) - (width / 2)
258 radius: height / 2
259 color: "white"
260 border.color: "black"
261 }
262 }
263
264 Loader {
265 anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
266 anchors.left: parent.left
267 anchors.right: parent.right
268 sourceComponent: singleCompassSettingsComponent
269
270 property int index: _index
271 }
272 }
273 }
274
275 QGCPopupDialogFactory {
276 id: postOnboardCompassCalibrationFactory
277
278 dialogComponent: postOnboardCompassCalibrationComponent
279 }
280
281 Component {
282 id: postOnboardCompassCalibrationComponent
283
284 QGCPopupDialog {
285 id: postOnboardCompassCalibrationDialog
286 title: qsTr("Calibration complete")
287 buttons: Dialog.Ok
288
289 Column {
290 width: 40 * ScreenTools.defaultFontPixelWidth
291 spacing: ScreenTools.defaultFontPixelHeight
292
293 Repeater {
294 model: 3
295 delegate: singleCompassOnboardResultsComponent
296 }
297
298 QGCLabel {
299 anchors.left: parent.left
300 anchors.right: parent.right
301 wrapMode: Text.WordWrap
302 text: qsTr("Shown in the indicator bars is the quality of the calibration for each compass.\n\n") +
303 qsTr("- Green indicates a well functioning compass.\n") +
304 qsTr("- Yellow indicates a questionable compass or calibration.\n") +
305 qsTr("- Red indicates a compass which should not be used.\n\n") +
306 qsTr("YOU MUST REBOOT YOUR VEHICLE AFTER EACH CALIBRATION.")
307 }
308
309 QGCButton {
310 text: qsTr("Reboot Vehicle")
311 onClicked: {
312 controller.vehicle.rebootVehicle()
313 postOnboardCompassCalibrationDialog.close()
314 }
315 }
316 }
317 }
318 }
319
320 Component {
321 id: postCalibrationComponent
322
323 QGCPopupDialog {
324 id: postCalibrationDialog
325 title: qsTr("Calibration complete")
326
327 Column {
328 width: 40 * ScreenTools.defaultFontPixelWidth
329 spacing: ScreenTools.defaultFontPixelHeight
330
331 QGCLabel {
332 anchors.left: parent.left
333 anchors.right: parent.right
334 wrapMode: Text.WordWrap
335 text: qsTr("YOU MUST REBOOT YOUR VEHICLE AFTER EACH CALIBRATION.")
336 }
337
338 QGCButton {
339 text: qsTr("Reboot Vehicle")
340 onClicked: {
341 controller.vehicle.rebootVehicle()
342 postCalibrationDialog.close()
343 }
344 }
345 }
346 }
347 }
348
349 property bool _singleCompassSettingsComponentShowPriority: true
350 Component {
351 id: singleCompassSettingsComponent
352
353 Column {
354 spacing: Math.round(ScreenTools.defaultFontPixelHeight / 2)
355 visible: sensorParams.rgCompassAvailable[index]
356
357 QGCLabel {
358 text: compassLabel(index)
359 }
360 APMSensorIdDecoder {
361 fact: sensorParams.rgCompassId[index]
362 }
363
364 Column {
365 anchors.margins: ScreenTools.defaultFontPixelWidth * 2
366 anchors.left: parent.left
367 spacing: Math.round(ScreenTools.defaultFontPixelHeight / 4)
368
369 RowLayout {
370 spacing: ScreenTools.defaultFontPixelWidth
371
372 FactCheckBox {
373 id: useCompassCheckBox
374 text: qsTr("Use Compass")
375 fact: sensorParams.rgCompassUseFact[index]
376 visible: sensorParams.rgCompassUseParamAvailable[index] && !sensorParams.rgCompassPrimary[index]
377 }
378
379 QGCComboBox {
380 model: [ qsTr("Priority 1"), qsTr("Priority 2"), qsTr("Priority 3"), qsTr("Not Set") ]
381 visible: _singleCompassSettingsComponentShowPriority && sensorParams.compassPrioFactsAvailable && useCompassCheckBox.visible && useCompassCheckBox.checked
382
383 property int _compassIndex: index
384
385 function selectPriorityfromParams() {
386 currentIndex = 3
387 let compassId = sensorParams.rgCompassId[_compassIndex].rawValue
388 for (let prioIndex=0; prioIndex<3; prioIndex++) {
389 if (compassId == sensorParams.rgCompassPrio[prioIndex].rawValue) {
390 currentIndex = prioIndex
391 break
392 }
393 }
394 }
395
396 Component.onCompleted: selectPriorityfromParams()
397
398 onActivated: (index) => {
399 if (index == 3) {
400 // User cannot select Not Set
401 selectPriorityfromParams()
402 } else {
403 sensorParams.rgCompassPrio[index].rawValue = sensorParams.rgCompassId[_compassIndex].rawValue
404 }
405 }
406 }
407 }
408
409 Column {
410 visible: !_compassAutoRot && sensorParams.rgCompassExternal[index] && sensorParams.rgCompassRotParamAvailable[index]
411
412 QGCLabel { text: qsTr("Orientation:") }
413
414 FactComboBox {
415 width: rotationColumnWidth
416 indexModel: false
417 fact: sensorParams.rgCompassRotFact[index]
418 }
419 }
420 }
421 }
422 }
423
424 QGCPopupDialogFactory {
425 id: orientationsDialogFactory
426
427 dialogComponent: orientationsDialogComponent
428 }
429
430 Component {
431 id: orientationsDialogComponent
432
433 QGCPopupDialog {
434 function compassMask () {
435 let mask = 0
436 mask |= (0 + (sensorParams.rgCompassPrio[0].rawValue !== 0)) << 0
437 mask |= (0 + (sensorParams.rgCompassPrio[1].rawValue !== 0)) << 1
438 mask |= (0 + (sensorParams.rgCompassPrio[2].rawValue !== 0)) << 2
439 return mask
440 }
441
442 onAccepted: {
443 if (_orientationDialogCalType == _calTypeAccel) {
444 controller.calibrateAccel(_doSimpleAccelCal)
445 } else if (_orientationDialogCalType == _calTypeCompass) {
446 if (!northCalibrationCheckBox.checked) {
447 controller.calibrateCompass()
448 } else {
449 let lat = parseFloat(northCalLat.text)
450 let lon = parseFloat(northCalLon.text)
451 if (useMapPositionCheckbox.checked) {
452 lat = _mapPosition.latitude
453 lon = _mapPosition.longitude
454 }
455 if (useGcsPositionCheckbox.checked) {
456 lat = _gcsPosition.latitude
457 lon = _gcsPosition.longitude
458 }
459 if (isNaN(lat) || isNaN(lon)) {
460 return
461 }
462 controller.calibrateCompassNorth(lat, lon, compassMask())
463 }
464 }
465 }
466
467 Column {
468 width: 40 * ScreenTools.defaultFontPixelWidth
469 spacing: ScreenTools.defaultFontPixelHeight
470
471 QGCLabel {
472 width: parent.width
473 wrapMode: Text.WordWrap
474 text: _orientationDialogHelp
475 }
476
477 Column {
478 QGCLabel { text: qsTr("Autopilot Rotation:") }
479
480 FactComboBox {
481 width: rotationColumnWidth
482 indexModel: false
483 fact: boardRot
484 }
485 }
486
487 Column {
488
489 visible: _orientationDialogCalType == _calTypeAccel
490 spacing: ScreenTools.defaultFontPixelHeight
491
492 QGCLabel {
493 width: parent.width
494 wrapMode: Text.WordWrap
495 text: qsTr("Simple accelerometer calibration is less precise but allows calibrating without rotating the vehicle. Check this if you have a large/heavy vehicle.")
496 }
497
498 QGCCheckBox {
499 text: "Simple Accelerometer Calibration"
500 onClicked: _doSimpleAccelCal = this.checked
501 }
502 }
503
504 Repeater {
505 model: _orientationsDialogShowCompass ? 3 : 0
506 delegate: singleCompassSettingsComponent
507 }
508
509 QGCLabel {
510 id: magneticDeclinationLabel
511 width: parent.width
512 visible: globals.activeVehicle.sub && _orientationsDialogShowCompass
513 text: qsTr("Magnetic Declination")
514 }
515
516 Column {
517 visible: magneticDeclinationLabel.visible
518 anchors.margins: ScreenTools.defaultFontPixelWidth
519 anchors.left: parent.left
520 anchors.right: parent.right
521 spacing: ScreenTools.defaultFontPixelHeight
522
523 QGCCheckBox {
524 id: manualMagneticDeclinationCheckBox
525 text: qsTr("Manual Magnetic Declination")
526 property Fact autoDecFact: controller.getParameterFact(-1, "COMPASS_AUTODEC")
527 property int manual: 0
528 property int automatic: 1
529
530 checked: autoDecFact.rawValue === manual
531 onClicked: autoDecFact.value = (checked ? manual : automatic)
532 }
533
534 FactTextField {
535 fact: sensorParams.declinationFact
536 enabled: manualMagneticDeclinationCheckBox.checked
537 }
538 }
539
540 Item { height: ScreenTools.defaultFontPixelHeight; width: 10 } // spacer
541
542 QGCLabel {
543 id: northCalibrationLabel
544 width: parent.width
545 visible: _orientationsDialogShowCompass
546 wrapMode: Text.WordWrap
547 text: qsTr("Fast compass calibration given vehicle position and yaw. This ") +
548 qsTr("results in zero diagonal and off-diagonal elements, so is only ") +
549 qsTr("suitable for vehicles where the field is close to spherical. It is ") +
550 qsTr("useful for large vehicles where moving the vehicle to calibrate it ") +
551 qsTr("is difficult. Point the vehicle North before using it.")
552 }
553
554 Column {
555 visible: northCalibrationLabel.visible
556 anchors.margins: ScreenTools.defaultFontPixelWidth
557 anchors.left: parent.left
558 anchors.right: parent.right
559 spacing: ScreenTools.defaultFontPixelHeight
560
561 QGCCheckBox {
562 id: northCalibrationCheckBox
563 visible: northCalibrationLabel.visible
564 text: qsTr("Fast Calibration")
565 }
566
567 QGCLabel {
568 id: northCalibrationManualPosition
569 width: parent.width
570 visible: northCalibrationCheckBox.checked && !globals.activeVehicle.coordinate.isValid
571 wrapMode: Text.WordWrap
572 text: qsTr("Vehicle has no Valid positon, please provide it")
573 }
574
575 QGCCheckBox {
576 visible: northCalibrationManualPosition.visible && _gcsPosition.isValid
577 id: useGcsPositionCheckbox
578 text: qsTr("Use GCS position instead")
579 checked: _gcsPosition.isValid
580 }
581 QGCCheckBox {
582 visible: northCalibrationManualPosition.visible && !_gcsPosition.isValid
583 id: useMapPositionCheckbox
584 text: qsTr("Use current map position instead")
585 }
586
587 QGCLabel {
588 width: parent.width
589 visible: useMapPositionCheckbox.checked
590 wrapMode: Text.WordWrap
591 text: qsTr(`Lat: ${_mapPosition.latitude.toFixed(4)} Lon: ${_mapPosition.longitude.toFixed(4)}`)
592 }
593
594 FactTextField {
595 id: northCalLat
596 visible: !useGcsPositionCheckbox.checked && !useMapPositionCheckbox.checked && northCalibrationCheckBox.checked
597 text: "0.00"
598 textColor: isNaN(parseFloat(text)) ? qgcPal.warningText: qgcPal.textFieldText
599 enabled: !useGcsPositionCheckbox.checked
600 }
601 FactTextField {
602 id: northCalLon
603 visible: !useGcsPositionCheckbox.checked && !useMapPositionCheckbox.checked && northCalibrationCheckBox.checked
604 text: "0.00"
605 textColor: isNaN(parseFloat(text)) ? qgcPal.warningText: qgcPal.textFieldText
606 enabled: !useGcsPositionCheckbox.checked
607 }
608
609 }
610 }
611 }
612 }
613
614 QGCPopupDialogFactory {
615 id: compassMotDialogFactory
616
617 dialogComponent: compassMotDialogComponent
618 }
619
620 Component {
621 id: compassMotDialogComponent
622
623 QGCPopupDialog {
624 title: qsTr("Compass Motor Interference Calibration")
625 buttons: Dialog.Cancel | Dialog.Ok
626
627 onAccepted: controller.calibrateMotorInterference()
628
629 Column {
630 width: 40 * ScreenTools.defaultFontPixelWidth
631 spacing: ScreenTools.defaultFontPixelHeight
632
633 QGCLabel {
634 anchors.left: parent.left
635 anchors.right: parent.right
636 wrapMode: Text.WordWrap
637 text: qsTr("This is recommended for vehicles that have only an internal compass and on vehicles where there is significant interference on the compass from the motors, power wires, etc. ") +
638 qsTr("CompassMot only works well if you have a battery current monitor because the magnetic interference is linear with current drawn. ") +
639 qsTr("It is technically possible to set-up CompassMot using throttle but this is not recommended.")
640 }
641
642 QGCLabel {
643 anchors.left: parent.left
644 anchors.right: parent.right
645 wrapMode: Text.WordWrap
646 text: qsTr("Disconnect your props, flip them over and rotate them one position around the frame. ") +
647 qsTr("In this configuration they should push the copter down into the ground when the throttle is raised.")
648 }
649
650 QGCLabel {
651 anchors.left: parent.left
652 anchors.right: parent.right
653 wrapMode: Text.WordWrap
654 text: qsTr("Secure the copter (perhaps with tape) so that it does not move.")
655 }
656
657 QGCLabel {
658 anchors.left: parent.left
659 anchors.right: parent.right
660 wrapMode: Text.WordWrap
661 text: qsTr("Turn on your transmitter and keep throttle at zero.")
662 }
663
664 QGCLabel {
665 anchors.left: parent.left
666 anchors.right: parent.right
667 wrapMode: Text.WordWrap
668 text: qsTr("Click Ok to start CompassMot calibration.")
669 }
670 }
671 }
672 }
673
674 QGCFlickable {
675 id: buttonFlickable
676 anchors.left: parent.left
677 anchors.top: parent.top
678 anchors.bottom: parent.bottom
679 width: _buttonWidth
680 contentHeight: nextCancelColumn.y + nextCancelColumn.height + _margins
681
682 // Calibration button column - Calibratin buttons are kept in a separate column from Next/Cancel buttons
683 // so we can enable/disable them all as a group
684 Column {
685 id: buttonColumn
686 spacing: _margins
687 Layout.alignment: Qt.AlignLeft | Qt.AlignTop
688
689 IndicatorButton {
690 objectName: "sensorsSetup_calibrateAccel"
691 width: _buttonWidth
692 text: qsTr("Accelerometer")
693 indicatorGreen: !accelCalNeeded
694
695 onClicked: function () {
696 showOrientationsDialog(_calTypeAccel);
697 showSimpleAccelCalOption();
698 }
699 }
700
701 IndicatorButton {
702 objectName: "sensorsSetup_calibrateCompass"
703 width: _buttonWidth
704 text: qsTr("Compass")
705 indicatorGreen: !compassCalNeeded
706
707 onClicked: {
708 if (controller.accelSetupNeeded) {
709 QGroundControl.showMessageDialog(sensorsPage, qsTr("Calibrate Compass"), qsTr("Accelerometer must be calibrated prior to Compass."))
710 } else {
711 showOrientationsDialog(_calTypeCompass)
712 }
713 }
714 }
715
716 QGCButton {
717 width: _buttonWidth
718 text: _levelHorizonText
719
720 readonly property string _levelHorizonText: qsTr("Level Horizon")
721
722 onClicked: {
723 if (controller.accelSetupNeeded) {
724 QGroundControl.showMessageDialog(sensorsPage, _levelHorizonText, qsTr("Accelerometer must be calibrated prior to Level Horizon."))
725 } else {
726 QGroundControl.showMessageDialog(sensorsPage, _levelHorizonText,
727 qsTr("To level the horizon you need to place the vehicle in its level flight position and press Ok."),
728 Dialog.Cancel | Dialog.Ok,
729 function() { controller.levelHorizon() })
730 }
731 }
732 }
733
734 QGCButton {
735 width: _buttonWidth
736 text: qsTr("Gyro")
737 visible: globals.activeVehicle && (globals.activeVehicle.multiRotor | globals.activeVehicle.rover | globals.activeVehicle.sub)
738 onClicked: QGroundControl.showMessageDialog(sensorsPage, qsTr("Calibrate Gyro"),
739 qsTr("For Gyroscope calibration you will need to place your vehicle on a surface and leave it still.\n\nClick Ok to start calibration."),
740 Dialog.Cancel | Dialog.Ok,
741 function() { controller.calibrateGyro() })
742 }
743
744 QGCButton {
745 width: _buttonWidth
746 text: _calibratePressureText
747 onClicked: QGroundControl.showMessageDialog(sensorsPage, _calibratePressureText,
748 qsTr("Pressure calibration will set the %1 to zero at the current pressure reading. %2").arg(_altText).arg(_helpTextFW),
749 Dialog.Cancel | Dialog.Ok,
750 function() { controller.calibratePressure() })
751
752 readonly property string _altText: globals.activeVehicle.sub ? qsTr("depth") : qsTr("altitude")
753 readonly property string _helpTextFW: globals.activeVehicle.fixedWing ? qsTr("To calibrate the airspeed sensor shield it from the wind. Do not touch the sensor or obstruct any holes during the calibration.") : ""
754 readonly property string _calibratePressureText: globals.activeVehicle.fixedWing ? qsTr("Baro/Airspeed") : qsTr("Pressure")
755 }
756
757 QGCButton {
758 width: _buttonWidth
759 text: qsTr("CompassMot")
760 visible: globals.activeVehicle ? globals.activeVehicle.supports.motorInterference : false
761 onClicked: compassMotDialogFactory.open()
762 }
763
764 QGCButton {
765 width: _buttonWidth
766 text: qsTr("Sensor Settings")
767 onClicked: showOrientationsDialog(_calTypeSet)
768 }
769 } // Column - Cal Buttons
770
771 Column {
772 id: nextCancelColumn
773 anchors.topMargin: buttonColumn.spacing
774 anchors.top: buttonColumn.bottom
775 anchors.left: buttonColumn.left
776 spacing: buttonColumn.spacing
777
778 QGCButton {
779 id: nextButton
780 objectName: "sensorsSetup_nextButton"
781 width: _buttonWidth
782 text: qsTr("Next")
783 enabled: false
784 onClicked: controller.nextClicked()
785 }
786
787 QGCButton {
788 id: cancelButton
789 objectName: "sensorsSetup_cancelButton"
790 width: _buttonWidth
791 text: qsTr("Cancel")
792 enabled: false
793 onClicked: controller.cancelCalibration()
794 }
795 }
796 } // QGCFlickable - buttons
797
798 /// Right column - cal area
799 Column {
800 anchors.leftMargin: _margins
801 anchors.top: parent.top
802 anchors.bottom: parent.bottom
803 anchors.left: buttonFlickable.right
804 anchors.right: parent.right
805
806 ProgressBar {
807 id: progressBar
808 objectName: "sensorsSetup_progressBar"
809 anchors.left: parent.left
810 anchors.right: parent.right
811 }
812
813 Item { height: ScreenTools.defaultFontPixelHeight; width: 10 } // spacer
814
815 Item {
816 id: centerPanel
817 width: parent.width
818 height: parent.height - y
819
820 TextArea {
821 id: statusTextArea
822 anchors.fill: parent
823 readOnly: true
824 text: statusTextAreaDefaultText
825 color: qgcPal.text
826 background: Rectangle { color: qgcPal.windowShade }
827 }
828
829 Rectangle {
830 id: orientationCalArea
831 anchors.fill: parent
832 visible: controller.showOrientationCalArea
833 color: qgcPal.windowShade
834
835 QGCLabel {
836 id: orientationCalAreaHelpText
837 anchors.margins: ScreenTools.defaultFontPixelWidth
838 anchors.top: orientationCalArea.top
839 anchors.left: orientationCalArea.left
840 width: parent.width
841 wrapMode: Text.WordWrap
842 font.pointSize: ScreenTools.mediumFontPointSize
843 }
844
845 Flow {
846 anchors.topMargin: ScreenTools.defaultFontPixelWidth
847 anchors.top: orientationCalAreaHelpText.bottom
848 anchors.bottom: parent.bottom
849 anchors.left: parent.left
850 anchors.right: parent.right
851 spacing: ScreenTools.defaultFontPixelWidth
852
853 property real indicatorWidth: (width / 3) - (spacing * 2)
854 property real indicatorHeight: (height / 2) - spacing
855
856 VehicleRotationCal {
857 objectName: "sensorsCal_downSide"
858 width: parent.indicatorWidth
859 height: parent.indicatorHeight
860 visible: controller.orientationCalDownSideVisible
861 calState: sideCalState(controller.orientationCalDownSideDone, controller.orientationCalDownSideInProgress)
862 calInProgressText: controller.orientationCalDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
863 imageSource: "qrc:///qmlimages/VehicleDown.png"
864 }
865 VehicleRotationCal {
866 objectName: "sensorsCal_leftSide"
867 width: parent.indicatorWidth
868 height: parent.indicatorHeight
869 visible: controller.orientationCalLeftSideVisible
870 calState: sideCalState(controller.orientationCalLeftSideDone, controller.orientationCalLeftSideInProgress)
871 calInProgressText: controller.orientationCalLeftSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
872 imageSource: "qrc:///qmlimages/VehicleLeft.png"
873 }
874 VehicleRotationCal {
875 objectName: "sensorsCal_rightSide"
876 width: parent.indicatorWidth
877 height: parent.indicatorHeight
878 visible: controller.orientationCalRightSideVisible
879 calState: sideCalState(controller.orientationCalRightSideDone, controller.orientationCalRightSideInProgress)
880 calInProgressText: controller.orientationCalRightSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
881 imageSource: "qrc:///qmlimages/VehicleRight.png"
882 }
883 VehicleRotationCal {
884 objectName: "sensorsCal_noseDownSide"
885 width: parent.indicatorWidth
886 height: parent.indicatorHeight
887 visible: controller.orientationCalNoseDownSideVisible
888 calState: sideCalState(controller.orientationCalNoseDownSideDone, controller.orientationCalNoseDownSideInProgress)
889 calInProgressText: controller.orientationCalNoseDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
890 imageSource: "qrc:///qmlimages/VehicleNoseDown.png"
891 }
892 VehicleRotationCal {
893 objectName: "sensorsCal_tailDownSide"
894 width: parent.indicatorWidth
895 height: parent.indicatorHeight
896 visible: controller.orientationCalTailDownSideVisible
897 calState: sideCalState(controller.orientationCalTailDownSideDone, controller.orientationCalTailDownSideInProgress)
898 calInProgressText: controller.orientationCalTailDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
899 imageSource: "qrc:///qmlimages/VehicleTailDown.png"
900 }
901 VehicleRotationCal {
902 objectName: "sensorsCal_upsideDownSide"
903 width: parent.indicatorWidth
904 height: parent.indicatorHeight
905 visible: controller.orientationCalUpsideDownSideVisible
906 calState: sideCalState(controller.orientationCalUpsideDownSideDone, controller.orientationCalUpsideDownSideInProgress)
907 calInProgressText: controller.orientationCalUpsideDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
908 imageSource: "qrc:///qmlimages/VehicleUpsideDown.png"
909 }
910 }
911 }
912 } // Item - Cal display area
913 } // Column - cal display
914 } // Row
915 } // Component - sensorsPageComponent
916} // SetupPage