Add ids to flatbuffer fields in y2012, y2016, frc971, and aos

Change-Id: I9ed9006ce6224e2df0459df47771786b928164a1
diff --git a/aos/actions/actions.fbs b/aos/actions/actions.fbs
index aa4f7a7..d47df08 100644
--- a/aos/actions/actions.fbs
+++ b/aos/actions/actions.fbs
@@ -2,25 +2,25 @@
 
 table Status {
   // The run value of the instance we're currently running or 0.
-  running:uint;
+  running:uint (id: 0);
   // A run value we were previously running or 0.
-  last_running:uint;
+  last_running:uint (id: 1);
   // If false the action failed to complete and may be in a bad state,
   // this is a critical problem not a cancellation.
-  success:bool;
+  success:bool (id: 2);
 }
 
 table DoubleParam {
-  val:double;
+  val:double (id: 0);
 }
 
 table Goal {
   // The unique value to put into status.running while running this instance or
   // 0 to cancel.
-  run:uint;
+  run:uint (id: 0);
   // Default parameter.  The more useful thing to do would be to define your own
   // goal type to change param to a useful structure.
-  params:DoubleParam;
+  params:DoubleParam (id: 1);
 }
 
 root_type Status;
diff --git a/aos/actions/test_action.fbs b/aos/actions/test_action.fbs
index 8aebcb8..51de3b9 100644
--- a/aos/actions/test_action.fbs
+++ b/aos/actions/test_action.fbs
@@ -1,22 +1,22 @@
 namespace aos.common.actions;
 
 table UInt {
-  val:uint;
+  val:uint (id: 0);
 }
 
 table TestActionGoal {
-  run:uint;
-  params:UInt;
+  run:uint (id: 0);
+  params:UInt (id: 1);
 }
 
 table MyParams {
-  param1:double;
-  param2:int;
+  param1:double (id: 0);
+  param2:int (id: 1);
 }
 
 table TestAction2Goal {
-  run:uint;
-  params:MyParams;
+  run:uint (id: 0);
+  params:MyParams (id: 1);
 }
 
 root_type TestActionGoal;
diff --git a/aos/actions/test_action2.fbs b/aos/actions/test_action2.fbs
index 906867f..f20f414 100644
--- a/aos/actions/test_action2.fbs
+++ b/aos/actions/test_action2.fbs
@@ -1,13 +1,13 @@
 namespace aos.common.actions;
 
 table MyParams {
-  param1:double;
-  param2:int;
+  param1:double (id: 0);
+  param2:int (id: 1);
 }
 
 table TestAction2Goal {
-  run:uint;
-  params:MyParams;
+  run:uint (id: 0);
+  params:MyParams (id: 1);
 }
 
 root_type TestAction2Goal;
diff --git a/aos/controls/control_loops.fbs b/aos/controls/control_loops.fbs
index 8456bfa..be5b7db 100644
--- a/aos/controls/control_loops.fbs
+++ b/aos/controls/control_loops.fbs
@@ -3,19 +3,19 @@
 // control loop.
 
 table Goal {
-  goal:double;
+  goal:double (id: 0);
 }
 
 table Position {
-  position:double;
+  position:double (id: 0);
 }
 
 table Output {
-  voltage:double;
+  voltage:double (id: 0);
 }
 
 table Status {
-  done:bool;
+  done:bool (id: 0);
 }
 
 root_type Goal;
diff --git a/aos/events/event_loop.fbs b/aos/events/event_loop.fbs
index 4053a75..1434c4e 100644
--- a/aos/events/event_loop.fbs
+++ b/aos/events/event_loop.fbs
@@ -4,85 +4,85 @@
 
 // Holds statistics for a time or size sample.
 table Statistic {
-  average:float = nan;
-  min:float = nan;
-  max:float = nan;
-  standard_deviation:float = nan;
+  average:float = nan (id: 0);
+  min:float = nan (id: 1);
+  max:float = nan (id: 2);
+  standard_deviation:float = nan (id: 3);
 }
 
 table Sender {
   // Index into the channel config for this event loop.
-  channel_index:int = -1;
+  channel_index:int = -1 (id: 0);
 
   // Number of messages published.
-  count:uint;
+  count:uint (id: 1);
   // Statistics on the size of messages published.
-  size:Statistic;
+  size:Statistic (id: 2);
 
   // Channel for this sender.  Not filled out by default.
-  channel:Channel;
+  channel:Channel (id: 3);
 }
 
 table Watcher {
   // Index into the channel config for this event loop.
-  channel_index:int = -1;
+  channel_index:int = -1 (id: 0);
 
   // Number of messages received since the last report.
-  count:uint;
+  count:uint (id: 1);
 
   // Latency measurement from when the event was generated (send time), and when
   // the handler was started.
-  wakeup_latency:Statistic;
+  wakeup_latency:Statistic (id: 2);
   // Statistics on the execution time of the handler.
-  handler_time:Statistic;
+  handler_time:Statistic (id: 3);
 
   // Channel for this watcher.  Not filled out by default.
-  channel:Channel;
+  channel:Channel (id: 4);
 }
 
 table Fetcher {
   // Index into the channel config for this event loop.
-  channel_index:int = -1;
+  channel_index:int = -1 (id: 0);
 
   // Number of messages fetched since the last time this was published.
-  count:uint;
+  count:uint (id: 1);
   // Latency measurement from when the event was generated (send time), and when
   // the message was fetched.
-  latency:Statistic;
+  latency:Statistic (id: 2);
 
   // Channel for this fetcher.  Not filled out by default.
-  channel:Channel;
+  channel:Channel (id: 3);
 }
 
 table Timer {
-  name:string;
+  name:string (id: 0);
 
   // Number of wakeups since the last report.
-  count:uint;
+  count:uint (id: 1);
 
   // Latency measurement from when the event was generated (send time), and when
   // the handler was started.
-  wakeup_latency:Statistic;
+  wakeup_latency:Statistic (id: 2);
   // Statistics on the execution time of the handler.
-  handler_time:Statistic;
+  handler_time:Statistic (id: 3);
 
   // Maximum number of cycles missed.
 }
 
 table Report {
   // Name of the event loop which is publishing this report.
-  name:string;
+  name:string (id: 0);
   // Identifier for the event loop.  This should change every time a process
   // gets restarted.
-  pid:int;
+  pid:int (id: 1);
 
   // List of statistics for each watcher, sender, fetcher, timer, and
   // phased loop.
-  watchers:[Watcher];
-  senders:[Sender];
-  fetchers:[Fetcher];
-  timers:[Timer];
-  phased_loops:[Timer];
+  watchers:[Watcher] (id: 2);
+  senders:[Sender] (id: 3);
+  fetchers:[Fetcher] (id: 4);
+  timers:[Timer] (id: 5);
+  phased_loops:[Timer] (id: 6);
 }
 
 root_type Report;
diff --git a/aos/events/logging/test_message.fbs b/aos/events/logging/test_message.fbs
index ef876aa..6802a86 100644
--- a/aos/events/logging/test_message.fbs
+++ b/aos/events/logging/test_message.fbs
@@ -1,7 +1,7 @@
 namespace aos.logger.testing;
 
 table TestMessage {
-  value:int;
+  value:int (id: 0);
 }
 
 root_type TestMessage;
diff --git a/aos/events/ping.fbs b/aos/events/ping.fbs
index c41498b..ccad470 100644
--- a/aos/events/ping.fbs
+++ b/aos/events/ping.fbs
@@ -1,8 +1,8 @@
 namespace aos.examples;
 
 table Ping {
-  value:int;
-  send_time:long;
+  value:int (id: 0);
+  send_time:long (id: 1);
 }
 
 root_type Ping;
diff --git a/aos/events/pong.fbs b/aos/events/pong.fbs
index 115dbbe..19b5db4 100644
--- a/aos/events/pong.fbs
+++ b/aos/events/pong.fbs
@@ -1,8 +1,8 @@
 namespace aos.examples;
 
 table Pong {
-  value:int;
-  initial_send_time:long;
+  value:int (id: 0);
+  initial_send_time:long (id: 1);
 }
 
 root_type Pong;
diff --git a/aos/events/test_message.fbs b/aos/events/test_message.fbs
index 1d26c2e..df2ffd7 100644
--- a/aos/events/test_message.fbs
+++ b/aos/events/test_message.fbs
@@ -1,7 +1,7 @@
 namespace aos;
 
 table TestMessage {
-  value:int;
+  value:int (id: 0);
 }
 
 root_type TestMessage;
diff --git a/aos/json_to_flatbuffer.fbs b/aos/json_to_flatbuffer.fbs
index ad2c901..7ce9ae6 100644
--- a/aos/json_to_flatbuffer.fbs
+++ b/aos/json_to_flatbuffer.fbs
@@ -22,30 +22,30 @@
 }
 
 table Location {
-  name:string;
-  type:string;
-  frequency:int;
-  max_size:int;
+  name:string (id: 0);
+  type:string (id: 1);
+  frequency:int (id: 2);
+  max_size:int (id: 3);
 }
 
 table Map {
-  match:Location;
-  rename:Location;
+  match:Location (id: 0);
+  rename:Location (id: 1);
 }
 
 table Application {
-  name:string;
-  priority:int;
-  maps:[Map];
-  long_thingy:uint64;
+  name:string (id: 0);
+  priority:int (id: 1);
+  maps:[Map] (id: 2);
+  long_thingy:uint64 (id: 3);
 }
 
 table VectorOfStrings {
-  str:[string];
+  str:[string] (id: 0);
 }
 
 table VectorOfVectorOfString {
-  v:[VectorOfStrings];
+  v:[VectorOfStrings] (id: 0);
 }
 
 struct FooStructNested {
diff --git a/aos/logging/log_message.fbs b/aos/logging/log_message.fbs
index 7e246cf..b68287f 100644
--- a/aos/logging/log_message.fbs
+++ b/aos/logging/log_message.fbs
@@ -18,10 +18,10 @@
   level:Level (id: 1);
 
   // Pid of the process creating the log message
-  source_pid:int (id:2);
+  source_pid:int (id: 2);
 
   // Application name
-  name:string (id:3);
+  name:string (id: 3);
 }
 
 root_type LogMessageFbs;
