Merge changes I81640476,I878f821d,Iaa9c2dda,I2215354d,I3cd0f02f, ...

* changes:
  Rephrase defense options for scouting app
  scouting: Add more high-level fields to the scouting app
  Simplify climbing screen on the scouting app
  scouting: Reduce number of Auto balls to 5
  Add scouting images for auto
  Collect the username when data scouting data is submitted
  Allow users to run the scouting app with HTTPS/LDAP
  Migrate the scouting database to postgres
diff --git a/BUILD b/BUILD
index 70ef3f6..8b45953 100644
--- a/BUILD
+++ b/BUILD
@@ -16,10 +16,14 @@
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/error_response //scouting/webserver/requests/messages:error_response_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting //scouting/webserver/requests/messages:submit_data_scouting_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response //scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes //scouting/webserver/requests/messages:submit_notes_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes_response //scouting/webserver/requests/messages:submit_notes_response_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response //scouting/webserver/requests/messages:request_data_scouting_response_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting //scouting/webserver/requests/messages:request_data_scouting_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team_response //scouting/webserver/requests/messages:request_matches_for_team_response_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team //scouting/webserver/requests/messages:request_matches_for_team_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team_response //scouting/webserver/requests/messages:request_notes_for_team_response_go_fbs
+# gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team //scouting/webserver/requests/messages:request_notes_for_team_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches_response //scouting/webserver/requests/messages:request_all_matches_response_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches //scouting/webserver/requests/messages:request_all_matches_go_fbs
 # gazelle:resolve go github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/refresh_match_list //scouting/webserver/requests/messages:refresh_match_list_go_fbs
diff --git a/scouting/webserver/requests/BUILD b/scouting/webserver/requests/BUILD
index df487f2..744772c 100644
--- a/scouting/webserver/requests/BUILD
+++ b/scouting/webserver/requests/BUILD
@@ -18,8 +18,12 @@
         "//scouting/webserver/requests/messages:request_data_scouting_response_go_fbs",
         "//scouting/webserver/requests/messages:request_matches_for_team_go_fbs",
         "//scouting/webserver/requests/messages:request_matches_for_team_response_go_fbs",
+        "//scouting/webserver/requests/messages:request_notes_for_team_go_fbs",
+        "//scouting/webserver/requests/messages:request_notes_for_team_response_go_fbs",
         "//scouting/webserver/requests/messages:submit_data_scouting_go_fbs",
         "//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+        "//scouting/webserver/requests/messages:submit_notes_go_fbs",
+        "//scouting/webserver/requests/messages:submit_notes_response_go_fbs",
         "//scouting/webserver/server",
         "@com_github_google_flatbuffers//go:go_default_library",
     ],
@@ -43,8 +47,10 @@
         "//scouting/webserver/requests/messages:request_data_scouting_response_go_fbs",
         "//scouting/webserver/requests/messages:request_matches_for_team_go_fbs",
         "//scouting/webserver/requests/messages:request_matches_for_team_response_go_fbs",
+        "//scouting/webserver/requests/messages:request_notes_for_team_go_fbs",
         "//scouting/webserver/requests/messages:submit_data_scouting_go_fbs",
         "//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+        "//scouting/webserver/requests/messages:submit_notes_go_fbs",
         "//scouting/webserver/server",
         "@com_github_google_flatbuffers//go:go_default_library",
     ],
diff --git a/scouting/webserver/requests/debug/BUILD b/scouting/webserver/requests/debug/BUILD
index 402503f..e5f5234 100644
--- a/scouting/webserver/requests/debug/BUILD
+++ b/scouting/webserver/requests/debug/BUILD
@@ -12,6 +12,8 @@
         "//scouting/webserver/requests/messages:request_all_matches_response_go_fbs",
         "//scouting/webserver/requests/messages:request_data_scouting_response_go_fbs",
         "//scouting/webserver/requests/messages:request_matches_for_team_response_go_fbs",
+        "//scouting/webserver/requests/messages:request_notes_for_team_response_go_fbs",
         "//scouting/webserver/requests/messages:submit_data_scouting_response_go_fbs",
+        "//scouting/webserver/requests/messages:submit_notes_response_go_fbs",
     ],
 )
