Added y2018 wpilib_interface, and constants

Change-Id: I9499fc4fbb34434372583e8e2a572740b60a4715
diff --git a/frc971/wpilib/encoder_and_potentiometer.h b/frc971/wpilib/encoder_and_potentiometer.h
index 09c1244..3cce77d 100644
--- a/frc971/wpilib/encoder_and_potentiometer.h
+++ b/frc971/wpilib/encoder_and_potentiometer.h
@@ -203,6 +203,72 @@
   DISALLOW_COPY_AND_ASSIGN(DMAEncoderAndPotentiometer);
 };
 
+// Class to read duty cycle of an input.  This is tuned for the CTRE encoder's
+// absolute position output.
+class DutyCycleReader {
+ public:
+  // Configure the reader to use the provided digital input.
+  void set_input(::std::unique_ptr<::frc::DigitalInput> input) {
+    high_counter_.reset(new ::frc::Counter(input.get()));
+    high_counter_->SetMaxPeriod(kMaxPeriod);
+    high_counter_->SetSemiPeriodMode(true);
+
+    period_length_counter_.reset(new ::frc::Counter(input.get()));
+    period_length_counter_->SetMaxPeriod(kMaxPeriod);
+    period_length_counter_->SetUpSourceEdge(true, false);
+
+    input_ = ::std::move(input);
+  }
+
+  // Returns the last duty cycle or nan if the signal is stale.
+  double Read() const {
+    const double high_time = high_counter_->GetPeriod();
+    const double period_length = period_length_counter_->GetPeriod();
+    if (!::std::isfinite(high_time) || !::std::isfinite(period_length)) {
+      return ::std::numeric_limits<double>::quiet_NaN();
+    }
+    return high_time / period_length;
+  }
+
+ private:
+  static constexpr ::std::chrono::nanoseconds kNominalPeriod =
+      ::std::chrono::microseconds(4096);
+  static constexpr double kMaxPeriod =
+      (::std::chrono::duration_cast<::std::chrono::duration<double>>(
+           kNominalPeriod) *
+       2).count();
+
+  ::std::unique_ptr<::frc::Counter> high_counter_, period_length_counter_;
+  ::std::unique_ptr<::frc::DigitalInput> input_;
+};
+
+// Class to hold a CTRE encoder with absolute angle pwm and potentiometer pair.
+class AbsoluteEncoderAndPotentiometer {
+ public:
+  void set_absolute_pwm(::std::unique_ptr<DigitalInput> input) {
+    duty_cycle_.set_input(::std::move(input));
+  }
+
+  void set_encoder(::std::unique_ptr<Encoder> encoder) {
+    encoder_ = ::std::move(encoder);
+  }
+
+  void set_potentiometer(::std::unique_ptr<AnalogInput> potentiometer) {
+    potentiometer_ = ::std::move(potentiometer);
+  }
+
+  double ReadAbsoluteEncoder() const { return duty_cycle_.Read(); }
+  int32_t ReadRelativeEncoder() const { return encoder_->GetRaw(); }
+  double ReadPotentiometerVoltage() const {
+    return potentiometer_->GetVoltage();
+  }
+
+ private:
+  DutyCycleReader duty_cycle_;
+  ::std::unique_ptr<Encoder> encoder_;
+  ::std::unique_ptr<AnalogInput> potentiometer_;
+};
+
 }  // namespace wpilib
 }  // namespace frc971