2 ******************************************************************************
4 * @file gyrobiascalibrationmodel.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
6 * @addtogroup board level calibration
8 * @addtogroup ConfigPlugin Config Plugin
10 * @brief Telemetry configuration panel
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "calibration/gyrobiascalibrationmodel.h"
29 #include "calibration/calibrationutils.h"
30 #include "calibration/calibrationuiutils.h"
31 #include "extensionsystem/pluginmanager.h"
33 static const int LEVEL_SAMPLES
= 100;
36 GyroBiasCalibrationModel::GyroBiasCalibrationModel(QObject
*parent
) :
37 QObject(parent
), collectingData(false), m_dirty(false)
39 gyroState
= GyroState::GetInstance(getObjectManager());
42 gyroSensor
= GyroSensor::GetInstance(getObjectManager());
45 revoCalibration
= RevoCalibration::GetInstance(getObjectManager());
46 Q_ASSERT(revoCalibration
);
48 attitudeSettings
= AttitudeSettings::GetInstance(getObjectManager());
49 Q_ASSERT(attitudeSettings
);
51 accelGyroSettings
= AccelGyroSettings::GetInstance(getObjectManager());
52 Q_ASSERT(accelGyroSettings
);
56 void GyroBiasCalibrationModel::start()
58 // reset dirty state to forget previous unsaved runs
61 // configure board for calibration
62 RevoCalibration::DataFields revoCalibrationData
= revoCalibration
->getData();
63 memento
.revoCalibrationData
= revoCalibrationData
;
64 revoCalibrationData
.BiasCorrectedRaw
= RevoCalibration::BIASCORRECTEDRAW_FALSE
;
65 revoCalibration
->setData(revoCalibrationData
);
67 AttitudeSettings::DataFields attitudeSettingsData
= attitudeSettings
->getData();
68 memento
.attitudeSettingsData
= attitudeSettingsData
;
69 // Disable gyro bias correction while calibrating
70 attitudeSettingsData
.BiasCorrectGyro
= AttitudeSettings::BIASCORRECTGYRO_FALSE
;
71 // Zero board rotation
72 attitudeSettingsData
.BoardRotation
[AttitudeSettings::BOARDROTATION_YAW
] = 0;
73 attitudeSettingsData
.BoardRotation
[AttitudeSettings::BOARDROTATION_ROLL
] = 0;
74 attitudeSettingsData
.BoardRotation
[AttitudeSettings::BOARDROTATION_PITCH
] = 0;
75 // Zero board level trim
76 attitudeSettingsData
.BoardLevelTrim
[AttitudeSettings::BOARDLEVELTRIM_ROLL
] = 0;
77 attitudeSettingsData
.BoardLevelTrim
[AttitudeSettings::BOARDLEVELTRIM_PITCH
] = 0;
79 attitudeSettings
->setData(attitudeSettingsData
);
81 UAVObject::Metadata gyroStateMetadata
= gyroState
->getMetadata();
82 memento
.gyroStateMetadata
= gyroStateMetadata
;
83 UAVObject::SetFlightTelemetryUpdateMode(gyroStateMetadata
, UAVObject::UPDATEMODE_PERIODIC
);
84 gyroStateMetadata
.flightTelemetryUpdatePeriod
= 100;
85 gyroState
->setMetadata(gyroStateMetadata
);
87 UAVObject::Metadata gyroSensorMetadata
= gyroSensor
->getMetadata();
88 memento
.gyroSensorMetadata
= gyroSensorMetadata
;
89 UAVObject::SetFlightTelemetryUpdateMode(gyroSensorMetadata
, UAVObject::UPDATEMODE_PERIODIC
);
90 gyroSensorMetadata
.flightTelemetryUpdatePeriod
= 100;
91 gyroSensor
->setMetadata(gyroSensorMetadata
);
97 gyro_state_accum_x
.clear();
98 gyro_state_accum_y
.clear();
99 gyro_state_accum_z
.clear();
103 displayVisualHelp(CALIBRATION_HELPER_PLANE_PREFIX
+ CALIBRATION_HELPER_IMAGE_NED
);
104 displayInstructions(tr("Calibrating the gyroscopes. Keep the vehicle steady..."));
106 // Now connect to the accels and mag updates, gather for 100 samples
107 collectingData
= true;
108 connect(gyroState
, SIGNAL(objectUpdated(UAVObject
*)), this, SLOT(getSample(UAVObject
*)));
109 connect(gyroSensor
, SIGNAL(objectUpdated(UAVObject
*)), this, SLOT(getSample(UAVObject
*)));
113 Updates the gyro bias raw values
115 void GyroBiasCalibrationModel::getSample(UAVObject
*obj
)
117 QMutexLocker
lock(&sensorsUpdateLock
);
119 switch (obj
->getObjID()) {
120 case GyroState::OBJID
:
122 GyroState::DataFields gyroStateData
= gyroState
->getData();
123 gyro_state_accum_x
.append(gyroStateData
.x
);
124 gyro_state_accum_y
.append(gyroStateData
.y
);
125 gyro_state_accum_z
.append(gyroStateData
.z
);
128 case GyroSensor::OBJID
:
130 GyroSensor::DataFields gyroSensorData
= gyroSensor
->getData();
131 gyro_accum_x
.append(gyroSensorData
.x
);
132 gyro_accum_y
.append(gyroSensorData
.y
);
133 gyro_accum_z
.append(gyroSensorData
.z
);
140 // Work out the progress based on whichever has less
141 double p1
= (double)gyro_state_accum_x
.size() / (double)LEVEL_SAMPLES
;
142 double p2
= (double)gyro_accum_y
.size() / (double)LEVEL_SAMPLES
;
143 progressChanged(((p1
> p2
) ? p1
: p2
) * 100);
145 if ((gyro_accum_y
.size() >= LEVEL_SAMPLES
|| (gyro_accum_y
.size() == 0 && gyro_state_accum_y
.size() >= LEVEL_SAMPLES
)) &&
146 collectingData
== true) {
147 collectingData
= false;
150 disconnect(gyroSensor
, SIGNAL(objectUpdated(UAVObject
*)), this, SLOT(getSample(UAVObject
*)));
151 disconnect(gyroState
, SIGNAL(objectUpdated(UAVObject
*)), this, SLOT(getSample(UAVObject
*)));
153 gyroState
->setMetadata(memento
.gyroStateMetadata
);
154 gyroSensor
->setMetadata(memento
.gyroSensorMetadata
);
155 revoCalibration
->setData(memento
.revoCalibrationData
);
156 attitudeSettings
->setData(memento
.attitudeSettingsData
);
159 displayInstructions(tr("Gyroscope calibration completed successfully."), WizardModel::Success
);
160 displayVisualHelp(CALIBRATION_HELPER_IMAGE_EMPTY
);
164 void GyroBiasCalibrationModel::save()
169 // Update biases based on collected data
170 AccelGyroSettings::DataFields accelGyroSettingsData
= accelGyroSettings
->getData();
172 // check whether the board does supports gyroSensor (updates were received)
173 if (gyro_accum_x
.count() < LEVEL_SAMPLES
/ 10) {
174 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_X
] += OpenPilot::CalibrationUtils::listMean(gyro_state_accum_x
);
175 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_Y
] += OpenPilot::CalibrationUtils::listMean(gyro_state_accum_y
);
176 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_Z
] += OpenPilot::CalibrationUtils::listMean(gyro_state_accum_z
);
178 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_X
] += OpenPilot::CalibrationUtils::listMean(gyro_accum_x
);
179 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_Y
] += OpenPilot::CalibrationUtils::listMean(gyro_accum_y
);
180 accelGyroSettingsData
.gyro_bias
[AccelGyroSettings::GYRO_BIAS_Z
] += OpenPilot::CalibrationUtils::listMean(gyro_accum_z
);
183 accelGyroSettings
->setData(accelGyroSettingsData
);
188 UAVObjectManager
*GyroBiasCalibrationModel::getObjectManager()
190 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
191 UAVObjectManager
*objMngr
= pm
->getObject
<UAVObjectManager
>();