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) {
diff --git a/frc971/control_loops/drivetrain/drivetrain.q b/frc971/control_loops/drivetrain/drivetrain.q
index f56c115..2085eb8 100644
--- a/frc971/control_loops/drivetrain/drivetrain.q
+++ b/frc971/control_loops/drivetrain/drivetrain.q
@@ -12,7 +12,9 @@
     bool quickturn;
     bool control_loop_driving;
     float left_goal;
+    float left_velocity_goal;
     float right_goal;
+    float right_velocity_goal;
   };
 
   message Position {
diff --git a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
index 75a8b8f..d15de44 100644
--- a/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_lib_test.cc
@@ -39,7 +39,7 @@
   void Reinitialize() {
     drivetrain_plant_->X(0, 0) = 0.0;
     drivetrain_plant_->X(1, 0) = 0.0;
-    drivetrain_plant_->Y = drivetrain_plant_->C * drivetrain_plant_->X;
+    drivetrain_plant_->Y = drivetrain_plant_->C() * drivetrain_plant_->X;
     last_left_position_ = drivetrain_plant_->Y(0, 0);
     last_right_position_ = drivetrain_plant_->Y(1, 0);
   }
diff --git a/frc971/control_loops/drivetrain/drivetrain_motor_plant.cc b/frc971/control_loops/drivetrain/drivetrain_motor_plant.cc
index d4edba8..e543c9f 100644
--- a/frc971/control_loops/drivetrain/drivetrain_motor_plant.cc
+++ b/frc971/control_loops/drivetrain/drivetrain_motor_plant.cc
@@ -1,16 +1,17 @@
 #include "frc971/control_loops/drivetrain/drivetrain_motor_plant.h"
 
+#include <vector>
+
 #include "frc971/control_loops/state_feedback_loop.h"
 
 namespace frc971 {
 namespace control_loops {
 
-
-StateFeedbackPlant<4, 2, 2> MakeDrivetrainPlant() {
+StateFeedbackPlantCoefficients<4, 2, 2> MakeDrivetrainPlantCoefficients() {
   Eigen::Matrix<double, 4, 4> A;
-  A << 1.0, 0.0081841122497, 0.0, -5.9473473594e-05, 0.0, 0.660289401132, 0.0, -0.0103071702002, 0.0, -5.9473473594e-05, 1.0, 0.0081841122497, 0.0, -0.0103071702002, 0.0, 0.660289401132;
+  A << 1.0, 0.00931379160739, 0.0, 4.70184876909e-06, 0.0, 0.865971883056, 0.0, 0.000895808426591, 0.0, 4.70184876909e-06, 1.0, 0.00931379160739, 0.0, 0.000895808426591, 0.0, 0.865971883056;
   Eigen::Matrix<double, 4, 2> B;
-  B << 0.000333031510271, 1.09073596255e-05, 0.0623024929693, 0.00189032194188, 1.09073596255e-05, 0.000333031510271, 0.00189032194188, 0.0623024929693;
+  B << 0.000126707931029, -8.6819330098e-07, 0.0247482041615, -0.000165410440259, -8.6819330098e-07, 0.000126707931029, -0.000165410440259, 0.0247482041615;
   Eigen::Matrix<double, 2, 4> C;
   C << 1, 0, 0, 0, 0, 0, 1, 0;
   Eigen::Matrix<double, 2, 2> D;
@@ -19,16 +20,28 @@
   U_max << 12.0, 12.0;
   Eigen::Matrix<double, 2, 1> U_min;
   U_min << -12.0, -12.0;
-  return StateFeedbackPlant<4, 2, 2>(A, B, C, D, U_max, U_min);
+  return StateFeedbackPlantCoefficients<4, 2, 2>(A, B, C, D, U_max, U_min);
+}
+
+StateFeedbackController<4, 2, 2> MakeDrivetrainController() {
+  Eigen::Matrix<double, 4, 2> L;
+  L << 1.70597188306, 0.000895808426591, 66.3158545945, 0.117712892743, 0.000895808426591, 1.70597188306, 0.117712892743, 66.3158545945;
+  Eigen::Matrix<double, 2, 4> K;
+  K << 240.432225842, 14.3659115621, 1.60698530163, 0.13242189318, 1.60698530163, 0.13242189318, 240.432225842, 14.3659115621;
+  return StateFeedbackController<4, 2, 2>(L, K, MakeDrivetrainPlantCoefficients());
+}
+
+StateFeedbackPlant<4, 2, 2> MakeDrivetrainPlant() {
+  ::std::vector<StateFeedbackPlantCoefficients<4, 2, 2> *> plants(1);
+  plants[0] = new StateFeedbackPlantCoefficients<4, 2, 2>(MakeDrivetrainPlantCoefficients());
+  return StateFeedbackPlant<4, 2, 2>(plants);
 }
 
 StateFeedbackLoop<4, 2, 2> MakeDrivetrainLoop() {
-  Eigen::Matrix<double, 4, 2> L;
-  L << 1.50028940113, -0.0103071702002, 41.1373728147, -1.1627040905, -0.0103071702002, 1.50028940113, -1.1627040905, 41.1373728147;
-  Eigen::Matrix<double, 2, 4> K;
-  K << 48.196534943, -0.087263189034, -1.46233261597, -0.163410937407, -1.46233261597, -0.163410937407, 48.196534943, -0.087263189034;
-  return StateFeedbackLoop<4, 2, 2>(L, K, MakeDrivetrainPlant());
+  ::std::vector<StateFeedbackController<4, 2, 2> *> controllers(1);
+  controllers[0] = new StateFeedbackController<4, 2, 2>(MakeDrivetrainController());
+  return StateFeedbackLoop<4, 2, 2>(controllers);
 }
 
-}  // namespace frc971
 }  // namespace control_loops
+}  // namespace frc971
diff --git a/frc971/control_loops/drivetrain/drivetrain_motor_plant.h b/frc971/control_loops/drivetrain/drivetrain_motor_plant.h
index af43b46..2060b6f 100644
--- a/frc971/control_loops/drivetrain/drivetrain_motor_plant.h
+++ b/frc971/control_loops/drivetrain/drivetrain_motor_plant.h
@@ -6,11 +6,15 @@
 namespace frc971 {
 namespace control_loops {
 
+StateFeedbackPlantCoefficients<4, 2, 2> MakeDrivetrainPlantCoefficients();
+
+StateFeedbackController<4, 2, 2> MakeDrivetrainController();
+
 StateFeedbackPlant<4, 2, 2> MakeDrivetrainPlant();
 
 StateFeedbackLoop<4, 2, 2> MakeDrivetrainLoop();
 
-}  // namespace frc971
 }  // namespace control_loops
+}  // namespace frc971
 
 #endif  // FRC971_CONTROL_LOOPS_DRIVETRAIN_DRIVETRAIN_MOTOR_PLANT_H_