added a force fire mode to the indexer for clearing jams
diff --git a/frc971/autonomous/auto.cc b/frc971/autonomous/auto.cc
index 673368a..9b41633 100644
--- a/frc971/autonomous/auto.cc
+++ b/frc971/autonomous/auto.cc
@@ -50,25 +50,25 @@
 void StartIndex() {
   LOG(INFO, "Starting index\n");
   control_loops::index_loop.goal.MakeWithBuilder()
-    .goal_state(2).Send();
+    .goal_state(2).force_fire(false).Send();
 }
 
 void PreloadIndex() {
   LOG(INFO, "Preloading index\n");
   control_loops::index_loop.goal.MakeWithBuilder()
-    .goal_state(3).Send();
+    .goal_state(3).force_fire(false).Send();
 }
 
 void ShootIndex() {
   LOG(INFO, "Shooting index\n");
   control_loops::index_loop.goal.MakeWithBuilder()
-    .goal_state(4).Send();
+    .goal_state(4).force_fire(false).Send();
 }
 
 void ResetIndex() {
   LOG(INFO, "Resetting index\n");
   control_loops::index_loop.goal.MakeWithBuilder()
-    .goal_state(5).Send();
+    .goal_state(5).force_fire(false).Send();
 }
 
 void WaitForIndexReset() {
diff --git a/frc971/control_loops/index/index.cc b/frc971/control_loops/index/index.cc
index 4c82517..bec7992 100644
--- a/frc971/control_loops/index/index.cc
+++ b/frc971/control_loops/index/index.cc
@@ -833,8 +833,10 @@
       disc_clamped_ = false;
       disc_ejected_ = false;
       if (loader_goal_ == LoaderGoal::GRAB ||
-          loader_goal_ == LoaderGoal::SHOOT_AND_RESET) {
-        if (loader_goal_ == LoaderGoal::GRAB) {
+          loader_goal_ == LoaderGoal::SHOOT_AND_RESET || goal->force_fire) {
+        if (goal->force_fire) {
+          LOG(INFO, "Told to force fire, moving on\n");
+        } else if (loader_goal_ == LoaderGoal::GRAB) {
           LOG(INFO, "Told to GRAB, moving on\n");
         } else {
           LOG(INFO, "Told to SHOOT_AND_RESET, moving on\n");
@@ -862,7 +864,7 @@
       loader_up_ = false;
       disc_clamped_ = true;
       disc_ejected_ = false;
-      if (loader_goal_ == LoaderGoal::SHOOT_AND_RESET) {
+      if (loader_goal_ == LoaderGoal::SHOOT_AND_RESET || goal->force_fire) {
         shooter.status.FetchLatest();
         if (shooter.status.get()) {
           // TODO(aschuh): If we aren't shooting nicely, wait until the shooter
diff --git a/frc971/control_loops/index/index_motor.q b/frc971/control_loops/index/index_motor.q
index b125e38..94e65b9 100644
--- a/frc971/control_loops/index/index_motor.q
+++ b/frc971/control_loops/index/index_motor.q
@@ -14,6 +14,8 @@
     // 4 means shoot at will.
     // 5 means re-initialize
     int32_t goal_state;
+    // Forces the loader to fire.
+    bool force_fire;
   };
 
   message Position {
diff --git a/frc971/input/JoystickReader.cc b/frc971/input/JoystickReader.cc
index 8035bed..bbac61e 100644
--- a/frc971/input/JoystickReader.cc
+++ b/frc971/input/JoystickReader.cc
@@ -187,6 +187,7 @@
         // get ready to intake
         index_goal->goal_state = 1;
       }
+      index_goal->force_fire = Pressed(2, 12);
 
       index_goal.Send();
       shooter_goal.Send();