diff --git a/aos/network/connect.fbs b/aos/network/connect.fbs
index 32893b8..b593472 100644
--- a/aos/network/connect.fbs
+++ b/aos/network/connect.fbs
@@ -6,8 +6,8 @@
 // It communicates the channels that need to be forwarded back.
 table Connect {
   // The node making the request.
-  node:aos.Node;
+  node:aos.Node (id: 0);
 
   // The channels that we want transfered to this client.
-  channels_to_transfer:[Channel];
+  channels_to_transfer:[Channel] (id: 1);
 }
diff --git a/aos/network/message_bridge_client.fbs b/aos/network/message_bridge_client.fbs
index df3f02f..9dddd16 100644
--- a/aos/network/message_bridge_client.fbs
+++ b/aos/network/message_bridge_client.fbs
@@ -5,25 +5,25 @@
 // Statistics from a single client connection to a server.
 table ClientConnection {
   // The node that we are connected to.
-  node:Node;
+  node:Node (id: 0);
 
   // Health of this connection.  Connected or not?
-  state:State;
+  state:State (id: 1);
 
   // Number of packets received on all channels.
-  received_packets:uint;
+  received_packets:uint (id: 2);
 
   // This is the measured monotonic offset for just the server -> client
   // direction measured in nanoseconds.  Subtract this from our monotonic time
   // to get their monotonic time.
-  monotonic_offset:int64;
+  monotonic_offset:int64 (id: 3);
 
   // TODO(austin): Per channel counts?
 }
 
 // Statistics for all clients.
 table ClientStatistics {
-  connections:[ClientConnection];
+  connections:[ClientConnection] (id: 0);
 }
 
 root_type ClientStatistics;
diff --git a/aos/network/message_bridge_server.fbs b/aos/network/message_bridge_server.fbs
index 8f06fdb..1be0796 100644
--- a/aos/network/message_bridge_server.fbs
+++ b/aos/network/message_bridge_server.fbs
@@ -11,28 +11,28 @@
 // Statistics from a single connection to a client from this server.
 table ServerConnection {
   // The node that we are connected to.
-  node:Node;
+  node:Node (id: 0);
 
   // Health of this connection.  Connected or not?
-  state:State;
+  state:State (id: 1);
 
   // Number of packets that have been dropped (if known).
-  dropped_packets:uint;
+  dropped_packets:uint (id: 2);
 
   // Number of packets received on all channels.
-  sent_packets:uint;
+  sent_packets:uint (id: 3);
 
   // This is the measured monotonic offset for the connected node in
   // nanoseconds.  Add this to our monotonic time to get their
   // monotonic time.
-  monotonic_offset:int64;
+  monotonic_offset:int64 (id: 4);
 
   // TODO(austin): Per channel counts?
 }
 
 // Statistics for all connections to all the clients.
 table ServerStatistics {
-  connections:[ServerConnection];
+  connections:[ServerConnection] (id: 0);
 }
 
 root_type ServerStatistics;
diff --git a/aos/network/timestamp.fbs b/aos/network/timestamp.fbs
index 299ecaf..ccd7f40 100644
--- a/aos/network/timestamp.fbs
+++ b/aos/network/timestamp.fbs
@@ -3,13 +3,13 @@
 namespace aos.message_bridge;
 
 table ClientOffset {
-  node:Node;
+  node:Node (id: 0);
 
-  monotonic_offset:int64;
+  monotonic_offset:int64 (id: 1);
 }
 
 table Timestamp {
-  offsets:[ClientOffset];
+  offsets:[ClientOffset] (id: 0);
 }
 
 root_type Timestamp;
diff --git a/aos/network/web_proxy.fbs b/aos/network/web_proxy.fbs
index 196d38c..e11ff26 100644
--- a/aos/network/web_proxy.fbs
+++ b/aos/network/web_proxy.fbs
@@ -16,24 +16,24 @@
 // The SDP payload is an opaque string that describes what (media/data) we
 // want to transmit.
 table WebSocketSdp {
-  type:SdpType;
-  payload:string;
+  type:SdpType (id: 0);
+  payload:string (id: 1);
 }
 
 // ICE is way for different peers to learn how to connect to each other.
 // Because we will only be running in a local network, we don't have to support
 // advaced features.
 table WebSocketIce {
-  candidate:string;
-  sdpMid:string;
-  sdpMLineIndex:int;
+  candidate:string (id: 0);
+  sdpMid:string (id: 1);
+  sdpMLineIndex:int (id: 2);
 }
 
 union Payload {WebSocketSdp, WebSocketIce}
 
 // We only send a single type of message on the websocket to simplify parsing.
 table WebSocketMessage {
-  payload:Payload;
+  payload:Payload (id: 1);
 }
 
 // WebRTC has size limits on the messages sent on datachannels. This message
@@ -42,22 +42,22 @@
 // data starts again.
 table MessageHeader {
   // Index of the channel in config
-  channel_index:uint;
+  channel_index:uint (id: 0);
 
   // How many packets will be required for the message being sent.
-  packet_count:uint;
+  packet_count:uint (id: 1);
   // What index into the the total packets for the multipart message, this
   // header is parts of.
-  packet_index:uint;
+  packet_index:uint (id: 2);
 
   // Total number of bytes in the message
-  length:uint;
+  length:uint (id: 3);
 
   // Index into the sequence of messages. This will not always increase.
-  queue_index:uint;
+  queue_index:uint (id: 4);
 
-  data:[ubyte];
+  data:[ubyte] (id: 5);
 
   // Time at which the message was sent, in nanoseconds.
-  monotonic_sent_time:long;
+  monotonic_sent_time:long (id: 6);
 }
diff --git a/aos/robot_state/joystick_state.fbs b/aos/robot_state/joystick_state.fbs
index 1deaa06..2f48bdf 100644
--- a/aos/robot_state/joystick_state.fbs
+++ b/aos/robot_state/joystick_state.fbs
@@ -2,14 +2,14 @@
 
 table Joystick {
   // A bitmask of the butotn state.
-  buttons:ushort;
+  buttons:ushort (id: 0);
 
   // The 6 joystick axes.
   // TODO: Should have size of 6
-  axis:[double];
+  axis:[double] (id: 1);
 
   // The POV axis.
-  pov:int;
+  pov:int (id: 2);
 }
 
 enum Alliance : byte { kRed, kBlue, kInvalid }
@@ -18,18 +18,18 @@
 // joystick code hasn't died.  It is published on "/aos"
 table JoystickState {
   //TODO: should have fixed size.
-  joysticks:[Joystick];
+  joysticks:[Joystick] (id: 0);
 
-  test_mode:bool;
-  fms_attached:bool;
-  enabled:bool;
-  autonomous:bool;
-  team_id:ushort;
+  test_mode:bool (id: 1);
+  fms_attached:bool (id: 2);
+  enabled:bool (id: 3);
+  autonomous:bool (id: 4);
+  team_id:ushort (id: 5);
 
   // 2018 scale and switch positions.
   // TODO(austin): Push these out to a new message?
-  switch_left:bool;
-  scale_left:bool;
+  switch_left:bool (id: 6);
+  scale_left:bool (id: 7);
 
   // 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
@@ -37,13 +37,13 @@
   // However, most things should ignore this so that sending fake messages is
   // useful for testing. The only difference in behavior should be motors not
   // actually turning on.
-  fake:bool;
+  fake:bool (id: 8);
 
   // Color of our current alliance.
-  alliance:Alliance;
+  alliance:Alliance (id: 9);
 
   // String corresponding to the game data string
-  game_data:string;
+  game_data:string (id: 10);
 }
 
 root_type JoystickState;
diff --git a/aos/robot_state/robot_state.fbs b/aos/robot_state/robot_state.fbs
index 437cfd7..7d0199b 100644
--- a/aos/robot_state/robot_state.fbs
+++ b/aos/robot_state/robot_state.fbs
@@ -7,29 +7,29 @@
 table RobotState {
   // The PID of the process reading sensors.
   // This is here so control loops can tell when it changes.
-  reader_pid:int;
+  reader_pid:int (id: 0);
 
   // True when outputs are enabled.
   // Motor controllers keep going for a bit after this goes to false.
-  outputs_enabled:bool;
+  outputs_enabled:bool (id: 1);
   // Indicates whether something is browned out (I think motor controller
   // outputs). IMPORTANT: This is NOT !outputs_enabled. outputs_enabled goes to
   // false for other reasons too (disabled, e-stopped, maybe more).
-  browned_out:bool;
+  browned_out:bool (id: 2);
 
   // Whether the two sensor rails are currently working.
-  is_3v3_active:bool;
-  is_5v_active:bool;
+  is_3v3_active:bool (id: 3);
+  is_5v_active:bool (id: 4);
   // The current voltages measured on the two sensor rails.
-  voltage_3v3:double;
-  voltage_5v:double;
+  voltage_3v3:double (id: 5);
+  voltage_5v:double (id: 6);
 
   // The input voltage to the roboRIO.
-  voltage_roborio_in:double;
+  voltage_roborio_in:double (id: 7);
 
   // From the DriverStation object, aka what FMS sees and what shows up on the
   // actual driver's station.
-  voltage_battery:double;
+  voltage_battery:double (id: 8);
 }
 
 root_type RobotState;
diff --git a/aos/starter/starter.fbs b/aos/starter/starter.fbs
index 2234518..8c7cdae 100644
--- a/aos/starter/starter.fbs
+++ b/aos/starter/starter.fbs
@@ -46,30 +46,30 @@
 }
 
 table Status {
-  statuses: [ApplicationStatus];
+  statuses: [ApplicationStatus] (id: 0);
 }
 
 table ApplicationStatus {
-  name: string;
+  name: string (id: 0);
 
-  state: State;
+  state: State (id: 1);
 
   // Last exit code of the process. Has a value of 0 if not started.
-  last_exit_code: ubyte;
+  last_exit_code: ubyte (id: 2);
 
   // Last pid of the process. Could be associated with a different process
   // unless status == RUNNING. Not present if the process has not started.
-  pid: uint;
+  pid: uint (id: 3);
 
   // Unique id of this application and process
-  id: uint64;
+  id: uint64 (id: 4);
 
   // Start time in nanoseconds relative to monotonic clock
-  last_start_time: int64;
+  last_start_time: int64 (id: 5);
 
   // Indicates the reason the application is not running. Only valid if
   // application is STOPPED.
-  last_stop_reason: LastStopReason;
+  last_stop_reason: LastStopReason (id: 6);
 }
 
 root_type Status;
