Merge "Refactoring logger_test into separate files"
diff --git a/frc971/autonomous/base_autonomous_actor.cc b/frc971/autonomous/base_autonomous_actor.cc
index ca6cc89..90c1454 100644
--- a/frc971/autonomous/base_autonomous_actor.cc
+++ b/frc971/autonomous/base_autonomous_actor.cc
@@ -177,6 +177,24 @@
   return false;
 }
 
+double BaseAutonomousActor::X() {
+  drivetrain_status_fetcher_.Fetch();
+  CHECK(drivetrain_status_fetcher_.get());
+  return drivetrain_status_fetcher_->x();
+}
+
+double BaseAutonomousActor::Y() {
+  drivetrain_status_fetcher_.Fetch();
+  CHECK(drivetrain_status_fetcher_.get());
+  return drivetrain_status_fetcher_->y();
+}
+
+double BaseAutonomousActor::Theta() {
+  drivetrain_status_fetcher_.Fetch();
+  CHECK(drivetrain_status_fetcher_.get());
+  return drivetrain_status_fetcher_->theta();
+}
+
 bool BaseAutonomousActor::WaitForAboveAngle(double angle) {
   ::aos::time::PhasedLoop phased_loop(frc971::controls::kLoopFrequency,
                                       event_loop()->monotonic_now(),
@@ -412,18 +430,26 @@
     //     when we reach the end of the spline).
     // (b) The spline that we are executing is the correct one.
     // (c) There is less than distance distance remaining.
+    if (base_autonomous_actor_->drivetrain_status_fetcher_->trajectory_logging()
+            ->goal_spline_handle() != spline_handle_) {
+      // Never done if we aren't the active spline.
+      return false;
+    }
+
+    if (base_autonomous_actor_->drivetrain_status_fetcher_->trajectory_logging()
+            ->is_executed()) {
+      return true;
+    }
     return base_autonomous_actor_->drivetrain_status_fetcher_
                ->trajectory_logging()
                ->is_executing() &&
            base_autonomous_actor_->drivetrain_status_fetcher_
                    ->trajectory_logging()
-                   ->goal_spline_handle() == spline_handle_ &&
-           base_autonomous_actor_->drivetrain_status_fetcher_
-                   ->trajectory_logging()
                    ->distance_remaining() < distance;
   }
   return false;
 }
+
 bool BaseAutonomousActor::SplineHandle::WaitForSplineDistanceRemaining(
     double distance) {
   ::aos::time::PhasedLoop phased_loop(
diff --git a/frc971/autonomous/base_autonomous_actor.h b/frc971/autonomous/base_autonomous_actor.h
index a70a440..5562dde 100644
--- a/frc971/autonomous/base_autonomous_actor.h
+++ b/frc971/autonomous/base_autonomous_actor.h
@@ -91,6 +91,11 @@
   // Returns true if the drive has finished.
   bool IsDriveDone();
 
+  // Returns the current x, y, theta of the robot on the field.
+  double X();
+  double Y();
+  double Theta();
+
   void LineFollowAtVelocity(
       double velocity,
       y2019::control_loops::drivetrain::SelectionHint hint =
diff --git a/scouting/db/db.go b/scouting/db/db.go
index bc32e12..3791596 100644
--- a/scouting/db/db.go
+++ b/scouting/db/db.go
@@ -7,6 +7,7 @@
 	"gorm.io/gorm"
 	"gorm.io/gorm/clause"
 	"gorm.io/gorm/logger"
+	"strconv"
 )
 
 type Database struct {
@@ -19,7 +20,7 @@
 	CompLevel        string `gorm:"primaryKey"`
 	Alliance         string `gorm:"primaryKey"` // "R" or "B"
 	AlliancePosition int32  `gorm:"primaryKey"` // 1, 2, or 3
-	TeamNumber       int32
+	TeamNumber       string
 }
 
 type Shift struct {
@@ -76,6 +77,8 @@
 	LowCubes, MiddleCubes, HighCubes, CubesDropped                 int32
 	LowCones, MiddleCones, HighCones, ConesDropped                 int32
 	AvgCycle                                                       int64
+	DockedAuto, EngagedAuto                                        bool
+	Docked, Engaged                                                bool
 	// The username of the person who collected these statistics.
 	// "unknown" if submitted without logging in.
 	// Empty if the stats have not yet been collected.
@@ -195,7 +198,7 @@
 }
 
 func (database *Database) AddToStats(s Stats) error {
-	matches, err := database.queryMatches(s.TeamNumber)
+	matches, err := database.queryMatches(strconv.Itoa(int(s.TeamNumber)))
 	if err != nil {
 		return err
 	}
@@ -344,7 +347,7 @@
 	return rankins, result.Error
 }
 
-func (database *Database) queryMatches(teamNumber_ int32) ([]TeamMatch, error) {
+func (database *Database) queryMatches(teamNumber_ string) ([]TeamMatch, error) {
 	var matches []TeamMatch
 	result := database.
 		Where("team_number = $1", teamNumber_).
diff --git a/scouting/db/db_test.go b/scouting/db/db_test.go
index a6bfa79..72c5f86 100644
--- a/scouting/db/db_test.go
+++ b/scouting/db/db_test.go
@@ -6,7 +6,6 @@
 	"os"
 	"os/exec"
 	"reflect"
-	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -75,27 +74,27 @@
 	correct := []TeamMatch{
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 9999,
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "9999",
 		},
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1000,
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1000",
 		},
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 777,
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "777",
 		},
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 0000,
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "0000",
 		},
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 4321,
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "4321",
 		},
 		TeamMatch{
 			MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1234,
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1234",
 		},
 	}
 