diff --git a/scouting/webserver/requests/debug/debug.go b/scouting/webserver/requests/debug/debug.go
index 49b6f79..acd8b04 100644
--- a/scouting/webserver/requests/debug/debug.go
+++ b/scouting/webserver/requests/debug/debug.go
@@ -14,7 +14,9 @@
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_all_matches_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes_response"
 )
 
 // The username to submit the various requests as.
@@ -154,3 +156,23 @@
 	response := refresh_match_list_response.GetRootAsRefreshMatchListResponse(responseBytes, 0)
 	return response.UnPack(), nil
 }
+
+func SubmitNotes(server string, requestBytes []byte) (*submit_notes_response.SubmitNotesResponseT, error) {
+	responseBytes, err := performPost(server+"/requests/submit/submit_notes", requestBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	response := submit_notes_response.GetRootAsSubmitNotesResponse(responseBytes, 0)
+	return response.UnPack(), nil
+}
+
+func RequestNotes(server string, requestBytes []byte) (*request_notes_for_team_response.RequestNotesForTeamResponseT, error) {
+	responseBytes, err := performPost(server+"/requests/request/notes_for_team", requestBytes)
+	if err != nil {
+		return nil, err
+	}
+
+	response := request_notes_for_team_response.GetRootAsRequestNotesForTeamResponse(responseBytes, 0)
+	return response.UnPack(), nil
+}
diff --git a/scouting/webserver/requests/messages/BUILD b/scouting/webserver/requests/messages/BUILD
index c27f730..f7e194b 100644
--- a/scouting/webserver/requests/messages/BUILD
+++ b/scouting/webserver/requests/messages/BUILD
@@ -12,6 +12,10 @@
     "request_data_scouting_response",
     "refresh_match_list",
     "refresh_match_list_response",
+    "submit_notes",
+    "submit_notes_response",
+    "request_notes_for_team",
+    "request_notes_for_team_response",
 )
 
 filegroup(
diff --git a/scouting/webserver/requests/messages/request_notes_for_team.fbs b/scouting/webserver/requests/messages/request_notes_for_team.fbs
new file mode 100644
index 0000000..9bda6d3
--- /dev/null
+++ b/scouting/webserver/requests/messages/request_notes_for_team.fbs
@@ -0,0 +1,8 @@
+namespace scouting.webserver.requests;
+
+table RequestNotesForTeam {
+    team:int (id: 0);
+}
+
+root_type RequestNotesForTeam;
+
diff --git a/scouting/webserver/requests/messages/request_notes_for_team_response.fbs b/scouting/webserver/requests/messages/request_notes_for_team_response.fbs
new file mode 100644
index 0000000..5c73098
--- /dev/null
+++ b/scouting/webserver/requests/messages/request_notes_for_team_response.fbs
@@ -0,0 +1,13 @@
+namespace scouting.webserver.requests;
+
+// A repeated table is better when we expect each index to have various data points
+table Note {
+    data:string (id: 0);
+}
+
+table RequestNotesForTeamResponse {
+    notes:[Note] (id: 0);
+}
+
+root_type RequestNotesForTeamResponse;
+
diff --git a/scouting/webserver/requests/messages/submit_notes.fbs b/scouting/webserver/requests/messages/submit_notes.fbs
new file mode 100644
index 0000000..cf111b3
--- /dev/null
+++ b/scouting/webserver/requests/messages/submit_notes.fbs
@@ -0,0 +1,8 @@
+namespace scouting.webserver.requests;
+
+table SubmitNotes {
+    team:int (id: 0);
+    notes:string (id: 1);
+}
+
+root_type SubmitNotes;
diff --git a/scouting/webserver/requests/messages/submit_notes_response.fbs b/scouting/webserver/requests/messages/submit_notes_response.fbs
new file mode 100644
index 0000000..2a5bea2
--- /dev/null
+++ b/scouting/webserver/requests/messages/submit_notes_response.fbs
@@ -0,0 +1,8 @@
+namespace scouting.webserver.requests;
+
+table SubmitNotesResponse {
+    // empty response
+}
+
+root_type SubmitNotesResponse;
+
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 2076030..5a469b5 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -21,8 +21,12 @@
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/server"
 	flatbuffers "github.com/google/flatbuffers/go"
 )
