blob: 6e78faa2ee31235e5cd9f126b3dcd14ef707b929 [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
Brian Silvermana57b7012020-03-11 20:19:23 -07008namespace frc971 {
9namespace zeroing {
10namespace testing {
11
12using constants::AbsoluteEncoderZeroingConstants;
13
14class AbsoluteEncoderZeroingTest : public ZeroingTest {
15 protected:
16 void MoveTo(PositionSensorSimulator *simulator,
17 AbsoluteEncoderZeroingEstimator *estimator, double new_position) {
18 simulator->MoveTo(new_position);
Ravago Jones726deb02021-05-29 14:36:43 -070019 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -070020 estimator->UpdateEstimate(
21 *simulator->FillSensorValues<AbsolutePosition>(&fbb));
22 }
23};
24
25// Makes sure that using an absolute encoder lets us zero without moving.
26TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
27 const double index_diff = 1.0;
28 PositionSensorSimulator sim(index_diff);
29
30 const double kMiddlePosition = 2.5;
31 const double start_pos = 2.1;
32 double measured_absolute_position = 0.3 * index_diff;
33
James Kuszmauld12497a2024-01-14 18:00:34 -080034 AbsoluteEncoderZeroingConstants constants{{},
35 kSampleSize,
36 index_diff,
37 measured_absolute_position,
38 kMiddlePosition,
39 0.1,
40 kMovingBufferSize,
41 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -070042
43 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
44 constants.measured_absolute_position);
45
46 AbsoluteEncoderZeroingEstimator estimator(constants);
47
48 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
49 MoveTo(&sim, &estimator, start_pos);
50 ASSERT_FALSE(estimator.zeroed());
51 }
52
53 MoveTo(&sim, &estimator, start_pos);
54 ASSERT_TRUE(estimator.zeroed());
55 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
56}
57
58// Makes sure that we ignore a NAN if we get it, but will correctly zero
59// afterwards.
60TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingIgnoresNAN) {
61 const double index_diff = 1.0;
62 PositionSensorSimulator sim(index_diff);
63
64 const double start_pos = 2.1;
65 double measured_absolute_position = 0.3 * index_diff;
66 const double kMiddlePosition = 2.5;
67
James Kuszmauld12497a2024-01-14 18:00:34 -080068 AbsoluteEncoderZeroingConstants constants{{},
69 kSampleSize,
70 index_diff,
71 measured_absolute_position,
72 kMiddlePosition,
73 0.1,
74 kMovingBufferSize,
75 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -070076
77 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
78 constants.measured_absolute_position);
79
80 AbsoluteEncoderZeroingEstimator estimator(constants);
81
82 // We tolerate a couple NANs before we start.
Ravago Jones726deb02021-05-29 14:36:43 -070083 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -070084 fbb.Finish(CreateAbsolutePosition(
85 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
86 const auto sensor_values =
87 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
88 for (size_t i = 0; i < kSampleSize - 1; ++i) {
89 estimator.UpdateEstimate(*sensor_values);
90 }
91
92 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
93 MoveTo(&sim, &estimator, start_pos);
94 ASSERT_FALSE(estimator.zeroed());
95 }
96
97 MoveTo(&sim, &estimator, start_pos);
98 ASSERT_TRUE(estimator.zeroed());
99 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
100}
101
102// Makes sure that using an absolute encoder doesn't let us zero while moving.
103TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
104 const double index_diff = 1.0;
105 PositionSensorSimulator sim(index_diff);
106
107 const double start_pos = 10 * index_diff;
108 double measured_absolute_position = 0.3 * index_diff;
109 const double kMiddlePosition = 2.5;
110
James Kuszmauld12497a2024-01-14 18:00:34 -0800111 AbsoluteEncoderZeroingConstants constants{{},
112 kSampleSize,
113 index_diff,
114 measured_absolute_position,
115 kMiddlePosition,
116 0.1,
117 kMovingBufferSize,
118 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -0700119
120 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
121 constants.measured_absolute_position);
122
123 AbsoluteEncoderZeroingEstimator estimator(constants);
124
125 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
126 MoveTo(&sim, &estimator, start_pos + i * index_diff);
127 ASSERT_FALSE(estimator.zeroed());
128 }
129 MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
130
131 MoveTo(&sim, &estimator, start_pos);
132 ASSERT_FALSE(estimator.zeroed());
133}
134
135// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
136TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
James Kuszmauld12497a2024-01-14 18:00:34 -0800137 AbsoluteEncoderZeroingConstants constants{{},
138 kSampleSize,
139 1,
140 0.3,
141 1.0,
142 0.1,
143 kMovingBufferSize,
144 kIndexErrorFraction};
Brian Silvermana57b7012020-03-11 20:19:23 -0700145
146 AbsoluteEncoderZeroingEstimator estimator(constants);
147
Ravago Jones726deb02021-05-29 14:36:43 -0700148 flatbuffers::FlatBufferBuilder fbb;
Brian Silvermana57b7012020-03-11 20:19:23 -0700149 fbb.Finish(CreateAbsolutePosition(
150 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
151 const auto sensor_values =
152 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
153 for (size_t i = 0; i < kSampleSize - 1; ++i) {
154 estimator.UpdateEstimate(*sensor_values);
155 }
156 ASSERT_FALSE(estimator.error());
157
158 estimator.UpdateEstimate(*sensor_values);
159 ASSERT_TRUE(estimator.error());
Ravago Jones726deb02021-05-29 14:36:43 -0700160
161 flatbuffers::FlatBufferBuilder fbb2;
162 fbb2.Finish(estimator.GetEstimatorState(&fbb2));
163
164 const AbsoluteEncoderEstimatorState *state =
165 flatbuffers::GetRoot<AbsoluteEncoderEstimatorState>(
166 fbb2.GetBufferPointer());
167
168 EXPECT_THAT(*state->errors(),
169 ::testing::ElementsAre(ZeroingError::LOST_ABSOLUTE_ENCODER));
Brian Silvermana57b7012020-03-11 20:19:23 -0700170}
171
172} // namespace testing
173} // namespace zeroing
174} // namespace frc971