blob: 473c674bd3ed6f03540490b0e65628283c49d3c3 [file] [log] [blame]
Brian Silvermana57b7012020-03-11 20:19:23 -07001#ifndef FRC971_ZEROING_POT_AND_INDEX_H_
2#define FRC971_ZEROING_POT_AND_INDEX_H_
3
4#include <vector>
5
6#include "flatbuffers/flatbuffers.h"
7
8#include "frc971/zeroing/zeroing.h"
9
10namespace frc971 {
11namespace zeroing {
12
13// Estimates the position with an incremental encoder with an index pulse and a
14// potentiometer.
15class PotAndIndexPulseZeroingEstimator
16 : public ZeroingEstimator<PotAndIndexPosition,
17 constants::PotAndIndexPulseZeroingConstants,
18 EstimatorState> {
19 public:
20 explicit PotAndIndexPulseZeroingEstimator(
21 const constants::PotAndIndexPulseZeroingConstants &constants);
22
23 // Update the internal logic with the next sensor values.
24 void UpdateEstimate(const PotAndIndexPosition &info) override;
25
26 // Reset the internal logic so it needs to be re-zeroed.
27 void Reset() override;
28
29 // Manually trigger an internal error. This is used for testing the error
30 // logic.
31 void TriggerError() override;
32
33 bool error() const override { return error_; }
34
35 bool zeroed() const override { return zeroed_; }
36
37 double offset() const override { return offset_; }
38
39 // Returns a number between 0 and 1 that represents the percentage of the
40 // samples being used in the moving average filter. A value of 0.0 means that
41 // no samples are being used. A value of 1.0 means that the filter is using
42 // as many samples as it has room for. For example, after a Reset() this
43 // value returns 0.0. As more samples get added with UpdateEstimate(...) the
44 // return value starts increasing to 1.0.
45 double offset_ratio_ready() const {
46 return start_pos_samples_.size() /
47 static_cast<double>(constants_.average_filter_size);
48 }
49
50 // Returns true if the sample buffer is full.
51 bool offset_ready() const override {
52 return start_pos_samples_.size() == constants_.average_filter_size;
53 }
54
55 // Returns information about our current state.
56 virtual flatbuffers::Offset<State> GetEstimatorState(
57 flatbuffers::FlatBufferBuilder *fbb) const override;
58
59 private:
60 // This function calculates the start position given the internal state and
61 // the provided `latched_encoder' value.
62 double CalculateStartPosition(double start_average,
63 double latched_encoder) const;
64
65 // The zeroing constants used to describe the configuration of the system.
66 const constants::PotAndIndexPulseZeroingConstants constants_;
67
68 // The estimated position.
69 double position_;
70 // The unzeroed filtered position.
71 double filtered_position_ = 0.0;
72 // The next position in 'start_pos_samples_' to be used to store the next
73 // sample.
74 int samples_idx_;
75 // Last 'max_sample_count_' samples for start positions.
76 std::vector<double> start_pos_samples_;
77 // The estimated starting position of the mechanism. We also call this the
78 // 'offset' in some contexts.
79 double offset_;
80 // Flag for triggering logic that takes note of the current index pulse count
81 // after a reset. See `last_used_index_pulse_count_'.
82 bool wait_for_index_pulse_;
83 // After a reset we keep track of the index pulse count with this. Only after
84 // the index pulse count changes (i.e. increments at least once or wraps
85 // around) will we consider the mechanism zeroed. We also use this to store
86 // the most recent `PotAndIndexPosition::index_pulses' value when the start
87 // position was calculated. It helps us calculate the start position only on
88 // index pulses to reject corrupted intermediate data.
89 uint32_t last_used_index_pulse_count_;
90 // Marker to track whether we're fully zeroed yet or not.
91 bool zeroed_;
92 // Marker to track whether an error has occurred. This gets reset to false
93 // whenever Reset() is called.
94 bool error_;
95 // Stores the position "start_pos" variable the first time the program
96 // is zeroed.
97 double first_start_pos_;
98};
99
100} // namespace zeroing
101} // namespace frc971
102
103#endif // FRC971_ZEROING_POT_AND_INDEX_H_