This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
Indoor/sensors/pressure/RelativePressure.h
FrankE a2c9e575a2 huge commit
- worked on about everything
- grid walker using plugable modules
- wifi models
- new distributions
- worked on geometric data-structures
- added typesafe timestamps
- worked on grid-building
- added sensor-classes
- added sensor analysis (step-detection, turn-detection)
- offline data reader
- many test-cases
2016-08-29 08:18:44 +02:00

140 lines
3.0 KiB
C++

#ifndef BAROMETER_H
#define BAROMETER_H
#include "../../data/Timestamp.h"
#include "../../math/MovingAVG.h"
#include "BarometerData.h"
/**
* calculates the pressure realtive to a startup-calibration of a barometer
* hereafter all returned values are relative to the calibration
*
*/
class RelativePressure {
private:
/** barometer history entries (timestamp -> value) */
struct History {
Timestamp ts;
BarometerData data;
History(const Timestamp ts, const BarometerData data) : ts(ts), data(data) {;}
};
/** barometer calibration helper */
struct Calibration {
Timestamp neededTimeframe = Timestamp::fromMS(5000);
std::vector<History> history;
bool isCalibrated = false;
float baseAvg = 0;
float sigma = 0;
// prevent sensor-startup-issues and skip the first 25% of measurement values
float skipStart = 0.25;
void tryToCalibrate() {
// determine the timeframe contained within the history
const Timestamp timeframe = history.back().ts - history.front().ts;
// do we have enough values to perform a calibration?
if (timeframe < neededTimeframe) {return;}
// we need double as float would lead to huge rounding errors!
double sum = 0;
double sum2 = 0;
int cnt = 0;
// calculate sum and sum²
for (int i = (int)(skipStart*history.size()); i < (int)history.size(); ++i) {
const History& h = history[i];
sum += h.data.hPa;
sum2 += ((double)h.data.hPa * (double)h.data.hPa);
++cnt;
}
// calculate E(x) and E(x²)
double avg = sum / (double)cnt;
double avg2 = sum2 / (double)cnt;
// set calibrated values
this->baseAvg = avg;
this->sigma = std::sqrt( avg2 - (avg*avg) );
this->isCalibrated = true;
}
void reset() {
history.clear();
isCalibrated = false;
sigma = 0;
baseAvg = 0;
}
} calib;
float latesthPa;
public:
/** ctor */
RelativePressure() {
}
/** set the timeframe used for the startup calibration (e.g. 5 seconds) */
void setCalibrationTimeframe(const Timestamp timeframe) {
this->calib.neededTimeframe = timeframe;
}
/** add new sensor readings that were received at the given timestamp */
void add(const Timestamp& ts, const BarometerData& baro) {
// perform calibration?
if (!calib.isCalibrated) {
calib.history.push_back(History(ts, baro));
calib.tryToCalibrate();
}
// most recent pressure reading
latesthPa = baro.hPa;
}
/** get the most recent pressure reading realtive to the startup calibration. returns 0 until the sensor is calibrated */
float getPressureRealtiveToStart() {
if (calib.isCalibrated) {
return latesthPa - calib.baseAvg;
} else {
return 0;
}
}
/** reset the sensor's calibration */
void reset() {
calib.reset();
}
/** get the barometer's calibrated uncertainty determined during the startup calibration */
float getSigma() {
return calib.sigma;
}
/** get the barometer's calibrated average during the startup calibration */
float getBaseAvg() {
return calib.baseAvg;
}
private:
};
#endif // BAROMETER_H