Add starting quadrant and Auto balls to the scouting database

This patch makes sure that the starting quadrant data and the auto
balls that get picked actually make it into the database.

Signed-off-by: Philipp Schrader <philipp.schrader@gmail.com>
Change-Id: Icfbe31009913a7fa42b499c6d53fe07310e1e12a
diff --git a/scouting/webserver/requests/debug/cli/cli_test.py b/scouting/webserver/requests/debug/cli/cli_test.py
index b20703b..8bebc69 100644
--- a/scouting/webserver/requests/debug/cli/cli_test.py
+++ b/scouting/webserver/requests/debug/cli/cli_test.py
@@ -62,6 +62,12 @@
         json_path = write_json_request({
             "team": 100,
             "match": 1,
+            "starting_quadrant": 3,
+            "auto_ball_1": True,
+            "auto_ball_2": False,
+            "auto_ball_3": False,
+            "auto_ball_4": False,
+            "auto_ball_5": True,
             "missed_shots_auto": 10,
             "upper_goal_auto": 11,
             "lower_goal_auto": 12,
@@ -92,7 +98,13 @@
             LowerGoalTele: (int32) 15,
             DefenseRating: (int32) 3,
             Climbing: (int32) 1,
-            CollectedBy: (string) (len=9) "debug_cli"
+            CollectedBy: (string) (len=9) "debug_cli",
+            AutoBall1: (bool) true,
+            AutoBall2: (bool) false,
+            AutoBall3: (bool) false,
+            AutoBall4: (bool) false,
+            AutoBall5: (bool) true,
+            StartingQuadrant: (int32) 3
             }"""), stdout)
 
     def test_request_all_matches(self):
diff --git a/scouting/webserver/requests/messages/request_data_scouting_response.fbs b/scouting/webserver/requests/messages/request_data_scouting_response.fbs
index 5703a07..7d91cb7 100644
--- a/scouting/webserver/requests/messages/request_data_scouting_response.fbs
+++ b/scouting/webserver/requests/messages/request_data_scouting_response.fbs
@@ -3,6 +3,7 @@
 table Stats {
     team:int (id: 0);
     match:int (id: 1);
+
     missed_shots_auto:int (id: 2);
     upper_goal_auto:int (id:3);
     lower_goal_auto:int (id:4);
@@ -12,6 +13,15 @@
     defense_rating:int (id:8);
     climbing:int (id:9);
     collected_by:string (id:10);
+
+    auto_ball_1:bool (id:11);
+    auto_ball_2:bool (id:12);
+    auto_ball_3:bool (id:13);
+    auto_ball_4:bool (id:14);
+    auto_ball_5:bool (id:15);
+    // The quadrant that the robot starts in for autonomous mode.
+    // Valid values are 1 through 4.
+    starting_quadrant: int (id:16);
 }
 
 table RequestDataScoutingResponse {
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 5a469b5..13d7396 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -142,8 +142,13 @@
 	}
 
 	stats := db.Stats{
-		TeamNumber:      request.Team(),
-		MatchNumber:     request.Match(),
+		TeamNumber:       request.Team(),
+		MatchNumber:      request.Match(),
+		StartingQuadrant: request.StartingQuadrant(),
+		AutoBallPickedUp: [5]bool{
+			request.AutoBall1(), request.AutoBall2(), request.AutoBall3(),
+			request.AutoBall4(), request.AutoBall5(),
+		},
 		ShotsMissedAuto: request.MissedShotsAuto(),
 		UpperGoalAuto:   request.UpperGoalAuto(),
 		LowerGoalAuto:   request.LowerGoalAuto(),
@@ -155,9 +160,17 @@
 		CollectedBy:     username,
 	}
 
+	// Do some error checking.
+	if stats.StartingQuadrant < 1 || stats.StartingQuadrant > 4 {
+		respondWithError(w, http.StatusBadRequest, fmt.Sprint(
+			"Invalid starting_quadrant field value of ", stats.StartingQuadrant))
+		return
+	}
+
 	err = handler.db.AddToStats(stats)
 	if err != nil {
 		respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to submit datascouting data: ", err))
+		return
 	}
 
 	builder := flatbuffers.NewBuilder(50 * 1024)
@@ -316,17 +329,23 @@
 	var response RequestDataScoutingResponseT
 	for _, stat := range stats {
 		response.StatsList = append(response.StatsList, &request_data_scouting_response.StatsT{
-			Team:            stat.TeamNumber,
-			Match:           stat.MatchNumber,
-			MissedShotsAuto: stat.ShotsMissedAuto,
-			UpperGoalAuto:   stat.UpperGoalAuto,
-			LowerGoalAuto:   stat.LowerGoalAuto,
-			MissedShotsTele: stat.ShotsMissed,
-			UpperGoalTele:   stat.UpperGoalShots,
-			LowerGoalTele:   stat.LowerGoalShots,
-			DefenseRating:   stat.PlayedDefense,
-			Climbing:        stat.Climbing,
-			CollectedBy:     stat.CollectedBy,
+			Team:             stat.TeamNumber,
+			Match:            stat.MatchNumber,
+			StartingQuadrant: stat.StartingQuadrant,
+			AutoBall1:        stat.AutoBallPickedUp[0],
+			AutoBall2:        stat.AutoBallPickedUp[1],
+			AutoBall3:        stat.AutoBallPickedUp[2],
+			AutoBall4:        stat.AutoBallPickedUp[3],
+			AutoBall5:        stat.AutoBallPickedUp[4],
+			MissedShotsAuto:  stat.ShotsMissedAuto,
+			UpperGoalAuto:    stat.UpperGoalAuto,
+			LowerGoalAuto:    stat.LowerGoalAuto,
+			MissedShotsTele:  stat.ShotsMissed,
+			UpperGoalTele:    stat.UpperGoalShots,
+			LowerGoalTele:    stat.LowerGoalShots,
+			DefenseRating:    stat.PlayedDefense,
+			Climbing:         stat.Climbing,
+			CollectedBy:      stat.CollectedBy,
 		})
 	}
 
diff --git a/scouting/webserver/requests/requests_test.go b/scouting/webserver/requests/requests_test.go
index c716b44..12d918b 100644
--- a/scouting/webserver/requests/requests_test.go
+++ b/scouting/webserver/requests/requests_test.go
@@ -82,16 +82,22 @@
 
 	builder := flatbuffers.NewBuilder(1024)
 	builder.Finish((&submit_data_scouting.SubmitDataScoutingT{
-		Team:            971,
-		Match:           1,
-		MissedShotsAuto: 9971,
-		UpperGoalAuto:   9971,
-		LowerGoalAuto:   9971,
-		MissedShotsTele: 9971,
-		UpperGoalTele:   9971,
-		LowerGoalTele:   9971,
-		DefenseRating:   9971,
-		Climbing:        9971,
+		Team:             971,
+		Match:            1,
+		StartingQuadrant: 2,
+		AutoBall1:        true,
+		AutoBall2:        false,
+		AutoBall3:        false,
+		AutoBall4:        false,
+		AutoBall5:        false,
+		MissedShotsAuto:  9971,
+		UpperGoalAuto:    9971,
+		LowerGoalAuto:    9971,
+		MissedShotsTele:  9971,
+		UpperGoalTele:    9971,
+		LowerGoalTele:    9971,
+		DefenseRating:    9971,
+		Climbing:         9971,
 	}).Pack(builder))
 
 	response, err := debug.SubmitDataScouting("http://localhost:8080", builder.FinishedBytes())
@@ -221,14 +227,18 @@
 		stats: []db.Stats{
 			{
 				TeamNumber: 971, MatchNumber: 1,
-				ShotsMissed: 1, UpperGoalShots: 2, LowerGoalShots: 3,
+				StartingQuadrant: 1,
+				AutoBallPickedUp: [5]bool{true, false, false, false, true},
+				ShotsMissed:      1, UpperGoalShots: 2, LowerGoalShots: 3,
 				ShotsMissedAuto: 4, UpperGoalAuto: 5, LowerGoalAuto: 6,
 				PlayedDefense: 7, Climbing: 8,
 				CollectedBy: "john",
 			},
 			{
 				TeamNumber: 972, MatchNumber: 1,
-				ShotsMissed: 2, UpperGoalShots: 3, LowerGoalShots: 4,
+				StartingQuadrant: 2,
+				AutoBallPickedUp: [5]bool{false, false, true, false, false},
+				ShotsMissed:      2, UpperGoalShots: 3, LowerGoalShots: 4,
 				ShotsMissedAuto: 5, UpperGoalAuto: 6, LowerGoalAuto: 7,
 				PlayedDefense: 8, Climbing: 9,
 				CollectedBy: "andrea",
@@ -255,12 +265,18 @@
 			// MissedShotsTele, UpperGoalTele, LowerGoalTele,
 			// DefenseRating, Climbing,
 			// CollectedBy,
+			// AutoBall1, AutoBall2, AutoBall3,
+			// AutoBall4, AutoBall5,
+			// StartingQuadrant,
 			{
 				971, 1,
 				4, 5, 6,
 				1, 2, 3,
 				7, 8,
 				"john",
+				true, false, false,
+				false, true,
+				1,
 			},
 			{
 				972, 1,
@@ -268,6 +284,9 @@
 				2, 3, 4,
 				8, 9,
 				"andrea",
+				false, false, true,
+				false, false,
+				2,
 			},
 		},
 	}