diff --git a/frc971/zeroing/BUILD b/frc971/zeroing/BUILD
index 75d610a..5955f8b 100644
--- a/frc971/zeroing/BUILD
+++ b/frc971/zeroing/BUILD
@@ -59,9 +59,18 @@
 cc_library(
     name = "zeroing",
     srcs = [
-        "zeroing.cc",
+        "absolute_encoder.cc",
+        "hall_effect_and_position.cc",
+        "pot_and_absolute_encoder.cc",
+        "pot_and_index.cc",
+        "pulse_index.cc",
     ],
     hdrs = [
+        "absolute_encoder.h",
+        "hall_effect_and_position.h",
+        "pot_and_absolute_encoder.h",
+        "pot_and_index.h",
+        "pulse_index.h",
         "zeroing.h",
     ],
     deps = [
@@ -76,11 +85,16 @@
 cc_test(
     name = "zeroing_test",
     srcs = [
-        "zeroing_test.cc",
+        "absolute_encoder_test.cc",
+        "hall_effect_and_position_test.cc",
+        "pot_and_absolute_encoder_test.cc",
+        "pot_and_index_test.cc",
+        "pulse_index_test.cc",
+        "relative_encoder_test.cc",
+        "zeroing_test.h",
     ],
     deps = [
         ":zeroing",
-        "//aos:die",
         "//aos/testing:googletest",
         "//aos/testing:test_shm",
         "//frc971/control_loops:control_loops_fbs",
diff --git a/frc971/zeroing/absolute_encoder.cc b/frc971/zeroing/absolute_encoder.cc
new file mode 100644
index 0000000..ffdf9da
--- /dev/null
+++ b/frc971/zeroing/absolute_encoder.cc
@@ -0,0 +1,178 @@
+#include "frc971/zeroing/absolute_encoder.h"
+
+#include <cmath>
+#include <numeric>
+
+#include "glog/logging.h"
+
+#include "frc971/zeroing/wrap.h"
+
+namespace frc971 {
+namespace zeroing {
+
+AbsoluteEncoderZeroingEstimator::AbsoluteEncoderZeroingEstimator(
+    const constants::AbsoluteEncoderZeroingConstants &constants)
+    : constants_(constants), move_detector_(constants_.moving_buffer_size) {
+  relative_to_absolute_offset_samples_.reserve(constants_.average_filter_size);
+  Reset();
+}
+
+void AbsoluteEncoderZeroingEstimator::Reset() {
+  zeroed_ = false;
+  error_ = false;
+  first_offset_ = 0.0;
+  offset_ = 0.0;
+  samples_idx_ = 0;
+  position_ = 0.0;
+  nan_samples_ = 0;
+  relative_to_absolute_offset_samples_.clear();
+  move_detector_.Reset();
+}
+
+
+// The math here is a bit backwards, but I think it'll be less error prone that
+// way and more similar to the version with a pot as well.
+//
+// We start by unwrapping the absolute encoder using the relative encoder.  This
+// puts us in a non-wrapping space and lets us average a bit easier.  From
+// there, we can compute an offset and wrap ourselves back such that we stay
+// close to the middle value.
+//
+// To guard against the robot moving while updating estimates, buffer a number
+// of samples and check that the buffered samples are not different than the
+// zeroing threshold. At any point that the samples differ too much, do not
+// update estimates based on those samples.
+void AbsoluteEncoderZeroingEstimator::UpdateEstimate(
+    const AbsolutePosition &info) {
+  // Check for Abs Encoder NaN value that would mess up the rest of the zeroing
+  // code below. NaN values are given when the Absolute Encoder is disconnected.
+  if (::std::isnan(info.absolute_encoder())) {
+    if (zeroed_) {
+      VLOG(1) << "NAN on absolute encoder.";
+      error_ = true;
+    } else {
+      ++nan_samples_;
+      VLOG(1) << "NAN on absolute encoder while zeroing " << nan_samples_;
+      if (nan_samples_ >= constants_.average_filter_size) {
+        error_ = true;
+        zeroed_ = true;
+      }
+    }
+    // Throw some dummy values in for now.
+    filtered_absolute_encoder_ = info.absolute_encoder();
+    position_ = offset_ + info.encoder();
+    return;
+  }
+
+  const bool moving = move_detector_.Update(info, constants_.moving_buffer_size,
+                                            constants_.zeroing_threshold);
+
+  if (!moving) {
+    const PositionStruct &sample = move_detector_.GetSample();
+
+    // Compute the average offset between the absolute encoder and relative
+    // encoder.  If we have 0 samples, assume it is 0.
+    double average_relative_to_absolute_offset =
+        relative_to_absolute_offset_samples_.size() == 0
+            ? 0.0
+            : ::std::accumulate(relative_to_absolute_offset_samples_.begin(),
+                                relative_to_absolute_offset_samples_.end(),
+                                0.0) /
+                  relative_to_absolute_offset_samples_.size();
+
+    // Now, compute the estimated absolute position using the previously
+    // estimated offset and the incremental encoder.
+    const double adjusted_incremental_encoder =
+        sample.encoder + average_relative_to_absolute_offset;
+
+    // Now, compute the absolute encoder value nearest to the offset relative
+    // encoder position.
+    const double adjusted_absolute_encoder =
+        UnWrap(adjusted_incremental_encoder,
+               sample.absolute_encoder - constants_.measured_absolute_position,
+               constants_.one_revolution_distance);
+
+    // We can now compute the offset now that we have unwrapped the absolute
+    // encoder.
+    const double relative_to_absolute_offset =
+        adjusted_absolute_encoder - sample.encoder;
+
+    // Add the sample and update the average with the new reading.
+    const size_t relative_to_absolute_offset_samples_size =
+        relative_to_absolute_offset_samples_.size();
+    if (relative_to_absolute_offset_samples_size <
+        constants_.average_filter_size) {
+      average_relative_to_absolute_offset =
+          (average_relative_to_absolute_offset *
+               relative_to_absolute_offset_samples_size +
+           relative_to_absolute_offset) /
+          (relative_to_absolute_offset_samples_size + 1);
+
+      relative_to_absolute_offset_samples_.push_back(
+          relative_to_absolute_offset);
+    } else {
+      average_relative_to_absolute_offset -=
+          relative_to_absolute_offset_samples_[samples_idx_] /
+          relative_to_absolute_offset_samples_size;
+      relative_to_absolute_offset_samples_[samples_idx_] =
+          relative_to_absolute_offset;
+      average_relative_to_absolute_offset +=
+          relative_to_absolute_offset /
+          relative_to_absolute_offset_samples_size;
+    }
+
+    // Drop the oldest sample when we run this function the next time around.
+    samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
+
+    // And our offset is the offset that gives us the position within +- ord/2
+    // of the middle position.
+    offset_ = Wrap(constants_.middle_position,
+                   average_relative_to_absolute_offset + sample.encoder,
+                   constants_.one_revolution_distance) -
+              sample.encoder;
+
+    // Reverse the math for adjusted_absolute_encoder to compute the absolute
+    // encoder. Do this by taking the adjusted encoder, and then subtracting off
+    // the second argument above, and the value that was added by Wrap.
+    filtered_absolute_encoder_ =
+        ((sample.encoder + average_relative_to_absolute_offset) -
+         (-constants_.measured_absolute_position +
+          (adjusted_absolute_encoder -
+           (sample.absolute_encoder - constants_.measured_absolute_position))));
+
+    if (offset_ready()) {
+      if (!zeroed_) {
+        first_offset_ = offset_;
+      }
+
+      if (::std::abs(first_offset_ - offset_) >
+          constants_.allowable_encoder_error *
+              constants_.one_revolution_distance) {
+        VLOG(1) << "Offset moved too far. Initial: " << first_offset_
+                << ", current " << offset_ << ", allowable change: "
+                << constants_.allowable_encoder_error *
+                       constants_.one_revolution_distance;
+        error_ = true;
+      }
+
+      zeroed_ = true;
+    }
+  }
+
+  // Update the position.
+  position_ = offset_ + info.encoder();
+}
+
+flatbuffers::Offset<AbsoluteEncoderZeroingEstimator::State>
+AbsoluteEncoderZeroingEstimator::GetEstimatorState(
+    flatbuffers::FlatBufferBuilder *fbb) const {
+  State::Builder builder(*fbb);
+  builder.add_error(error_);
+  builder.add_zeroed(zeroed_);
+  builder.add_position(position_);
+  builder.add_absolute_position(filtered_absolute_encoder_);
+  return builder.Finish();
+}
+
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/absolute_encoder.h b/frc971/zeroing/absolute_encoder.h
new file mode 100644
index 0000000..0021e13
--- /dev/null
+++ b/frc971/zeroing/absolute_encoder.h
@@ -0,0 +1,93 @@
+#ifndef FRC971_ZEROING_ABSOLUTE_ENCODER_H_
+#define FRC971_ZEROING_ABSOLUTE_ENCODER_H_
+
+#include <vector>
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "frc971/zeroing/zeroing.h"
+
+namespace frc971 {
+namespace zeroing {
+
+// Estimates the position with an absolute encoder which also reports
+// incremental counts.  The absolute encoder can't spin more than one
+// revolution.
+class AbsoluteEncoderZeroingEstimator
+    : public ZeroingEstimator<AbsolutePosition,
+                              constants::AbsoluteEncoderZeroingConstants,
+                              AbsoluteEncoderEstimatorState> {
+ public:
+  explicit AbsoluteEncoderZeroingEstimator(
+      const constants::AbsoluteEncoderZeroingConstants &constants);
+
+  // Resets the internal logic so it needs to be re-zeroed.
+  void Reset() override;
+
+  // Updates the sensor values for the zeroing logic.
+  void UpdateEstimate(const AbsolutePosition &info) override;
+
+  void TriggerError() override { error_ = true; }
+
+  bool zeroed() const override { return zeroed_; }
+
+  double offset() const override { return offset_; }
+
+  bool error() const override { return error_; }
+
+  // Returns true if the sample buffer is full.
+  bool offset_ready() const override {
+    return relative_to_absolute_offset_samples_.size() ==
+           constants_.average_filter_size;
+  }
+
+  // Returns information about our current state.
+  virtual flatbuffers::Offset<State> GetEstimatorState(
+      flatbuffers::FlatBufferBuilder *fbb) const override;
+
+ private:
+  struct PositionStruct {
+    PositionStruct(const AbsolutePosition &position_buffer)
+        : absolute_encoder(position_buffer.absolute_encoder()),
+          encoder(position_buffer.encoder()) {}
+    double absolute_encoder;
+    double encoder;
+  };
+
+  // The zeroing constants used to describe the configuration of the system.
+  const constants::AbsoluteEncoderZeroingConstants constants_;
+
+  // True if the mechanism is zeroed.
+  bool zeroed_;
+  // Marker to track whether an error has occurred.
+  bool error_;
+  // The first valid offset we recorded. This is only set after zeroed_ first
+  // changes to true.
+  double first_offset_;
+
+  // The filtered absolute encoder.  This is used in the status for calibration.
+  double filtered_absolute_encoder_ = 0.0;
+
+  // Samples of the offset needed to line the relative encoder up with the
+  // absolute encoder.
+  ::std::vector<double> relative_to_absolute_offset_samples_;
+
+  MoveDetector<PositionStruct, AbsolutePosition> move_detector_;
+
+  // Estimated start position of the mechanism
+  double offset_ = 0;
+  // The next position in 'relative_to_absolute_offset_samples_' and
+  // 'encoder_samples_' to be used to store the next sample.
+  int samples_idx_ = 0;
+
+  // Number of NANs we've seen in a row.
+  size_t nan_samples_ = 0;
+
+  // The filtered position.
+  double position_ = 0.0;
+};
+
+}  // namespace zeroing
+}  // namespace frc971
+
+#endif  // FRC971_ZEROING_ABSOLUTE_ENCODER_H_
diff --git a/frc971/zeroing/absolute_encoder_test.cc b/frc971/zeroing/absolute_encoder_test.cc
new file mode 100644
index 0000000..38ce069
--- /dev/null
+++ b/frc971/zeroing/absolute_encoder_test.cc
@@ -0,0 +1,145 @@
+#include "frc971/zeroing/absolute_encoder.h"
+
+#include "gtest/gtest.h"
+
+#include "frc971/zeroing/zeroing_test.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+using constants::AbsoluteEncoderZeroingConstants;
+
+class AbsoluteEncoderZeroingTest : public ZeroingTest {
+ protected:
+  void MoveTo(PositionSensorSimulator *simulator,
+              AbsoluteEncoderZeroingEstimator *estimator, double new_position) {
+    simulator->MoveTo(new_position);
+    FBB fbb;
+    estimator->UpdateEstimate(
+        *simulator->FillSensorValues<AbsolutePosition>(&fbb));
+  }
+};
+
+// Makes sure that using an absolute encoder lets us zero without moving.
+TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double kMiddlePosition = 2.5;
+  const double start_pos = 2.1;
+  double measured_absolute_position = 0.3 * index_diff;
+
+  AbsoluteEncoderZeroingConstants constants{
+      kSampleSize,        index_diff, measured_absolute_position,
+      kMiddlePosition,    0.1,        kMovingBufferSize,
+      kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  AbsoluteEncoderZeroingEstimator estimator(constants);
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_TRUE(estimator.zeroed());
+  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
+}
+
+// Makes sure that we ignore a NAN if we get it, but will correctly zero
+// afterwards.
+TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingIgnoresNAN) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double start_pos = 2.1;
+  double measured_absolute_position = 0.3 * index_diff;
+  const double kMiddlePosition = 2.5;
+
+  AbsoluteEncoderZeroingConstants constants{
+      kSampleSize,        index_diff, measured_absolute_position,
+      kMiddlePosition,    0.1,        kMovingBufferSize,
+      kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  AbsoluteEncoderZeroingEstimator estimator(constants);
+
+  // We tolerate a couple NANs before we start.
+  FBB fbb;
+  fbb.Finish(CreateAbsolutePosition(
+      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
+  const auto sensor_values =
+      flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
+  for (size_t i = 0; i < kSampleSize - 1; ++i) {
+    estimator.UpdateEstimate(*sensor_values);
+  }
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_TRUE(estimator.zeroed());
+  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
+}
+
+// Makes sure that using an absolute encoder doesn't let us zero while moving.
+TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double start_pos = 10 * index_diff;
+  double measured_absolute_position = 0.3 * index_diff;
+  const double kMiddlePosition = 2.5;
+
+  AbsoluteEncoderZeroingConstants constants{
+      kSampleSize,        index_diff, measured_absolute_position,
+      kMiddlePosition,    0.1,        kMovingBufferSize,
+      kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  AbsoluteEncoderZeroingEstimator estimator(constants);
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos + i * index_diff);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+  MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_FALSE(estimator.zeroed());
+}
+
+// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
+TEST_F(AbsoluteEncoderZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
+  AbsoluteEncoderZeroingConstants constants{
+      kSampleSize, 1, 0.3, 1.0, 0.1, kMovingBufferSize, kIndexErrorFraction};
+
+  AbsoluteEncoderZeroingEstimator estimator(constants);
+
+  FBB fbb;
+  fbb.Finish(CreateAbsolutePosition(
+      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
+  const auto sensor_values =
+      flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
+  for (size_t i = 0; i < kSampleSize - 1; ++i) {
+    estimator.UpdateEstimate(*sensor_values);
+  }
+  ASSERT_FALSE(estimator.error());
+
+  estimator.UpdateEstimate(*sensor_values);
+  ASSERT_TRUE(estimator.error());
+}
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/hall_effect_and_position.cc b/frc971/zeroing/hall_effect_and_position.cc
new file mode 100644
index 0000000..e074668
--- /dev/null
+++ b/frc971/zeroing/hall_effect_and_position.cc
@@ -0,0 +1,127 @@
+#include "frc971/zeroing/hall_effect_and_position.h"
+
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+#include "glog/logging.h"
+
+namespace frc971 {
+namespace zeroing {
+
+HallEffectAndPositionZeroingEstimator::HallEffectAndPositionZeroingEstimator(
+    const ZeroingConstants &constants)
+    : constants_(constants) {
+  Reset();
+}
+
+void HallEffectAndPositionZeroingEstimator::Reset() {
+  offset_ = 0.0;
+  min_low_position_ = ::std::numeric_limits<double>::max();
+  max_low_position_ = ::std::numeric_limits<double>::lowest();
+  zeroed_ = false;
+  initialized_ = false;
+  last_used_posedge_count_ = 0;
+  cycles_high_ = 0;
+  high_long_enough_ = false;
+  first_start_pos_ = 0.0;
+  error_ = false;
+  current_ = 0.0;
+  first_start_pos_ = 0.0;
+}
+
+void HallEffectAndPositionZeroingEstimator::TriggerError() {
+  if (!error_) {
+    VLOG(1) << "Manually triggered zeroing error.\n";
+    error_ = true;
+  }
+}
+
+void HallEffectAndPositionZeroingEstimator::StoreEncoderMaxAndMin(
+    const HallEffectAndPosition &info) {
+  // If we have a new posedge.
+  if (!info.current()) {
+    if (last_hall_) {
+      min_low_position_ = max_low_position_ = info.encoder();
+    } else {
+      min_low_position_ = ::std::min(min_low_position_, info.encoder());
+      max_low_position_ = ::std::max(max_low_position_, info.encoder());
+    }
+  }
+  last_hall_ = info.current();
+}
+
+void HallEffectAndPositionZeroingEstimator::UpdateEstimate(
+    const HallEffectAndPosition &info) {
+  // We want to make sure that we encounter at least one posedge while zeroing.
+  // So we take the posedge count from the first sample after reset and wait for
+  // that count to change and for the hall effect to stay high before we
+  // consider ourselves zeroed.
+  if (!initialized_) {
+    last_used_posedge_count_ = info.posedge_count();
+    initialized_ = true;
+    last_hall_ = info.current();
+  }
+
+  StoreEncoderMaxAndMin(info);
+
+  if (info.current()) {
+    cycles_high_++;
+  } else {
+    cycles_high_ = 0;
+    last_used_posedge_count_ = info.posedge_count();
+  }
+
+  high_long_enough_ = cycles_high_ >= constants_.hall_trigger_zeroing_length;
+
+  bool moving_backward = false;
+  if (constants_.zeroing_move_direction) {
+    moving_backward = info.encoder() > min_low_position_;
+  } else {
+    moving_backward = info.encoder() < max_low_position_;
+  }
+
+  // If there are no posedges to use or we don't have enough samples yet to
+  // have a well-filtered starting position then we use the filtered value as
+  // our best guess.
+  if (last_used_posedge_count_ != info.posedge_count() && high_long_enough_ &&
+      moving_backward) {
+    // Note the offset and the current posedge count so that we only run this
+    // logic once per posedge. That should be more resilient to corrupted
+    // intermediate data.
+    offset_ = -info.posedge_value();
+    if (constants_.zeroing_move_direction) {
+      offset_ += constants_.lower_hall_position;
+    } else {
+      offset_ += constants_.upper_hall_position;
+    }
+    last_used_posedge_count_ = info.posedge_count();
+
+    // Save the first starting position.
+    if (!zeroed_) {
+      first_start_pos_ = offset_;
+      VLOG(2) << "latching start position" << first_start_pos_;
+    }
+
+    // Now that we have an accurate starting position we can consider ourselves
+    // zeroed.
+    zeroed_ = true;
+  }
+
+  position_ = info.encoder() - offset_;
+}
+
+flatbuffers::Offset<HallEffectAndPositionZeroingEstimator::State>
+HallEffectAndPositionZeroingEstimator::GetEstimatorState(
+    flatbuffers::FlatBufferBuilder *fbb) const {
+  State::Builder builder(*fbb);
+  builder.add_error(error_);
+  builder.add_zeroed(zeroed_);
+  builder.add_encoder(position_);
+  builder.add_high_long_enough(high_long_enough_);
+  builder.add_offset(offset_);
+  return builder.Finish();
+}
+
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/hall_effect_and_position.h b/frc971/zeroing/hall_effect_and_position.h
new file mode 100644
index 0000000..f03a442
--- /dev/null
+++ b/frc971/zeroing/hall_effect_and_position.h
@@ -0,0 +1,90 @@
+#ifndef FRC971_ZEROING_HALL_EFFECT_AND_POSITION_H_
+#define FRC971_ZEROING_HALL_EFFECT_AND_POSITION_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "frc971/zeroing/zeroing.h"
+
+namespace frc971 {
+namespace zeroing {
+
+// Estimates the position with an incremental encoder and a hall effect sensor.
+class HallEffectAndPositionZeroingEstimator
+    : public ZeroingEstimator<HallEffectAndPosition,
+                              constants::HallEffectZeroingConstants,
+                              HallEffectAndPositionEstimatorState> {
+ public:
+  explicit HallEffectAndPositionZeroingEstimator(
+      const ZeroingConstants &constants);
+
+  // Update the internal logic with the next sensor values.
+  void UpdateEstimate(const Position &info) override;
+
+  // Reset the internal logic so it needs to be re-zeroed.
+  void Reset() override;
+
+  // Manually trigger an internal error. This is used for testing the error
+  // logic.
+  void TriggerError() override;
+
+  bool error() const override { return error_; }
+
+  bool zeroed() const override { return zeroed_; }
+
+  double offset() const override { return offset_; }
+
+  bool offset_ready() const override { return zeroed_; }
+
+  // Returns information about our current state.
+  virtual flatbuffers::Offset<State> GetEstimatorState(
+      flatbuffers::FlatBufferBuilder *fbb) const override;
+
+ private:
+  // Sets the minimum and maximum posedge position values.
+  void StoreEncoderMaxAndMin(const HallEffectAndPosition &info);
+
+  // The zeroing constants used to describe the configuration of the system.
+  const ZeroingConstants constants_;
+
+  // The estimated state of the hall effect.
+  double current_ = 0.0;
+  // The estimated position.
+  double position_ = 0.0;
+  // The smallest and largest positions of the last set of encoder positions
+  // while the hall effect was low.
+  double min_low_position_;
+  double max_low_position_;
+  // If we've seen the hall effect high for enough times without going low, then
+  // we can be sure it isn't a false positive.
+  bool high_long_enough_;
+  size_t cycles_high_;
+
+  bool last_hall_ = false;
+
+  // The estimated starting position of the mechanism. We also call this the
+  // 'offset' in some contexts.
+  double offset_;
+  // Flag for triggering logic that takes note of the current posedge count
+  // after a reset. See `last_used_posedge_count_'.
+  bool initialized_;
+  // After a reset we keep track of the posedge count with this. Only after the
+  // posedge count changes (i.e. increments at least once or wraps around) will
+  // we consider the mechanism zeroed. We also use this to store the most recent
+  // `HallEffectAndPosition::posedge_count' value when the start position
+  // was calculated. It helps us calculate the start position only on posedges
+  // to reject corrupted intermediate data.
+  int32_t last_used_posedge_count_;
+  // Marker to track whether we're fully zeroed yet or not.
+  bool zeroed_;
+  // Marker to track whether an error has occurred. This gets reset to false
+  // whenever Reset() is called.
+  bool error_ = false;
+  // Stores the position "start_pos" variable the first time the program
+  // is zeroed.
+  double first_start_pos_;
+};
+
+}  // namespace zeroing
+}  // namespace frc971
+
+#endif  // FRC971_ZEROING_HALL_EFFECT_AND_POSITION_H_
diff --git a/frc971/zeroing/hall_effect_and_position_test.cc b/frc971/zeroing/hall_effect_and_position_test.cc
new file mode 100644
index 0000000..c9ddf65
--- /dev/null
+++ b/frc971/zeroing/hall_effect_and_position_test.cc
@@ -0,0 +1,135 @@
+#include "frc971/zeroing/hall_effect_and_position.h"
+
+#include "gtest/gtest.h"
+
+#include "frc971/zeroing/zeroing_test.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+class HallEffectAndPositionZeroingTest : public ZeroingTest {
+ protected:
+  // The starting position of the system.
+  static constexpr double kStartPosition = 2.0;
+
+  HallEffectAndPositionZeroingTest()
+      : constants_(MakeConstants()), sim_(constants_.index_difference) {
+    // Start the system out at the starting position.
+    sim_.InitializeHallEffectAndPosition(kStartPosition,
+                                         constants_.lower_hall_position,
+                                         constants_.upper_hall_position);
+  }
+
+  void MoveTo(PositionSensorSimulator *simulator,
+              HallEffectAndPositionZeroingEstimator *estimator,
+              double new_position) {
+    simulator->MoveTo(new_position);
+    FBB fbb;
+    estimator->UpdateEstimate(
+        *simulator->FillSensorValues<HallEffectAndPosition>(&fbb));
+  }
+
+  // Returns a reasonable set of test constants.
+  static constants::HallEffectZeroingConstants MakeConstants() {
+    constants::HallEffectZeroingConstants constants;
+    constants.lower_hall_position = 0.25;
+    constants.upper_hall_position = 0.75;
+    constants.index_difference = 1.0;
+    constants.hall_trigger_zeroing_length = 2;
+    constants.zeroing_move_direction = false;
+    return constants;
+  }
+
+  // Constants, and the simulation using them.
+  const constants::HallEffectZeroingConstants constants_;
+  PositionSensorSimulator sim_;
+};
+
+// Tests that an error is detected when the starting position changes too much.
+TEST_F(HallEffectAndPositionZeroingTest, TestHallEffectZeroing) {
+  HallEffectAndPositionZeroingEstimator estimator(constants_);
+
+  // Should not be zeroed when we stand still.
+  for (int i = 0; i < 300; ++i) {
+    MoveTo(&sim_, &estimator, kStartPosition);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim_, &estimator, 1.9);
+  ASSERT_FALSE(estimator.zeroed());
+
+  // Move to where the hall effect is triggered and make sure it becomes zeroed.
+  MoveTo(&sim_, &estimator, 1.5);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 1.5);
+  ASSERT_TRUE(estimator.zeroed());
+
+  // Check that the offset is calculated correctly.  We should expect to read
+  // 0.5.  Since the encoder is reading -0.5 right now, the offset needs to be
+  // 1.
+  EXPECT_DOUBLE_EQ(1.0, estimator.offset());
+
+  // Make sure triggering errors works.
+  estimator.TriggerError();
+  ASSERT_TRUE(estimator.error());
+
+  // Ensure resetting resets the state of the estimator.
+  estimator.Reset();
+  ASSERT_FALSE(estimator.zeroed());
+  ASSERT_FALSE(estimator.error());
+}
+
+// Tests that we don't zero on a too short pulse.
+TEST_F(HallEffectAndPositionZeroingTest, TestTooShortPulse) {
+  HallEffectAndPositionZeroingEstimator estimator(constants_);
+
+  // Trigger for 1 cycle.
+  MoveTo(&sim_, &estimator, 0.9);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.5);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.9);
+  EXPECT_FALSE(estimator.zeroed());
+}
+
+// Tests that we don't zero when we go the wrong direction.
+TEST_F(HallEffectAndPositionZeroingTest, TestWrongDirectionNoZero) {
+  HallEffectAndPositionZeroingEstimator estimator(constants_);
+
+  // Pass through the sensor, lingering long enough that we should zero.
+  MoveTo(&sim_, &estimator, 0.0);
+  ASSERT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.4);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.6);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.7);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.9);
+  EXPECT_FALSE(estimator.zeroed());
+}
+
+// Make sure we don't zero if we start in the hall effect's range.
+TEST_F(HallEffectAndPositionZeroingTest, TestStartingOnNoZero) {
+  HallEffectAndPositionZeroingEstimator estimator(constants_);
+  MoveTo(&sim_, &estimator, 0.5);
+  estimator.Reset();
+
+  // Stay on the hall effect.  We shouldn't zero.
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.5);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.5);
+  EXPECT_FALSE(estimator.zeroed());
+
+  // Verify moving off the hall still doesn't zero us.
+  MoveTo(&sim_, &estimator, 0.0);
+  EXPECT_FALSE(estimator.zeroed());
+  MoveTo(&sim_, &estimator, 0.0);
+  EXPECT_FALSE(estimator.zeroed());
+}
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pot_and_absolute_encoder.cc b/frc971/zeroing/pot_and_absolute_encoder.cc
new file mode 100644
index 0000000..200f399
--- /dev/null
+++ b/frc971/zeroing/pot_and_absolute_encoder.cc
@@ -0,0 +1,196 @@
+#include "frc971/zeroing/pot_and_absolute_encoder.h"
+
+#include <cmath>
+#include <numeric>
+
+#include "glog/logging.h"
+
+#include "frc971/zeroing/wrap.h"
+
+namespace frc971 {
+namespace zeroing {
+
+PotAndAbsoluteEncoderZeroingEstimator::PotAndAbsoluteEncoderZeroingEstimator(
+    const constants::PotAndAbsoluteEncoderZeroingConstants &constants)
+    : constants_(constants), move_detector_(constants_.moving_buffer_size) {
+  relative_to_absolute_offset_samples_.reserve(constants_.average_filter_size);
+  offset_samples_.reserve(constants_.average_filter_size);
+  Reset();
+}
+
+void PotAndAbsoluteEncoderZeroingEstimator::Reset() {
+  first_offset_ = 0.0;
+  pot_relative_encoder_offset_ = 0.0;
+  offset_ = 0.0;
+  samples_idx_ = 0;
+  filtered_position_ = 0.0;
+  position_ = 0.0;
+  zeroed_ = false;
+  nan_samples_ = 0;
+  relative_to_absolute_offset_samples_.clear();
+  offset_samples_.clear();
+  move_detector_.Reset();
+  error_ = false;
+}
+
+// So, this needs to be a multistep process.  We need to first estimate the
+// offset between the absolute encoder and the relative encoder.  That process
+// should get us an absolute number which is off by integer multiples of the
+// distance/rev.  In parallel, we can estimate the offset between the pot and
+// encoder.  When both estimates have converged, we can then compute the offset
+// in a cycle, and which cycle, which gives us the accurate global offset.
+//
+// It's tricky to compute the offset between the absolute and relative encoder.
+// We need to compute this inside 1 revolution.  The easiest way to do this
+// would be to wrap the encoder, subtract the two of them, and then average the
+// result.  That will struggle when they are off by PI.  Instead, we need to
+// wrap the number to +- PI from the current averaged offset.
+//
+// To guard against the robot moving while updating estimates, buffer a number
+// of samples and check that the buffered samples are not different than the
+// zeroing threshold. At any point that the samples differ too much, do not
+// update estimates based on those samples.
+void PotAndAbsoluteEncoderZeroingEstimator::UpdateEstimate(
+    const PotAndAbsolutePosition &info) {
+  // Check for Abs Encoder NaN value that would mess up the rest of the zeroing
+  // code below. NaN values are given when the Absolute Encoder is disconnected.
+  if (::std::isnan(info.absolute_encoder())) {
+    if (zeroed_) {
+      VLOG(1) << "NAN on absolute encoder.";
+      error_ = true;
+    } else {
+      ++nan_samples_;
+      VLOG(1) << "NAN on absolute encoder while zeroing" << nan_samples_;
+      if (nan_samples_ >= constants_.average_filter_size) {
+        error_ = true;
+        zeroed_ = true;
+      }
+    }
+    // Throw some dummy values in for now.
+    filtered_absolute_encoder_ = info.absolute_encoder();
+    filtered_position_ = pot_relative_encoder_offset_ + info.encoder();
+    position_ = offset_ + info.encoder();
+    return;
+  }
+
+  const bool moving = move_detector_.Update(info, constants_.moving_buffer_size,
+                                            constants_.zeroing_threshold);
+
+  if (!moving) {
+    const PositionStruct &sample = move_detector_.GetSample();
+
+    // Compute the average offset between the absolute encoder and relative
+    // encoder.  If we have 0 samples, assume it is 0.
+    double average_relative_to_absolute_offset =
+        relative_to_absolute_offset_samples_.size() == 0
+            ? 0.0
+            : ::std::accumulate(relative_to_absolute_offset_samples_.begin(),
+                                relative_to_absolute_offset_samples_.end(),
+                                0.0) /
+                  relative_to_absolute_offset_samples_.size();
+
+    const double adjusted_incremental_encoder =
+        sample.encoder + average_relative_to_absolute_offset;
+
+    // Now, compute the nearest absolute encoder value to the offset relative
+    // encoder position.
+    const double adjusted_absolute_encoder =
+        UnWrap(adjusted_incremental_encoder,
+               sample.absolute_encoder - constants_.measured_absolute_position,
+               constants_.one_revolution_distance);
+
+    // We can now compute the offset now that we have unwrapped the absolute
+    // encoder.
+    const double relative_to_absolute_offset =
+        adjusted_absolute_encoder - sample.encoder;
+
+    // Add the sample and update the average with the new reading.
+    const size_t relative_to_absolute_offset_samples_size =
+        relative_to_absolute_offset_samples_.size();
+    if (relative_to_absolute_offset_samples_size <
+        constants_.average_filter_size) {
+      average_relative_to_absolute_offset =
+          (average_relative_to_absolute_offset *
+               relative_to_absolute_offset_samples_size +
+           relative_to_absolute_offset) /
+          (relative_to_absolute_offset_samples_size + 1);
+
+      relative_to_absolute_offset_samples_.push_back(
+          relative_to_absolute_offset);
+    } else {
+      average_relative_to_absolute_offset -=
+          relative_to_absolute_offset_samples_[samples_idx_] /
+          relative_to_absolute_offset_samples_size;
+      relative_to_absolute_offset_samples_[samples_idx_] =
+          relative_to_absolute_offset;
+      average_relative_to_absolute_offset +=
+          relative_to_absolute_offset /
+          relative_to_absolute_offset_samples_size;
+    }
+
+    // Now compute the offset between the pot and relative encoder.
+    if (offset_samples_.size() < constants_.average_filter_size) {
+      offset_samples_.push_back(sample.pot - sample.encoder);
+    } else {
+      offset_samples_[samples_idx_] = sample.pot - sample.encoder;
+    }
+
+    // Drop the oldest sample when we run this function the next time around.
+    samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
+
+    pot_relative_encoder_offset_ =
+        ::std::accumulate(offset_samples_.begin(), offset_samples_.end(), 0.0) /
+        offset_samples_.size();
+
+    offset_ = UnWrap(sample.encoder + pot_relative_encoder_offset_,
+                     average_relative_to_absolute_offset + sample.encoder,
+                     constants_.one_revolution_distance) -
+              sample.encoder;
+
+    // Reverse the math for adjusted_absolute_encoder to compute the absolute
+    // encoder. Do this by taking the adjusted encoder, and then subtracting off
+    // the second argument above, and the value that was added by Wrap.
+    filtered_absolute_encoder_ =
+        ((sample.encoder + average_relative_to_absolute_offset) -
+         (-constants_.measured_absolute_position +
+          (adjusted_absolute_encoder -
+           (sample.absolute_encoder - constants_.measured_absolute_position))));
+
+    if (offset_ready()) {
+      if (!zeroed_) {
+        first_offset_ = offset_;
+      }
+
+      if (::std::abs(first_offset_ - offset_) >
+          constants_.allowable_encoder_error *
+              constants_.one_revolution_distance) {
+        VLOG(1) << "Offset moved too far. Initial: " << first_offset_
+                << ", current " << offset_ << ", allowable change: "
+                << constants_.allowable_encoder_error *
+                       constants_.one_revolution_distance;
+        error_ = true;
+      }
+
+      zeroed_ = true;
+    }
+  }
+
+  // Update the position.
+  filtered_position_ = pot_relative_encoder_offset_ + info.encoder();
+  position_ = offset_ + info.encoder();
+}
+
+flatbuffers::Offset<PotAndAbsoluteEncoderZeroingEstimator::State>
+PotAndAbsoluteEncoderZeroingEstimator::GetEstimatorState(
+    flatbuffers::FlatBufferBuilder *fbb) const {
+  State::Builder builder(*fbb);
+  builder.add_error(error_);
+  builder.add_zeroed(zeroed_);
+  builder.add_position(position_);
+  builder.add_pot_position(filtered_position_);
+  builder.add_absolute_position(filtered_absolute_encoder_);
+  return builder.Finish();
+}
+
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pot_and_absolute_encoder.h b/frc971/zeroing/pot_and_absolute_encoder.h
new file mode 100644
index 0000000..133eaf5
--- /dev/null
+++ b/frc971/zeroing/pot_and_absolute_encoder.h
@@ -0,0 +1,100 @@
+#ifndef FRC971_ZEROING_POT_AND_ABSOLUTE_ENCODER_H_
+#define FRC971_ZEROING_POT_AND_ABSOLUTE_ENCODER_H_
+
+#include <vector>
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "frc971/zeroing/zeroing.h"
+
+namespace frc971 {
+namespace zeroing {
+
+// Estimates the position with an absolute encoder which also reports
+// incremental counts, and a potentiometer.
+class PotAndAbsoluteEncoderZeroingEstimator
+    : public ZeroingEstimator<PotAndAbsolutePosition,
+                              constants::PotAndAbsoluteEncoderZeroingConstants,
+                              PotAndAbsoluteEncoderEstimatorState> {
+ public:
+  explicit PotAndAbsoluteEncoderZeroingEstimator(
+      const constants::PotAndAbsoluteEncoderZeroingConstants &constants);
+
+  // Resets the internal logic so it needs to be re-zeroed.
+  void Reset() override;
+
+  // Updates the sensor values for the zeroing logic.
+  void UpdateEstimate(const PotAndAbsolutePosition &info) override;
+
+  void TriggerError() override { error_ = true; }
+
+  bool zeroed() const override { return zeroed_; }
+
+  double offset() const override { return offset_; }
+
+  bool error() const override { return error_; }
+
+  // Returns true if the sample buffer is full.
+  bool offset_ready() const override {
+    return relative_to_absolute_offset_samples_.size() ==
+               constants_.average_filter_size &&
+           offset_samples_.size() == constants_.average_filter_size;
+  }
+
+  // Returns information about our current state.
+  virtual flatbuffers::Offset<State> GetEstimatorState(
+      flatbuffers::FlatBufferBuilder *fbb) const override;
+
+ private:
+  struct PositionStruct {
+    PositionStruct(const PotAndAbsolutePosition &position_buffer)
+        : absolute_encoder(position_buffer.absolute_encoder()),
+          encoder(position_buffer.encoder()),
+          pot(position_buffer.pot()) {}
+    double absolute_encoder;
+    double encoder;
+    double pot;
+  };
+
+  // The zeroing constants used to describe the configuration of the system.
+  const constants::PotAndAbsoluteEncoderZeroingConstants constants_;
+
+  // True if the mechanism is zeroed.
+  bool zeroed_;
+  // Marker to track whether an error has occurred.
+  bool error_;
+  // The first valid offset we recorded. This is only set after zeroed_ first
+  // changes to true.
+  double first_offset_;
+
+  // The filtered absolute encoder.  This is used in the status for calibration.
+  double filtered_absolute_encoder_ = 0.0;
+
+  // Samples of the offset needed to line the relative encoder up with the
+  // absolute encoder.
+  ::std::vector<double> relative_to_absolute_offset_samples_;
+  // Offset between the Pot and Relative encoder position.
+  ::std::vector<double> offset_samples_;
+
+  MoveDetector<PositionStruct, PotAndAbsolutePosition> move_detector_;
+
+  // Estimated offset between the pot and relative encoder.
+  double pot_relative_encoder_offset_ = 0;
+  // Estimated start position of the mechanism
+  double offset_ = 0;
+  // The next position in 'relative_to_absolute_offset_samples_' and
+  // 'encoder_samples_' to be used to store the next sample.
+  int samples_idx_ = 0;
+
+  size_t nan_samples_ = 0;
+
+  // The unzeroed filtered position.
+  double filtered_position_ = 0.0;
+  // The filtered position.
+  double position_ = 0.0;
+};
+
+}  // namespace zeroing
+}  // namespace frc971
+
+#endif  // FRC971_ZEROING_POT_AND_ABSOLUTE_ENCODER_H_
diff --git a/frc971/zeroing/pot_and_absolute_encoder_test.cc b/frc971/zeroing/pot_and_absolute_encoder_test.cc
new file mode 100644
index 0000000..ba89834
--- /dev/null
+++ b/frc971/zeroing/pot_and_absolute_encoder_test.cc
@@ -0,0 +1,143 @@
+#include "frc971/zeroing/pot_and_absolute_encoder.h"
+
+#include "gtest/gtest.h"
+
+#include "frc971/zeroing/zeroing_test.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+using constants::PotAndAbsoluteEncoderZeroingConstants;
+
+class PotAndAbsoluteEncoderZeroingTest : public ZeroingTest {
+ protected:
+  void MoveTo(PositionSensorSimulator *simulator,
+              PotAndAbsoluteEncoderZeroingEstimator *estimator,
+              double new_position) {
+    simulator->MoveTo(new_position);
+    FBB fbb;
+    estimator->UpdateEstimate(
+        *simulator->FillSensorValues<PotAndAbsolutePosition>(&fbb));
+  }
+};
+
+// Makes sure that using an absolute encoder lets us zero without moving.
+TEST_F(PotAndAbsoluteEncoderZeroingTest,
+       TestPotAndAbsoluteEncoderZeroingWithoutMovement) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double start_pos = 2.1;
+  double measured_absolute_position = 0.3 * index_diff;
+
+  PotAndAbsoluteEncoderZeroingConstants constants{
+      kSampleSize, index_diff,        measured_absolute_position,
+      0.1,         kMovingBufferSize, kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_TRUE(estimator.zeroed());
+  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
+}
+
+// Makes sure that we ignore a NAN if we get it, but will correctly zero
+// afterwards.
+TEST_F(PotAndAbsoluteEncoderZeroingTest,
+       TestPotAndAbsoluteEncoderZeroingIgnoresNAN) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double start_pos = 2.1;
+  double measured_absolute_position = 0.3 * index_diff;
+
+  PotAndAbsoluteEncoderZeroingConstants constants{
+      kSampleSize, index_diff,        measured_absolute_position,
+      0.1,         kMovingBufferSize, kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
+
+  // We tolerate a couple NANs before we start.
+  FBB fbb;
+  fbb.Finish(CreatePotAndAbsolutePosition(
+      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
+  for (size_t i = 0; i < kSampleSize - 1; ++i) {
+    estimator.UpdateEstimate(
+        *flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer()));
+  }
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_TRUE(estimator.zeroed());
+  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
+}
+
+// Makes sure that using an absolute encoder doesn't let us zero while moving.
+TEST_F(PotAndAbsoluteEncoderZeroingTest,
+       TestPotAndAbsoluteEncoderZeroingWithMovement) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+
+  const double start_pos = 10 * index_diff;
+  double measured_absolute_position = 0.3 * index_diff;
+
+  PotAndAbsoluteEncoderZeroingConstants constants{
+      kSampleSize, index_diff,        measured_absolute_position,
+      0.1,         kMovingBufferSize, kIndexErrorFraction};
+
+  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
+                 constants.measured_absolute_position);
+
+  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
+
+  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
+    MoveTo(&sim, &estimator, start_pos + i * index_diff);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+  MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
+
+  MoveTo(&sim, &estimator, start_pos);
+  ASSERT_FALSE(estimator.zeroed());
+}
+
+// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
+TEST_F(PotAndAbsoluteEncoderZeroingTest,
+       TestPotAndAbsoluteEncoderZeroingWithNaN) {
+  PotAndAbsoluteEncoderZeroingConstants constants{
+      kSampleSize, 1, 0.3, 0.1, kMovingBufferSize, kIndexErrorFraction};
+
+  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
+
+  FBB fbb;
+  fbb.Finish(CreatePotAndAbsolutePosition(
+      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
+  const auto sensor_values =
+      flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer());
+  for (size_t i = 0; i < kSampleSize - 1; ++i) {
+    estimator.UpdateEstimate(*sensor_values);
+  }
+  ASSERT_FALSE(estimator.error());
+
+  estimator.UpdateEstimate(*sensor_values);
+  ASSERT_TRUE(estimator.error());
+}
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pot_and_index.cc b/frc971/zeroing/pot_and_index.cc
new file mode 100644
index 0000000..7c713d9
--- /dev/null
+++ b/frc971/zeroing/pot_and_index.cc
@@ -0,0 +1,135 @@
+#include "frc971/zeroing/pot_and_index.h"
+
+#include <cmath>
+
+#include "glog/logging.h"
+
+namespace frc971 {
+namespace zeroing {
+
+PotAndIndexPulseZeroingEstimator::PotAndIndexPulseZeroingEstimator(
+    const constants::PotAndIndexPulseZeroingConstants &constants)
+    : constants_(constants) {
+  start_pos_samples_.reserve(constants_.average_filter_size);
+  Reset();
+}
+
+void PotAndIndexPulseZeroingEstimator::Reset() {
+  samples_idx_ = 0;
+  offset_ = 0;
+  start_pos_samples_.clear();
+  zeroed_ = false;
+  wait_for_index_pulse_ = true;
+  last_used_index_pulse_count_ = 0;
+  error_ = false;
+}
+
+void PotAndIndexPulseZeroingEstimator::TriggerError() {
+  if (!error_) {
+    VLOG(1) << "Manually triggered zeroing error.";
+    error_ = true;
+  }
+}
+
+double PotAndIndexPulseZeroingEstimator::CalculateStartPosition(
+    double start_average, double latched_encoder) const {
+  // We calculate an aproximation of the value of the last index position.
+  // Also account for index pulses not lining up with integer multiples of the
+  // index_diff.
+  double index_pos =
+      start_average + latched_encoder - constants_.measured_index_position;
+  // We round index_pos to the closest valid value of the index.
+  double accurate_index_pos = (round(index_pos / constants_.index_difference)) *
+                              constants_.index_difference;
+  // Now we reverse the first calculation to get the accurate start position.
+  return accurate_index_pos - latched_encoder +
+         constants_.measured_index_position;
+}
+
+void PotAndIndexPulseZeroingEstimator::UpdateEstimate(
+    const PotAndIndexPosition &info) {
+  // We want to make sure that we encounter at least one index pulse while
+  // zeroing. So we take the index pulse count from the first sample after
+  // reset and wait for that count to change before we consider ourselves
+  // zeroed.
+  if (wait_for_index_pulse_) {
+    last_used_index_pulse_count_ = info.index_pulses();
+    wait_for_index_pulse_ = false;
+  }
+
+  if (start_pos_samples_.size() < constants_.average_filter_size) {
+    start_pos_samples_.push_back(info.pot() - info.encoder());
+  } else {
+    start_pos_samples_[samples_idx_] = info.pot() - info.encoder();
+  }
+
+  // Drop the oldest sample when we run this function the next time around.
+  samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
+
+  double sample_sum = 0.0;
+
+  for (size_t i = 0; i < start_pos_samples_.size(); ++i) {
+    sample_sum += start_pos_samples_[i];
+  }
+
+  // Calculates the average of the starting position.
+  double start_average = sample_sum / start_pos_samples_.size();
+
+  // If there are no index pulses to use or we don't have enough samples yet to
+  // have a well-filtered starting position then we use the filtered value as
+  // our best guess.
+  if (!zeroed_ &&
+      (info.index_pulses() == last_used_index_pulse_count_ || !offset_ready())) {
+    offset_ = start_average;
+  } else if (!zeroed_ || last_used_index_pulse_count_ != info.index_pulses()) {
+    // Note the accurate start position and the current index pulse count so
+    // that we only run this logic once per index pulse. That should be more
+    // resilient to corrupted intermediate data.
+    offset_ = CalculateStartPosition(start_average, info.latched_encoder());
+    last_used_index_pulse_count_ = info.index_pulses();
+
+    // TODO(austin): Reject encoder positions which have x% error rather than
+    // rounding to the closest index pulse.
+
+    // Save the first starting position.
+    if (!zeroed_) {
+      first_start_pos_ = offset_;
+      VLOG(2) << "latching start position" << first_start_pos_;
+    }
+
+    // Now that we have an accurate starting position we can consider ourselves
+    // zeroed.
+    zeroed_ = true;
+    // Throw an error if first_start_pos is bigger/smaller than
+    // constants_.allowable_encoder_error * index_diff + start_pos.
+    if (::std::abs(first_start_pos_ - offset_) >
+        constants_.allowable_encoder_error * constants_.index_difference) {
+      if (!error_) {
+        VLOG(1)
+            << "Encoder ticks out of range since last index pulse. first start "
+               "position: "
+            << first_start_pos_ << " recent starting position: " << offset_
+            << ", allowable error: "
+            << constants_.allowable_encoder_error * constants_.index_difference;
+        error_ = true;
+      }
+    }
+  }
+
+  position_ = offset_ + info.encoder();
+  filtered_position_ = start_average + info.encoder();
+}
+
+flatbuffers::Offset<PotAndIndexPulseZeroingEstimator::State>
+PotAndIndexPulseZeroingEstimator::GetEstimatorState(
+    flatbuffers::FlatBufferBuilder *fbb) const {
+  State::Builder builder(*fbb);
+  builder.add_error(error_);
+  builder.add_zeroed(zeroed_);
+  builder.add_position(position_);
+  builder.add_pot_position(filtered_position_);
+  return builder.Finish();
+}
+
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pot_and_index.h b/frc971/zeroing/pot_and_index.h
new file mode 100644
index 0000000..473c674
--- /dev/null
+++ b/frc971/zeroing/pot_and_index.h
@@ -0,0 +1,103 @@
+#ifndef FRC971_ZEROING_POT_AND_INDEX_H_
+#define FRC971_ZEROING_POT_AND_INDEX_H_
+
+#include <vector>
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "frc971/zeroing/zeroing.h"
+
+namespace frc971 {
+namespace zeroing {
+
+// Estimates the position with an incremental encoder with an index pulse and a
+// potentiometer.
+class PotAndIndexPulseZeroingEstimator
+    : public ZeroingEstimator<PotAndIndexPosition,
+                              constants::PotAndIndexPulseZeroingConstants,
+                              EstimatorState> {
+ public:
+  explicit PotAndIndexPulseZeroingEstimator(
+      const constants::PotAndIndexPulseZeroingConstants &constants);
+
+  // Update the internal logic with the next sensor values.
+  void UpdateEstimate(const PotAndIndexPosition &info) override;
+
+  // Reset the internal logic so it needs to be re-zeroed.
+  void Reset() override;
+
+  // Manually trigger an internal error. This is used for testing the error
+  // logic.
+  void TriggerError() override;
+
+  bool error() const override { return error_; }
+
+  bool zeroed() const override { return zeroed_; }
+
+  double offset() const override { return offset_; }
+
+  // Returns a number between 0 and 1 that represents the percentage of the
+  // samples being used in the moving average filter. A value of 0.0 means that
+  // no samples are being used. A value of 1.0 means that the filter is using
+  // as many samples as it has room for. For example, after a Reset() this
+  // value returns 0.0. As more samples get added with UpdateEstimate(...) the
+  // return value starts increasing to 1.0.
+  double offset_ratio_ready() const {
+    return start_pos_samples_.size() /
+           static_cast<double>(constants_.average_filter_size);
+  }
+
+  // Returns true if the sample buffer is full.
+  bool offset_ready() const override {
+    return start_pos_samples_.size() == constants_.average_filter_size;
+  }
+
+  // Returns information about our current state.
+  virtual flatbuffers::Offset<State> GetEstimatorState(
+      flatbuffers::FlatBufferBuilder *fbb) const override;
+
+ private:
+  // This function calculates the start position given the internal state and
+  // the provided `latched_encoder' value.
+  double CalculateStartPosition(double start_average,
+                                double latched_encoder) const;
+
+  // The zeroing constants used to describe the configuration of the system.
+  const constants::PotAndIndexPulseZeroingConstants constants_;
+
+  // The estimated position.
+  double position_;
+  // The unzeroed filtered position.
+  double filtered_position_ = 0.0;
+  // The next position in 'start_pos_samples_' to be used to store the next
+  // sample.
+  int samples_idx_;
+  // Last 'max_sample_count_' samples for start positions.
+  std::vector<double> start_pos_samples_;
+  // The estimated starting position of the mechanism. We also call this the
+  // 'offset' in some contexts.
+  double offset_;
+  // Flag for triggering logic that takes note of the current index pulse count
+  // after a reset. See `last_used_index_pulse_count_'.
+  bool wait_for_index_pulse_;
+  // After a reset we keep track of the index pulse count with this. Only after
+  // the index pulse count changes (i.e. increments at least once or wraps
+  // around) will we consider the mechanism zeroed. We also use this to store
+  // the most recent `PotAndIndexPosition::index_pulses' value when the start
+  // position was calculated. It helps us calculate the start position only on
+  // index pulses to reject corrupted intermediate data.
+  uint32_t last_used_index_pulse_count_;
+  // Marker to track whether we're fully zeroed yet or not.
+  bool zeroed_;
+  // Marker to track whether an error has occurred. This gets reset to false
+  // whenever Reset() is called.
+  bool error_;
+  // Stores the position "start_pos" variable the first time the program
+  // is zeroed.
+  double first_start_pos_;
+};
+
+}  // namespace zeroing
+}  // namespace frc971
+
+#endif  // FRC971_ZEROING_POT_AND_INDEX_H_
diff --git a/frc971/zeroing/pot_and_index_test.cc b/frc971/zeroing/pot_and_index_test.cc
new file mode 100644
index 0000000..b2b00ce
--- /dev/null
+++ b/frc971/zeroing/pot_and_index_test.cc
@@ -0,0 +1,283 @@
+#include "frc971/zeroing/pot_and_index.h"
+
+#include "gtest/gtest.h"
+
+#include "frc971/zeroing/zeroing_test.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+using constants::PotAndIndexPulseZeroingConstants;
+
+class PotAndIndexZeroingTest : public ZeroingTest {
+ protected:
+  void MoveTo(PositionSensorSimulator *simulator,
+              PotAndIndexPulseZeroingEstimator *estimator,
+              double new_position) {
+    simulator->MoveTo(new_position);
+    FBB fbb;
+    estimator->UpdateEstimate(
+        *simulator->FillSensorValues<PotAndIndexPosition>(&fbb));
+  }
+};
+
+TEST_F(PotAndIndexZeroingTest, TestMovingAverageFilter) {
+  const double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.6 * index_diff, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  // The zeroing code is supposed to perform some filtering on the difference
+  // between the potentiometer value and the encoder value. We assume that 300
+  // samples are sufficient to have updated the filter.
+  for (int i = 0; i < 300; i++) {
+    MoveTo(&sim, &estimator, 3.3 * index_diff);
+  }
+  ASSERT_NEAR(3.3 * index_diff, GetEstimatorPosition(&estimator),
+              kAcceptableUnzeroedError * index_diff);
+
+  for (int i = 0; i < 300; i++) {
+    MoveTo(&sim, &estimator, 3.9 * index_diff);
+  }
+  ASSERT_NEAR(3.9 * index_diff, GetEstimatorPosition(&estimator),
+              kAcceptableUnzeroedError * index_diff);
+}
+
+TEST_F(PotAndIndexZeroingTest, NotZeroedBeforeEnoughSamplesCollected) {
+  double index_diff = 0.5;
+  double position = 3.6 * index_diff;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(position, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  // Make sure that the zeroing code does not consider itself zeroed until we
+  // collect a good amount of samples. In this case we're waiting until the
+  // moving average filter is full.
+  for (unsigned int i = 0; i < kSampleSize - 1; i++) {
+    MoveTo(&sim, &estimator, position += index_diff);
+    ASSERT_FALSE(estimator.zeroed());
+  }
+
+  MoveTo(&sim, &estimator, position);
+  ASSERT_TRUE(estimator.zeroed());
+}
+
+TEST_F(PotAndIndexZeroingTest, TestLotsOfMovement) {
+  double index_diff = 1.0;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.6, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  // The zeroing code is supposed to perform some filtering on the difference
+  // between the potentiometer value and the encoder value. We assume that 300
+  // samples are sufficient to have updated the filter.
+  for (int i = 0; i < 300; i++) {
+    MoveTo(&sim, &estimator, 3.6);
+  }
+  ASSERT_NEAR(3.6, GetEstimatorPosition(&estimator),
+              kAcceptableUnzeroedError * index_diff);
+
+  // With a single index pulse the zeroing estimator should be able to lock
+  // onto the true value of the position.
+  MoveTo(&sim, &estimator, 4.01);
+  ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 4.99);
+  ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 3.99);
+  ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 3.01);
+  ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 13.55);
+  ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
+}
+
+TEST_F(PotAndIndexZeroingTest, TestDifferentIndexDiffs) {
+  double index_diff = 0.89;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.5 * index_diff, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  // The zeroing code is supposed to perform some filtering on the difference
+  // between the potentiometer value and the encoder value. We assume that 300
+  // samples are sufficient to have updated the filter.
+  for (int i = 0; i < 300; i++) {
+    MoveTo(&sim, &estimator, 3.5 * index_diff);
+  }
+  ASSERT_NEAR(3.5 * index_diff, GetEstimatorPosition(&estimator),
+              kAcceptableUnzeroedError * index_diff);
+
+  // With a single index pulse the zeroing estimator should be able to lock
+  // onto the true value of the position.
+  MoveTo(&sim, &estimator, 4.01);
+  ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 4.99);
+  ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 3.99);
+  ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 3.01);
+  ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
+
+  MoveTo(&sim, &estimator, 13.55);
+  ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
+}
+
+TEST_F(PotAndIndexZeroingTest, TestPercentage) {
+  double index_diff = 0.89;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.5 * index_diff, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  for (unsigned int i = 0; i < kSampleSize / 2; i++) {
+    MoveTo(&sim, &estimator, 3.5 * index_diff);
+  }
+  ASSERT_NEAR(0.5, estimator.offset_ratio_ready(), 0.001);
+  ASSERT_FALSE(estimator.offset_ready());
+
+  for (unsigned int i = 0; i < kSampleSize / 2; i++) {
+    MoveTo(&sim, &estimator, 3.5 * index_diff);
+  }
+  ASSERT_NEAR(1.0, estimator.offset_ratio_ready(), 0.001);
+  ASSERT_TRUE(estimator.offset_ready());
+}
+
+TEST_F(PotAndIndexZeroingTest, TestOffset) {
+  double index_diff = 0.89;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.1 * index_diff, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  MoveTo(&sim, &estimator, 3.1 * index_diff);
+
+  for (unsigned int i = 0; i < kSampleSize; i++) {
+    MoveTo(&sim, &estimator, 5.0 * index_diff);
+  }
+
+  ASSERT_NEAR(3.1 * index_diff, estimator.offset(), 0.001);
+}
+
+TEST_F(PotAndIndexZeroingTest, WaitForIndexPulseAfterReset) {
+  double index_diff = 0.6;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.1 * index_diff, index_diff / 3.0);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+
+  // Make sure to fill up the averaging filter with samples.
+  for (unsigned int i = 0; i < kSampleSize; i++) {
+    MoveTo(&sim, &estimator, 3.1 * index_diff);
+  }
+
+  // Make sure we're not zeroed until we hit an index pulse.
+  ASSERT_FALSE(estimator.zeroed());
+
+  // Trigger an index pulse; we should now be zeroed.
+  MoveTo(&sim, &estimator, 4.5 * index_diff);
+  ASSERT_TRUE(estimator.zeroed());
+
+  // Reset the zeroing logic and supply a bunch of samples within the current
+  // index segment.
+  estimator.Reset();
+  for (unsigned int i = 0; i < kSampleSize; i++) {
+    MoveTo(&sim, &estimator, 4.2 * index_diff);
+  }
+
+  // Make sure we're not zeroed until we hit an index pulse.
+  ASSERT_FALSE(estimator.zeroed());
+
+  // Trigger another index pulse; we should be zeroed again.
+  MoveTo(&sim, &estimator, 3.1 * index_diff);
+  ASSERT_TRUE(estimator.zeroed());
+}
+
+TEST_F(PotAndIndexZeroingTest, TestNonZeroIndexPulseOffsets) {
+  const double index_diff = 0.9;
+  const double known_index_pos = 3.5 * index_diff;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(3.3 * index_diff, index_diff / 3.0, known_index_pos);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, known_index_pos, kIndexErrorFraction});
+
+  // Make sure to fill up the averaging filter with samples.
+  for (unsigned int i = 0; i < kSampleSize; i++) {
+    MoveTo(&sim, &estimator, 3.3 * index_diff);
+  }
+
+  // Make sure we're not zeroed until we hit an index pulse.
+  ASSERT_FALSE(estimator.zeroed());
+
+  // Trigger an index pulse; we should now be zeroed.
+  MoveTo(&sim, &estimator, 3.7 * index_diff);
+  ASSERT_TRUE(estimator.zeroed());
+  ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
+  ASSERT_DOUBLE_EQ(3.7 * index_diff, GetEstimatorPosition(&estimator));
+
+  // Trigger one more index pulse and check the offset.
+  MoveTo(&sim, &estimator, 4.7 * index_diff);
+  ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
+  ASSERT_DOUBLE_EQ(4.7 * index_diff, GetEstimatorPosition(&estimator));
+}
+
+TEST_F(PotAndIndexZeroingTest, BasicErrorAPITest) {
+  const double index_diff = 1.0;
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(1.5 * index_diff, index_diff / 3.0, 0.0);
+
+  // Perform a simple move and make sure that no error occured.
+  MoveTo(&sim, &estimator, 3.5 * index_diff);
+  ASSERT_FALSE(estimator.error());
+
+  // Trigger an error and make sure it's reported.
+  estimator.TriggerError();
+  ASSERT_TRUE(estimator.error());
+
+  // Make sure that it can recover after a reset.
+  estimator.Reset();
+  ASSERT_FALSE(estimator.error());
+  MoveTo(&sim, &estimator, 4.5 * index_diff);
+  MoveTo(&sim, &estimator, 5.5 * index_diff);
+  ASSERT_FALSE(estimator.error());
+}
+
+// Tests that an error is detected when the starting position changes too much.
+TEST_F(PotAndIndexZeroingTest, TestIndexOffsetError) {
+  const double index_diff = 0.8;
+  const double known_index_pos = 2 * index_diff;
+  const size_t sample_size = 30;
+  PositionSensorSimulator sim(index_diff);
+  sim.Initialize(10 * index_diff, index_diff / 3.0, known_index_pos);
+  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
+      sample_size, index_diff, known_index_pos, kIndexErrorFraction});
+
+  for (size_t i = 0; i < sample_size; i++) {
+    MoveTo(&sim, &estimator, 13 * index_diff);
+  }
+  MoveTo(&sim, &estimator, 8 * index_diff);
+
+  ASSERT_TRUE(estimator.zeroed());
+  ASSERT_FALSE(estimator.error());
+  sim.Initialize(9.0 * index_diff + 0.31 * index_diff, index_diff / 3.0,
+                 known_index_pos);
+  MoveTo(&sim, &estimator, 9 * index_diff);
+  ASSERT_TRUE(estimator.zeroed());
+  ASSERT_TRUE(estimator.error());
+}
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pulse_index.cc b/frc971/zeroing/pulse_index.cc
new file mode 100644
index 0000000..c0831e8
--- /dev/null
+++ b/frc971/zeroing/pulse_index.cc
@@ -0,0 +1,116 @@
+#include "frc971/zeroing/pulse_index.h"
+
+#include <cmath>
+#include <limits>
+
+#include "glog/logging.h"
+
+namespace frc971 {
+namespace zeroing {
+
+void PulseIndexZeroingEstimator::Reset() {
+  max_index_position_ = ::std::numeric_limits<double>::lowest();
+  min_index_position_ = ::std::numeric_limits<double>::max();
+  offset_ = 0;
+  last_used_index_pulse_count_ = 0;
+  zeroed_ = false;
+  error_ = false;
+}
+
+void PulseIndexZeroingEstimator::StoreIndexPulseMaxAndMin(
+    const IndexPosition &info) {
+  // If we have a new index pulse.
+  if (last_used_index_pulse_count_ != info.index_pulses()) {
+    // If the latest pulses's position is outside the range we've currently
+    // seen, record it appropriately.
+    if (info.latched_encoder() > max_index_position_) {
+      max_index_position_ = info.latched_encoder();
+    }
+    if (info.latched_encoder() < min_index_position_) {
+      min_index_position_ = info.latched_encoder();
+    }
+    last_used_index_pulse_count_ = info.index_pulses();
+  }
+}
+
+int PulseIndexZeroingEstimator::IndexPulseCount() const {
+  if (min_index_position_ > max_index_position_) {
+    // This condition means we haven't seen a pulse yet.
+    return 0;
+  }
+
+  // Calculate the number of pulses encountered so far.
+  return 1 + static_cast<int>(
+                 ::std::round((max_index_position_ - min_index_position_) /
+                              constants_.index_difference));
+}
+
+void PulseIndexZeroingEstimator::UpdateEstimate(const IndexPosition &info) {
+  StoreIndexPulseMaxAndMin(info);
+  const int index_pulse_count = IndexPulseCount();
+  if (index_pulse_count > constants_.index_pulse_count) {
+    if (!error_) {
+      VLOG(1) << "Got more index pulses than expected. Got "
+              << index_pulse_count << " expected "
+              << constants_.index_pulse_count;
+      error_ = true;
+    }
+  }
+
+  // TODO(austin): Detect if the encoder or index pulse is unplugged.
+  // TODO(austin): Detect missing counts.
+
+  if (index_pulse_count == constants_.index_pulse_count && !zeroed_) {
+    offset_ = constants_.measured_index_position -
+              constants_.known_index_pulse * constants_.index_difference -
+              min_index_position_;
+    zeroed_ = true;
+  } else if (zeroed_ && !error_) {
+    // Detect whether the index pulse is somewhere other than where we expect
+    // it to be. First we compute the position of the most recent index pulse.
+    double index_pulse_distance =
+        info.latched_encoder() + offset_ - constants_.measured_index_position;
+    // Second we compute the position of the index pulse in terms of
+    // the index difference. I.e. if this index pulse is two pulses away from
+    // the index pulse that we know about then this number should be positive
+    // or negative two.
+    double relative_distance =
+        index_pulse_distance / constants_.index_difference;
+    // Now we compute how far away the measured index pulse is from the
+    // expected index pulse.
+    double error = relative_distance - ::std::round(relative_distance);
+    // This lets us check if the index pulse is within an acceptable error
+    // margin of where we expected it to be.
+    if (::std::abs(error) > constants_.allowable_encoder_error) {
+      VLOG(1)
+          << "Encoder ticks out of range since last index pulse. known index "
+             "pulse: "
+          << constants_.measured_index_position << ", expected index pulse: "
+          << round(relative_distance) * constants_.index_difference +
+                 constants_.measured_index_position
+          << ", actual index pulse: " << info.latched_encoder() + offset_
+          << ", "
+             "allowable error: "
+          << constants_.allowable_encoder_error * constants_.index_difference;
+      error_ = true;
+    }
+  }
+
+  position_ = info.encoder() + offset_;
+}
+
+flatbuffers::Offset<PulseIndexZeroingEstimator::State>
+PulseIndexZeroingEstimator::GetEstimatorState(
+    flatbuffers::FlatBufferBuilder *fbb) const {
+  State::Builder builder(*fbb);
+  builder.add_error(error_);
+  builder.add_zeroed(zeroed_);
+  builder.add_position(position_);
+  builder.add_min_index_position(min_index_position_);
+  builder.add_max_index_position(max_index_position_);
+  builder.add_index_pulses_seen(IndexPulseCount());
+  return builder.Finish();
+}
+
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/pulse_index.h b/frc971/zeroing/pulse_index.h
new file mode 100644
index 0000000..4bcf210
--- /dev/null
+++ b/frc971/zeroing/pulse_index.h
@@ -0,0 +1,84 @@
+#ifndef FRC971_ZEROING_PULSE_INDEX_H_
+#define FRC971_ZEROING_PULSE_INDEX_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "frc971/zeroing/zeroing.h"
+
+namespace frc971 {
+namespace zeroing {
+
+// Zeros by seeing all the index pulses in the range of motion of the mechanism
+// and using that to figure out which index pulse is which.
+class PulseIndexZeroingEstimator
+    : public ZeroingEstimator<IndexPosition,
+                              constants::EncoderPlusIndexZeroingConstants,
+                              IndexEstimatorState> {
+ public:
+  explicit PulseIndexZeroingEstimator(const ZeroingConstants &constants)
+      : constants_(constants) {
+    Reset();
+  }
+
+  // Resets the internal logic so it needs to be re-zeroed.
+  void Reset() override;
+
+  bool zeroed() const override { return zeroed_; }
+
+  // It's as ready as it'll ever be...
+  bool offset_ready() const override { return true; }
+
+  double offset() const override { return offset_; }
+
+  bool error() const override { return error_; }
+
+  // Updates the internal logic with the next sensor values.
+  void UpdateEstimate(const IndexPosition &info) override;
+
+  // Returns information about our current state.
+  virtual flatbuffers::Offset<State> GetEstimatorState(
+      flatbuffers::FlatBufferBuilder *fbb) const override;
+
+  void TriggerError() override { error_ = true; }
+
+ private:
+  // Returns the current real position using the relative encoder offset.
+  double CalculateCurrentPosition(const IndexPosition &info);
+
+  // Sets the minimum and maximum index pulse position values.
+  void StoreIndexPulseMaxAndMin(const IndexPosition &info);
+
+  // Returns the number of index pulses we should have seen so far.
+  int IndexPulseCount() const;
+
+  // Contains the physical constants describing the system.
+  const ZeroingConstants constants_;
+
+  // The smallest position of all the index pulses.
+  double min_index_position_;
+  // The largest position of all the index pulses.
+  double max_index_position_;
+
+  // The estimated starting position of the mechanism.
+  double offset_;
+  // After a reset we keep track of the index pulse count with this. Only after
+  // the index pulse count changes (i.e. increments at least once or wraps
+  // around) will we consider the mechanism zeroed. We also use this to store
+  // the most recent `PotAndIndexPosition::index_pulses' value when the start
+  // position was calculated. It helps us calculate the start position only on
+  // index pulses to reject corrupted intermediate data.
+  uint32_t last_used_index_pulse_count_;
+
+  // True if we are fully zeroed.
+  bool zeroed_;
+  // Marker to track whether an error has occurred.
+  bool error_;
+
+  // The estimated position.
+  double position_;
+};
+
+}  // namespace zeroing
+}  // namespace frc971
+
+#endif  // FRC971_ZEROING_PULSE_INDEX_H_
diff --git a/frc971/zeroing/pulse_index_test.cc b/frc971/zeroing/pulse_index_test.cc
new file mode 100644
index 0000000..bd257f7
--- /dev/null
+++ b/frc971/zeroing/pulse_index_test.cc
@@ -0,0 +1,132 @@
+#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
diff --git a/frc971/zeroing/relative_encoder_test.cc b/frc971/zeroing/relative_encoder_test.cc
new file mode 100644
index 0000000..fd86fb3
--- /dev/null
+++ b/frc971/zeroing/relative_encoder_test.cc
@@ -0,0 +1,40 @@
+#include "frc971/zeroing/zeroing.h"
+
+#include "gtest/gtest.h"
+
+#include "frc971/zeroing/zeroing_test.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+class RelativeEncoderZeroingTest : public ZeroingTest {
+ protected:
+  void MoveTo(PositionSensorSimulator *simulator,
+              RelativeEncoderZeroingEstimator *estimator, double new_position) {
+    simulator->MoveTo(new_position);
+    FBB fbb;
+    estimator->UpdateEstimate(
+        *simulator->FillSensorValues<RelativePosition>(&fbb));
+  }
+};
+
+TEST_F(RelativeEncoderZeroingTest, TestRelativeEncoderZeroingWithoutMovement) {
+  PositionSensorSimulator sim(1.0);
+  RelativeEncoderZeroingEstimator estimator;
+
+  sim.InitializeRelativeEncoder();
+
+  ASSERT_TRUE(estimator.zeroed());
+  ASSERT_TRUE(estimator.offset_ready());
+  EXPECT_DOUBLE_EQ(estimator.offset(), 0.0);
+  EXPECT_DOUBLE_EQ(GetEstimatorPosition(&estimator), 0.0);
+
+  MoveTo(&sim, &estimator, 0.1);
+
+  EXPECT_DOUBLE_EQ(GetEstimatorPosition(&estimator), 0.1);
+}
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
diff --git a/frc971/zeroing/zeroing.cc b/frc971/zeroing/zeroing.cc
deleted file mode 100644
index f0aab23..0000000
--- a/frc971/zeroing/zeroing.cc
+++ /dev/null
@@ -1,706 +0,0 @@
-#include "frc971/zeroing/zeroing.h"
-
-#include <algorithm>
-#include <cmath>
-#include <limits>
-#include <numeric>
-#include <vector>
-
-#include "frc971/zeroing/wrap.h"
-
-#include "flatbuffers/flatbuffers.h"
-#include "glog/logging.h"
-
-namespace frc971 {
-namespace zeroing {
-
-PotAndIndexPulseZeroingEstimator::PotAndIndexPulseZeroingEstimator(
-    const constants::PotAndIndexPulseZeroingConstants &constants)
-    : constants_(constants) {
-  start_pos_samples_.reserve(constants_.average_filter_size);
-  Reset();
-}
-
-void PotAndIndexPulseZeroingEstimator::Reset() {
-  samples_idx_ = 0;
-  offset_ = 0;
-  start_pos_samples_.clear();
-  zeroed_ = false;
-  wait_for_index_pulse_ = true;
-  last_used_index_pulse_count_ = 0;
-  error_ = false;
-}
-
-void PotAndIndexPulseZeroingEstimator::TriggerError() {
-  if (!error_) {
-    VLOG(1) << "Manually triggered zeroing error.";
-    error_ = true;
-  }
-}
-
-double PotAndIndexPulseZeroingEstimator::CalculateStartPosition(
-    double start_average, double latched_encoder) const {
-  // We calculate an aproximation of the value of the last index position.
-  // Also account for index pulses not lining up with integer multiples of the
-  // index_diff.
-  double index_pos =
-      start_average + latched_encoder - constants_.measured_index_position;
-  // We round index_pos to the closest valid value of the index.
-  double accurate_index_pos = (round(index_pos / constants_.index_difference)) *
-                              constants_.index_difference;
-  // Now we reverse the first calculation to get the accurate start position.
-  return accurate_index_pos - latched_encoder +
-         constants_.measured_index_position;
-}
-
-void PotAndIndexPulseZeroingEstimator::UpdateEstimate(
-    const PotAndIndexPosition &info) {
-  // We want to make sure that we encounter at least one index pulse while
-  // zeroing. So we take the index pulse count from the first sample after
-  // reset and wait for that count to change before we consider ourselves
-  // zeroed.
-  if (wait_for_index_pulse_) {
-    last_used_index_pulse_count_ = info.index_pulses();
-    wait_for_index_pulse_ = false;
-  }
-
-  if (start_pos_samples_.size() < constants_.average_filter_size) {
-    start_pos_samples_.push_back(info.pot() - info.encoder());
-  } else {
-    start_pos_samples_[samples_idx_] = info.pot() - info.encoder();
-  }
-
-  // Drop the oldest sample when we run this function the next time around.
-  samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
-
-  double sample_sum = 0.0;
-
-  for (size_t i = 0; i < start_pos_samples_.size(); ++i) {
-    sample_sum += start_pos_samples_[i];
-  }
-
-  // Calculates the average of the starting position.
-  double start_average = sample_sum / start_pos_samples_.size();
-
-  // If there are no index pulses to use or we don't have enough samples yet to
-  // have a well-filtered starting position then we use the filtered value as
-  // our best guess.
-  if (!zeroed_ &&
-      (info.index_pulses() == last_used_index_pulse_count_ || !offset_ready())) {
-    offset_ = start_average;
-  } else if (!zeroed_ || last_used_index_pulse_count_ != info.index_pulses()) {
-    // Note the accurate start position and the current index pulse count so
-    // that we only run this logic once per index pulse. That should be more
-    // resilient to corrupted intermediate data.
-    offset_ = CalculateStartPosition(start_average, info.latched_encoder());
-    last_used_index_pulse_count_ = info.index_pulses();
-
-    // TODO(austin): Reject encoder positions which have x% error rather than
-    // rounding to the closest index pulse.
-
-    // Save the first starting position.
-    if (!zeroed_) {
-      first_start_pos_ = offset_;
-      VLOG(2) << "latching start position" << first_start_pos_;
-    }
-
-    // Now that we have an accurate starting position we can consider ourselves
-    // zeroed.
-    zeroed_ = true;
-    // Throw an error if first_start_pos is bigger/smaller than
-    // constants_.allowable_encoder_error * index_diff + start_pos.
-    if (::std::abs(first_start_pos_ - offset_) >
-        constants_.allowable_encoder_error * constants_.index_difference) {
-      if (!error_) {
-        VLOG(1)
-            << "Encoder ticks out of range since last index pulse. first start "
-               "position: "
-            << first_start_pos_ << " recent starting position: " << offset_
-            << ", allowable error: "
-            << constants_.allowable_encoder_error * constants_.index_difference;
-        error_ = true;
-      }
-    }
-  }
-
-  position_ = offset_ + info.encoder();
-  filtered_position_ = start_average + info.encoder();
-}
-
-flatbuffers::Offset<PotAndIndexPulseZeroingEstimator::State>
-PotAndIndexPulseZeroingEstimator::GetEstimatorState(
-    flatbuffers::FlatBufferBuilder *fbb) const {
-  State::Builder builder(*fbb);
-  builder.add_error(error_);
-  builder.add_zeroed(zeroed_);
-  builder.add_position(position_);
-  builder.add_pot_position(filtered_position_);
-  return builder.Finish();
-}
-
-HallEffectAndPositionZeroingEstimator::HallEffectAndPositionZeroingEstimator(
-    const ZeroingConstants &constants)
-    : constants_(constants) {
-  Reset();
-}
-
-void HallEffectAndPositionZeroingEstimator::Reset() {
-  offset_ = 0.0;
-  min_low_position_ = ::std::numeric_limits<double>::max();
-  max_low_position_ = ::std::numeric_limits<double>::lowest();
-  zeroed_ = false;
-  initialized_ = false;
-  last_used_posedge_count_ = 0;
-  cycles_high_ = 0;
-  high_long_enough_ = false;
-  first_start_pos_ = 0.0;
-  error_ = false;
-  current_ = 0.0;
-  first_start_pos_ = 0.0;
-}
-
-void HallEffectAndPositionZeroingEstimator::TriggerError() {
-  if (!error_) {
-    VLOG(1) << "Manually triggered zeroing error.\n";
-    error_ = true;
-  }
-}
-
-void HallEffectAndPositionZeroingEstimator::StoreEncoderMaxAndMin(
-    const HallEffectAndPosition &info) {
-  // If we have a new posedge.
-  if (!info.current()) {
-    if (last_hall_) {
-      min_low_position_ = max_low_position_ = info.encoder();
-    } else {
-      min_low_position_ = ::std::min(min_low_position_, info.encoder());
-      max_low_position_ = ::std::max(max_low_position_, info.encoder());
-    }
-  }
-  last_hall_ = info.current();
-}
-
-void HallEffectAndPositionZeroingEstimator::UpdateEstimate(
-    const HallEffectAndPosition &info) {
-  // We want to make sure that we encounter at least one posedge while zeroing.
-  // So we take the posedge count from the first sample after reset and wait for
-  // that count to change and for the hall effect to stay high before we
-  // consider ourselves zeroed.
-  if (!initialized_) {
-    last_used_posedge_count_ = info.posedge_count();
-    initialized_ = true;
-    last_hall_ = info.current();
-  }
-
-  StoreEncoderMaxAndMin(info);
-
-  if (info.current()) {
-    cycles_high_++;
-  } else {
-    cycles_high_ = 0;
-    last_used_posedge_count_ = info.posedge_count();
-  }
-
-  high_long_enough_ = cycles_high_ >= constants_.hall_trigger_zeroing_length;
-
-  bool moving_backward = false;
-  if (constants_.zeroing_move_direction) {
-    moving_backward = info.encoder() > min_low_position_;
-  } else {
-    moving_backward = info.encoder() < max_low_position_;
-  }
-
-  // If there are no posedges to use or we don't have enough samples yet to
-  // have a well-filtered starting position then we use the filtered value as
-  // our best guess.
-  if (last_used_posedge_count_ != info.posedge_count() && high_long_enough_ &&
-      moving_backward) {
-    // Note the offset and the current posedge count so that we only run this
-    // logic once per posedge. That should be more resilient to corrupted
-    // intermediate data.
-    offset_ = -info.posedge_value();
-    if (constants_.zeroing_move_direction) {
-      offset_ += constants_.lower_hall_position;
-    } else {
-      offset_ += constants_.upper_hall_position;
-    }
-    last_used_posedge_count_ = info.posedge_count();
-
-    // Save the first starting position.
-    if (!zeroed_) {
-      first_start_pos_ = offset_;
-      VLOG(2) << "latching start position" << first_start_pos_;
-    }
-
-    // Now that we have an accurate starting position we can consider ourselves
-    // zeroed.
-    zeroed_ = true;
-  }
-
-  position_ = info.encoder() - offset_;
-}
-
-flatbuffers::Offset<HallEffectAndPositionZeroingEstimator::State>
-HallEffectAndPositionZeroingEstimator::GetEstimatorState(
-    flatbuffers::FlatBufferBuilder *fbb) const {
-  State::Builder builder(*fbb);
-  builder.add_error(error_);
-  builder.add_zeroed(zeroed_);
-  builder.add_encoder(position_);
-  builder.add_high_long_enough(high_long_enough_);
-  builder.add_offset(offset_);
-  return builder.Finish();
-}
-
-PotAndAbsoluteEncoderZeroingEstimator::PotAndAbsoluteEncoderZeroingEstimator(
-    const constants::PotAndAbsoluteEncoderZeroingConstants &constants)
-    : constants_(constants), move_detector_(constants_.moving_buffer_size) {
-  relative_to_absolute_offset_samples_.reserve(constants_.average_filter_size);
-  offset_samples_.reserve(constants_.average_filter_size);
-  Reset();
-}
-
-void PotAndAbsoluteEncoderZeroingEstimator::Reset() {
-  first_offset_ = 0.0;
-  pot_relative_encoder_offset_ = 0.0;
-  offset_ = 0.0;
-  samples_idx_ = 0;
-  filtered_position_ = 0.0;
-  position_ = 0.0;
-  zeroed_ = false;
-  nan_samples_ = 0;
-  relative_to_absolute_offset_samples_.clear();
-  offset_samples_.clear();
-  move_detector_.Reset();
-  error_ = false;
-}
-
-// So, this needs to be a multistep process.  We need to first estimate the
-// offset between the absolute encoder and the relative encoder.  That process
-// should get us an absolute number which is off by integer multiples of the
-// distance/rev.  In parallel, we can estimate the offset between the pot and
-// encoder.  When both estimates have converged, we can then compute the offset
-// in a cycle, and which cycle, which gives us the accurate global offset.
-//
-// It's tricky to compute the offset between the absolute and relative encoder.
-// We need to compute this inside 1 revolution.  The easiest way to do this
-// would be to wrap the encoder, subtract the two of them, and then average the
-// result.  That will struggle when they are off by PI.  Instead, we need to
-// wrap the number to +- PI from the current averaged offset.
-//
-// To guard against the robot moving while updating estimates, buffer a number
-// of samples and check that the buffered samples are not different than the
-// zeroing threshold. At any point that the samples differ too much, do not
-// update estimates based on those samples.
-void PotAndAbsoluteEncoderZeroingEstimator::UpdateEstimate(
-    const PotAndAbsolutePosition &info) {
-  // Check for Abs Encoder NaN value that would mess up the rest of the zeroing
-  // code below. NaN values are given when the Absolute Encoder is disconnected.
-  if (::std::isnan(info.absolute_encoder())) {
-    if (zeroed_) {
-      VLOG(1) << "NAN on absolute encoder.";
-      error_ = true;
-    } else {
-      ++nan_samples_;
-      VLOG(1) << "NAN on absolute encoder while zeroing" << nan_samples_;
-      if (nan_samples_ >= constants_.average_filter_size) {
-        error_ = true;
-        zeroed_ = true;
-      }
-    }
-    // Throw some dummy values in for now.
-    filtered_absolute_encoder_ = info.absolute_encoder();
-    filtered_position_ = pot_relative_encoder_offset_ + info.encoder();
-    position_ = offset_ + info.encoder();
-    return;
-  }
-
-  const bool moving = move_detector_.Update(info, constants_.moving_buffer_size,
-                                            constants_.zeroing_threshold);
-
-  if (!moving) {
-    const PositionStruct &sample = move_detector_.GetSample();
-
-    // Compute the average offset between the absolute encoder and relative
-    // encoder.  If we have 0 samples, assume it is 0.
-    double average_relative_to_absolute_offset =
-        relative_to_absolute_offset_samples_.size() == 0
-            ? 0.0
-            : ::std::accumulate(relative_to_absolute_offset_samples_.begin(),
-                                relative_to_absolute_offset_samples_.end(),
-                                0.0) /
-                  relative_to_absolute_offset_samples_.size();
-
-    const double adjusted_incremental_encoder =
-        sample.encoder + average_relative_to_absolute_offset;
-
-    // Now, compute the nearest absolute encoder value to the offset relative
-    // encoder position.
-    const double adjusted_absolute_encoder =
-        UnWrap(adjusted_incremental_encoder,
-               sample.absolute_encoder - constants_.measured_absolute_position,
-               constants_.one_revolution_distance);
-
-    // We can now compute the offset now that we have unwrapped the absolute
-    // encoder.
-    const double relative_to_absolute_offset =
-        adjusted_absolute_encoder - sample.encoder;
-
-    // Add the sample and update the average with the new reading.
-    const size_t relative_to_absolute_offset_samples_size =
-        relative_to_absolute_offset_samples_.size();
-    if (relative_to_absolute_offset_samples_size <
-        constants_.average_filter_size) {
-      average_relative_to_absolute_offset =
-          (average_relative_to_absolute_offset *
-               relative_to_absolute_offset_samples_size +
-           relative_to_absolute_offset) /
-          (relative_to_absolute_offset_samples_size + 1);
-
-      relative_to_absolute_offset_samples_.push_back(
-          relative_to_absolute_offset);
-    } else {
-      average_relative_to_absolute_offset -=
-          relative_to_absolute_offset_samples_[samples_idx_] /
-          relative_to_absolute_offset_samples_size;
-      relative_to_absolute_offset_samples_[samples_idx_] =
-          relative_to_absolute_offset;
-      average_relative_to_absolute_offset +=
-          relative_to_absolute_offset /
-          relative_to_absolute_offset_samples_size;
-    }
-
-    // Now compute the offset between the pot and relative encoder.
-    if (offset_samples_.size() < constants_.average_filter_size) {
-      offset_samples_.push_back(sample.pot - sample.encoder);
-    } else {
-      offset_samples_[samples_idx_] = sample.pot - sample.encoder;
-    }
-
-    // Drop the oldest sample when we run this function the next time around.
-    samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
-
-    pot_relative_encoder_offset_ =
-        ::std::accumulate(offset_samples_.begin(), offset_samples_.end(), 0.0) /
-        offset_samples_.size();
-
-    offset_ = UnWrap(sample.encoder + pot_relative_encoder_offset_,
-                     average_relative_to_absolute_offset + sample.encoder,
-                     constants_.one_revolution_distance) -
-              sample.encoder;
-
-    // Reverse the math for adjusted_absolute_encoder to compute the absolute
-    // encoder. Do this by taking the adjusted encoder, and then subtracting off
-    // the second argument above, and the value that was added by Wrap.
-    filtered_absolute_encoder_ =
-        ((sample.encoder + average_relative_to_absolute_offset) -
-         (-constants_.measured_absolute_position +
-          (adjusted_absolute_encoder -
-           (sample.absolute_encoder - constants_.measured_absolute_position))));
-
-    if (offset_ready()) {
-      if (!zeroed_) {
-        first_offset_ = offset_;
-      }
-
-      if (::std::abs(first_offset_ - offset_) >
-          constants_.allowable_encoder_error *
-              constants_.one_revolution_distance) {
-        VLOG(1) << "Offset moved too far. Initial: " << first_offset_
-                << ", current " << offset_ << ", allowable change: "
-                << constants_.allowable_encoder_error *
-                       constants_.one_revolution_distance;
-        error_ = true;
-      }
-
-      zeroed_ = true;
-    }
-  }
-
-  // Update the position.
-  filtered_position_ = pot_relative_encoder_offset_ + info.encoder();
-  position_ = offset_ + info.encoder();
-}
-
-flatbuffers::Offset<PotAndAbsoluteEncoderZeroingEstimator::State>
-PotAndAbsoluteEncoderZeroingEstimator::GetEstimatorState(
-    flatbuffers::FlatBufferBuilder *fbb) const {
-  State::Builder builder(*fbb);
-  builder.add_error(error_);
-  builder.add_zeroed(zeroed_);
-  builder.add_position(position_);
-  builder.add_pot_position(filtered_position_);
-  builder.add_absolute_position(filtered_absolute_encoder_);
-  return builder.Finish();
-}
-
-void PulseIndexZeroingEstimator::Reset() {
-  max_index_position_ = ::std::numeric_limits<double>::lowest();
-  min_index_position_ = ::std::numeric_limits<double>::max();
-  offset_ = 0;
-  last_used_index_pulse_count_ = 0;
-  zeroed_ = false;
-  error_ = false;
-}
-
-void PulseIndexZeroingEstimator::StoreIndexPulseMaxAndMin(
-    const IndexPosition &info) {
-  // If we have a new index pulse.
-  if (last_used_index_pulse_count_ != info.index_pulses()) {
-    // If the latest pulses's position is outside the range we've currently
-    // seen, record it appropriately.
-    if (info.latched_encoder() > max_index_position_) {
-      max_index_position_ = info.latched_encoder();
-    }
-    if (info.latched_encoder() < min_index_position_) {
-      min_index_position_ = info.latched_encoder();
-    }
-    last_used_index_pulse_count_ = info.index_pulses();
-  }
-}
-
-int PulseIndexZeroingEstimator::IndexPulseCount() const {
-  if (min_index_position_ > max_index_position_) {
-    // This condition means we haven't seen a pulse yet.
-    return 0;
-  }
-
-  // Calculate the number of pulses encountered so far.
-  return 1 + static_cast<int>(
-                 ::std::round((max_index_position_ - min_index_position_) /
-                              constants_.index_difference));
-}
-
-void PulseIndexZeroingEstimator::UpdateEstimate(const IndexPosition &info) {
-  StoreIndexPulseMaxAndMin(info);
-  const int index_pulse_count = IndexPulseCount();
-  if (index_pulse_count > constants_.index_pulse_count) {
-    if (!error_) {
-      VLOG(1) << "Got more index pulses than expected. Got "
-              << index_pulse_count << " expected "
-              << constants_.index_pulse_count;
-      error_ = true;
-    }
-  }
-
-  // TODO(austin): Detect if the encoder or index pulse is unplugged.
-  // TODO(austin): Detect missing counts.
-
-  if (index_pulse_count == constants_.index_pulse_count && !zeroed_) {
-    offset_ = constants_.measured_index_position -
-              constants_.known_index_pulse * constants_.index_difference -
-              min_index_position_;
-    zeroed_ = true;
-  } else if (zeroed_ && !error_) {
-    // Detect whether the index pulse is somewhere other than where we expect
-    // it to be. First we compute the position of the most recent index pulse.
-    double index_pulse_distance =
-        info.latched_encoder() + offset_ - constants_.measured_index_position;
-    // Second we compute the position of the index pulse in terms of
-    // the index difference. I.e. if this index pulse is two pulses away from
-    // the index pulse that we know about then this number should be positive
-    // or negative two.
-    double relative_distance =
-        index_pulse_distance / constants_.index_difference;
-    // Now we compute how far away the measured index pulse is from the
-    // expected index pulse.
-    double error = relative_distance - ::std::round(relative_distance);
-    // This lets us check if the index pulse is within an acceptable error
-    // margin of where we expected it to be.
-    if (::std::abs(error) > constants_.allowable_encoder_error) {
-      VLOG(1)
-          << "Encoder ticks out of range since last index pulse. known index "
-             "pulse: "
-          << constants_.measured_index_position << ", expected index pulse: "
-          << round(relative_distance) * constants_.index_difference +
-                 constants_.measured_index_position
-          << ", actual index pulse: " << info.latched_encoder() + offset_
-          << ", "
-             "allowable error: "
-          << constants_.allowable_encoder_error * constants_.index_difference;
-      error_ = true;
-    }
-  }
-
-  position_ = info.encoder() + offset_;
-}
-
-flatbuffers::Offset<PulseIndexZeroingEstimator::State>
-PulseIndexZeroingEstimator::GetEstimatorState(
-    flatbuffers::FlatBufferBuilder *fbb) const {
-  State::Builder builder(*fbb);
-  builder.add_error(error_);
-  builder.add_zeroed(zeroed_);
-  builder.add_position(position_);
-  builder.add_min_index_position(min_index_position_);
-  builder.add_max_index_position(max_index_position_);
-  builder.add_index_pulses_seen(IndexPulseCount());
-  return builder.Finish();
-}
-
-AbsoluteEncoderZeroingEstimator::AbsoluteEncoderZeroingEstimator(
-    const constants::AbsoluteEncoderZeroingConstants &constants)
-    : constants_(constants), move_detector_(constants_.moving_buffer_size) {
-  relative_to_absolute_offset_samples_.reserve(constants_.average_filter_size);
-  Reset();
-}
-
-void AbsoluteEncoderZeroingEstimator::Reset() {
-  zeroed_ = false;
-  error_ = false;
-  first_offset_ = 0.0;
-  offset_ = 0.0;
-  samples_idx_ = 0;
-  position_ = 0.0;
-  nan_samples_ = 0;
-  relative_to_absolute_offset_samples_.clear();
-  move_detector_.Reset();
-}
-
-
-// The math here is a bit backwards, but I think it'll be less error prone that
-// way and more similar to the version with a pot as well.
-//
-// We start by unwrapping the absolute encoder using the relative encoder.  This
-// puts us in a non-wrapping space and lets us average a bit easier.  From
-// there, we can compute an offset and wrap ourselves back such that we stay
-// close to the middle value.
-//
-// To guard against the robot moving while updating estimates, buffer a number
-// of samples and check that the buffered samples are not different than the
-// zeroing threshold. At any point that the samples differ too much, do not
-// update estimates based on those samples.
-void AbsoluteEncoderZeroingEstimator::UpdateEstimate(
-    const AbsolutePosition &info) {
-  // Check for Abs Encoder NaN value that would mess up the rest of the zeroing
-  // code below. NaN values are given when the Absolute Encoder is disconnected.
-  if (::std::isnan(info.absolute_encoder())) {
-    if (zeroed_) {
-      VLOG(1) << "NAN on absolute encoder.";
-      error_ = true;
-    } else {
-      ++nan_samples_;
-      VLOG(1) << "NAN on absolute encoder while zeroing " << nan_samples_;
-      if (nan_samples_ >= constants_.average_filter_size) {
-        error_ = true;
-        zeroed_ = true;
-      }
-    }
-    // Throw some dummy values in for now.
-    filtered_absolute_encoder_ = info.absolute_encoder();
-    position_ = offset_ + info.encoder();
-    return;
-  }
-
-  const bool moving = move_detector_.Update(info, constants_.moving_buffer_size,
-                                            constants_.zeroing_threshold);
-
-  if (!moving) {
-    const PositionStruct &sample = move_detector_.GetSample();
-
-    // Compute the average offset between the absolute encoder and relative
-    // encoder.  If we have 0 samples, assume it is 0.
-    double average_relative_to_absolute_offset =
-        relative_to_absolute_offset_samples_.size() == 0
-            ? 0.0
-            : ::std::accumulate(relative_to_absolute_offset_samples_.begin(),
-                                relative_to_absolute_offset_samples_.end(),
-                                0.0) /
-                  relative_to_absolute_offset_samples_.size();
-
-    // Now, compute the estimated absolute position using the previously
-    // estimated offset and the incremental encoder.
-    const double adjusted_incremental_encoder =
-        sample.encoder + average_relative_to_absolute_offset;
-
-    // Now, compute the absolute encoder value nearest to the offset relative
-    // encoder position.
-    const double adjusted_absolute_encoder =
-        UnWrap(adjusted_incremental_encoder,
-               sample.absolute_encoder - constants_.measured_absolute_position,
-               constants_.one_revolution_distance);
-
-    // We can now compute the offset now that we have unwrapped the absolute
-    // encoder.
-    const double relative_to_absolute_offset =
-        adjusted_absolute_encoder - sample.encoder;
-
-    // Add the sample and update the average with the new reading.
-    const size_t relative_to_absolute_offset_samples_size =
-        relative_to_absolute_offset_samples_.size();
-    if (relative_to_absolute_offset_samples_size <
-        constants_.average_filter_size) {
-      average_relative_to_absolute_offset =
-          (average_relative_to_absolute_offset *
-               relative_to_absolute_offset_samples_size +
-           relative_to_absolute_offset) /
-          (relative_to_absolute_offset_samples_size + 1);
-
-      relative_to_absolute_offset_samples_.push_back(
-          relative_to_absolute_offset);
-    } else {
-      average_relative_to_absolute_offset -=
-          relative_to_absolute_offset_samples_[samples_idx_] /
-          relative_to_absolute_offset_samples_size;
-      relative_to_absolute_offset_samples_[samples_idx_] =
-          relative_to_absolute_offset;
-      average_relative_to_absolute_offset +=
-          relative_to_absolute_offset /
-          relative_to_absolute_offset_samples_size;
-    }
-
-    // Drop the oldest sample when we run this function the next time around.
-    samples_idx_ = (samples_idx_ + 1) % constants_.average_filter_size;
-
-    // And our offset is the offset that gives us the position within +- ord/2
-    // of the middle position.
-    offset_ = Wrap(constants_.middle_position,
-                   average_relative_to_absolute_offset + sample.encoder,
-                   constants_.one_revolution_distance) -
-              sample.encoder;
-
-    // Reverse the math for adjusted_absolute_encoder to compute the absolute
-    // encoder. Do this by taking the adjusted encoder, and then subtracting off
-    // the second argument above, and the value that was added by Wrap.
-    filtered_absolute_encoder_ =
-        ((sample.encoder + average_relative_to_absolute_offset) -
-         (-constants_.measured_absolute_position +
-          (adjusted_absolute_encoder -
-           (sample.absolute_encoder - constants_.measured_absolute_position))));
-
-    if (offset_ready()) {
-      if (!zeroed_) {
-        first_offset_ = offset_;
-      }
-
-      if (::std::abs(first_offset_ - offset_) >
-          constants_.allowable_encoder_error *
-              constants_.one_revolution_distance) {
-        VLOG(1) << "Offset moved too far. Initial: " << first_offset_
-                << ", current " << offset_ << ", allowable change: "
-                << constants_.allowable_encoder_error *
-                       constants_.one_revolution_distance;
-        error_ = true;
-      }
-
-      zeroed_ = true;
-    }
-  }
-
-  // Update the position.
-  position_ = offset_ + info.encoder();
-}
-
-flatbuffers::Offset<AbsoluteEncoderZeroingEstimator::State>
-AbsoluteEncoderZeroingEstimator::GetEstimatorState(
-    flatbuffers::FlatBufferBuilder *fbb) const {
-  State::Builder builder(*fbb);
-  builder.add_error(error_);
-  builder.add_zeroed(zeroed_);
-  builder.add_position(position_);
-  builder.add_absolute_position(filtered_absolute_encoder_);
-  return builder.Finish();
-}
-
-}  // namespace zeroing
-}  // namespace frc971
diff --git a/frc971/zeroing/zeroing.h b/frc971/zeroing/zeroing.h
index fe1b461..4d0c1cc 100644
--- a/frc971/zeroing/zeroing.h
+++ b/frc971/zeroing/zeroing.h
@@ -58,169 +58,6 @@
       flatbuffers::FlatBufferBuilder *fbb) const = 0;
 };
 