@@ -37,6 +41,10 @@
 type RequestDataScoutingResponseT = request_data_scouting_response.RequestDataScoutingResponseT
 type RefreshMatchList = refresh_match_list.RefreshMatchList
 type RefreshMatchListResponseT = refresh_match_list_response.RefreshMatchListResponseT
+type SubmitNotes = submit_notes.SubmitNotes
+type SubmitNotesResponseT = submit_notes_response.SubmitNotesResponseT
+type RequestNotesForTeam = request_notes_for_team.RequestNotesForTeam
+type RequestNotesForTeamResponseT = request_notes_for_team_response.RequestNotesForTeamResponseT
 
 // The interface we expect the database abstraction to conform to.
 // We use an interface here because it makes unit testing easier.
@@ -47,6 +55,8 @@
 	ReturnStats() ([]db.Stats, error)
 	QueryMatches(int32) ([]db.Match, error)
 	QueryStats(int) ([]db.Stats, error)
+	QueryNotes(int32) (db.NotesData, error)
+	AddNotes(db.NotesData) error
 }
 
 type ScrapeMatchList func(int32, string) ([]scraping.Match, error)
@@ -433,6 +443,93 @@
 	w.Write(builder.FinishedBytes())
 }
 
+func parseSubmitNotes(w http.ResponseWriter, buf []byte) (*SubmitNotes, bool) {
+	success := true
+	defer func() {
+		if r := recover(); r != nil {
+			respondWithError(w, http.StatusBadRequest, fmt.Sprintf("Failed to parse RefreshMatchList: %v", r))
+			success = false
+		}
+	}()
+	result := submit_notes.GetRootAsSubmitNotes(buf, 0)
+	return result, success
+}
+
+type submitNoteScoutingHandler struct {
+	db Database
+}
+
+func (handler submitNoteScoutingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	requestBytes, err := io.ReadAll(req.Body)
+	if err != nil {
+		respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
+		return
+	}
+
+	request, success := parseSubmitNotes(w, requestBytes)
+	if !success {
+		return
+	}
+
+	err = handler.db.AddNotes(db.NotesData{
+		TeamNumber: request.Team(),
+		Notes:      []string{string(request.Notes())},
+	})
+	if err != nil {
+		respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to insert notes: %v", err))
+		return
+	}
+
+	var response SubmitNotesResponseT
+	builder := flatbuffers.NewBuilder(10)
+	builder.Finish((&response).Pack(builder))
+	w.Write(builder.FinishedBytes())
+}
+
+func parseRequestNotesForTeam(w http.ResponseWriter, buf []byte) (*RequestNotesForTeam, bool) {
+	success := true
+	defer func() {
+		if r := recover(); r != nil {
+			respondWithError(w, http.StatusBadRequest, fmt.Sprintf("Failed to parse RefreshMatchList: %v", r))
+			success = false
+		}
+	}()
+	result := request_notes_for_team.GetRootAsRequestNotesForTeam(buf, 0)
+	return result, success
+}
+
+type requestNotesForTeamHandler struct {
+	db Database
+}
+
+func (handler requestNotesForTeamHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	requestBytes, err := io.ReadAll(req.Body)
+	if err != nil {
+		respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
+		return
+	}
+
+	request, success := parseRequestNotesForTeam(w, requestBytes)
+	if !success {
+		return
+	}
+
+	notesData, err := handler.db.QueryNotes(request.Team())
+	if err != nil {
+		respondWithError(w, http.StatusInternalServerError, fmt.Sprintf("Failed to query notes: %v", err))
+		return
+	}
+
+	var response RequestNotesForTeamResponseT
+	for _, data := range notesData.Notes {
+		response.Notes = append(response.Notes, &request_notes_for_team_response.NoteT{data})
+	}
+
+	builder := flatbuffers.NewBuilder(1024)
+	builder.Finish((&response).Pack(builder))
+	w.Write(builder.FinishedBytes())
+}
+
 func HandleRequests(db Database, scrape ScrapeMatchList, scoutingServer server.ScoutingServer) {
 	scoutingServer.HandleFunc("/requests", unknown)
 	scoutingServer.Handle("/requests/submit/data_scouting", submitDataScoutingHandler{db})
@@ -440,4 +537,6 @@
 	scoutingServer.Handle("/requests/request/matches_for_team", requestMatchesForTeamHandler{db})
 	scoutingServer.Handle("/requests/request/data_scouting", requestDataScoutingHandler{db})
 	scoutingServer.Handle("/requests/refresh_match_list", refreshMatchListHandler{db, scrape})
+	scoutingServer.Handle("/requests/submit/submit_notes", submitNoteScoutingHandler{db})
+	scoutingServer.Handle("/requests/request/notes_for_team", requestNotesForTeamHandler{db})
 }
