blob: aa2fb9ffdc43d87f3e6b1cf46530d8016775de24 [file] [log] [blame]
Brian Silvermana57b7012020-03-11 20:19:23 -07001#include "frc971/zeroing/absolute_encoder.h"
2
Ravago Jones726deb02021-05-29 14:36:43 -07003#include "gmock/gmock.h"
4#include "gtest/gtest.h"
Brian Silvermana57b7012020-03-11 20:19:23 -07005
Philipp Schrader790cb542023-07-05 21:06:52 -07006#include "frc971/zeroing/zeroing_test.h"
7
Stephan Pleinesf63bde82024-01-13 15:59:33 -08008namespace frc971::zeroing::testing {
Brian Silvermana57b7012020-03-11 20:19:23 -07009
10using constants::AbsoluteEncoderZeroingConstants;
11
12class AbsoluteEncoderZeroingTest : public ZeroingTest {
13 protected:
14 void MoveTo(PositionSensorSimulator *simulator,
15 AbsoluteEncoderZeroingEstimator *estimator, double new_position) {
16 simulator->MoveTo(new_position);
Ravago Jones726deb02021-05-29 14:36:43 -070017 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -070018 estimator->UpdateEstimate(
19 *simulator->FillSensorValues<AbsolutePosition>(&fbb));
20 }
21};
22
23// Makes sure that using an absolute encoder lets us zero without moving.
24TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
25 const double index_diff = 1.0;
26 PositionSensorSimulator sim(index_diff);
27
28 const double kMiddlePosition = 2.5;
29 const double start_pos = 2.1;
30 double measured_absolute_position = 0.3 * index_diff;
31
James Kuszmauld12497a2024-01-14 18:00:34 -080032 AbsoluteEncoderZeroingConstants constants{{},
33 kSampleSize,
34 index_diff,
35 measured_absolute_position,
36 kMiddlePosition,
37 0.1,
38 kMovingBufferSize,
39 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -070040
41 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
42 constants.measured_absolute_position);
43
44 AbsoluteEncoderZeroingEstimator estimator(constants);
45
46 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
47 MoveTo(&sim, &estimator, start_pos);
48 ASSERT_FALSE(estimator.zeroed());
49 }
50
51 MoveTo(&sim, &estimator, start_pos);
52 ASSERT_TRUE(estimator.zeroed());
53 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
54}
55
56// Makes sure that we ignore a NAN if we get it, but will correctly zero
57// afterwards.
58TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingIgnoresNAN) {
59 const double index_diff = 1.0;
60 PositionSensorSimulator sim(index_diff);
61
62 const double start_pos = 2.1;
63 double measured_absolute_position = 0.3 * index_diff;
64 const double kMiddlePosition = 2.5;
65
James Kuszmauld12497a2024-01-14 18:00:34 -080066 AbsoluteEncoderZeroingConstants constants{{},
67 kSampleSize,
68 index_diff,
69 measured_absolute_position,
70 kMiddlePosition,
71 0.1,
72 kMovingBufferSize,
73 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -070074
75 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
76 constants.measured_absolute_position);
77
78 AbsoluteEncoderZeroingEstimator estimator(constants);
79
80 // We tolerate a couple NANs before we start.
Ravago Jones726deb02021-05-29 14:36:43 -070081 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -070082 fbb.Finish(CreateAbsolutePosition(
83 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
84 const auto sensor_values =
85 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
86 for (size_t i = 0; i < kSampleSize - 1; ++i) {
87 estimator.UpdateEstimate(*sensor_values);
88 }
89
90 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
91 MoveTo(&sim, &estimator, start_pos);
92 ASSERT_FALSE(estimator.zeroed());
93 }
94
95 MoveTo(&sim, &estimator, start_pos);
96 ASSERT_TRUE(estimator.zeroed());
97 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
98}
99
100// Makes sure that using an absolute encoder doesn't let us zero while moving.
101TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
102 const double index_diff = 1.0;
103 PositionSensorSimulator sim(index_diff);
104
105 const double start_pos = 10 * index_diff;
106 double measured_absolute_position = 0.3 * index_diff;
107 const double kMiddlePosition = 2.5;
108
James Kuszmauld12497a2024-01-14 18:00:34 -0800109 AbsoluteEncoderZeroingConstants constants{{},
110 kSampleSize,
111 index_diff,
112 measured_absolute_position,
113 kMiddlePosition,
114 0.1,
115 kMovingBufferSize,
116 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -0700117
118 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
119 constants.measured_absolute_position);
120
121 AbsoluteEncoderZeroingEstimator estimator(constants);
122
123 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
124 MoveTo(&sim, &estimator, start_pos + i * index_diff);
125 ASSERT_FALSE(estimator.zeroed());
126 }
127 MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
128
129 MoveTo(&sim, &estimator, start_pos);
130 ASSERT_FALSE(estimator.zeroed());
131}
132
133// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
134TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
James Kuszmauld12497a2024-01-14 18:00:34 -0800135 AbsoluteEncoderZeroingConstants constants{{},
136 kSampleSize,
137 1,
138 0.3,
139 1.0,
140 0.1,
141 kMovingBufferSize,
142 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -0700143
144 AbsoluteEncoderZeroingEstimator estimator(constants);
145
Ravago Jones726deb02021-05-29 14:36:43 -0700146 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -0700147 fbb.Finish(CreateAbsolutePosition(
148 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
149 const auto sensor_values =
150 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
151 for (size_t i = 0; i < kSampleSize - 1; ++i) {
152 estimator.UpdateEstimate(*sensor_values);
153 }
154 ASSERT_FALSE(estimator.error());
155
156 estimator.UpdateEstimate(*sensor_values);
157 ASSERT_TRUE(estimator.error());
Ravago Jones726deb02021-05-29 14:36:43 -0700158
159 flatbuffers::FlatBufferBuilder fbb2;
160 fbb2.Finish(estimator.GetEstimatorState(&fbb2));
161
162 const AbsoluteEncoderEstimatorState *state =
163 flatbuffers::GetRoot<AbsoluteEncoderEstimatorState>(
164 fbb2.GetBufferPointer());
165
166 EXPECT_THAT(*state->errors(),
167 ::testing::ElementsAre(ZeroingError::LOST_ABSOLUTE_ENCODER));
Brian Silvermana57b7012020-03-11 20:19:23 -0700168}
169
Stephan Pleinesf63bde82024-01-13 15:59:33 -0800170} // namespace frc971::zeroing::testing