Browse Source

Merge pull request #2385 from DonLakeFlyer/APMSensorCal

APM accel calibration
QGC4.4
Don Gagne 9 years ago
parent
commit
1540b469e2
  1. 4
      qgroundcontrol.pro
  2. 2
      qgroundcontrol.qrc
  3. 51
      src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
  4. 5
      src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
  5. 116
      src/AutoPilotPlugins/APM/APMSensorsComponent.cc
  6. 56
      src/AutoPilotPlugins/APM/APMSensorsComponent.h
  7. 565
      src/AutoPilotPlugins/APM/APMSensorsComponent.qml
  8. 469
      src/AutoPilotPlugins/APM/APMSensorsComponentController.cc
  9. 175
      src/AutoPilotPlugins/APM/APMSensorsComponentController.h
  10. 47
      src/AutoPilotPlugins/APM/APMSensorsComponentSummary.qml
  11. 42
      src/FirmwarePlugin/APM/APMFirmwarePlugin.cc
  12. 1
      src/FirmwarePlugin/APM/APMFirmwarePlugin.h
  13. 2
      src/QGCApplication.cc
  14. 12
      src/comm/APMArduCopterMockLink.params
  15. 12
      src/comm/APMArduPlaneMockLink.params

4
qgroundcontrol.pro

@ -554,6 +554,8 @@ HEADERS+= \ @@ -554,6 +554,8 @@ HEADERS+= \
src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.h \
src/AutoPilotPlugins/APM/APMSensorsComponent.h \
src/AutoPilotPlugins/APM/APMSensorsComponentController.h \
src/AutoPilotPlugins/Common/RadioComponentController.h \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \
src/AutoPilotPlugins/PX4/AirframeComponent.h \
@ -601,6 +603,8 @@ SOURCES += \ @@ -601,6 +603,8 @@ SOURCES += \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.cc \
src/AutoPilotPlugins/APM/APMSensorsComponent.cc \
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc \
src/AutoPilotPlugins/Common/RadioComponentController.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \

2
qgroundcontrol.qrc

@ -111,6 +111,8 @@ @@ -111,6 +111,8 @@
<file alias="SensorsComponent.qml">src/AutoPilotPlugins/PX4/SensorsComponent.qml</file>
<file alias="SensorsComponentSummary.qml">src/AutoPilotPlugins/PX4/SensorsComponentSummary.qml</file>
<file alias="SensorsComponentSummaryFixedWing.qml">src/AutoPilotPlugins/PX4/SensorsComponentSummaryFixedWing.qml</file>
<file alias="APMSensorsComponent.qml">src/AutoPilotPlugins/APM/APMSensorsComponent.qml</file>
<file alias="APMSensorsComponentSummary.qml">src/AutoPilotPlugins/APM/APMSensorsComponentSummary.qml</file>
<file alias="SetupParameterEditor.qml">src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">src/VehicleSetup/SetupView.qml</file>
<file alias="test.qml">src/test.qml</file>

51
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
@ -50,19 +50,36 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void) @@ -50,19 +50,36 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
if (parametersReady()) {
_airframeComponent = new APMAirframeComponent(_vehicle, this);
Q_CHECK_PTR(_airframeComponent);
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
if (_airframeComponent) {
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_airframeComponent));
} else {
qWarning() << "new APMAirframeComponent failed";
}
_flightModesComponent = new APMFlightModesComponent(_vehicle, this);
Q_CHECK_PTR(_flightModesComponent);
_flightModesComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));
if (_flightModesComponent) {
_flightModesComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_flightModesComponent));
} else {
qWarning() << "new APMFlightModesComponent failed";
}
_radioComponent = new APMRadioComponent(_vehicle, this);
Q_CHECK_PTR(_radioComponent);
_radioComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_radioComponent));
if (_radioComponent) {
_radioComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_radioComponent));
} else {
qWarning() << "new APMRadioComponent failed";
}
_sensorsComponent = new APMSensorsComponent(_vehicle, this);
if (_sensorsComponent) {
_sensorsComponent->setupTriggerSignals();
_components.append(QVariant::fromValue((VehicleComponent*)_sensorsComponent));
} else {
qWarning() << "new APMSensorsComponent failed";
}
} else {
qWarning() << "Call to vehicleCompenents prior to parametersReady";
}
@ -76,17 +93,17 @@ void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters) @@ -76,17 +93,17 @@ void APMAutoPilotPlugin::_parametersReadyPreChecks(bool missingParameters)
{
#if 0
I believe APM has parameter version stamp, we should check that
// Check for older parameter version set
// FIXME: Firmware is moving to version stamp parameter set. Once that is complete the version stamp
// should be used instead.
if (parameterExists(FactSystem::defaultComponentId, "SENS_GYRO_XOFF")) {
// Check for older parameter version set
// FIXME: Firmware is moving to version stamp parameter set. Once that is complete the version stamp
// should be used instead.
if (parameterExists(FactSystem::defaultComponentId, "SENS_GYRO_XOFF")) {
_incorrectParameterVersion = true;
qgcApp()->showMessage("This version of GroundControl can only perform vehicle setup on a newer version of firmware. "
"Please perform a Firmware Upgrade if you wish to use Vehicle Setup.");
}
}
#endif
_parametersReady = true;
_missingParameters = missingParameters;
emit missingParametersChanged(_missingParameters);

5
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h

@ -27,8 +27,9 @@ @@ -27,8 +27,9 @@
#include "AutoPilotPlugin.h"
#include "Vehicle.h"
#include "APMAirframeComponent.h"
#include "APMRadioComponent.h"
#include "APMFlightModesComponent.h"
#include "APMRadioComponent.h"
#include "APMSensorsComponent.h"
/// This is the APM specific implementation of the AutoPilot class.
class APMAutoPilotPlugin : public AutoPilotPlugin
@ -45,6 +46,7 @@ public: @@ -45,6 +46,7 @@ public:
APMAirframeComponent* airframeComponent (void) { return _airframeComponent; }
APMFlightModesComponent* flightModesComponent(void) { return _flightModesComponent; }
APMRadioComponent* radioComponent (void) { return _radioComponent; }
APMSensorsComponent* sensorsComponent (void) { return _sensorsComponent; }
public slots:
// FIXME: This is public until we restructure AutoPilotPlugin/FirmwarePlugin/Vehicle
@ -57,6 +59,7 @@ private: @@ -57,6 +59,7 @@ private:
APMAirframeComponent* _airframeComponent;
APMFlightModesComponent* _flightModesComponent;
APMRadioComponent* _radioComponent;
APMSensorsComponent* _sensorsComponent;
};
#endif