diff --git a/aos/starter/starter_rpc.fbs b/aos/starter/starter_rpc.fbs
index 0e72cff..21b7117 100644
--- a/aos/starter/starter_rpc.fbs
+++ b/aos/starter/starter_rpc.fbs
@@ -17,11 +17,11 @@
 }
 
 table StarterRpc {
-  command : Command;
+  command : Command (id: 0);
 
   // The name of the application to send the command to. Command is ignored if
   // the given application does not exist.
-  name: string;
+  name: string (id: 1);
 }
 
 root_type StarterRpc;
diff --git a/frc971/autonomous/auto.fbs b/frc971/autonomous/auto.fbs
index ef8e915..5a180e3 100644
--- a/frc971/autonomous/auto.fbs
+++ b/frc971/autonomous/auto.fbs
@@ -2,12 +2,12 @@
 
 table AutonomousActionParams {
   // The mode from the sensors when auto starts.
-  mode:int;
+  mode:int (id: 0);
 }
 
 table Goal {
-  run:uint;
-  params:AutonomousActionParams;
+  run:uint (id: 0);
+  params:AutonomousActionParams (id: 1);
 }
 
 root_type Goal;
diff --git a/frc971/autonomous/auto_mode.fbs b/frc971/autonomous/auto_mode.fbs
index 412cd17..b6bff20 100644
--- a/frc971/autonomous/auto_mode.fbs
+++ b/frc971/autonomous/auto_mode.fbs
@@ -2,7 +2,7 @@
 
 table AutonomousMode {
   // Mode read from the mode setting sensors.
-  mode:int;
+  mode:int (id: 0);
 }
 
 root_type AutonomousMode;
diff --git a/frc971/codelab/basic_goal.fbs b/frc971/codelab/basic_goal.fbs
index cfde3ba..9509fa7 100644
--- a/frc971/codelab/basic_goal.fbs
+++ b/frc971/codelab/basic_goal.fbs
@@ -5,7 +5,7 @@
 table Goal {
   // If set to true, the intake should turn on the motor and run until the
   // limit sensor in the Position message turns on.
-  intake:bool;
+  intake:bool (id: 0);
 }
 
 root_type Goal;
diff --git a/frc971/codelab/basic_output.fbs b/frc971/codelab/basic_output.fbs
index 7f3b0b9..be27122 100644
--- a/frc971/codelab/basic_output.fbs
+++ b/frc971/codelab/basic_output.fbs
@@ -5,7 +5,7 @@
   // hope to intake something. Voltages on our robots generally range from
   // -12.0 V to +12.0V. In this case, the intake should be commanded to actually
   // intake by setting the voltage to 12 V.
-  intake_voltage:double;
+  intake_voltage:double (id: 0);
 }
 
 root_type Output;
diff --git a/frc971/codelab/basic_position.fbs b/frc971/codelab/basic_position.fbs
index 1420313..72d80d2 100644
--- a/frc971/codelab/basic_position.fbs
+++ b/frc971/codelab/basic_position.fbs
@@ -6,7 +6,7 @@
   // ball in, and the ball then hits a limit sensor when it is fully contained.
   // We would then want to stop running the intake to avoid spinning the intake
   // against the ball.
-  limit_sensor: bool;
+  limit_sensor: bool (id: 0);
 }
 
 root_type Position;
diff --git a/frc971/codelab/basic_status.fbs b/frc971/codelab/basic_status.fbs
index ec754b4..0aa2938 100644
--- a/frc971/codelab/basic_status.fbs
+++ b/frc971/codelab/basic_status.fbs
@@ -5,7 +5,7 @@
   // be set to true by the intake subsystem when the Goal message is requesting
   // the intake to be on and the limit sensor from the position message has
   // been enabled.
-  intake_complete:bool;
+  intake_complete:bool (id: 0);
 }
 
 root_type Status;
diff --git a/frc971/control_loops/control_loops.fbs b/frc971/control_loops/control_loops.fbs
index f510085..243e2cb 100644
--- a/frc971/control_loops/control_loops.fbs
+++ b/frc971/control_loops/control_loops.fbs
@@ -8,11 +8,11 @@
 // position which varies with each robot.
 table IndexPosition {
   // Current position read from the encoder.
-  encoder:double;
+  encoder:double (id: 0);
   // Position from the encoder latched at the last index pulse.
-  latched_encoder:double;
+  latched_encoder:double (id: 1);
   // How many index pulses we've seen since startup. Starts at 0.
-  index_pulses:uint;
+  index_pulses:uint (id: 2);
 }
 
 // Represents all of the data for a single potentiometer and indexed encoder
@@ -23,17 +23,17 @@
 // position which varies with each robot.
 table PotAndIndexPosition {
   // Current position read from the encoder.
-  encoder:double;
+  encoder:double (id: 0);
   // Current position read from the potentiometer.
-  pot:double;
+  pot:double (id: 1);
 
   // Position from the encoder latched at the last index pulse.
-  latched_encoder:double;
+  latched_encoder:double (id: 2);
   // Position from the potentiometer latched at the last index pulse.
-  latched_pot:double;
+  latched_pot:double (id: 3);
 
   // How many index pulses we've seen since startup. Starts at 0.
-  index_pulses:uint;
+  index_pulses:uint (id: 4);
 }
 
 // Represents all of the data for a single potentiometer with an absolute and
@@ -44,11 +44,11 @@
 // arbitrary 0 position which varies with each robot.
 table PotAndAbsolutePosition {
   // Current position read from each encoder.
-  encoder:double;
-  absolute_encoder:double;
+  encoder:double (id: 0);
+  absolute_encoder:double (id: 1);
 
   // Current position read from the potentiometer.
-  pot:double;
+  pot:double (id: 2);
 }
 
 // Represents all of the data for an absolute and relative encoder pair.
@@ -57,8 +57,8 @@
 // arbitrary point in time.
 table AbsolutePosition {
   // Current position read from each encoder.
-  encoder:double;
-  absolute_encoder:double;
+  encoder:double (id: 0);
+  absolute_encoder:double (id: 1);
 }
 
 // Represents all of the data for an absolute and relative encoder pair,
@@ -70,12 +70,12 @@
 // arbitrary point in time.
 table AbsoluteAndAbsolutePosition {
   // Current position read from each encoder.
-  encoder:double;
-  absolute_encoder:double;
+  encoder:double (id: 0);
+  absolute_encoder:double (id: 1);
 
   // Current position read from the single turn absolute encoder.
   // This can not turn more than one rotation.
-  single_turn_absolute_encoder:double;
+  single_turn_absolute_encoder:double (id: 2);
 }
 
 // Represents all of the data for a single encoder.
@@ -83,51 +83,51 @@
 // arbitrary point in time.
 table RelativePosition {
   // Current position read from the encoder.
-  encoder:double;
+  encoder:double (id: 0);
 }
 
 // The internal state of a zeroing estimator.
 table EstimatorState {
   // If true, there has been a fatal error for the estimator.
-  error:bool;
+  error:bool (id: 0);
   // If the joint has seen an index pulse and is zeroed.
-  zeroed:bool;
+  zeroed:bool (id: 1);
   // The estimated position of the joint.
-  position:double;
+  position:double (id: 2);
 
   // The estimated position not using the index pulse.
-  pot_position:double;
+  pot_position:double (id: 3);
 }
 
 // The internal state of a zeroing estimator.
 table PotAndAbsoluteEncoderEstimatorState {
   // If true, there has been a fatal error for the estimator.
-  error:bool;
+  error:bool (id: 0);
   // If the joint has seen an index pulse and is zeroed.
-  zeroed:bool;
+  zeroed:bool (id: 1);
   // The estimated position of the joint.
-  position:double;
+  position:double (id: 2);
 
   // The estimated position not using the index pulse.
-  pot_position:double;
+  pot_position:double (id: 3);
 
   // The estimated absolute position of the encoder.  This is filtered, so it
   // can be easily used when zeroing.
-  absolute_position:double;
+  absolute_position:double (id: 4);
 }
 
 // The internal state of a zeroing estimator.
 table AbsoluteEncoderEstimatorState {
   // If true, there has been a fatal error for the estimator.
-  error:bool;
+  error:bool (id: 0);
   // If the joint has seen an index pulse and is zeroed.
-  zeroed:bool;
+  zeroed:bool (id: 1);
   // The estimated position of the joint.
-  position:double;
+  position:double (id: 2);
 
   // The estimated absolute position of the encoder.  This is filtered, so it
   // can be easily used when zeroing.
-  absolute_position:double;
+  absolute_position:double (id: 3);
 }
 
 // The internal state of a zeroing estimator.
