blob: 526a514d07a1376d313762801dd7385561cd6258 [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"
Adam Snaiderc4b3c192015-02-01 01:30:39 +00008#include "frc971/zeroing/zeroing.h"
Adam Snaiderb4119252015-02-15 01:30:57 +00009#include "frc971/control_loops/control_loops.q.h"
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050010#include "aos/testing/test_shm.h"
Adam Snaiderc4b3c192015-02-01 01:30:39 +000011#include "aos/common/util/thread.h"
12#include "aos/common/die.h"
Adam Snaiderb4119252015-02-15 01:30:57 +000013#include "frc971/control_loops/position_sensor_sim.h"
Adam Snaiderc4b3c192015-02-01 01:30:39 +000014
15namespace frc971 {
16namespace zeroing {
17
Adam Snaiderb4119252015-02-15 01:30:57 +000018using control_loops::PositionSensorSimulator;
Tyler Chatowf8f03112017-02-05 14:31:34 -080019using constants::PotAndIndexPulseZeroingConstants;
Austin Schuh5f01f152017-02-11 21:34:08 -080020using constants::PotAndAbsoluteEncoderZeroingConstants;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000021
Adam Snaiderb4119252015-02-15 01:30:57 +000022static const size_t kSampleSize = 30;
23static const double kAcceptableUnzeroedError = 0.2;
Adam Snaider3cd11c52015-02-16 02:16:09 +000024static const double kIndexErrorFraction = 0.3;
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -080025static const size_t kMovingBufferSize = 3;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000026
Adam Snaiderb4119252015-02-15 01:30:57 +000027class ZeroingTest : public ::testing::Test {
Adam Snaiderc4b3c192015-02-01 01:30:39 +000028 protected:
29 void SetUp() override { aos::SetDieTestMode(true); }
30
Tyler Chatowf8f03112017-02-05 14:31:34 -080031 void MoveTo(PositionSensorSimulator *simulator,
32 PotAndIndexPulseZeroingEstimator *estimator,
Adam Snaiderb4119252015-02-15 01:30:57 +000033 double new_position) {
Brian Silvermandc4eb102017-02-05 17:34:41 -080034 PotAndIndexPosition sensor_values;
Adam Snaiderb4119252015-02-15 01:30:57 +000035 simulator->MoveTo(new_position);
Brian Silvermandc4eb102017-02-05 17:34:41 -080036 simulator->GetSensorValues(&sensor_values);
37 estimator->UpdateEstimate(sensor_values);
Adam Snaiderb4119252015-02-15 01:30:57 +000038 }
Adam Snaiderc4b3c192015-02-01 01:30:39 +000039
Austin Schuh5f01f152017-02-11 21:34:08 -080040 void MoveTo(PositionSensorSimulator *simulator,
Neil Balch16275e32017-02-18 16:38:45 -080041 PotAndAbsEncoderZeroingEstimator *estimator,
42 double new_position) {
Austin Schuh5f01f152017-02-11 21:34:08 -080043 PotAndAbsolutePosition sensor_values_;
44 simulator->MoveTo(new_position);
45 simulator->GetSensorValues(&sensor_values_);
46 estimator->UpdateEstimate(sensor_values_);
47 }
48 // TODO(phil): Add new MoveTo overloads for different zeroing estimators.
49
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050050 ::aos::testing::TestSharedMemory my_shm_;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000051};
52
Adam Snaiderb4119252015-02-15 01:30:57 +000053TEST_F(ZeroingTest, TestMovingAverageFilter) {
54 const double index_diff = 1.0;
55 PositionSensorSimulator sim(index_diff);
56 sim.Initialize(3.6 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -080057 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +000058 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +000059
60 // The zeroing code is supposed to perform some filtering on the difference
61 // between the potentiometer value and the encoder value. We assume that 300
62 // samples are sufficient to have updated the filter.
63 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +000064 MoveTo(&sim, &estimator, 3.3 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000065 }
Adam Snaiderb4119252015-02-15 01:30:57 +000066 ASSERT_NEAR(3.3 * index_diff, estimator.position(),
67 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000068
69 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +000070 MoveTo(&sim, &estimator, 3.9 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000071 }
Adam Snaiderb4119252015-02-15 01:30:57 +000072 ASSERT_NEAR(3.9 * index_diff, estimator.position(),
73 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000074}
75
Adam Snaiderb4119252015-02-15 01:30:57 +000076TEST_F(ZeroingTest, NotZeroedBeforeEnoughSamplesCollected) {
77 double index_diff = 0.5;
78 double position = 3.6 * index_diff;
79 PositionSensorSimulator sim(index_diff);
80 sim.Initialize(position, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -080081 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +000082 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +000083
84 // Make sure that the zeroing code does not consider itself zeroed until we
85 // collect a good amount of samples. In this case we're waiting until the
86 // moving average filter is full.
87 for (unsigned int i = 0; i < kSampleSize - 1; i++) {
88 MoveTo(&sim, &estimator, position += index_diff);
89 ASSERT_FALSE(estimator.zeroed());
90 }
91
92 MoveTo(&sim, &estimator, position);
93 ASSERT_TRUE(estimator.zeroed());
94}
95
96TEST_F(ZeroingTest, TestLotsOfMovement) {
97 double index_diff = 1.0;
98 PositionSensorSimulator sim(index_diff);
99 sim.Initialize(3.6, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800100 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000101 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000102
103 // The zeroing code is supposed to perform some filtering on the difference
104 // between the potentiometer value and the encoder value. We assume that 300
105 // samples are sufficient to have updated the filter.
106 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000107 MoveTo(&sim, &estimator, 3.6);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000108 }
Adam Snaiderb4119252015-02-15 01:30:57 +0000109 ASSERT_NEAR(3.6, estimator.position(), kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000110
111 // With a single index pulse the zeroing estimator should be able to lock
112 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000113 MoveTo(&sim, &estimator, 4.01);
114 ASSERT_NEAR(4.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000115
Adam Snaiderb4119252015-02-15 01:30:57 +0000116 MoveTo(&sim, &estimator, 4.99);
117 ASSERT_NEAR(4.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000118
Adam Snaiderb4119252015-02-15 01:30:57 +0000119 MoveTo(&sim, &estimator, 3.99);
120 ASSERT_NEAR(3.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000121
Adam Snaiderb4119252015-02-15 01:30:57 +0000122 MoveTo(&sim, &estimator, 3.01);
123 ASSERT_NEAR(3.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000124
Adam Snaiderb4119252015-02-15 01:30:57 +0000125 MoveTo(&sim, &estimator, 13.55);
126 ASSERT_NEAR(13.55, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000127}
128
Adam Snaiderb4119252015-02-15 01:30:57 +0000129TEST_F(ZeroingTest, TestDifferentIndexDiffs) {
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000130 double index_diff = 0.89;
Adam Snaiderb4119252015-02-15 01:30:57 +0000131 PositionSensorSimulator sim(index_diff);
132 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800133 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000134 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000135
136 // The zeroing code is supposed to perform some filtering on the difference
137 // between the potentiometer value and the encoder value. We assume that 300
138 // samples are sufficient to have updated the filter.
139 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000140 MoveTo(&sim, &estimator, 3.5 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000141 }
Adam Snaiderb4119252015-02-15 01:30:57 +0000142 ASSERT_NEAR(3.5 * index_diff, estimator.position(),
143 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000144
145 // With a single index pulse the zeroing estimator should be able to lock
146 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000147 MoveTo(&sim, &estimator, 4.01);
148 ASSERT_NEAR(4.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000149
Adam Snaiderb4119252015-02-15 01:30:57 +0000150 MoveTo(&sim, &estimator, 4.99);
151 ASSERT_NEAR(4.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000152
Adam Snaiderb4119252015-02-15 01:30:57 +0000153 MoveTo(&sim, &estimator, 3.99);
154 ASSERT_NEAR(3.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000155
Adam Snaiderb4119252015-02-15 01:30:57 +0000156 MoveTo(&sim, &estimator, 3.01);
157 ASSERT_NEAR(3.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000158
Adam Snaiderb4119252015-02-15 01:30:57 +0000159 MoveTo(&sim, &estimator, 13.55);
160 ASSERT_NEAR(13.55, estimator.position(), 0.001);
161}
162
163TEST_F(ZeroingTest, TestPercentage) {
164 double index_diff = 0.89;
165 PositionSensorSimulator sim(index_diff);
166 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800167 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000168 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000169
170 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
171 MoveTo(&sim, &estimator, 3.5 * index_diff);
172 }
173 ASSERT_NEAR(0.5, estimator.offset_ratio_ready(), 0.001);
Austin Schuh7485dbb2016-02-08 00:21:58 -0800174 ASSERT_FALSE(estimator.offset_ready());
175
176 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
177 MoveTo(&sim, &estimator, 3.5 * index_diff);
178 }
179 ASSERT_NEAR(1.0, estimator.offset_ratio_ready(), 0.001);
180 ASSERT_TRUE(estimator.offset_ready());
Adam Snaiderb4119252015-02-15 01:30:57 +0000181}
182
183TEST_F(ZeroingTest, TestOffset) {
184 double index_diff = 0.89;
185 PositionSensorSimulator sim(index_diff);
186 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800187 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000188 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000189
Philipp Schrader41d82912015-02-15 03:44:23 +0000190 MoveTo(&sim, &estimator, 3.1 * index_diff);
191
Adam Snaiderb4119252015-02-15 01:30:57 +0000192 for (unsigned int i = 0; i < kSampleSize; i++) {
193 MoveTo(&sim, &estimator, 5.0 * index_diff);
194 }
Philipp Schrader41d82912015-02-15 03:44:23 +0000195
Adam Snaiderb4119252015-02-15 01:30:57 +0000196 ASSERT_NEAR(3.1 * index_diff, estimator.offset(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000197}
198
Philipp Schrader41d82912015-02-15 03:44:23 +0000199TEST_F(ZeroingTest, WaitForIndexPulseAfterReset) {
200 double index_diff = 0.6;
201 PositionSensorSimulator sim(index_diff);
202 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800203 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000204 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader41d82912015-02-15 03:44:23 +0000205
206 // Make sure to fill up the averaging filter with samples.
207 for (unsigned int i = 0; i < kSampleSize; i++) {
208 MoveTo(&sim, &estimator, 3.1 * index_diff);
209 }
210
211 // Make sure we're not zeroed until we hit an index pulse.
212 ASSERT_FALSE(estimator.zeroed());
213
214 // Trigger an index pulse; we should now be zeroed.
215 MoveTo(&sim, &estimator, 4.5 * index_diff);
216 ASSERT_TRUE(estimator.zeroed());
217
218 // Reset the zeroing logic and supply a bunch of samples within the current
219 // index segment.
220 estimator.Reset();
221 for (unsigned int i = 0; i < kSampleSize; i++) {
222 MoveTo(&sim, &estimator, 4.2 * index_diff);
223 }
224
225 // Make sure we're not zeroed until we hit an index pulse.
226 ASSERT_FALSE(estimator.zeroed());
227
228 // Trigger another index pulse; we should be zeroed again.
229 MoveTo(&sim, &estimator, 3.1 * index_diff);
230 ASSERT_TRUE(estimator.zeroed());
231}
232
Philipp Schrader030ad182015-02-15 05:40:58 +0000233TEST_F(ZeroingTest, TestNonZeroIndexPulseOffsets) {
234 const double index_diff = 0.9;
235 const double known_index_pos = 3.5 * index_diff;
236 PositionSensorSimulator sim(index_diff);
237 sim.Initialize(3.3 * index_diff, index_diff / 3.0, known_index_pos);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800238 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000239 kSampleSize, index_diff, known_index_pos, kIndexErrorFraction});
Philipp Schrader030ad182015-02-15 05:40:58 +0000240
241 // Make sure to fill up the averaging filter with samples.
242 for (unsigned int i = 0; i < kSampleSize; i++) {
243 MoveTo(&sim, &estimator, 3.3 * index_diff);
244 }
245
246 // Make sure we're not zeroed until we hit an index pulse.
247 ASSERT_FALSE(estimator.zeroed());
248
249 // Trigger an index pulse; we should now be zeroed.
250 MoveTo(&sim, &estimator, 3.7 * index_diff);
251 ASSERT_TRUE(estimator.zeroed());
252 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
253 ASSERT_DOUBLE_EQ(3.7 * index_diff, estimator.position());
254
255 // Trigger one more index pulse and check the offset.
256 MoveTo(&sim, &estimator, 4.7 * index_diff);
257 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
258 ASSERT_DOUBLE_EQ(4.7 * index_diff, estimator.position());
259}
260
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000261TEST_F(ZeroingTest, BasicErrorAPITest) {
262 const double index_diff = 1.0;
Tyler Chatowf8f03112017-02-05 14:31:34 -0800263 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000264 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000265 PositionSensorSimulator sim(index_diff);
266 sim.Initialize(1.5 * index_diff, index_diff / 3.0, 0.0);
267
268 // Perform a simple move and make sure that no error occured.
269 MoveTo(&sim, &estimator, 3.5 * index_diff);
270 ASSERT_FALSE(estimator.error());
271
272 // Trigger an error and make sure it's reported.
273 estimator.TriggerError();
274 ASSERT_TRUE(estimator.error());
275
276 // Make sure that it can recover after a reset.
277 estimator.Reset();
278 ASSERT_FALSE(estimator.error());
279 MoveTo(&sim, &estimator, 4.5 * index_diff);
280 MoveTo(&sim, &estimator, 5.5 * index_diff);
281 ASSERT_FALSE(estimator.error());
282}
283
Adam Snaider3cd11c52015-02-16 02:16:09 +0000284// I want to test that the the zeroing class can
285// detect an error when the starting position
286// changes too much. I do so by creating the
287// simulator at an 'X' positon, making sure
288// that the estimator is zeroed, and then
289// initializing the simulator at another
290// position. After making sure it's zeroed,
291// if the error() function returns true,
292// then, it works.
293TEST_F(ZeroingTest, TestOffsetError) {
294 const double index_diff = 0.8;
295 const double known_index_pos = 2 * index_diff;
Austin Schuh5f01f152017-02-11 21:34:08 -0800296 const size_t sample_size = 30;
Adam Snaider3cd11c52015-02-16 02:16:09 +0000297 PositionSensorSimulator sim(index_diff);
298 sim.Initialize(10 * index_diff, index_diff / 3.0, known_index_pos);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800299 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000300 sample_size, index_diff, known_index_pos, kIndexErrorFraction});
301
Austin Schuh5f01f152017-02-11 21:34:08 -0800302 for (size_t i = 0; i < sample_size; i++) {
Adam Snaider3cd11c52015-02-16 02:16:09 +0000303 MoveTo(&sim, &estimator, 13 * index_diff);
304 }
305 MoveTo(&sim, &estimator, 8 * index_diff);
306
307 ASSERT_TRUE(estimator.zeroed());
308 ASSERT_FALSE(estimator.error());
309 sim.Initialize(9.0 * index_diff + 0.31 * index_diff, index_diff / 3.0,
310 known_index_pos);
311 MoveTo(&sim, &estimator, 9 * index_diff);
312 ASSERT_TRUE(estimator.zeroed());
313 ASSERT_TRUE(estimator.error());
314}
315
Austin Schuh5f01f152017-02-11 21:34:08 -0800316// Makes sure that using an absolute encoder lets us zero without moving.
317TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
318 const double index_diff = 1.0;
319 PositionSensorSimulator sim(index_diff);
320
321 const double start_pos = 2.1;
322 double measured_absolute_position = 0.3 * index_diff;
323
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800324 PotAndAbsoluteEncoderZeroingConstants constants{kSampleSize, index_diff,
325 measured_absolute_position,
326 0.1, kMovingBufferSize};
Austin Schuh5f01f152017-02-11 21:34:08 -0800327
328 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
329 constants.measured_absolute_position);
330
331 PotAndAbsEncoderZeroingEstimator estimator(constants);
332
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800333 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800334 MoveTo(&sim, &estimator, start_pos);
335 ASSERT_FALSE(estimator.zeroed());
336 }
337
338 MoveTo(&sim, &estimator, start_pos);
339 ASSERT_TRUE(estimator.zeroed());
340 EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
341}
342
343// Makes sure that using an absolute encoder doesn't let us zero while moving.
344TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
345 const double index_diff = 1.0;
346 PositionSensorSimulator sim(index_diff);
347
348 const double start_pos = 10 * index_diff;
349 double measured_absolute_position = 0.3 * index_diff;
350
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800351 PotAndAbsoluteEncoderZeroingConstants constants{kSampleSize, index_diff,
352 measured_absolute_position,
353 0.1, kMovingBufferSize};
Austin Schuh5f01f152017-02-11 21:34:08 -0800354
355 sim.Initialize(start_pos, index_diff / 3.0, 0.0,
356 constants.measured_absolute_position);
357
358 PotAndAbsEncoderZeroingEstimator estimator(constants);
359
Diana Vandenberg8fea6ea2017-02-18 17:24:45 -0800360 for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
Austin Schuh5f01f152017-02-11 21:34:08 -0800361 MoveTo(&sim, &estimator, start_pos + i * index_diff);
362 ASSERT_FALSE(estimator.zeroed());
363 }
364 MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
365
366 MoveTo(&sim, &estimator, start_pos);
367 ASSERT_FALSE(estimator.zeroed());
368}
Neil Balch16275e32017-02-18 16:38:45 -0800369
370// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
371TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
372 PotAndAbsoluteEncoderZeroingConstants constants{
373 kSampleSize, 1, 0.3, 0.1, kMovingBufferSize};
374
375 PotAndAbsEncoderZeroingEstimator estimator(constants);
376
377 PotAndAbsolutePosition sensor_values_;
378 sensor_values_.absolute_encoder = ::std::numeric_limits<double>::quiet_NaN();
379 sensor_values_.encoder = 0.0;
380 sensor_values_.pot = 0.0;
381 estimator.UpdateEstimate(sensor_values_);
382
383 ASSERT_TRUE(estimator.error());
384}
385
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000386} // namespace zeroing
387} // namespace frc971