116
src/AutoPilotPlugins/APM/APMSensorsComponent.cc

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "APMSensorsComponent.h"
#include "APMAutoPilotPlugin.h"
#include "APMSensorsComponentController.h"
// These two list must be kept in sync
APMSensorsComponent::APMSensorsComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent) :
APMComponent(vehicle, autopilot, parent),
_name(tr("Sensors"))
{
}
QString APMSensorsComponent::name(void) const
{
return _name;
}
QString APMSensorsComponent::description(void) const
{
return tr("The Sensors Component allows you to calibrate the sensors within your vehicle. "
"Prior to flight you must calibrate the Magnetometer, Gyroscope and Accelerometer.");
}
QString APMSensorsComponent::iconResource(void) const
{
return "/qmlimages/SensorsComponentIcon.png";
}
bool APMSensorsComponent::requiresSetup(void) const
{
return true;
}
bool APMSensorsComponent::setupComplete(void) const
{
foreach(QString triggerParam, setupCompleteChangedTriggerList()) {
if (_autopilot->getParameterFact(FactSystem::defaultComponentId, triggerParam)->rawValue().toFloat() == 0.0f) {
return false;
}
}
return true;
}
QString APMSensorsComponent::setupStateDescription(void) const
{
const char* stateDescription;
if (requiresSetup()) {
stateDescription = "Requires calibration";
} else {
stateDescription = "Calibrated";
}
return QString(stateDescription);
}
QStringList APMSensorsComponent::setupCompleteChangedTriggerList(void) const
{
QStringList triggers;
triggers << "COMPASS_OFS_X" << "COMPASS_OFS_X" << "COMPASS_OFS_X"
<< "INS_ACCOFFS_X" << "INS_ACCOFFS_Y" << "INS_ACCOFFS_Z";
return triggers;
}
QStringList APMSensorsComponent::paramFilterList(void) const
{
return QStringList();
}
QUrl APMSensorsComponent::setupSource(void) const
{
return QUrl::fromUserInput("qrc:/qml/APMSensorsComponent.qml");
}
QUrl APMSensorsComponent::summaryQmlSource(void) const
{
return QUrl::fromUserInput("qrc:/qml/APMSensorsComponentSummary.qml");
}
QString APMSensorsComponent::prerequisiteSetup(void) const
{
APMAutoPilotPlugin* plugin = dynamic_cast<APMAutoPilotPlugin*>(_autopilot);
Q_ASSERT(plugin);
if (!plugin->airframeComponent()->setupComplete()) {
return plugin->airframeComponent()->name();
}
return QString();
}

56
src/AutoPilotPlugins/APM/APMSensorsComponent.h

@ -0,0 +1,56 @@ @@ -0,0 +1,56 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef APMSensorsComponent_H
#define APMSensorsComponent_H
#include "APMComponent.h"
class APMSensorsComponent : public APMComponent
{
Q_OBJECT
public:
APMSensorsComponent(Vehicle* vehicle, AutoPilotPlugin* autopilot, QObject* parent = NULL);
// Virtuals from APMComponent
virtual QStringList setupCompleteChangedTriggerList(void) const;
// Virtuals from VehicleComponent
virtual QString name(void) const;
virtual QString description(void) const;
virtual QString iconResource(void) const;
virtual bool requiresSetup(void) const;
virtual bool setupComplete(void) const;
virtual QString setupStateDescription(void) const;
virtual QUrl setupSource(void) const;
virtual QStringList paramFilterList(void) const;
virtual QUrl summaryQmlSource(void) const;
virtual QString prerequisiteSetup(void) const;
private:
const QString _name;
QVariantList _summaryItems;
};
#endif

565
src/AutoPilotPlugins/APM/APMSensorsComponent.qml

