1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-03-15 07:29:15 +01:00

OP-1150 UI for thermal calibration: Samples acquisition and rough progressbar working

This commit is contained in:
Alessio Morale 2014-01-16 23:09:08 +01:00
parent 0a43971dc1
commit 847c3327eb
10 changed files with 404 additions and 84 deletions

View File

@ -1,10 +1,10 @@
/**
******************************************************************************
*
* @file thermalcalibrationtransitions.h
* @file boardsetuptransition.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
*
* @brief State transitions used to implement thermal calibration
* @brief
* @see The GNU Public License (GPL) Version 3
* @defgroup
* @{
@ -26,8 +26,8 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef THERMALCALIBRATIONTRANSITIONS_H
#define THERMALCALIBRATIONTRANSITIONS_H
#ifndef BOARDSETUPTRANSITION_H
#define BOARDSETUPTRANSITION_H
#include <QSignalTransition>
#include <QEventTransition>
@ -54,7 +54,7 @@ public:
}
QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent *>(e);
// check wether status stave was successful and retry if not
// check wether status save was successful and retry if not
qDebug() << "BoardSetupTransition::eventTest - " << se->arguments().at(0).toBool();
if (se->arguments().at(0).toBool()) {
return true;
@ -80,4 +80,4 @@ private:
};
#endif // THERMALCALIBRATIONTRANSITIONS_H
#endif // BOARDSETUPTRANSITION_H

View File

@ -0,0 +1,64 @@
/**
******************************************************************************
*
* @file thermalcalibrationtransitions.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
*
* @brief State transitions used to implement thermal calibration
* @see The GNU Public License (GPL) Version 3
* @defgroup
* @{
*
*****************************************************************************/
/*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef DATAACQUISITIONTRANSITION_H
#define DATAACQUISITIONTRANSITION_H
#include <QSignalTransition>
#include <QEventTransition>
#include "thermalcalibrationhelper.h"
class DataAcquisitionTransition : public QSignalTransition {
Q_OBJECT
public:
DataAcquisitionTransition(ThermalCalibrationHelper *helper, QState *currentState, QState *targetState)
: QSignalTransition(helper, SIGNAL(collectionCompleted())),
m_helper(helper)
{
QObject::connect(currentState, SIGNAL(entered()), this, SLOT(enterState()));
setTargetState(targetState);
}
virtual void onTransition(QEvent *e)
{
qDebug() << "DataAcquisitionTransition::collectionCompleted";
}
public slots:
void enterState()
{
qDebug() << "DataAcquisitionTransition::enterStatus";
m_helper->initAcquisition();
}
private:
ThermalCalibrationHelper *m_helper;
};
#endif // DATAACQUISITIONTRANSITION_H

View File

@ -37,7 +37,6 @@ ThermalCalibrationHelper::ThermalCalibrationHelper(QObject *parent) :
* @brief Change board settings to prepare it for calibration
* @return
*/
bool ThermalCalibrationHelper::setupBoardForCalibration()
{
qDebug() << "setupBoardForCalibration";
@ -72,7 +71,6 @@ bool ThermalCalibrationHelper::setupBoardForCalibration()
return true;
}
/**
* @brief Save board status to be later restored using restoreBoardStatus
* @return
@ -115,35 +113,6 @@ bool ThermalCalibrationHelper::saveBoardInitialSettings()
return true;
}
void ThermalCalibrationHelper::setupBoard()
{
if (setupBoardForCalibration()) {
emit setupBoardCompleted(true);
} else {
emit setupBoardCompleted(false);
}
}
void ThermalCalibrationHelper::statusRestore()
{
if (isBoardInitialSettingsSaved() && restoreInitialSettings()) {
clearBoardInitialSettingsSaved();
emit statusRestoreCompleted(true);
} else {
emit statusRestoreCompleted(false);
}
}
void ThermalCalibrationHelper::statusSave()
{
// prevent saving multiple times
if (!isBoardInitialSettingsSaved() && saveBoardInitialSettings()) {
emit statusSaveCompleted(true);
} else {
emit statusSaveCompleted(false);
}
}
/**
* @brief restore board settings from status saved calling saveBoardStatus
* @return true if success
@ -181,6 +150,195 @@ bool ThermalCalibrationHelper::restoreInitialSettings()
return true;
}
/* Methods called from transitions */
void ThermalCalibrationHelper::setupBoard()
{
setProcessPercentage(ProcessPercentageSetupBoard);
if (setupBoardForCalibration()) {
emit setupBoardCompleted(true);
} else {
emit setupBoardCompleted(false);
}
}
void ThermalCalibrationHelper::statusRestore()
{
if (isBoardInitialSettingsSaved() && restoreInitialSettings()) {
clearBoardInitialSettingsSaved();
emit statusRestoreCompleted(true);
} else {
emit statusRestoreCompleted(false);
}
}
void ThermalCalibrationHelper::statusSave()
{
setProcessPercentage(ProcessPercentageSaveSettings);
// prevent saving multiple times
if (!isBoardInitialSettingsSaved() && saveBoardInitialSettings()) {
emit statusSaveCompleted(true);
} else {
emit statusSaveCompleted(false);
}
}
void ThermalCalibrationHelper::initAcquisition()
{
setProcessPercentage(ProcessPercentageBaseAcquisition);
QMutexLocker lock(&sensorsUpdateLock);
m_targetduration = 0;
m_gradient = 0.0f;
m_initialGradient = m_gradient;
// Clear all samples
m_accelSamples.clear();
m_gyroSamples.clear();
m_baroSamples.clear();
m_magSamples.clear();
// retrieve current temperature/time as initial checkpoint.
m_lastCheckpointTime = QTime::currentTime();
m_startTime = m_lastCheckpointTime;
BaroSensor *baroSensor = BaroSensor::GetInstance(getObjectManager());
Q_ASSERT(baroSensor);
m_lastCheckpointTemp = baroSensor->getTemperature();
m_gradient = 0;
connectUAVOs();
}
void ThermalCalibrationHelper::collectSample(UAVObject *sample)
{
QMutexLocker lock(&sensorsUpdateLock);
switch (sample->getObjID()) {
case AccelSensor::OBJID:
{
AccelSensor *reading = AccelSensor::GetInstance(getObjectManager());
Q_ASSERT(reading);
m_accelSamples.append(reading->getData());
break;
}
case GyroSensor::OBJID:
{
GyroSensor *reading = GyroSensor::GetInstance(getObjectManager());
Q_ASSERT(reading);
m_gyroSamples.append(reading->getData());
break;
}
case BaroSensor::OBJID:
{
BaroSensor *reading = BaroSensor::GetInstance(getObjectManager());
Q_ASSERT(reading);
m_baroSamples.append(reading->getData());
// this is needed as temperature is low pass filtered
m_temperature = reading->getTemperature();
updateTemp(m_temperature);
break;
}
case MagSensor::OBJID:
{
MagSensor *reading = MagSensor::GetInstance(getObjectManager());
Q_ASSERT(reading);
m_magSamples.append(reading->getData());
break;
}
default:
{
qDebug() << " unexpected object " << sample->getObjID();
}
}
}
void ThermalCalibrationHelper::calculate()
{
setProcessPercentage(ProcessPercentageBaseCalculation);
}
/* helper methods */
void ThermalCalibrationHelper::updateTemp(float temp)
{
int elapsed = m_startTime.secsTo(QTime::currentTime());
int secondsSinceLastCheck = m_lastCheckpointTime.secsTo(QTime::currentTime());
m_temperature = m_temperature * 0.9f + temp * 0.1f;
emit temperatureChanged(m_temperature);
if (secondsSinceLastCheck > TimeBetweenCheckpoints) {
// gradient is expressed in °C/min
float gradient = 60.0 * (m_temperature - m_lastCheckpointTemp) / (float)secondsSinceLastCheck;
m_gradient = gradient;
emit gradientChanged(gradient);
qDebug() << "Temp Gradient " << gradient << " Elapsed" << elapsed;
m_lastCheckpointTime = QTime::currentTime();
m_lastCheckpointTemp = m_temperature;
}
// at least a checkpoint has been reached
if (elapsed > TimeBetweenCheckpoints) {
// .1 is a "very" small value in this case thats > 0
if (m_initialGradient < .1 && m_gradient > .1) {
m_initialGradient = m_gradient;
}
if (m_gradient < TargetGradient) {
endAcquisition();
}
if (m_targetduration != 0) {
int tmp = ((ProcessPercentageBaseCalculation - ProcessPercentageBaseAcquisition)
* elapsed) / m_targetduration;
tmp = tmp > ProcessPercentageBaseCalculation - 5 ? ProcessPercentageBaseCalculation - 5 : tmp;
setProcessPercentage(tmp);
} else if (m_gradient > .1 && m_initialGradient / 2.0f > m_gradient) {
qDebug() << "M_gradient " << m_gradient << " Elapsed" << elapsed << " m_initialGradient" << m_initialGradient;
// make a rough estimation of the time needed
m_targetduration = elapsed * 5;
}
}
}
void ThermalCalibrationHelper::endAcquisition()
{
// this is called from the collectSample that already has the lock
// QMutexLocker lock(&sensorsUpdateLock);
disconnectUAVOs();
emit collectionCompleted();
}
void ThermalCalibrationHelper::connectUAVOs()
{
AccelSensor *accel = AccelSensor::GetInstance(getObjectManager());
connect(accel, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
GyroSensor *gyro = GyroSensor::GetInstance(getObjectManager());
connect(gyro, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
BaroSensor *baro = BaroSensor::GetInstance(getObjectManager());
connect(baro, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
MagSensor *mag = MagSensor::GetInstance(getObjectManager());
connect(mag, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
}
void ThermalCalibrationHelper::disconnectUAVOs()
{
AccelSensor *accel = AccelSensor::GetInstance(getObjectManager());
disconnect(accel, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
GyroSensor *gyro = GyroSensor::GetInstance(getObjectManager());
disconnect(gyro, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
BaroSensor *baro = BaroSensor::GetInstance(getObjectManager());
disconnect(baro, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
MagSensor *mag = MagSensor::GetInstance(getObjectManager());
disconnect(mag, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(collectSample(UAVObject *)));
}
void ThermalCalibrationHelper::setMetadataForCalibration(UAVDataObject *uavo)
{
Q_ASSERT(uavo);

View File

@ -30,7 +30,7 @@
#include <QObject>
#include <QtCore>
#include <QTime>
#include "uavobjectmanager.h"
#include <uavobject.h>
#include <uavobjectmanager.h>
@ -41,6 +41,7 @@
#include <accelsensor.h>
#include <gyrosensor.h>
#include <barosensor.h>
#include <magsensor.h>
#include "accelgyrosettings.h"
@ -49,7 +50,6 @@
#include <revocalibration.h>
#include <revosettings.h>
typedef struct {
// this is not needed for revo, but should for CC/CC3D
// AccelGyroSettings::DataFields accelGyroSettings;
@ -64,38 +64,108 @@ class ThermalCalibrationHelper : public QObject {
Q_OBJECT
public:
explicit ThermalCalibrationHelper(QObject *parent = 0);
float temperature()
{
return m_temperature;
}
float gradient()
{
return m_gradient;
}
int processPercentage()
{
return m_processPercentage;
}
signals:
void statusRestoreCompleted(bool succesful);
void statusSaveCompleted(bool succesful);
void setupBoardCompleted(bool succesful);
void temperatureChanged(float value);
void gradientChanged(float value);
void processPercentageChanged(int percentage);
void collectionCompleted();
void calculationCompleted();
public slots:
/**
* @brief statusSave save the initial board status/configuration to be restored later
*/
void statusSave();
/**
* @brief statusRestore restore previous saved status.
*/
void statusRestore();
/**
* @brief setupBoard prepare board settings for acquisition state
*/
void setupBoard();
/**
* @brief initAcquisition Initialize the helper class for data acquisition/collection
*/
void initAcquisition();
void calculate();
void collectSample(UAVObject *sample);
void endAcquisition();
void setProcessPercentage(int value)
{
if (m_processPercentage != value) {
m_processPercentage = value;
emit processPercentageChanged(value);
}
}
private:
void updateTemp(float temp);
void connectUAVOs();
void disconnectUAVOs();
QMutex sensorsUpdateLock;
QList<AccelSensor::DataFields> m_accelSamples;
QList<GyroSensor::DataFields> m_gyroSamples;
QList<BaroSensor::DataFields> m_baroSamples;
QList<MagSensor::DataFields> m_magSamples;
QTime m_startTime;
// temperature checkpoints, used to calculate temp gradient
const int TimeBetweenCheckpoints = 10;
QTime m_lastCheckpointTime;
float m_lastCheckpointTemp;
float m_gradient;
float m_temperature;
float m_initialGradient;
const int ProcessPercentageSaveSettings = 5;
const int ProcessPercentageSetupBoard = 10;
const int ProcessPercentageBaseAcquisition = 15;
const int ProcessPercentageBaseCalculation = 85;
const float TargetGradient = 0.5f;
int m_targetduration;
int m_processPercentage;
/* board settings save/restore */
bool setupBoardForCalibration();
bool saveBoardInitialSettings();
bool restoreInitialSettings();
bool isBoardInitialSettingsSaved()
{
return m_boardInitialSettings.statusSaved;
}
private:
void setMetadataForCalibration(UAVDataObject *uavo);
void clearBoardInitialSettingsSaved()
{
m_boardInitialSettings.statusSaved = false;
}
signals:
void statusRestoreCompleted(bool succesful);
void statusSaveCompleted(bool succesful);
public slots:
void statusSave();
void statusRestore();
/* board configuration setup for calibration */
public:
bool setupBoardForCalibration();
signals:
void setupBoardCompleted(bool succesful);
public slots:
void setupBoard();
private:
thermalCalibrationBoardSettings m_boardInitialSettings;
void setMetadataForCalibration(UAVDataObject *uavo);
UAVObjectManager *getObjectManager();
};

View File

@ -27,8 +27,10 @@
*/
#include "thermalcalibrationmodel.h"
#include "thermalcalibrationtransitions.h"
#include "settinghandlingtransitions.h"
#include "settingshandlingtransitions.h"
#include "boardsetuptransition.h"
#include "dataacquisitiontransition.h"
#define NEXT_EVENT "next"
#define PREVIOUS_EVENT "previous"
#define ABORT_EVENT "abort"
@ -53,6 +55,10 @@ ThermalCalibrationModel::ThermalCalibrationModel(QObject *parent) :
setTransitions();
connect(m_helper, SIGNAL(gradientChanged(float)), this, SLOT(setTemperatureGradient(float)));
connect(m_helper, SIGNAL(temperatureChanged(float)), this, SLOT(setTemperature(float)));
connect(m_helper, SIGNAL(processPercentageChanged(int)), this, SLOT(setProgress(int)));
this->setInitialState(m_readyState);
m_steps << m_readyState
<< m_setupState
@ -64,8 +70,8 @@ void ThermalCalibrationModel::init()
setEndEnabled(false);
setCancelEnabled(false);
start();
setTemperature(QStringLiteral("0.01"));
setTemperatureGradient(QStringLiteral("0.02"));
setTemperature(0);
setTemperatureGradient(0);
emit instructionsChanged(instructions());
}
@ -85,7 +91,7 @@ void ThermalCalibrationModel::setTransitions()
// m_acquisitionState->addTransition(this,SIGNAL(next()),m_calculateState);
// revert settings after acquisition is completed
// m_acquisitionState->addTransition(new BoardStatusRestoreTransition(m_helper, m_acquisitionState, m_calculateState));
m_acquisitionState->addTransition(this, SIGNAL(next()), m_calculateState);
m_acquisitionState->addTransition(new DataAcquisitionTransition(m_helper, m_acquisitionState, m_calculateState));
m_calculateState->addTransition(new BoardStatusRestoreTransition(m_helper, m_calculateState, m_finalizeState));

View File

@ -30,7 +30,7 @@
#define THERMALCALIBRATIONMODEL_H
#include "thermalcalibrationhelper.h"
#include "thermalcalibrationtransitions.h"
#include <QObject>
#include <QState>
@ -45,7 +45,7 @@ class ThermalCalibrationModel : public WizardModel {
Q_PROPERTY(QString temperature READ temperature NOTIFY temperatureChanged)
Q_PROPERTY(QString temperatureGradient READ temperatureGradient NOTIFY temperatureGradientChanged)
Q_PROPERTY(int progress READ progress NOTIFY progressChanged)
Q_OBJECT
public:
explicit ThermalCalibrationModel(QObject *parent = 0);
@ -87,6 +87,12 @@ public:
}
public slots:
int progress()
{
return m_progress;
}
QString temperature()
{
return m_temperature;
@ -97,26 +103,38 @@ public:
return m_temperatureGradient;
}
void setTemperature(QString status)
void setTemperature(float status)
{
if (m_temperature != status) {
m_temperature = status;
emit temperatureChanged(status);
}
}
void setTemperatureGradient(QString status)
{
if (m_temperatureGradient != status) {
m_temperatureGradient = status;
emit temperatureGradientChanged(status);
}
}
QString tmp = QString("%1").arg(status, 5, 'f', 2);
if (m_temperature != tmp) {
m_temperature = tmp;
emit temperatureChanged(tmp);
}
}
void setTemperatureGradient(float status)
{
QString tmp = QString("%1 %2").arg(status, 5, 'f', 2);
if (m_temperatureGradient != tmp) {
m_temperatureGradient = tmp;
emit temperatureGradientChanged(tmp);
}
}
void setProgress(int status)
{
m_progress = status;
emit progressChanged(status);
if (this->currentState()) {
setInstructions(this->currentState()->stepName());
}
}
private:
bool m_startEnabled;
bool m_cancelEnabled;
bool m_endEnabled;
int m_progress;
QString m_temperature;
QString m_temperatureGradient;
@ -150,6 +168,7 @@ signals:
void temperatureChanged(QString status);
void temperatureGradientChanged(QString status);
void progressChanged(int value);
void next();
void previous();
@ -164,7 +183,8 @@ public slots:
void btnEnd()
{
emit previous();
// emit previous();
m_helper->endAcquisition();
}
void btnAbort()

View File

@ -46,11 +46,12 @@ HEADERS += configplugin.h \
calibration/calibrationutils.h \
calibration/wizardstate.h \
calibration/wizardmodel.h \
calibration/thermal/thermalcalibrationtransitions.h \
calibration/thermal/thermalcalibration.h \
calibration/thermal/thermalcalibrationhelper.h \
calibration/thermal/thermalcalibrationmodel.h \
calibration/thermal/settinghandlingtransitions.h
calibration/thermal/boardsetuptransition.h \
calibration/thermal/dataacquisitiontransition.h \
calibration/thermal/settingshandlingtransitions.h \
SOURCES += configplugin.cpp \
configgadgetwidget.cpp \

View File

@ -233,8 +233,9 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) :
connect(m_thermalCalibrationModel, SIGNAL(cancelEnabledChanged(bool)), m_ui->ThermalBiasCancel, SLOT(setEnabled(bool)));
connect(m_thermalCalibrationModel, SIGNAL(instructionsChanged(QString)), m_ui->label_thermalDescription, SLOT(setText(QString)));
connect(m_thermalCalibrationModel, SIGNAL(temperatureChanged(QString)), m_ui->label_thermalGradient, SLOT(setText(QString)));
connect(m_thermalCalibrationModel, SIGNAL(temperatureGradientChanged(QString)), m_ui->label_thermalGradient1, SLOT(setText(QString)));
connect(m_thermalCalibrationModel, SIGNAL(temperatureChanged(QString)), m_ui->textTemperature, SLOT(setText(QString)));
connect(m_thermalCalibrationModel, SIGNAL(temperatureGradientChanged(QString)), m_ui->textThermalGradient, SLOT(setText(QString)));
connect(m_thermalCalibrationModel, SIGNAL(progressChanged(int)), m_ui->thermalBiasProgress, SLOT(setValue(int)));
m_thermalCalibrationModel->init();

View File

@ -488,7 +488,7 @@ Hint: run this with engines at cruising speed.</string>
</widget>
</item>
<item>
<widget class="QProgressBar" name="ProgressThermalBias">
<widget class="QProgressBar" name="thermalBiasProgress">
<property name="value">
<number>0</number>
</property>