@@ -149,94 +149,94 @@
 
 table RelativeEncoderEstimatorState {
   // If true, there has been a fatal error for the estimator.
-  error:bool;
+  error:bool (id: 0);
 
   // The estimated position of the joint.
-  position:double;
+  position:double (id: 1);
 }
 
 // The internal state of a zeroing estimator.
 table IndexEstimatorState {
   // If true, there has been a fatal error for the estimator.
-  error:bool;
+  error:bool (id: 0);
   // If the joint has seen an index pulse and is zeroed.
-  zeroed:bool;
+  zeroed:bool (id: 1);
   // The estimated position of the joint. This is just the position relative to
   // where we started if we're not zeroed yet.
-  position:double;
+  position:double (id: 2);
 
   // The positions of the extreme index pulses we've seen.
-  min_index_position:double;
-  max_index_position:double;
+  min_index_position:double (id: 3);
+  max_index_position:double (id: 4);
   // The number of index pulses we've seen.
-  index_pulses_seen:int;
+  index_pulses_seen:int (id: 5);
 }
 
 table HallEffectAndPositionEstimatorState {
   // If error.
-  error:bool;
+  error:bool (id: 0);
   // If we've found a positive edge while moving backwards and is zeroed.
-  zeroed:bool;
+  zeroed:bool (id: 1);
   // Encoder angle relative to where we started.
-  encoder:double;
+  encoder:double (id: 2);
   // The positions of the extreme posedges we've seen.
   // If we've gotten enough samples where the hall effect is high before can be
   // certain it is not a false positive.
-  high_long_enough:bool;
-  offset:double;
+  high_long_enough:bool (id: 3);
+  offset:double (id: 4);
 }
 
 // A left/right pair of PotAndIndexPositions.
 table PotAndIndexPair {
-  left:PotAndIndexPosition;
-  right:PotAndIndexPosition;
+  left:PotAndIndexPosition (id: 0);
+  right:PotAndIndexPosition (id: 1);
 }
 
 // Records edges captured on a single hall effect sensor.
 table HallEffectStruct {
-  current:bool;
-  posedge_count:int;
-  negedge_count:int;
-  posedge_value:double;
-  negedge_value:double;
+  current:bool (id: 0);
+  posedge_count:int (id: 1);
+  negedge_count:int (id: 2);
+  posedge_value:double (id: 3);
+  negedge_value:double (id: 4);
 }
 
 // Records the hall effect sensor and encoder values.
 table HallEffectAndPosition {
   // The current hall effect state.
-  current:bool;
+  current:bool (id: 0);
   // The current encoder position.
-  encoder:double;
+  encoder:double (id: 1);
   // The number of positive and negative edges we've seen on the hall effect
   // sensor.
-  posedge_count:int;
-  negedge_count:int;
+  posedge_count:int (id: 2);
+  negedge_count:int (id: 3);
   // The values corresponding to the last hall effect sensor reading.
-  posedge_value:double;
-  negedge_value:double;
+  posedge_value:double (id: 4);
+  negedge_value:double (id: 5);
 }
 
 // Records the positions for a mechanism with edge-capturing sensors on it.
 table HallEventPositions {
-  current:double;
-  posedge:double;
-  negedge:double;
+  current:double (id: 0);
+  posedge:double (id: 1);
+  negedge:double (id: 2);
 }
 
 // Records edges captured on a single hall effect sensor.
 table PosedgeOnlyCountedHallEffectStruct {
-  current:bool;
-  posedge_count:int;
-  negedge_count:int;
-  posedge_value:double;
+  current:bool (id: 0);
+  posedge_count:int (id: 1);
+  negedge_count:int (id: 2);
+  posedge_value:double (id: 3);
 }
 
 // Parameters for the motion profiles.
 table ProfileParameters {
   // Maximum velocity for the profile.
-  max_velocity:float;
+  max_velocity:float (id: 0);
   // Maximum acceleration for the profile.
-  max_acceleration:float;
+  max_acceleration:float (id: 1);
 }
 
 enum ConstraintType : byte {
@@ -249,13 +249,13 @@
 
 // Definition of a constraint on a trajectory
 table Constraint {
-  constraint_type:ConstraintType;
+  constraint_type:ConstraintType (id: 0);
 
-  value:float;
+  value:float (id: 1);
 
   // start and end distance are only checked for velocity limits.
-  start_distance:float;
-  end_distance:float;
+  start_distance:float (id: 2);
+  end_distance:float (id: 3);
 }
 
 // Parameters for computing a trajectory using a chain of splines and
@@ -264,11 +264,11 @@
   // Number of splines. The spline point arrays will be expected to have
   // 6 + 5 * (n - 1) points in them. The endpoints are shared between
   // neighboring splines.
-  spline_count:byte;
+  spline_count:byte (id: 0);
   // Maximum of 36 spline points (7 splines).
-  spline_x:[float];
-  spline_y:[float];
+  spline_x:[float] (id: 1);
+  spline_y:[float] (id: 2);
 
   // Maximum of 6 constraints;
-  constraints:[Constraint];
+  constraints:[Constraint] (id: 3);
 }
diff --git a/frc971/control_loops/drivetrain/drivetrain_goal.fbs b/frc971/control_loops/drivetrain/drivetrain_goal.fbs
index 8a67849..3df5210 100644
--- a/frc971/control_loops/drivetrain/drivetrain_goal.fbs
+++ b/frc971/control_loops/drivetrain/drivetrain_goal.fbs
@@ -11,55 +11,55 @@
 
 table SplineGoal {
   // index of the spline. Zero indicates the spline should not be computed.
-  spline_idx:int;
+  spline_idx:int (id: 0);
 
   // Acutal spline.
-  spline:frc971.MultiSpline;
+  spline:frc971.MultiSpline (id: 1);
 
   // Whether to follow the spline driving forwards or backwards.
-  drive_spline_backwards:bool;
+  drive_spline_backwards:bool (id: 2);
 }
 
 table Goal {
   // Position of the steering wheel (positive = turning left when going
   // forwards).
-  wheel:float;
-  wheel_velocity:float;
-  wheel_torque:float;
+  wheel:float (id: 0);
+  wheel_velocity:float (id: 1);
+  wheel_torque:float (id: 2);
 
   // Position of the throttle (positive forwards).
-  throttle:float;
-  throttle_velocity:float;
-  throttle_torque:float;
+  throttle:float (id: 3);
+  throttle_velocity:float (id: 4);
+  throttle_torque:float (id: 5);
 
   // True to shift into high, false to shift into low.
-  highgear:bool;
+  highgear:bool (id: 6);
 
   // True to activate quickturn.
-  quickturn:bool;
+  quickturn:bool (id: 7);
 
   // Type of controller in charge of the drivetrain.
-  controller_type:ControllerType;
+  controller_type:ControllerType (id: 8);
 
   // Position goals for each drivetrain side (in meters) when the
   // closed-loop controller is active.
-  left_goal:double;
-  right_goal:double;
+  left_goal:double (id: 9);
+  right_goal:double (id: 10);
 
-  max_ss_voltage:float;
+  max_ss_voltage:float (id: 11);
 
   // Motion profile parameters.
   // The control loop will profile if these are all non-zero.
-  linear:ProfileParameters;
-  angular:ProfileParameters;
+  linear:ProfileParameters (id: 12);
+  angular:ProfileParameters (id: 13);
 
   // Parameters for a spline to follow. This just contains info on a spline to
   // compute. Each time this is sent, spline drivetrain will compute a new
   // spline.
-  spline:SplineGoal;
+  spline:SplineGoal (id: 14);
 
   // Which spline to follow.
-  spline_handle:int;
+  spline_handle:int (id: 15);
 }
 
 root_type Goal;
diff --git a/frc971/control_loops/drivetrain/drivetrain_output.fbs b/frc971/control_loops/drivetrain/drivetrain_output.fbs
index da8c889..dba178a 100644
--- a/frc971/control_loops/drivetrain/drivetrain_output.fbs
+++ b/frc971/control_loops/drivetrain/drivetrain_output.fbs
@@ -2,12 +2,12 @@
 
 table Output {
   // Voltage to send to motor(s) on either side of the drivetrain.
-  left_voltage:double;
-  right_voltage:double;
+  left_voltage:double (id: 0);
+  right_voltage:double (id: 1);
 
   // Whether to set each shifter piston to high gear.
-  left_high:bool;
-  right_high:bool;
+  left_high:bool (id: 2);
+  right_high:bool (id: 3);
 }
 
 root_type Output;
diff --git a/frc971/control_loops/drivetrain/drivetrain_position.fbs b/frc971/control_loops/drivetrain/drivetrain_position.fbs
index 900c036..3ada998 100644
--- a/frc971/control_loops/drivetrain/drivetrain_position.fbs
+++ b/frc971/control_loops/drivetrain/drivetrain_position.fbs
@@ -2,24 +2,24 @@
 
 table Position {
   // Relative position of each drivetrain side (in meters).
-  left_encoder:double;
-  right_encoder:double;
+  left_encoder:double (id: 0);
+  right_encoder:double (id: 1);
 
   // The speed in m/s of each drivetrain side from the most recent encoder
   // pulse, or 0 if there was no edge within the last 5ms.
-  left_speed:double;
-  right_speed:double;
+  left_speed:double (id: 2);
+  right_speed:double (id: 3);
 
   // Position of each drivetrain shifter, scaled from 0.0 to 1.0 where smaller
   // is towards low gear.
-  left_shifter_position:double;
-  right_shifter_position:double;
+  left_shifter_position:double (id: 4);
+  right_shifter_position:double (id: 5);
 
   // Raw analog voltages of each shifter hall effect for logging purposes.
-  low_left_hall:double;
-  high_left_hall:double;
-  low_right_hall:double;
-  high_right_hall:double;
+  low_left_hall:double (id: 6);
+  high_left_hall:double (id: 7);
+  low_right_hall:double (id: 8);
+  high_right_hall:double (id: 9);
 }
 
 root_type Position;
