Drivetrain is now tuned.  Quite stiff.
diff --git a/frc971/control_loops/drivetrain/drivetrain.cc b/frc971/control_loops/drivetrain/drivetrain.cc
index 63e6718..79e2864 100644
--- a/frc971/control_loops/drivetrain/drivetrain.cc
+++ b/frc971/control_loops/drivetrain/drivetrain.cc
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <sched.h>
 #include <cmath>
+#include <memory>
 
 #include "aos/aos_core.h"
 #include "aos/common/logging/logging.h"
@@ -21,72 +22,61 @@
 // Width of the robot.
 const double width = 22.0 / 100.0 * 2.54;
 
-class DrivetrainMotorsSS : public StateFeedbackLoop<4, 2, 2> {
+class DrivetrainMotorsSS {
  public:
-  DrivetrainMotorsSS (void)
-      : StateFeedbackLoop(MakeDrivetrainLoop()) {
+  DrivetrainMotorsSS ()
+      : loop_(new StateFeedbackLoop<4, 2, 2>(MakeDrivetrainLoop())) {
     _offset = 0;
     _integral_offset = 0;
     _left_goal = 0.0;
     _right_goal = 0.0;
     _raw_left = 0.0;
     _raw_right = 0.0;
+    _control_loop_driving = false;
   }
   void SetGoal(double left, double left_velocity, double right, double right_velocity) {
     _left_goal = left;
     _right_goal = right;
-    R << left + _integral_offset * width / 2.0, left_velocity, right - _integral_offset * width / 2.0, right_velocity;
+    loop_->R << left, left_velocity, right, right_velocity;
   }
   void SetRawPosition(double left, double right) {
     _raw_right = right;
     _raw_left = left;
-    Y << left + _offset + _integral_offset, right - _offset + _integral_offset;
+    loop_->Y << left, right;
   }
-  void SetPosition(double left, double right, double gyro, bool control_loop_driving) {
+  void SetPosition(
+      double left, double right, double gyro, bool control_loop_driving) {
     // Decay the offset quickly because this gyro is great.
     _offset = (0.25) * (right - left - gyro * width) / 2.0 + 0.75 * _offset;
     const double angle_error = (_right_goal - _left_goal) / width - (_raw_right - _offset - _raw_left - _offset) / width;
-    if (!control_loop_driving) {
-      _integral_offset = 0.0;
-    } else if (::std::abs(angle_error) < M_PI / 10.0) {
-      _integral_offset -= angle_error * 0.010;
-    } else {
-      _integral_offset *= 0.97;
-    }
+    // TODO(aschuh): Add in the gyro.
+    _integral_offset = 0.0;
+    _offset = 0.0;
     _gyro = gyro;
+    _control_loop_driving = control_loop_driving;
     SetRawPosition(left, right);
     LOG(DEBUG, "Left %f->%f Right %f->%f Gyro %f aerror %f ioff %f\n", left + _offset, _left_goal, right - _offset, _right_goal, gyro, angle_error, _integral_offset);
   }
-  double UnDeadband(double value) {
-    const double positive_deadband_power = 0.15 * 12;
-    const double negative_deadband_power = 0.09 * 12;
-    if (value > 0) {
-      value += positive_deadband_power;
-    }
-    if (value < 0) {
-      value -= negative_deadband_power;
-    }
-    if (value > 12.0) {
-      value = 12.0;
-    }
-    if (value < -12.0) {
-      value = -12.0;
-    }
-    return value;
+
+  void Update(bool update_observer, bool stop_motors) {
+    loop_->Update(update_observer, stop_motors);
   }
 
-  void SendMotors(Drivetrain::Output *status) {
-    if (status) {
-      status->left_voltage = UnDeadband(U[0]);
-      status->right_voltage = UnDeadband(U[1]);
+  void SendMotors(Drivetrain::Output *output) {
+    if (output) {
+      output->left_voltage = loop_->U(0, 0);
+      output->right_voltage = loop_->U(1, 0);
     }
   }
   void PrintMotors() const {
     // LOG(DEBUG, "Left Power %f Right Power %f lg %f rg %f le %f re %f gyro %f\n", U[0], U[1], R[0], R[2], Y[0], Y[1], _gyro);
-    LOG(DEBUG, "lg %f rg %f le %f re %f gyro %f off %f\n", R[0], R[2], Y[0], Y[1], _gyro * 180.0 / M_PI, _offset);
+    ::Eigen::Matrix<double, 4, 1> E = loop_->R - loop_->X_hat;
+    LOG(DEBUG, "E[0, 0]: %f E[1, 0] %f E[2, 0] %f E[3, 0] %f\n", E(0, 0), E(1, 0), E(2, 0), E(3, 0));
   }
 
  private:
+  ::std::unique_ptr<StateFeedbackLoop<4, 2, 2>> loop_;
+
   double _integral_offset;
   double _offset;
   double _gyro;
@@ -94,6 +84,7 @@
   double _right_goal;
   double _raw_left;
   double _raw_right;
+  bool _control_loop_driving;
 };
 
 class DrivetrainMotorsOL {
@@ -273,7 +264,8 @@
   double left_goal = goal->left_goal;
   double right_goal = goal->right_goal;
 
-  dt_closedloop.SetGoal(left_goal, 0.0, right_goal, 0.0);
+  dt_closedloop.SetGoal(left_goal, goal->left_velocity_goal,
+                        right_goal, goal->right_velocity_goal);
   if (!bad_pos) {
     const double left_encoder = position->left_encoder;
     const double right_encoder = position->right_encoder;
@@ -284,7 +276,8 @@
       dt_closedloop.SetRawPosition(left_encoder, right_encoder);
     }
   }
-  dt_closedloop.Update(!bad_pos, bad_pos || bad_output);
+  dt_closedloop.Update(position, output == NULL);
+  //dt_closedloop.PrintMotors();
   dt_openloop.SetGoal(wheel, throttle, quickturn, highgear);
   dt_openloop.Update();
   if (control_loop_driving) {