blob: bd257f7c129b3cb1176c177911498c2bd104ddd8 [file] [log] [blame]
#include "frc971/zeroing/pulse_index.h"
#include "gtest/gtest.h"
#include "frc971/zeroing/zeroing_test.h"
namespace frc971 {
namespace zeroing {
namespace testing {
using constants::EncoderPlusIndexZeroingConstants;
class PulseIndexZeroingTest : public ZeroingTest {
protected:
void MoveTo(PositionSensorSimulator *simulator,
PulseIndexZeroingEstimator *estimator, double new_position) {
simulator->MoveTo(new_position);
FBB fbb;
estimator->UpdateEstimate(
*simulator->FillSensorValues<IndexPosition>(&fbb));
}
};
// Tests that an error is detected when the starting position changes too much.
TEST_F(PulseIndexZeroingTest, TestRelativeEncoderZeroing) {
EncoderPlusIndexZeroingConstants constants;
constants.index_pulse_count = 3;
constants.index_difference = 10.0;
constants.measured_index_position = 20.0;
constants.known_index_pulse = 1;
constants.allowable_encoder_error = 0.01;
PositionSensorSimulator sim(constants.index_difference);
const double start_pos = 2.5 * constants.index_difference;
sim.Initialize(start_pos, constants.index_difference / 3.0,
constants.measured_index_position);
PulseIndexZeroingEstimator estimator(constants);
// Should not be zeroed when we stand still.
for (int i = 0; i < 300; ++i) {
MoveTo(&sim, &estimator, start_pos);
ASSERT_FALSE(estimator.zeroed());
}
// Move to 1.5 constants.index_difference and we should still not be zeroed.
MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
ASSERT_FALSE(estimator.zeroed());
// Move to 0.5 constants.index_difference and we should still not be zeroed.
MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
ASSERT_FALSE(estimator.zeroed());
// Move back to 1.5 constants.index_difference and we should still not be
// zeroed.
MoveTo(&sim, &estimator, 1.5 * constants.index_difference);
ASSERT_FALSE(estimator.zeroed());
// Move back to 2.5 constants.index_difference and we should still not be
// zeroed.
MoveTo(&sim, &estimator, 2.5 * constants.index_difference);
ASSERT_FALSE(estimator.zeroed());
// Move back to 3.5 constants.index_difference and we should now be zeroed.
MoveTo(&sim, &estimator, 3.5 * constants.index_difference);
ASSERT_TRUE(estimator.zeroed());
ASSERT_DOUBLE_EQ(start_pos, estimator.offset());
ASSERT_DOUBLE_EQ(3.5 * constants.index_difference,
GetEstimatorPosition(&estimator));
MoveTo(&sim, &estimator, 0.5 * constants.index_difference);
ASSERT_DOUBLE_EQ(0.5 * constants.index_difference,
GetEstimatorPosition(&estimator));
}
// Tests that we can detect when an index pulse occurs where we didn't expect
// it to for the PulseIndexZeroingEstimator.
TEST_F(PulseIndexZeroingTest, TestRelativeEncoderSlipping) {
EncoderPlusIndexZeroingConstants constants;
constants.index_pulse_count = 3;
constants.index_difference = 10.0;
constants.measured_index_position = 20.0;
constants.known_index_pulse = 1;
constants.allowable_encoder_error = 0.05;
PositionSensorSimulator sim(constants.index_difference);
const double start_pos =
constants.measured_index_position + 0.5 * constants.index_difference;
for (double direction : {1.0, -1.0}) {
sim.Initialize(start_pos, constants.index_difference / 3.0,
constants.measured_index_position);
PulseIndexZeroingEstimator estimator(constants);
// Zero the estimator.
MoveTo(&sim, &estimator, start_pos - 1 * constants.index_difference);
MoveTo(
&sim, &estimator,
start_pos - constants.index_pulse_count * constants.index_difference);
ASSERT_TRUE(estimator.zeroed());
ASSERT_FALSE(estimator.error());
// We have a 5% allowable error so we slip a little bit each time and make
// sure that the index pulses are still accepted.
for (double error = 0.00;
::std::abs(error) < constants.allowable_encoder_error;
error += 0.01 * direction) {
sim.Initialize(start_pos, constants.index_difference / 3.0,
constants.measured_index_position +
error * constants.index_difference);
MoveTo(&sim, &estimator, start_pos - constants.index_difference);
EXPECT_FALSE(estimator.error());
}
// As soon as we hit cross the error margin, we should trigger an error.
sim.Initialize(start_pos, constants.index_difference / 3.0,
constants.measured_index_position +
constants.allowable_encoder_error * 1.1 *
constants.index_difference * direction);
MoveTo(&sim, &estimator, start_pos - constants.index_difference);
ASSERT_TRUE(estimator.error());
}
}
} // namespace testing
} // namespace zeroing
} // namespace frc971