diff --git a/frc971/control_loops/drivetrain/drivetrain_status.fbs b/frc971/control_loops/drivetrain/drivetrain_status.fbs
index 3642131..5ce14e6 100644
--- a/frc971/control_loops/drivetrain/drivetrain_status.fbs
+++ b/frc971/control_loops/drivetrain/drivetrain_status.fbs
@@ -5,43 +5,43 @@
 // For logging information about what the code is doing with the shifters.
 table GearLogging {
   // Which controller is being used.
-  controller_index:byte;
+  controller_index:byte (id: 0);
 
   // Whether each loop for the drivetrain sides is the high-gear one.
-  left_loop_high:bool;
-  right_loop_high:bool;
+  left_loop_high:bool (id: 1);
+  right_loop_high:bool (id: 2);
 
   // The states of each drivetrain shifter.
-  left_state:byte;
-  right_state:byte;
+  left_state:byte (id: 3);
+  right_state:byte (id: 4);
 }
 
 // For logging information about the state of the shifters.
 table CIMLogging {
   // Whether the code thinks each drivetrain side is currently in gear.
-  left_in_gear:bool;
-  right_in_gear:bool;
+  left_in_gear:bool (id: 0);
+  right_in_gear:bool (id: 1);
 
   // The angular velocities (in rad/s, positive forward) the code thinks motors
   // on each side of the drivetrain are moving at.
-  left_motor_speed:double;
-  right_motor_speed:double;
+  left_motor_speed:double (id: 2);
+  right_motor_speed:double (id: 3);
 
   // The velocity estimates for each drivetrain side of the robot (in m/s,
   // positive forward) that can be used for shifting.
-  left_velocity:double;
-  right_velocity:double;
+  left_velocity:double (id: 4);
+  right_velocity:double (id: 5);
 }
 
 // Logging information for the polydrivetrain implementation.
 table PolyDriveLogging {
   // Calculated velocity goals for the left/right sides of the drivetrain, in
   // m/s.
-  goal_left_velocity:float;
-  goal_right_velocity:float;
+  goal_left_velocity:float (id: 0);
+  goal_right_velocity:float (id: 1);
   // Feedforward components of the left/right voltages.
-  ff_left_voltage:float;
-  ff_right_voltage:float;
+  ff_left_voltage:float (id: 2);
+  ff_right_voltage:float (id: 3);
 }
 
 enum PlanningState : byte {
@@ -54,84 +54,84 @@
 // For logging information about the state of the trajectory planning.
 table TrajectoryLogging {
   // state of planning the trajectory.
-  planning_state:PlanningState;
+  planning_state:PlanningState (id: 0);
 
   // State of the spline execution.
-  is_executing:bool;
+  is_executing:bool (id: 1);
   // Whether we have finished the spline specified by current_spline_idx.
-  is_executed:bool;
+  is_executed:bool (id: 2);
 
   // The handle of the goal spline.  0 means stop requested.
-  goal_spline_handle:int;
+  goal_spline_handle:int (id: 3);
   // Handle of the executing spline.  -1 means none requested.  If there was no
   // spline executing when a spline finished optimizing, it will become the
   // current spline even if we aren't ready to start yet.
-  current_spline_idx:int;
+  current_spline_idx:int (id: 4);
   // Handle of the spline that is being optimized and staged.
-  planning_spline_idx:int;
+  planning_spline_idx:int (id: 5);
 
   // Expected position and velocity on the spline
-  x:float;
-  y:float;
-  theta:float;
-  left_velocity:float;
-  right_velocity:float;
-  distance_remaining:float;
+  x:float (id: 6);
+  y:float (id: 7);
+  theta:float (id: 8);
+  left_velocity:float (id: 9);
+  right_velocity:float (id: 10);
+  distance_remaining:float (id: 11);
 }
 
 // For logging state of the line follower.
 table LineFollowLogging {
   // Whether we are currently freezing target choice.
-  frozen:bool;
+  frozen:bool (id: 0);
   // Whether we currently have a target.
-  have_target:bool;
+  have_target:bool (id: 1);
   // Absolute position of the current goal.
-  x:float;
-  y:float;
-  theta:float;
+  x:float (id: 2);
+  y:float (id: 3);
+  theta:float (id: 4);
   // Current lateral offset from line pointing straight out of the target.
-  offset:float;
+  offset:float (id: 5);
   // Current distance from the plane of the target, in meters.
-  distance_to_target:float;
+  distance_to_target:float (id: 6);
   // Current goal heading.
-  goal_theta:float;
+  goal_theta:float (id: 7);
   // Current relative heading.
-  rel_theta:float;
+  rel_theta:float (id: 8);
 }
 
 // Current states of the EKF. See hybrid_ekf.h for detailed comments.
 table LocalizerState {
   // X/Y field position, in meters.
-  x:float;
-  y:float;
+  x:float (id: 0);
+  y:float (id: 1);
   // Current heading, in radians.
-  theta:float;
+  theta:float (id: 2);
   // Current estimate of the left encoder position, in meters.
-  left_encoder:float;
+  left_encoder:float (id: 3);
   // Velocity of the left side of the robot.
-  left_velocity:float;
+  left_velocity:float (id: 4);
   // Current estimate of the right encoder position, in meters.
-  right_encoder:float;
+  right_encoder:float (id: 5);
   // Velocity of the right side of the robot.
-  right_velocity:float;
+  right_velocity:float (id: 6);
   // Current "voltage error" terms, in V.
-  left_voltage_error:float;
-  right_voltage_error:float;
+  left_voltage_error:float (id: 7);
+  right_voltage_error:float (id: 8);
   // Estimate of the offset between the encoder readings and true rotation of
   // the robot, in rad/sec.
-  angular_error:float;
+  angular_error:float (id: 9);
   // Current difference between the estimated longitudinal velocity of the robot
   // and that experienced by the wheels, in m/s.
-  longitudinal_velocity_offset:float;
+  longitudinal_velocity_offset:float (id: 10);
   // Lateral velocity of the robot, in m/s.
-  lateral_velocity:float;
+  lateral_velocity:float (id: 11);
 }
 
 table DownEstimatorState {
-  quaternion_x:double;
-  quaternion_y:double;
-  quaternion_z:double;
-  quaternion_w:double;
+  quaternion_x:double (id: 0);
+  quaternion_y:double (id: 1);
+  quaternion_z:double (id: 2);
+  quaternion_w:double (id: 3);
 
   // Side-to-side and forwards/backwards pitch numbers. Note that we do this
   // instead of standard roll/pitch/yaw euler angles because it was a pain to
@@ -141,116 +141,116 @@
   // the forwards to backwards pitch of the robot; longitudinal_pitch
   // corresponds with the traditional usage of "pitch".
   // All angles in radians.
-  lateral_pitch:float;
-  longitudinal_pitch:float;
+  lateral_pitch:float (id: 4);
+  longitudinal_pitch:float (id: 5);
   // Current yaw angle (heading) of the robot, as estimated solely by
   // integrating the Z-axis of the gyro (in rad).
-  yaw:float;
+  yaw:float (id: 6);
 
   // Current position of the robot, as determined solely from the
   // IMU/down-estimator, in meters.
-  position_x:float;
-  position_y:float;
-  position_z:float;
+  position_x:float (id: 7);
+  position_y:float (id: 8);
+  position_z:float (id: 9);
 
   // Current velocity of the robot, as determined solely from the
   // IMU/down-estimator, in meters / sec.
-  velocity_x:float;
-  velocity_y:float;
-  velocity_z:float;
+  velocity_x:float (id: 10);
+  velocity_y:float (id: 11);
+  velocity_z:float (id: 12);
 
   // Current acceleration of the robot, with pitch/roll (but not yaw)
   // compensated out, in meters / sec / sec.
-  accel_x:float;
-  accel_y:float;
-  accel_z:float;
+  accel_x:float (id: 13);
+  accel_y:float (id: 14);
+  accel_z:float (id: 15);
 
   // Current acceleration that we expect to see from the accelerometer, assuming
   // no acceleration other than that due to gravity, in g's.
-  expected_accel_x:float;
-  expected_accel_y:float;
-  expected_accel_z:float;
+  expected_accel_x:float (id: 16);
+  expected_accel_y:float (id: 17);
+  expected_accel_z:float (id: 18);
 
   // Current estimate of the overall acceleration due to gravity, in g's. Should
   // generally be within ~0.003 g's of 1.0.
-  gravity_magnitude:float;
+  gravity_magnitude:float (id: 19);
 
-  consecutive_still:int;
+  consecutive_still:int (id: 20);
 }
 
 table ImuZeroerState {
   // True if we have successfully zeroed the IMU.
-  zeroed:bool;
+  zeroed:bool (id: 0);
   // True if the zeroing code has observed some inconsistency in the IMU.
-  faulted:bool;
+  faulted:bool (id: 1);
   // Number of continuous zeroing measurements that we have accumulated for use
   // in the zeroing.
-  number_of_zeroes:int;
+  number_of_zeroes:int (id: 2);
 
   // Current zeroing values beind used for each gyro axis, in rad / sec.
-  gyro_x_average:float;
-  gyro_y_average:float;
-  gyro_z_average:float;
+  gyro_x_average:float (id: 3);
+  gyro_y_average:float (id: 4);
+  gyro_z_average:float (id: 5);
 }
 
 table Status {
   // Estimated speed of the center of the robot in m/s (positive forwards).
-  robot_speed:double;
+  robot_speed:double (id: 0);
 
   // Estimated relative position of each drivetrain side (in meters).
-  estimated_left_position:double;
-  estimated_right_position:double;
+  estimated_left_position:double (id: 1);
+  estimated_right_position:double (id: 2);
 
   // Estimated velocity of each drivetrain side (in m/s).
-  estimated_left_velocity:double;
-  estimated_right_velocity:double;
+  estimated_left_velocity:double (id: 3);
+  estimated_right_velocity:double (id: 4);
 
   // The voltage we wanted to send to each drivetrain side last cycle.
-  uncapped_left_voltage:double;
-  uncapped_right_voltage:double;
+  uncapped_left_voltage:double (id: 5);
+  uncapped_right_voltage:double (id: 6);
 
   // The voltage error for the left and right sides.
-  left_voltage_error:double;
-  right_voltage_error:double;
+  left_voltage_error:double (id: 7);
+  right_voltage_error:double (id: 8);
 
   // The profiled goal states.
-  profiled_left_position_goal:double;
-  profiled_right_position_goal:double;
-  profiled_left_velocity_goal:double;
-  profiled_right_velocity_goal:double;
+  profiled_left_position_goal:double (id: 9);
+  profiled_right_position_goal:double (id: 10);
+  profiled_left_velocity_goal:double (id: 11);
+  profiled_right_velocity_goal:double (id: 12);
 
   // The KF offset
-  estimated_angular_velocity_error:double;
+  estimated_angular_velocity_error:double (id: 13);
   // The KF estimated heading.
-  estimated_heading:double;
+  estimated_heading:double (id: 14);
 
   // xytheta of the robot.
-  x:double;
-  y:double;
-  theta:double;
+  x:double (id: 15);
+  y:double (id: 16);
+  theta:double (id: 17);
 
   // True if the output voltage was capped last cycle.
-  output_was_capped:bool;
+  output_was_capped:bool (id: 18);
 
   // The pitch of the robot relative to the ground--only includes
   // forwards/backwards rotation.
-  ground_angle:double;
+  ground_angle:double (id: 19);
 
   // Information about shifting logic and curent gear, for logging purposes
-  gear_logging:GearLogging;
-  cim_logging:CIMLogging;
+  gear_logging:GearLogging (id: 20);
+  cim_logging:CIMLogging (id: 21);
 
-  trajectory_logging:TrajectoryLogging;
+  trajectory_logging:TrajectoryLogging (id: 22);
 
-  line_follow_logging:LineFollowLogging;
+  line_follow_logging:LineFollowLogging (id: 23);
 
-  poly_drive_logging:PolyDriveLogging;
+  poly_drive_logging:PolyDriveLogging (id: 24);
 
-  down_estimator:DownEstimatorState;
+  down_estimator:DownEstimatorState (id: 25);
 
-  localizer:LocalizerState;
+  localizer:LocalizerState (id: 26);
 
-  zeroing:ImuZeroerState;
+  zeroing:ImuZeroerState (id: 27);
 }
 
 root_type Status;
diff --git a/frc971/control_loops/drivetrain/localizer.fbs b/frc971/control_loops/drivetrain/localizer.fbs
index 5450c08..31493e6 100644
--- a/frc971/control_loops/drivetrain/localizer.fbs
+++ b/frc971/control_loops/drivetrain/localizer.fbs
@@ -3,11 +3,11 @@
 // Allows you to reset the state of the localizer to a specific position on the
 // field.
 table LocalizerControl {
-  x:float;      // X position, meters
-  y:float;      // Y position, meters
-  theta:float;  // heading, radians
-  theta_uncertainty:double; // Uncertainty in theta.
-  keep_current_theta:bool; // Whether to keep the current theta value.
+  x:float (id: 0);      // X position, meters
+  y:float (id: 1);      // Y position, meters
+  theta:float (id: 2);  // heading, radians
+  theta_uncertainty:double (id: 3); // Uncertainty in theta.
+  keep_current_theta:bool (id: 4); // Whether to keep the current theta value.
 }
 
 root_type LocalizerControl;
diff --git a/frc971/control_loops/profiled_subsystem.fbs b/frc971/control_loops/profiled_subsystem.fbs
index 185133b..9ecb98c 100644
--- a/frc971/control_loops/profiled_subsystem.fbs
+++ b/frc971/control_loops/profiled_subsystem.fbs
@@ -4,244 +4,244 @@
 
 table ProfiledJointStatus {
   // Is the subsystem zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 1);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 2);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 3);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 4);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 5);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 6);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 7);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 8);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 9);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 10);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 11);
+  velocity_power:float (id: 12);
+  feedforwards_power:float (id: 13);
 
   // State of the estimator.
-  estimator_state:frc971.EstimatorState;
+  estimator_state:frc971.EstimatorState (id: 14);
 }
 
 table HallProfiledJointStatus {
   // Is the subsystem zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 1);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 2);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 3);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 4);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 5);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 6);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 7);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 8);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 9);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 10);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 11);
+  velocity_power:float (id: 12);
+  feedforwards_power:float (id: 13);
 
   // State of the estimator.
-  estimator_state:frc971.HallEffectAndPositionEstimatorState;
+  estimator_state:frc971.HallEffectAndPositionEstimatorState (id: 14);
 }
 
 table PotAndAbsoluteEncoderProfiledJointStatus {
   // Is the subsystem zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 1);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 2);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 3);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 4);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 5);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 6);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 7);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 8);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 9);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 10);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 11);
+  velocity_power:float (id: 12);
+  feedforwards_power:float (id: 13);
 
   // State of the estimator.
-  estimator_state:frc971.PotAndAbsoluteEncoderEstimatorState;
+  estimator_state:frc971.PotAndAbsoluteEncoderEstimatorState (id: 14);
 }
 
 table IndexProfiledJointStatus {
   // Is the subsystem zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 1);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 2);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 3);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 4);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 5);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 6);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 7);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 8);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 9);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 10);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 11);
+  velocity_power:float (id: 12);
+  feedforwards_power:float (id: 13);
 
   // State of the estimator.
-  estimator_state:frc971.IndexEstimatorState;
+  estimator_state:frc971.IndexEstimatorState (id: 14);
 }
 
 table AbsoluteEncoderProfiledJointStatus {
   // Is the subsystem zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 1);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 2);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 3);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 4);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 5);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 6);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 7);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 8);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 9);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 10);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 11);
+  velocity_power:float (id: 12);
+  feedforwards_power:float (id: 13);
 
   // State of the estimator.
-  estimator_state:frc971.AbsoluteEncoderEstimatorState;
+  estimator_state:frc971.AbsoluteEncoderEstimatorState (id: 14);
 }
 
 table RelativeEncoderProfiledJointStatus {
   // The state of the subsystem, if applicable.  -1 otherwise.
   // TODO(alex): replace with enum.
-  state:int;
+  state:int (id: 0);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 1);
 
   // Position of the joint.
-  position:float;
+  position:float (id: 2);
   // Velocity of the joint in units/second.
-  velocity:float;
+  velocity:float (id: 3);
   // Profiled goal position of the joint.
-  goal_position:float;
+  goal_position:float (id: 4);
   // Profiled goal velocity of the joint in units/second.
-  goal_velocity:float;
+  goal_velocity:float (id: 5);
   // Unprofiled goal position from absoulte zero  of the joint.
-  unprofiled_goal_position:float;
+  unprofiled_goal_position:float (id: 6);
   // Unprofiled goal velocity of the joint in units/second.
-  unprofiled_goal_velocity:float;
+  unprofiled_goal_velocity:float (id: 7);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 8);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 9);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 10);
+  velocity_power:float (id: 11);
+  feedforwards_power:float (id: 12);
 
   // State of the estimator.
