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/ActivityButterPressure.h
kazu 4f511d907e some fixes [multithreading,..]
needed interface changes [new options]
logger for android
wifi-ap-optimization
new test-cases
2016-09-28 12:19:14 +02:00

186 lines
4.7 KiB
C++

#ifndef ACTIVITYBUTTERPRESSURE_H
#define ACTIVITYBUTTERPRESSURE_H
#include "../../data/Timestamp.h"
#include "../../math/filter/Butterworth.h"
#include "../../math/FixedFrequencyInterpolator.h"
#include "../../math/MovingAVG.h"
#include "BarometerData.h"
/**
* receives pressure measurements, interpolates them to a ficex frequency, lowpass filtering
* activity recognition based on a small window given by matlabs diff(window)
*/
class ActivityButterPressure {
public:
enum Activity {DOWN, STAY, UP};
struct History {
Timestamp ts;
BarometerData data;
History(const Timestamp ts, const BarometerData data) : ts(ts), data(data) {;}
};
private:
//just for debugging and plotting
std::vector<History> input;
std::vector<History> inputInterp;
std::vector<History> output;
std::vector<float> sumHist;
std::vector<float> mvAvgHist;
std::vector<History> actHist;
Activity currentActivity;
MovingAVG<float> mvAvg = MovingAVG<float>(20);
/** change this values for much success */
const bool additionalLowpassFilter = false;
const int diffSize = 20; //the number values used for finding the activity.
const float threshold = 0.025; // if diffSize is getting smaller, treshold needs to be adjusted in the same direction!
Filter::ButterworthLP<float> butter = Filter::ButterworthLP<float>(10,0.1f,2);
Filter::ButterworthLP<float> butter2 = Filter::ButterworthLP<float>(10,0.1f,2);
FixedFrequencyInterpolator<float> ffi = FixedFrequencyInterpolator<float>(Timestamp::fromMS(100));
public:
/** ctor */
ActivityButterPressure() : currentActivity(STAY){
;
}
/** add new sensor readings that were received at the given timestamp */
Activity add(const Timestamp& ts, const BarometerData& baro) {
//init
static bool firstCall = false;
if(!firstCall){
butter.stepInitialization(baro.hPa);
firstCall = true;
butter2.stepInitialization(0);
return STAY;
}
input.push_back(History(ts, baro));
bool newInterpolatedValues = false;
//interpolate & butter
auto callback = [&] (const Timestamp ts, const float val) {
float interpValue = val;
inputInterp.push_back(History(ts, BarometerData(interpValue)));
//butter
float butterValue = butter.process(interpValue);
output.push_back(History(ts, BarometerData(butterValue)));
newInterpolatedValues = true;
};
ffi.add(ts, baro.hPa, callback);
if(newInterpolatedValues == true){
//getActivity
if((int)output.size() > diffSize){
//diff
std::vector<float> diff;
for(int i = output.size() - diffSize; i < output.size() - 1; ++i){
float diffVal = output[i+1].data.hPa - output[i].data.hPa;
diff.push_back(diffVal);
}
float sum = 0;
for(float val : diff){
sum += val;
}
float actValue = 0;
if(additionalLowpassFilter == true){
//additional butter/moving average for the results
//mvAvg.add(sum);
//actValue = mvAvg.get();
actValue = butter2.process(sum);
}else{
actValue = sum;
}
sumHist.push_back(actValue);
if(actValue > threshold){
currentActivity = DOWN;
}
else if (actValue < -threshold){
currentActivity = UP;
}
else{
currentActivity = STAY;
}
}
}
actHist.push_back(History(ts, BarometerData(currentActivity)));
return currentActivity;
}
/** get the current Activity */
Activity getCurrentActivity() {
return currentActivity;
}
std::vector<float> getSensorHistory(){
std::vector<float> tmp;
for(History val : input){
tmp.push_back(val.data.hPa);
}
return tmp;
}
std::vector<float> getInterpolatedHistory(){
std::vector<float> tmp;
for(History val : inputInterp){
tmp.push_back(val.data.hPa);
}
return tmp;
}
std::vector<float> getOutputHistory(){
std::vector<float> tmp;
for(History val : output){
tmp.push_back(val.data.hPa);
}
return tmp;
}
std::vector<float> getSumHistory(){
return sumHist;
}
std::vector<History> getActHistory(){
return actHist;
}
};
#endif // ACTIVITYBUTTERPRESSURE_H