added butterworth filter \n added activity rec for baro using butter \n added moduel for walker with activity

This commit is contained in:
toni
2016-09-09 17:16:10 +02:00
parent 34e29b70c9
commit 7baeecb3f9
8 changed files with 868 additions and 97 deletions

View File

@@ -1,94 +0,0 @@
# Usage:
# Create build folder, like RC-build next to RobotControl and WifiScan folder
# CD into build folder and execute 'cmake -DCMAKE_BUILD_TYPE=Debug ../RobotControl'
# make
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# select build type
SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" )
PROJECT(Indoor)
IF(NOT CMAKE_BUILD_TYPE)
MESSAGE(STATUS "No build type selected. Default to Debug")
SET(CMAKE_BUILD_TYPE "Debug")
ENDIF()
INCLUDE_DIRECTORIES(
../
/mnt/firma/kunden/HandyGames/
)
FILE(GLOB HEADERS
./*.h
./*/*.h
./*/*/*.h
./*/*/*/*.h
./*/*/*/*/*.h
./*/*/*/*/*/*.h
)
FILE(GLOB SOURCES
./*.cpp
./*/*.cpp
./*/*/*.cpp
./*/*/*/*.cpp
)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_X86_ /D_USE_MATH_DEFINES")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /Oi /GL /Ot /Ox /D_X86_ /D_USE_MATH_DEFINES")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG /INCREMENTAL:NO")
set(CMAKE_CONFIGURATION_TYPES Release Debug)
else()
# system specific compiler flags
ADD_DEFINITIONS(
-std=gnu++11
-Wall
-Werror=return-type
-Wextra
-Wpedantic
-fstack-protector-all
-g3
-O0
-march=native
-DWITH_TESTS
-DWITH_ASSERTIONS
-DWITH_DEBUG_LOG
)
endif()
# build a binary file
ADD_EXECUTABLE(
${PROJECT_NAME}
${HEADERS}
${SOURCES}
)
# needed external libraries
TARGET_LINK_LIBRARIES(
${PROJECT_NAME}
gtest
pthread
)
SET(CMAKE_C_COMPILER ${CMAKE_CXX_COMPILER})

View File

@@ -0,0 +1,64 @@
#ifndef WALKMODULEBUTTERACTIVITY_H
#define WALKMODULEBUTTERACTIVITY_H
#include "WalkModule.h"
#include "WalkStateHeading.h"
#include "../../../../geo/Heading.h"
#include "../../../../math/Distributions.h"
#include "../../../../sensors/pressure/ActivityButterPressure.h"
/** favor z-transitions */
template <typename Node, typename WalkState> class WalkModuleButterActivity : public WalkModule<Node, WalkState> {
public:
/** ctor */
WalkModuleButterActivity() {
;
}
virtual void updateBefore(WalkState& state) override {
(void) state;
}
virtual void updateAfter(WalkState& state, const Node& startNode, const Node& endNode) override {
(void) state;
(void) startNode;
(void) endNode;
}
virtual void step(WalkState& state, const Node& curNode, const Node& nextNode) override {
(void) state;
(void) curNode;
(void) nextNode;
}
double getProbability(const WalkState& state, const Node& startNode, const Node& curNode, const Node& potentialNode) const override {
(void) state;
(void) startNode;
const int deltaZ_cm = curNode.z_cm - potentialNode.z_cm;
if(state.act == ActivityButterPressure::Activity::DOWN){
if (deltaZ_cm < 0) {return 0;}
if (deltaZ_cm == 0) {return 0.1;}
return 0.9;
} else if (state.act == ActivityButterPressure::Activity::UP){
if (deltaZ_cm > 0) {return 0;}
if (deltaZ_cm == 0) {return 0.1;}
return 0.9;
} else {
if (deltaZ_cm == 0) {return 0.9;}
return 0.1;
}
}
};
#endif // WALKMODULEBUTTERACTIVITY_H

View File

@@ -17,9 +17,9 @@ int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
// skip all tests starting with LIVE_
::testing::GTEST_FLAG(filter) = "-*.LIVE_*";
::testing::GTEST_FLAG(filter) = "*Barometer*";
::testing::GTEST_FLAG(filter) = "*GridWalk2HeadingControl*";
::testing::GTEST_FLAG(filter) = "*Activity*";
//::testing::GTEST_FLAG(filter) = "*Grid.*";
//::testing::GTEST_FLAG(filter) = "*Dijkstra.*";

312
math/filter/Butterworth.h Normal file
View File

@@ -0,0 +1,312 @@
#ifndef BUTTERWORTHLP_H
#define BUTTERWORTHLP_H
#include <math.h>
#include <vector>
#include <complex>
namespace Filter {
/** butterworth lowpass filter*/
template <typename Scalar> class ButterworthLP {
private:
/** Cascaded second-order sections */
class SOS{
public:
SOS(const Scalar b0, const Scalar b1, const Scalar b2, const Scalar a1, const Scalar a2, const Scalar gain) :
_b0(b0), _b1(b1), _b2(b2), _a1(a1), _a2(a2), _gain(gain), _z1(0), _z2(0),
_preCompStateSpaceOutputVec1(_b1 - _b0*_a1),
_preCompStateSpaceOutputVec2(_b2 - _b0*_a2){
}
void safeRestoreState(Scalar &z1, Scalar &z2, const bool restore){
if (restore)
{
_z1 = z1;
_z2 = z2;
}
else
{
z1 = _z1;
z2 = _z2;
}
}
void stepInitialization(const Scalar value){
// Set second-order section state to steady state w.r.t. given step response value
// http://www.emt.tugraz.at/publications/diplomarbeiten/da_hoebenreich/node21.html
_z1 = _z2 = value / (1.0 + _a1 + _a2);
}
Scalar process(const Scalar input){
/**
SOS state space model
z' = A * z + b * x
y = c^T * z + d * x
with A = [-a1 -a2; 1 0] b = [1; 0] c = [b1 - b0*a1; b2 - b0*a2] d = [b0]
*/
Scalar x = input;
Scalar y = x;
Scalar z1_new, z2_new;
z1_new = -_a1 * _z1 - _a2 * _z2 + x;
z2_new = _z1;
y = _preCompStateSpaceOutputVec1 * _z1 + _preCompStateSpaceOutputVec2 * _z2 + _b0 * x;
_z1 = z1_new;
_z2 = z2_new;
// Include SOS gain factor
y *= _gain;
return y;
}
~SOS()
{ }
private:
const Scalar _b0, _b1, _b2, _a1, _a2, _gain;
const Scalar _preCompStateSpaceOutputVec1, _preCompStateSpaceOutputVec2;
Scalar _z1, _z2;
};
size_t _numSOS;
std::vector<SOS> _sosVec;
public:
/**
Generates a Butterworth lowpass filter with a given normalized cutoff frequency and filter order.
@param normalizedCutoffFrequency (0, 1) Normalized cutoff frequency := cuttoffFreq / samplingFreq.
@param filterOrder [1, inf] Butterworth filter order.
*/
ButterworthLP(const Scalar normalizedCutoffFrequency, const size_t filterOrder) :
_numSOS(0)
{
if (!coefficients(normalizedCutoffFrequency, filterOrder))
{
throw std::domain_error(std::string("Failed to design a filter due to invalid parameters (normalized cutoff frequency and / or filter order) or instability of the resulting digitalized filter."));
}
}
/**
Generates a Butterworth lowpass filter of a given order with a given cutoff frequency [Hz] in respect of the data sampling frequency [Hz].
@param samplingFrequency [1, inf] [Hz] Sampling frequency of the data.
@param cutoffFrequency [1, samplingFrequency - 1] [Hz] Cutoff frequency
@param filterOrder [1, inf] Butterworth filter order.
*/
ButterworthLP(const Scalar samplingFrequency, const Scalar cutoffFrequency, const size_t filterOrder) :
ButterworthLP(cutoffFrequency / samplingFrequency, filterOrder)
{ }
/**
Set the filter state to a steady state w.r.t. to the given input value (assuming a constant filter input for infinite time steps in the past;
see also http://www.emt.tugraz.at/publications/diplomarbeiten/da_hoebenreich/node21.html).
@param value Desired steady state output value
*/
void stepInitialization(const Scalar value){
Scalar stepResponseValue = value;
// Propagate step initialization through all second-order sections
for (size_t i = 0; i < _numSOS; ++i)
{
_sosVec[i].stepInitialization(stepResponseValue);
stepResponseValue = _sosVec[i].process(stepResponseValue);
}
}
/**
Processes the input value online depending on the current filter state.
@param input [-inf, inf] Input value
@return [-inf, inf] Filter response
*/
Scalar process(const Scalar input){
Scalar x = input;
Scalar y = x;
// Cascade all second-order sections s.t. output of SOS i is input for SOS i+1
for (size_t i = 0; i < _numSOS; ++i)
{
y = _sosVec[i].process(x);
x = y;
}
return y;
}
/**
Processes the input data offline.
@param *input Ptr to input data.
@param *output Ptr to output data.
@param size [0, inf] Length of data.
@param initialConditionValue [-inf, inf] Initializes the filter state to a steady state w.r.t. the given initial value (see stepInitialization).
@param forwardBackward {true, false} Eliminate phase delay by filtering twice: forward and backward.
Note that forward-backward filtering corresponds to filtering with a 2n-th order filter.
*/
void filter(const Scalar *input, Scalar *output, const size_t size, const Scalar initialConditionValue, const bool forwardBackward){
// Save all current SOS states before offline filtering
std::vector<Scalar> zSaved(_numSOS * 2);
for (size_t i = 0; i < _numSOS; ++i)
{
_sosVec[i].safeRestoreState(zSaved[i], zSaved[i + 1], false);
}
// Set initial step response conditions
stepInitialization(initialConditionValue);
// Filtering on input data
for (size_t i = 0; i < size; ++i)
{
output[i] = process(input[i]);
}
// Additional backward filtering on filtered output data if requested
if (forwardBackward)
{
for (size_t i = size; i > 0;)
{
output[--i] = process(output[i]);
}
}
// Restore all SOS states
for (size_t i = 0; i < _numSOS; ++i)
{
_sosVec[i].safeRestoreState(zSaved[i], zSaved[i + 1], true);
}
}
private:
bool coefficients(const Scalar normalizedCutoffFrequency, const size_t filterOrder){
// Assure valid parameters
if (filterOrder < 1 || normalizedCutoffFrequency <= 0 || normalizedCutoffFrequency > 1)
{
return false;
}
std::vector<std::complex<Scalar>> poles(filterOrder);
// Prewarp the analog prototype's cutoff frequency
Scalar omegaCutoff = 2 * tan(M_PI * normalizedCutoffFrequency);
Scalar gain = pow(omegaCutoff, filterOrder);
Scalar initialGain = gain;
std::complex<Scalar> two(2.0, 0);
for (size_t i = 0, i_end = (filterOrder + 1) / 2; i < i_end; ++i){
size_t i2 = 2 * i;
/**
Design the analog prototype Butterworth lowpass filter
*/
// Generate s-poles of prototype filter
Scalar phi = static_cast<Scalar>(i2 + 1) * M_PI / (2 * filterOrder);
Scalar real = -sin(phi);
Scalar imag = cos(phi);
std::complex<Scalar> pole = std::complex<Scalar>(real, imag);
/**
Customize analog prototype filter w.r.t cutoff frequency
*/
// Scale s-pole with the cutoff frequency
pole *= omegaCutoff;
/**
Digitalize the analog filter
*/
// Map pole from s-plane to z-plane using bilinear transform
std::complex<Scalar> s = pole;
pole = (two + s) / (two - s);
// Update overall gain in respect of z-pole gain
gain *= abs((two - s));
// Ensure z-pole lies in unit circle of z-plane
if (abs(pole) > 1)
{
return false;
}
// Add stable z-pole
poles[i2] = pole;
// Odd filter order: ignore the second complex conjugate pole
if (i2 + 1 >= filterOrder)
{
break;
}
// Do the same as above with the conjugate complex pole
pole = std::complex<Scalar>(real, -imag);
pole *= omegaCutoff;
s = pole;
pole = (two + s) / (two - s);
gain *= abs((two - s));
if (abs(pole) > 1)
{
return false;
}
poles[i2 + 1] = pole;
}
// Distribute the overall gain over all z-poles
Scalar overallGain = initialGain * (initialGain / gain);
Scalar distributedPoleGain = pow(overallGain, 1.0 / static_cast<Scalar>(filterOrder));
Scalar distributedPolePairGain = distributedPoleGain * distributedPoleGain;
/**
Generate second-order sections from conjugate complex z-pole pairs
*/
for (size_t i = 0, i_end = filterOrder - 1; i < i_end; i += 2){
addSOS(SOS(1.0, 2.0, 1.0, -(poles[i] + poles[i + 1]).real(), (poles[i] * poles[i + 1]).real(), distributedPolePairGain));
}
// Odd filter order: remaining single z-pole requires additional second-order section
if (filterOrder % 2 == 1){
addSOS(SOS(1.0, 1.0, 0.0, -poles[filterOrder - 1].real(), 0.0, distributedPoleGain));
}
return true;
}
void addSOS(const SOS sos){
_sosVec.push_back(sos);
++_numSOS;
}
};
}
#endif // BUTTERWORTHLP_H

View File

@@ -0,0 +1,185 @@
#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.05f,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(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

View File

@@ -6,7 +6,7 @@
#include <gtest/gtest.h>
static inline std::string getDataFile(const std::string& name) {
return "/mnt/data/workspaces/Indoor/tests/data/" + name;
return "/home/toni/Documents/programme/localization/Indoor/tests/data/" + name;
}

View File

@@ -0,0 +1,257 @@
#ifdef WITH_TESTS
#include "../../Tests.h"
#include "../../../math/filter/Butterworth.h"
#include "../../../misc/Time.h"
#include "../../../math/Interpolator.h"
#include"../../../sensors/pressure/ActivityButterPressure.h"
#include <KLib/misc/gnuplot/Gnuplot.h>
#include <KLib/misc/gnuplot/GnuplotPlot.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementPoints.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementColorPoints.h>
#include <KLib/misc/gnuplot/GnuplotPlotElementLines.h>
#include <random>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
TEST(Butterworth, offlineSinus) {
//input data
std::minstd_rand gen;
std::uniform_real_distribution<double> noise (-0.1, +0.1);
int size = 1100; //Fs
double* input = new double[size];
double* output = new double[size];
// 17.5hz sin signal with random noise [-0.1, 0.1]
for( int i=0; i < size; ++i ){
input[i] = sin(0.1 * i) + noise(gen);
}
//butterworth
Filter::ButterworthLP<double> butter(size,20,5);
butter.stepInitialization(0);
butter.filter(input, output, size, 0, true);
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines linesInput;
K::GnuplotPlotElementLines linesOutput;
for(int i=0; i < size-1; ++i){
K::GnuplotPoint2 input_p1(i, input[i]);
K::GnuplotPoint2 input_p2(i+1, input[i+1]);
K::GnuplotPoint2 output_p1(i, output[i]);
K::GnuplotPoint2 output_p2(i+1, output[i+1]);
linesInput.addSegment(input_p1, input_p2);
linesOutput.addSegment(output_p1, output_p2);
}
linesOutput.setColorHex("#00FF00");
plot.add(&linesInput);
plot.add(&linesOutput);
gp.draw(plot);
gp.flush();
sleep(10);
}
TEST(Butterworth, onlineSinus) {
int size = 1100; //Fs
double* input = new double[size];
double* output = new double[size];
Filter::ButterworthLP<double> butter(size,20,5);
butter.stepInitialization(0);
//input data
std::minstd_rand gen;
std::uniform_real_distribution<double> noise (-0.1, +0.1);
// 17.5hz sin signal with random noise [-0.1, 0.1]
for( int i=0; i < size; ++i ){
input[i] = sin(0.1 * i) + noise(gen);
output[i] = butter.process(input[i]);
}
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines linesInput;
K::GnuplotPlotElementLines linesOutput;
for(int i=0; i < size-1; ++i){
K::GnuplotPoint2 input_p1(i, input[i]);
K::GnuplotPoint2 input_p2(i+1, input[i+1]);
K::GnuplotPoint2 output_p1(i, output[i]);
K::GnuplotPoint2 output_p2(i+1, output[i+1]);
linesInput.addSegment(input_p1, input_p2);
linesOutput.addSegment(output_p1, output_p2);
}
linesOutput.setColorHex("#00FF00");
plot.add(&linesInput);
plot.add(&linesOutput);
gp.draw(plot);
gp.flush();
sleep(1);
}
TEST(Butterworth, offlineOctaveBaro) {
double* input = new double[100000];
double* output = new double[100000];
Interpolator<int, double> interp;
//read file
std::string line;
std::string filename = getDataFile("baro/logfile_UAH_R1_S4_baro.dat");
std::ifstream infile(filename);
int counter = 0;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int ts;
double value;
while (iss >> ts >> value) {
interp.add(ts, value);
while(interp.getMaxKey() > counter*20 ){
double interpValue = interp.get(counter*20);
input[counter] = interpValue;
//std::cout << counter*20 << " " << interpValue << " i" << std::endl;
++counter;
}
//std::cout << ts << " " << value << " r" << std::endl;
}
}
Filter::ButterworthLP<double> butter(50,0.2,2);
butter.filter(input, output, counter, 938.15, true);
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines linesInput;
K::GnuplotPlotElementLines linesOutput;
for(int i=0; i < counter-1; ++i){
K::GnuplotPoint2 input_p1(i, input[i]);
K::GnuplotPoint2 input_p2(i+1, input[i+1]);
K::GnuplotPoint2 output_p1(i, output[i]);
K::GnuplotPoint2 output_p2(i+1, output[i+1]);
linesInput.addSegment(input_p1, input_p2);
linesOutput.addSegment(output_p1, output_p2);
}
linesOutput.setColorHex("#00FF00");
plot.add(&linesInput);
plot.add(&linesOutput);
gp.draw(plot);
gp.flush();
sleep(1);
}
TEST(Butterworth, onlineOctaveBaro) {
std::vector<double> input;
std::vector<double> output;
Interpolator<int, double> interp;
Filter::ButterworthLP<double> butter(50,0.02,2);
butter.stepInitialization(938.15);
//read file
std::string line;
std::string filename = getDataFile("baro/logfile_UAH_R1_S4_baro.dat");
std::ifstream infile(filename);
int counter = 1;
while (std::getline(infile, line))
{
std::istringstream iss(line);
int ts;
double value;
while (iss >> ts >> value) {
interp.add(ts, value);
while(interp.getMaxKey() > counter*20 ){
double interpValue = interp.get(counter*20);
//std::cout << counter*20 << " " << interpValue << " i" << std::endl;
input.push_back(interpValue);
output.push_back(butter.process(interpValue));
++counter;
}
//std::cout << ts << " " << value << " r" << std::endl;
}
}
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines linesInput;
K::GnuplotPlotElementLines linesOutput;
for(int i=0; i < input.size()-1; ++i){
K::GnuplotPoint2 input_p1(i, input[i]);
K::GnuplotPoint2 input_p2(i+1, input[i+1]);
K::GnuplotPoint2 output_p1(i, output[i]);
K::GnuplotPoint2 output_p2(i+1, output[i+1]);
linesInput.addSegment(input_p1, input_p2);
linesOutput.addSegment(output_p1, output_p2);
}
linesOutput.setColorHex("#00FF00");
plot.add(&linesInput);
plot.add(&linesOutput);
gp.draw(plot);
gp.flush();
sleep(1);
}
#endif