@ -0,0 +1,565 @@ @@ -0,0 +1,565 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Dialogs 1.2
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
QGCView {
id: rootQGCView
viewPanel: panel
// 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 boardRotationText: "If the autopilot is mounted in flight direction, leave the default value (None)"
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. Most users prefer to do this wirelessly with the telemetry link."
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 above."
// Used to pass what type of calibration is being performed to the preCalibrationDialog
property string preCalibrationDialogType
// Used to pass help text to the preCalibrationDialog dialog
property string preCalibrationDialogHelp
readonly property int sideBarH1PointSize: ScreenTools.mediumFontPixelSize
readonly property int mainTextH1PointSize: ScreenTools.mediumFontPixelSize // Seems to be unused
readonly property int rotationColumnWidth: 250
readonly property var rotations: [
"None",
"Yaw 45",
"Yaw 90",
"Yaw 135",
"Yaw 180",
"Yaw 225",
"Yaw 270",
"Yaw 315",
"Roll 180",
"Roll 180. Yaw 45",
"Roll 180. Yaw 90",
"Roll 180. Yaw 135",
"Pitch 180",
"Roll 180. Yaw 225",
"Roll 180, Yaw 270",
"Roll 180, Yaw 315",
"Roll 90",
"Roll 90, Yaw 45",
"Roll 90, Yaw 90",
"Roll 90, Yaw 135",
"Roll 270",
"Roll 270, Yaw 45",
"Roll 270, Yaw 90",
"Roll 270, Yaw 136",
"Pitch 90",
"Pitch 270",
"Pitch 180, Yaw 90",
"Pitch 180, Yaw 270",
"Roll 90, Pitch 90",
"Roll 180, Pitch 90",
"Roll 270, Pitch 90",
"Roll 90, Pitch 180",
"Roll 270, Pitch 180",
"Roll 90, Pitch 270",
"Roll 180, Pitch 270",
"Roll 270, Pitch 270",
"Roll 90, Pitch 180, Yaw 90",
"Roll 90, Yaw 270",
"Yaw 293, Pitch 68, Roll 90",
]
property Fact cal_mag0_id: controller.getParameterFact(-1, "COMPASS_DEV_ID")
property Fact cal_mag1_id: controller.getParameterFact(-1, "COMPASS_DEV_ID2")
property Fact cal_mag2_id: controller.getParameterFact(-1, "COMPASS_DEV_ID3")
property Fact cal_mag0_rot: controller.getParameterFact(-1, "COMPASS_ORIENT")
property Fact cal_mag1_rot: controller.getParameterFact(-1, "COMPASS_ORIENT2")
property Fact cal_mag2_rot: controller.getParameterFact(-1, "COMPASS_ORIENT3")
property Fact sens_board_rot: controller.getParameterFact(-1, "AHRS_ORIENTATION")
/*
property Fact cal_gyro0_id: controller.getParameterFact(-1, "CAL_GYRO0_ID")
property Fact cal_acc0_id: controller.getParameterFact(-1, "CAL_ACC0_ID")
property Fact sens_board_x_off: controller.getParameterFact(-1, "SENS_BOARD_X_OFF")
property Fact sens_dpres_off: controller.getParameterFact(-1, "SENS_DPRES_OFF")
*/
property Fact ins_accoffs_x: controller.getParameterFact(-1, "INS_ACCOFFS_X")
property Fact ins_accoffs_y: controller.getParameterFact(-1, "INS_ACCOFFS_Y")
property Fact ins_accoffs_z: controller.getParameterFact(-1, "INS_ACCOFFS_Z")
property Fact compass_ofs_x: controller.getParameterFact(-1, "COMPASS_OFS_X")
property Fact compass_ofs_y: controller.getParameterFact(-1, "COMPASS_OFS_Y")
property Fact compass_ofs_z: controller.getParameterFact(-1, "COMPASS_OFS_Z")
property bool accelCalNeeded: ins_accoffs_x.value == 0 && ins_accoffs_y.value == 0 && ins_accoffs_z.value == 0
property bool compassCalNeeded: compass_ofs_x.value == 0 && compass_ofs_y.value == 0 && compass_ofs_y.value == 0
// Id > = signals compass available, rot < 0 signals internal compass
property bool showCompass0Rot: cal_mag0_id.value > 0 && cal_mag0_rot.value >= 0
property bool showCompass1Rot: cal_mag1_id.value > 0 && cal_mag1_rot.value >= 0
property bool showCompass2Rot: cal_mag2_id.value > 0 && cal_mag2_rot.value >= 0
APMSensorsComponentController {
id: controller
factPanel: panel
statusLog: statusTextArea
progressBar: progressBar
compassButton: compassButton
accelButton: accelButton
nextButton: nextButton
cancelButton: cancelButton
orientationCalAreaHelpText: orientationCalAreaHelpText
onResetStatusTextArea: statusLog.text = statusTextAreaDefaultText
onSetCompassRotations: {
if (showCompass0Rot || showCompass1Rot || showCompass2Rot) {
showDialog(compassRotationDialogComponent, "Set Compass Rotation(s)", 50, StandardButton.Ok)
}
}
onWaitingForCancelChanged: {
if (controller.waitingForCancel) {
showMessage("Calibration Cancel", "Waiting for Vehicle to response to Cancel. This may take a few seconds.", 0)
} else {
hideDialog()
}
}
}
QGCPalette { id: qgcPal; colorGroupEnabled: panel.enabled }
Component {
id: preCalibrationDialogComponent
QGCViewDialog {
id: preCalibrationDialog
function accept() {
if (preCalibrationDialogType == "gyro") {
controller.calibrateGyro()
} else if (preCalibrationDialogType == "accel") {
controller.calibrateAccel()
} else if (preCalibrationDialogType == "level") {
controller.calibrateLevel()
} else if (preCalibrationDialogType == "compass") {
controller.calibrateCompass()
} else if (preCalibrationDialogType == "airspeed") {
controller.calibrateAirspeed()
}
preCalibrationDialog.hideDialog()
}
Column {
anchors.fill: parent
spacing: 5
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: preCalibrationDialogHelp
}
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
visible: (preCalibrationDialogType != "airspeed") && (preCalibrationDialogType != "gyro")
text: boardRotationText
}
FactComboBox {
width: rotationColumnWidth
model: rotations
visible: preCalibrationDialogType != "airspeed" && (preCalibrationDialogType != "gyro")
fact: sens_board_rot
}
}
}
}
Component {
id: compassRotationDialogComponent
QGCViewDialog {
id: compassRotationDialog
Column {
anchors.fill: parent
spacing: ScreenTools.defaultFontPixelHeight
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: compassRotationText
}
// Compass 0 rotation
Component {
id: compass0ComponentLabel
QGCLabel {
font.pixelSize: sideBarH1PointSize
text: "External Compass Orientation"
}
}
Component {
id: compass0ComponentCombo
FactComboBox {
id: compass0RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag0_rot
}
}
Loader { sourceComponent: showCompass0Rot ? compass0ComponentLabel : null }
Loader { sourceComponent: showCompass0Rot ? compass0ComponentCombo : null }
// Compass 1 rotation
Component {
id: compass1ComponentLabel
QGCLabel { text: "Compass 1 Orientation" }
}
Component {
id: compass1ComponentCombo
FactComboBox {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag1_rot
}
}
Loader { sourceComponent: showCompass1Rot ? compass1ComponentLabel : null }
Loader { sourceComponent: showCompass1Rot ? compass1ComponentCombo : null }
// Compass 2 rotation
Component {
id: compass2ComponentLabel
QGCLabel { text: "Compass 2 Orientation" }
}
Component {
id: compass2ComponentCombo
FactComboBox {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag2_rot
}
}
Loader { sourceComponent: showCompass2Rot ? compass2ComponentLabel : null }
Loader { sourceComponent: showCompass2Rot ? compass2ComponentCombo : null }
} // Column
} // QGCViewDialog
} // Component - compassRotationDialogComponent
QGCViewPanel {
id: panel
anchors.fill: parent
Column {
anchors.fill: parent
Row {
readonly property int buttonWidth: ScreenTools.defaultFontPixelWidth * 15
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel { text: "Calibrate:"; anchors.baseline: compassButton.baseline }
IndicatorButton {
id: compassButton
width: parent.buttonWidth
text: "Compass - NYI"
indicatorGreen: !compassCalNeeded
onClicked: {
preCalibrationDialogType = "compass"
preCalibrationDialogHelp = compassHelp
showDialog(preCalibrationDialogComponent, "Calibrate Compass", 50, StandardButton.Cancel | StandardButton.Ok)
}
}
IndicatorButton {
id: accelButton
width: parent.buttonWidth
text: "Accelerometer"
indicatorGreen: !accelCalNeeded
onClicked: {
preCalibrationDialogType = "accel"
preCalibrationDialogHelp = accelHelp
showDialog(preCalibrationDialogComponent, "Calibrate Accelerometer", 50, StandardButton.Cancel | StandardButton.Ok)
}
}
QGCButton {
id: nextButton
showBorder: true
text: "Next"
enabled: false
onClicked: controller.nextClicked()
}
QGCButton {
id: cancelButton
showBorder: true
text: "Cancel"
enabled: false
onClicked: controller.cancelCalibration()
}
}
Item { height: ScreenTools.defaultFontPixelHeight; width: 10 } // spacer
ProgressBar {
id: progressBar
width: parent.width - rotationColumnWidth
}
Item { height: ScreenTools.defaultFontPixelHeight; width: 10 } // spacer
Item {
property int calDisplayAreaWidth: parent.width - rotationColumnWidth
width: parent.width
height: parent.height - y
TextArea {
id: statusTextArea
width: parent.calDisplayAreaWidth
height: parent.height
readOnly: true
frameVisible: false
text: statusTextAreaDefaultText
style: TextAreaStyle {
textColor: qgcPal.text
backgroundColor: qgcPal.windowShade
}
}
Rectangle {
id: orientationCalArea
width: parent.calDisplayAreaWidth
height: parent.height
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.pixelSize: ScreenTools.mediumFontPixelSize
}
Flow {
anchors.topMargin: ScreenTools.defaultFontPixelWidth
anchors.top: orientationCalAreaHelpText.bottom
anchors.left: orientationCalAreaHelpText.left
width: parent.width
height: parent.height - orientationCalAreaHelpText.implicitHeight
spacing: ScreenTools.defaultFontPixelWidth
VehicleRotationCal {
visible: controller.orientationCalDownSideVisible
calValid: controller.orientationCalDownSideDone
calInProgress: controller.orientationCalDownSideInProgress
calInProgressText: controller.orientationCalDownSideRotate ? "Rotate" : "Hold Still"
imageSource: controller.orientationCalDownSideRotate ? "qrc:///qmlimages/VehicleDownRotate.png" : "qrc:///qmlimages/VehicleDown.png"
}
VehicleRotationCal {
visible: controller.orientationCalUpsideDownSideVisible
calValid: controller.orientationCalUpsideDownSideDone
calInProgress: controller.orientationCalUpsideDownSideInProgress
calInProgressText: controller.orientationCalUpsideDownSideRotate ? "Rotate" : "Hold Still"
imageSource: "qrc:///qmlimages/VehicleUpsideDown.png"
}
VehicleRotationCal {
visible: controller.orientationCalNoseDownSideVisible
calValid: controller.orientationCalNoseDownSideDone
calInProgress: controller.orientationCalNoseDownSideInProgress
calInProgressText: controller.orientationCalNoseDownSideRotate ? "Rotate" : "Hold Still"
imageSource: controller.orientationCalNoseDownSideRotate ? "qrc:///qmlimages/VehicleNoseDownRotate.png" : "qrc:///qmlimages/VehicleNoseDown.png"
}
VehicleRotationCal {
visible: controller.orientationCalTailDownSideVisible
calValid: controller.orientationCalTailDownSideDone
calInProgress: controller.orientationCalTailDownSideInProgress
calInProgressText: controller.orientationCalTailDownSideRotate ? "Rotate" : "Hold Still"
imageSource: "qrc:///qmlimages/VehicleTailDown.png"
}
VehicleRotationCal {
visible: controller.orientationCalLeftSideVisible
calValid: controller.orientationCalLeftSideDone
calInProgress: controller.orientationCalLeftSideInProgress
calInProgressText: controller.orientationCalLeftSideRotate ? "Rotate" : "Hold Still"
imageSource: controller.orientationCalLeftSideRotate ? "qrc:///qmlimages/VehicleLeftRotate.png" : "qrc:///qmlimages/VehicleLeft.png"
}
VehicleRotationCal {
visible: controller.orientationCalRightSideVisible
calValid: controller.orientationCalRightSideDone
calInProgress: controller.orientationCalRightSideInProgress
calInProgressText: controller.orientationCalRightSideRotate ? "Rotate" : "Hold Still"
imageSource: "qrc:///qmlimages/VehicleRight.png"
}
}
}
Column {
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.left: orientationCalArea.right
x: parent.width - rotationColumnWidth
spacing: ScreenTools.defaultFontPixelWidth
Column {
spacing: ScreenTools.defaultFontPixelWidth
QGCLabel {
font.pixelSize: sideBarH1PointSize
text: "Autopilot Orientation"
}
QGCLabel {
width: parent.width
wrapMode: Text.WordWrap
text: boardRotationText
}
FactComboBox {
id: boardRotationCombo
width: rotationColumnWidth;
model: rotations
fact: sens_board_rot
}
}
Column {
spacing: ScreenTools.defaultFontPixelWidth
// Compass 0 rotation
Component {
id: compass0ComponentLabel2
QGCLabel {
font.pixelSize: sideBarH1PointSize
text: "External Compass Orientation"
}
}
Component {
id: compass0ComponentCombo2
FactComboBox {
id: compass0RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag0_rot
}
}
Loader { sourceComponent: showCompass0Rot ? compass0ComponentLabel2 : null }
Loader { sourceComponent: showCompass0Rot ? compass0ComponentCombo2 : null }
}
Column {
spacing: ScreenTools.defaultFontPixelWidth
// Compass 1 rotation
Component {
id: compass1ComponentLabel2
QGCLabel {
font.pixelSize: sideBarH1PointSize
text: "External Compass 1 Orientation"
}
}
Component {
id: compass1ComponentCombo2
FactComboBox {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag1_rot
}
}
Loader { sourceComponent: showCompass1Rot ? compass1ComponentLabel2 : null }
Loader { sourceComponent: showCompass1Rot ? compass1ComponentCombo2 : null }
}
Column {
spacing: ScreenTools.defaultFontPixelWidth
// Compass 2 rotation
Component {
id: compass2ComponentLabel2
QGCLabel {
font.pixelSize: sidebarH1PointSize
text: "Compass 2 Orientation"
}
}
Component {
id: compass2ComponentCombo2
FactComboBox {
id: compass1RotationCombo
width: rotationColumnWidth
model: rotations
fact: cal_mag2_rot
}
}
Loader { sourceComponent: showCompass2Rot ? compass2ComponentLabel2 : null }
Loader { sourceComponent: showCompass2Rot ? compass2ComponentCombo2 : null }
}
}
}
}
} // QGCViewPanel
} // QGCView

