Newer
Older
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
SetupPage {
id: sensorsPage
pageComponent: sensorsPageComponent
id: sensorsPageComponent
RowLayout {
width: availableWidth
height: availableHeight
spacing: ScreenTools.defaultFontPixelWidth / 2
// Help text which is shown both in the status text area prior to pressing a cal button and in the
// pre-calibration dialog.
readonly property string orientationHelpSet: "If the orientation is in the direction of flight, select None."
readonly property string orientationHelpCal: "Before calibrating make sure orientation settings are correct. " + orientationHelpSet
readonly property string compassRotationText: "If the compass or GPS module is mounted in flight direction, leave the default value (None)"
readonly property string compassHelp: "For Compass calibration you will need to rotate your vehicle through a number of positions."
readonly property string gyroHelp: "For Gyroscope calibration you will need to place your vehicle on a surface and leave it still."
readonly property string accelHelp: "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."
readonly property string levelHelp: "To level the horizon you need to place the vehicle in its level flight position and press OK."
readonly property string airspeedHelp: "For Airspeed calibration you will need to keep your airspeed sensor out of any wind and then blow across the sensor."
readonly property string statusTextAreaDefaultText: "Start the individual calibration steps by clicking one of the buttons to the left."
// Used to pass help text to the preCalibrationDialog dialog
property string preCalibrationDialogHelp
property string _postCalibrationDialogText
property var _postCalibrationDialogParams
readonly property string _badCompassCalText: "The calibration for Compass %1 appears to be poor. " +
"Check the compass position within your vehicle and re-do the calibration."
readonly property int sideBarH1PointSize: ScreenTools.mediumFontPointSize
readonly property int mainTextH1PointSize: ScreenTools.mediumFontPointSize // Seems to be unused
readonly property int rotationColumnWidth: 250
property bool accelCalNeeded: controller.accelSetupNeeded
property bool compassCalNeeded: controller.compassSetupNeeded
property Fact boardRot: controller.getParameterFact(-1, "AHRS_ORIENTATION")
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
readonly property int _calTypeCompass: 1 ///< Calibrate compass
readonly property int _calTypeAccel: 2 ///< Calibrate accel
readonly property int _calTypeSet: 3 ///< Set orientations only
property bool _orientationsDialogShowCompass: true
property string _orientationDialogHelp: orientationHelpSet
property int _orientationDialogCalType
function showOrientationsDialog(calType) {
var dialogTitle
var buttons = StandardButton.Ok
_orientationDialogCalType = calType
switch (calType) {
case _calTypeCompass:
_orientationsDialogShowCompass = true
_orientationDialogHelp = orientationHelpCal
dialogTitle = qsTr("Calibrate Compass")
buttons |= StandardButton.Cancel
break
case _calTypeAccel:
_orientationsDialogShowCompass = false
_orientationDialogHelp = orientationHelpCal
dialogTitle = qsTr("Calibrate Accelerometer")
buttons |= StandardButton.Cancel
break
case _calTypeSet:
_orientationsDialogShowCompass = true
_orientationDialogHelp = orientationHelpSet
dialogTitle = qsTr("Sensor Settings")
break
}
showDialog(orientationsDialogComponent, dialogTitle, qgcView.showDialogDefaultWidth, buttons)
}
APMSensorParams {
id: sensorParams
factPanelController: controller
}
APMSensorsComponentController {
id: controller
factPanel: sensorsPage.viewPanel
statusLog: statusTextArea
progressBar: progressBar
compassButton: compassButton
accelButton: accelButton
compassMotButton: motorInterferenceButton
calibratePressureButton: calibratePressureButton
nextButton: nextButton
cancelButton: cancelButton
setOrientationsButton: setOrientationsButton
orientationCalAreaHelpText: orientationCalAreaHelpText
property var rgCompassCalFitness: [ controller.compass1CalFitness, controller.compass2CalFitness, controller.compass3CalFitness ]
onResetStatusTextArea: statusLog.text = statusTextAreaDefaultText
onWaitingForCancelChanged: {
if (controller.waitingForCancel) {
showMessage(qsTr("Calibration Cancel"), qsTr("Waiting for Vehicle to response to Cancel. This may take a few seconds."), 0)
} else {
hideDialog()
}
}
onCalibrationComplete: {
switch (calType) {
case APMSensorsComponentController.CalTypeAccel:
showMessage(qsTr("Calibration complete"), qsTr("Accelerometer calibration complete."), StandardButton.Ok)
break
case APMSensorsComponentController.CalTypeOffboardCompass:
showMessage(qsTr("Calibration complete"), qsTr("Compass calibration complete."), StandardButton.Ok)
break
case APMSensorsComponentController.CalTypeOnboardCompass:
showDialog(postOnboardCompassCalibrationComponent, qsTr("Calibration complete"), qgcView.showDialogDefaultWidth, StandardButton.Ok)
break
Component.onCompleted: {
var usingUDP = controller.usingUDPLink()
if (usingUDP) {
showMessage("Sensor Calibration", "Performing sensor calibration over a WiFi connection can be unreliable. If you run into problems try using a direct USB connection instead.", StandardButton.Ok)
QGCPalette { id: qgcPal; colorGroupEnabled: true }
id: singleCompassOnboardResultsComponent
Column {
anchors.left: parent.left
anchors.right: parent.right
spacing: Math.round(ScreenTools.defaultFontPixelHeight / 2)
visible: sensorParams.rgCompassAvailable[index]
property real greenMaxThreshold: 8 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
property real yellowMaxThreshold: 15 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
property real fitnessRange: 25 * (sensorParams.rgCompassExternal[index] ? 1 : 2)
Item {
anchors.left: parent.left
anchors.right: parent.right
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
height: ScreenTools.defaultFontPixelHeight
Row {
id: fitnessRow
anchors.fill: parent
Rectangle {
width: parent.width * (greenMaxThreshold / fitnessRange)
height: parent.height
color: "green"
}
Rectangle {
width: parent.width * ((yellowMaxThreshold - greenMaxThreshold) / fitnessRange)
height: parent.height
color: "yellow"
}
Rectangle {
width: parent.width * ((fitnessRange - yellowMaxThreshold) / fitnessRange)
height: parent.height
color: "red"
}
}
Rectangle {
height: fitnessRow.height * 0.66
width: height
anchors.verticalCenter: fitnessRow.verticalCenter
x: (fitnessRow.width * (Math.min(Math.max(controller.rgCompassCalFitness[index], 0.0), fitnessRange) / fitnessRange)) - (width / 2)
radius: height / 2
color: "white"
border.color: "black"
}
Column {
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.left: parent.left
anchors.right: parent.right
spacing: Math.round(ScreenTools.defaultFontPixelHeight / 4)
QGCLabel {
(sensorParams.rgCompassPrimary[index] ? "(primary" : "(secondary") +
(sensorParams.rgCompassExternalParamAvailable[index] ?
(sensorParams.rgCompassExternal[index] ? ", external" : ", internal" ) :
"") +
")"
}
FactCheckBox {
text: "Use Compass"
fact: sensorParams.rgCompassUseFact[index]
visible: sensorParams.rgCompassUseParamAvailable[index] && !sensorParams.rgCompassPrimary[index]
}
Component {
id: postOnboardCompassCalibrationComponent
QGCViewDialog {
Column {
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight
Repeater {
model: 3
delegate: singleCompassOnboardResultsComponent
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: qsTr("Shown in the indicator bars is the quality of the calibration for each compass.\n\n") +
qsTr("- Green indicates a well functioning compass.\n") +
qsTr("- Yellow indicates a questionable compass or calibration.\n") +
qsTr("- Red indicates a compass which should not be used.\n\n") +
qsTr("YOU MUST REBOOT YOUR VEHICLE AFTER EACH CALIBRATION.")
}
}
}
}
Component {
id: singleCompassSettingsComponent
Column {
spacing: Math.round(ScreenTools.defaultFontPixelHeight / 2)
visible: sensorParams.rgCompassAvailable[index]
QGCLabel {
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
(sensorParams.rgCompassPrimary[index] ? "(primary" : "(secondary") +
(sensorParams.rgCompassExternalParamAvailable[index] ?
(sensorParams.rgCompassExternal[index] ? ", external" : ", internal" ) :
"") +
")"
}
Column {
anchors.margins: ScreenTools.defaultFontPixelWidth * 2
anchors.left: parent.left
spacing: Math.round(ScreenTools.defaultFontPixelHeight / 4)
FactCheckBox {
text: "Use Compass"
fact: sensorParams.rgCompassUseFact[index]
visible: sensorParams.rgCompassUseParamAvailable[index] && !sensorParams.rgCompassPrimary[index]
}
Column {
visible: sensorParams.rgCompassExternal[index] && sensorParams.rgCompassRotParamAvailable[index]
QGCLabel { text: qsTr("Orientation:") }
FactComboBox {
width: rotationColumnWidth
indexModel: false
fact: sensorParams.rgCompassRotFact[index]
Component {
id: orientationsDialogComponent
QGCViewDialog {
id: orientationsDialog
function accept() {
if (_orientationDialogCalType == _calTypeAccel) {
controller.calibrateAccel()
} else if (_orientationDialogCalType == _calTypeCompass) {
controller.calibrateCompass()
orientationsDialog.hideDialog()
}
QGCFlickable {
anchors.fill: parent
contentHeight: columnLayout.height
clip: true
id: columnLayout
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight
width: parent.width
wrapMode: Text.WordWrap
text: _orientationDialogHelp
QGCLabel { text: qsTr("Autopilot Orientation:") }
FactComboBox {
width: rotationColumnWidth
indexModel: false
fact: boardRot
}
Repeater {
model: _orientationsDialogShowCompass ? 3 : 0
delegate: singleCompassSettingsComponent
}
} // Column
} // QGCFlickable
} // QGCViewDialog
} // Component - orientationsDialogComponent
Component {
id: compassMotDialogComponent
QGCViewDialog {
id: compassMotDialog
function accept() {
controller.calibrateMotorInterference()
compassMotDialog.hideDialog()
QGCFlickable {
anchors.fill: parent
contentHeight: columnLayout.height
clip: true
Column {
id: columnLayout
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "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. " +
"CompassMot only works well if you have a battery current monitor because the magnetic interference is linear with current drawn. " +
"It is technically possible to set-up CompassMot using throttle but this is not recommended."
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "Disconnect your props, flip them over and rotate them one position around the frame. " +
"In this configuration they should push the copter down into the ground when the throttle is raised."
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "Secure the copter (perhaps with tape) so that it does not move."
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "Turn on your transmitter and keep throttle at zero."
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: "Click Ok to start CompassMot calibration."
}
} // Column
} // QGCFlickable
} // QGCViewDialog
} // Component - compassMotDialogComponent
Component {
id: levelHorizonDialogComponent
QGCViewDialog {
id: levelHorizonDialog
function accept() {
controller.levelHorizon()
levelHorizonDialog.hideDialog()
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: qsTr("To level the horizon you need to place the vehicle in its level flight position and press Ok.")
}
} // QGCViewDialog
} // Component - levelHorizonDialogComponent
Component {
id: calibratePressureDialogComponent
QGCViewDialog {
id: calibratePressureDialog
function accept() {
controller.calibratePressure()
calibratePressureDialog.hideDialog()
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: qsTr("Pressure calibration will set the depth to zero at the current pressure reading.")
}
} // QGCViewDialog
} // Component - calibratePressureDialogComponent
Column {
spacing: ScreenTools.defaultFontPixelHeight / 2
Layout.alignment: Qt.AlignLeft | Qt.AlignTop
readonly property int buttonWidth: ScreenTools.defaultFontPixelWidth * 15
IndicatorButton {
id: accelButton
width: parent.buttonWidth
text: qsTr("Accelerometer")
indicatorGreen: !accelCalNeeded
onClicked: showOrientationsDialog(_calTypeAccel)
}
IndicatorButton {
id: compassButton
width: parent.buttonWidth
text: qsTr("Compass")
indicatorGreen: !compassCalNeeded
onClicked: {
if (controller.accelSetupNeeded) {
showMessage(qsTr("Calibrate Compass"), qsTr("Accelerometer must be calibrated prior to Compass."), StandardButton.Ok)
} else {
showOrientationsDialog(_calTypeCompass)
}
QGCButton {
id: levelHorizonButton
width: parent.buttonWidth
text: _levelHorizonText
readonly property string _levelHorizonText: qsTr("Level Horizon")
onClicked: {
if (controller.accelSetupNeeded) {
showMessage(_levelHorizonText, qsTr("Accelerometer must be calibrated prior to Level Horizon."), StandardButton.Ok)
} else {
showDialog(levelHorizonDialogComponent, _levelHorizonText, qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
}
QGCButton {
id: calibratePressureButton
width: parent.buttonWidth
text: _calibratePressureText
visible: _activeVehicle ? _activeVehicle.supportsCalibratePressure : false
readonly property string _calibratePressureText: qsTr("Calibrate Pressure")
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
onClicked: {
showDialog(calibratePressureDialogComponent, _calibratePressureText, qgcView.showDialogDefaultWidth, StandardButton.Cancel | StandardButton.Ok)
}
}
QGCButton {
id: motorInterferenceButton
width: parent.buttonWidth
text: qsTr("CompassMot")
onClicked: showDialog(compassMotDialogComponent, qsTr("CompassMot - Compass Motor Interference Calibration"), qgcView.showDialogFullWidth, StandardButton.Cancel | StandardButton.Ok)
}
QGCButton {
id: nextButton
width: parent.buttonWidth
text: qsTr("Next")
enabled: false
onClicked: controller.nextClicked()
}
QGCButton {
id: cancelButton
width: parent.buttonWidth
text: qsTr("Cancel")
enabled: false
onClicked: controller.cancelCalibration()
}
QGCButton {
id: setOrientationsButton
width: parent.buttonWidth
text: qsTr("Sensor Settings")
onClicked: showOrientationsDialog(_calTypeSet)
}
} // Column - Buttons
Column {
anchors.top: parent.top
anchors.bottom: parent.bottom
Layout.fillWidth: true
ProgressBar {
id: progressBar
anchors.left: parent.left
anchors.right: parent.right
}
Item { height: ScreenTools.defaultFontPixelHeight; width: 10 } // spacer
Item {
id: centerPanel
width: parent.width
height: parent.height - y
TextArea {
id: statusTextArea
anchors.fill: parent
readOnly: true
frameVisible: false
text: statusTextAreaDefaultText
style: TextAreaStyle {
textColor: qgcPal.text
backgroundColor: qgcPal.windowShade
}
Rectangle {
id: orientationCalArea
anchors.fill: parent
visible: controller.showOrientationCalArea
color: qgcPal.windowShade
QGCLabel {
id: orientationCalAreaHelpText
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: orientationCalArea.top
anchors.left: orientationCalArea.left
width: parent.width
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.mediumFontPointSize
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
Flow {
anchors.topMargin: ScreenTools.defaultFontPixelWidth
anchors.top: orientationCalAreaHelpText.bottom
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelWidth
property real indicatorWidth: (width / 3) - (spacing * 2)
property real indicatorHeight: (height / 2) - spacing
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalDownSideVisible
calValid: controller.orientationCalDownSideDone
calInProgress: controller.orientationCalDownSideInProgress
calInProgressText: controller.orientationCalDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalDownSideRotate ? "qrc:///qmlimages/VehicleDownRotate.png" : "qrc:///qmlimages/VehicleDown.png"
}
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalUpsideDownSideVisible
calValid: controller.orientationCalUpsideDownSideDone
calInProgress: controller.orientationCalUpsideDownSideInProgress
calInProgressText: controller.orientationCalUpsideDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalUpsideDownSideRotate ? "qrc:///qmlimages/VehicleUpsideDownRotate.png" : "qrc:///qmlimages/VehicleUpsideDown.png"
}
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalNoseDownSideVisible
calValid: controller.orientationCalNoseDownSideDone
calInProgress: controller.orientationCalNoseDownSideInProgress
calInProgressText: controller.orientationCalNoseDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalNoseDownSideRotate ? "qrc:///qmlimages/VehicleNoseDownRotate.png" : "qrc:///qmlimages/VehicleNoseDown.png"
}
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalTailDownSideVisible
calValid: controller.orientationCalTailDownSideDone
calInProgress: controller.orientationCalTailDownSideInProgress
calInProgressText: controller.orientationCalTailDownSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalTailDownSideRotate ? "qrc:///qmlimages/VehicleTailDownRotate.png" : "qrc:///qmlimages/VehicleTailDown.png"
}
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalLeftSideVisible
calValid: controller.orientationCalLeftSideDone
calInProgress: controller.orientationCalLeftSideInProgress
calInProgressText: controller.orientationCalLeftSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalLeftSideRotate ? "qrc:///qmlimages/VehicleLeftRotate.png" : "qrc:///qmlimages/VehicleLeft.png"
}
VehicleRotationCal {
width: parent.indicatorWidth
height: parent.indicatorHeight
visible: controller.orientationCalRightSideVisible
calValid: controller.orientationCalRightSideDone
calInProgress: controller.orientationCalRightSideInProgress
calInProgressText: controller.orientationCalRightSideRotate ? qsTr("Rotate") : qsTr("Hold Still")
imageSource: controller.orientationCalRightSideRotate ? "qrc:///qmlimages/VehicleRightRotate.png" : "qrc:///qmlimages/VehicleRight.png"
}