Split joystick_reader into hardware shim + application.

Change-Id: If31e6dd7ece547a2952ec21e2f4bc745ee6f9d84
diff --git a/aos/common/input/driver_station_data.cc b/aos/common/input/driver_station_data.cc
index 18b3403..d97601a 100644
--- a/aos/common/input/driver_station_data.cc
+++ b/aos/common/input/driver_station_data.cc
@@ -6,7 +6,7 @@
 
 Data::Data() : current_values_(), old_values_() {}
 
-void Data::Update(const NetworkRobotJoysticks &new_values) {
+void Data::Update(const RobotState &new_values) {
   old_values_ = current_values_;
   current_values_ = new_values;
 }
@@ -14,22 +14,22 @@
 namespace {
 
 bool GetButton(const ButtonLocation location,
-               const NetworkRobotJoysticks &values) {
+               const RobotState &values) {
   return values.joysticks[location.joystick() - 1].buttons &
       (1 << (location.number() - 1));
 }
 
 bool GetControlBitValue(const ControlBit bit,
-                        const NetworkRobotJoysticks &values) {
+                        const RobotState &values) {
   switch (bit) {
     case ControlBit::kTestMode:
-      return values.control.test_mode();
+      return values.test_mode;
     case ControlBit::kFmsAttached:
-      return values.control.fms_attached();
+      return values.fms_attached;
     case ControlBit::kAutonomous:
-      return values.control.autonomous();
+      return values.autonomous;
     case ControlBit::kEnabled:
-      return values.control.enabled();
+      return values.enabled;
     default:
       __builtin_unreachable();
   }
@@ -66,9 +66,7 @@
 }
 
 float Data::GetAxis(JoystickAxis axis) const {
-  // TODO(brians): check this math against what our joysticks report as their
-  // logical minimums and maximums
-  return current_values_.joysticks[axis.joystick() - 1].axes[axis.number() - 1] / 127.0;
+  return current_values_.joysticks[axis.joystick() - 1].axis[axis.number() - 1];
 }
 
 }  // namespace driver_station
diff --git a/aos/common/input/driver_station_data.h b/aos/common/input/driver_station_data.h
index 4bef0b6..a8a9ddf 100644
--- a/aos/common/input/driver_station_data.h
+++ b/aos/common/input/driver_station_data.h
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "aos/externals/WPILib/WPILib/NetworkRobot/NetworkRobotValues.h"
+#include "aos/common/messages/robot_state.q.h"
 
 namespace aos {
 namespace input {
@@ -20,8 +20,8 @@
       : joystick_(joystick), number_(number) {}
 
   // How many joysticks there are.
-  static const int kJoysticks = sizeof(NetworkRobotJoysticks::joysticks) /
-                                sizeof(NetworkRobotJoysticks::joysticks[0]);
+  static const int kJoysticks = sizeof(RobotState::joysticks) /
+                                sizeof(RobotState::joysticks[0]);
 
   // Which joystick number this is (1-based).
   int joystick() const { return joystick_; }
@@ -59,8 +59,8 @@
       : JoystickFeature(joystick, number) {}
 
   // How many axes there are available on each joystick.
-  static const int kAxes = sizeof(NetworkRobotJoysticks::Joystick::axes) /
-                           sizeof(NetworkRobotJoysticks::Joystick::axes[0]);
+  static const int kAxes = sizeof(Joystick::axis) /
+                           sizeof(Joystick::axis[0]);
 };
 
 class Data {
@@ -70,7 +70,7 @@
   Data();
 
   // Updates the current information with a new set of values.
-  void Update(const NetworkRobotJoysticks &new_values);
+  void Update(const RobotState &new_values);
 
   bool IsPressed(ButtonLocation location) const;
   bool PosEdge(ButtonLocation location) const;
@@ -84,7 +84,7 @@
   float GetAxis(JoystickAxis axis) const;
 
  private:
-  NetworkRobotJoysticks current_values_, old_values_;
+  RobotState current_values_, old_values_;
 };
 
 }  // namespace driver_station
diff --git a/aos/common/input/input.gyp b/aos/common/input/input.gyp
index e5c964c..7d5af30 100644
--- a/aos/common/input/input.gyp
+++ b/aos/common/input/input.gyp
@@ -8,9 +8,11 @@
       ],
       'dependencies': [
         '<(EXTERNALS):WPILib-NetworkRobotValues',
+        '<(AOS)/common/messages/messages.gyp:robot_state',
       ],
       'export_dependent_settings': [
         '<(EXTERNALS):WPILib-NetworkRobotValues',
+        '<(AOS)/common/messages/messages.gyp:robot_state',
       ],
     },
   ],