469
src/AutoPilotPlugins/APM/APMSensorsComponentController.cc

@ -0,0 +1,469 @@ @@ -0,0 +1,469 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "APMSensorsComponentController.h"
#include "QGCMAVLink.h"
#include "UAS.h"
#include "QGCApplication.h"
#include <QVariant>
#include <QQmlProperty>
QGC_LOGGING_CATEGORY(APMSensorsComponentControllerLog, "APMSensorsComponentControllerLog")
APMSensorsComponentController::APMSensorsComponentController(void) :
_statusLog(NULL),
_progressBar(NULL),
_compassButton(NULL),
_accelButton(NULL),
_nextButton(NULL),
_cancelButton(NULL),
_showOrientationCalArea(false),
_gyroCalInProgress(false),
_magCalInProgress(false),
_accelCalInProgress(false),
_orientationCalDownSideDone(false),
_orientationCalUpsideDownSideDone(false),
_orientationCalLeftSideDone(false),
_orientationCalRightSideDone(false),
_orientationCalNoseDownSideDone(false),
_orientationCalTailDownSideDone(false),
_orientationCalDownSideVisible(false),
_orientationCalUpsideDownSideVisible(false),
_orientationCalLeftSideVisible(false),
_orientationCalRightSideVisible(false),
_orientationCalNoseDownSideVisible(false),
_orientationCalTailDownSideVisible(false),
_orientationCalDownSideInProgress(false),
_orientationCalUpsideDownSideInProgress(false),
_orientationCalLeftSideInProgress(false),
_orientationCalRightSideInProgress(false),
_orientationCalNoseDownSideInProgress(false),
_orientationCalTailDownSideInProgress(false),
_orientationCalDownSideRotate(false),
_orientationCalUpsideDownSideRotate(false),
_orientationCalLeftSideRotate(false),
_orientationCalRightSideRotate(false),
_orientationCalNoseDownSideRotate(false),
_orientationCalTailDownSideRotate(false),
_waitingForCancel(false)
{
}
/// Appends the specified text to the status log area in the ui
void APMSensorsComponentController::_appendStatusLog(const QString& text)
{
Q_ASSERT(_statusLog);
QVariant returnedValue;
QVariant varText = text;
QMetaObject::invokeMethod(_statusLog,
"append",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, varText));
}
void APMSensorsComponentController::_startLogCalibration(void)
{
_hideAllCalAreas();
connect(_uas, &UASInterface::textMessageReceived, this, &APMSensorsComponentController::_handleUASTextMessage);
_compassButton->setEnabled(false);
_accelButton->setEnabled(false);
_nextButton->setEnabled(true);
_cancelButton->setEnabled(false);
}
void APMSensorsComponentController::_startVisualCalibration(void)
{
_compassButton->setEnabled(false);
_accelButton->setEnabled(false);
_cancelButton->setEnabled(true);
_resetInternalState();
_progressBar->setProperty("value", 0);
}
void APMSensorsComponentController::_resetInternalState(void)
{
_orientationCalDownSideDone = true;
_orientationCalUpsideDownSideDone = true;
_orientationCalLeftSideDone = true;
_orientationCalRightSideDone = true;
_orientationCalTailDownSideDone = true;
_orientationCalNoseDownSideDone = true;
_orientationCalDownSideInProgress = false;
_orientationCalUpsideDownSideInProgress = false;
_orientationCalLeftSideInProgress = false;
_orientationCalRightSideInProgress = false;
_orientationCalNoseDownSideInProgress = false;
_orientationCalTailDownSideInProgress = false;
_orientationCalDownSideRotate = false;
_orientationCalUpsideDownSideRotate = false;
_orientationCalLeftSideRotate = false;
_orientationCalRightSideRotate = false;
_orientationCalNoseDownSideRotate = false;
_orientationCalTailDownSideRotate = false;
emit orientationCalSidesRotateChanged();
emit orientationCalSidesDoneChanged();
emit orientationCalSidesInProgressChanged();
}
void APMSensorsComponentController::_stopCalibration(APMSensorsComponentController::StopCalibrationCode code)
{
disconnect(_uas, &UASInterface::textMessageReceived, this, &APMSensorsComponentController::_handleUASTextMessage);
_compassButton->setEnabled(true);
_accelButton->setEnabled(true);
_nextButton->setEnabled(false);
_cancelButton->setEnabled(false);
if (code == StopCalibrationSuccess) {
_resetInternalState();
_progressBar->setProperty("value", 1);
} else {
_progressBar->setProperty("value", 0);
}
_waitingForCancel = false;
emit waitingForCancelChanged();
_refreshParams();
switch (code) {
case StopCalibrationSuccess:
_orientationCalAreaHelpText->setProperty("text", "Calibration complete");
emit resetStatusTextArea();
if (_magCalInProgress) {
emit setCompassRotations();
}
break;
case StopCalibrationCancelled:
emit resetStatusTextArea();
_hideAllCalAreas();
break;
default:
// Assume failed
_hideAllCalAreas();
qgcApp()->showMessage("Calibration failed. Calibration log will be displayed.");
break;
}
_magCalInProgress = false;
_accelCalInProgress = false;
_gyroCalInProgress = false;
}
void APMSensorsComponentController::calibrateGyro(void)
{
_startLogCalibration();
_uas->startCalibration(UASInterface::StartCalibrationGyro);
}
void APMSensorsComponentController::calibrateCompass(void)
{
_startLogCalibration();
_uas->startCalibration(UASInterface::StartCalibrationMag);
}
void APMSensorsComponentController::calibrateAccel(void)
{
_startLogCalibration();
_uas->startCalibration(UASInterface::StartCalibrationAccel);
}
void APMSensorsComponentController::calibrateLevel(void)
{
_startLogCalibration();
_uas->startCalibration(UASInterface::StartCalibrationLevel);
}
void APMSensorsComponentController::calibrateAirspeed(void)
{
_startLogCalibration();
_uas->startCalibration(UASInterface::StartCalibrationAirspeed);
}
void APMSensorsComponentController::_handleUASTextMessage(int uasId, int compId, int severity, QString text)
{
Q_UNUSED(compId);
Q_UNUSED(severity);
UASInterface* uas = _autopilot->vehicle()->uas();
Q_ASSERT(uas);
if (uasId != uas->getUASID()) {
return;
}
if (text.startsWith("PreArm:") || text.startsWith("EKF") || text.startsWith("Arm") || text.startsWith("Initialising")) {
return;
}
QString anyKey("and press any");
if (text.contains(anyKey)) {
text = text.left(text.indexOf(anyKey)) + "and click Next to continue.";
}
_appendStatusLog(text);
qCDebug(APMSensorsComponentControllerLog) << text << severity;
if (text.contains("Calibration successful")) {
_stopCalibration(StopCalibrationSuccess);
return;
}
if (text.contains("FAILED")) {
_stopCalibration(StopCalibrationFailed);
return;
}
/*
// All calibration messages start with [cal]
QString calPrefix("[cal] ");
if (!text.startsWith(calPrefix)) {
return;
}
text = text.right(text.length() - calPrefix.length());
QString calStartPrefix("calibration started: ");
if (text.startsWith(calStartPrefix)) {
text = text.right(text.length() - calStartPrefix.length());
_startVisualCalibration();
text = parts[1];
if (text == "accel" || text == "mag" || text == "gyro") {
// Reset all progress indication
_orientationCalDownSideDone = false;
_orientationCalUpsideDownSideDone = false;
_orientationCalLeftSideDone = false;
_orientationCalRightSideDone = false;
_orientationCalTailDownSideDone = false;
_orientationCalNoseDownSideDone = false;
_orientationCalDownSideInProgress = false;
_orientationCalUpsideDownSideInProgress = false;
_orientationCalLeftSideInProgress = false;
_orientationCalRightSideInProgress = false;
_orientationCalNoseDownSideInProgress = false;
_orientationCalTailDownSideInProgress = false;
// Reset all visibility
_orientationCalDownSideVisible = false;
_orientationCalUpsideDownSideVisible = false;
_orientationCalLeftSideVisible = false;
_orientationCalRightSideVisible = false;
_orientationCalTailDownSideVisible = false;
_orientationCalNoseDownSideVisible = false;
_orientationCalAreaHelpText->setProperty("text", "Place your vehicle into one of the Incomplete orientations shown below and hold it still");
if (text == "accel") {
_accelCalInProgress = true;
_orientationCalDownSideVisible = true;
_orientationCalUpsideDownSideVisible = true;
_orientationCalLeftSideVisible = true;
_orientationCalRightSideVisible = true;
_orientationCalTailDownSideVisible = true;
_orientationCalNoseDownSideVisible = true;
} else if (text == "mag") {
_magCalInProgress = true;
_orientationCalDownSideVisible = true;
_orientationCalUpsideDownSideVisible = true;
_orientationCalLeftSideVisible = true;
_orientationCalRightSideVisible = true;
_orientationCalTailDownSideVisible = true;
_orientationCalNoseDownSideVisible = true;
} else if (text == "gyro") {
_gyroCalInProgress = true;
_orientationCalDownSideVisible = true;
} else {
Q_ASSERT(false);
}
emit orientationCalSidesDoneChanged();
emit orientationCalSidesVisibleChanged();
emit orientationCalSidesInProgressChanged();
_updateAndEmitShowOrientationCalArea(true);
}
return;
}
if (text.endsWith("orientation detected")) {
QString side = text.section(" ", 0, 0);
qDebug() << "Side started" << side;
if (side == "down") {
_orientationCalDownSideInProgress = true;
if (_magCalInProgress) {
_orientationCalDownSideRotate = true;
}
} else if (side == "up") {
_orientationCalUpsideDownSideInProgress = true;
if (_magCalInProgress) {
_orientationCalUpsideDownSideRotate = true;
}
} else if (side == "left") {
_orientationCalLeftSideInProgress = true;
if (_magCalInProgress) {
_orientationCalLeftSideRotate = true;
}
} else if (side == "right") {
_orientationCalRightSideInProgress = true;
if (_magCalInProgress) {
_orientationCalRightSideRotate = true;
}
} else if (side == "front") {
_orientationCalNoseDownSideInProgress = true;
if (_magCalInProgress) {
_orientationCalNoseDownSideRotate = true;
}
} else if (side == "back") {
_orientationCalTailDownSideInProgress = true;
if (_magCalInProgress) {
_orientationCalTailDownSideRotate = true;
}
}
if (_magCalInProgress) {
_orientationCalAreaHelpText->setProperty("text", "Rotate the vehicle continuously as shown in the diagram until marked as Completed");
} else {
_orientationCalAreaHelpText->setProperty("text", "Hold still in the current orientation");
}
emit orientationCalSidesInProgressChanged();
emit orientationCalSidesRotateChanged();
return;
}
if (text.endsWith("side done, rotate to a different side")) {
QString side = text.section(" ", 0, 0);
qDebug() << "Side finished" << side;
if (side == "down") {
_orientationCalDownSideInProgress = false;
_orientationCalDownSideDone = true;
_orientationCalDownSideRotate = false;
} else if (side == "up") {
_orientationCalUpsideDownSideInProgress = false;
_orientationCalUpsideDownSideDone = true;
} else if (side == "left") {
_orientationCalLeftSideInProgress = false;
_orientationCalLeftSideDone = true;
_orientationCalLeftSideRotate = false;
} else if (side == "right") {
_orientationCalRightSideInProgress = false;
_orientationCalRightSideDone = true;
} else if (side == "front") {
_orientationCalNoseDownSideInProgress = false;
_orientationCalNoseDownSideDone = true;
_orientationCalNoseDownSideRotate = false;
} else if (side == "back") {
_orientationCalTailDownSideInProgress = false;
_orientationCalTailDownSideDone = true;
}
_orientationCalAreaHelpText->setProperty("text", "Place you vehicle into one of the orientations shown below and hold it still");
emit orientationCalSidesInProgressChanged();
emit orientationCalSidesDoneChanged();
emit orientationCalSidesRotateChanged();
return;
}
if (text.startsWith("calibration cancelled")) {
_stopCalibration(_waitingForCancel ? StopCalibrationCancelled : StopCalibrationFailed);
return;
}
*/
}
void APMSensorsComponentController::_refreshParams(void)
{
QStringList fastRefreshList;
fastRefreshList << "COMPASS_OFS_X" << "COMPASS_OFS_X" << "COMPASS_OFS_X"
<< "INS_ACCOFFS_X" << "INS_ACCOFFS_Y" << "INS_ACCOFFS_Z";
foreach (QString paramName, fastRefreshList) {
_autopilot->refreshParameter(FactSystem::defaultComponentId, paramName);
}
// Now ask for all to refresh
_autopilot->refreshParametersPrefix(FactSystem::defaultComponentId, "COMPASS_");
_autopilot->refreshParametersPrefix(FactSystem::defaultComponentId, "INS_");
}
bool APMSensorsComponentController::fixedWing(void)
{
switch (_vehicle->vehicleType()) {
case MAV_TYPE_FIXED_WING:
case MAV_TYPE_VTOL_DUOROTOR:
case MAV_TYPE_VTOL_QUADROTOR:
case MAV_TYPE_VTOL_TILTROTOR:
case MAV_TYPE_VTOL_RESERVED2:
case MAV_TYPE_VTOL_RESERVED3:
case MAV_TYPE_VTOL_RESERVED4:
case MAV_TYPE_VTOL_RESERVED5:
return true;
default:
return false;
}
}
void APMSensorsComponentController::_updateAndEmitShowOrientationCalArea(bool show)
{
_showOrientationCalArea = show;
emit showOrientationCalAreaChanged();
}
void APMSensorsComponentController::_hideAllCalAreas(void)
{
_updateAndEmitShowOrientationCalArea(false);
}
void APMSensorsComponentController::cancelCalibration(void)
{
// The firmware doesn't allow us to cancel calibration. The best we can do is wait
// for it to timeout.
_waitingForCancel = true;
emit waitingForCancelChanged();
_cancelButton->setEnabled(false);
_uas->stopCalibration();
}
void APMSensorsComponentController::nextClicked(void)
{
mavlink_message_t msg;
mavlink_command_ack_t ack;
ack.command = 0;
ack.result = 1;
mavlink_msg_command_ack_encode(qgcApp()->toolbox()->mavlinkProtocol()->getSystemId(), qgcApp()->toolbox()->mavlinkProtocol()->getComponentId(), &msg, &ack);
_vehicle->sendMessage(msg);
}

