Add support for robots without DMA.

DMA now won't loop if you don't have a dma device.

Change-Id: I8bbb4a2e44dede031f96974b7bc5c7c86889b985
diff --git a/frc971/wpilib/sensor_reader.cc b/frc971/wpilib/sensor_reader.cc
index dc33698..f5372bf 100644
--- a/frc971/wpilib/sensor_reader.cc
+++ b/frc971/wpilib/sensor_reader.cc
@@ -42,15 +42,6 @@
   drivetrain_right_encoder_->SetMaxPeriod(0.005);
 }
 
-// All of the DMA-related set_* calls must be made before this, and it
-// doesn't hurt to do all of them.
-// TODO(austin): Does anyone actually do anything other than set this?  Or can
-// we just take care of that automatically?
-void SensorReader::set_dma(::std::unique_ptr<DMA> dma) {
-  dma_synchronizer_.reset(
-      new ::frc971::wpilib::DMASynchronizer(::std::move(dma)));
-}
-
 void SensorReader::set_pwm_trigger(
     ::std::unique_ptr<frc::DigitalInput> pwm_trigger) {
   fast_encoder_filter_.Add(pwm_trigger.get());
@@ -130,7 +121,9 @@
   int32_t my_pid = getpid();
 
   Start();
-  dma_synchronizer_->Start();
+  if (dma_synchronizer_) {
+    dma_synchronizer_->Start();
+  }
 
   if (pwm_trigger_) {
     last_period_ = chrono::microseconds(5050);
@@ -160,8 +153,10 @@
 
     ::frc971::wpilib::SendRobotState(my_pid);
     RunIteration();
-    dma_synchronizer_->RunIteration();
-    RunDmaIteration();
+    if (dma_synchronizer_) {
+      dma_synchronizer_->RunIteration();
+      RunDmaIteration();
+    }
 
     if (pwm_trigger_) {
       monotonic_clock::time_point last_tick_timepoint;
diff --git a/frc971/wpilib/sensor_reader.h b/frc971/wpilib/sensor_reader.h
index fb25360..dc34e1c 100644
--- a/frc971/wpilib/sensor_reader.h
+++ b/frc971/wpilib/sensor_reader.h
@@ -34,10 +34,12 @@
   // Sets the right drivetrain encoder.
   void set_drivetrain_right_encoder(::std::unique_ptr<frc::Encoder> encoder);
 
-  // Sets the dma.
-  void set_dma(::std::unique_ptr<DMA> dma);
-
+  // Adds a sensor to DMA.
   void AddToDMA(DMASampleHandlerInterface *handler) {
+    if (!dma_synchronizer_) {
+      dma_synchronizer_.reset(
+          new ::frc971::wpilib::DMASynchronizer(std::make_unique<DMA>()));
+    }
     dma_synchronizer_->Add(handler);
   }
 
@@ -48,6 +50,8 @@
   void Quit() { run_ = false; }
 
   virtual void RunIteration() = 0;
+  // Runs the DMA iteration after the synchronizer.  This only gets run if a
+  // sensor has been added to DMA.
   virtual void RunDmaIteration() {}
 
   void operator()();