diff --git a/scouting/webserver/requests/requests_test.go b/scouting/webserver/requests/requests_test.go
index 0183736..c716b44 100644
--- a/scouting/webserver/requests/requests_test.go
+++ b/scouting/webserver/requests/requests_test.go
@@ -19,8 +19,10 @@
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_data_scouting_response"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_matches_for_team_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_notes_for_team"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_data_scouting_response"
+	"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/submit_notes"
 	"github.com/frc971/971-Robot-Code/scouting/webserver/server"
 	flatbuffers "github.com/google/flatbuffers/go"
 )
@@ -279,6 +281,59 @@
 	}
 }
 
+func TestSubmitNotes(t *testing.T) {
+	database := MockDatabase{}
+	scoutingServer := server.NewScoutingServer()
+	HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
+	scoutingServer.Start(8080)
+	defer scoutingServer.Stop()
+
+	builder := flatbuffers.NewBuilder(1024)
+	builder.Finish((&submit_notes.SubmitNotesT{
+		Team:  971,
+		Notes: "Notes",
+	}).Pack(builder))
+
+	_, err := debug.SubmitNotes("http://localhost:8080", builder.FinishedBytes())
+	if err != nil {
+		t.Fatal("Failed to submit notes: ", err)
+	}
+
+	expected := []db.NotesData{
+		{TeamNumber: 971, Notes: []string{"Notes"}},
+	}
+
+	if !reflect.DeepEqual(database.notes, expected) {
+		t.Fatal("Submitted notes did not match", expected, database.notes)
+	}
+}
+
+func TestRequestNotes(t *testing.T) {
+	database := MockDatabase{
+		notes: []db.NotesData{{
+			TeamNumber: 971,
+			Notes:      []string{"Notes"},
+		}},
+	}
+	scoutingServer := server.NewScoutingServer()
+	HandleRequests(&database, scrapeEmtpyMatchList, scoutingServer)
+	scoutingServer.Start(8080)
+	defer scoutingServer.Stop()
+
+	builder := flatbuffers.NewBuilder(1024)
+	builder.Finish((&request_notes_for_team.RequestNotesForTeamT{
+		Team: 971,
+	}).Pack(builder))
+	response, err := debug.RequestNotes("http://localhost:8080", builder.FinishedBytes())
+	if err != nil {
+		t.Fatal("Failed to submit notes: ", err)
+	}
+
+	if response.Notes[0].Data != "Notes" {
+		t.Fatal("requested notes did not match", response)
+	}
+}
+
 // Validates that we can download the schedule from The Blue Alliance.
 func TestRefreshMatchList(t *testing.T) {
 	scrapeMockSchedule := func(int32, string) ([]scraping.Match, error) {
@@ -358,6 +413,7 @@
 type MockDatabase struct {
 	matches []db.Match
 	stats   []db.Stats
+	notes   []db.NotesData
 }
 
 func (database *MockDatabase) AddToMatch(match db.Match) error {
@@ -395,6 +451,21 @@
 	return []db.Stats{}, nil
 }
 
+func (database *MockDatabase) QueryNotes(requestedTeam int32) (db.NotesData, error) {
+	var results []string
+	for _, data := range database.notes {
+		if data.TeamNumber == requestedTeam {
+			results = append(results, data.Notes[0])
+		}
+	}
+	return db.NotesData{TeamNumber: requestedTeam, Notes: results}, nil
+}
+
+func (database *MockDatabase) AddNotes(data db.NotesData) error {
+	database.notes = append(database.notes, data)
+	return nil
+}
+
 // Returns an empty match list from the fake The Blue Alliance scraping.
 func scrapeEmtpyMatchList(int32, string) ([]scraping.Match, error) {
 	return nil, nil
diff --git a/y2022/actors/auto_splines.cc b/y2022/actors/auto_splines.cc
index b06ec99..9dd1860 100644
--- a/y2022/actors/auto_splines.cc
+++ b/y2022/actors/auto_splines.cc
@@ -80,25 +80,5 @@
       alliance);
 }
 
-flatbuffers::Offset<frc971::MultiSpline> AutonomousSplines::Spline4(
-    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
-        *builder,
-    aos::Alliance alliance) {
-  return FixSpline(
-      builder,
-      aos::CopyFlatBuffer<frc971::MultiSpline>(spline_4_, builder->fbb()),
-      alliance);
-}
-
-flatbuffers::Offset<frc971::MultiSpline> AutonomousSplines::Spline5(
-    aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
-        *builder,
-    aos::Alliance alliance) {
-  return FixSpline(
-      builder,
-      aos::CopyFlatBuffer<frc971::MultiSpline>(spline_5_, builder->fbb()),
-      alliance);
-}
-
 }  // namespace actors
 }  // namespace y2022