-  estimator_state:frc971.RelativeEncoderEstimatorState;
+  estimator_state:frc971.RelativeEncoderEstimatorState (id: 13);
 }
 
 table StaticZeroingSingleDOFProfiledSubsystemGoal {
-  unsafe_goal:double;
+  unsafe_goal:double (id: 0);
 
-  profile_params:frc971.ProfileParameters;
+  profile_params:frc971.ProfileParameters (id: 1);
 
   // Sets the goal velocity of the subsystem.
-  goal_velocity:double;
+  goal_velocity:double (id: 2);
 
   // If set to true, then we will ignore the profiling on this joint and pass
   // the goal + goal velocity directly to the control loop.
-  ignore_profile:bool;
+  ignore_profile:bool (id: 3);
 }
diff --git a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.fbs b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.fbs
index da6e7ae..f824b3e 100644
--- a/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.fbs
+++ b/frc971/control_loops/static_zeroing_single_dof_profiled_subsystem_test.fbs
@@ -4,12 +4,12 @@
 namespace frc971.control_loops.zeroing.testing;
 
 table SubsystemGoal {
-  unsafe_goal:double;
-  profile_params:frc971.ProfileParameters;
-  goal_velocity:double;
-  ignore_profile:bool;
+  unsafe_goal:double (id: 0);
+  profile_params:frc971.ProfileParameters (id: 1);
+  goal_velocity:double (id: 2);
+  ignore_profile:bool (id: 3);
 }
 
 table SubsystemOutput {
-  output:double;
+  output:double (id: 0);
 }
diff --git a/frc971/queues/gyro.fbs b/frc971/queues/gyro.fbs
index a6dce45..d90a4b9 100644
--- a/frc971/queues/gyro.fbs
+++ b/frc971/queues/gyro.fbs
@@ -5,9 +5,9 @@
   // Positive is counter-clockwise (Austin says "it's Positive").
   // Right-hand coordinate system around the Z-axis going up.
   // The angle is measured in radians.
-  angle:double;
+  angle:double (id: 0);
   // The angular velocity in radians/sec
-  velocity:double;
+  velocity:double (id: 1);
 }
 
 root_type GyroReading;
diff --git a/frc971/queues/gyro_uid.fbs b/frc971/queues/gyro_uid.fbs
index 05934bf..86e61ee 100644
--- a/frc971/queues/gyro_uid.fbs
+++ b/frc971/queues/gyro_uid.fbs
@@ -2,7 +2,7 @@
 
 // Published on "/drivetrain"
 table Uid {
-  uid:uint;
+  uid:uint (id: 0);
 }
 
 root_type Uid;
diff --git a/frc971/wpilib/imu.fbs b/frc971/wpilib/imu.fbs
index 65b181b..abd01e2 100644
--- a/frc971/wpilib/imu.fbs
+++ b/frc971/wpilib/imu.fbs
@@ -7,7 +7,7 @@
   // applies when using scale sync mode (Register MSC_CTRL, Bits[4:2] = 010, see
   // Table 101). When this occurs, adjust the frequency of the clock signal on
   // the SYNC pin to operate within the appropriate range.
-  clock_error:bool;
+  clock_error:bool (id: 0);
 
   // True indicates a failure in the flash memory test (Register GLOB_CMD, Bit
   // 4, see Table 109), which involves a comparison between a cyclic redundancy
@@ -15,36 +15,36 @@
   // from the same memory locations at the time of initial programming (during
   // production process). If this occurs, repeat the same test.  If this error
   // persists, replace the ADIS16470 device.
-  memory_failure:bool;
+  memory_failure:bool (id: 1);
 
   // True indicates failure of at least one sensor, at the conclusion of the
   // self test (Register GLOB_CMD, Bit 2, see Table 109). If this occurs, repeat
   // the same test.  If this error persists, replace the ADIS16470. Motion,
   // during the execution of this test, can cause a false failure.
-  sensor_failure:bool;
+  sensor_failure:bool (id: 2);
 
   // True indicates that the voltage across VDD and GND is <2.8 V, which causes
   // data processing to stop. When VDD ≥ 2.8 V for 250 ms, the ADIS16470
   // reinitializes itself and starts producing data again.
-  standby_mode:bool;
+  standby_mode:bool (id: 3);
 
   // True indicates that the total number of SCLK cycles is not equal to an
   // integer multiple of 16. When this occurs, repeat the previous communication
   // sequence. Persistence in this error may indicate a weakness in the SPI
   // service that the ADIS16470 is receiving from the system it is supporting.
-  spi_communication_error:bool;
+  spi_communication_error:bool (id: 4);
 
   // True indicates that the most recent flash memory update (Register GLOB_CMD,
   // Bit 3, see Table 109) failed. If this occurs, ensure that VDD ≥ 3 V and
   // repeat the update attempt. If this error persists, replace the ADIS16470.
-  flash_memory_update_error:bool;
+  flash_memory_update_error:bool (id: 5);
 
   // True indicates that one of the data paths have experienced an overrun
   // condition. If this occurs, initiate a reset, using the RST pin (see Table
   // 5, Pin F3) or Register GLOB_CMD, Bit 7 (see Table 109). See the Serial Port
   // Operation section for more details on conditions that may cause this bit to
   // be set to 1.
-  data_path_overrun:bool;
+  data_path_overrun:bool (id: 6);
 }
 
 // Values returned from an IMU.
