diff --git a/y2018/wpilib_interface.cc b/y2018/wpilib_interface.cc
new file mode 100644
index 0000000..0aa4203
--- /dev/null
+++ b/y2018/wpilib_interface.cc
@@ -0,0 +1,887 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <array>
+#include <chrono>
+#include <cmath>
+#include <functional>
+#include <mutex>
+#include <thread>
+
+#include "AnalogInput.h"
+#include "Counter.h"
+#include "DigitalGlitchFilter.h"
+#include "DriverStation.h"
+#include "Encoder.h"
+#include "Relay.h"
+#include "Servo.h"
+#include "VictorSP.h"
+#undef ERROR
+
+#include "aos/common/commonmath.h"
+#include "aos/common/logging/logging.h"
+#include "aos/common/logging/queue_logging.h"
+#include "aos/common/messages/robot_state.q.h"
+#include "aos/common/stl_mutex.h"
+#include "aos/common/time.h"
+#include "aos/common/util/compiler_memory_barrier.h"
+#include "aos/common/util/log_interval.h"
+#include "aos/common/util/phased_loop.h"
+#include "aos/common/util/wrapping_counter.h"
+#include "aos/linux_code/init.h"
+
+#include "frc971/autonomous/auto.q.h"
+#include "frc971/control_loops/control_loops.q.h"
+#include "frc971/control_loops/drivetrain/drivetrain.q.h"
+#include "frc971/wpilib/ADIS16448.h"
+#include "frc971/wpilib/buffered_pcm.h"
+#include "frc971/wpilib/buffered_solenoid.h"
+#include "frc971/wpilib/dma.h"
+#include "frc971/wpilib/dma_edge_counting.h"
+#include "frc971/wpilib/encoder_and_potentiometer.h"
+#include "frc971/wpilib/interrupt_edge_counting.h"
+#include "frc971/wpilib/joystick_sender.h"
+#include "frc971/wpilib/logging.q.h"
+#include "frc971/wpilib/loop_output_handler.h"
+#include "frc971/wpilib/pdp_fetcher.h"
+#include "frc971/wpilib/wpilib_interface.h"
+#include "frc971/wpilib/wpilib_robot_base.h"
+#include "y2018/constants.h"
+#include "y2018/control_loops/superstructure/superstructure.q.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+using ::frc971::control_loops::drivetrain_queue;
+using ::y2018::control_loops::superstructure_queue;
+using ::y2018::constants::Values;
+using ::aos::monotonic_clock;
+namespace chrono = ::std::chrono;
+
+namespace y2018 {
+namespace wpilib {
+namespace {
+
+constexpr double kMaxBringupPower = 12.0;
+
+// TODO(Brian): Fix the interpretation of the result of GetRaw here and in the
+// DMA stuff and then removing the * 2.0 in *_translate.
+// The low bit is direction.
+
+// TODO(brian): Replace this with ::std::make_unique once all our toolchains
+// have support.
+
+template <class T, class... U>
+std::unique_ptr<T> make_unique(U &&... u) {
+  return std::unique_ptr<T>(new T(std::forward<U>(u)...));
+}
+
+// TODO(brian): Use ::std::max instead once we have C++14 so that can be
+// constexpr.
+
+template <typename T>
+constexpr T max(T a, T b) {
+  return (a > b) ? a : b;
+}
+
+template <typename T, typename... Rest>
+constexpr T max(T a, T b, T c, Rest... rest) {
+  return max(max(a, b), c, rest...);
+}
+
+double drivetrain_translate(int32_t in) {
+  return static_cast<double>(in) /
+         Values::kDrivetrainEncoderCountsPerRevolution() *
+         Values::kDrivetrainEncoderRatio() * control_loops::drivetrain::kWheelRadius;
+}
+
+double drivetrain_velocity_translate(double in) {
+  return (1.0 / in) / Values::kDrivetrainCyclesPerRevolution() *
+         Values::kDrivetrainEncoderRatio() * control_loops::drivetrain::kWheelRadius;
+}
+
+double proximal_pot_translate(double voltage) {
+  return voltage * Values::kProximalPotRatio() *
+         (3.0 /*turns*/ / 5.0 /*volts*/) * (2 * M_PI /*radians*/);
+}
+
+double distal_pot_translate(double voltage) {
+  return voltage * Values::kDistalPotRatio() *
+         (10.0 /*turns*/ / 5.0 /*volts*/) * (2 * M_PI /*radians*/);
+}
+
+double intake_pot_translate(double voltage) {
+  return voltage * Values::kIntakeMotorPotRatio() *
+         (10.0 /*turns*/ / 5.0 /*volts*/) * (2 * M_PI /*radians*/);
+}
+
+double intake_spring_translate(double voltage) {
+  return voltage * Values::kIntakeSpringRatio() * (2 * M_PI /*radians*/) /
+         (5.0 /*volts*/);
+}
+
+// TODO() figure out differnce between max and min voltages on shifter pots.
+// Returns value from 0.0 to 1.0, with 0.0 being close to low gear so it can be
+// passed drectly into the drivetrain position queue.
+double drivetrain_shifter_pot_translate(double voltage) {
+  return voltage / (Values::kDrivetrainShifterPotMaxVoltage() -
+                    Values::kDrivetrainShifterPotMinVoltage());
+}
+
+constexpr double kMaxFastEncoderPulsesPerSecond =
+    max(Values::kMaxDrivetrainEncoderPulsesPerSecond(),
+        Values::kMaxIntakeMotorEncoderPulsesPerSecond());
+static_assert(kMaxFastEncoderPulsesPerSecond <= 1300000,
+              "fast encoders are too fast");
+
+constexpr double kMaxMediumEncoderPulsesPerSecond =
+    max(Values::kMaxProximalEncoderPulsesPerSecond(),
+        Values::kMaxDistalEncoderPulsesPerSecond());
+static_assert(kMaxMediumEncoderPulsesPerSecond <= 400000,
+              "medium encoders are too fast");
+
+// Class to send position messages with sensor readings to our loops.
+class SensorReader {
+ public:
+  SensorReader() {
+    // Set to filter out anything shorter than 1/4 of the minimum pulse width
+    // we should ever see.
+    fast_encoder_filter_.SetPeriodNanoSeconds(
+        static_cast<int>(1 / 4.0 /* built-in tolerance */ /
+                             kMaxFastEncoderPulsesPerSecond * 1e9 +
+                         0.5));
+    medium_encoder_filter_.SetPeriodNanoSeconds(
+        static_cast<int>(1 / 4.0 /* built-in tolerance */ /
+                             kMaxMediumEncoderPulsesPerSecond * 1e9 +
+                         0.5));
+    hall_filter_.SetPeriodNanoSeconds(100000);
+  }
+
+  // Left drivetrain side.
+  void set_drivetrain_left_encoder(::std::unique_ptr<Encoder> encoder) {
+    fast_encoder_filter_.Add(encoder.get());
+    drivetrain_left_encoder_ = ::std::move(encoder);
+  }
+
+  void set_left_drivetrain_shifter_potentiometer(
+      ::std::unique_ptr<AnalogInput> potentiometer) {
+    left_drivetrain_shifter_ = ::std::move(potentiometer);
+  }
+
+  // Right drivetrain side.
+  void set_drivetrain_right_encoder(::std::unique_ptr<Encoder> encoder) {
+    fast_encoder_filter_.Add(encoder.get());
+    drivetrain_right_encoder_ = ::std::move(encoder);
+  }
+
+  void set_right_drivetrain_shifter_potentiometer(
+      ::std::unique_ptr<AnalogInput> potentiometer) {
+    right_drivetrain_shifter_ = ::std::move(potentiometer);
+  }
+
+  // Proximal joint.
+  void set_proximal_encoder(::std::unique_ptr<Encoder> encoder) {
+    medium_encoder_filter_.Add(encoder.get());
+    proximal_encoder_.set_encoder(::std::move(encoder));
+  }
+
+  void set_proximal_absolute_pwm(::std::unique_ptr<DigitalInput> absolute_pwm) {
+    proximal_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
+  }
+
+  void set_proximal_potentiometer(
+      ::std::unique_ptr<AnalogInput> potentiometer) {
+    proximal_encoder_.set_potentiometer(::std::move(potentiometer));
+  }
+
+  // Distal joint.
+  void set_distal_encoder(::std::unique_ptr<Encoder> encoder) {
+    medium_encoder_filter_.Add(encoder.get());
+    distal_encoder_.set_encoder(::std::move(encoder));
+  }
+
+  void set_distal_absolute_pwm(::std::unique_ptr<DigitalInput> absolute_pwm) {
+    fast_encoder_filter_.Add(absolute_pwm.get());
+    distal_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
+  }
+
+  void set_distal_potentiometer(::std::unique_ptr<AnalogInput> potentiometer) {
+    distal_encoder_.set_potentiometer(::std::move(potentiometer));
+  }
+
+  // Left intake side.
+  void set_left_intake_encoder(::std::unique_ptr<Encoder> encoder) {
+    fast_encoder_filter_.Add(encoder.get());
+    left_intake_encoder_.set_encoder(::std::move(encoder));
+  }
+
+  void set_left_intake_absolute_pwm(
+      ::std::unique_ptr<DigitalInput> absolute_pwm) {
+    fast_encoder_filter_.Add(absolute_pwm.get());
+    left_intake_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
+  }
+
+  void set_left_intake_potentiometer(
+      ::std::unique_ptr<AnalogInput> potentiometer) {
+    left_intake_encoder_.set_potentiometer(::std::move(potentiometer));
+  }
+
+  void set_left_intake_spring_angle(::std::unique_ptr<AnalogInput> encoder) {
+    left_intake_spring_angle_ = ::std::move(encoder);
+  }
+
+  void set_left_intake_cube_detector(::std::unique_ptr<DigitalInput> input) {
+    left_intake_cube_detector_ = ::std::move(input);
+  }
+
+  // Right intake side.
+  void set_right_intake_encoder(::std::unique_ptr<Encoder> encoder) {
+    fast_encoder_filter_.Add(encoder.get());
+    right_intake_encoder_.set_encoder(::std::move(encoder));
+  }
+
+  void set_right_intake_absolute_pwm(
+      ::std::unique_ptr<DigitalInput> absolute_pwm) {
+    fast_encoder_filter_.Add(absolute_pwm.get());
+    right_intake_encoder_.set_absolute_pwm(::std::move(absolute_pwm));
+  }
+
+  void set_right_intake_potentiometer(
+      ::std::unique_ptr<AnalogInput> potentiometer) {
+    right_intake_encoder_.set_potentiometer(::std::move(potentiometer));
+  }
+
+  void set_right_intake_spring_angle(::std::unique_ptr<AnalogInput> encoder) {
+    right_intake_spring_angle_ = ::std::move(encoder);
+  }
+
+  void set_right_intake_cube_detector(::std::unique_ptr<DigitalInput> input) {
+    right_intake_cube_detector_ = ::std::move(input);
+  }
+
+  // Auto mode switches.
+  void set_autonomous_mode(int i, ::std::unique_ptr<DigitalInput> sensor) {
+    autonomous_modes_.at(i) = ::std::move(sensor);
+  }
+
+  void set_pwm_trigger(::std::unique_ptr<DigitalInput> pwm_trigger) {
+    medium_encoder_filter_.Add(pwm_trigger.get());
+    pwm_trigger_ = ::std::move(pwm_trigger);
+  }
+
+  // All of the DMA-related set_* calls must be made before this, and it
+  // doesn't hurt to do all of them.
+  void set_dma(::std::unique_ptr<DMA> dma) {
+    dma_synchronizer_.reset(
+        new ::frc971::wpilib::DMASynchronizer(::std::move(dma)));
+  }
+
+  void RunPWMDetecter() {
+    ::aos::SetCurrentThreadRealtimePriority(41);
+
+    pwm_trigger_->RequestInterrupts();
+    // Rising edge only.
+    pwm_trigger_->SetUpSourceEdge(true, false);
+
+    monotonic_clock::time_point last_posedge_monotonic =
+        monotonic_clock::min_time;
+
+    while (run_) {
+      auto ret = pwm_trigger_->WaitForInterrupt(1.0, true);
+      if (ret == InterruptableSensorBase::WaitResult::kRisingEdge) {
+        // Grab all the clocks.
+        const double pwm_fpga_time = pwm_trigger_->ReadRisingTimestamp();
+
+        aos_compiler_memory_barrier();
+        const double fpga_time_before = GetFPGATime() * 1e-6;
+        aos_compiler_memory_barrier();
+        const monotonic_clock::time_point monotonic_now =
+            monotonic_clock::now();
+        aos_compiler_memory_barrier();
+        const double fpga_time_after = GetFPGATime() * 1e-6;
+        aos_compiler_memory_barrier();
+
+        const double fpga_offset =
+            (fpga_time_after + fpga_time_before) / 2.0 - pwm_fpga_time;
+
+        // Compute when the edge was.
+        const monotonic_clock::time_point monotonic_edge =
+            monotonic_now - chrono::duration_cast<chrono::nanoseconds>(
+                                chrono::duration<double>(fpga_offset));
+
+        LOG(DEBUG, "Got PWM pulse %f spread, %f offset, %lld trigger\n",
+            fpga_time_after - fpga_time_before, fpga_offset,
+            monotonic_edge.time_since_epoch().count());
+
+        // Compute bounds on the timestep and sampling times.
+        const double fpga_sample_length = fpga_time_after - fpga_time_before;
+        const chrono::nanoseconds elapsed_time =
+            monotonic_edge - last_posedge_monotonic;
+
+        last_posedge_monotonic = monotonic_edge;
+
+        // Verify that the values are sane.
+        if (fpga_sample_length > 2e-5 || fpga_sample_length < 0) {
+          continue;
+        }
+        if (fpga_offset < 0 || fpga_offset > 0.00015) {
+          continue;
+        }
+        if (elapsed_time >
+                chrono::microseconds(5050) + chrono::microseconds(4) ||
+            elapsed_time <
+                chrono::microseconds(5050) - chrono::microseconds(4)) {
+          continue;
+        }
+        // Good edge!
+        {
+          ::std::unique_lock<::aos::stl_mutex> locker(tick_time_mutex_);
+          last_tick_time_monotonic_timepoint_ = last_posedge_monotonic;
+          last_period_ = elapsed_time;
+        }
+      } else {
+        LOG(INFO, "PWM triggered %d\n", ret);
+      }
+    }
+    pwm_trigger_->CancelInterrupts();
+  }
+
+  void operator()() {
+    ::aos::SetCurrentThreadName("SensorReader");
+
+    my_pid_ = getpid();
+    ds_ = &DriverStation::GetInstance();
+
+    dma_synchronizer_->Start();
+
+    ::aos::time::PhasedLoop phased_loop(last_period_,
+                                        ::std::chrono::milliseconds(3));
+    chrono::nanoseconds filtered_period = last_period_;
+
+    ::std::thread pwm_detecter_thread(
+        ::std::bind(&SensorReader::RunPWMDetecter, this));
+
+    ::aos::SetCurrentThreadRealtimePriority(40);
+    while (run_) {
+      {
+        const int iterations = phased_loop.SleepUntilNext();
+        if (iterations != 1) {
+          LOG(WARNING, "SensorReader skipped %d iterations\n", iterations - 1);
+        }
+      }
+      RunIteration();
+
+      monotonic_clock::time_point last_tick_timepoint;
+      chrono::nanoseconds period;
+      {
+        ::std::unique_lock<::aos::stl_mutex> locker(tick_time_mutex_);
+        last_tick_timepoint = last_tick_time_monotonic_timepoint_;
+        period = last_period_;
+      }
+
+      if (last_tick_timepoint == monotonic_clock::min_time) {
+        continue;
+      }
+      chrono::nanoseconds new_offset = phased_loop.OffsetFromIntervalAndTime(
+          period, last_tick_timepoint + chrono::microseconds(2050));
+
+      // TODO(austin): If this is the first edge in a while, skip to it (plus
+      // an offset). Otherwise, slowly drift time to line up.
+
+      phased_loop.set_interval_and_offset(period, new_offset);
+    }
+    pwm_detecter_thread.join();
+  }
+
+  void RunIteration() {
+    ::frc971::wpilib::SendRobotState(my_pid_, ds_);
+
+    const auto values = constants::GetValues();
+
+    {
+      auto drivetrain_message = drivetrain_queue.position.MakeMessage();
+      drivetrain_message->right_encoder =
+          drivetrain_translate(drivetrain_right_encoder_->GetRaw());
+      drivetrain_message->right_speed =
+          drivetrain_velocity_translate(drivetrain_right_encoder_->GetPeriod());
+      drivetrain_message->left_shifter_position =
+          drivetrain_shifter_pot_translate(
+              left_drivetrain_shifter_->GetVoltage());
+
+      drivetrain_message->left_encoder =
+          -drivetrain_translate(drivetrain_left_encoder_->GetRaw());
+      drivetrain_message->left_speed =
+          drivetrain_velocity_translate(drivetrain_left_encoder_->GetPeriod());
+      drivetrain_message->right_shifter_position =
+          drivetrain_shifter_pot_translate(
+              right_drivetrain_shifter_->GetVoltage());
+
+      drivetrain_message.Send();
+    }
+
+    dma_synchronizer_->RunIteration();
+
+    {
+      auto superstructure_message = superstructure_queue.position.MakeMessage();
+
+      CopyPosition(proximal_encoder_, &superstructure_message->arm.proximal,
+                   Values::kProximalEncoderCountsPerRevolution(),
+                   Values::kProximalEncoderRatio(), proximal_pot_translate,
+                   false, values.proximal.pot_offset);
+
+      CopyPosition(distal_encoder_, &superstructure_message->arm.distal,
+                   Values::kDistalEncoderCountsPerRevolution(),
+                   Values::kDistalEncoderRatio(), distal_pot_translate, false,
+                   values.distal.pot_offset);
+
+      CopyPosition(left_intake_encoder_,
+                   &superstructure_message->intake.left.motor_position,
+                   Values::kIntakeMotorEncoderCountsPerRevolution(),
+                   Values::kIntakeMotorEncoderRatio(), intake_pot_translate,
+                   false, values.intake.left_pot_offset);
+
+      CopyPosition(right_intake_encoder_,
+                   &superstructure_message->intake.right.motor_position,
+                   Values::kIntakeMotorEncoderCountsPerRevolution(),
+                   Values::kIntakeMotorEncoderRatio(), intake_pot_translate,
+                   false, values.intake.right_pot_offset);
+
+      superstructure_message->intake.left.spring_angle =
+          intake_spring_translate(left_intake_spring_angle_->GetVoltage());
+      superstructure_message->intake.left.beam_break =
+          left_intake_cube_detector_->Get();
+
+      superstructure_message->intake.right.spring_angle =
+          intake_spring_translate(right_intake_spring_angle_->GetVoltage());
+      superstructure_message->intake.right.beam_break =
+          right_intake_cube_detector_->Get();
+
+      superstructure_message.Send();
+    }
+
+    {
+      auto auto_mode_message = ::frc971::autonomous::auto_mode.MakeMessage();
+      auto_mode_message->mode = 0;
+      for (size_t i = 0; i < autonomous_modes_.size(); ++i) {
+        if (autonomous_modes_[i] && autonomous_modes_[i]->Get()) {
+          auto_mode_message->mode |= 1 << i;
+        }
+      }
+      LOG_STRUCT(DEBUG, "auto mode", *auto_mode_message);
+      auto_mode_message.Send();
+    }
+  }
+
+  void Quit() { run_ = false; }
+
+ private:
+  double encoder_translate(int32_t value, double counts_per_revolution,
+                           double ratio) {
+    return static_cast<double>(value) / counts_per_revolution * ratio *
+           (2.0 * M_PI);
+  }
+
+  void CopyPosition(
+      const ::frc971::wpilib::AbsoluteEncoderAndPotentiometer &encoder,
+      ::frc971::PotAndAbsolutePosition *position,
+      double encoder_counts_per_revolution, double encoder_ratio,
+      ::std::function<double(double)> potentiometer_translate, bool reverse,
+      double pot_offset) {
+    const double multiplier = reverse ? -1.0 : 1.0;
+    position->pot = multiplier * potentiometer_translate(
+                                     encoder.ReadPotentiometerVoltage()) +
+                    pot_offset;
+    position->encoder =
+        multiplier * encoder_translate(encoder.ReadRelativeEncoder(),
+                                       encoder_counts_per_revolution,
+                                       encoder_ratio);
+
+    position->absolute_encoder =
+        (reverse ? (1.0 - encoder.ReadAbsoluteEncoder())
+                 : encoder.ReadAbsoluteEncoder()) *
+        encoder_ratio * (2.0 * M_PI);
+  }
+
+  int32_t my_pid_;
+  DriverStation *ds_;
+
+  // Mutex to manage access to the period and tick time variables.
+  ::aos::stl_mutex tick_time_mutex_;
+  monotonic_clock::time_point last_tick_time_monotonic_timepoint_ =
+      monotonic_clock::min_time;
+  chrono::nanoseconds last_period_ = chrono::microseconds(5050);
+
+  ::std::unique_ptr<::frc971::wpilib::DMASynchronizer> dma_synchronizer_;
+
+  DigitalGlitchFilter fast_encoder_filter_, medium_encoder_filter_,
+      hall_filter_;
+
+  ::std::unique_ptr<Encoder> drivetrain_left_encoder_,
+      drivetrain_right_encoder_;
+
+  ::std::unique_ptr<AnalogInput> left_drivetrain_shifter_,
+      right_drivetrain_shifter_;
+
+  ::frc971::wpilib::AbsoluteEncoderAndPotentiometer proximal_encoder_,
+      distal_encoder_;
+
+  ::frc971::wpilib::AbsoluteEncoderAndPotentiometer left_intake_encoder_,
+      right_intake_encoder_;
+
+  ::std::unique_ptr<AnalogInput> left_intake_spring_angle_,
+      right_intake_spring_angle_;
+  ::std::unique_ptr<DigitalInput> left_intake_cube_detector_,
+      right_intake_cube_detector_;
+
+  ::std::unique_ptr<DigitalInput> pwm_trigger_;
+
+  ::std::array<::std::unique_ptr<DigitalInput>, 4> autonomous_modes_;
+
+  ::std::atomic<bool> run_{true};
+};
+
+class SolenoidWriter {
+ public:
+  SolenoidWriter(::frc971::wpilib::BufferedPcm *pcm)
+      : pcm_(pcm),
+        drivetrain_(".frc971.control_loops.drivetrain_queue.output"),
+        superstructure_(".y2018.control_loops.superstructure_queue.output") {}
+
+  // left drive
+  // right drive
+  //
+  // claw
+  // arm brakes
+  // hook release
+  // fork release
+  void set_left_drivetrain_shifter(
+      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    left_drivetrain_shifter_ = ::std::move(s);
+  }
+  void set_right_drivetrain_shifter(
+      ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    right_drivetrain_shifter_ = ::std::move(s);
+  }
+
+  void set_claw(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    claw_ = ::std::move(s);
+  }
+
+  void set_arm_brakes(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    arm_brakes_ = ::std::move(s);
+  }
+
+  void set_hook(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    hook_ = ::std::move(s);
+  }
+
+  void set_forks(::std::unique_ptr<::frc971::wpilib::BufferedSolenoid> s) {
+    forks_ = ::std::move(s);
+  }
+
+  void operator()() {
+    ::aos::SetCurrentThreadName("Solenoids");
+    ::aos::SetCurrentThreadRealtimePriority(27);
+
+    ::aos::time::PhasedLoop phased_loop(::std::chrono::milliseconds(20),
+                                        ::std::chrono::milliseconds(1));
+
+    while (run_) {
+      {
+        const int iterations = phased_loop.SleepUntilNext();
+        if (iterations != 1) {
+          LOG(DEBUG, "Solenoids skipped %d iterations\n", iterations - 1);
+        }
+      }
+
+      {
+        drivetrain_.FetchLatest();
+        if (drivetrain_.get()) {
+          LOG_STRUCT(DEBUG, "solenoids", *drivetrain_);
+          left_drivetrain_shifter_->Set(!drivetrain_->left_high);
+          right_drivetrain_shifter_->Set(!drivetrain_->right_high);
+        }
+      }
+
+      {
+        superstructure_.FetchLatest();
+        if (superstructure_.get()) {
+          LOG_STRUCT(DEBUG, "solenoids", *superstructure_);
+
+          claw_->Set(superstructure_->claw_grabbed);
+          arm_brakes_->Set(superstructure_->release_arm_brake);
+          hook_->Set(superstructure_->hook_release);
+          forks_->Set(superstructure_->forks_release);
+        }
+      }
+
+      {
+        ::frc971::wpilib::PneumaticsToLog to_log;
+
+        pcm_->Flush();
+        to_log.read_solenoids = pcm_->GetAll();
+        LOG_STRUCT(DEBUG, "pneumatics info", to_log);
+      }
+    }
+  }
+
+  void Quit() { run_ = false; }
+
+ private:
+  ::frc971::wpilib::BufferedPcm *pcm_;
+
+  ::std::unique_ptr<::frc971::wpilib::BufferedSolenoid>
+      left_drivetrain_shifter_, right_drivetrain_shifter_, claw_, arm_brakes_,
+      hook_, forks_;
+
+  ::aos::Queue<::frc971::control_loops::DrivetrainQueue::Output> drivetrain_;
+  ::aos::Queue<::y2018::control_loops::SuperstructureQueue::Output>
+      superstructure_;
+
+  ::std::atomic<bool> run_{true};
+};
+
+class DrivetrainWriter : public ::frc971::wpilib::LoopOutputHandler {
+ public:
+  void set_drivetrain_left_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    drivetrain_left_victor_ = ::std::move(t);
+  }
+
+  void set_drivetrain_right_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    drivetrain_right_victor_ = ::std::move(t);
+  }
+
+ private:
+  virtual void Read() override {
+    ::frc971::control_loops::drivetrain_queue.output.FetchAnother();
+  }
+
+  virtual void Write() override {
+    auto &queue = ::frc971::control_loops::drivetrain_queue.output;
+    LOG_STRUCT(DEBUG, "will output", *queue);
+    drivetrain_left_victor_->SetSpeed(-queue->left_voltage / 12.0);
+    drivetrain_right_victor_->SetSpeed(queue->right_voltage / 12.0);
+  }
+
+  virtual void Stop() override {
+    LOG(WARNING, "drivetrain output too old\n");
+    drivetrain_left_victor_->SetDisabled();
+    drivetrain_right_victor_->SetDisabled();
+  }
+
+  ::std::unique_ptr<::frc::VictorSP> drivetrain_left_victor_,
+      drivetrain_right_victor_;
+};
+
+class SuperstructureWriter : public ::frc971::wpilib::LoopOutputHandler {
+ public:
+  void set_proximal_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    proximal_victor_ = ::std::move(t);
+  }
+  void set_distal_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    distal_victor_ = ::std::move(t);
+  }
+
+  void set_left_intake_elastic_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    left_intake_elastic_victor_ = ::std::move(t);
+  }
+  void set_right_intake_elastic_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    right_intake_elastic_victor_ = ::std::move(t);
+  }
+
+  void set_left_intake_rollers_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    left_intake_rollers_victor_ = ::std::move(t);
+  }
+
+  void set_right_intake_rollers_victor(::std::unique_ptr<::frc::VictorSP> t) {
+    right_intake_rollers_victor_ = ::std::move(t);
+  }
+
+ private:
+  virtual void Read() override {
+    ::y2018::control_loops::superstructure_queue.output.FetchAnother();
+  }
+
+  virtual void Write() override {
+    auto &queue = ::y2018::control_loops::superstructure_queue.output;
+    LOG_STRUCT(DEBUG, "will output", *queue);
+
+    left_intake_elastic_victor_->SetSpeed(
+        ::aos::Clip(queue->intake.left.voltage_elastic, -kMaxBringupPower,
+                    kMaxBringupPower) /
+        12.0);
+
+    right_intake_elastic_victor_->SetSpeed(
+        ::aos::Clip(queue->intake.right.voltage_elastic, -kMaxBringupPower,
+                    kMaxBringupPower) /
+        12.0);
+
+    left_intake_rollers_victor_->SetSpeed(
+        ::aos::Clip(queue->intake.right.voltage_rollers, -kMaxBringupPower,
+                    kMaxBringupPower) /
+        12.0);
+
+    right_intake_rollers_victor_->SetSpeed(
+        ::aos::Clip(queue->intake.right.voltage_rollers, -kMaxBringupPower,
+                    kMaxBringupPower) /
+        12.0);
+
+    proximal_victor_->SetSpeed(::aos::Clip(queue->voltage_proximal,
+                                           -kMaxBringupPower,
+                                           kMaxBringupPower) /
+                               12.0);
+
+    distal_victor_->SetSpeed(::aos::Clip(queue->voltage_distal,
+                                         -kMaxBringupPower, kMaxBringupPower) /
+                             12.0);
+  }
+
+  virtual void Stop() override {
+    LOG(WARNING, "Superstructure output too old.\n");
+
+    left_intake_rollers_victor_->SetDisabled();
+    right_intake_rollers_victor_->SetDisabled();
+    left_intake_elastic_victor_->SetDisabled();
+    right_intake_elastic_victor_->SetDisabled();
+
+    proximal_victor_->SetDisabled();
+    distal_victor_->SetDisabled();
+  }
+
+  ::std::unique_ptr<::frc::VictorSP> left_intake_rollers_victor_,
+      right_intake_rollers_victor_, left_intake_elastic_victor_,
+      right_intake_elastic_victor_, proximal_victor_, distal_victor_;
+};
+
+class WPILibRobot : public ::frc971::wpilib::WPILibRobotBase {
+ public:
+  ::std::unique_ptr<Encoder> make_encoder(int index) {
+    return make_unique<Encoder>(10 + index * 2, 11 + index * 2, false,
+                                Encoder::k4X);
+  }
+
+  void Run() override {
+    ::aos::InitNRT();
+    ::aos::SetCurrentThreadName("StartCompetition");
+
+    ::frc971::wpilib::JoystickSender joystick_sender;
+    ::std::thread joystick_thread(::std::ref(joystick_sender));
+
+    ::frc971::wpilib::PDPFetcher pdp_fetcher;
+    ::std::thread pdp_fetcher_thread(::std::ref(pdp_fetcher));
+    SensorReader reader;
+
+    // TODO(Sabina): Update port numbers(Sensors and Victors)
+    reader.set_drivetrain_left_encoder(make_encoder(0));
+    reader.set_drivetrain_right_encoder(make_encoder(1));
+
+    reader.set_proximal_encoder(make_encoder(2));
+    reader.set_proximal_absolute_pwm(make_unique<DigitalInput>(2));
+    reader.set_proximal_potentiometer(make_unique<AnalogInput>(2));
+
+    reader.set_distal_encoder(make_encoder(3));
+    reader.set_distal_absolute_pwm(make_unique<DigitalInput>(3));
+    reader.set_distal_potentiometer(make_unique<AnalogInput>(3));
+
+    reader.set_right_intake_encoder(make_encoder(4));
+    reader.set_right_intake_absolute_pwm(make_unique<DigitalInput>(4));
+    reader.set_right_intake_potentiometer(make_unique<AnalogInput>(4));
+    reader.set_right_intake_cube_detector(make_unique<DigitalInput>(6));
+
+    reader.set_left_intake_encoder(make_encoder(5));
+    reader.set_left_intake_absolute_pwm(make_unique<DigitalInput>(5));
+    reader.set_left_intake_potentiometer(make_unique<AnalogInput>(5));
+    reader.set_left_intake_cube_detector(make_unique<DigitalInput>(7));
+
+    reader.set_autonomous_mode(0, make_unique<DigitalInput>(9));
+    reader.set_autonomous_mode(1, make_unique<DigitalInput>(8));
+
+    reader.set_pwm_trigger(make_unique<DigitalInput>(0));
+
+    reader.set_dma(make_unique<DMA>());
+    ::std::thread reader_thread(::std::ref(reader));
+
+    auto imu_trigger = make_unique<DigitalInput>(3);
+    ::frc971::wpilib::ADIS16448 imu(SPI::Port::kOnboardCS1, imu_trigger.get());
+    imu.SetDummySPI(SPI::Port::kOnboardCS2);
+    auto imu_reset = make_unique<DigitalOutput>(6);
+    imu.set_reset(imu_reset.get());
+    ::std::thread imu_thread(::std::ref(imu));
+
+// While as of 2/9/18 the drivetrain Victors are SPX, it appears as though they
+// are identical, as far as DrivetrainWriter is concerned, to the SP variety
+// so all the Victors are written as SPs.
+
+    DrivetrainWriter drivetrain_writer;
+    drivetrain_writer.set_drivetrain_left_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(7)));
+    drivetrain_writer.set_drivetrain_right_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(3)));
+    ::std::thread drivetrain_writer_thread(::std::ref(drivetrain_writer));
+
+    SuperstructureWriter superstructure_writer;
+    superstructure_writer.set_left_intake_elastic_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(1)));
+    superstructure_writer.set_right_intake_elastic_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(4)));
+    superstructure_writer.set_right_intake_rollers_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(6)));
+    superstructure_writer.set_left_intake_rollers_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(5)));
+    superstructure_writer.set_proximal_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(9)));
+    superstructure_writer.set_distal_victor(
+        ::std::unique_ptr<::frc::VictorSP>(new ::frc::VictorSP(8)));
+
+    ::std::thread superstructure_writer_thread(
+        ::std::ref(superstructure_writer));
+
+    ::frc971::wpilib::BufferedPcm *pcm = new ::frc971::wpilib::BufferedPcm();
+    SolenoidWriter solenoid_writer(pcm);
+    solenoid_writer.set_left_drivetrain_shifter(pcm->MakeSolenoid(0));
+    solenoid_writer.set_right_drivetrain_shifter(pcm->MakeSolenoid(1));
+    solenoid_writer.set_claw(pcm->MakeSolenoid(2));
+    solenoid_writer.set_arm_brakes(pcm->MakeSolenoid(3));
+    solenoid_writer.set_hook(pcm->MakeSolenoid(4));
+    solenoid_writer.set_forks(pcm->MakeSolenoid(5));
+
+    ::std::thread solenoid_thread(::std::ref(solenoid_writer));
+
+    // Wait forever. Not much else to do...
+    while (true) {
+      const int r = select(0, nullptr, nullptr, nullptr, nullptr);
+      if (r != 0) {
+        PLOG(WARNING, "infinite select failed");
+      } else {
+        PLOG(WARNING, "infinite select succeeded??\n");
+      }
+    }
+
+    LOG(ERROR, "Exiting WPILibRobot\n");
+
+    joystick_sender.Quit();
+    joystick_thread.join();
+    pdp_fetcher.Quit();
+    pdp_fetcher_thread.join();
+    reader.Quit();
+    reader_thread.join();
+    imu.Quit();
+    imu_thread.join();
+
+    drivetrain_writer.Quit();
+    drivetrain_writer_thread.join();
+    superstructure_writer.Quit();
+    superstructure_writer_thread.join();
+
+    ::aos::Cleanup();
+  }
+};
+
+}  // namespace
+}  // namespace wpilib
+}  // namespace y2018
+
+AOS_ROBOT_CLASS(::y2018::wpilib::WPILibRobot);
