blob: 3e8c931271412100316d2ad9a9e24d7de72b4303 [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;
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000021using constants::EncoderPlusIndexZeroingConstants;
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:
30 void SetUp() override { aos::SetDieTestMode(true); }
31
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) {
Brian Silvermandc4eb102017-02-05 17:34:41 -080035 PotAndIndexPosition sensor_values;
Adam Snaiderb4119252015-02-15 01:30:57 +000036 simulator->MoveTo(new_position);
Brian Silvermandc4eb102017-02-05 17:34:41 -080037 simulator->GetSensorValues(&sensor_values);
38 estimator->UpdateEstimate(sensor_values);
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,
Neil Balch16275e32017-02-18 16:38:45 -080042 PotAndAbsEncoderZeroingEstimator *estimator,
43 double new_position) {
Austin Schuh5f01f152017-02-11 21:34:08 -080044 PotAndAbsolutePosition sensor_values_;
45 simulator->MoveTo(new_position);
46 simulator->GetSensorValues(&sensor_values_);
47 estimator->UpdateEstimate(sensor_values_);
48 }
Isaac Wilcove0851ffd2017-02-16 04:13:14 +000049
50 void MoveTo(PositionSensorSimulator *simulator,
51 PulseIndexZeroingEstimator *estimator, double new_position) {
52 IndexPosition sensor_values_;
53 simulator->MoveTo(new_position);
54 simulator->GetSensorValues(&sensor_values_);
55 estimator->UpdateEstimate(sensor_values_);
56 }
Austin Schuh5f01f152017-02-11 21:34:08 -080057
Brian Silvermanf5f8d8e2015-12-06 18:39:12 -050058 ::aos::testing::TestSharedMemory my_shm_;
Adam Snaiderc4b3c192015-02-01 01:30:39 +000059};
60
Adam Snaiderb4119252015-02-15 01:30:57 +000061TEST_F(ZeroingTest, TestMovingAverageFilter) {
62 const double index_diff = 1.0;
63 PositionSensorSimulator sim(index_diff);
64 sim.Initialize(3.6 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -080065 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +000066 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +000067
68 // The zeroing code is supposed to perform some filtering on the difference
69 // between the potentiometer value and the encoder value. We assume that 300
70 // samples are sufficient to have updated the filter.
71 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +000072 MoveTo(&sim, &estimator, 3.3 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000073 }
Adam Snaiderb4119252015-02-15 01:30:57 +000074 ASSERT_NEAR(3.3 * index_diff, estimator.position(),
75 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000076
77 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +000078 MoveTo(&sim, &estimator, 3.9 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000079 }
Adam Snaiderb4119252015-02-15 01:30:57 +000080 ASSERT_NEAR(3.9 * index_diff, estimator.position(),
81 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +000082}
83
Adam Snaiderb4119252015-02-15 01:30:57 +000084TEST_F(ZeroingTest, NotZeroedBeforeEnoughSamplesCollected) {
85 double index_diff = 0.5;
86 double position = 3.6 * index_diff;
87 PositionSensorSimulator sim(index_diff);
88 sim.Initialize(position, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -080089 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +000090 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +000091
92 // Make sure that the zeroing code does not consider itself zeroed until we
93 // collect a good amount of samples. In this case we're waiting until the
94 // moving average filter is full.
95 for (unsigned int i = 0; i < kSampleSize - 1; i++) {
96 MoveTo(&sim, &estimator, position += index_diff);
97 ASSERT_FALSE(estimator.zeroed());
98 }
99
100 MoveTo(&sim, &estimator, position);
101 ASSERT_TRUE(estimator.zeroed());
102}
103
104TEST_F(ZeroingTest, TestLotsOfMovement) {
105 double index_diff = 1.0;
106 PositionSensorSimulator sim(index_diff);
107 sim.Initialize(3.6, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800108 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000109 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000110
111 // The zeroing code is supposed to perform some filtering on the difference
112 // between the potentiometer value and the encoder value. We assume that 300
113 // samples are sufficient to have updated the filter.
114 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000115 MoveTo(&sim, &estimator, 3.6);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000116 }
Adam Snaiderb4119252015-02-15 01:30:57 +0000117 ASSERT_NEAR(3.6, estimator.position(), kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000118
119 // With a single index pulse the zeroing estimator should be able to lock
120 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000121 MoveTo(&sim, &estimator, 4.01);
122 ASSERT_NEAR(4.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000123
Adam Snaiderb4119252015-02-15 01:30:57 +0000124 MoveTo(&sim, &estimator, 4.99);
125 ASSERT_NEAR(4.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000126
Adam Snaiderb4119252015-02-15 01:30:57 +0000127 MoveTo(&sim, &estimator, 3.99);
128 ASSERT_NEAR(3.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000129
Adam Snaiderb4119252015-02-15 01:30:57 +0000130 MoveTo(&sim, &estimator, 3.01);
131 ASSERT_NEAR(3.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000132
Adam Snaiderb4119252015-02-15 01:30:57 +0000133 MoveTo(&sim, &estimator, 13.55);
134 ASSERT_NEAR(13.55, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000135}
136
Adam Snaiderb4119252015-02-15 01:30:57 +0000137TEST_F(ZeroingTest, TestDifferentIndexDiffs) {
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000138 double index_diff = 0.89;
Adam Snaiderb4119252015-02-15 01:30:57 +0000139 PositionSensorSimulator sim(index_diff);
140 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800141 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000142 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000143
144 // The zeroing code is supposed to perform some filtering on the difference
145 // between the potentiometer value and the encoder value. We assume that 300
146 // samples are sufficient to have updated the filter.
147 for (int i = 0; i < 300; i++) {
Adam Snaiderb4119252015-02-15 01:30:57 +0000148 MoveTo(&sim, &estimator, 3.5 * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000149 }
Adam Snaiderb4119252015-02-15 01:30:57 +0000150 ASSERT_NEAR(3.5 * index_diff, estimator.position(),
151 kAcceptableUnzeroedError * index_diff);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000152
153 // With a single index pulse the zeroing estimator should be able to lock
154 // onto the true value of the position.
Adam Snaiderb4119252015-02-15 01:30:57 +0000155 MoveTo(&sim, &estimator, 4.01);
156 ASSERT_NEAR(4.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000157
Adam Snaiderb4119252015-02-15 01:30:57 +0000158 MoveTo(&sim, &estimator, 4.99);
159 ASSERT_NEAR(4.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000160
Adam Snaiderb4119252015-02-15 01:30:57 +0000161 MoveTo(&sim, &estimator, 3.99);
162 ASSERT_NEAR(3.99, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000163
Adam Snaiderb4119252015-02-15 01:30:57 +0000164 MoveTo(&sim, &estimator, 3.01);
165 ASSERT_NEAR(3.01, estimator.position(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000166
Adam Snaiderb4119252015-02-15 01:30:57 +0000167 MoveTo(&sim, &estimator, 13.55);
168 ASSERT_NEAR(13.55, estimator.position(), 0.001);
169}
170
171TEST_F(ZeroingTest, TestPercentage) {
172 double index_diff = 0.89;
173 PositionSensorSimulator sim(index_diff);
174 sim.Initialize(3.5 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800175 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000176 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000177
178 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
179 MoveTo(&sim, &estimator, 3.5 * index_diff);
180 }
181 ASSERT_NEAR(0.5, estimator.offset_ratio_ready(), 0.001);
Austin Schuh7485dbb2016-02-08 00:21:58 -0800182 ASSERT_FALSE(estimator.offset_ready());
183
184 for (unsigned int i = 0; i < kSampleSize / 2; i++) {
185 MoveTo(&sim, &estimator, 3.5 * index_diff);
186 }
187 ASSERT_NEAR(1.0, estimator.offset_ratio_ready(), 0.001);
188 ASSERT_TRUE(estimator.offset_ready());
Adam Snaiderb4119252015-02-15 01:30:57 +0000189}
190
191TEST_F(ZeroingTest, TestOffset) {
192 double index_diff = 0.89;
193 PositionSensorSimulator sim(index_diff);
194 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800195 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000196 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Adam Snaiderb4119252015-02-15 01:30:57 +0000197
Philipp Schrader41d82912015-02-15 03:44:23 +0000198 MoveTo(&sim, &estimator, 3.1 * index_diff);
199
Adam Snaiderb4119252015-02-15 01:30:57 +0000200 for (unsigned int i = 0; i < kSampleSize; i++) {
201 MoveTo(&sim, &estimator, 5.0 * index_diff);
202 }
Philipp Schrader41d82912015-02-15 03:44:23 +0000203
Adam Snaiderb4119252015-02-15 01:30:57 +0000204 ASSERT_NEAR(3.1 * index_diff, estimator.offset(), 0.001);
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000205}
206
Philipp Schrader41d82912015-02-15 03:44:23 +0000207TEST_F(ZeroingTest, WaitForIndexPulseAfterReset) {
208 double index_diff = 0.6;
209 PositionSensorSimulator sim(index_diff);
210 sim.Initialize(3.1 * index_diff, index_diff / 3.0);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800211 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000212 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader41d82912015-02-15 03:44:23 +0000213
214 // Make sure to fill up the averaging filter with samples.
215 for (unsigned int i = 0; i < kSampleSize; i++) {
216 MoveTo(&sim, &estimator, 3.1 * index_diff);
217 }
218
219 // Make sure we're not zeroed until we hit an index pulse.
220 ASSERT_FALSE(estimator.zeroed());
221
222 // Trigger an index pulse; we should now be zeroed.
223 MoveTo(&sim, &estimator, 4.5 * index_diff);
224 ASSERT_TRUE(estimator.zeroed());
225
226 // Reset the zeroing logic and supply a bunch of samples within the current
227 // index segment.
228 estimator.Reset();
229 for (unsigned int i = 0; i < kSampleSize; i++) {
230 MoveTo(&sim, &estimator, 4.2 * index_diff);
231 }
232
233 // Make sure we're not zeroed until we hit an index pulse.
234 ASSERT_FALSE(estimator.zeroed());
235
236 // Trigger another index pulse; we should be zeroed again.
237 MoveTo(&sim, &estimator, 3.1 * index_diff);
238 ASSERT_TRUE(estimator.zeroed());
239}
240
Philipp Schrader030ad182015-02-15 05:40:58 +0000241TEST_F(ZeroingTest, TestNonZeroIndexPulseOffsets) {
242 const double index_diff = 0.9;
243 const double known_index_pos = 3.5 * index_diff;
244 PositionSensorSimulator sim(index_diff);
245 sim.Initialize(3.3 * index_diff, index_diff / 3.0, known_index_pos);
Tyler Chatowf8f03112017-02-05 14:31:34 -0800246 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000247 kSampleSize, index_diff, known_index_pos, kIndexErrorFraction});
Philipp Schrader030ad182015-02-15 05:40:58 +0000248
249 // Make sure to fill up the averaging filter with samples.
250 for (unsigned int i = 0; i < kSampleSize; i++) {
251 MoveTo(&sim, &estimator, 3.3 * index_diff);
252 }
253
254 // Make sure we're not zeroed until we hit an index pulse.
255 ASSERT_FALSE(estimator.zeroed());
256
257 // Trigger an index pulse; we should now be zeroed.
258 MoveTo(&sim, &estimator, 3.7 * index_diff);
259 ASSERT_TRUE(estimator.zeroed());
260 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
261 ASSERT_DOUBLE_EQ(3.7 * index_diff, estimator.position());
262
263 // Trigger one more index pulse and check the offset.
264 MoveTo(&sim, &estimator, 4.7 * index_diff);
265 ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
266 ASSERT_DOUBLE_EQ(4.7 * index_diff, estimator.position());
267}
268
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000269TEST_F(ZeroingTest, BasicErrorAPITest) {
270 const double index_diff = 1.0;
Tyler Chatowf8f03112017-02-05 14:31:34 -0800271 PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
Adam Snaider3cd11c52015-02-16 02:16:09 +0000272 kSampleSize, index_diff, 0.0, kIndexErrorFraction});
Philipp Schrader53f4b6d2015-02-15 22:32:08 +0000273 PositionSensorSimulator sim(index_diff);
274 sim.Initialize(1.5 * index_diff, index_diff / 3.0, 0.0);
275
276 // Perform a simple move and make sure that no error occured.
277 MoveTo(&sim, &estimator, 3.5 * index_diff);
278 ASSERT_FALSE(estimator.error());
279
280 // Trigger an error and make sure it's reported.
281 estimator.TriggerError();
282 ASSERT_TRUE(estimator.error());
283
284 // Make sure that it can recover after a reset.
285 estimator.Reset();
286 ASSERT_FALSE(estimator.error());
287 MoveTo(&sim, &estimator, 4.5 * index_diff);
288 MoveTo(&sim, &estimator, 5.5 * index_diff);
289 ASSERT_FALSE(estimator.error());
290}
291
Brian Silvermana10d20a2017-02-19 14:28:53 -0800292// Tests that an error is detected when the starting position changes too much.
293TEST_F(ZeroingTest, TestIndexOffsetError) {
Adam Snaider3cd11c52015-02-16 02:16:09 +0000294 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
Brian Silvermana10d20a2017-02-19 14:28:53 -0800324 PotAndAbsoluteEncoderZeroingConstants constants{
325 kSampleSize, index_diff, measured_absolute_position,
326 0.1, kMovingBufferSize, kIndexErrorFraction};
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
Brian Silvermana10d20a2017-02-19 14:28:53 -0800351 PotAndAbsoluteEncoderZeroingConstants constants{
352 kSampleSize, index_diff, measured_absolute_position,
353 0.1, kMovingBufferSize, kIndexErrorFraction};
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{
Brian Silvermana10d20a2017-02-19 14:28:53 -0800373 kSampleSize, 1, 0.3, 0.1, kMovingBufferSize, kIndexErrorFraction};
Neil Balch16275e32017-02-18 16:38:45 -0800374
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
Brian Silvermana10d20a2017-02-19 14:28:53 -0800386// Tests that an error is detected when the starting position changes too much.
Isaac Wilcove0851ffd2017-02-16 04:13:14 +0000387TEST_F(ZeroingTest, TestRelativeEncoderZeroing) {
388 EncoderPlusIndexZeroingConstants constants;
389 constants.index_pulse_count = 3;
390 constants.index_difference = 10.0;
391 constants.measured_index_position = 20.0;
392 constants.known_index_pulse = 1;
393
394 PositionSensorSimulator sim(constants.index_difference);
395
396 const double start_pos = 2.5 * constants.index_difference;
397
398 sim.Initialize(start_pos, constants.index_difference / 3.0,
399 constants.measured_index_position);
400
401 PulseIndexZeroingEstimator estimator(constants);
402
403 // Should not be zeroed when we stand still.
404 for (int i = 0; i < 300; ++i) {
405 MoveTo(&sim, &estimator, start_pos);
406 ASSERT_FALSE(estimator.zeroed());
407 }
408
409 // Move to 1.5 constants.index_difference and we should still not be zeroed.
410 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
411 ASSERT_FALSE(estimator.zeroed());
412
413 // Move to 0.5 constants.index_difference and we should still not be zeroed.
414 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
415 ASSERT_FALSE(estimator.zeroed());
416
417 // Move back to 1.5 constants.index_difference and we should still not be
418 // zeroed.
419 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
420 ASSERT_FALSE(estimator.zeroed());
421
422 // Move back to 2.5 constants.index_difference and we should still not be
423 // zeroed.
424 MoveTo(&sim, &estimator, 2.5 * constants.index_difference);
425 ASSERT_FALSE(estimator.zeroed());
426
427 // Move back to 3.5 constants.index_difference and we should now be zeroed.
428 MoveTo(&sim, &estimator, 3.5 * constants.index_difference);
429 ASSERT_TRUE(estimator.zeroed());
430
431 ASSERT_DOUBLE_EQ(start_pos, estimator.offset());
432 ASSERT_DOUBLE_EQ(3.5 * constants.index_difference, estimator.position());
433
434 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
435 ASSERT_DOUBLE_EQ(0.5 * constants.index_difference, estimator.position());
436}
437
Adam Snaiderc4b3c192015-02-01 01:30:39 +0000438} // namespace zeroing
439} // namespace frc971