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