@@ -202,17 +201,17 @@
 	}
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1236},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1236"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1001},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1001"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 777},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "777"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 1000},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "1000"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 4321},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "4321"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1234},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1234"},
 	}
 
 	for _, match := range matches {
@@ -246,7 +245,8 @@
 			ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 1, CubesDropped: 0, LowCones: 0,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 0, CollectedBy: "emma",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "emma",
 		},
 		Stats2023{
 			TeamNumber: "7454", MatchNumber: 3, SetNumber: 1,
@@ -256,7 +256,8 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 0,
 			HighCubes: 0, CubesDropped: 1, LowCones: 0,
 			MiddleCones: 0, HighCones: 1, ConesDropped: 0,
-			AvgCycle: 0, CollectedBy: "tyler",
+			AvgCycle: 0, DockedAuto: false, EngagedAuto: false,
+			Docked: true, Engaged: true, CollectedBy: "tyler",
 		},
 		Stats2023{
 			TeamNumber: "4354", MatchNumber: 3, SetNumber: 1,
@@ -266,7 +267,8 @@
 			ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
 			HighCubes: 2, CubesDropped: 1, LowCones: 1,
 			MiddleCones: 1, HighCones: 0, ConesDropped: 1,
-			AvgCycle: 0, CollectedBy: "isaac",
+			AvgCycle: 0, DockedAuto: false, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "isaac",
 		},
 		Stats2023{
 			TeamNumber: "6533", MatchNumber: 3, SetNumber: 1,
@@ -276,7 +278,8 @@
 			ConesDroppedAuto: 0, LowCubes: 0, MiddleCubes: 1,
 			HighCubes: 2, CubesDropped: 1, LowCones: 0,
 			MiddleCones: 1, HighCones: 0, ConesDropped: 0,
-			AvgCycle: 0, CollectedBy: "will",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: true,
+			Docked: false, Engaged: false, CollectedBy: "will",
 		},
 		Stats2023{
 			TeamNumber: "8354", MatchNumber: 3, SetNumber: 1,
@@ -286,21 +289,22 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 0,
 			HighCubes: 0, CubesDropped: 2, LowCones: 1,
 			MiddleCones: 1, HighCones: 0, ConesDropped: 1,
-			AvgCycle: 0, CollectedBy: "unkown",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: false,
+			Docked: true, Engaged: false, CollectedBy: "unkown",
 		},
 	}
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 6344},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "6344"},
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 7454},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "7454"},
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 4354},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "4354"},
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 6533},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "6533"},
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 8354},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "8354"},
 	}
 
 	for _, match := range matches {
@@ -334,7 +338,8 @@
 			ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 1, CubesDropped: 0, LowCones: 0,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 0, CollectedBy: "emma",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "emma",
 		},
 		Stats2023{
 			TeamNumber: "7454", MatchNumber: 4, SetNumber: 1,
@@ -344,7 +349,8 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 0,
 			HighCubes: 0, CubesDropped: 1, LowCones: 0,
 			MiddleCones: 0, HighCones: 1, ConesDropped: 0,
-			AvgCycle: 0, CollectedBy: "tyler",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: true,
+			Docked: false, Engaged: false, CollectedBy: "tyler",
 		},
 		Stats2023{
 			TeamNumber: "6344", MatchNumber: 5, SetNumber: 1,
@@ -354,17 +360,18 @@
 			ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 1, CubesDropped: 0, LowCones: 0,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 0, CollectedBy: "emma",
+			AvgCycle: 0, DockedAuto: true, EngagedAuto: false,
+			Docked: true, Engaged: false, CollectedBy: "emma",
 		},
 	}
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 6344},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "6344"},
 		TeamMatch{MatchNumber: 4, SetNumber: 1, CompLevel: "qm",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 7454},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "7454"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "qm",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 6344},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "6344"},
 	}
 
 	for _, match := range matches {
@@ -413,17 +420,17 @@
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1236},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1236"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1001},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1001"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 777},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "777"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 1000},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "1000"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 4321},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "4321"},
 		TeamMatch{MatchNumber: 7, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1234},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1234"},
 	}
 
 	for _, match := range matches {
@@ -458,7 +465,8 @@
 			ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 1,
 			HighCubes: 2, CubesDropped: 1, LowCones: 1,
 			MiddleCones: 0, HighCones: 1, ConesDropped: 2,
-			AvgCycle: 58, CollectedBy: "unknown",
+			AvgCycle: 58, DockedAuto: false, EngagedAuto: false,
+			Docked: true, Engaged: true, CollectedBy: "unknown",
 		},
 		Stats2023{
 			TeamNumber: "2314", MatchNumber: 5, SetNumber: 1,
@@ -468,7 +476,8 @@
 			ConesDroppedAuto: 0, LowCubes: 2, MiddleCubes: 0,
 			HighCubes: 1, CubesDropped: 0, LowCones: 0,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 0,
-			AvgCycle: 34, CollectedBy: "simon",
+			AvgCycle: 34, DockedAuto: true, EngagedAuto: true,
+			Docked: true, Engaged: false, CollectedBy: "simon",
 		},
 		Stats2023{
 			TeamNumber: "3242", MatchNumber: 5, SetNumber: 1,
@@ -478,7 +487,8 @@
 			ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 2,
 			MiddleCones: 0, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 50, CollectedBy: "eliza",
+			AvgCycle: 50, DockedAuto: false, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "eliza",
 		},
 		Stats2023{
 			TeamNumber: "1742", MatchNumber: 5, SetNumber: 1,
@@ -488,7 +498,8 @@
 			ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 1,
 			HighCubes: 2, CubesDropped: 1, LowCones: 0,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 49, CollectedBy: "isaac",
+			AvgCycle: 49, DockedAuto: true, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "isaac",
 		},
 		Stats2023{
 			TeamNumber: "2454", MatchNumber: 5, SetNumber: 1,
@@ -498,7 +509,8 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 1,
 			MiddleCones: 1, HighCones: 1, ConesDropped: 0,
-			AvgCycle: 70, CollectedBy: "sam",
+			AvgCycle: 70, DockedAuto: true, EngagedAuto: true,
+			Docked: false, Engaged: false, CollectedBy: "sam",
 		},
 	}
 
@@ -511,7 +523,8 @@
 			ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 2,
 			MiddleCones: 0, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 50, CollectedBy: "eliza",
+			AvgCycle: 50, DockedAuto: false, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "eliza",
 		},
 		Stats2023{
 			TeamNumber: "2454", MatchNumber: 5, SetNumber: 1,
@@ -521,31 +534,32 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 1,
 			MiddleCones: 1, HighCones: 1, ConesDropped: 0,
-			AvgCycle: 70, CollectedBy: "sam",
+			AvgCycle: 70, DockedAuto: true, EngagedAuto: true,
+			Docked: false, Engaged: false, CollectedBy: "sam",
 		},
 	}
 
 	originalMatches := []TeamMatch{
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1111},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1111"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 2314},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "2314"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 1742},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "1742"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 2454},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "2454"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 3242},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "3242"},
 	}
 
 	// Matches for which we want to delete the stats.
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			TeamNumber: 1111},
+			TeamNumber: "1111"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			TeamNumber: 2314},
+			TeamNumber: "2314"},
 		TeamMatch{MatchNumber: 5, SetNumber: 1, CompLevel: "quals",
-			TeamNumber: 1742},
+			TeamNumber: "1742"},
 	}
 
 	for _, match := range originalMatches {
@@ -560,7 +574,7 @@
 	}
 
 	for _, match := range matches {
-		err := fixture.db.DeleteFromStats(match.CompLevel, match.MatchNumber, match.SetNumber, strconv.Itoa(int(match.TeamNumber)))
+		err := fixture.db.DeleteFromStats(match.CompLevel, match.MatchNumber, match.SetNumber, match.TeamNumber)
 		check(t, err, "Failed to delete stat")
 	}
 
@@ -663,17 +677,17 @@
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1235},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1235"},
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1234},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1234"},
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 1233},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "1233"},
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 1232},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "1232"},
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 1231},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "1231"},
 		TeamMatch{MatchNumber: 94, SetNumber: 2, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1239},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1239"},
 	}
 
 	for _, match := range matches {
@@ -759,15 +773,15 @@
 
 	correct := []TeamMatch{
 		TeamMatch{
-			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 1, TeamNumber: 6835},
+			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 1, TeamNumber: "6835"},
 		TeamMatch{
-			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: 4834},
+			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: "4834"},
 		TeamMatch{
-			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: 9824},
+			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: "9824"},
 		TeamMatch{
-			MatchNumber: 7, SetNumber: 2, CompLevel: "quals", Alliance: "B", AlliancePosition: 1, TeamNumber: 3732},
+			MatchNumber: 7, SetNumber: 2, CompLevel: "quals", Alliance: "B", AlliancePosition: 1, TeamNumber: "3732"},
 		TeamMatch{
-			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 1, TeamNumber: 3732},
+			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 1, TeamNumber: "3732"},
 	}
 
 	for i := 0; i < len(correct); i++ {
@@ -789,11 +803,11 @@
 
 	testDatabase := []TeamMatch{
 		TeamMatch{
-			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: 4464},
+			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: "4464"},
 		TeamMatch{
-			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: 2352},
+			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: "2352"},
 		TeamMatch{
-			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: 6321},
+			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: "6321"},
 	}
 
 	for i := 0; i < len(testDatabase); i++ {
@@ -803,9 +817,9 @@
 
 	correct := []TeamMatch{
 		TeamMatch{
-			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: 2352},
+			MatchNumber: 8, SetNumber: 1, CompLevel: "quals", Alliance: "R", AlliancePosition: 2, TeamNumber: "2352"},
 		TeamMatch{
-			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: 6321},
+			MatchNumber: 9, SetNumber: 1, CompLevel: "quals", Alliance: "B", AlliancePosition: 3, TeamNumber: "6321"},
 	}
 
 	got, err := fixture.db.ReturnMatches()