-// Estimates the position with an incremental encoder with an index pulse and a
-// potentiometer.
-class PotAndIndexPulseZeroingEstimator
-    : public ZeroingEstimator<PotAndIndexPosition,
-                              constants::PotAndIndexPulseZeroingConstants,
-                              EstimatorState> {
- public:
-  explicit PotAndIndexPulseZeroingEstimator(
-      const constants::PotAndIndexPulseZeroingConstants &constants);
-
-  // Update the internal logic with the next sensor values.
-  void UpdateEstimate(const PotAndIndexPosition &info) override;
-
-  // Reset the internal logic so it needs to be re-zeroed.
-  void Reset() override;
-
-  // Manually trigger an internal error. This is used for testing the error
-  // logic.
-  void TriggerError() override;
-
-  bool error() const override { return error_; }
-
-  bool zeroed() const override { return zeroed_; }
-
-  double offset() const override { return offset_; }
-
-  // Returns a number between 0 and 1 that represents the percentage of the
-  // samples being used in the moving average filter. A value of 0.0 means that
-  // no samples are being used. A value of 1.0 means that the filter is using
-  // as many samples as it has room for. For example, after a Reset() this
-  // value returns 0.0. As more samples get added with UpdateEstimate(...) the
-  // return value starts increasing to 1.0.
-  double offset_ratio_ready() const {
-    return start_pos_samples_.size() /
-           static_cast<double>(constants_.average_filter_size);
-  }
-
-  // Returns true if the sample buffer is full.
-  bool offset_ready() const override {
-    return start_pos_samples_.size() == constants_.average_filter_size;
-  }
-
-  // Returns information about our current state.
-  virtual flatbuffers::Offset<State> GetEstimatorState(
-      flatbuffers::FlatBufferBuilder *fbb) const override;
-
- private:
-  // This function calculates the start position given the internal state and
-  // the provided `latched_encoder' value.
-  double CalculateStartPosition(double start_average,
-                                double latched_encoder) const;
-
-  // The zeroing constants used to describe the configuration of the system.
-  const constants::PotAndIndexPulseZeroingConstants constants_;
-
-  // The estimated position.
-  double position_;
-  // The unzeroed filtered position.
-  double filtered_position_ = 0.0;
-  // The next position in 'start_pos_samples_' to be used to store the next
-  // sample.
-  int samples_idx_;
-  // Last 'max_sample_count_' samples for start positions.
-  std::vector<double> start_pos_samples_;
-  // The estimated starting position of the mechanism. We also call this the
-  // 'offset' in some contexts.
-  double offset_;
-  // Flag for triggering logic that takes note of the current index pulse count
-  // after a reset. See `last_used_index_pulse_count_'.
-  bool wait_for_index_pulse_;
-  // After a reset we keep track of the index pulse count with this. Only after
-  // the index pulse count changes (i.e. increments at least once or wraps
-  // around) will we consider the mechanism zeroed. We also use this to store
-  // the most recent `PotAndIndexPosition::index_pulses' value when the start
-  // position was calculated. It helps us calculate the start position only on
-  // index pulses to reject corrupted intermediate data.
-  uint32_t last_used_index_pulse_count_;
-  // Marker to track whether we're fully zeroed yet or not.
-  bool zeroed_;
-  // Marker to track whether an error has occurred. This gets reset to false
-  // whenever Reset() is called.
-  bool error_;
-  // Stores the position "start_pos" variable the first time the program
-  // is zeroed.
-  double first_start_pos_;
-};
-
-// Estimates the position with an incremental encoder and a hall effect sensor.
-class HallEffectAndPositionZeroingEstimator
-    : public ZeroingEstimator<HallEffectAndPosition,
-                              constants::HallEffectZeroingConstants,
-                              HallEffectAndPositionEstimatorState> {
- public:
-  explicit HallEffectAndPositionZeroingEstimator(
-      const ZeroingConstants &constants);
-
-  // Update the internal logic with the next sensor values.
-  void UpdateEstimate(const Position &info) override;
-
-  // Reset the internal logic so it needs to be re-zeroed.
-  void Reset() override;
-
-  // Manually trigger an internal error. This is used for testing the error
-  // logic.
-  void TriggerError() override;
-
-  bool error() const override { return error_; }
-
-  bool zeroed() const override { return zeroed_; }
-
-  double offset() const override { return offset_; }
-
-  bool offset_ready() const override { return zeroed_; }
-
-  // Returns information about our current state.
-  virtual flatbuffers::Offset<State> GetEstimatorState(
-      flatbuffers::FlatBufferBuilder *fbb) const override;
-
- private:
-  // Sets the minimum and maximum posedge position values.
-  void StoreEncoderMaxAndMin(const HallEffectAndPosition &info);
-
-  // The zeroing constants used to describe the configuration of the system.
-  const ZeroingConstants constants_;
-
-  // The estimated state of the hall effect.
-  double current_ = 0.0;
-  // The estimated position.
-  double position_ = 0.0;
-  // The smallest and largest positions of the last set of encoder positions
-  // while the hall effect was low.
-  double min_low_position_;
-  double max_low_position_;
-  // If we've seen the hall effect high for enough times without going low, then
-  // we can be sure it isn't a false positive.
-  bool high_long_enough_;
-  size_t cycles_high_;
-
-  bool last_hall_ = false;
-
-  // The estimated starting position of the mechanism. We also call this the
-  // 'offset' in some contexts.
-  double offset_;
-  // Flag for triggering logic that takes note of the current posedge count
-  // after a reset. See `last_used_posedge_count_'.
-  bool initialized_;
-  // After a reset we keep track of the posedge count with this. Only after the
-  // posedge count changes (i.e. increments at least once or wraps around) will
-  // we consider the mechanism zeroed. We also use this to store the most recent
-  // `HallEffectAndPosition::posedge_count' value when the start position
-  // was calculated. It helps us calculate the start position only on posedges
-  // to reject corrupted intermediate data.
-  int32_t last_used_posedge_count_;
-  // Marker to track whether we're fully zeroed yet or not.
-  bool zeroed_;
-  // Marker to track whether an error has occurred. This gets reset to false
-  // whenever Reset() is called.
-  bool error_ = false;
-  // Stores the position "start_pos" variable the first time the program
-  // is zeroed.
-  double first_start_pos_;
-};
-
 // Class to encapsulate the logic to decide when we are moving and which samples
 // are safe to use.
 template <typename Position, typename PositionBuffer>
