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