@@ -940,17 +954,17 @@
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1235},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1235"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1236},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1236"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 1237},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "1237"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 1238},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "1238"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 1239},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "1239"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1233},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1233"},
 	}
 
 	for _, match := range matches {
@@ -984,7 +998,8 @@
 			ConesDroppedAuto: 1, LowCubes: 1, MiddleCubes: 2,
 			HighCubes: 1, CubesDropped: 0, LowCones: 2,
 			MiddleCones: 0, HighCones: 2, ConesDropped: 1,
-			AvgCycle: 51, CollectedBy: "isaac",
+			AvgCycle: 51, DockedAuto: true, EngagedAuto: true,
+			Docked: false, Engaged: false, CollectedBy: "isaac",
 		},
 		Stats2023{
 			TeamNumber: "5443", MatchNumber: 2, SetNumber: 1,
@@ -994,7 +1009,8 @@
 			ConesDroppedAuto: 0, LowCubes: 2, MiddleCubes: 2,
 			HighCubes: 1, CubesDropped: 0, LowCones: 1,
 			MiddleCones: 0, HighCones: 2, ConesDropped: 1,
-			AvgCycle: 39, CollectedBy: "jack",
+			AvgCycle: 39, DockedAuto: false, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "jack",
 		},
 		Stats2023{
 			TeamNumber: "5436", MatchNumber: 2, SetNumber: 1,
@@ -1004,7 +1020,8 @@
 			ConesDroppedAuto: 1, LowCubes: 2, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 1,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 45, CollectedBy: "martin",
+			AvgCycle: 45, DockedAuto: true, EngagedAuto: false,
+			Docked: false, Engaged: false, CollectedBy: "martin",
 		},
 		Stats2023{
 			TeamNumber: "5643", MatchNumber: 2, SetNumber: 1,
@@ -1014,19 +1031,20 @@
 			ConesDroppedAuto: 1, LowCubes: 2, MiddleCubes: 2,
 			HighCubes: 0, CubesDropped: 0, LowCones: 2,
 			MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-			AvgCycle: 34, CollectedBy: "unknown",
+			AvgCycle: 34, DockedAuto: true, EngagedAuto: false,
+			Docked: true, Engaged: false, CollectedBy: "unknown",
 		},
 	}
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 2, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 2343},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "2343"},
 		TeamMatch{MatchNumber: 2, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 5443},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "5443"},
 		TeamMatch{MatchNumber: 2, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 5436},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "5436"},
 		TeamMatch{MatchNumber: 2, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 5643},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "5643"},
 	}
 
 	for _, match := range matches {
@@ -1079,17 +1097,17 @@
 
 	matches := []TeamMatch{
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 1, TeamNumber: 1235},
+			Alliance: "R", AlliancePosition: 1, TeamNumber: "1235"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 2, TeamNumber: 1236},
+			Alliance: "R", AlliancePosition: 2, TeamNumber: "1236"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "R", AlliancePosition: 3, TeamNumber: 1237},
+			Alliance: "R", AlliancePosition: 3, TeamNumber: "1237"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 1, TeamNumber: 1238},
+			Alliance: "B", AlliancePosition: 1, TeamNumber: "1238"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 2, TeamNumber: 1239},
+			Alliance: "B", AlliancePosition: 2, TeamNumber: "1239"},
 		TeamMatch{MatchNumber: 94, SetNumber: 1, CompLevel: "quals",
-			Alliance: "B", AlliancePosition: 3, TeamNumber: 1233},
+			Alliance: "B", AlliancePosition: 3, TeamNumber: "1233"},
 	}
 
 	for _, match := range matches {
diff --git a/scouting/webserver/match_list/match_list.go b/scouting/webserver/match_list/match_list.go
index 9029438..c5af661 100644
--- a/scouting/webserver/match_list/match_list.go
+++ b/scouting/webserver/match_list/match_list.go
@@ -97,32 +97,32 @@
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "R", AlliancePosition: 1, TeamNumber: red[0],
+				Alliance: "R", AlliancePosition: 1, TeamNumber: strconv.Itoa(int(red[0])),
 			},
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "R", AlliancePosition: 2, TeamNumber: red[1],
+				Alliance: "R", AlliancePosition: 2, TeamNumber: strconv.Itoa(int(red[1])),
 			},
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "R", AlliancePosition: 3, TeamNumber: red[2],
+				Alliance: "R", AlliancePosition: 3, TeamNumber: strconv.Itoa(int(red[2])),
 			},
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "B", AlliancePosition: 1, TeamNumber: blue[0],
+				Alliance: "B", AlliancePosition: 1, TeamNumber: strconv.Itoa(int(blue[0])),
 			},
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "B", AlliancePosition: 2, TeamNumber: blue[1],
+				Alliance: "B", AlliancePosition: 2, TeamNumber: strconv.Itoa(int(blue[1])),
 			},
 			{
 				MatchNumber: int32(match.MatchNumber),
 				SetNumber:   int32(match.SetNumber), CompLevel: match.CompLevel,
-				Alliance: "B", AlliancePosition: 3, TeamNumber: blue[2],
+				Alliance: "B", AlliancePosition: 3, TeamNumber: strconv.Itoa(int(blue[2])),
 			},
 		}
 
diff --git a/scouting/webserver/requests/messages/request_2023_data_scouting_response.fbs b/scouting/webserver/requests/messages/request_2023_data_scouting_response.fbs
index 93583ce..cd6afc6 100644
--- a/scouting/webserver/requests/messages/request_2023_data_scouting_response.fbs
+++ b/scouting/webserver/requests/messages/request_2023_data_scouting_response.fbs
@@ -26,8 +26,12 @@
   cones_dropped:int (id:18);
   // Time in nanoseconds.
   avg_cycle:int64 (id:19);
+  docked_auto:bool (id:20);
+  engaged_auto:bool (id:23);
+  docked:bool (id:25);
+  engaged:bool (id:26);
 
-  collected_by:string (id:20);
+  collected_by:string (id:24);
 }
 
 table Request2023DataScoutingResponse {
diff --git a/scouting/webserver/requests/messages/request_all_matches_response.fbs b/scouting/webserver/requests/messages/request_all_matches_response.fbs
index 9404675..55da7bb 100644
--- a/scouting/webserver/requests/messages/request_all_matches_response.fbs
+++ b/scouting/webserver/requests/messages/request_all_matches_response.fbs
@@ -14,12 +14,12 @@
     match_number:int (id: 0);
     set_number:int (id: 1);
     comp_level:string (id: 2);
-    r1:int (id: 3);
-    r2:int (id: 4);
-    r3:int (id: 5);
-    b1:int (id: 6);
-    b2:int (id: 7);
-    b3:int (id: 8);
+    r1:string (id: 3);
+    r2:string (id: 4);
+    r3:string (id: 5);
+    b1:string (id: 6);
+    b2:string (id: 7);
+    b3:string (id: 8);
 
     // Tells you how completely we've data scouted this match.
     data_scouted: ScoutedLevel (id: 9);
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 6f83bfe..4f12a4f 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -232,9 +232,9 @@
 	return -1, errors.New(fmt.Sprint("Failed to find comp level ", comp_level, " in list ", list))
 }
 