@@ -287,237 +124,7 @@
   size_t buffered_samples_idx_;
 };
 
-// Estimates the position with an absolute encoder which also reports
-// incremental counts, and a potentiometer.
-class PotAndAbsoluteEncoderZeroingEstimator
-    : public ZeroingEstimator<PotAndAbsolutePosition,
-                              constants::PotAndAbsoluteEncoderZeroingConstants,
-                              PotAndAbsoluteEncoderEstimatorState> {
- public:
-  explicit PotAndAbsoluteEncoderZeroingEstimator(
-      const constants::PotAndAbsoluteEncoderZeroingConstants &constants);
-
-  // Resets the internal logic so it needs to be re-zeroed.
-  void Reset() override;
-
-  // Updates the sensor values for the zeroing logic.
-  void UpdateEstimate(const PotAndAbsolutePosition &info) override;
-
-  void TriggerError() override { error_ = true; }
-
-  bool zeroed() const override { return zeroed_; }
-
-  double offset() const override { return offset_; }
-
-  bool error() const override { return error_; }
-
-  // Returns true if the sample buffer is full.
-  bool offset_ready() const override {
-    return relative_to_absolute_offset_samples_.size() ==
-               constants_.average_filter_size &&
-           offset_samples_.size() == constants_.average_filter_size;
-  }
-
-  // Returns information about our current state.
-  virtual flatbuffers::Offset<State> GetEstimatorState(
-      flatbuffers::FlatBufferBuilder *fbb) const override;
-
- private:
-  struct PositionStruct {
-    PositionStruct(const PotAndAbsolutePosition &position_buffer)
-        : absolute_encoder(position_buffer.absolute_encoder()),
-          encoder(position_buffer.encoder()),
-          pot(position_buffer.pot()) {}
-    double absolute_encoder;
-    double encoder;
-    double pot;
-  };
-
-  // The zeroing constants used to describe the configuration of the system.
-  const constants::PotAndAbsoluteEncoderZeroingConstants constants_;
-
-  // True if the mechanism is zeroed.
-  bool zeroed_;
-  // Marker to track whether an error has occurred.
-  bool error_;
-  // The first valid offset we recorded. This is only set after zeroed_ first
-  // changes to true.
-  double first_offset_;
-
-  // The filtered absolute encoder.  This is used in the status for calibration.
-  double filtered_absolute_encoder_ = 0.0;
-
-  // Samples of the offset needed to line the relative encoder up with the
-  // absolute encoder.
-  ::std::vector<double> relative_to_absolute_offset_samples_;
-  // Offset between the Pot and Relative encoder position.
-  ::std::vector<double> offset_samples_;
-
-  MoveDetector<PositionStruct, PotAndAbsolutePosition> move_detector_;
-
-  // Estimated offset between the pot and relative encoder.
-  double pot_relative_encoder_offset_ = 0;
-  // Estimated start position of the mechanism
-  double offset_ = 0;
-  // The next position in 'relative_to_absolute_offset_samples_' and
-  // 'encoder_samples_' to be used to store the next sample.
-  int samples_idx_ = 0;
-
-  size_t nan_samples_ = 0;
-
-  // The unzeroed filtered position.
-  double filtered_position_ = 0.0;
-  // The filtered position.
-  double position_ = 0.0;
-};
-
-// Zeros by seeing all the index pulses in the range of motion of the mechanism
-// and using that to figure out which index pulse is which.
-class PulseIndexZeroingEstimator
-    : public ZeroingEstimator<IndexPosition,
-                              constants::EncoderPlusIndexZeroingConstants,
-                              IndexEstimatorState> {
- public:
-  explicit PulseIndexZeroingEstimator(const ZeroingConstants &constants)
-      : constants_(constants) {
-    Reset();
-  }
-
-  // Resets the internal logic so it needs to be re-zeroed.
-  void Reset() override;
-
-  bool zeroed() const override { return zeroed_; }
-
-  // It's as ready as it'll ever be...
-  bool offset_ready() const override { return true; }
-
-  double offset() const override { return offset_; }
-
-  bool error() const override { return error_; }
-
-  // Updates the internal logic with the next sensor values.
-  void UpdateEstimate(const IndexPosition &info) override;
-
-  // Returns information about our current state.
-  virtual flatbuffers::Offset<State> GetEstimatorState(
-      flatbuffers::FlatBufferBuilder *fbb) const override;
-
-  void TriggerError() override { error_ = true; }
-
- private:
-  // Returns the current real position using the relative encoder offset.
-  double CalculateCurrentPosition(const IndexPosition &info);
-
-  // Sets the minimum and maximum index pulse position values.
-  void StoreIndexPulseMaxAndMin(const IndexPosition &info);
-
-  // Returns the number of index pulses we should have seen so far.
-  int IndexPulseCount() const;
-
-  // Contains the physical constants describing the system.
-  const ZeroingConstants constants_;
-
-  // The smallest position of all the index pulses.
-  double min_index_position_;
-  // The largest position of all the index pulses.
-  double max_index_position_;
-
-  // The estimated starting position of the mechanism.
-  double offset_;
-  // After a reset we keep track of the index pulse count with this. Only after
-  // the index pulse count changes (i.e. increments at least once or wraps
-  // around) will we consider the mechanism zeroed. We also use this to store
-  // the most recent `PotAndIndexPosition::index_pulses' value when the start
-  // position was calculated. It helps us calculate the start position only on
-  // index pulses to reject corrupted intermediate data.
-  uint32_t last_used_index_pulse_count_;
-
-  // True if we are fully zeroed.
-  bool zeroed_;
-  // Marker to track whether an error has occurred.
-  bool error_;
-
-  // The estimated position.
-  double position_;
-};
-
-// Estimates the position with an absolute encoder which also reports
-// incremental counts.  The absolute encoder can't spin more than one
-// revolution.
-class AbsoluteEncoderZeroingEstimator
-    : public ZeroingEstimator<AbsolutePosition,
-                              constants::AbsoluteEncoderZeroingConstants,
-                              AbsoluteEncoderEstimatorState> {
- public:
-  explicit AbsoluteEncoderZeroingEstimator(
-      const constants::AbsoluteEncoderZeroingConstants &constants);
-
-  // Resets the internal logic so it needs to be re-zeroed.
-  void Reset() override;
-
-  // Updates the sensor values for the zeroing logic.
-  void UpdateEstimate(const AbsolutePosition &info) override;
-
-  void TriggerError() override { error_ = true; }
-
-  bool zeroed() const override { return zeroed_; }
-
-  double offset() const override { return offset_; }
-
-  bool error() const override { return error_; }
-
-  // Returns true if the sample buffer is full.
-  bool offset_ready() const override {
-    return relative_to_absolute_offset_samples_.size() ==
-           constants_.average_filter_size;
-  }
-
-  // Returns information about our current state.
-  virtual flatbuffers::Offset<State> GetEstimatorState(
-      flatbuffers::FlatBufferBuilder *fbb) const override;
-
- private:
-  struct PositionStruct {
-    PositionStruct(const AbsolutePosition &position_buffer)
-        : absolute_encoder(position_buffer.absolute_encoder()),
-          encoder(position_buffer.encoder()) {}
-    double absolute_encoder;
-    double encoder;
-  };
-
-  // The zeroing constants used to describe the configuration of the system.
-  const constants::AbsoluteEncoderZeroingConstants constants_;
-
-  // True if the mechanism is zeroed.
-  bool zeroed_;
-  // Marker to track whether an error has occurred.
-  bool error_;
-  // The first valid offset we recorded. This is only set after zeroed_ first
-  // changes to true.
-  double first_offset_;
-
-  // The filtered absolute encoder.  This is used in the status for calibration.
-  double filtered_absolute_encoder_ = 0.0;
-
-  // Samples of the offset needed to line the relative encoder up with the
-  // absolute encoder.
-  ::std::vector<double> relative_to_absolute_offset_samples_;
-
-  MoveDetector<PositionStruct, AbsolutePosition> move_detector_;
-
-  // Estimated start position of the mechanism
-  double offset_ = 0;
-  // The next position in 'relative_to_absolute_offset_samples_' and
-  // 'encoder_samples_' to be used to store the next sample.
-  int samples_idx_ = 0;
-
-  // Number of NANs we've seen in a row.
-  size_t nan_samples_ = 0;
-
-  // The filtered position.
-  double position_ = 0.0;
-};
-
+// A trivial ZeroingEstimator which just passes the position straight through.
 class RelativeEncoderZeroingEstimator
     : public ZeroingEstimator<RelativePosition, void,
                               RelativeEncoderEstimatorState> {
@@ -562,4 +169,12 @@
 }  // namespace zeroing
 }  // namespace frc971
 
