blob: 879c246ed251c81df80c772f0a26b3c40f289d72 [file] [log] [blame]
Philipp Schrader29d54f22016-04-02 22:14:48 +00001#ifndef FRC971_ZEROING_AVERAGER_H_
2#define FRC971_ZEROING_AVERAGER_H_
3
4#include <algorithm>
5#include <array>
6#include <stdint.h>
7
8namespace frc971 {
9namespace zeroing {
10
11// Averages a set of given numbers. Numbers are given one at a time. Once full
12// the average may be requested.
13template <typename data_type, size_t data_size>
14class Averager {
15 public:
16 // Adds one data point to the set of data points to be averaged.
17 // If more than "data_size" samples are added, they will start overwriting
18 // the oldest ones.
19 void AddData(data_type data) {
20 data_[data_point_index_] = data;
21 num_data_points_ = ::std::min(data_size, num_data_points_ + 1);
22 data_point_index_ = (data_point_index_ + 1) % data_size;
23 }
24
25 // Returns the average of the data points.
26 data_type GetAverage() const {
27 // TODO(phil): What do we want to do without any elements?
28 if (num_data_points_ == 0) {
29 return 0;
30 }
31
32 data_type average = 0;
33 for (data_type data : data_) {
34 average += data;
35 }
36 return average / num_data_points_;
37 }
38
39 // Returns true when we've gathered data_size data points.
40 bool full() const { return num_data_points_ >= data_size; };
41
42 size_t size() const { return data_size; }
43
44 private:
45 // Data points to be averaged.
46 ::std::array<data_type, data_size> data_;
47 // Which data point in "data_" will be filled in next.
48 size_t data_point_index_ = 0;
49 // Number of data points added via AddData().
50 size_t num_data_points_ = 0;
51};
52
53} // namespace zeroing
54} // namespace frc971
55
56#endif // FRC971_ZEROING_AVERAGER_H_