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/PressureTendence.h
kazu d40032ca74 interface changes
added new data-strcutures for new sensors
new helper methods
fixed some issues
2017-05-24 09:23:27 +02:00

228 lines
4.6 KiB
C++

#ifndef PRESSURETENDENCE_H
#define PRESSURETENDENCE_H
#include "../../data/Timestamp.h"
#include "../../math/MovingAVG.h"
#include "../../math/MovingMedian.h"
#include "../../math/Stats.h"
#include "BarometerData.h"
#include <KLib/misc/gnuplot/Gnuplot.h>
#include <KLib/misc/gnuplot/GnuplotPlot.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementLines.h>
/**
*
*/
class PressureTendence {
private:
/** barometer history entries (timestamp -> value) */
struct History {
Timestamp ts;
BarometerData data;
History(const Timestamp ts, const BarometerData data) : ts(ts), data(data) {;}
};
Timestamp timeframe;
std::vector<History> history;
public:
enum class Type {
STRONG_MOVING_UPWARDS,
MOVING_UPWARDS,
NO_CHANGE,
MOVING_DOWNWARDS,
STRONG_MOVING_DOWNWARDS,
};
struct Debug {
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines raw;
K::GnuplotPlotElementLines avg;
K::GnuplotPlotElementLines tendence;
Debug() {
plot.add(&raw); raw.getStroke().getColor().setHexStr("#999999");
plot.add(&avg); avg.getStroke().getColor().setHexStr("#000000");
plot.add(&tendence); tendence.getStroke().setWidth(2);
tendence.setCustomAttr(" axes x1y2 ");
gp << "set y2tics\n";
gp << "set y2range[-0.3:+0.3]\n";
}
void addRaw(Timestamp ts, float val) {
raw.add(K::GnuplotPoint2(ts.ms(), val));
}
void addAvg(Timestamp ts, float val) {
avg.add(K::GnuplotPoint2(ts.ms(), val));
}
void addTendence(Timestamp ts, float val) {
tendence.add(K::GnuplotPoint2(ts.ms(), val));
}
void show() {
static int cnt = 0;
if (++cnt % 4 == 0) {
gp.draw(plot);
gp.flush();
}
}
};
public:
Debug debug;
/** ctor with the timeframe to use. 1.0 sec should be fine */
PressureTendence(const Timestamp timeframe) : timeframe(timeframe) {
}
/** add new sensor readings that were received at the given timestamp */
void add(const Timestamp& ts, const BarometerData& baro) {
static MovingAVG<float> avg(5);
avg.add(baro.hPa);
debug.addRaw(ts, baro.hPa);
debug.addAvg(ts, avg.get());
debug.show();
// add to the history
//history.push_back(History(ts, baro));
history.push_back(History(ts, BarometerData(avg.get())));
// remove too old values
while( (ts - history[0].ts) > Timestamp::fromMS(2000)) {history.erase(history.begin());}
}
/** get the current tendence */
float get() {
// static MovingAVG<float> avg(3);
if (history.empty()) {return 0;}
// const float tendence = history.back().data.hPa - history.front().data.hPa;
// avg.add(tendence);
// debug.addTendence(history.back().ts, avg.get());
// return tendence;
// const int ws = 5;
// if (history.size() < (ws+1)) {return 0;}
// const int s = history.size() - 1;
// bool rising = true;
// for (int i = s-ws; i < s; ++i) {
// if (history[i+0].data.hPa >= history[i+1].data.hPa) {rising = false; break;}
// }
// bool falling = true;
// for (int i = s-ws; i < s; ++i) {
// if (history[i+0].data.hPa <= history[i+1].data.hPa) {falling = false; break;}
// }
// float tendence = 0;
// if (rising) {tendence = +0.1;}
// if (falling) {tendence = -0.1;}
float tendence = 0;
// if (delta > +0.1) {tendence = +0.1;}
// if (delta < -0.1) {tendence = -0.1;}
int numUp = 0;
int numDown = 0;
float slopeSum = 0;
float slopeUp = 0;
float slopeDown = 0;
int cnt=0;
for (int i = 0; i < history.size() - 1; ++i) {
if (history[i+0].data.hPa < history[i+1].data.hPa) {++numUp;} else {++numDown;}
const float slope = history[i+0].data.hPa - history[i+1].data.hPa;
slopeSum += slope;
if (slope > 0) {slopeUp += slope;}
if (slope < 0) {slopeDown += slope;}
++cnt;
}
//tendence = (numUp-numDown)/((float)cnt)/10.0f;
tendence = (std::abs(slopeUp) - std::abs(slopeDown)) ;
//slopeSum /= cnt;
// const float sd = std::abs(slopeUp) - std::abs(slopeDown);
// tendence = sd;
// if (std::abs(sd) > 0.07) {
// tendence = 0.1;
// }
// const int delta = numUp - numDown;
// if (std::abs(delta) > cnt*0.3) {
// if (delta < 0) {tendence = -0.1;}
// if (delta > 0) {tendence = +0.1;}
// }
//if (std::abs(deltaP) < 0.005) {tendence = 0;}
// const float delta = history.front().data.hPa - history.back().data.hPa;
// tendence = delta > 0.15;
debug.addTendence(history.back().ts, tendence);
return tendence;
// const int avgSize = 7;
// if (history.size() < avgSize) {return 0;}
// Median<float> hPa1;
// Median<float> hPa2;
// int s = history.size() - 1;
// for (int i = 0; i < avgSize; ++i) {
// hPa1.add(history[0+i].data.hPa);
// hPa2.add(history[s-i].data.hPa);
// }
// const float diff = (hPa2.get()) - (hPa1.get());
// return diff;
}
};
#endif // PRESSURETENDENCE_H