-func (handler requestAllMatchesHandler) teamHasBeenDataScouted(key MatchAssemblyKey, teamNumber int32) (bool, error) {
+func (handler requestAllMatchesHandler) teamHasBeenDataScouted(key MatchAssemblyKey, teamNumber string) (bool, error) {
 	stats, err := handler.db.ReturnStats2023ForTeam(
-		strconv.Itoa(int(teamNumber)), key.MatchNumber, key.SetNumber, key.CompLevel)
+		teamNumber, key.MatchNumber, key.SetNumber, key.CompLevel)
 	if err != nil {
 		return false, err
 	}
@@ -277,7 +277,7 @@
 			}
 		}
 
-		var team *int32
+		var team *string
 		var dataScoutedTeam *bool
 
 		// Fill in the field for the match that we have in in the
@@ -524,6 +524,15 @@
 			var startMatchAction submit_actions.StartMatchAction
 			startMatchAction.Init(actionTable.Bytes, actionTable.Pos)
 			stat.StartingQuadrant = startMatchAction.Position()
+		} else if action_type == submit_actions.ActionTypeAutoBalanceAction {
+			var autoBalanceAction submit_actions.AutoBalanceAction
+			autoBalanceAction.Init(actionTable.Bytes, actionTable.Pos)
+			if autoBalanceAction.Docked() {
+				stat.DockedAuto = true
+			}
+			if autoBalanceAction.Engaged() {
+				stat.EngagedAuto = true
+			}
 		} else if action_type == submit_actions.ActionTypePickupObjectAction {
 			var pick_up_action submit_actions.PickupObjectAction
 			pick_up_action.Init(actionTable.Bytes, actionTable.Pos)
@@ -587,6 +596,15 @@
 				cycles += 1
 			}
 			lastPlacedTime = int64(action.Timestamp())
+		} else if action_type == submit_actions.ActionTypeEndMatchAction {
+			var endMatchAction submit_actions.EndMatchAction
+			endMatchAction.Init(actionTable.Bytes, actionTable.Pos)
+			if endMatchAction.Docked() {
+				stat.Docked = true
+			}
+			if endMatchAction.Engaged() {
+				stat.Engaged = true
+			}
 		}
 	}
 	if cycles != 0 {
@@ -645,6 +663,10 @@
 			HighCones:        stat.HighCones,
 			ConesDropped:     stat.ConesDropped,
 			AvgCycle:         stat.AvgCycle,
+			DockedAuto:       stat.DockedAuto,
+			EngagedAuto:      stat.EngagedAuto,
+			Docked:           stat.Docked,
+			Engaged:          stat.Engaged,
 			CollectedBy:      stat.CollectedBy,
 		})
 	}
diff --git a/scouting/webserver/requests/requests_test.go b/scouting/webserver/requests/requests_test.go
index dbad955..d2d5acc 100644
--- a/scouting/webserver/requests/requests_test.go
+++ b/scouting/webserver/requests/requests_test.go
@@ -128,75 +128,75 @@
 		matches: []db.TeamMatch{
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 1, TeamNumber: 5,
+				Alliance: "R", AlliancePosition: 1, TeamNumber: "5",
 			},
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 2, TeamNumber: 42,
+				Alliance: "R", AlliancePosition: 2, TeamNumber: "42",
 			},
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 3, TeamNumber: 600,
+				Alliance: "R", AlliancePosition: 3, TeamNumber: "600",
 			},
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 1, TeamNumber: 971,
+				Alliance: "B", AlliancePosition: 1, TeamNumber: "971",
 			},
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 2, TeamNumber: 400,
+				Alliance: "B", AlliancePosition: 2, TeamNumber: "400",
 			},
 			{
 				MatchNumber: 1, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 3, TeamNumber: 200,
+				Alliance: "B", AlliancePosition: 3, TeamNumber: "200",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 1, TeamNumber: 6,
+				Alliance: "R", AlliancePosition: 1, TeamNumber: "6",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 2, TeamNumber: 43,
+				Alliance: "R", AlliancePosition: 2, TeamNumber: "43",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 3, TeamNumber: 601,
+				Alliance: "R", AlliancePosition: 3, TeamNumber: "601",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 1, TeamNumber: 972,
+				Alliance: "B", AlliancePosition: 1, TeamNumber: "972",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 2, TeamNumber: 401,
+				Alliance: "B", AlliancePosition: 2, TeamNumber: "401",
 			},
 			{
 				MatchNumber: 2, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 3, TeamNumber: 201,
+				Alliance: "B", AlliancePosition: 3, TeamNumber: "201",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 1, TeamNumber: 7,
+				Alliance: "R", AlliancePosition: 1, TeamNumber: "7",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 2, TeamNumber: 44,
+				Alliance: "R", AlliancePosition: 2, TeamNumber: "44",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "R", AlliancePosition: 3, TeamNumber: 602,
+				Alliance: "R", AlliancePosition: 3, TeamNumber: "602",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 1, TeamNumber: 973,
+				Alliance: "B", AlliancePosition: 1, TeamNumber: "973",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 2, TeamNumber: 402,
+				Alliance: "B", AlliancePosition: 2, TeamNumber: "402",
 			},
 			{
 				MatchNumber: 3, SetNumber: 1, CompLevel: "qm",
-				Alliance: "B", AlliancePosition: 3, TeamNumber: 202,
+				Alliance: "B", AlliancePosition: 3, TeamNumber: "202",
 			},
 		},
 		// Pretend that we have some data scouting data.
@@ -209,7 +209,8 @@
 				ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
 				HighCubes: 2, CubesDropped: 1, LowCones: 1,
 				MiddleCones: 2, HighCones: 0, ConesDropped: 1,
-				AvgCycle: 34, CollectedBy: "alex",
+				AvgCycle: 34, DockedAuto: true, EngagedAuto: true,
+				Docked: false, Engaged: false, CollectedBy: "alex",
 			},
 			{
 				TeamNumber: "973", MatchNumber: 3, SetNumber: 1,
@@ -219,7 +220,8 @@
 				ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
 				HighCubes: 1, CubesDropped: 0, LowCones: 0,
 				MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-				AvgCycle: 53, CollectedBy: "bob",
+				AvgCycle: 53, DockedAuto: true, EngagedAuto: false,
+				Docked: false, Engaged: false, CollectedBy: "bob",
 			},
 		},
 	}