diff --git a/y2022/actors/auto_splines.h b/y2022/actors/auto_splines.h
index 4d532f4..546710c 100644
--- a/y2022/actors/auto_splines.h
+++ b/y2022/actors/auto_splines.h
@@ -22,15 +22,11 @@
       : test_spline_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
             "splines/test_spline.json")),
         spline_1_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-            "splines/spline_1.json")),
+            "splines/spline_5_ball_1.json")),
         spline_2_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-            "splines/spline_2.json")),
+            "splines/spline_5_ball_2.json")),
         spline_3_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-            "splines/spline_3.json")),
-        spline_4_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-            "splines/spline_4.json")),
-        spline_5_(aos::JsonFileToFlatbuffer<frc971::MultiSpline>(
-            "splines/spline_5.json")) {}
+            "splines/spline_5_ball_3.json")){}
 
   static flatbuffers::Offset<frc971::MultiSpline> BasicSSpline(
       aos::Sender<frc971::control_loops::drivetrain::Goal>::Builder *builder);
@@ -54,22 +50,12 @@
       aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
           *builder,
       aos::Alliance alliance);
-  flatbuffers::Offset<frc971::MultiSpline> Spline4(
-      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
-          *builder,
-      aos::Alliance alliance);
-  flatbuffers::Offset<frc971::MultiSpline> Spline5(
-      aos::Sender<frc971::control_loops::drivetrain::SplineGoal>::Builder
-          *builder,
-      aos::Alliance alliance);
 
  private:
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> test_spline_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> spline_1_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> spline_2_;
   aos::FlatbufferDetachedBuffer<frc971::MultiSpline> spline_3_;
-  aos::FlatbufferDetachedBuffer<frc971::MultiSpline> spline_4_;
-  aos::FlatbufferDetachedBuffer<frc971::MultiSpline> spline_5_;
 };
 
 }  // namespace actors
diff --git a/y2022/actors/autonomous_actor.cc b/y2022/actors/autonomous_actor.cc
index 339d7bf..5e344ac 100644
--- a/y2022/actors/autonomous_actor.cc
+++ b/y2022/actors/autonomous_actor.cc
@@ -104,18 +104,12 @@
     rapid_react_splines_ = {
         PlanSpline(std::bind(&AutonomousSplines::Spline1, &auto_splines_,
                              std::placeholders::_1, alliance_),
-                   SplineDirection::kForward),
+                   SplineDirection::kBackward),
         PlanSpline(std::bind(&AutonomousSplines::Spline2, &auto_splines_,
                              std::placeholders::_1, alliance_),
                    SplineDirection::kForward),
         PlanSpline(std::bind(&AutonomousSplines::Spline3, &auto_splines_,
                              std::placeholders::_1, alliance_),
-                   SplineDirection::kForward),
-        PlanSpline(std::bind(&AutonomousSplines::Spline4, &auto_splines_,
-                             std::placeholders::_1, alliance_),
-                   SplineDirection::kBackward),
-        PlanSpline(std::bind(&AutonomousSplines::Spline5, &auto_splines_,
-                             std::placeholders::_1, alliance_),
                    SplineDirection::kBackward)};
     starting_position_ = rapid_react_splines_.value()[0].starting_position();
     CHECK(starting_position_);