175
src/AutoPilotPlugins/APM/APMSensorsComponentController.h

@ -0,0 +1,175 @@ @@ -0,0 +1,175 @@
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef APMSensorsComponentController_H
#define APMSensorsComponentController_H
#include <QObject>
#include "UASInterface.h"
#include "FactPanelController.h"
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(APMSensorsComponentControllerLog)
/// Sensors Component MVC Controller for SensorsComponent.qml.
class APMSensorsComponentController : public FactPanelController
{
Q_OBJECT
public:
APMSensorsComponentController(void);
Q_PROPERTY(bool fixedWing READ fixedWing CONSTANT)
Q_PROPERTY(QQuickItem* statusLog MEMBER _statusLog)
Q_PROPERTY(QQuickItem* progressBar MEMBER _progressBar)
Q_PROPERTY(QQuickItem* compassButton MEMBER _compassButton)
Q_PROPERTY(QQuickItem* accelButton MEMBER _accelButton)
Q_PROPERTY(QQuickItem* nextButton MEMBER _nextButton)
Q_PROPERTY(QQuickItem* cancelButton MEMBER _cancelButton)
Q_PROPERTY(QQuickItem* orientationCalAreaHelpText MEMBER _orientationCalAreaHelpText)
Q_PROPERTY(bool showOrientationCalArea MEMBER _showOrientationCalArea NOTIFY showOrientationCalAreaChanged)
Q_PROPERTY(bool orientationCalDownSideDone MEMBER _orientationCalDownSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalUpsideDownSideDone MEMBER _orientationCalUpsideDownSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalLeftSideDone MEMBER _orientationCalLeftSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalRightSideDone MEMBER _orientationCalRightSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalNoseDownSideDone MEMBER _orientationCalNoseDownSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalTailDownSideDone MEMBER _orientationCalTailDownSideDone NOTIFY orientationCalSidesDoneChanged)
Q_PROPERTY(bool orientationCalDownSideVisible MEMBER _orientationCalDownSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalUpsideDownSideVisible MEMBER _orientationCalUpsideDownSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalLeftSideVisible MEMBER _orientationCalLeftSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalRightSideVisible MEMBER _orientationCalRightSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalNoseDownSideVisible MEMBER _orientationCalNoseDownSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalTailDownSideVisible MEMBER _orientationCalTailDownSideVisible NOTIFY orientationCalSidesVisibleChanged)
Q_PROPERTY(bool orientationCalDownSideInProgress MEMBER _orientationCalDownSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalUpsideDownSideInProgress MEMBER _orientationCalUpsideDownSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalLeftSideInProgress MEMBER _orientationCalLeftSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalRightSideInProgress MEMBER _orientationCalRightSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalNoseDownSideInProgress MEMBER _orientationCalNoseDownSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalTailDownSideInProgress MEMBER _orientationCalTailDownSideInProgress NOTIFY orientationCalSidesInProgressChanged)
Q_PROPERTY(bool orientationCalDownSideRotate MEMBER _orientationCalDownSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool orientationCalUpsideDownSideRotate MEMBER _orientationCalUpsideDownSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool orientationCalLeftSideRotate MEMBER _orientationCalLeftSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool orientationCalRightSideRotate MEMBER _orientationCalRightSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool orientationCalNoseDownSideRotate MEMBER _orientationCalNoseDownSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool orientationCalTailDownSideRotate MEMBER _orientationCalTailDownSideRotate NOTIFY orientationCalSidesRotateChanged)
Q_PROPERTY(bool waitingForCancel MEMBER _waitingForCancel NOTIFY waitingForCancelChanged)
Q_INVOKABLE void calibrateCompass(void);
Q_INVOKABLE void calibrateGyro(void);
Q_INVOKABLE void calibrateAccel(void);
Q_INVOKABLE void calibrateLevel(void);
Q_INVOKABLE void calibrateAirspeed(void);
Q_INVOKABLE void cancelCalibration(void);
Q_INVOKABLE void nextClicked(void);
bool fixedWing(void);
signals:
void showGyroCalAreaChanged(void);
void showOrientationCalAreaChanged(void);
void orientationCalSidesDoneChanged(void);
void orientationCalSidesVisibleChanged(void);
void orientationCalSidesInProgressChanged(void);
void orientationCalSidesRotateChanged(void);
void resetStatusTextArea(void);
void waitingForCancelChanged(void);
void setCompassRotations(void);
private slots:
void _handleUASTextMessage(int uasId, int compId, int severity, QString text);
private:
void _startLogCalibration(void);
void _startVisualCalibration(void);
void _appendStatusLog(const QString& text);
void _refreshParams(void);
void _hideAllCalAreas(void);
void _resetInternalState(void);
enum StopCalibrationCode {
StopCalibrationSuccess,
StopCalibrationFailed,
StopCalibrationCancelled
};
void _stopCalibration(StopCalibrationCode code);
void _updateAndEmitShowOrientationCalArea(bool show);
QQuickItem* _statusLog;
QQuickItem* _progressBar;
QQuickItem* _compassButton;
QQuickItem* _accelButton;
QQuickItem* _nextButton;
QQuickItem* _cancelButton;
QQuickItem* _orientationCalAreaHelpText;
bool _showGyroCalArea;
bool _showOrientationCalArea;
bool _gyroCalInProgress;
bool _magCalInProgress;
bool _accelCalInProgress;
bool _orientationCalDownSideDone;
bool _orientationCalUpsideDownSideDone;
bool _orientationCalLeftSideDone;
bool _orientationCalRightSideDone;
bool _orientationCalNoseDownSideDone;
bool _orientationCalTailDownSideDone;
bool _orientationCalDownSideVisible;
bool _orientationCalUpsideDownSideVisible;
bool _orientationCalLeftSideVisible;
bool _orientationCalRightSideVisible;
bool _orientationCalNoseDownSideVisible;
bool _orientationCalTailDownSideVisible;
bool _orientationCalDownSideInProgress;
bool _orientationCalUpsideDownSideInProgress;
bool _orientationCalLeftSideInProgress;
bool _orientationCalRightSideInProgress;
bool _orientationCalNoseDownSideInProgress;
bool _orientationCalTailDownSideInProgress;
bool _orientationCalDownSideRotate;
bool _orientationCalUpsideDownSideRotate;
bool _orientationCalLeftSideRotate;
bool _orientationCalRightSideRotate;
bool _orientationCalNoseDownSideRotate;
bool _orientationCalTailDownSideRotate;
bool _waitingForCancel;
static const int _supportedFirmwareCalVersion = 2;
};
#endif