@@ -53,52 +53,52 @@
 table IMUValues {
   // Gyro readings in radians/second.
   // Positive is clockwise looking at the connector.
-  gyro_x:float;
+  gyro_x:float (id: 0);
   // Positive is clockwise looking at the right side (from the connector).
-  gyro_y:float;
+  gyro_y:float (id: 1);
   // Positive is counterclockwise looking at the top.
-  gyro_z:float;
+  gyro_z:float (id: 2);
 
   // Accelerometer readings in Gs.
   // Positive is up.
-  accelerometer_x:float;
+  accelerometer_x:float (id: 3);
   // Positive is away from the right side (from the connector).
-  accelerometer_y:float;
+  accelerometer_y:float (id: 4);
   // Positive is away from the connector.
-  accelerometer_z:float;
+  accelerometer_z:float (id: 5);
 
   // Magnetometer readings in gauss.
   // Positive is up.
-  magnetometer_x:float;
+  magnetometer_x:float (id: 6);
   // Positive is away from the right side (from the connector).
-  magnetometer_y:float;
+  magnetometer_y:float (id: 7);
   // Positive is away from the connector.
-  magnetometer_z:float;
+  magnetometer_z:float (id: 8);
 
   // Barometer readings in pascals.
-  barometer:float;
+  barometer:float (id: 9);
 
   // Temperature readings in degrees Celsius.
-  temperature:float;
+  temperature:float (id: 10);
 
   // FPGA timestamp when the values were captured.
-  fpga_timestamp:double;
+  fpga_timestamp:double (id: 11);
   // CLOCK_MONOTONIC time in nanoseconds when the values were captured,
   // converted from fpga_timestamp.
-  monotonic_timestamp_ns:long;
+  monotonic_timestamp_ns:long (id: 12);
 
   // For an ADIS16470, the DIAG_STAT value immediately after reset.
-  start_diag_stat:ADIS16470DiagStat;
+  start_diag_stat:ADIS16470DiagStat (id: 13);
   // For an ADIS16470, the DIAG_STAT value after the initial sensor self test we
   // trigger is finished.
-  self_test_diag_stat:ADIS16470DiagStat;
+  self_test_diag_stat:ADIS16470DiagStat (id: 14);
   // For an ADIS16470, the DIAG_STAT value associated with the previous set of
   // readings. This will never change during normal operation, so being 1 cycle
   // state is OK.
-  previous_reading_diag_stat:ADIS16470DiagStat;
+  previous_reading_diag_stat:ADIS16470DiagStat (id: 15);
 
   // The value read from the PROD_ID register.
-  product_id:uint16;
+  product_id:uint16 (id: 16);
 }
 
 root_type IMUValues;
diff --git a/frc971/wpilib/imu_batch.fbs b/frc971/wpilib/imu_batch.fbs
index 8029ced..1483314 100644
--- a/frc971/wpilib/imu_batch.fbs
+++ b/frc971/wpilib/imu_batch.fbs
@@ -3,7 +3,7 @@
 namespace frc971;
 
 table IMUValuesBatch {
-  readings:[IMUValues];
+  readings:[IMUValues] (id: 0);
 }
 
 root_type IMUValuesBatch;
diff --git a/frc971/wpilib/logging.fbs b/frc971/wpilib/logging.fbs
index fcb4235..d76412f 100644
--- a/frc971/wpilib/logging.fbs
+++ b/frc971/wpilib/logging.fbs
@@ -2,8 +2,8 @@
 
 // Information about the current state of the pneumatics system to log.
 table PneumaticsToLog {
-  compressor_on:bool;
-  read_solenoids:ubyte;
+  compressor_on:bool (id: 0);
+  read_solenoids:ubyte (id: 1);
 }
 
 root_type PneumaticsToLog;
diff --git a/frc971/wpilib/loop_output_handler_test.fbs b/frc971/wpilib/loop_output_handler_test.fbs
index ddd36d0..7bcb91b 100644
--- a/frc971/wpilib/loop_output_handler_test.fbs
+++ b/frc971/wpilib/loop_output_handler_test.fbs
@@ -2,7 +2,7 @@
 
 // Test output message.
 table LoopOutputHandlerTestOutput {
-  voltage:double;
+  voltage:double (id: 0);
 }
 
 root_type LoopOutputHandlerTestOutput;
diff --git a/frc971/wpilib/pdp_values.fbs b/frc971/wpilib/pdp_values.fbs
index 4db2ade..43afcc4 100644
--- a/frc971/wpilib/pdp_values.fbs
+++ b/frc971/wpilib/pdp_values.fbs
@@ -3,11 +3,11 @@
 // Values retrieved from the PDP.
 // Published on ".frc971.pdp_values"
 table PDPValues {
-  voltage:double;
-  temperature:double;
-  power:double;
+  voltage:double (id: 0);
+  temperature:double (id: 1);
+  power:double (id: 2);
   // Array of 16 currents.
-  currents:[double];
+  currents:[double] (id: 3);
 }
 
 root_type PDPValues;
diff --git a/y2012/control_loops/accessories/accessories.fbs b/y2012/control_loops/accessories/accessories.fbs
index 1174b55..0840da4 100644
--- a/y2012/control_loops/accessories/accessories.fbs
+++ b/y2012/control_loops/accessories/accessories.fbs
@@ -1,8 +1,8 @@
 namespace y2012.control_loops.accessories;
 
 table Message {
-  solenoids:[bool]; // Exactly 3 values
-  sticks:[double]; // Exactly 2 values
+  solenoids:[bool] (id: 0); // Exactly 3 values
+  sticks:[double] (id: 1); // Exactly 2 values
 }
 
 root_type Message;
diff --git a/y2016/actors/superstructure_action.fbs b/y2016/actors/superstructure_action.fbs
index 405f35b..3a86888 100644
--- a/y2016/actors/superstructure_action.fbs
+++ b/y2016/actors/superstructure_action.fbs
@@ -2,15 +2,15 @@
 
 // Parameters to send with start.
 table SuperstructureActionParams {
-  partial_angle:double;
-  delay_time:double;
-  full_angle:double;
-  shooter_angle:double;
+  partial_angle:double (id: 0);
+  delay_time:double (id: 1);
+  full_angle:double (id: 2);
+  shooter_angle:double (id: 3);
 }
 
 table Goal {
-  run:uint;
-  params:SuperstructureActionParams;
+  run:uint (id: 0);
+  params:SuperstructureActionParams (id: 1);
 }
 
 root_type Goal;
diff --git a/y2016/actors/vision_align_action.fbs b/y2016/actors/vision_align_action.fbs
index 1dd66fc..8b8ea46 100644
--- a/y2016/actors/vision_align_action.fbs
+++ b/y2016/actors/vision_align_action.fbs
@@ -2,12 +2,12 @@
 
 // Parameters to send with start.
 table VisionAlignActionParams {
-  run:int;
+  run:int (id: 0);
 }
 
 table Goal {
-  run:uint;
-  params:VisionAlignActionParams;
+  run:uint (id: 0);
+  params:VisionAlignActionParams (id: 1);
 }
 
 root_type Goal;
diff --git a/y2016/control_loops/shooter/shooter_goal.fbs b/y2016/control_loops/shooter/shooter_goal.fbs
index f041503..5931d57 100644
--- a/y2016/control_loops/shooter/shooter_goal.fbs
+++ b/y2016/control_loops/shooter/shooter_goal.fbs
@@ -4,20 +4,20 @@
 // For all angular velocities, positive is shooting the ball out of the robot.
 table Goal {
   // Angular velocity goals in radians/second.
-  angular_velocity:double;
+  angular_velocity:double (id: 0);
 
-  clamp_open:bool; // True to release our clamp on the ball.
+  clamp_open:bool (id: 1); // True to release our clamp on the ball.
   // True to push the ball into the shooter.
   // If we are in the act of shooting with a goal velocity != 0, wait until it
   // is up to speed, push the ball into the shooter, and then wait until it
   // spins up and down before letting the piston be released.
-  push_to_shooter:bool;
+  push_to_shooter:bool (id: 2);
 
   // Forces the lights on.
-  force_lights_on:bool;
+  force_lights_on:bool (id: 3);
 
   // If true, the robot is shooting forwards.
-  shooting_forwards:bool;
+  shooting_forwards:bool (id: 4);
 }
 
 root_type Goal;
diff --git a/y2016/control_loops/shooter/shooter_output.fbs b/y2016/control_loops/shooter/shooter_output.fbs
index 6d7fcdf..a1f3914 100644
--- a/y2016/control_loops/shooter/shooter_output.fbs
+++ b/y2016/control_loops/shooter/shooter_output.fbs
@@ -2,18 +2,18 @@
 
 table Output {
   // Voltage in volts of the left and right shooter motors.
-  voltage_left:double;
-  voltage_right:double;
+  voltage_left:double (id: 0);
+  voltage_right:double (id: 1);
 
   // See comments on the identical fields in Goal for details.
-  clamp_open:bool;
-  push_to_shooter:bool;
+  clamp_open:bool (id: 2);
+  push_to_shooter:bool (id: 3);
 
   // If true, the lights are on.
-  lights_on:bool;
+  lights_on:bool (id: 4);
 
-  forwards_flashlight:bool;
-  backwards_flashlight:bool;
+  forwards_flashlight:bool (id: 5);
+  backwards_flashlight:bool (id: 6);
 }
 
 root_type Output;
diff --git a/y2016/control_loops/shooter/shooter_position.fbs b/y2016/control_loops/shooter/shooter_position.fbs
index d97268c..27ac7d8 100644
--- a/y2016/control_loops/shooter/shooter_position.fbs
+++ b/y2016/control_loops/shooter/shooter_position.fbs
@@ -4,8 +4,8 @@
 // For all angular velocities, positive is shooting the ball out of the robot.
 table Position {
   // Wheel angle in radians/second.
-  theta_left:double;
-  theta_right:double;
+  theta_left:double (id: 0);
+  theta_right:double (id: 1);
 }
 
 root_type Position;
diff --git a/y2016/control_loops/shooter/shooter_status.fbs b/y2016/control_loops/shooter/shooter_status.fbs
index 6f6262b..0ea54e5 100644
--- a/y2016/control_loops/shooter/shooter_status.fbs
+++ b/y2016/control_loops/shooter/shooter_status.fbs
@@ -2,26 +2,26 @@
 
 table ShooterSideStatus {
   // True if the shooter side is up to speed and stable.
-  ready:bool;
+  ready:bool (id: 0);
   // The current average velocity in radians/second.
-  avg_angular_velocity:double;
+  avg_angular_velocity:double (id: 1);
   // The current instantaneous filtered velocity in radians/second.
-  angular_velocity:double;
+  angular_velocity:double (id: 2);
 }
 
 table Status {
   // Left side status.
-  left:ShooterSideStatus;
+  left:ShooterSideStatus (id: 0);
   // Right side status.
-  right:ShooterSideStatus;
+  right:ShooterSideStatus (id: 1);
 
   // True if the shooter is ready.  It is better to compare the velocities
   // directly so there isn't confusion on if the goal is up to date.
-  ready:bool;
+  ready:bool (id: 2);
 
   // The number of shots that have been fired since the start of the shooter
   // control loop.
-  shots:uint;
+  shots:uint (id: 3);
 }
 
 root_type Status;