@@ -242,7 +244,7 @@
 			// R1, R2, R3, B1, B2, B3
 			{
 				1, 1, "qm",
-				5, 42, 600, 971, 400, 200,
+				"5", "42", "600", "971", "400", "200",
 				&request_all_matches_response.ScoutedLevelT{
 					// The R1 team has already been data
 					// scouted.
@@ -251,14 +253,14 @@
 			},
 			{
 				2, 1, "qm",
-				6, 43, 601, 972, 401, 201,
+				"6", "43", "601", "972", "401", "201",
 				&request_all_matches_response.ScoutedLevelT{
 					false, false, false, false, false, false,
 				},
 			},
 			{
 				3, 1, "qm",
-				7, 44, 602, 973, 402, 202,
+				"7", "44", "602", "973", "402", "202",
 				&request_all_matches_response.ScoutedLevelT{
 					// The B1 team has already been data
 					// scouted.
@@ -367,7 +369,8 @@
 				ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
 				HighCubes: 2, CubesDropped: 1, LowCones: 1,
 				MiddleCones: 2, HighCones: 0, ConesDropped: 1,
-				AvgCycle: 34, CollectedBy: "isaac",
+				AvgCycle: 34, DockedAuto: true, EngagedAuto: false,
+				Docked: false, Engaged: false, CollectedBy: "isaac",
 			},
 			{
 				TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
@@ -377,7 +380,8 @@
 				ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
 				HighCubes: 1, CubesDropped: 0, LowCones: 0,
 				MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-				AvgCycle: 53, CollectedBy: "unknown",
+				AvgCycle: 53, DockedAuto: false, EngagedAuto: false,
+				Docked: false, Engaged: false, CollectedBy: "unknown",
 			},
 		},
 	}
@@ -404,7 +408,8 @@
 				ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
 				HighCubes: 2, CubesDropped: 1, LowCones: 1,
 				MiddleCones: 2, HighCones: 0, ConesDropped: 1,
-				AvgCycle: 34, CollectedBy: "isaac",
+				AvgCycle: 34, DockedAuto: true, EngagedAuto: false,
+				Docked: false, Engaged: false, CollectedBy: "isaac",
 			},
 			{
 				TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
@@ -414,7 +419,8 @@
 				ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
 				HighCubes: 1, CubesDropped: 0, LowCones: 0,
 				MiddleCones: 2, HighCones: 1, ConesDropped: 1,
-				AvgCycle: 53, CollectedBy: "unknown",
+				AvgCycle: 53, DockedAuto: false, EngagedAuto: false,
+				Docked: false, Engaged: false, CollectedBy: "unknown",
 			},
 		},
 	}
@@ -480,6 +486,16 @@
 			},
 			{
 				ActionTaken: &submit_actions.ActionTypeT{
+					Type: submit_actions.ActionTypeAutoBalanceAction,
+					Value: &submit_actions.AutoBalanceActionT{
+						Docked:  true,
+						Engaged: true,
+					},
+				},
+				Timestamp: 2400,
+			},
+			{
+				ActionTaken: &submit_actions.ActionTypeT{
 					Type: submit_actions.ActionTypePickupObjectAction,
 					Value: &submit_actions.PickupObjectActionT{
 						ObjectType: submit_actions.ObjectTypekCone,
@@ -499,6 +515,16 @@
 				},
 				Timestamp: 3100,
 			},
+			{
+				ActionTaken: &submit_actions.ActionTypeT{
+					Type: submit_actions.ActionTypeEndMatchAction,
+					Value: &submit_actions.EndMatchActionT{
+						Docked:  true,
+						Engaged: false,
+					},
+				},
+				Timestamp: 4000,
+			},
 		},
 	}).Pack(builder))
 
@@ -517,7 +543,8 @@
 		ConesDroppedAuto: 0, LowCubes: 0, MiddleCubes: 0,
 		HighCubes: 0, CubesDropped: 0, LowCones: 0,
 		MiddleCones: 0, HighCones: 1, ConesDropped: 0,
-		AvgCycle: 1100, CollectedBy: "katie",
+		AvgCycle: 1100, DockedAuto: true, EngagedAuto: true,
+		Docked: true, Engaged: false, CollectedBy: "katie",
 	}
 
 	if expected != response {
diff --git a/scouting/www/entry/entry.ng.html b/scouting/www/entry/entry.ng.html
index 9f4c8eb..e06ab18 100644
--- a/scouting/www/entry/entry.ng.html
+++ b/scouting/www/entry/entry.ng.html
@@ -115,20 +115,17 @@
       <!-- 'Balancing' during auto. -->
       <div *ngIf="autoPhase" class="d-grid gap-2">
         <label>
-          <input type="checkbox" (change)="dockedValue = $event.target.value" />
+          <input #docked type="checkbox" />
           Docked
         </label>
         <label>
-          <input
-            type="checkbox"
-            (change)="engagedValue = $event.target.value"
-          />
+          <input #engaged type="checkbox" />
           Engaged
         </label>
         <br />
         <button
           class="btn btn-info"
-          (click)="addAction({type: 'autoBalanceAction', docked: dockedValue, engaged: engagedValue});"
+          (click)="addAction({type: 'autoBalanceAction', docked: docked.checked, engaged: engaged.checked});"
         >
           Submit Balancing
         </button>
@@ -183,20 +180,17 @@
       <!-- 'Balancing' during auto. -->
       <div *ngIf="autoPhase" class="d-grid gap-2">
         <label>
-          <input type="checkbox" (change)="dockedValue = $event.target.value" />
+          <input #docked type="checkbox" />
           Docked
         </label>
         <label>
-          <input
-            type="checkbox"
-            (change)="engagedValue = $event.target.value"
-          />
+          <input #engaged type="checkbox" />
           Engaged
         </label>
         <br />
         <button
           class="btn btn-info"
-          (click)="addAction({type: 'autoBalanceAction', docked: dockedValue, engaged: engagedValue});"
+          (click)="addAction({type: 'autoBalanceAction', docked: docked.checked, engaged: engaged.checked});"
         >
           Submit Balancing
         </button>
@@ -231,17 +225,17 @@
         DEAD
       </button>
       <label>
-        <input type="checkbox" (change)="dockedValue = $event.target.value" />
+        <input #docked type="checkbox" />
         Docked
       </label>
       <label>
-        <input type="checkbox" (change)="engagedValue = $event.target.value" />
+        <input #engaged type="checkbox" />
         Engaged
       </label>
       <button
         *ngIf="!autoPhase"
         class="btn btn-info"
-        (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: dockedValue, engaged: engagedValue});"
+        (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: docked.checked, engaged: engaged.checked});"
       >
         End Match
       </button>
@@ -259,7 +253,7 @@
       </button>
       <button
         class="btn btn-info"
-        (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: dockedValue, engaged: engagedValue});"
+        (click)="changeSectionTo('Review and Submit'); addAction({type: 'endMatchAction', docked: docked.checked, engaged: engaged.checked});"
       >
         End Match
       </button>
@@ -276,4 +270,6 @@
   <div *ngSwitchCase="'Success'" id="Success" class="container-fluid">
     <h2>Successfully submitted data.</h2>
   </div>
+
+  <span class="error_message" role="alert">{{ errorMessage }}</span>
 </ng-container>