47
src/AutoPilotPlugins/APM/APMSensorsComponentSummary.qml

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
/*
IMPORTANT NOTE: Any changes made here must also be made to SensorsComponentSummary.qml
*/
FactPanel {
id: panel
anchors.fill: parent
color: qgcPal.windowShadeDark
QGCPalette { id: qgcPal; colorGroupEnabled: enabled }
FactPanelController { id: controller; factPanel: panel }
property Fact ins_accoffs_x: controller.getParameterFact(-1, "INS_ACCOFFS_X")
property Fact ins_accoffs_y: controller.getParameterFact(-1, "INS_ACCOFFS_Y")
property Fact ins_accoffs_z: controller.getParameterFact(-1, "INS_ACCOFFS_Z")
property Fact compass_ofs_x: controller.getParameterFact(-1, "COMPASS_OFS_X")
property Fact compass_ofs_y: controller.getParameterFact(-1, "COMPASS_OFS_Y")
property Fact compass_ofs_z: controller.getParameterFact(-1, "COMPASS_OFS_Z")
property bool accelCalNeeded: ins_accoffs_x.value == 0 && ins_accoffs_y.value == 0 && ins_accoffs_z.value == 0
property bool compassCalNeeded: compass_ofs_x.value == 0 && compass_ofs_y.value == 0 && compass_ofs_y.value == 0
Column {
anchors.fill: parent
anchors.margins: 8
VehicleSummaryRow {
labelText: "Compass:"
valueText: compassCalNeeded ? "Setup required" : "Ready"
}
VehicleSummaryRow {
labelText: "Accelerometer:"
valueText: accelCalNeeded ? "Setup required" : "Ready"
}
}
}

