Added POV to joysticks.

Change-Id: Iad0ea8ed1526a6173502f3f0a9bc8918f0569adc
diff --git a/aos/common/input/driver_station_data.cc b/aos/common/input/driver_station_data.cc
index f825bd4..00a126e 100644
--- a/aos/common/input/driver_station_data.cc
+++ b/aos/common/input/driver_station_data.cc
@@ -19,6 +19,10 @@
       (1 << (location.number() - 1));
 }
 
+bool GetPOV(const POVLocation location, const JoystickState &values) {
+  return values.joysticks[location.joystick() - 1].pov == location.number();
+}
+
 bool GetControlBitValue(const ControlBit bit,
                         const JoystickState &values) {
   switch (bit) {
@@ -51,6 +55,18 @@
       !GetButton(location, current_values_);
 }
 
+bool Data::IsPressed(const POVLocation location) const {
+  return GetPOV(location, current_values_);
+}
+
+bool Data::PosEdge(const POVLocation location) const {
+  return !GetPOV(location, old_values_) && GetPOV(location, current_values_);
+}
+
+bool Data::NegEdge(const POVLocation location) const {
+  return GetPOV(location, old_values_) && !GetPOV(location, current_values_);
+}
+
 bool Data::GetControlBit(const ControlBit bit) const {
   return GetControlBitValue(bit, current_values_);
 }
diff --git a/aos/common/input/driver_station_data.h b/aos/common/input/driver_station_data.h
index 7a946eb..41d54f5 100644
--- a/aos/common/input/driver_station_data.h
+++ b/aos/common/input/driver_station_data.h
@@ -44,6 +44,15 @@
   static const int kButtons = 12;
 };
 
+// Represents the direction of a POV on a joystick.
+// Use Data to actually get the value.
+// Safe for static initialization.
+class POVLocation : public JoystickFeature {
+ public:
+  POVLocation(int joystick, int number)
+      : JoystickFeature(joystick, number) {}
+};
+
 // Represents various bits of control information that the DS sends.
 // Use Data to actually get the value.
 enum class ControlBit {
@@ -72,6 +81,10 @@
   // Updates the current information with a new set of values.
   void Update(const JoystickState &new_values);
 
+  bool IsPressed(POVLocation location) const;
+  bool PosEdge(POVLocation location) const;
+  bool NegEdge(POVLocation location) const;
+
   bool IsPressed(ButtonLocation location) const;
   bool PosEdge(ButtonLocation location) const;
   bool NegEdge(ButtonLocation location) const;
diff --git a/aos/common/messages/robot_state.q b/aos/common/messages/robot_state.q
index 74fe5d0..3ecb653 100644
--- a/aos/common/messages/robot_state.q
+++ b/aos/common/messages/robot_state.q
@@ -6,6 +6,9 @@
 
   // The 4 joystick axes.
   double[4] axis;
+
+  // The POV axis.
+  int32_t pov;
 };
 
 message JoystickState {
diff --git a/frc971/wpilib/joystick_sender.cc b/frc971/wpilib/joystick_sender.cc
index de7fe88..236cc0f 100644
--- a/frc971/wpilib/joystick_sender.cc
+++ b/frc971/wpilib/joystick_sender.cc
@@ -36,6 +36,7 @@
       for (int j = 0; j < 4; ++j) {
         new_state->joysticks[i].axis[j] = ds->GetStickAxis(i, j);
       }
+      new_state->joysticks[i].pov = ds->GetStickPOV(i, 0);
     }
     LOG_STRUCT(DEBUG, "joystick_state", *new_state);