+// TODO(Brian): Actually split these targets apart. Need to convert all the
+// reverse dependencies to #include what they actually need...
+#include "frc971/zeroing/absolute_encoder.h"
+#include "frc971/zeroing/hall_effect_and_position.h"
+#include "frc971/zeroing/pot_and_absolute_encoder.h"
+#include "frc971/zeroing/pot_and_index.h"
+#include "frc971/zeroing/pulse_index.h"
+
 #endif  // FRC971_ZEROING_ZEROING_H_
diff --git a/frc971/zeroing/zeroing_test.cc b/frc971/zeroing/zeroing_test.cc
deleted file mode 100644
index 2b715ea..0000000
--- a/frc971/zeroing/zeroing_test.cc
+++ /dev/null
@@ -1,817 +0,0 @@
-#include "frc971/zeroing/zeroing.h"
-
-#include <unistd.h>
-
-#include <memory>
-#include <random>
-
-#include "aos/die.h"
-#include "frc971/control_loops/control_loops_generated.h"
-#include "frc971/control_loops/position_sensor_sim.h"
-#include "gtest/gtest.h"
-
-namespace frc971 {
-namespace zeroing {
-
-using constants::AbsoluteEncoderZeroingConstants;
-using constants::EncoderPlusIndexZeroingConstants;
-using constants::PotAndAbsoluteEncoderZeroingConstants;
-using constants::PotAndIndexPulseZeroingConstants;
-using control_loops::PositionSensorSimulator;
-using FBB = flatbuffers::FlatBufferBuilder;
-
-static const size_t kSampleSize = 30;
-static const double kAcceptableUnzeroedError = 0.2;
-static const double kIndexErrorFraction = 0.3;
-static const size_t kMovingBufferSize = 3;
-
-class ZeroingTest : public ::testing::Test {
- protected:
-  void SetUp() override {}
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              PotAndIndexPulseZeroingEstimator *estimator,
-              double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<PotAndIndexPosition>(&fbb));
-  }
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              AbsoluteEncoderZeroingEstimator *estimator, double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<AbsolutePosition>(&fbb));
-  }
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              PotAndAbsoluteEncoderZeroingEstimator *estimator,
-              double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<PotAndAbsolutePosition>(&fbb));
-  }
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              PulseIndexZeroingEstimator *estimator, double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<IndexPosition>(&fbb));
-  }
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              HallEffectAndPositionZeroingEstimator *estimator,
-              double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<HallEffectAndPosition>(&fbb));
-  }
-
-  void MoveTo(PositionSensorSimulator *simulator,
-              RelativeEncoderZeroingEstimator *estimator, double new_position) {
-    simulator->MoveTo(new_position);
-    FBB fbb;
-    estimator->UpdateEstimate(
-        *simulator->FillSensorValues<RelativePosition>(&fbb));
-  }
-
-  template <typename T>
-  double GetEstimatorPosition(T *estimator) {
-    FBB fbb;
-    fbb.Finish(estimator->GetEstimatorState(&fbb));
-    return flatbuffers::GetRoot<typename T::State>(fbb.GetBufferPointer())
-        ->position();
-  }
-};
-
-TEST_F(ZeroingTest, TestMovingAverageFilter) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.6 * index_diff, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  // The zeroing code is supposed to perform some filtering on the difference
-  // between the potentiometer value and the encoder value. We assume that 300
-  // samples are sufficient to have updated the filter.
-  for (int i = 0; i < 300; i++) {
-    MoveTo(&sim, &estimator, 3.3 * index_diff);
-  }
-  ASSERT_NEAR(3.3 * index_diff, GetEstimatorPosition(&estimator),
-              kAcceptableUnzeroedError * index_diff);
-
-  for (int i = 0; i < 300; i++) {
-    MoveTo(&sim, &estimator, 3.9 * index_diff);
-  }
-  ASSERT_NEAR(3.9 * index_diff, GetEstimatorPosition(&estimator),
-              kAcceptableUnzeroedError * index_diff);
-}
-
-TEST_F(ZeroingTest, NotZeroedBeforeEnoughSamplesCollected) {
-  double index_diff = 0.5;
-  double position = 3.6 * index_diff;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(position, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  // Make sure that the zeroing code does not consider itself zeroed until we
-  // collect a good amount of samples. In this case we're waiting until the
-  // moving average filter is full.
-  for (unsigned int i = 0; i < kSampleSize - 1; i++) {
-    MoveTo(&sim, &estimator, position += index_diff);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim, &estimator, position);
-  ASSERT_TRUE(estimator.zeroed());
-}
-
-TEST_F(ZeroingTest, TestLotsOfMovement) {
-  double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.6, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  // The zeroing code is supposed to perform some filtering on the difference
-  // between the potentiometer value and the encoder value. We assume that 300
-  // samples are sufficient to have updated the filter.
-  for (int i = 0; i < 300; i++) {
-    MoveTo(&sim, &estimator, 3.6);
-  }
-  ASSERT_NEAR(3.6, GetEstimatorPosition(&estimator),
-              kAcceptableUnzeroedError * index_diff);
-
-  // With a single index pulse the zeroing estimator should be able to lock
-  // onto the true value of the position.
-  MoveTo(&sim, &estimator, 4.01);
-  ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 4.99);
-  ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 3.99);
-  ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 3.01);
-  ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 13.55);
-  ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
-}
-
-TEST_F(ZeroingTest, TestDifferentIndexDiffs) {
-  double index_diff = 0.89;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.5 * index_diff, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  // The zeroing code is supposed to perform some filtering on the difference
-  // between the potentiometer value and the encoder value. We assume that 300
-  // samples are sufficient to have updated the filter.
-  for (int i = 0; i < 300; i++) {
-    MoveTo(&sim, &estimator, 3.5 * index_diff);
-  }
-  ASSERT_NEAR(3.5 * index_diff, GetEstimatorPosition(&estimator),
-              kAcceptableUnzeroedError * index_diff);
-
-  // With a single index pulse the zeroing estimator should be able to lock
-  // onto the true value of the position.
-  MoveTo(&sim, &estimator, 4.01);
-  ASSERT_NEAR(4.01, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 4.99);
-  ASSERT_NEAR(4.99, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 3.99);
-  ASSERT_NEAR(3.99, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 3.01);
-  ASSERT_NEAR(3.01, GetEstimatorPosition(&estimator), 0.001);
-
-  MoveTo(&sim, &estimator, 13.55);
-  ASSERT_NEAR(13.55, GetEstimatorPosition(&estimator), 0.001);
-}
-
-TEST_F(ZeroingTest, TestPercentage) {
-  double index_diff = 0.89;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.5 * index_diff, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  for (unsigned int i = 0; i < kSampleSize / 2; i++) {
-    MoveTo(&sim, &estimator, 3.5 * index_diff);
-  }
-  ASSERT_NEAR(0.5, estimator.offset_ratio_ready(), 0.001);
-  ASSERT_FALSE(estimator.offset_ready());
-
-  for (unsigned int i = 0; i < kSampleSize / 2; i++) {
-    MoveTo(&sim, &estimator, 3.5 * index_diff);
-  }
-  ASSERT_NEAR(1.0, estimator.offset_ratio_ready(), 0.001);
-  ASSERT_TRUE(estimator.offset_ready());
-}
-
-TEST_F(ZeroingTest, TestOffset) {
-  double index_diff = 0.89;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.1 * index_diff, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  MoveTo(&sim, &estimator, 3.1 * index_diff);
-
-  for (unsigned int i = 0; i < kSampleSize; i++) {
-    MoveTo(&sim, &estimator, 5.0 * index_diff);
-  }
-
-  ASSERT_NEAR(3.1 * index_diff, estimator.offset(), 0.001);
-}
-
-TEST_F(ZeroingTest, WaitForIndexPulseAfterReset) {
-  double index_diff = 0.6;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.1 * index_diff, index_diff / 3.0);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-
-  // Make sure to fill up the averaging filter with samples.
-  for (unsigned int i = 0; i < kSampleSize; i++) {
-    MoveTo(&sim, &estimator, 3.1 * index_diff);
-  }
-
-  // Make sure we're not zeroed until we hit an index pulse.
-  ASSERT_FALSE(estimator.zeroed());
-
-  // Trigger an index pulse; we should now be zeroed.
-  MoveTo(&sim, &estimator, 4.5 * index_diff);
-  ASSERT_TRUE(estimator.zeroed());
-
-  // Reset the zeroing logic and supply a bunch of samples within the current
-  // index segment.
-  estimator.Reset();
-  for (unsigned int i = 0; i < kSampleSize; i++) {
-    MoveTo(&sim, &estimator, 4.2 * index_diff);
-  }
-
-  // Make sure we're not zeroed until we hit an index pulse.
-  ASSERT_FALSE(estimator.zeroed());
-
-  // Trigger another index pulse; we should be zeroed again.
-  MoveTo(&sim, &estimator, 3.1 * index_diff);
-  ASSERT_TRUE(estimator.zeroed());
-}
-
-TEST_F(ZeroingTest, TestNonZeroIndexPulseOffsets) {
-  const double index_diff = 0.9;
-  const double known_index_pos = 3.5 * index_diff;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(3.3 * index_diff, index_diff / 3.0, known_index_pos);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, known_index_pos, kIndexErrorFraction});
-
-  // Make sure to fill up the averaging filter with samples.
-  for (unsigned int i = 0; i < kSampleSize; i++) {
-    MoveTo(&sim, &estimator, 3.3 * index_diff);
-  }
-
-  // Make sure we're not zeroed until we hit an index pulse.
-  ASSERT_FALSE(estimator.zeroed());
-
-  // Trigger an index pulse; we should now be zeroed.
-  MoveTo(&sim, &estimator, 3.7 * index_diff);
-  ASSERT_TRUE(estimator.zeroed());
-  ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
-  ASSERT_DOUBLE_EQ(3.7 * index_diff, GetEstimatorPosition(&estimator));
-
-  // Trigger one more index pulse and check the offset.
-  MoveTo(&sim, &estimator, 4.7 * index_diff);
-  ASSERT_DOUBLE_EQ(3.3 * index_diff, estimator.offset());
-  ASSERT_DOUBLE_EQ(4.7 * index_diff, GetEstimatorPosition(&estimator));
-}
-
-TEST_F(ZeroingTest, BasicErrorAPITest) {
-  const double index_diff = 1.0;
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      kSampleSize, index_diff, 0.0, kIndexErrorFraction});
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(1.5 * index_diff, index_diff / 3.0, 0.0);
-
-  // Perform a simple move and make sure that no error occured.
-  MoveTo(&sim, &estimator, 3.5 * index_diff);
-  ASSERT_FALSE(estimator.error());
-
-  // Trigger an error and make sure it's reported.
-  estimator.TriggerError();
-  ASSERT_TRUE(estimator.error());
-
-  // Make sure that it can recover after a reset.
-  estimator.Reset();
-  ASSERT_FALSE(estimator.error());
-  MoveTo(&sim, &estimator, 4.5 * index_diff);
-  MoveTo(&sim, &estimator, 5.5 * index_diff);
-  ASSERT_FALSE(estimator.error());
-}
-
-// Tests that an error is detected when the starting position changes too much.
-TEST_F(ZeroingTest, TestIndexOffsetError) {
-  const double index_diff = 0.8;
-  const double known_index_pos = 2 * index_diff;
-  const size_t sample_size = 30;
-  PositionSensorSimulator sim(index_diff);
-  sim.Initialize(10 * index_diff, index_diff / 3.0, known_index_pos);
-  PotAndIndexPulseZeroingEstimator estimator(PotAndIndexPulseZeroingConstants{
-      sample_size, index_diff, known_index_pos, kIndexErrorFraction});
-
-  for (size_t i = 0; i < sample_size; i++) {
-    MoveTo(&sim, &estimator, 13 * index_diff);
-  }
-  MoveTo(&sim, &estimator, 8 * index_diff);
-
-  ASSERT_TRUE(estimator.zeroed());
-  ASSERT_FALSE(estimator.error());
-  sim.Initialize(9.0 * index_diff + 0.31 * index_diff, index_diff / 3.0,
-                 known_index_pos);
-  MoveTo(&sim, &estimator, 9 * index_diff);
-  ASSERT_TRUE(estimator.zeroed());
-  ASSERT_TRUE(estimator.error());
-}
-
-// Makes sure that using an absolute encoder lets us zero without moving.
-TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithoutMovement) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double start_pos = 2.1;
-  double measured_absolute_position = 0.3 * index_diff;
-
-  PotAndAbsoluteEncoderZeroingConstants constants{
-      kSampleSize, index_diff,        measured_absolute_position,
-      0.1,         kMovingBufferSize, kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_TRUE(estimator.zeroed());
-  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
-}
-
-// Makes sure that we ignore a NAN if we get it, but will correctly zero
-// afterwards.
-TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingIgnoresNAN) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double start_pos = 2.1;
-  double measured_absolute_position = 0.3 * index_diff;
-
-  PotAndAbsoluteEncoderZeroingConstants constants{
-      kSampleSize, index_diff,        measured_absolute_position,
-      0.1,         kMovingBufferSize, kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
-
-  // We tolerate a couple NANs before we start.
-  FBB fbb;
-  fbb.Finish(CreatePotAndAbsolutePosition(
-      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
-  for (size_t i = 0; i < kSampleSize - 1; ++i) {
-    estimator.UpdateEstimate(
-        *flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer()));
-  }
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_TRUE(estimator.zeroed());
-  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
-}
-
-// Makes sure that using an absolute encoder doesn't let us zero while moving.
-TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithMovement) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double start_pos = 10 * index_diff;
-  double measured_absolute_position = 0.3 * index_diff;
-
-  PotAndAbsoluteEncoderZeroingConstants constants{
-      kSampleSize, index_diff,        measured_absolute_position,
-      0.1,         kMovingBufferSize, kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos + i * index_diff);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-  MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_FALSE(estimator.zeroed());
-}
-
-// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
-TEST_F(ZeroingTest, TestPotAndAbsoluteEncoderZeroingWithNaN) {
-  PotAndAbsoluteEncoderZeroingConstants constants{
-      kSampleSize, 1, 0.3, 0.1, kMovingBufferSize, kIndexErrorFraction};
-
-  PotAndAbsoluteEncoderZeroingEstimator estimator(constants);
-
-  FBB fbb;
-  fbb.Finish(CreatePotAndAbsolutePosition(
-      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN(), 0.0));
-  const auto sensor_values =
-      flatbuffers::GetRoot<PotAndAbsolutePosition>(fbb.GetBufferPointer());
-  for (size_t i = 0; i < kSampleSize - 1; ++i) {
-    estimator.UpdateEstimate(*sensor_values);
-  }
-  ASSERT_FALSE(estimator.error());
-
-  estimator.UpdateEstimate(*sensor_values);
-  ASSERT_TRUE(estimator.error());
-}
-
-// Tests that an error is detected when the starting position changes too much.
-TEST_F(ZeroingTest, 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(ZeroingTest, 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());
-  }
-}
-
-// Test fixture for HallEffectAndPositionZeroingEstimator.
-class HallEffectAndPositionZeroingEstimatorTest : public ZeroingTest {
- public:
-  // The starting position of the system.
-  static constexpr double kStartPosition = 2.0;
-
-  // Returns a reasonable set of test constants.
-  static constants::HallEffectZeroingConstants MakeConstants() {
-    constants::HallEffectZeroingConstants constants;
-    constants.lower_hall_position = 0.25;
-    constants.upper_hall_position = 0.75;
-    constants.index_difference = 1.0;
-    constants.hall_trigger_zeroing_length = 2;
-    constants.zeroing_move_direction = false;
-    return constants;
-  }
-
-  HallEffectAndPositionZeroingEstimatorTest()
-      : constants_(MakeConstants()), sim_(constants_.index_difference) {
-    // Start the system out at the starting position.
-    sim_.InitializeHallEffectAndPosition(kStartPosition,
-                                         constants_.lower_hall_position,
-                                         constants_.upper_hall_position);
-  }
-
- protected:
-  // Constants, and the simulation using them.
-  const constants::HallEffectZeroingConstants constants_;
-  PositionSensorSimulator sim_;
-};
-
-// Tests that an error is detected when the starting position changes too much.
-TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestHallEffectZeroing) {
-  HallEffectAndPositionZeroingEstimator estimator(constants_);
-
-  // Should not be zeroed when we stand still.
-  for (int i = 0; i < 300; ++i) {
-    MoveTo(&sim_, &estimator, kStartPosition);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim_, &estimator, 1.9);
-  ASSERT_FALSE(estimator.zeroed());
-
-  // Move to where the hall effect is triggered and make sure it becomes zeroed.
-  MoveTo(&sim_, &estimator, 1.5);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 1.5);
-  ASSERT_TRUE(estimator.zeroed());
-
-  // Check that the offset is calculated correctly.  We should expect to read
-  // 0.5.  Since the encoder is reading -0.5 right now, the offset needs to be
-  // 1.
-  EXPECT_DOUBLE_EQ(1.0, estimator.offset());
-
-  // Make sure triggering errors works.
-  estimator.TriggerError();
-  ASSERT_TRUE(estimator.error());
-
-  // Ensure resetting resets the state of the estimator.
-  estimator.Reset();
-  ASSERT_FALSE(estimator.zeroed());
-  ASSERT_FALSE(estimator.error());
-}
-
-// Tests that we don't zero on a too short pulse.
-TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestTooShortPulse) {
-  HallEffectAndPositionZeroingEstimator estimator(constants_);
-
-  // Trigger for 1 cycle.
-  MoveTo(&sim_, &estimator, 0.9);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.5);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.9);
-  EXPECT_FALSE(estimator.zeroed());
-}
-
-// Tests that we don't zero when we go the wrong direction.
-TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestWrongDirectionNoZero) {
-  HallEffectAndPositionZeroingEstimator estimator(constants_);
-
-  // Pass through the sensor, lingering long enough that we should zero.
-  MoveTo(&sim_, &estimator, 0.0);
-  ASSERT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.4);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.6);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.7);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.9);
-  EXPECT_FALSE(estimator.zeroed());
-}
-
-// Make sure we don't zero if we start in the hall effect's range.
-TEST_F(HallEffectAndPositionZeroingEstimatorTest, TestStartingOnNoZero) {
-  HallEffectAndPositionZeroingEstimator estimator(constants_);
-  MoveTo(&sim_, &estimator, 0.5);
-  estimator.Reset();
-
-  // Stay on the hall effect.  We shouldn't zero.
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.5);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.5);
-  EXPECT_FALSE(estimator.zeroed());
-
-  // Verify moving off the hall still doesn't zero us.
-  MoveTo(&sim_, &estimator, 0.0);
-  EXPECT_FALSE(estimator.zeroed());
-  MoveTo(&sim_, &estimator, 0.0);
-  EXPECT_FALSE(estimator.zeroed());
-}
-
-// Makes sure that using an absolute encoder lets us zero without moving.
-TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithoutMovement) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double kMiddlePosition = 2.5;
-  const double start_pos = 2.1;
-  double measured_absolute_position = 0.3 * index_diff;
-
-  AbsoluteEncoderZeroingConstants constants{
-      kSampleSize,        index_diff, measured_absolute_position,
-      kMiddlePosition,    0.1,        kMovingBufferSize,
-      kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  AbsoluteEncoderZeroingEstimator estimator(constants);
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_TRUE(estimator.zeroed());
-  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
-}
-
-// Makes sure that we ignore a NAN if we get it, but will correctly zero
-// afterwards.
-TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingIgnoresNAN) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double start_pos = 2.1;
-  double measured_absolute_position = 0.3 * index_diff;
-  const double kMiddlePosition = 2.5;
-
-  AbsoluteEncoderZeroingConstants constants{
-      kSampleSize,        index_diff, measured_absolute_position,
-      kMiddlePosition,    0.1,        kMovingBufferSize,
-      kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  AbsoluteEncoderZeroingEstimator estimator(constants);
-
-  // We tolerate a couple NANs before we start.
-  FBB fbb;
-  fbb.Finish(CreateAbsolutePosition(
-      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
-  const auto sensor_values =
-      flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
-  for (size_t i = 0; i < kSampleSize - 1; ++i) {
-    estimator.UpdateEstimate(*sensor_values);
-  }
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_TRUE(estimator.zeroed());
-  EXPECT_DOUBLE_EQ(start_pos, estimator.offset());
-}
-
-// Makes sure that using an absolute encoder doesn't let us zero while moving.
-TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithMovement) {
-  const double index_diff = 1.0;
-  PositionSensorSimulator sim(index_diff);
-
-  const double start_pos = 10 * index_diff;
-  double measured_absolute_position = 0.3 * index_diff;
-  const double kMiddlePosition = 2.5;
-
-  AbsoluteEncoderZeroingConstants constants{
-      kSampleSize,        index_diff, measured_absolute_position,
-      kMiddlePosition,    0.1,        kMovingBufferSize,
-      kIndexErrorFraction};
-
-  sim.Initialize(start_pos, index_diff / 3.0, 0.0,
-                 constants.measured_absolute_position);
-
-  AbsoluteEncoderZeroingEstimator estimator(constants);
-
-  for (size_t i = 0; i < kSampleSize + kMovingBufferSize - 1; ++i) {
-    MoveTo(&sim, &estimator, start_pos + i * index_diff);
-    ASSERT_FALSE(estimator.zeroed());
-  }
-  MoveTo(&sim, &estimator, start_pos + 10 * index_diff);
-
-  MoveTo(&sim, &estimator, start_pos);
-  ASSERT_FALSE(estimator.zeroed());
-}
-
-// Makes sure we detect an error if the ZeroingEstimator gets sent a NaN.
-TEST_F(ZeroingTest, TestAbsoluteEncoderZeroingWithNaN) {
-  AbsoluteEncoderZeroingConstants constants{
-      kSampleSize, 1, 0.3, 1.0, 0.1, kMovingBufferSize, kIndexErrorFraction};
-
-  AbsoluteEncoderZeroingEstimator estimator(constants);
-
-  FBB fbb;
-  fbb.Finish(CreateAbsolutePosition(
-      fbb, 0.0, ::std::numeric_limits<double>::quiet_NaN()));
-  const auto sensor_values =
-      flatbuffers::GetRoot<AbsolutePosition>(fbb.GetBufferPointer());
-  for (size_t i = 0; i < kSampleSize - 1; ++i) {
-    estimator.UpdateEstimate(*sensor_values);
-  }
-  ASSERT_FALSE(estimator.error());
-
-  estimator.UpdateEstimate(*sensor_values);
-  ASSERT_TRUE(estimator.error());
-}
-
-TEST_F(ZeroingTest, TestRelativeEncoderZeroingWithoutMovement) {
-  PositionSensorSimulator sim(1.0);
-  RelativeEncoderZeroingEstimator estimator;
-
-  sim.InitializeRelativeEncoder();
-
-  ASSERT_TRUE(estimator.zeroed());
-  ASSERT_TRUE(estimator.offset_ready());
-  EXPECT_DOUBLE_EQ(estimator.offset(), 0.0);
-  EXPECT_DOUBLE_EQ(GetEstimatorPosition(&estimator), 0.0);
-
-  MoveTo(&sim, &estimator, 0.1);
-
-  EXPECT_DOUBLE_EQ(GetEstimatorPosition(&estimator), 0.1);
-}
-
-}  // namespace zeroing
-}  // namespace frc971
diff --git a/frc971/zeroing/zeroing_test.h b/frc971/zeroing/zeroing_test.h
new file mode 100644
index 0000000..9b7ba95
--- /dev/null
+++ b/frc971/zeroing/zeroing_test.h
@@ -0,0 +1,32 @@
+#include "frc971/zeroing/zeroing.h"
+
+#include "frc971/control_loops/control_loops_generated.h"
+#include "frc971/control_loops/position_sensor_sim.h"
+#include "gtest/gtest.h"
+
+namespace frc971 {
+namespace zeroing {
+namespace testing {
+
+using control_loops::PositionSensorSimulator;
+using FBB = flatbuffers::FlatBufferBuilder;
+
+constexpr size_t kSampleSize = 30;
+constexpr double kAcceptableUnzeroedError = 0.2;
+constexpr double kIndexErrorFraction = 0.3;
+constexpr size_t kMovingBufferSize = 3;
+
+class ZeroingTest : public ::testing::Test {
+ protected:
+  template <typename T>
+  double GetEstimatorPosition(T *estimator) {
+    FBB fbb;
+    fbb.Finish(estimator->GetEstimatorState(&fbb));
+    return flatbuffers::GetRoot<typename T::State>(fbb.GetBufferPointer())
+        ->position();
+  }
+};
+
+}  // namespace testing
+}  // namespace zeroing
+}  // namespace frc971
