blob: 61d2d0c1eca76016c5d669863eb1743beea46f08 [file] [log] [blame]
Adam Snaiderc4b3c192015-02-01 01:30:39 +00001#include <unistd.h>
2
3#include <memory>
4
5#include <random>
6
7#include "gtest/gtest.h"
Alex Perrycb7da4b2019-08-28 19:35:56 -07008#include "frc971/control_loops/control_loops_generated.h"
Adam Snaiderc4b3c192015-02-01 01:30:39 +00009#include "frc971/zeroing/zeroing.h"
John Park33858a32018-09-28 23:05:48 -070010#include "aos/die.h"
Adam Snaiderb4119252015-02-15 01:30:57 +000011#include "frc971/control_loops/position_sensor_sim.h"
Adam Snaiderc4b3c192015-02-01 01:30:39 +000012
13namespace frc971 {
14namespace zeroing {
15
Austin Schuhd82068e2019-01-26 20:05:42 -080016using constants::AbsoluteEncoderZeroingConstants;
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000017using constants::EncoderPlusIndexZeroingConstants;
Austin Schuhd82068e2019-01-26 20:05:42 -080018using constants::PotAndAbsoluteEncoderZeroingConstants;
19using constants::PotAndIndexPulseZeroingConstants;
Alex Perrycb7da4b2019-08-28 19:35:56 -070020using control_loops::PositionSensorSimulator;
21using FBB = flatbuffers::FlatBufferBuilder;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000022
Adam Snaiderb4119252015-02-15 01:30:57 +000023static const size_t kSampleSize = 30;
24static const double kAcceptableUnzeroedError = 0.2;
Adam Snaider3cd11c52015-02-16 02:16:09 +000025static const double kIndexErrorFraction = 0.3;
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -080026static const size_t kMovingBufferSize = 3;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000027
Adam Snaiderb4119252015-02-15 01:30:57 +000028class ZeroingTest : public ::testing::Test {
Adam Snaiderc4b3c192015-02-01 01:30:39 +000029 protected:
Alex Perrycb7da4b2019-08-28 19:35:56 -070030 void SetUp() override {}
Adam Snaiderc4b3c192015-02-01 01:30:39 +000031
Tyler Chatowf8f03112017-02-05 14:31:34 -080032 void MoveTo(PositionSensorSimulator *simulator,
33 PotAndIndexPulseZeroingEstimator *estimator,
Adam Snaiderb4119252015-02-15 01:30:57 +000034 double new_position) {
Adam Snaiderb4119252015-02-15 01:30:57 +000035 simulator->MoveTo(new_position);
Alex Perrycb7da4b2019-08-28 19:35:56 -070036 FBB fbb;
37 estimator->UpdateEstimate(
38 *simulator->FillSensorValues<PotAndIndexPosition>(&fbb));
Adam Snaiderb4119252015-02-15 01:30:57 +000039 }
Adam Snaiderc4b3c192015-02-01 01:30:39 +000040
Austin Schuh5f01f152017-02-11 21:34:08 -080041 void MoveTo(PositionSensorSimulator *simulator,
Alex Perrycb7da4b2019-08-28 19:35:56 -070042 AbsoluteEncoderZeroingEstimator *estimator, double new_position) {
Austin Schuhd82068e2019-01-26 20:05:42 -080043 simulator->MoveTo(new_position);
Alex Perrycb7da4b2019-08-28 19:35:56 -070044 FBB fbb;
45 estimator->UpdateEstimate(
46 *simulator->FillSensorValues<AbsolutePosition>(&fbb));
Austin Schuhd82068e2019-01-26 20:05:42 -080047 }
48
49 void MoveTo(PositionSensorSimulator *simulator,
Austin Schuh72db9a12019-01-21 18:02:51 -080050 PotAndAbsoluteEncoderZeroingEstimator *estimator,
Neil Balch16275e32017-02-18 16:38:45 -080051 double new_position) {
Austin Schuh5f01f152017-02-11 21:34:08 -080052 simulator->MoveTo(new_position);
Alex Perrycb7da4b2019-08-28 19:35:56 -070053 FBB fbb;
54 estimator->UpdateEstimate(
55 *simulator->FillSensorValues<PotAndAbsolutePosition>(&fbb));
Austin Schuh5f01f152017-02-11 21:34:08 -080056 }
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000057
58 void MoveTo(PositionSensorSimulator *simulator,
59 PulseIndexZeroingEstimator *estimator, double new_position) {
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000060 simulator->MoveTo(new_position);
Alex Perrycb7da4b2019-08-28 19:35:56 -070061 FBB fbb;
62 estimator->UpdateEstimate(
63 *simulator->FillSensorValues<IndexPosition>(&fbb));
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000064 }
Austin Schuh5f01f152017-02-11 21:34:08 -080065
Austin Schuh55934032017-03-11 12:45:27 -080066 void MoveTo(PositionSensorSimulator *simulator,
67 HallEffectAndPositionZeroingEstimator *estimator,
68 double new_position) {
Austin Schuh55934032017-03-11 12:45:27 -080069 simulator->MoveTo(new_position);
Alex Perrycb7da4b2019-08-28 19:35:56 -070070 FBB fbb;
71 estimator->UpdateEstimate(
72 *simulator->FillSensorValues<HallEffectAndPosition>(&fbb));
Austin Schuh55934032017-03-11 12:45:27 -080073 }
74
Alex Perrycb7da4b2019-08-28 19:35:56 -070075 template <typename T>
76 double GetEstimatorPosition(T *estimator) {
77 FBB fbb;
78 fbb.Finish(estimator->GetEstimatorState(&fbb));
79 return flatbuffers::GetRoot<typename T::State>(fbb.GetBufferPointer())
80 ->position();
81 }
Adam Snaiderc4b3c192015-02-01 01:30:39 +000082};
83
Adam Snaiderb4119252015-02-15 01:30:57 +000084TEST_F(ZeroingTest, TestMovingAverageFilter) {
85 const double index_diff = 1.0;
86 PositionSensorSimulator sim(index_diff);
87 sim.Initialize(3.6 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -080088 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +000089 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +000090
91 // The zeroing code is supposed to perform some filtering on the difference
92 // between the potentiometer value and the encoder value. We assume that 300
93 // samples are sufficient to have updated the filter.
94 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +000095 MoveTo(&sim, &estimator, 3.3 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000096 }
Alex Perrycb7da4b2019-08-28 19:35:56 -070097 ASSERT_NEAR(3.3 * index_diff, GetEstimatorPosition(&estimator),
Adam Snaiderb4119252015-02-15 01:30:57 +000098 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000099
100 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000101 MoveTo(&sim, &estimator, 3.9 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000102 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700103 ASSERT_NEAR(3.9 * index_diff, GetEstimatorPosition(&estimator),
Adam Snaiderb4119252015-02-15 01:30:57 +0000104 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000105}
106
Adam Snaiderb4119252015-02-15 01:30:57 +0000107TEST_F(ZeroingTest, NotZeroedBeforeEnoughSamplesCollected) {
108 double index_diff = 0.5;
109 double position = 3.6 * index_diff;
110 PositionSensorSimulator sim(index_diff);
111 sim.Initialize(position, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800112 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000113 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000114
115 // Make sure that the zeroing code does not consider itself zeroed until we
116 // collect a good amount of samples. In this case we're waiting until the
117 // moving average filter is full.
118 for (unsigned int i = 0; i < kSampleSize - 1; i++) {
119 MoveTo(&sim, &estimator, position += index_diff);
120 ASSERT_FALSE(estimator.zeroed());
121 }
122
123 MoveTo(&sim, &estimator, position);
124 ASSERT_TRUE(estimator.zeroed());
125}
126
127TEST_F(ZeroingTest, TestLotsOfMovement) {
128 double index_diff = 1.0;
129 PositionSensorSimulator sim(index_diff);
130 sim.Initialize(3.6, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800131 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000132 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000133
134 // The zeroing code is supposed to perform some filtering on the difference
135 // between the potentiometer value and the encoder value. We assume that 300
136 // samples are sufficient to have updated the filter.
137 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000138 MoveTo(&sim, &estimator, 3.6);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000139 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700140 ASSERT_NEAR(3.6, GetEstimatorPosition(&estimator),
Brian Silvermanf37839c2017-02-19 18:07:15 -0800141 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000142
143 // With a single index pulse the zeroing estimator should be able to lock
144 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000145 MoveTo(&sim, &estimator, 4.01);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700146 ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000147
Adam Snaiderb4119252015-02-15 01:30:57 +0000148 MoveTo(&sim, &estimator, 4.99);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700149 ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000150
Adam Snaiderb4119252015-02-15 01:30:57 +0000151 MoveTo(&sim, &estimator, 3.99);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700152 ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000153
Adam Snaiderb4119252015-02-15 01:30:57 +0000154 MoveTo(&sim, &estimator, 3.01);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700155 ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000156
Adam Snaiderb4119252015-02-15 01:30:57 +0000157 MoveTo(&sim, &estimator, 13.55);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700158 ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000159}
160
Adam Snaiderb4119252015-02-15 01:30:57 +0000161TEST_F(ZeroingTest, TestDifferentIndexDiffs) {
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000162 double index_diff = 0.89;
Adam Snaiderb4119252015-02-15 01:30:57 +0000163 PositionSensorSimulator sim(index_diff);
164 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800165 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000166 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000167
168 // The zeroing code is supposed to perform some filtering on the difference
169 // between the potentiometer value and the encoder value. We assume that 300
170 // samples are sufficient to have updated the filter.
171 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000172 MoveTo(&sim, &estimator, 3.5 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000173 }
Alex Perrycb7da4b2019-08-28 19:35:56 -0700174 ASSERT_NEAR(3.5 * index_diff, GetEstimatorPosition(&estimator),
Adam Snaiderb4119252015-02-15 01:30:57 +0000175 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000176
177 // With a single index pulse the zeroing estimator should be able to lock
178 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000179 MoveTo(&sim, &estimator, 4.01);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700180 ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000181
Adam Snaiderb4119252015-02-15 01:30:57 +0000182 MoveTo(&sim, &estimator, 4.99);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700183 ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000184
Adam Snaiderb4119252015-02-15 01:30:57 +0000185 MoveTo(&sim, &estimator, 3.99);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700186 ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000187
Adam Snaiderb4119252015-02-15 01:30:57 +0000188 MoveTo(&sim, &estimator, 3.01);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700189 ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000190
Adam Snaiderb4119252015-02-15 01:30:57 +0000191 MoveTo(&sim, &estimator, 13.55);
Alex Perrycb7da4b2019-08-28 19:35:56 -0700192 ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
Adam Snaiderb4119252015-02-15 01:30:57 +0000193}
194
195TEST_F(ZeroingTest, TestPercentage) {
196 double index_diff = 0.89;
197 PositionSensorSimulator sim(index_diff);
198 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800199 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000200 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000201
202 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
203 MoveTo(&sim, &estimator, 3.5 * index_diff);
204 }
205 ASSERT_NEAR(0.5, estimator.offset_ratio_ready(), 0.001);
Austin Schuh7485dbb2016-02-08 00:21:58 -0800206 ASSERT_FALSE(estimator.offset_ready());
207
208 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
209 MoveTo(&sim, &estimator, 3.5 * index_diff);
210 }
211 ASSERT_NEAR(1.0, estimator.offset_ratio_ready(), 0.001);
212 ASSERT_TRUE(estimator.offset_ready());
Adam Snaiderb4119252015-02-15 01:30:57 +0000213}
214
215TEST_F(ZeroingTest, TestOffset) {
216 double index_diff = 0.89;
217 PositionSensorSimulator sim(index_diff);
218 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800219 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000220 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000221
Philipp Schrader41d82912015-02-15 03:44:23 +0000222 MoveTo(&sim, &estimator, 3.1 * index_diff);
223
Adam Snaiderb4119252015-02-15 01:30:57 +0000224 for (unsigned int i = 0; i < kSampleSize; i++) {
225 MoveTo(&sim, &estimator, 5.0 * index_diff);
226 }
Philipp Schrader41d82912015-02-15 03:44:23 +0000227
Adam Snaiderb4119252015-02-15 01:30:57 +0000228 ASSERT_NEAR(3.1 * index_diff, estimator.offset(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000229}
230
Philipp Schrader41d82912015-02-15 03:44:23 +0000231TEST_F(ZeroingTest, WaitForIndexPulseAfterReset) {
232 double index_diff = 0.6;
233 PositionSensorSimulator sim(index_diff);
234 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800235 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000236 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader41d82912015-02-15 03:44:23 +0000237
238 // Make sure to fill up the averaging filter with samples.
239 for (unsigned int i = 0; i < kSampleSize; i++) {
240 MoveTo(&sim, &estimator, 3.1 * index_diff);
241 }
242
243 // Make sure we're not zeroed until we hit an index pulse.
244 ASSERT_FALSE(estimator.zeroed());
245
246 // Trigger an index pulse; we should now be zeroed.
247 MoveTo(&sim, &estimator, 4.5 * index_diff);
248 ASSERT_TRUE(estimator.zeroed());
249
250 // Reset the zeroing logic and supply a bunch of samples within the current
251 // index segment.
252 estimator.Reset();
253 for (unsigned int i = 0; i < kSampleSize; i++) {
254 MoveTo(&sim, &estimator, 4.2 * index_diff);
255 }
256
257 // Make sure we're not zeroed until we hit an index pulse.
258 ASSERT_FALSE(estimator.zeroed());
259
260 // Trigger another index pulse; we should be zeroed again.
261 MoveTo(&sim, &estimator, 3.1 * index_diff);
262 ASSERT_TRUE(estimator.zeroed());
263}
264
Philipp Schrader030ad182015-02-15 05:40:58 +0000265TEST_F(ZeroingTest, TestNonZeroIndexPulseOffsets) {
266 const double index_diff = 0.9;
267 const double known_index_pos = 3.5 * index_diff;
268 PositionSensorSimulator sim(index_diff);
269 sim.Initialize(3.3 * index_diff, index_diff / 3.0, known_index_pos);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800270 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000271 kSampleSize, index_diff, known_index_pos, kIndexErrorFraction});
Philipp Schrader030ad182015-02-15 05:40:58 +0000272
273 // Make sure to fill up the averaging filter with samples.
274 for (unsigned int i = 0; i < kSampleSize; i++) {
275 MoveTo(&sim, &estimator, 3.3 * index_diff);
276 }
277
278 // Make sure we're not zeroed until we hit an index pulse.
279 ASSERT_FALSE(estimator.zeroed());
280
281 // Trigger an index pulse; we should now be zeroed.
282 MoveTo(&sim, &estimator, 3.7 * index_diff);
283 ASSERT_TRUE(estimator.zeroed());
284 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700285 ASSERT_DOUBLE_EQ(3.7 * index_diff, GetEstimatorPosition(&estimator));
Philipp Schrader030ad182015-02-15 05:40:58 +0000286
287 // Trigger one more index pulse and check the offset.
288 MoveTo(&sim, &estimator, 4.7 * index_diff);
289 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
Alex Perrycb7da4b2019-08-28 19:35:56 -0700290 ASSERT_DOUBLE_EQ(4.7 * index_diff, GetEstimatorPosition(&estimator));
Philipp Schrader030ad182015-02-15 05:40:58 +0000291}
292
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000293TEST_F(ZeroingTest, BasicErrorAPITest) {
294 const double index_diff = 1.0;
Tyler Chatowf8f03112017-02-05 14:31:34 -0800295 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000296 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000297 PositionSensorSimulator sim(index_diff);
298 sim.Initialize(1.5 * index_diff, index_diff / 3.0, 0.0);
299
300 // Perform a simple move and make sure that no error occured.
301 MoveTo(&sim, &estimator, 3.5 * index_diff);
302 ASSERT_FALSE(estimator.error());
303
304 // Trigger an error and make sure it's reported.
305 estimator.TriggerError();
306 ASSERT_TRUE(estimator.error());
307
308 // Make sure that it can recover after a reset.
309 estimator.Reset();
310 ASSERT_FALSE(estimator.error());
311 MoveTo(&sim, &estimator, 4.5 * index_diff);
312 MoveTo(&sim, &estimator, 5.5 * index_diff);
313 ASSERT_FALSE(estimator.error());
314}
315
Brian Silvermana10d20a2017-02-19 14:28:53 -0800316// Tests that an error is detected when the starting position changes too much.
317TEST_F(ZeroingTest, TestIndexOffsetError) {
Adam Snaider3cd11c52015-02-16 02:16:09 +0000318 const double index_diff = 0.8;
319 const double known_index_pos = 2 * index_diff;
Austin Schuh5f01f152017-02-11 21:34:08 -0800320 const size_t sample_size = 30;
Adam Snaider3cd11c52015-02-16 02:16:09 +0000321 PositionSensorSimulator sim(index_diff);
322 sim.Initialize(10 * index_diff, index_diff / 3.0, known_index_pos);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800323 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000324 sample_size, index_diff, known_index_pos, kIndexErrorFraction});
325
Austin Schuh5f01f152017-02-11 21:34:08 -0800326 for (size_t i = 0; i < sample_size; i++) {
Adam Snaider3cd11c52015-02-16 02:16:09 +0000327 MoveTo(&sim, &estimator, 13 * index_diff);
328 }
329 MoveTo(&sim, &estimator, 8 * index_diff);
330
331 ASSERT_TRUE(estimator.zeroed());
332 ASSERT_FALSE(estimator.error());
333 sim.Initialize(9.0 * index_diff + 0.31 * index_diff, index_diff / 3.0,
334 known_index_pos);
335 MoveTo(&sim, &estimator, 9 * index_diff);
336 ASSERT_TRUE(estimator.zeroed());
337 ASSERT_TRUE(estimator.error());
338}
339
Austin Schuh5f01f152017-02-11 21:34:08 -0800340// Makes sure that using an absolute encoder lets us zero without moving.
Austin Schuhd82068e2019-01-26 20:05:42 -0800341TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithoutMovement) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800342 const double index_diff = 1.0;
343 PositionSensorSimulator sim(index_diff);
344
345 const double start_pos = 2.1;
346 double measured_absolute_position = 0.3 * index_diff;
347
Brian Silvermana10d20a2017-02-19 14:28:53 -0800348 PotAndAbsoluteEncoderZeroingConstants constants{
349 kSampleSize, index_diff, measured_absolute_position,
350 0.1, kMovingBufferSize, kIndexErrorFraction};
Austin Schuh5f01f152017-02-11 21:34:08 -0800351
352 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
353 constants.measured_absolute_position);
354
Austin Schuh72db9a12019-01-21 18:02:51 -0800355 PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
Austin Schuh5f01f152017-02-11 21:34:08 -0800356
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800357 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800358 MoveTo(&sim, &estimator, start_pos);
359 ASSERT_FALSE(estimator.zeroed());
360 }
361
362 MoveTo(&sim, &estimator, start_pos);
363 ASSERT_TRUE(estimator.zeroed());
364 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
365}
366
Austin Schuhddd08f82018-03-02 20:05:29 -0800367// Makes sure that we ignore a NAN if we get it, but will correctly zero
Austin Schuhd82068e2019-01-26 20:05:42 -0800368// afterwards.
369TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingIgnoresNAN) {
Austin Schuhddd08f82018-03-02 20:05:29 -0800370 const double index_diff = 1.0;
371 PositionSensorSimulator sim(index_diff);
372
373 const double start_pos = 2.1;
374 double measured_absolute_position = 0.3 * index_diff;
375
376 PotAndAbsoluteEncoderZeroingConstants constants{
377 kSampleSize, index_diff, measured_absolute_position,
378 0.1, kMovingBufferSize, kIndexErrorFraction};
379
380 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
381 constants.measured_absolute_position);
382
Austin Schuh72db9a12019-01-21 18:02:51 -0800383 PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
Austin Schuhddd08f82018-03-02 20:05:29 -0800384
385 // We tolerate a couple NANs before we start.
Alex Perrycb7da4b2019-08-28 19:35:56 -0700386 FBB fbb;
387 fbb.Finish(CreatePotAndAbsolutePosition(
388 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
Austin Schuhddd08f82018-03-02 20:05:29 -0800389 for (size_t i = 0; i < kSampleSize - 1; ++i) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700390 estimator.UpdateEstimate(
391 *flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer()));
Austin Schuhddd08f82018-03-02 20:05:29 -0800392 }
393
394 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
395 MoveTo(&sim, &estimator, start_pos);
396 ASSERT_FALSE(estimator.zeroed());
397 }
398
399 MoveTo(&sim, &estimator, start_pos);
400 ASSERT_TRUE(estimator.zeroed());
401 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
402}
403
Austin Schuh5f01f152017-02-11 21:34:08 -0800404// Makes sure that using an absolute encoder doesn't let us zero while moving.
Austin Schuhd82068e2019-01-26 20:05:42 -0800405TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithMovement) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800406 const double index_diff = 1.0;
407 PositionSensorSimulator sim(index_diff);
408
409 const double start_pos = 10 * index_diff;
410 double measured_absolute_position = 0.3 * index_diff;
411
Brian Silvermana10d20a2017-02-19 14:28:53 -0800412 PotAndAbsoluteEncoderZeroingConstants constants{
413 kSampleSize, index_diff, measured_absolute_position,
414 0.1, kMovingBufferSize, kIndexErrorFraction};
Austin Schuh5f01f152017-02-11 21:34:08 -0800415
416 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
417 constants.measured_absolute_position);
418
Austin Schuh72db9a12019-01-21 18:02:51 -0800419 PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
Austin Schuh5f01f152017-02-11 21:34:08 -0800420
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800421 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800422 MoveTo(&sim, &estimator, start_pos + i * index_diff);
423 ASSERT_FALSE(estimator.zeroed());
424 }
425 MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
426
427 MoveTo(&sim, &estimator, start_pos);
428 ASSERT_FALSE(estimator.zeroed());
429}
Neil Balch16275e32017-02-18 16:38:45 -0800430
431// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
Austin Schuhd82068e2019-01-26 20:05:42 -0800432TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithNaN) {
Neil Balch16275e32017-02-18 16:38:45 -0800433 PotAndAbsoluteEncoderZeroingConstants constants{
Brian Silvermana10d20a2017-02-19 14:28:53 -0800434 kSampleSize, 1, 0.3, 0.1, kMovingBufferSize, kIndexErrorFraction};
Neil Balch16275e32017-02-18 16:38:45 -0800435
Austin Schuh72db9a12019-01-21 18:02:51 -0800436 PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
Neil Balch16275e32017-02-18 16:38:45 -0800437
Alex Perrycb7da4b2019-08-28 19:35:56 -0700438 FBB fbb;
439 fbb.Finish(CreatePotAndAbsolutePosition(
440 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
441 const auto sensor_values =
442 flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer());
Austin Schuhddd08f82018-03-02 20:05:29 -0800443 for (size_t i = 0; i < kSampleSize - 1; ++i) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700444 estimator.UpdateEstimate(*sensor_values);
Austin Schuhddd08f82018-03-02 20:05:29 -0800445 }
446 ASSERT_FALSE(estimator.error());
Neil Balch16275e32017-02-18 16:38:45 -0800447
Alex Perrycb7da4b2019-08-28 19:35:56 -0700448 estimator.UpdateEstimate(*sensor_values);
Neil Balch16275e32017-02-18 16:38:45 -0800449 ASSERT_TRUE(estimator.error());
450}
451
Brian Silvermana10d20a2017-02-19 14:28:53 -0800452// Tests that an error is detected when the starting position changes too much.
Isaac Wilcove0851ffd2017-02-16 04:13:14 +0000453TEST_F(ZeroingTest, TestRelativeEncoderZeroing) {
454 EncoderPlusIndexZeroingConstants constants;
455 constants.index_pulse_count = 3;
456 constants.index_difference = 10.0;
457 constants.measured_index_position = 20.0;
458 constants.known_index_pulse = 1;
Philipp Schrader3f5b6182017-03-25 22:36:37 +0000459 constants.allowable_encoder_error = 0.01;
Isaac Wilcove0851ffd2017-02-16 04:13:14 +0000460
461 PositionSensorSimulator sim(constants.index_difference);
462
463 const double start_pos = 2.5 * constants.index_difference;
464
465 sim.Initialize(start_pos, constants.index_difference / 3.0,
466 constants.measured_index_position);
467
468 PulseIndexZeroingEstimator estimator(constants);
469
470 // Should not be zeroed when we stand still.
471 for (int i = 0; i < 300; ++i) {
472 MoveTo(&sim, &estimator, start_pos);
473 ASSERT_FALSE(estimator.zeroed());
474 }
475
476 // Move to 1.5 constants.index_difference and we should still not be zeroed.
477 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
478 ASSERT_FALSE(estimator.zeroed());
479
480 // Move to 0.5 constants.index_difference and we should still not be zeroed.
481 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
482 ASSERT_FALSE(estimator.zeroed());
483
484 // Move back to 1.5 constants.index_difference and we should still not be
485 // zeroed.
486 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
487 ASSERT_FALSE(estimator.zeroed());
488
489 // Move back to 2.5 constants.index_difference and we should still not be
490 // zeroed.
491 MoveTo(&sim, &estimator, 2.5 * constants.index_difference);
492 ASSERT_FALSE(estimator.zeroed());
493
494 // Move back to 3.5 constants.index_difference and we should now be zeroed.
495 MoveTo(&sim, &estimator, 3.5 * constants.index_difference);
496 ASSERT_TRUE(estimator.zeroed());
497
498 ASSERT_DOUBLE_EQ(start_pos, estimator.offset());
Brian Silvermanf37839c2017-02-19 18:07:15 -0800499 ASSERT_DOUBLE_EQ(3.5 * constants.index_difference,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700500 GetEstimatorPosition(&estimator));
Isaac Wilcove0851ffd2017-02-16 04:13:14 +0000501
502 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
Brian Silvermanf37839c2017-02-19 18:07:15 -0800503 ASSERT_DOUBLE_EQ(0.5 * constants.index_difference,
Alex Perrycb7da4b2019-08-28 19:35:56 -0700504 GetEstimatorPosition(&estimator));
Isaac Wilcove0851ffd2017-02-16 04:13:14 +0000505}
506
Philipp Schrader3f5b6182017-03-25 22:36:37 +0000507// Tests that we can detect when an index pulse occurs where we didn't expect
508// it to for the PulseIndexZeroingEstimator.
509TEST_F(ZeroingTest, TestRelativeEncoderSlipping) {
510 EncoderPlusIndexZeroingConstants constants;
511 constants.index_pulse_count = 3;
512 constants.index_difference = 10.0;
513 constants.measured_index_position = 20.0;
514 constants.known_index_pulse = 1;
515 constants.allowable_encoder_error = 0.05;
516
517 PositionSensorSimulator sim(constants.index_difference);
518
519 const double start_pos =
520 constants.measured_index_position + 0.5 * constants.index_difference;
521
522 for (double direction : {1.0, -1.0}) {
523 sim.Initialize(start_pos, constants.index_difference / 3.0,
524 constants.measured_index_position);
525
526 PulseIndexZeroingEstimator estimator(constants);
527
528 // Zero the estimator.
529 MoveTo(&sim, &estimator, start_pos - 1 * constants.index_difference);
530 MoveTo(
531 &sim, &estimator,
532 start_pos - constants.index_pulse_count * constants.index_difference);
533 ASSERT_TRUE(estimator.zeroed());
534 ASSERT_FALSE(estimator.error());
535
536 // We have a 5% allowable error so we slip a little bit each time and make
537 // sure that the index pulses are still accepted.
538 for (double error = 0.00;
539 ::std::abs(error) < constants.allowable_encoder_error;
540 error += 0.01 * direction) {
541 sim.Initialize(start_pos, constants.index_difference / 3.0,
542 constants.measured_index_position +
543 error * constants.index_difference);
544 MoveTo(&sim, &estimator, start_pos - constants.index_difference);
545 EXPECT_FALSE(estimator.error());
546 }
547
548 // As soon as we hit cross the error margin, we should trigger an error.
549 sim.Initialize(start_pos, constants.index_difference / 3.0,
550 constants.measured_index_position +
551 constants.allowable_encoder_error * 1.1 *
552 constants.index_difference * direction);
553 MoveTo(&sim, &estimator, start_pos - constants.index_difference);
554 ASSERT_TRUE(estimator.error());
555 }
556}
557
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700558// Test fixture for HallEffectAndPositionZeroingEstimator.
559class HallEffectAndPositionZeroingEstimatorTest : public ZeroingTest {
560 public:
561 // The starting position of the system.
562 static constexpr double kStartPosition = 2.0;
563
564 // Returns a reasonable set of test constants.
565 static constants::HallEffectZeroingConstants MakeConstants() {
566 constants::HallEffectZeroingConstants constants;
567 constants.lower_hall_position = 0.25;
568 constants.upper_hall_position = 0.75;
569 constants.index_difference = 1.0;
570 constants.hall_trigger_zeroing_length = 2;
571 constants.zeroing_move_direction = false;
572 return constants;
573 }
574
575 HallEffectAndPositionZeroingEstimatorTest()
576 : constants_(MakeConstants()), sim_(constants_.index_difference) {
577 // Start the system out at the starting position.
578 sim_.InitializeHallEffectAndPosition(kStartPosition,
579 constants_.lower_hall_position,
580 constants_.upper_hall_position);
581 }
582
583 protected:
584 // Constants, and the simulation using them.
585 const constants::HallEffectZeroingConstants constants_;
586 PositionSensorSimulator sim_;
587};
588
Austin Schuh55934032017-03-11 12:45:27 -0800589// Tests that an error is detected when the starting position changes too much.
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700590TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestHallEffectZeroing) {
591 HallEffectAndPositionZeroingEstimator estimator(constants_);
Austin Schuh55934032017-03-11 12:45:27 -0800592
593 // Should not be zeroed when we stand still.
594 for (int i = 0; i < 300; ++i) {
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700595 MoveTo(&sim_, &estimator, kStartPosition);
Austin Schuh55934032017-03-11 12:45:27 -0800596 ASSERT_FALSE(estimator.zeroed());
597 }
598
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700599 MoveTo(&sim_, &estimator, 1.9);
Austin Schuh55934032017-03-11 12:45:27 -0800600 ASSERT_FALSE(estimator.zeroed());
601
602 // Move to where the hall effect is triggered and make sure it becomes zeroed.
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700603 MoveTo(&sim_, &estimator, 1.5);
Austin Schuh55934032017-03-11 12:45:27 -0800604 EXPECT_FALSE(estimator.zeroed());
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700605 MoveTo(&sim_, &estimator, 1.5);
Austin Schuh55934032017-03-11 12:45:27 -0800606 ASSERT_TRUE(estimator.zeroed());
607
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700608 // Check that the offset is calculated correctly. We should expect to read
609 // 0.5. Since the encoder is reading -0.5 right now, the offset needs to be
610 // 1.
611 EXPECT_DOUBLE_EQ(1.0, estimator.offset());
Austin Schuh55934032017-03-11 12:45:27 -0800612
613 // Make sure triggering errors works.
614 estimator.TriggerError();
615 ASSERT_TRUE(estimator.error());
616
617 // Ensure resetting resets the state of the estimator.
618 estimator.Reset();
619 ASSERT_FALSE(estimator.zeroed());
620 ASSERT_FALSE(estimator.error());
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700621}
Austin Schuh55934032017-03-11 12:45:27 -0800622
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700623// Tests that we don't zero on a too short pulse.
624TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestTooShortPulse) {
625 HallEffectAndPositionZeroingEstimator estimator(constants_);
Austin Schuh55934032017-03-11 12:45:27 -0800626
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700627 // Trigger for 1 cycle.
628 MoveTo(&sim_, &estimator, 0.9);
Austin Schuh55934032017-03-11 12:45:27 -0800629 EXPECT_FALSE(estimator.zeroed());
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700630 MoveTo(&sim_, &estimator, 0.5);
Austin Schuh55934032017-03-11 12:45:27 -0800631 EXPECT_FALSE(estimator.zeroed());
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700632 MoveTo(&sim_, &estimator, 0.9);
Austin Schuh55934032017-03-11 12:45:27 -0800633 EXPECT_FALSE(estimator.zeroed());
634}
635
Austin Schuh1fe4fb42017-10-16 22:35:54 -0700636// Tests that we don't zero when we go the wrong direction.
637TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestWrongDirectionNoZero) {
638 HallEffectAndPositionZeroingEstimator estimator(constants_);
639
640 // Pass through the sensor, lingering long enough that we should zero.
641 MoveTo(&sim_, &estimator, 0.0);
642 ASSERT_FALSE(estimator.zeroed());
643 MoveTo(&sim_, &estimator, 0.4);
644 EXPECT_FALSE(estimator.zeroed());
645 MoveTo(&sim_, &estimator, 0.6);
646 EXPECT_FALSE(estimator.zeroed());
647 MoveTo(&sim_, &estimator, 0.7);
648 EXPECT_FALSE(estimator.zeroed());
649 MoveTo(&sim_, &estimator, 0.9);
650 EXPECT_FALSE(estimator.zeroed());
651}
652
653// Make sure we don't zero if we start in the hall effect's range.
654TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestStartingOnNoZero) {
655 HallEffectAndPositionZeroingEstimator estimator(constants_);
656 MoveTo(&sim_, &estimator, 0.5);
657 estimator.Reset();
658
659 // Stay on the hall effect. We shouldn't zero.
660 EXPECT_FALSE(estimator.zeroed());
661 MoveTo(&sim_, &estimator, 0.5);
662 EXPECT_FALSE(estimator.zeroed());
663 MoveTo(&sim_, &estimator, 0.5);
664 EXPECT_FALSE(estimator.zeroed());
665
666 // Verify moving off the hall still doesn't zero us.
667 MoveTo(&sim_, &estimator, 0.0);
668 EXPECT_FALSE(estimator.zeroed());
669 MoveTo(&sim_, &estimator, 0.0);
670 EXPECT_FALSE(estimator.zeroed());
671}
Austin Schuh55934032017-03-11 12:45:27 -0800672
Austin Schuhd82068e2019-01-26 20:05:42 -0800673// Makes sure that using an absolute encoder lets us zero without moving.
674TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
675 const double index_diff = 1.0;
676 PositionSensorSimulator sim(index_diff);
677
678 const double kMiddlePosition = 2.5;
679 const double start_pos = 2.1;
680 double measured_absolute_position = 0.3 * index_diff;
681
682 AbsoluteEncoderZeroingConstants constants{
683 kSampleSize, index_diff, measured_absolute_position,
684 kMiddlePosition, 0.1, kMovingBufferSize,
685 kIndexErrorFraction};
686
687 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
688 constants.measured_absolute_position);
689
690 AbsoluteEncoderZeroingEstimator estimator(constants);
691
692 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
693 MoveTo(&sim, &estimator, start_pos);
694 ASSERT_FALSE(estimator.zeroed());
695 }
696
697 MoveTo(&sim, &estimator, start_pos);
698 ASSERT_TRUE(estimator.zeroed());
699 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
700}
701
702// Makes sure that we ignore a NAN if we get it, but will correctly zero
703// afterwards.
704TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingIgnoresNAN) {
705 const double index_diff = 1.0;
706 PositionSensorSimulator sim(index_diff);
707
708 const double start_pos = 2.1;
709 double measured_absolute_position = 0.3 * index_diff;
710 const double kMiddlePosition = 2.5;
711
712 AbsoluteEncoderZeroingConstants constants{
713 kSampleSize, index_diff, measured_absolute_position,
714 kMiddlePosition, 0.1, kMovingBufferSize,
715 kIndexErrorFraction};
716
717 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
718 constants.measured_absolute_position);
719
720 AbsoluteEncoderZeroingEstimator estimator(constants);
721
722 // We tolerate a couple NANs before we start.
Alex Perrycb7da4b2019-08-28 19:35:56 -0700723 FBB fbb;
724 fbb.Finish(CreateAbsolutePosition(
725 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
726 const auto sensor_values =
727 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
Austin Schuhd82068e2019-01-26 20:05:42 -0800728 for (size_t i = 0; i < kSampleSize - 1; ++i) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700729 estimator.UpdateEstimate(*sensor_values);
Austin Schuhd82068e2019-01-26 20:05:42 -0800730 }
731
732 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
733 MoveTo(&sim, &estimator, start_pos);
734 ASSERT_FALSE(estimator.zeroed());
735 }
736
737 MoveTo(&sim, &estimator, start_pos);
738 ASSERT_TRUE(estimator.zeroed());
739 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
740}
741
742// Makes sure that using an absolute encoder doesn't let us zero while moving.
743TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
744 const double index_diff = 1.0;
745 PositionSensorSimulator sim(index_diff);
746
747 const double start_pos = 10 * index_diff;
748 double measured_absolute_position = 0.3 * index_diff;
749 const double kMiddlePosition = 2.5;
750
751 AbsoluteEncoderZeroingConstants constants{
752 kSampleSize, index_diff, measured_absolute_position,
753 kMiddlePosition, 0.1, kMovingBufferSize,
754 kIndexErrorFraction};
755
756 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
757 constants.measured_absolute_position);
758
759 AbsoluteEncoderZeroingEstimator estimator(constants);
760
761 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
762 MoveTo(&sim, &estimator, start_pos + i * index_diff);
763 ASSERT_FALSE(estimator.zeroed());
764 }
765 MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
766
767 MoveTo(&sim, &estimator, start_pos);
768 ASSERT_FALSE(estimator.zeroed());
769}
770
771// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
772TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
773 AbsoluteEncoderZeroingConstants constants{
774 kSampleSize, 1, 0.3, 1.0, 0.1, kMovingBufferSize, kIndexErrorFraction};
775
776 AbsoluteEncoderZeroingEstimator estimator(constants);
777
Alex Perrycb7da4b2019-08-28 19:35:56 -0700778 FBB fbb;
779 fbb.Finish(CreateAbsolutePosition(
780 fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
781 const auto sensor_values =
782 flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
Austin Schuhd82068e2019-01-26 20:05:42 -0800783 for (size_t i = 0; i < kSampleSize - 1; ++i) {
Alex Perrycb7da4b2019-08-28 19:35:56 -0700784 estimator.UpdateEstimate(*sensor_values);
Austin Schuhd82068e2019-01-26 20:05:42 -0800785 }
786 ASSERT_FALSE(estimator.error());
787
Alex Perrycb7da4b2019-08-28 19:35:56 -0700788 estimator.UpdateEstimate(*sensor_values);
Austin Schuhd82068e2019-01-26 20:05:42 -0800789 ASSERT_TRUE(estimator.error());
790}
791
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000792} // namespace zeroing
793} // namespace frc971