#ifndef PRESSURETENDENCE_H #define PRESSURETENDENCE_H #include "../../data/Timestamp.h" #include "../../math/MovingAVG.h" #include "../../math/MovingMedian.h" #include "../../math/Median.h" #include "BarometerData.h" #include #include #include /** * */ 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; 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.setColorHex("#999999"); plot.add(&avg); avg.setColorHex("#000000"); plot.add(&tendence); tendence.setLineWidth(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 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 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 hPa1; // Median 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