diff --git a/scouting/www/match_list/match_list.component.ts b/scouting/www/match_list/match_list.component.ts
index a9b2cd5..0deeb11 100644
--- a/scouting/www/match_list/match_list.component.ts
+++ b/scouting/www/match_list/match_list.component.ts
@@ -10,7 +10,7 @@
 import {MatchListRequestor} from '@org_frc971/scouting/www/rpc';
 
 type TeamInMatch = {
-  teamNumber: number;
+  teamNumber: string;
   matchNumber: number;
   setNumber: number;
   compLevel: string;
@@ -72,7 +72,7 @@
 
   teamsInMatch(
     match: Match
-  ): {teamNumber: number; color: 'red' | 'blue'; disabled: boolean}[] {
+  ): {teamNumber: string; color: 'red' | 'blue'; disabled: boolean}[] {
     const scouted = match.dataScouted();
     return [
       {
diff --git a/y2023/BUILD b/y2023/BUILD
index e92292b..095b856 100644
--- a/y2023/BUILD
+++ b/y2023/BUILD
@@ -60,6 +60,7 @@
         "//y2023/constants:constants_sender",
         "//y2023/vision:foxglove_image_converter",
         "//aos/network:web_proxy_main",
+        ":joystick_republish",
         "//aos/events/logging:log_cat",
         "//y2023/rockpi:imu_main",
         "//frc971/image_streamer:image_streamer",
@@ -327,6 +328,23 @@
     ],
 )
 
+cc_binary(
+    name = "joystick_republish",
+    srcs = [
+        "joystick_republish.cc",
+    ],
+    target_compatible_with = ["@platforms//os:linux"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//aos:configuration",
+        "//aos:flatbuffer_merge",
+        "//aos:init",
+        "//aos/events:shm_event_loop",
+        "//frc971/input:joystick_state_fbs",
+        "@com_github_google_glog//:glog",
+    ],
+)
+
 py_library(
     name = "python_init",
     srcs = ["__init__.py"],
diff --git a/y2023/constants.cc b/y2023/constants.cc
index c2a09aa..f11c68c 100644
--- a/y2023/constants.cc
+++ b/y2023/constants.cc
@@ -83,19 +83,20 @@
       break;
 
     case kCompTeamNumber:
-      arm_proximal->zeroing.measured_absolute_position = 0.138453705930275;
+      arm_proximal->zeroing.measured_absolute_position = 0.153241637089465;
       arm_proximal->potentiometer_offset =
           0.931355973012855 + 8.6743197253382 - 0.101200335326309 -
-          0.0820901660993467 - 0.0703733798337964 - 0.0294645384848748;
+          0.0820901660993467 - 0.0703733798337964 - 0.0294645384848748 -
+          0.577156175549626;
 
-      arm_distal->zeroing.measured_absolute_position = 0.562947209110251;
+      arm_distal->zeroing.measured_absolute_position = 0.119544808434349;
       arm_distal->potentiometer_offset =
           0.436664933370656 + 0.49457213779426 + 6.78213223139724 -
           0.0220711555235029 - 0.0162945074111813 + 0.00630344935527365 -
           0.0164398318919943 - 0.145833494945215 + 0.234878799868491 +
-          0.125924230298394 + 0.147136306208754;
+          0.125924230298394 + 0.147136306208754 - 0.69167546169753;
 
-      roll_joint->zeroing.measured_absolute_position = 0.593975883699743;
+      roll_joint->zeroing.measured_absolute_position = 0.62315534539819;
       roll_joint->potentiometer_offset =
           -(3.87038557084874 - 0.0241774522172967 + 0.0711345168020632 -
             0.866186131631967 - 0.0256788357596952 + 0.18101759154572017 -
@@ -105,7 +106,7 @@
           0.0201047336425017 - 1.0173426655158 - 0.186085272847293 - 0.0317706563397807;
 
       wrist->subsystem_params.zeroing_constants.measured_absolute_position =
-          0.894159203288852;
+          1.00731305518279;
 
       break;
 
@@ -119,10 +120,11 @@
           7.673132586937 - 0.0799284644472573 - 0.0323574039310657 +
           0.0143810684138064 + 0.00945555248207735;
 
-      roll_joint->zeroing.measured_absolute_position = 1.7490367887908;
+      roll_joint->zeroing.measured_absolute_position = 1.85482286175059;
       roll_joint->potentiometer_offset =
           0.624713611895747 + 3.10458504917251 - 0.0966407797407789 +
-          0.0257708772364788 - 0.0395076737853459 - 6.87914956118006;
+          0.0257708772364788 - 0.0395076737853459 - 6.87914956118006 -
+          0.097581301615046;
 
       wrist->subsystem_params.zeroing_constants.measured_absolute_position =
           6.04062267812154;
diff --git a/y2023/constants.h b/y2023/constants.h
index 8996597..595a694 100644
--- a/y2023/constants.h
+++ b/y2023/constants.h
@@ -168,7 +168,7 @@
 
   // Game object is spit from end effector for at least this time
   static constexpr std::chrono::milliseconds kExtraSpittingTime() {
-    return std::chrono::seconds(2);
+    return std::chrono::seconds(1);
   }
 
   // if true, tune down all the arm constants for testing.
diff --git a/y2023/control_loops/drivetrain/drivetrain_main.cc b/y2023/control_loops/drivetrain/drivetrain_main.cc
index b13e76f..eebae91 100644
--- a/y2023/control_loops/drivetrain/drivetrain_main.cc
+++ b/y2023/control_loops/drivetrain/drivetrain_main.cc
@@ -15,6 +15,8 @@
   aos::FlatbufferDetachedBuffer<aos::Configuration> config =
       aos::configuration::ReadConfig("aos_config.json");
 
+  frc971::constants::WaitForConstants<y2023::Constants>(&config.message());
+
   aos::ShmEventLoop event_loop(&config.message());
   std::unique_ptr<::frc971::control_loops::drivetrain::PuppetLocalizer>
       localizer = std::make_unique<
diff --git a/y2023/control_loops/python/drivetrain.py b/y2023/control_loops/python/drivetrain.py
index 05739fc..9d2b006 100644
--- a/y2023/control_loops/python/drivetrain.py
+++ b/y2023/control_loops/python/drivetrain.py
@@ -14,17 +14,17 @@
 
 kDrivetrain = drivetrain.DrivetrainParams(
     J=6.5,
-    mass=58.0,
+    mass=68.0,
     # TODO(austin): Measure radius a bit better.
     robot_radius=0.39,
     wheel_radius=2.5 * 0.0254,
     motor_type=control_loop.Falcon(),
     num_motors=3,
-    G=(14.0 / 54.0) * (22.0 / 56.0),
+    G=(14.0 / 52.0) * (26.0 / 58.0),
     q_pos=0.24,
     q_vel=2.5,
-    efficiency=0.75,
-    has_imu=True,
+    efficiency=0.92,
+    has_imu=False,
     force=True,
     kf_q_voltage=1.0,
     controller_poles=[0.82, 0.82])
diff --git a/y2023/control_loops/superstructure/end_effector.cc b/y2023/control_loops/superstructure/end_effector.cc
index 8ab2f27..444be0d 100644
--- a/y2023/control_loops/superstructure/end_effector.cc
+++ b/y2023/control_loops/superstructure/end_effector.cc
@@ -18,9 +18,9 @@
       beambreak_(false) {}
 
 void EndEffector::RunIteration(
-    const ::aos::monotonic_clock::time_point timestamp, RollerGoal roller_goal,
-    double falcon_current, double cone_position, bool beambreak,
-    double *roller_voltage, bool preloaded_with_cone) {
+    const ::aos::monotonic_clock::time_point timestamp,
+    RollerGoal roller_goal, double falcon_current, double cone_position,
+    bool beambreak, double *roller_voltage, bool preloaded_with_cone) {
   *roller_voltage = 0.0;
 
   constexpr double kMinCurrent = 40.0;
@@ -32,6 +32,7 @@
     switch (state_) {
       case EndEffectorState::IDLE:
       case EndEffectorState::INTAKING:
+        game_piece_ = vision::Class::CONE_UP;
         state_ = EndEffectorState::LOADED;
         break;
       case EndEffectorState::LOADED:
@@ -124,6 +125,12 @@
         // Finished spitting
         state_ = EndEffectorState::IDLE;
         game_piece_ = vision::Class::NONE;
+      } else if (roller_goal == RollerGoal::INTAKE_CONE_UP ||
+                 roller_goal == RollerGoal::INTAKE_CONE_DOWN ||
+                 roller_goal == RollerGoal::INTAKE_CUBE ||
+                 roller_goal == RollerGoal::INTAKE_LAST) {
+        state_ = EndEffectorState::INTAKING;
+        timer_ = timestamp;
       }
 
       break;
diff --git a/y2023/joystick_reader.cc b/y2023/joystick_reader.cc
index 8d04056..efd7537 100644
--- a/y2023/joystick_reader.cc
+++ b/y2023/joystick_reader.cc
@@ -382,6 +382,8 @@
 
   GamePiece current_game_piece_ = GamePiece::CONE_UP;
 
+  bool has_scored_ = false;
+
   void HandleTeleop(
       const ::frc971::input::driver_station::Data &data) override {
     superstructure_status_fetcher_.Fetch();
@@ -445,6 +447,7 @@
 
     // Ok, no active setpoint.  Search for the right one.
     if (current_setpoint_ == nullptr) {
+      has_scored_ = false;
       const Side current_side =
           data.IsPressed(kBack) ? Side::BACK : Side::FRONT;
       // Search for the active setpoint.
@@ -485,13 +488,16 @@
         // spit.
         if (std::abs(score_wrist_goal.value() -
                      superstructure_status_fetcher_->wrist()->goal_position()) <
-            0.1) {
+                0.1 ||
+            has_scored_) {
           if (place_index.has_value()) {
             arm_goal_position_ = place_index.value();
-            if (arm_goal_position_ ==
-                    superstructure_status_fetcher_->arm()->current_node() &&
-                superstructure_status_fetcher_->arm()->path_distance_to_go() <
-                    0.01) {
+            if ((arm_goal_position_ ==
+                     superstructure_status_fetcher_->arm()->current_node() &&
+                 superstructure_status_fetcher_->arm()->path_distance_to_go() <
+                     0.01) ||
+                has_scored_) {
+              has_scored_ = true;
               roller_goal = RollerGoal::SPIT;
             }
           } else {
diff --git a/y2023/joystick_republish.cc b/y2023/joystick_republish.cc
new file mode 100644
index 0000000..9542001
--- /dev/null
+++ b/y2023/joystick_republish.cc
@@ -0,0 +1,34 @@
+#include <sys/resource.h>
+#include <sys/time.h>
+
+#include "aos/configuration.h"
+#include "aos/init.h"
+#include "aos/events/shm_event_loop.h"
+#include "aos/flatbuffer_merge.h"
+#include "aos/init.h"
+#include "frc971/input/joystick_state_generated.h"
+#include "glog/logging.h"
+
+DEFINE_string(config, "aos_config.json", "Config file to use.");
+
+int main(int argc, char *argv[]) {
+  aos::InitGoogle(&argc, &argv);
+
+  aos::FlatbufferDetachedBuffer<aos::Configuration> config =
+      aos::configuration::ReadConfig(FLAGS_config);
+  aos::ShmEventLoop event_loop(&config.message());
+
+  aos::Sender<aos::JoystickState> sender(
+      event_loop.MakeSender<aos::JoystickState>("/imu/aos"));
+
+  event_loop.MakeWatcher(
+      "/roborio/aos", [&](const aos::JoystickState &joystick_state) {
+        auto builder = sender.MakeBuilder();
+        flatbuffers::Offset<aos::JoystickState> state_fbs =
+            aos::CopyFlatBuffer(&joystick_state, builder.fbb());
+        builder.CheckOk(builder.Send(state_fbs));
+      });
+
+  event_loop.Run();
+  return 0;
+}
diff --git a/y2023/vision/camera_reader.cc b/y2023/vision/camera_reader.cc
index 7de3eb5..b526086 100644
--- a/y2023/vision/camera_reader.cc
+++ b/y2023/vision/camera_reader.cc
@@ -12,6 +12,7 @@
 
 DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
 DEFINE_bool(lowlight_camera, true, "Switch to use imx462 image sensor.");
+DEFINE_int32(gain, 200, "analogue_gain");
 
 DEFINE_double(red, 1.252, "Red gain");
 DEFINE_double(green, 1, "Green gain");
@@ -117,7 +118,7 @@
                                           rkisp1_selfpath->device(),
                                           camera->device());
   if (FLAGS_lowlight_camera) {
-    v4l2_reader_selfpath.SetGainExt(100);
+    v4l2_reader_selfpath.SetGainExt(FLAGS_gain);
     v4l2_reader_selfpath.SetVerticalBlanking(1000);
     v4l2_reader_selfpath.SetExposure(FLAGS_exposure);
   } else {
diff --git a/y2023/vision/image_logger.cc b/y2023/vision/image_logger.cc
index b87cec0..d90f9c2 100644
--- a/y2023/vision/image_logger.cc
+++ b/y2023/vision/image_logger.cc
@@ -62,7 +62,7 @@
   });
 
   event_loop.MakeWatcher(
-      "/roborio/aos", [&](const aos::JoystickState &joystick_state) {
+      "/imu/aos", [&](const aos::JoystickState &joystick_state) {
         const auto timestamp = event_loop.context().monotonic_event_time;
         // Store the last time we got disabled
         if (enabled && !joystick_state.enabled()) {
diff --git a/y2023/y2023_imu.json b/y2023/y2023_imu.json
index e802795..416552b 100644
--- a/y2023/y2023_imu.json
+++ b/y2023/y2023_imu.json
@@ -2,6 +2,108 @@
   "channels": [
     {
       "name": "/imu/aos",
+      "type": "aos.JoystickState",
+      "source_node": "imu",
+      "frequency": 100,
+      "logger": "LOCAL_AND_REMOTE_LOGGER",
+      "logger_nodes": [
+        "imu"
+      ],
+      "destination_nodes": [
+        {
+          "name": "logger",
+          "priority": 5,
+          "time_to_live": 50000000,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": [
+            "imu"
+          ]
+        },
+        {
+          "name": "pi1",
+          "priority": 5,
+          "time_to_live": 50000000,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": [
+            "imu"
+          ]
+        },
+        {
+          "name": "pi2",
+          "priority": 5,
+          "time_to_live": 50000000,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": [
+            "imu"
+          ]
+        },
+        {
+          "name": "pi3",
+          "priority": 5,
+          "time_to_live": 50000000,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": [
+            "imu"
+          ]
+        },
+        {
+          "name": "pi4",
+          "priority": 5,
+          "time_to_live": 50000000,
+          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
+          "timestamp_logger_nodes": [
+            "imu"
+          ]
+        }
+      ]
+    },
+    {
+      "name": "/imu/aos/remote_timestamps/logger/imu/aos/aos-JoystickState",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "imu",
+      "logger": "NOT_LOGGED",
+      "frequency": 300,
+      "num_senders": 2,
+      "max_size": 200
+    },
+    {
+      "name": "/imu/aos/remote_timestamps/pi1/imu/aos/aos-JoystickState",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "imu",
+      "logger": "NOT_LOGGED",
+      "frequency": 300,
+      "num_senders": 2,
+      "max_size": 200
+    },
+    {
+      "name": "/imu/aos/remote_timestamps/pi2/imu/aos/aos-JoystickState",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "imu",
+      "logger": "NOT_LOGGED",
+      "frequency": 300,
+      "num_senders": 2,
+      "max_size": 200
+    },
+    {
+      "name": "/imu/aos/remote_timestamps/pi3/imu/aos/aos-JoystickState",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "imu",
+      "logger": "NOT_LOGGED",
+      "frequency": 300,
+      "num_senders": 2,
+      "max_size": 200
+    },
+    {
+      "name": "/imu/aos/remote_timestamps/pi4/imu/aos/aos-JoystickState",
+      "type": "aos.message_bridge.RemoteMessage",
+      "source_node": "imu",
+      "logger": "NOT_LOGGED",
+      "frequency": 300,
+      "num_senders": 2,
+      "max_size": 200
+    },
+    {
+      "name": "/imu/aos",
       "type": "aos.timing.Report",
       "source_node": "imu",
       "frequency": 50,
@@ -373,6 +475,14 @@
       ]
     },
     {
+      "name": "joystick_republish",
+      "executable_name": "joystick_republish",
+      "user": "pi",
+      "nodes": [
+        "imu"
+      ]
+    },
+    {
       "name": "message_bridge_server",
       "executable_name": "message_bridge_server",
       "user": "pi",
@@ -383,7 +493,12 @@
     {
       "name": "localizer_logger",
       "executable_name": "logger_main",
-      "args": ["--logging_folder", "", "--snappy_compress"],
+      "args": [
+        "--logging_folder",
+        "",
+        "--snappy_compress",
+        "--rotate_every", "30.0"
+      ],
       "user": "pi",
       "nodes": [
         "imu"
@@ -392,6 +507,10 @@
     {
       "name": "web_proxy",
       "executable_name": "web_proxy_main",
+      "args": [
+        "--min_ice_port=5800",
+        "--max_ice_port=5810"
+      ],
       "user": "pi",
       "nodes": [
         "imu"
@@ -450,6 +569,18 @@
     },
     {
       "name": "roborio"
+    },
+    {
+      "name": "pi1"
+    },
+    {
+      "name": "pi2"
+    },
+    {
+      "name": "pi3"
+    },
+    {
+      "name": "pi4"
     }
   ]
 }
diff --git a/y2023/y2023_pi_template.json b/y2023/y2023_pi_template.json
index 113e48f..8d9fdaa 100644
--- a/y2023/y2023_pi_template.json
+++ b/y2023/y2023_pi_template.json
@@ -377,6 +377,10 @@
       "name": "web_proxy",
       "executable_name": "web_proxy_main",
       "user": "pi",
+      "args": [
+        "--min_ice_port=5800",
+        "--max_ice_port=5810"
+      ],
       "nodes": [
         "pi{{ NUM }}"
       ]
@@ -397,7 +401,7 @@
         "--logging_folder",
         "",
         "--rotate_every",
-        "60.0",
+        "30.0",
         "--direct",
         "--flush_size=4194304"
       ],
diff --git a/y2023/y2023_roborio.json b/y2023/y2023_roborio.json
index f3697ac..3114ac9 100644
--- a/y2023/y2023_roborio.json
+++ b/y2023/y2023_roborio.json
@@ -6,7 +6,7 @@
       "source_node": "roborio",
       "frequency": 100,
       "logger": "LOCAL_AND_REMOTE_LOGGER",
-      "logger_nodes" : [
+      "logger_nodes": [
         "imu",
         "logger"
       ],
@@ -19,51 +19,6 @@
           "timestamp_logger_nodes": [
             "roborio"
           ]
-        },
-        {
-          "name": "logger",
-          "priority": 5,
-          "time_to_live": 50000000,
-          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
-          "timestamp_logger_nodes": [
-            "roborio"
-          ]
-        },
-        {
-          "name": "pi1",
-          "priority": 5,
-          "time_to_live": 50000000,
-          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
-          "timestamp_logger_nodes": [
-            "roborio"
-          ]
-        },
-        {
-          "name": "pi2",
-          "priority": 5,
-          "time_to_live": 50000000,
-          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
-          "timestamp_logger_nodes": [
-            "roborio"
-          ]
-        },
-        {
-          "name": "pi3",
-          "priority": 5,
-          "time_to_live": 50000000,
-          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
-          "timestamp_logger_nodes": [
-            "roborio"
-          ]
-        },
-        {
-          "name": "pi4",
-          "priority": 5,
-          "time_to_live": 50000000,
-          "timestamp_logger": "LOCAL_AND_REMOTE_LOGGER",
-          "timestamp_logger_nodes": [
-            "roborio"
-          ]
         }
       ]
     },
@@ -77,51 +32,6 @@
       "max_size": 200
     },
     {
-      "name": "/roborio/aos/remote_timestamps/logger/roborio/aos/aos-JoystickState",
-      "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "roborio",
-      "logger": "NOT_LOGGED",
-      "frequency": 300,
-      "num_senders": 2,
-      "max_size": 200
-    },
-    {
-      "name": "/roborio/aos/remote_timestamps/pi1/roborio/aos/aos-JoystickState",
-      "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "roborio",
-      "logger": "NOT_LOGGED",
-      "frequency": 300,
-      "num_senders": 2,
-      "max_size": 200
-    },
-    {
-      "name": "/roborio/aos/remote_timestamps/pi2/roborio/aos/aos-JoystickState",
-      "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "roborio",
-      "logger": "NOT_LOGGED",
-      "frequency": 300,
-      "num_senders": 2,
-      "max_size": 200
-    },
-    {
-      "name": "/roborio/aos/remote_timestamps/pi3/roborio/aos/aos-JoystickState",
-      "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "roborio",
-      "logger": "NOT_LOGGED",
-      "frequency": 300,
-      "num_senders": 2,
-      "max_size": 200
-    },
-    {
-      "name": "/roborio/aos/remote_timestamps/pi4/roborio/aos/aos-JoystickState",
-      "type": "aos.message_bridge.RemoteMessage",
-      "source_node": "roborio",
-      "logger": "NOT_LOGGED",
-      "frequency": 300,
-      "num_senders": 2,
-      "max_size": 200
-    },
-    {
       "name": "/roborio/aos",
       "type": "aos.RobotState",
       "source_node": "roborio",
@@ -608,7 +518,10 @@
     {
       "name": "roborio_web_proxy",
       "executable_name": "web_proxy_main",
-      "args": ["--min_ice_port=5800", "--max_ice_port=5810"],
+      "args": [
+        "--min_ice_port=5800",
+        "--max_ice_port=5810"
+      ],
       "nodes": [
         "roborio"
       ]
@@ -616,7 +529,9 @@
     {
       "name": "roborio_message_bridge_client",
       "executable_name": "message_bridge_client",
-      "args": ["--rt_priority=16"],
+      "args": [
+        "--rt_priority=16"
+      ],
       "nodes": [
         "roborio"
       ]
@@ -624,7 +539,9 @@
     {
       "name": "roborio_message_bridge_server",
       "executable_name": "message_bridge_server",
-      "args": ["--rt_priority=16"],
+      "args": [
+        "--rt_priority=16"
+      ],
       "nodes": [
         "roborio"
       ]
@@ -632,7 +549,11 @@
     {
       "name": "logger",
       "executable_name": "logger_main",
-      "args": ["--snappy_compress", "--logging_folder=/home/admin/logs/"],
+      "args": [
+        "--snappy_compress",
+        "--logging_folder=/home/admin/logs/",
+        "--rotate_every", "30.0"
+      ],
       "nodes": [
         "roborio"
       ]