diff --git a/y2016/control_loops/superstructure/superstructure_goal.fbs b/y2016/control_loops/superstructure/superstructure_goal.fbs
index 4274bd8..efba4a7 100644
--- a/y2016/control_loops/superstructure/superstructure_goal.fbs
+++ b/y2016/control_loops/superstructure/superstructure_goal.fbs
@@ -15,36 +15,36 @@
   // to the big frame supporting the shooter.
 
   // Goal angles and angular velocities of the superstructure subsystems.
-  angle_intake:double;
-  angle_shoulder:double;
+  angle_intake:double (id: 0);
+  angle_shoulder:double (id: 1);
   // In relation to the ground plane.
-  angle_wrist:double;
+  angle_wrist:double (id: 2);
 
   // Caps on velocity/acceleration for profiling. 0 for the default.
-  max_angular_velocity_intake:float;
-  max_angular_velocity_shoulder:float;
-  max_angular_velocity_wrist:float;
+  max_angular_velocity_intake:float (id: 3);
+  max_angular_velocity_shoulder:float (id: 4);
+  max_angular_velocity_wrist:float (id: 5);
 
-  max_angular_acceleration_intake:float;
-  max_angular_acceleration_shoulder:float;
-  max_angular_acceleration_wrist:float;
+  max_angular_acceleration_intake:float (id: 6);
+  max_angular_acceleration_shoulder:float (id: 7);
+  max_angular_acceleration_wrist:float (id: 8);
 
   // Voltage to send to the rollers. Positive is sucking in.
-  voltage_top_rollers:float;
-  voltage_bottom_rollers:float;
+  voltage_top_rollers:float (id: 9);
+  voltage_bottom_rollers:float (id: 10);
 
   // Voltage to sent to the climber. Positive is pulling the robot up.
-  voltage_climber:float;
+  voltage_climber:float (id: 11);
   // If true, unlatch the climber and allow it to unfold.
-  unfold_climber:bool;
+  unfold_climber:bool (id: 12);
 
-  force_intake:bool;
+  force_intake:bool (id: 13);
 
   // If true, release the latch which holds the traverse mechanism in the
   // middle.
-  traverse_unlatched:bool;
+  traverse_unlatched:bool (id: 14);
   // If true, fire the traverse mechanism down.
-  traverse_down:bool;
+  traverse_down:bool (id: 15);
 }
 
 root_type Goal;
diff --git a/y2016/control_loops/superstructure/superstructure_output.fbs b/y2016/control_loops/superstructure/superstructure_output.fbs
index 40a0091..7e790cd 100644
--- a/y2016/control_loops/superstructure/superstructure_output.fbs
+++ b/y2016/control_loops/superstructure/superstructure_output.fbs
@@ -1,22 +1,22 @@
 namespace y2016.control_loops.superstructure;
 
 table Output {
-  voltage_intake:float;
-  voltage_shoulder:float;
-  voltage_wrist:float;
+  voltage_intake:float (id: 0);
+  voltage_shoulder:float (id: 1);
+  voltage_wrist:float (id: 2);
 
-  voltage_top_rollers:float;
-  voltage_bottom_rollers:float;
+  voltage_top_rollers:float (id: 3);
+  voltage_bottom_rollers:float (id: 4);
 
   // Voltage to sent to the climber. Positive is pulling the robot up.
-  voltage_climber:float;
+  voltage_climber:float (id: 5);
   // If true, release the latch to trigger the climber to unfold.
-  unfold_climber:bool;
+  unfold_climber:bool (id: 6);
 
   // If true, release the latch to hold the traverse mechanism in the middle.
-  traverse_unlatched:bool;
+  traverse_unlatched:bool (id: 7);
   // If true, fire the traverse mechanism down.
-  traverse_down:bool;
+  traverse_down:bool (id: 8);
 }
 
 root_type Output;
diff --git a/y2016/control_loops/superstructure/superstructure_position.fbs b/y2016/control_loops/superstructure/superstructure_position.fbs
index fb356e0..3660e43 100644
--- a/y2016/control_loops/superstructure/superstructure_position.fbs
+++ b/y2016/control_loops/superstructure/superstructure_position.fbs
@@ -11,9 +11,9 @@
   // the shooter wheels pointed towards the shoulder joint.  This is measured
   // relative to the arm, not the ground, not like the world we actually
   // present to users.
-  intake:frc971.PotAndIndexPosition;
-  shoulder:frc971.PotAndIndexPosition;
-  wrist:frc971.PotAndIndexPosition;
+  intake:frc971.PotAndIndexPosition (id: 0);
+  shoulder:frc971.PotAndIndexPosition (id: 1);
+  wrist:frc971.PotAndIndexPosition (id: 2);
 }
 
 root_type Position;
diff --git a/y2016/control_loops/superstructure/superstructure_status.fbs b/y2016/control_loops/superstructure/superstructure_status.fbs
index 373bfe2..84648ac 100644
--- a/y2016/control_loops/superstructure/superstructure_status.fbs
+++ b/y2016/control_loops/superstructure/superstructure_status.fbs
@@ -4,53 +4,53 @@
 
 table JointState {
   // Angle of the joint in radians.
-  angle:float;
+  angle:float (id: 0);
   // Angular velocity of the joint in radians/second.
-  angular_velocity:float;
+  angular_velocity:float (id: 1);
   // Profiled goal angle of the joint in radians.
-  goal_angle:float;
+  goal_angle:float (id: 2);
   // Profiled goal angular velocity of the joint in radians/second.
-  goal_angular_velocity:float;
+  goal_angular_velocity:float (id: 3);
   // Unprofiled goal angle of the joint in radians.
-  unprofiled_goal_angle:float;
+  unprofiled_goal_angle:float (id: 4);
   // Unprofiled goal angular velocity of the joint in radians/second.
-  unprofiled_goal_angular_velocity:float;
+  unprofiled_goal_angular_velocity:float (id: 5);
 
   // The estimated voltage error.
-  voltage_error:float;
+  voltage_error:float (id: 6);
 
   // The calculated velocity with delta x/delta t
-  calculated_velocity:float;
+  calculated_velocity:float (id: 7);
 
   // Components of the control loop output
-  position_power:float;
-  velocity_power:float;
-  feedforwards_power:float;
+  position_power:float (id: 8);
+  velocity_power:float (id: 9);
+  feedforwards_power:float (id: 10);
 
   // State of the estimator.
-  estimator_state:frc971.EstimatorState;
+  estimator_state:frc971.EstimatorState (id: 11);
 }
 
 table Status {
   // Are the superstructure subsystems zeroed?
-  zeroed:bool;
+  zeroed:bool (id: 0);
 
   // If true, we have aborted.
-  estopped:bool;
+  estopped:bool (id: 1);
 
   // The internal state of the state machine.
-  state:int;
+  state:int (id: 2);
 
 
   // Estimated angles and angular velocities of the superstructure subsystems.
-  intake:JointState;
-  shoulder:JointState;
-  wrist:JointState;
+  intake:JointState (id: 3);
+  shoulder:JointState (id: 4);
+  wrist:JointState (id: 5);
 
-  shoulder_controller_index:int;
+  shoulder_controller_index:int (id: 6);
 
   // Is the superstructure collided?
-  is_collided:bool;
+  is_collided:bool (id: 7);
 }
 
 root_type Status;
diff --git a/y2016/queues/ball_detector.fbs b/y2016/queues/ball_detector.fbs
index c4ef07c..1ebe28c 100644
--- a/y2016/queues/ball_detector.fbs
+++ b/y2016/queues/ball_detector.fbs
@@ -9,7 +9,7 @@
   // TODO(comran): Check to see if our sensor's output corresponds with the
   // comment above.
 
-  voltage:double;
+  voltage:double (id: 0);
 }
 
 root_type BallDetector;
diff --git a/y2016/vision/vision.fbs b/y2016/vision/vision.fbs
index 4394b10..00209d9 100644
--- a/y2016/vision/vision.fbs
+++ b/y2016/vision/vision.fbs
@@ -2,37 +2,37 @@
 
 // Published on ".y2016.vision.vision_status"
 table VisionStatus {
-  left_image_valid:bool;
-  right_image_valid:bool;
+  left_image_valid:bool (id: 0);
+  right_image_valid:bool (id: 1);
   // Times when the images were taken as nanoseconds on CLOCK_MONOTONIC on the
   // TK1.
-  left_image_timestamp:long;
-  right_image_timestamp:long;
+  left_image_timestamp:long (id: 2);
+  right_image_timestamp:long (id: 3);
   // Times when the images were sent from the TK1 as nanoseconds on the TK1's
   // CLOCK_MONOTONIC.
-  left_send_timestamp:long;
-  right_send_timestamp:long;
+  left_send_timestamp:long (id: 4);
+  right_send_timestamp:long (id: 5);
 
   // Horizontal angle of the goal in radians.
   // TODO(Brian): Figure out which way is positive.
-  horizontal_angle:double;
+  horizontal_angle:double (id: 6);
   // Vertical angle of the goal in radians.
   // TODO(Brian): Figure out which way is positive.
-  vertical_angle:double;
+  vertical_angle:double (id: 7);
   // Distance to the target in meters.
-  distance:double;
+  distance:double (id: 8);
   // The angle in radians of the bottom of the target.
-  angle:double;
+  angle:double (id: 9);
 
   // Capture time of the angle using the clock behind monotonic_clock::now().
-  target_time:long;
+  target_time:long (id: 10);
 
   // The estimated positions of both sides of the drivetrain when the frame
   // was captured.
   // These are the estimated_left_position and estimated_right_position members
   // of the drivetrain queue.
-  drivetrain_left_position:double;
-  drivetrain_right_position:double;
+  drivetrain_left_position:double (id: 11);
+  drivetrain_right_position:double (id: 12);
 }
 
 root_type VisionStatus;