@@ -212,56 +206,53 @@
   auto &splines = *rapid_react_splines_;
 
   // Tell the superstructure a ball was preloaded
-
   if (!WaitForPreloaded()) return;
-  // Drive and intake the 2nd ball
-  ExtendFrontIntake();
+
+  // Fire preloaded ball
+  set_turret_goal(constants::Values::kTurretFrontIntakePos());
+  set_fire_at_will(true);
+  SendSuperstructureGoal();
+  if (!WaitForBallsShot(1)) return;
+  set_fire_at_will(false);
+  SendSuperstructureGoal();
+
+  // Drive and intake the 2 balls in nearest to the starting zonei
+  set_turret_goal(constants::Values::kTurretBackIntakePos());
+  ExtendBackIntake();
   if (!splines[0].WaitForPlan()) return;
   splines[0].Start();
   if (!splines[0].WaitForSplineDistanceRemaining(0.02)) return;
 
   // Fire the two balls once we stopped
+  RetractBackIntake();
   set_fire_at_will(true);
   SendSuperstructureGoal();
   if (!WaitForBallsShot(2)) return;
   set_fire_at_will(false);
-
-  // Drive and intake the 3rd ball
-  if (!splines[1].WaitForPlan()) return;
-  splines[1].Start();
-  if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
-
-  // Fire the 3rd once we stopped.
-  set_fire_at_will(true);
   SendSuperstructureGoal();
-  if (!WaitForBallsShot(1)) return;
-  set_fire_at_will(false);
 
   // Drive to the human player station while intaking two balls.
   // Once is already placed down,
   // and one will be rolled to the robot by the human player
-  if (!splines[2].WaitForPlan()) return;
-  splines[2].Start();
-  if (!splines[2].WaitForSplineDistanceRemaining(0.02)) return;
+  ExtendFrontIntake();
+  if (!splines[1].WaitForPlan()) return;
+  splines[1].Start();
+  if (!splines[1].WaitForSplineDistanceRemaining(0.02)) return;
 
   // Drive to the shooting position
-  if (!splines[3].WaitForPlan()) return;
-  splines[3].Start();
-  if (!splines[3].WaitForSplineDistanceRemaining(0.02)) return;
+  if (!splines[2].WaitForPlan()) return;
+  splines[2].Start();
+  if (!splines[2].WaitForSplineDistanceRemaining(2.00)) return;
+  RetractFrontIntake();
+
+  if (!splines[2].WaitForSplineDistanceRemaining(0.02)) return;
 
   // Fire the two balls once we stopped
   set_fire_at_will(true);
   SendSuperstructureGoal();
   if (!WaitForBallsShot(2)) return;
   set_fire_at_will(false);
-
-  // Done intaking
-  RetractFrontIntake();
-
-  // Drive to the middle of the field to get ready for teleop
-  if (!splines[4].WaitForPlan()) return;
-  splines[4].Start();
-  if (!splines[4].WaitForSplineDistanceRemaining(0.02)) return;
+  SendSuperstructureGoal();
 
   LOG(INFO) << "Took "
             << chrono::duration<double>(aos::monotonic_clock::now() -
@@ -312,6 +303,11 @@
           CreateProfileParameters(*builder.fbb(), 20.0, 60.0));
 
   flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
+      turret_offset = CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
+          *builder.fbb(), turret_goal_,
+          CreateProfileParameters(*builder.fbb(), 12.0, 20.0));
+
+  flatbuffers::Offset<StaticZeroingSingleDOFProfiledSubsystemGoal>
       catapult_return_position_offset =
           CreateStaticZeroingSingleDOFProfiledSubsystemGoal(
               *builder.fbb(), kCatapultReturnPosition,
@@ -339,10 +335,11 @@
       transfer_roller_front_voltage_);
   superstructure_builder.add_transfer_roller_speed_back(
       transfer_roller_back_voltage_);
+  superstructure_builder.add_turret(turret_offset);
   superstructure_builder.add_catapult(catapult_goal_offset);
   superstructure_builder.add_fire(fire_);
   superstructure_builder.add_preloaded(preloaded_);
