made sure everything's thread safe

Pretty much everything already was, but I tweaked a few things to make
sure they stay that way and added various comments about that fact. Also
cleaned up a few things along the way and removed SafeMessageBuilder
because it wasn't.
diff --git a/aos/prime/input/joystick_input.cc b/aos/prime/input/joystick_input.cc
index 6a6606e..7e2f0cd 100644
--- a/aos/prime/input/joystick_input.cc
+++ b/aos/prime/input/joystick_input.cc
@@ -70,7 +70,8 @@
           }
         }
       }
-
+    }
+    {
       using driver_station::ControlBit;
       if (data.PosEdge(ControlBit::kFmsAttached)) {
         LOG(INFO, "PosEdge(kFmsAttached)\n");
diff --git a/aos/prime/output/motor_output.cc b/aos/prime/output/motor_output.cc
index c02a11b..b6d59e2 100644
--- a/aos/prime/output/motor_output.cc
+++ b/aos/prime/output/motor_output.cc
@@ -51,6 +51,10 @@
     time::PhasedLoopXMS(5, 1000);
     ::aos::time::Time::UpdateMockTime();
 
+    no_robot_state_.Print();
+    fake_robot_state_.Print();
+    sending_failed_.Print();
+
     values_.digital_module = -1;
     // 0 means output disabled.
     memset(&values_.pwm_outputs, 0x00, sizeof(values_.pwm_outputs));
@@ -63,8 +67,12 @@
     RunIteration();
 
     ::aos::robot_state.FetchLatest();
-    if (!::aos::robot_state.get() || ::aos::robot_state->fake) {
-      LOG(DEBUG, "fake robot state -> not outputting\n");
+    if (!::aos::robot_state.get()) {
+      LOG_INTERVAL(no_robot_state_);
+      continue;
+    }
+    if (::aos::robot_state->fake) {
+      LOG_INTERVAL(fake_robot_state_);
       continue;
     }
 
@@ -75,7 +83,7 @@
       continue;
     }
     if (socket_.Send(buffer, size) != size) {
-      LOG(WARNING, "sending outputs failed\n");
+      LOG_INTERVAL(sending_failed_);
       continue;
     } else {
       LOG(DEBUG, "sent outputs\n");
diff --git a/aos/prime/output/motor_output.h b/aos/prime/output/motor_output.h
index 8c613e9..7d856bc 100644
--- a/aos/prime/output/motor_output.h
+++ b/aos/prime/output/motor_output.h
@@ -10,12 +10,13 @@
 #include "aos/common/network/send_socket.h"
 #include "aos/common/byteorder.h"
 #include "aos/common/type_traits.h"
+#include "aos/common/util/log_interval.h"
 
 namespace aos {
 
 // A class for sending output values to a cRIO.
 // values_ gets completely reset each time through, so RunIteration() needs to
-// set everything each time.
+// set everything each time (except solenoids).
 class MotorOutput {
  public:
   MotorOutput();
@@ -51,7 +52,7 @@
   void SetSolenoid(uint8_t channel, bool set);
   void SetPWMOutput(uint8_t channel, double value,
                     const MotorControllerBounds &bounds);
-  void SetRawPWMOutput(uint8_t cahnnel, uint8_t value);
+  void SetRawPWMOutput(uint8_t channel, uint8_t value);
   void DisablePWMOutput(uint8_t channel);
   void SetDigitalOutput(uint8_t channel, bool value);
 
@@ -65,6 +66,16 @@
   virtual void RunIteration() = 0;
 
   network::SendSocket socket_;
+
+  util::SimpleLogInterval no_robot_state_ =
+      util::SimpleLogInterval(::aos::time::Time::InSeconds(0.5), INFO,
+                        "no robot state -> not outputting");
+  util::SimpleLogInterval fake_robot_state_ =
+      util::SimpleLogInterval(::aos::time::Time::InSeconds(0.5), DEBUG,
+                        "fake robot state -> not outputting");
+  util::SimpleLogInterval sending_failed_ =
+      util::SimpleLogInterval(::aos::time::Time::InSeconds(0.1), WARNING,
+                        "sending outputs failed");
 };
 
 }  // namespace aos
diff --git a/aos/prime/output/output.gyp b/aos/prime/output/output.gyp
index 20fe699..1fadff0 100644
--- a/aos/prime/output/output.gyp
+++ b/aos/prime/output/output.gyp
@@ -12,10 +12,12 @@
         '<(EXTERNALS):WPILib-NetworkRobotValues',
         '<(AOS)/build/aos.gyp:logging',
         '<(AOS)/common/messages/messages.gyp:robot_state',
+        '<(AOS)/common/util/util.gyp:log_interval',
       ],
       'export_dependent_settings': [
         '<(AOS)/common/network/network.gyp:socket',
         '<(EXTERNALS):WPILib-NetworkRobotValues',
+        '<(AOS)/common/util/util.gyp:log_interval',
       ],
     },
     {