Merged in f5soh/librepilot/update_credits (pull request #529)
[librepilot.git] / ground / gcs / src / plugins / config / calibration / levelcalibrationmodel.cpp
blob0d2b31caba93a501eca1905917339fda09e872cd
1 /**
2 ******************************************************************************
4 * @file levelcalibrationmodel.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
6 * @addtogroup board level calibration
7 * @{
8 * @addtogroup ConfigPlugin Config Plugin
9 * @{
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
21 * for more details.
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 "levelcalibrationmodel.h"
29 #include "extensionsystem/pluginmanager.h"
30 #include "calibration/calibrationuiutils.h"
31 #include "uavobjectmanager.h"
33 #include <attitudestate.h>
34 #include <attitudesettings.h>
36 static const int LEVEL_SAMPLES = 100;
38 namespace OpenPilot {
39 LevelCalibrationModel::LevelCalibrationModel(QObject *parent) :
40 QObject(parent), m_dirty(false)
42 attitudeState = AttitudeState::GetInstance(getObjectManager());
43 Q_ASSERT(attitudeState);
45 attitudeSettings = AttitudeSettings::GetInstance(getObjectManager());
46 Q_ASSERT(attitudeSettings);
50 /**
51 * Starts an accelerometer bias calibration.
53 void LevelCalibrationModel::start()
55 memento.attitudeStateMdata = attitudeState->getMetadata();
56 UAVObject::Metadata mdata = attitudeState->getMetadata();
57 UAVObject::SetFlightTelemetryUpdateMode(mdata, UAVObject::UPDATEMODE_PERIODIC);
58 mdata.flightTelemetryUpdatePeriod = 100;
59 attitudeState->setMetadata(mdata);
61 rot_data_pitch = 0;
62 rot_data_roll = 0;
64 // reset dirty state to forget previous unsaved runs
65 m_dirty = false;
67 position = 0;
69 started();
71 // Show instructions and enable controls
72 progressChanged(0);
73 displayInstructions(tr("Place horizontally and press Save Position..."), WizardModel::Prompt);
74 displayVisualHelp(CALIBRATION_HELPER_PLANE_PREFIX + CALIBRATION_HELPER_IMAGE_NED);
75 savePositionEnabledChanged(true);
78 void LevelCalibrationModel::savePosition()
80 QMutexLocker lock(&sensorsUpdateLock);
82 savePositionEnabledChanged(false);
84 rot_accum_pitch.clear();
85 rot_accum_roll.clear();
87 collectingData = true;
89 connect(attitudeState, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(getSample(UAVObject *)));
91 displayInstructions(tr("Hold..."));
94 /**
95 Updates the accel bias raw values
97 void LevelCalibrationModel::getSample(UAVObject *obj)
99 QMutexLocker lock(&sensorsUpdateLock);
101 switch (obj->getObjID()) {
102 case AttitudeState::OBJID:
104 AttitudeState::DataFields attitudeStateData = attitudeState->getData();
105 rot_accum_roll.append(attitudeStateData.Roll);
106 rot_accum_pitch.append(attitudeStateData.Pitch);
107 break;
109 default:
110 Q_ASSERT(0);
113 // Work out the progress based on whichever has less
114 double p1 = (double)rot_accum_roll.size() / (double)LEVEL_SAMPLES;
115 progressChanged(p1 * 100);
117 if (rot_accum_roll.size() >= LEVEL_SAMPLES &&
118 collectingData == true) {
119 collectingData = false;
121 AttitudeState *attitudeState = AttitudeState::GetInstance(getObjectManager());
123 disconnect(attitudeState, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(getSample(UAVObject *)));
125 position++;
126 switch (position) {
127 case 1:
128 rot_data_pitch = OpenPilot::CalibrationUtils::listMean(rot_accum_pitch);
129 rot_data_roll = OpenPilot::CalibrationUtils::listMean(rot_accum_roll);
131 displayInstructions(tr("Leave horizontally, rotate 180° along yaw axis and press Save Position..."), WizardModel::Prompt);
132 displayVisualHelp(CALIBRATION_HELPER_PLANE_PREFIX + CALIBRATION_HELPER_IMAGE_SWD);
134 savePositionEnabledChanged(true);
135 break;
136 case 2:
137 rot_data_pitch += OpenPilot::CalibrationUtils::listMean(rot_accum_pitch);
138 rot_data_pitch /= 2;
139 rot_data_roll += OpenPilot::CalibrationUtils::listMean(rot_accum_roll);
140 rot_data_roll /= 2;
142 attitudeState->setMetadata(memento.attitudeStateMdata);
144 m_dirty = true;
146 stopped();
147 displayVisualHelp(CALIBRATION_HELPER_IMAGE_EMPTY);
148 displayInstructions(tr("Board level calibration completed successfully."), WizardModel::Success);
149 break;
154 void LevelCalibrationModel::save()
156 if (!m_dirty) {
157 return;
159 AttitudeSettings::DataFields attitudeSettingsData = attitudeSettings->getData();
161 // Update the biases based on collected data
162 // "rotate" the board in the opposite direction as the calculated offset
163 attitudeSettingsData.BoardLevelTrim[AttitudeSettings::BOARDLEVELTRIM_PITCH] -= rot_data_pitch;
164 attitudeSettingsData.BoardLevelTrim[AttitudeSettings::BOARDLEVELTRIM_ROLL] -= rot_data_roll;
166 attitudeSettings->setData(attitudeSettingsData);
168 m_dirty = false;
171 UAVObjectManager *LevelCalibrationModel::getObjectManager()
173 ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
174 UAVObjectManager *objMngr = pm->getObject<UAVObjectManager>();
176 Q_ASSERT(objMngr);
177 return objMngr;