-  superstructure_builder.add_auto_aim(true);
+  superstructure_builder.add_auto_aim(false);
 
   if (builder.Send(superstructure_builder.Finish()) !=
       aos::RawSender::Error::kOk) {
diff --git a/y2022/actors/autonomous_actor.h b/y2022/actors/autonomous_actor.h
index b7d89bf..461cfc1 100644
--- a/y2022/actors/autonomous_actor.h
+++ b/y2022/actors/autonomous_actor.h
@@ -50,6 +50,9 @@
   void set_requested_intake(std::optional<RequestedIntake> requested_intake) {
     requested_intake_ = requested_intake;
   }
+  void set_turret_goal(double turret_goal) {
+    turret_goal_ = turret_goal;
+  }
 
   void set_fire_at_will(bool fire) { fire_ = fire; }
   void set_preloaded(bool preloaded) { preloaded_ = preloaded; }
@@ -80,6 +83,7 @@
   double transfer_roller_front_voltage_ = 0.0;
   double transfer_roller_back_voltage_ = 0.0;
   std::optional<RequestedIntake> requested_intake_ = std::nullopt;
+  double turret_goal_ = 0.0;
   bool fire_ = false;
   bool preloaded_ = false;
 
@@ -96,7 +100,7 @@
   aos::TimerHandler *button_poll_;
 
   std::optional<SplineHandle> test_spline_;
-  std::optional<std::array<SplineHandle, 5>> rapid_react_splines_;
+  std::optional<std::array<SplineHandle, 3>> rapid_react_splines_;
 
   aos::Alliance alliance_ = aos::Alliance::kInvalid;
   AutonomousSplines auto_splines_;
diff --git a/y2022/actors/splines/spline_5_ball_1.json b/y2022/actors/splines/spline_5_ball_1.json
new file mode 100644
index 0000000..03b5644
--- /dev/null
+++ b/y2022/actors/splines/spline_5_ball_1.json
@@ -0,0 +1 @@
+{"spline_count": 1, "spline_x": [-0.18145693702491972, -0.20576409082414582, 0.49914336935341463, 5.522928566665585, 2.880988556589501, 1.845502911614626], "spline_y": [2.346189480782648, 3.695236516639704, 4.837672745203337, 2.7973591802504263, 2.3618745632049176, 1.471550457245212], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 3.0}, {"constraint_type": "LATERAL_ACCELERATION", "value": 2.0}, {"constraint_type": "VOLTAGE", "value": 10.0}]}
\ No newline at end of file
diff --git a/y2022/actors/splines/spline_5_ball_2.json b/y2022/actors/splines/spline_5_ball_2.json
new file mode 100644
index 0000000..975d6ed
--- /dev/null
+++ b/y2022/actors/splines/spline_5_ball_2.json
@@ -0,0 +1 @@
+{"spline_count": 1, "spline_x": [1.845502911614626, 2.4171345421461163, 3.004385177342393, 5.2666273627598565, 5.91167736359207, 6.7133296469650885], "spline_y": [1.471550457245212, 2.0368843425108123, 1.4829129663110887, 1.7324754229926884, 1.9201953550863622, 2.6087941113170316], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 3}, {"constraint_type": "LATERAL_ACCELERATION", "value": 2}, {"constraint_type": "VOLTAGE", "value": 10}]}
diff --git a/y2022/actors/splines/spline_5_ball_3.json b/y2022/actors/splines/spline_5_ball_3.json
new file mode 100644
index 0000000..e9e1a41
--- /dev/null
+++ b/y2022/actors/splines/spline_5_ball_3.json
@@ -0,0 +1 @@
+{"spline_count": 1, "spline_x": [6.7133296469650885, 6.343336285408311, 5.737641975476239, 3.4208648418667504, 2.51547308321015, 1.841750386467515], "spline_y": [2.6087941113170316, 2.2490783431368313, 1.931858867758041, 1.9600940870614552, 2.031396541720077, 1.4679812465169668], "constraints": [{"constraint_type": "LONGITUDINAL_ACCELERATION", "value": 3}, {"constraint_type": "LATERAL_ACCELERATION", "value": 2}, {"constraint_type": "VOLTAGE", "value": 10}]}