added activity detection

This commit is contained in:
kazu
2016-04-21 08:56:15 +02:00
parent ecd34cf6d3
commit 6f0d56fbef
10 changed files with 210 additions and 18 deletions

6
code/lukas/Activities.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef ACTIVITIES_H
#define ACTIVITIES_H
#endif // ACTIVITIES_H

View File

@@ -0,0 +1,121 @@
#ifndef ACTIVITYDETECTION_H
#define ACTIVITYDETECTION_H
#include <string>
#include "Activities.h"
#include <vector>
#include <Indoor/math/MovingAVG.h>
#include <Indoor/math/MovingMedian.h>
#include <KLib/math/statistics/Statistics.h>
#include <Indoor/math/Distributions.h>
/**
* classification of pedestrian activities using sensor inputs.
* sensor inputs are passed into this element
* recognized acitivities are the output
*
*/
class ActivityDetection {
private:
/** the currently detected activity */
Activity current = Activity::UNKNOWN;
K::Statistics<float> mag;
K::Statistics<float> hpa;
MovingMedian<float> hpaAvg;
public:
ActivityDetection() : hpaAvg(3) {;}
/** add accelerometer values */
void addAccel(float accel[3]) {
float magnitude = std::sqrt(accel[0]*accel[0] + accel[1]*accel[1] + accel[2]*accel[2]);
mag.add(magnitude - 9.81f);
}
/** add barometer values */
void addBaro(float hpa) {
hpaAvg.add(hpa);
float smoothed = hpaAvg.get();
this->hpa.add(smoothed);
if (this->hpa.getCount() > 50) {analyze();}
}
struct ActClass {
Activity act;
Distribution::Normal<float> barometer;
Distribution::Normal<float> magnitude;
ActClass(const Activity act, float muMag, float muBaro, float varMag, float varBaro) :
act(act), barometer(muBaro, std::sqrt(varBaro)), magnitude(muMag, std::sqrt(varMag)) {
;
}
float getProbability(const float hpaRange, const float varMag) const {
return barometer.getProbability(hpaRange) *
magnitude.getProbability(varMag);
}
};
void analyze() {
// std::vector<ActClass> classes = {
// ActClass(Activity::STANDING, 0.042118, 0.01, 0.002322, 0.001),
// ActClass(Activity::STAIRS, 3.561667, 0.035, 1.392631, 0.002), // stair up
// ActClass(Activity::STAIRS, 5.529414, -0.035, 3.416315, 0.002), // stair down
// ActClass(Activity::WALKING, 1.669506, 0.01, 0.273880, 0.001),
// };
// auto comp = [&] (const ActClass& a, const ActClass& b) {
// return a.getProbability(hpa.getRange(), mag.getStdDev()) < b.getProbability(hpa.getRange(), mag.getStdDev());
// };
// auto it = std::max_element(classes.begin(), classes.end(), comp);
// current = (*it).act;
if (mag.getStdDev() < 0.3) {
current = Activity::STANDING;
} else {
if (hpa.getRange() > 0.035) {
current = Activity::STAIRS;
} else {
current = Activity::WALKING;
}
}
// current = (Activity) idx;
mag.reset();
hpa.reset();
}
/** get the currently detected activity */
Activity getCurrentActivity() const {
return current;
}
std::string toString() const {
switch (current) {
case Activity::UNKNOWN: return "unknown";
case Activity::STANDING: return "standing";
case Activity::WALKING: return "walking";
case Activity::STAIRS: return "stairs";
case Activity::ELEVATOR: return "elevator";
}
throw "should not happen";
}
};
#endif // ACTIVITYDETECTION_H