Brick
Loading...
Searching...
No Matches
moving_average.h
1#pragma once
2#include <vector>
3
4/**
5 * Interface for filters
6 * Use add_entry to supply data and get_value to retrieve the filtered value
7 */
8class Filter {
9 public:
10 virtual void add_entry(double n) = 0;
11 virtual double get_value() const = 0;
12};
13
14/**
15 * MovingAverage
16 *
17 * A moving average is a way of smoothing out noisy data. For many sensor readings, the noise is
18 * roughly symmetric around the actual value. This means that if you collect enough samples those
19 * that are too high are cancelled out by the samples that are too low leaving the real value.
20 *
21 * The MovingAverage class provides a simple interface to do this smoothing from our noisy sensor
22 * values.
23 *
24 * WARNING: because we need a lot of samples to get the actual value, the value given by the
25 * MovingAverage will 'lag' behind the actual value that the sensor is reading. Using a
26 * MovingAverage is thus a tradeoff between accuracy and lag time (more samples) vs. less accuracy
27 * and faster updating (less samples).
28 *
29 */
30class MovingAverage : public Filter {
31 public:
32 /**
33 * Create a moving average calculator with 0 as the default value
34 *
35 * @param buffer_size The size of the buffer. The number of samples that constitute a valid
36 * reading
37 */
38 MovingAverage(int buffer_size);
39 /**
40 * Create a moving average calculator with a specified default value
41 * @param buffer_size The size of the buffer. The number of samples that constitute a valid
42 * reading
43 * @param starting_value The value that the average will be before any data is added
44 */
45 MovingAverage(int buffer_size, double starting_value);
46
47 /**
48 * Add a reading to the buffer
49 * Before:
50 * [ 1 1 2 2 3 3] => 2
51 * ^
52 * After:
53 * [ 2 1 2 2 3 3] => 2.16
54 * ^
55 * @param n the sample that will be added to the moving average.
56 */
57 void add_entry(double n) override;
58
59 /**
60 * Returns the average based off of all the samples collected so far
61 * @return the calculated average. sum(samples)/numsamples
62 */
63 double get_value() const override;
64
65 /**
66 * How many samples the average is made from
67 * @return the number of samples used to calculate this average
68 */
69 int get_size() const;
70
71 private:
72 int buffer_index; // index of the next value to be overridden
73 std::vector<double> buffer; // all current data readings we've taken
74 double current_avg; // the current value of the data
75};
76
77/**
78 * ExponentialMovingAverage
79 *
80 * An exponential moving average is a way of smoothing out noisy data. For many sensor readings, the
81 * noise is roughly symmetric around the actual value. This means that if you collect enough samples
82 * those that are too high are cancelled out by the samples that are too low leaving the real value.
83 *
84 * A simple mobing average lags significantly with time as it has to counteract old samples. An
85 * exponential moving average keeps more up to date by weighting newer readings higher than older
86 * readings so it is more up to date while also still smoothed.
87 *
88 * The ExponentialMovingAverage class provides an simple interface to do this smoothing from our
89 * noisy sensor values.
90 *
91 */
93 public:
94 /**
95 * Create a moving average calculator with 0 as the default value
96 *
97 * @param buffer_size The size of the buffer. The number of samples that constitute a valid
98 * reading
99 */
100 ExponentialMovingAverage(int buffer_size);
101 /**
102 * Create a moving average calculator with a specified default value
103 * @param buffer_size The size of the buffer. The number of samples that constitute a valid
104 * reading
105 * @param starting_value The value that the average will be before any data is added
106 */
107 ExponentialMovingAverage(int buffer_size, double starting_value);
108
109 /**
110 * Add a reading to the buffer
111 * Before:
112 * [ 1 1 2 2 3 3] => 2
113 * ^
114 * After:
115 * [ 2 1 2 2 3 3] => 2.16
116 * ^
117 * @param n the sample that will be added to the moving average.
118 */
119 void add_entry(double n) override;
120
121 /**
122 * Returns the average based off of all the samples collected so far
123 * @return the calculated average. sum(samples)/numsamples
124 */
125 double get_value() const override;
126
127 /**
128 * How many samples the average is made from
129 * @return the number of samples used to calculate this average
130 */
131 int get_size();
132
133 private:
134 int buffer_index; // index of the next value to be overridden
135 std::vector<double> buffer; // all current data readings we've taken
136 double current_avg; // the current value of the data
137};
ExponentialMovingAverage(int buffer_size, double starting_value)
ExponentialMovingAverage(int buffer_size)
double get_value() const override
void add_entry(double n) override
Definition moving_average.h:8
int get_size() const
MovingAverage(int buffer_size)
double get_value() const override
void add_entry(double n) override
MovingAverage(int buffer_size, double starting_value)