blob: bd257f7c129b3cb1176c177911498c2bd104ddd8 [file] [log] [blame]
Brian Silvermana57b7012020-03-11 20:19:23 -07001#include "frc971/zeroing/pulse_index.h"
2
3#include "gtest/gtest.h"
4
5#include "frc971/zeroing/zeroing_test.h"
6
7namespace frc971 {
8namespace zeroing {
9namespace testing {
10
11using constants::EncoderPlusIndexZeroingConstants;
12
13class PulseIndexZeroingTest : public ZeroingTest {
14 protected:
15 void MoveTo(PositionSensorSimulator *simulator,
16 PulseIndexZeroingEstimator *estimator, double new_position) {
17 simulator->MoveTo(new_position);
18 FBB fbb;
19 estimator->UpdateEstimate(
20 *simulator->FillSensorValues<IndexPosition>(&fbb));
21 }
22};
23
24// Tests that an error is detected when the starting position changes too much.
25TEST_F(PulseIndexZeroingTest, TestRelativeEncoderZeroing) {
26 EncoderPlusIndexZeroingConstants constants;
27 constants.index_pulse_count = 3;
28 constants.index_difference = 10.0;
29 constants.measured_index_position = 20.0;
30 constants.known_index_pulse = 1;
31 constants.allowable_encoder_error = 0.01;
32
33 PositionSensorSimulator sim(constants.index_difference);
34
35 const double start_pos = 2.5 * constants.index_difference;
36
37 sim.Initialize(start_pos, constants.index_difference / 3.0,
38 constants.measured_index_position);
39
40 PulseIndexZeroingEstimator estimator(constants);
41
42 // Should not be zeroed when we stand still.
43 for (int i = 0; i < 300; ++i) {
44 MoveTo(&sim, &estimator, start_pos);
45 ASSERT_FALSE(estimator.zeroed());
46 }
47
48 // Move to 1.5 constants.index_difference and we should still not be zeroed.
49 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
50 ASSERT_FALSE(estimator.zeroed());
51
52 // Move to 0.5 constants.index_difference and we should still not be zeroed.
53 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
54 ASSERT_FALSE(estimator.zeroed());
55
56 // Move back to 1.5 constants.index_difference and we should still not be
57 // zeroed.
58 MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
59 ASSERT_FALSE(estimator.zeroed());
60
61 // Move back to 2.5 constants.index_difference and we should still not be
62 // zeroed.
63 MoveTo(&sim, &estimator, 2.5 * constants.index_difference);
64 ASSERT_FALSE(estimator.zeroed());
65
66 // Move back to 3.5 constants.index_difference and we should now be zeroed.
67 MoveTo(&sim, &estimator, 3.5 * constants.index_difference);
68 ASSERT_TRUE(estimator.zeroed());
69
70 ASSERT_DOUBLE_EQ(start_pos, estimator.offset());
71 ASSERT_DOUBLE_EQ(3.5 * constants.index_difference,
72 GetEstimatorPosition(&estimator));
73
74 MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
75 ASSERT_DOUBLE_EQ(0.5 * constants.index_difference,
76 GetEstimatorPosition(&estimator));
77}
78
79// Tests that we can detect when an index pulse occurs where we didn't expect
80// it to for the PulseIndexZeroingEstimator.
81TEST_F(PulseIndexZeroingTest, TestRelativeEncoderSlipping) {
82 EncoderPlusIndexZeroingConstants constants;
83 constants.index_pulse_count = 3;
84 constants.index_difference = 10.0;
85 constants.measured_index_position = 20.0;
86 constants.known_index_pulse = 1;
87 constants.allowable_encoder_error = 0.05;
88
89 PositionSensorSimulator sim(constants.index_difference);
90
91 const double start_pos =
92 constants.measured_index_position + 0.5 * constants.index_difference;
93
94 for (double direction : {1.0, -1.0}) {
95 sim.Initialize(start_pos, constants.index_difference / 3.0,
96 constants.measured_index_position);
97
98 PulseIndexZeroingEstimator estimator(constants);
99
100 // Zero the estimator.
101 MoveTo(&sim, &estimator, start_pos - 1 * constants.index_difference);
102 MoveTo(
103 &sim, &estimator,
104 start_pos - constants.index_pulse_count * constants.index_difference);
105 ASSERT_TRUE(estimator.zeroed());
106 ASSERT_FALSE(estimator.error());
107
108 // We have a 5% allowable error so we slip a little bit each time and make
109 // sure that the index pulses are still accepted.
110 for (double error = 0.00;
111 ::std::abs(error) < constants.allowable_encoder_error;
112 error += 0.01 * direction) {
113 sim.Initialize(start_pos, constants.index_difference / 3.0,
114 constants.measured_index_position +
115 error * constants.index_difference);
116 MoveTo(&sim, &estimator, start_pos - constants.index_difference);
117 EXPECT_FALSE(estimator.error());
118 }
119
120 // As soon as we hit cross the error margin, we should trigger an error.
121 sim.Initialize(start_pos, constants.index_difference / 3.0,
122 constants.measured_index_position +
123 constants.allowable_encoder_error * 1.1 *
124 constants.index_difference * direction);
125 MoveTo(&sim, &estimator, start_pos - constants.index_difference);
126 ASSERT_TRUE(estimator.error());
127 }
128}
129
130} // namespace testing
131} // namespace zeroing
132} // namespace frc971