added button edge logging + cleaned up various naming and comments
diff --git a/aos/atom_code/input/joystick_input.cc b/aos/atom_code/input/joystick_input.cc
index 01bcbc6..3c66606 100644
--- a/aos/atom_code/input/joystick_input.cc
+++ b/aos/atom_code/input/joystick_input.cc
@@ -46,7 +46,23 @@
     }
 
     data.Update(joysticks);
-    // TODO(brians): posedge/negedge logging
+
+    {
+      using driver_station::JoystickFeature;
+      using driver_station::ButtonLocation;
+      for (int joystick = 0; joystick < JoystickFeature::kJoysticks;
+           ++joystick) {
+        for (int button = 0; button < ButtonLocation::kButtons; ++button) {
+          ButtonLocation location(joystick, button);
+          if (data.PosEdge(location)) {
+            LOG(INFO, "PosEdge(%d, %d)\n", joystick, button);
+          }
+          if (data.NegEdge(location)) {
+            LOG(INFO, "NegEdge(%d, %d)\n", joystick, button);
+          }
+        }
+      }
+    }
 
     RunIteration(data);
   }
diff --git a/aos/atom_code/input/joystick_input.h b/aos/atom_code/input/joystick_input.h
index d905eaa..de0ed9e 100644
--- a/aos/atom_code/input/joystick_input.h
+++ b/aos/atom_code/input/joystick_input.h
@@ -6,11 +6,17 @@
 namespace aos {
 namespace input {
 
+// A class for handling joystick packet values.
+// It will call RunIteration each time a new packet is received.
+//
+// This class automatically handles updating ::aos::robot_state and logging (at
+// INFO) button edges.
 class JoystickInput {
  public:
   void Run();
 
  private:
+  // Subclasses should do whatever they want with data here.
   virtual void RunIteration(const driver_station::Data &data) = 0;
 };
 
diff --git a/aos/atom_code/output/motor_output.cc b/aos/atom_code/output/motor_output.cc
index b24204b..2a92437 100644
--- a/aos/atom_code/output/motor_output.cc
+++ b/aos/atom_code/output/motor_output.cc
@@ -63,6 +63,8 @@
 void MotorOutput::SetSolenoid(uint8_t channel, bool set) {
   if (set) {
     values_.solenoid_values |= 1 << (channel - 1);
+  } else {
+    values_.solenoid_values &= ~(1 << (channel - 1));
   }
 }
 
@@ -80,6 +82,8 @@
   values_.digital_output_enables |= 1 << shift_amount;
   if (value) {
     values_.digital_output_values |= 1 << shift_amount;
+  } else {
+    values_.digital_output_values &= ~(1 << shift_amount);
   }
 }
 
diff --git a/aos/atom_code/output/motor_output.h b/aos/atom_code/output/motor_output.h
index 73648ce..8828f14 100644
--- a/aos/atom_code/output/motor_output.h
+++ b/aos/atom_code/output/motor_output.h
@@ -52,7 +52,7 @@
   void DisablePWMOutput(uint8_t channel);
   void SetDigitalOutput(uint8_t channel, bool value);
 
-  // The struct that's going to get sent over.
+  // The data that's going to get sent over.
   // Gets reset (everything set so that it won't do anything) each time through.
   NetworkRobotMotors values_;