42
src/FirmwarePlugin/APM/APMFirmwarePlugin.cc

@ -292,22 +292,34 @@ void APMFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message) @@ -292,22 +292,34 @@ void APMFirmwarePlugin::adjustMavlinkMessage(mavlink_message_t* message)
mavlink_msg_param_set_encode(message->sysid, message->compid, message, &paramSet);
}
if (message->msgid == MAVLINK_MSG_ID_STATUSTEXT)
{
if (!_firmwareVersion.isValid()) {
if (message->msgid == MAVLINK_MSG_ID_STATUSTEXT) {
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
// APM user facing calibration messages come through as high severity, we need to parse them out
// and lower the severity on them so that they don't pop in the users face.
if (!_firmwareVersion.isValid() || statusText.severity < MAV_SEVERITY_NOTICE) {
QByteArray b;
b.resize(MAVLINK_MSG_STATUSTEXT_FIELD_TEXT_LEN+1);
mavlink_msg_statustext_get_text(message, b.data());
// Ensure NUL-termination
b[b.length()-1] = '\0';
QString text = QString(b);
qCDebug(APMFirmwarePluginLog) << text;
// if don't know firmwareVersion yet, try and see this message contains it
if (text.contains(APM_COPTER_REXP) || text.contains(APM_PLANE_REXP) || text.contains(APM_ROVER_REXP)) {
// found version string
_firmwareVersion = APMFirmwareVersion(text);
_textSeverityAdjustmentNeeded = _isTextSeverityAdjustmentNeeded(_firmwareVersion);
QString messageText = QString(b);
qCDebug(APMFirmwarePluginLog) << messageText;
if (!_firmwareVersion.isValid()) {
// if don't know firmwareVersion yet, try and see if this message contains it
if (messageText.contains(APM_COPTER_REXP) || messageText.contains(APM_PLANE_REXP) || messageText.contains(APM_ROVER_REXP)) {
// found version string
_firmwareVersion = APMFirmwareVersion(messageText);
_textSeverityAdjustmentNeeded = _isTextSeverityAdjustmentNeeded(_firmwareVersion);
}
}
if (messageText.contains("Place vehicle") || messageText.contains("Calibration successful")) {
_adjustCalibrationMessageSeverity(message);
return;
}
}
@ -362,6 +374,14 @@ void APMFirmwarePlugin::_adjustSeverity(mavlink_message_t* message) const @@ -362,6 +374,14 @@ void APMFirmwarePlugin::_adjustSeverity(mavlink_message_t* message) const
mavlink_msg_statustext_encode(message->sysid, message->compid, message, &statusText);
}
void APMFirmwarePlugin::_adjustCalibrationMessageSeverity(mavlink_message_t* message) const
{
mavlink_statustext_t statusText;
mavlink_msg_statustext_decode(message, &statusText);
statusText.severity = MAV_SEVERITY_INFO;
mavlink_msg_statustext_encode(message->sysid, message->compid, message, &statusText);
}
void APMFirmwarePlugin::initializeVehicle(Vehicle* vehicle)
{
// Streams are not started automatically on APM stack

1
src/FirmwarePlugin/APM/APMFirmwarePlugin.h

@ -100,6 +100,7 @@ protected: @@ -100,6 +100,7 @@ protected:
private:
void _adjustSeverity(mavlink_message_t* message) const;
void _adjustCalibrationMessageSeverity(mavlink_message_t* message) const;
static bool _isTextSeverityAdjustmentNeeded(const APMFirmwareVersion& firmwareVersion);
APMFirmwareVersion _firmwareVersion;

2
src/QGCApplication.cc

@ -65,6 +65,7 @@ @@ -65,6 +65,7 @@
#include "APMFlightModesComponentController.h"
#include "AirframeComponentController.h"
#include "SensorsComponentController.h"
#include "APMSensorsComponentController.h"
#include "PowerComponentController.h"
#include "RadioComponentController.h"
#include "ScreenToolsController.h"
@ -381,6 +382,7 @@ void QGCApplication::_initCommon(void) @@ -381,6 +382,7 @@ void QGCApplication::_initCommon(void)
qmlRegisterType<APMFlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "APMFlightModesComponentController");
qmlRegisterType<FlightModesComponentController> ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController");
qmlRegisterType<AirframeComponentController> ("QGroundControl.Controllers", 1, 0, "AirframeComponentController");
qmlRegisterType<APMSensorsComponentController> ("QGroundControl.Controllers", 1, 0, "APMSensorsComponentController");
qmlRegisterType<SensorsComponentController> ("QGroundControl.Controllers", 1, 0, "SensorsComponentController");
qmlRegisterType<PowerComponentController> ("QGroundControl.Controllers", 1, 0, "PowerComponentController");
qmlRegisterType<RadioComponentController> ("QGroundControl.Controllers", 1, 0, "RadioComponentController");

12
src/comm/APMArduCopterMockLink.params

@ -97,9 +97,9 @@ @@ -97,9 +97,9 @@
1 1 COMPASS_OFS3_X 0 9
1 1 COMPASS_OFS3_Y 0 9
1 1 COMPASS_OFS3_Z 0 9
1 1 COMPASS_OFS_X 0 9
1 1 COMPASS_OFS_Y 0 9
1 1 COMPASS_OFS_Z 0 9
1 1 COMPASS_OFS_X 10 9
1 1 COMPASS_OFS_Y 10 9
1 1 COMPASS_OFS_Z 10 9
1 1 COMPASS_ORIENT 0 2
1 1 COMPASS_ORIENT2 0 2
1 1 COMPASS_ORIENT3 0 2
@ -200,9 +200,9 @@ @@ -200,9 +200,9 @@
1 1 INS_ACC3SCAL_Y 0 9
1 1 INS_ACC3SCAL_Z 0 9
1 1 INS_ACCEL_FILTER 20 2
1 1 INS_ACCOFFS_X 0 9
1 1 INS_ACCOFFS_Y 0 9
1 1 INS_ACCOFFS_Z 0 9
1 1 INS_ACCOFFS_X 10 9
1 1 INS_ACCOFFS_Y 10 9
1 1 INS_ACCOFFS_Z 10 9
1 1 INS_ACCSCAL_X 1 9
1 1 INS_ACCSCAL_Y 1 9
1 1 INS_ACCSCAL_Z 1 9

12
src/comm/APMArduPlaneMockLink.params

@ -121,9 +121,9 @@ @@ -121,9 +121,9 @@
1 1 COMPASS_OFS3_X 0 9
1 1 COMPASS_OFS3_Y 0 9
1 1 COMPASS_OFS3_Z 0 9
1 1 COMPASS_OFS_X 0 9
1 1 COMPASS_OFS_Y 0 9
1 1 COMPASS_OFS_Z 0 9
1 1 COMPASS_OFS_X 10 9
1 1 COMPASS_OFS_Y 10 9
1 1 COMPASS_OFS_Z 10 9
1 1 COMPASS_ORIENT 0 2
1 1 COMPASS_ORIENT2 0 2
1 1 COMPASS_ORIENT3 0 2
@ -244,9 +244,9 @@ @@ -244,9 +244,9 @@
1 1 INS_ACC3SCAL_Y 0 9
1 1 INS_ACC3SCAL_Z 0 9
1 1 INS_ACCEL_FILTER 20 2
1 1 INS_ACCOFFS_X 0 9
1 1 INS_ACCOFFS_Y 0 9
1 1 INS_ACCOFFS_Z 0 9
1 1 INS_ACCOFFS_X 10 9
1 1 INS_ACCOFFS_Y 10 9
1 1 INS_ACCOFFS_Z 10 9
1 1 INS_ACCSCAL_X 1 9
1 1 INS_ACCSCAL_Y 1 9
1 1 INS_ACCSCAL_Z 1 9

Loading…
Cancel
Save