diff --git a/aos/common/messages/robot_state.q b/aos/common/messages/robot_state.q
index 696bf2c..bd66e1d 100644
--- a/aos/common/messages/robot_state.q
+++ b/aos/common/messages/robot_state.q
@@ -1,15 +1,27 @@
 package aos;
 
+struct Joystick {
+  // A bitmask of the button state.
+  uint16_t buttons;
+
+  // The 4 joystick axes.
+  double[4] axis;
+};
+
 message RobotState {
-	bool enabled;
-	bool autonomous;
-	uint16_t team_id;
-	// If this is true, then this message isn't actually from the control
-	// system and so should not be trusted as evidence that the button inputs
-	// etc are actually real and should be acted on.
-	// However, most things should ignore this so that sending fake messages is
-	// useful for testing.
-	bool fake;
+  Joystick[4] joysticks;
+
+  bool test_mode;
+  bool fms_attached;
+  bool enabled;
+  bool autonomous;
+  uint16_t team_id;
+  // If this is true, then this message isn't actually from the control
+  // system and so should not be trusted as evidence that the button inputs
+  // etc are actually real and should be acted on.
+  // However, most things should ignore this so that sending fake messages is
+  // useful for testing.
+  bool fake;
 };
 
 // The robot_state Queue is checked by all control loops to make sure that the
diff --git a/aos/prime/input/joystick_input.cc b/aos/prime/input/joystick_input.cc
index 7e2f0cd..c9b890a 100644
--- a/aos/prime/input/joystick_input.cc
+++ b/aos/prime/input/joystick_input.cc
@@ -13,7 +13,7 @@
 namespace aos {
 namespace input {
 
-void JoystickInput::Run() {
+void JoystickProxy::Run() {
   network::ReceiveSocket sock(NetworkPort::kDS);
   // If true, this code won't try to read anything from the network and instead
   // feed all 0s to the joystick code.
@@ -23,7 +23,6 @@
 
   NetworkRobotJoysticks joysticks;
   char buffer[sizeof(joysticks) + ::buffers::kOverhead];
-  driver_station::Data data;
 
   while (true) {
     if (kFakeJoysticks) {
@@ -43,17 +42,38 @@
     }
 
     auto new_state = robot_state.MakeMessage();
+    new_state->test_mode = joysticks.control.test_mode();
+    new_state->fms_attached = joysticks.control.fms_attached();
     new_state->enabled = joysticks.control.enabled();
     new_state->autonomous = joysticks.control.autonomous();
     new_state->team_id = joysticks.team_number;
     new_state->fake = kFakeJoysticks;
+
+    for (int i = 0; i < 4; ++i) {
+      new_state->joysticks[i].buttons = joysticks.joysticks[i].buttons;
+      for (int j = 0; j < 4; ++j) {
+        // TODO(brians): check this math against what our joysticks report as
+        // their logical minimums and maximums
+        new_state->joysticks[i].axis[j] = joysticks.joysticks[i].axes[j] / 127.0;
+      }
+    }
+
     LOG_STRUCT(DEBUG, "sending", *new_state);
 
     if (!new_state.Send()) {
       LOG(WARNING, "sending robot_state failed\n");
     }
+  }
+}
 
-    data.Update(joysticks);
+void JoystickInput::Run() {
+  driver_station::Data data;
+  while (true) {
+    robot_state.FetchAnother();
+
+    LOG_STRUCT(DEBUG, "sending", *robot_state);
+
+    data.Update(*robot_state);
 
     {
       using driver_station::JoystickFeature;
diff --git a/aos/prime/input/joystick_input.h b/aos/prime/input/joystick_input.h
index 17fdbbe..c44c5e2 100644
--- a/aos/prime/input/joystick_input.h
+++ b/aos/prime/input/joystick_input.h
@@ -20,6 +20,12 @@
   virtual void RunIteration(const driver_station::Data &data) = 0;
 };
 
+// Class which will proxy joystick information from UDP packets to the queues.
+class JoystickProxy {
+ public:
+  void Run();
+};
+
 }  // namespace input
 }  // namespace aos