blob: e11d866ce8ba466b3a33e61b21865760ac6835d7 [file] [log] [blame]
James Kuszmaulbdc6a792023-08-12 16:29:38 -07001#ifndef FRC971_ZEROING_CONTINUOUS_ABSOLUTE_ENCODER_H_
2#define FRC971_ZEROING_CONTINUOUS_ABSOLUTE_ENCODER_H_
3
4#include <vector>
5
6#include "flatbuffers/flatbuffers.h"
7
James Kuszmaulec635d22023-08-12 18:39:24 -07008#include "aos/containers/error_list.h"
James Kuszmaulbdc6a792023-08-12 16:29:38 -07009#include "frc971/zeroing/zeroing.h"
10
11namespace frc971 {
12namespace zeroing {
13
14// Estimates the position with an absolute encoder which spins continuously. The
15// absolute encoder must have a 1:1 ratio to the output.
16// The provided offset(), when added to incremental encoder, may return a value
17// outside of +/- pi. The user is responsible for handling wrapping.
18class ContinuousAbsoluteEncoderZeroingEstimator
19 : public ZeroingEstimator<
20 AbsolutePosition,
21 constants::ContinuousAbsoluteEncoderZeroingConstants,
22 AbsoluteEncoderEstimatorState> {
23 public:
24 explicit ContinuousAbsoluteEncoderZeroingEstimator(
25 const constants::ContinuousAbsoluteEncoderZeroingConstants &constants);
26
27 // Resets the internal logic so it needs to be re-zeroed.
28 void Reset() override;
29
30 // Updates the sensor values for the zeroing logic.
31 void UpdateEstimate(const AbsolutePosition &info) override;
32
33 void TriggerError() override { error_ = true; }
34
35 bool zeroed() const override { return zeroed_; }
36
37 double offset() const override { return offset_; }
38
39 bool error() const override { return error_; }
40
41 // Returns true if the sample buffer is full.
42 bool offset_ready() const override {
43 return relative_to_absolute_offset_samples_.size() ==
44 constants_.average_filter_size;
45 }
46
47 // Returns information about our current state.
48 virtual flatbuffers::Offset<State> GetEstimatorState(
49 flatbuffers::FlatBufferBuilder *fbb) const override;
50
51 private:
52 struct PositionStruct {
53 PositionStruct(const AbsolutePosition &position_buffer)
54 : absolute_encoder(position_buffer.absolute_encoder()),
55 encoder(position_buffer.encoder()) {}
56 double absolute_encoder;
57 double encoder;
58 };
59
60 // The zeroing constants used to describe the configuration of the system.
61 const constants::ContinuousAbsoluteEncoderZeroingConstants constants_;
62
63 // True if the mechanism is zeroed.
64 bool zeroed_;
65 // Marker to track whether an error has occurred.
66 bool error_;
67 // The first valid offset we recorded. This is only set after zeroed_ first
68 // changes to true.
69 double first_offset_;
70
71 // The filtered absolute encoder. This is used in the status for calibration.
72 double filtered_absolute_encoder_ = 0.0;
73
74 // Samples of the offset needed to line the relative encoder up with the
75 // absolute encoder.
76 ::std::vector<double> relative_to_absolute_offset_samples_;
77
78 MoveDetector<PositionStruct, AbsolutePosition> move_detector_;
79
80 // Estimated start position of the mechanism
81 double offset_ = 0;
82 // The next position in 'relative_to_absolute_offset_samples_' and
83 // 'encoder_samples_' to be used to store the next sample.
84 int samples_idx_ = 0;
85
86 // Number of NANs we've seen in a row.
87 size_t nan_samples_ = 0;
88
89 // The filtered position.
90 double position_ = 0.0;
91
92 // Marker to track what kind of error has occured.
93 aos::ErrorList<ZeroingError> errors_;
94};
95
96} // namespace zeroing
97} // namespace frc971
98
99#endif // FRC971_ZEROING_CONTINUOUS_ABSOLUTE_ENCODER_H_