View File

@@ -4,6 +4,7 @@
#include "../../../sensors/pressure/RelativePressure.h"
#include "../../../sensors/pressure/PressureTendence.h"
#include "../../../sensors/pressure/ActivityButterPressure.h"
#include <random>
@@ -121,5 +122,51 @@ TEST(Barometer, LIVE_tendence2) {
}
TEST(Barometer, Activity) {
ActivityButterPressure act;
//read file
std::string line;
std::string filename = getDataFile("baro/logfile_UAH_R2_S3_baro.dat");
std::ifstream infile(filename);
while (std::getline(infile, line))
{
std::istringstream iss(line);
int ts;
double value;
while (iss >> ts >> value) {
ActivityButterPressure::Activity currentAct = act.add(Timestamp::fromMS(ts), BarometerData(value));
}
}
std::vector<float> sum = act.getSumHistory();
std::vector<float> interpolated = act.getInterpolatedHistory();
std::vector<float> raw = act.getSensorHistory();
std::vector<float> butter = act.getOutputHistory();
std::vector<ActivityButterPressure::History> actHist = act.getActHistory();
K::Gnuplot gp;
K::GnuplotPlot plot;
K::GnuplotPlotElementLines rawLines;
for(int i=0; i < actHist.size()-1; ++i){
K::GnuplotPoint2 input_p1(actHist[i].ts.sec(), actHist[i].data.hPa);
K::GnuplotPoint2 input_p2(actHist[i+1].ts.sec(), actHist[i+1].data.hPa);
rawLines.addSegment(input_p1, input_p2);
}
plot.add(&rawLines);
gp.draw(plot);
gp.flush();
sleep(1);
}
#endif