Merge "Sandbox libxml2 and switch clang to zstd compression"
diff --git a/scouting/db/db.go b/scouting/db/db.go
index b2feabe..9df6097 100644
--- a/scouting/db/db.go
+++ b/scouting/db/db.go
@@ -69,25 +69,23 @@
}
type Stats2024 struct {
- // This is set to `true` for "pre-scouted" matches. This means that the
- // match information is unlikely to correspond with an entry in the
- // `TeamMatch` table.
- PreScouting bool `gorm:"primaryKey"`
-
- TeamNumber string `gorm:"primaryKey"`
- MatchNumber int32 `gorm:"primaryKey"`
- SetNumber int32 `gorm:"primaryKey"`
- CompLevel string `gorm:"primaryKey"`
- StartingQuadrant int32
- SpeakerAuto, AmpAuto int32
- NotesDroppedAuto int32
- MobilityAuto bool
- Speaker, Amp, SpeakerAmplified, AmpAmplified int32
- NotesDropped int32
- Penalties int32
- AvgCycle int64
- RobotDied bool
- Park, OnStage, Harmony, TrapNote, Spotlight bool
+ TeamNumber string `gorm:"primaryKey"`
+ MatchNumber int32 `gorm:"primaryKey"`
+ SetNumber int32 `gorm:"primaryKey"`
+ CompLevel string `gorm:"primaryKey"`
+ CompType string `gorm:"primaryKey"`
+ StartingQuadrant int32
+ SpeakerAuto, AmpAuto int32
+ NotesDroppedAuto int32
+ MobilityAuto bool
+ Speaker, Amp, SpeakerAmplified int32
+ NotesDropped int32
+ Shuttled, OutOfField int32
+ Penalties int32
+ AvgCycle int64
+ RobotDied bool
+ Park, OnStage, Harmony, TrapNote, Spotlight bool
+ NoShow bool
// The username of the person who collected these statistics.
// "unknown" if submitted without logging in.
@@ -96,11 +94,11 @@
}
type Action struct {
- PreScouting bool `gorm:"primaryKey"`
TeamNumber string `gorm:"primaryKey"`
MatchNumber int32 `gorm:"primaryKey"`
SetNumber int32 `gorm:"primaryKey"`
CompLevel string `gorm:"primaryKey"`
+ CompType string `gorm:"primaryKey"`
// This contains a serialized scouting.webserver.requests.ActionType flatbuffer.
CompletedAction []byte
Timestamp int64 `gorm:"primaryKey"`
@@ -242,7 +240,7 @@
}
func (database *Database) AddToStats2024(s Stats2024) error {
- if !s.PreScouting {
+ if s.CompType == "Regular" {
matches, err := database.QueryMatchesString(s.TeamNumber)
if err != nil {
return err
@@ -359,11 +357,11 @@
return stats2023, result.Error
}
-func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]Stats2024, error) {
+func (database *Database) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, compType string) ([]Stats2024, error) {
var stats2024 []Stats2024
result := database.
- Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND pre_scouting = ?",
- teamNumber, matchNumber, setNumber, compLevel, preScouting).
+ Where("team_number = ? AND match_number = ? AND set_number = ? AND comp_level = ? AND comp_type = ?",
+ teamNumber, matchNumber, setNumber, compLevel, compType).
Find(&stats2024)
return stats2024, result.Error
}
diff --git a/scouting/db/db_test.go b/scouting/db/db_test.go
index c3b1143..ed71880 100644
--- a/scouting/db/db_test.go
+++ b/scouting/db/db_test.go
@@ -144,52 +144,60 @@
correct := []Stats2024{
Stats2024{
- PreScouting: false, TeamNumber: "894",
+ CompType: "Regular", TeamNumber: "894",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "emma",
},
Stats2024{
- PreScouting: false, TeamNumber: "942",
+ CompType: "Regular", TeamNumber: "942",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 2, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "harry",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "harry",
},
Stats2024{
- PreScouting: false, TeamNumber: "432",
+ CompType: "Practice", TeamNumber: "942",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 3,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 2, Amp: 1, SpeakerAmplified: 3, AmpAmplified: 0,
+ Speaker: 2, Amp: 1, SpeakerAmplified: 3,
NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "henry",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "kaleb",
},
Stats2024{
- PreScouting: false, TeamNumber: "52A",
+ CompType: "Regular", TeamNumber: "432",
+ MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 3,
+ SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
+ Speaker: 2, Amp: 1, SpeakerAmplified: 3, Shuttled: 0, OutOfField: 2,
+ NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "henry",
+ },
+ Stats2024{
+ CompType: "Regular", TeamNumber: "52A",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 1, SpeakerAmplified: 2, AmpAmplified: 3,
+ Speaker: 0, Amp: 1, SpeakerAmplified: 2, Shuttled: 0, OutOfField: 0,
NotesDropped: 2, Penalties: 0, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "jordan",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "jordan",
},
Stats2024{
- PreScouting: false, TeamNumber: "745",
+ CompType: "Regular", TeamNumber: "745",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 5, Amp: 0, SpeakerAmplified: 2, AmpAmplified: 1,
+ Speaker: 5, Amp: 0, SpeakerAmplified: 2, Shuttled: 0, OutOfField: 0,
NotesDropped: 1, Penalties: 1, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "taylor",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "taylor",
},
Stats2024{
- PreScouting: false, TeamNumber: "934",
+ CompType: "Regular", TeamNumber: "934",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 3,
SpeakerAuto: 1, AmpAuto: 3, NotesDroppedAuto: 0, MobilityAuto: true,
- Speaker: 0, Amp: 3, SpeakerAmplified: 2, AmpAmplified: 2,
+ Speaker: 0, Amp: 3, SpeakerAmplified: 2, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 3, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: false, Harmony: true, RobotDied: false, CollectedBy: "katie",
+ Park: false, OnStage: false, Harmony: true, RobotDied: false, NoShow: true, CollectedBy: "katie",
},
}
@@ -231,12 +239,12 @@
defer fixture.TearDown()
stats := Stats2024{
- PreScouting: false, TeamNumber: "6344",
+ CompType: "Regular", TeamNumber: "6344",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1, Shuttled: 1,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "emma",
}
// Attempt to insert the non-pre-scouted data and make sure it fails.
@@ -249,7 +257,35 @@
}
// Mark the data as pre-scouting data. It should now succeed.
- stats.PreScouting = true
+ stats.CompType = "Prescouting"
+ err = fixture.db.AddToStats2024(stats)
+ check(t, err, "Failed to add prescouted stats to DB")
+}
+
+func TestInsertPracticeMatchStats2024(t *testing.T) {
+ fixture := createDatabase(t)
+ defer fixture.TearDown()
+
+ stats := Stats2024{
+ CompType: "Regular", TeamNumber: "6344",
+ MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
+ SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1,
+ NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ }
+
+ // Attempt to insert the non-practice match data and make sure it fails.
+ err := fixture.db.AddToStats2024(stats)
+ if err == nil {
+ t.Fatal("Expected error from inserting the stats.")
+ }
+ if err.Error() != "Failed to find team 6344 in match 3 in the schedule." {
+ t.Fatal("Got:", err.Error())
+ }
+
+ // Mark the data as practice match data. It should now succeed.
+ stats.CompType = "Practice"
err = fixture.db.AddToStats2024(stats)
check(t, err, "Failed to add prescouted stats to DB")
}
@@ -260,28 +296,28 @@
stats := []Stats2024{
Stats2024{
- PreScouting: false, TeamNumber: "328A",
+ CompType: "Regular", TeamNumber: "328A",
MatchNumber: 7, SetNumber: 1, CompLevel: "qm", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1, Shuttled: 2, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "emma",
},
Stats2024{
- PreScouting: false, TeamNumber: "978",
+ CompType: "Regular", TeamNumber: "978",
MatchNumber: 2, SetNumber: 2, CompLevel: "qm", StartingQuadrant: 4,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 1, Amp: 2, SpeakerAmplified: 0, AmpAmplified: 2,
+ Speaker: 1, Amp: 2, SpeakerAmplified: 0, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "emma",
},
Stats2024{
- PreScouting: false, TeamNumber: "328A",
+ CompType: "Regular", TeamNumber: "328A",
MatchNumber: 4, SetNumber: 1, CompLevel: "qm", StartingQuadrant: 2,
SpeakerAuto: 1, AmpAuto: 1, NotesDroppedAuto: 1, MobilityAuto: true,
- Speaker: 0, Amp: 1, SpeakerAmplified: 1, AmpAmplified: 5,
+ Speaker: 0, Amp: 1, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 1,
NotesDropped: 1, Penalties: 0, TrapNote: false, Spotlight: true, AvgCycle: 0,
- Park: false, OnStage: false, Harmony: true, RobotDied: true, CollectedBy: "emma",
+ Park: false, OnStage: false, Harmony: true, RobotDied: true, NoShow: false, CollectedBy: "emma",
},
}
@@ -306,7 +342,7 @@
// Validate that requesting status for a single team gets us the
// expected data.
- statsFor328A, err := fixture.db.ReturnStats2024ForTeam("328A", 7, 1, "qm", false)
+ statsFor328A, err := fixture.db.ReturnStats2024ForTeam("328A", 7, 1, "qm", "Regular")
check(t, err, "Failed ReturnStats2024()")
if !reflect.DeepEqual([]Stats2024{stats[0]}, statsFor328A) {
@@ -314,7 +350,7 @@
}
// Validate that requesting team data for a non-existent match returns
// nothing.
- statsForMissing, err := fixture.db.ReturnStats2024ForTeam("6344", 9, 1, "qm", false)
+ statsForMissing, err := fixture.db.ReturnStats2024ForTeam("6344", 9, 1, "qm", "Regular")
check(t, err, "Failed ReturnStats2024()")
if !reflect.DeepEqual([]Stats2024{}, statsForMissing) {
@@ -695,47 +731,47 @@
startingStats := []Stats2024{
Stats2024{
- PreScouting: false, TeamNumber: "345",
+ CompType: "Regular", TeamNumber: "345",
MatchNumber: 5, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 1, Amp: 3, SpeakerAmplified: 1, AmpAmplified: 3,
+ Speaker: 1, Amp: 3, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 3,
NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "bailey",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "bailey",
},
Stats2024{
- PreScouting: false, TeamNumber: "645",
+ CompType: "Practice", TeamNumber: "645",
MatchNumber: 5, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 1, Amp: 2, SpeakerAmplified: 0, AmpAmplified: 1,
+ Speaker: 1, Amp: 2, SpeakerAmplified: 0, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "kate",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "kate",
},
Stats2024{
- PreScouting: false, TeamNumber: "323",
+ CompType: "Regular", TeamNumber: "323",
MatchNumber: 5, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 1, AmpAuto: 1, NotesDroppedAuto: 1, MobilityAuto: true,
- Speaker: 0, Amp: 0, SpeakerAmplified: 2, AmpAmplified: 1,
+ Speaker: 0, Amp: 0, SpeakerAmplified: 2, Shuttled: 0, OutOfField: 2,
NotesDropped: 1, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "tyler",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "tyler",
},
Stats2024{
- PreScouting: false, TeamNumber: "542",
+ CompType: "Regular", TeamNumber: "542",
MatchNumber: 5, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 1, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 1, Amp: 2, SpeakerAmplified: 2, AmpAmplified: 1,
+ Speaker: 1, Amp: 2, SpeakerAmplified: 2, Shuttled: 2, OutOfField: 2,
NotesDropped: 1, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: false, Harmony: true, RobotDied: false, CollectedBy: "max",
+ Park: false, OnStage: false, Harmony: true, RobotDied: false, NoShow: false, CollectedBy: "max",
},
}
correct := []Stats2024{
Stats2024{
- PreScouting: false, TeamNumber: "345",
+ CompType: "Regular", TeamNumber: "345",
MatchNumber: 5, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 1, Amp: 3, SpeakerAmplified: 1, AmpAmplified: 3,
+ Speaker: 1, Amp: 3, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 3,
NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "bailey",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "bailey",
},
}
@@ -1149,36 +1185,36 @@
correct := []Stats2024{
Stats2024{
- PreScouting: false, TeamNumber: "894",
+ CompType: "Practice", TeamNumber: "894",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "emma",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "emma",
},
Stats2024{
- PreScouting: false, TeamNumber: "942",
+ CompType: "Regular", TeamNumber: "942",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 2, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 0, Amp: 5, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 0, Amp: 5, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 2, TrapNote: true, Spotlight: false, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "harry",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "harry",
},
Stats2024{
- PreScouting: false, TeamNumber: "432",
+ CompType: "Practice", TeamNumber: "432",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 3,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 2, MobilityAuto: true,
- Speaker: 2, Amp: 1, SpeakerAmplified: 3, AmpAmplified: 0,
+ Speaker: 2, Amp: 1, SpeakerAmplified: 3, Shuttled: 5, OutOfField: 1,
NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "henry",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "henry",
},
Stats2024{
- PreScouting: false, TeamNumber: "52A",
+ CompType: "Regular", TeamNumber: "52A",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 1, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 1, SpeakerAmplified: 2, AmpAmplified: 3,
+ Speaker: 0, Amp: 1, SpeakerAmplified: 2, Shuttled: 0, OutOfField: 0,
NotesDropped: 2, Penalties: 0, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "jordan",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "jordan",
},
}
diff --git a/scouting/scouting_qrcode_test.cy.js b/scouting/scouting_qrcode_test.cy.js
index 559481e..34da4da 100644
--- a/scouting/scouting_qrcode_test.cy.js
+++ b/scouting/scouting_qrcode_test.cy.js
@@ -64,7 +64,7 @@
// Pick and Place Cube in Teleop.
clickButton('Start Teleop');
clickButton('NOTE');
- clickButton('AMP AMPLIFIED');
+ clickButton('SPEAKER AMPLIFIED');
// Generate some extra actions so that we are guaranteed to have at least 2
// QR codes.
diff --git a/scouting/scouting_test.cy.js b/scouting/scouting_test.cy.js
index 7600bb5..2727104 100644
--- a/scouting/scouting_test.cy.js
+++ b/scouting/scouting_test.cy.js
@@ -91,7 +91,7 @@
// Pick and Place Cube in Teleop.
clickButton('Start Teleop');
clickButton('NOTE');
- clickButton('AMP AMPLIFIED');
+ clickButton('SPEAKER AMPLIFIED');
// Robot dead and revive.
clickButton('DEAD');
@@ -187,6 +187,21 @@
headerShouldBe('1 Init ');
});
+ it('should: allow users to scout practice matches.', () => {
+ switchToTab('Entry');
+ headerShouldBe(' Team Selection ');
+ setInputTo('#team_number', '1');
+
+ // The default team information should be invalid.
+ cy.contains('button', 'Next').should('be.disabled');
+
+ // Click the checkmark to designate this as pre-scouting.
+ // We should now be able to continue scouting.
+ cy.get('#practice_match').click();
+ clickButton('Next');
+ headerShouldBe('1 Init ');
+ });
+
it('should: allow users to submit pit images.', () => {
switchToTab('Pit');
headerShouldBe('Pit Scouting');
diff --git a/scouting/webserver/requests/BUILD b/scouting/webserver/requests/BUILD
index 846414c..07ebbe6 100644
--- a/scouting/webserver/requests/BUILD
+++ b/scouting/webserver/requests/BUILD
@@ -56,7 +56,6 @@
deps = [
"//scouting/db",
"//scouting/webserver/requests/debug",
- "//scouting/webserver/requests/messages:delete_2023_data_scouting_go_fbs",
"//scouting/webserver/requests/messages:delete_2024_data_scouting_go_fbs",
"//scouting/webserver/requests/messages:request_2023_data_scouting_go_fbs",
"//scouting/webserver/requests/messages:request_2023_data_scouting_response_go_fbs",
diff --git a/scouting/webserver/requests/messages/request_2024_data_scouting_response.fbs b/scouting/webserver/requests/messages/request_2024_data_scouting_response.fbs
index f450d38..c0ac039 100644
--- a/scouting/webserver/requests/messages/request_2024_data_scouting_response.fbs
+++ b/scouting/webserver/requests/messages/request_2024_data_scouting_response.fbs
@@ -15,8 +15,10 @@
speaker:int (id:7);
amp:int (id:8);
speaker_amplified:int (id:9);
- amp_amplified:int (id:10);
+ amp_amplified:int (id:10, deprecated);
notes_dropped:int (id:11);
+ shuttled:int (id:24);
+ out_of_field:int (id:25);
penalties:int (id:12);
trap_note:bool (id:13);
@@ -27,9 +29,11 @@
harmony: bool (id:17);
spotlight: bool (id:22);
robot_died: bool (id:23);
+ no_show: bool (id:27);
- pre_scouting:bool (id:20);
+ pre_scouting:bool (id:20, deprecated);
collected_by:string (id:21);
+ comp_type:string (id:26);
}
table Request2024DataScoutingResponse {
diff --git a/scouting/webserver/requests/messages/submit_2024_actions.fbs b/scouting/webserver/requests/messages/submit_2024_actions.fbs
index e927b67..fce9045 100644
--- a/scouting/webserver/requests/messages/submit_2024_actions.fbs
+++ b/scouting/webserver/requests/messages/submit_2024_actions.fbs
@@ -6,12 +6,15 @@
enum ScoreType: short {
kAMP,
- kAMP_AMPLIFIED,
kSPEAKER,
kSPEAKER_AMPLIFIED,
kDROPPED,
+ kOUT_OF_FIELD,
+ kSHUTTLED,
}
+table NoShowAction {}
+
table MobilityAction {
mobility:bool (id:0);
}
@@ -54,6 +57,7 @@
union ActionType {
MobilityAction,
+ NoShowAction,
StartMatchAction,
EndAutoPhaseAction,
PickupNoteAction,
@@ -76,8 +80,6 @@
comp_level:string (id: 3);
actions_list:[Action] (id:4);
- // If this is for pre-scouting, then the server should accept this
- // submission. I.e. checking that the match information exists in the match
- // list should be skipped.
- pre_scouting:bool (id: 5);
+ pre_scouting:bool (id: 5, deprecated);
+ comp_type:string (id: 6);
}
diff --git a/scouting/webserver/requests/requests.go b/scouting/webserver/requests/requests.go
index 1536093..0367ff2 100644
--- a/scouting/webserver/requests/requests.go
+++ b/scouting/webserver/requests/requests.go
@@ -102,7 +102,7 @@
ReturnStats2023() ([]db.Stats2023, error)
ReturnStats2023ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]db.Stats2023, error)
ReturnStats2024() ([]db.Stats2024, error)
- ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]db.Stats2024, error)
+ ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, compType string) ([]db.Stats2024, error)
QueryAllShifts(int) ([]db.Shift, error)
QueryNotes(string) ([]string, error)
QueryPitImages(string) ([]db.RequestedPitImage, error)
@@ -200,7 +200,7 @@
func (handler requestAllMatchesHandler) teamHasBeenDataScouted(key MatchAssemblyKey, teamNumber string) (bool, error) {
stats, err := handler.db.ReturnStats2024ForTeam(
- teamNumber, key.MatchNumber, key.SetNumber, key.CompLevel, false)
+ teamNumber, key.MatchNumber, key.SetNumber, key.CompLevel, "Regular")
if err != nil {
return false, err
}
@@ -453,10 +453,11 @@
picked_up := false
lastPlacedTime := int64(0)
stat := db.Stats2024{
- PreScouting: submit2024Actions.PreScouting(), TeamNumber: string(submit2024Actions.TeamNumber()), MatchNumber: submit2024Actions.MatchNumber(), SetNumber: submit2024Actions.SetNumber(), CompLevel: string(submit2024Actions.CompLevel()),
+ CompType: string(submit2024Actions.CompType()), TeamNumber: string(submit2024Actions.TeamNumber()),
+ MatchNumber: submit2024Actions.MatchNumber(), SetNumber: submit2024Actions.SetNumber(), CompLevel: string(submit2024Actions.CompLevel()),
StartingQuadrant: 0, SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 0, SpeakerAmplified: 0, AmpAmplified: 0, NotesDropped: 0, Penalties: 0,
- TrapNote: false, Spotlight: false, AvgCycle: 0, Park: false, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "",
+ Speaker: 0, Amp: 0, SpeakerAmplified: 0, NotesDropped: 0, Shuttled: 0, OutOfField: 0, Penalties: 0,
+ TrapNote: false, Spotlight: false, AvgCycle: 0, Park: false, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "",
}
// Loop over all actions.
for i := 0; i < submit2024Actions.ActionsListLength(); i++ {
@@ -479,7 +480,6 @@
if mobilityAction.Mobility() {
stat.MobilityAuto = true
}
-
} else if action_type == submit_2024_actions.ActionTypePenaltyAction {
var penaltyAction submit_2024_actions.PenaltyAction
penaltyAction.Init(actionTable.Bytes, actionTable.Pos)
@@ -490,6 +490,11 @@
robotDeathAction.Init(actionTable.Bytes, actionTable.Pos)
stat.RobotDied = true
+ } else if action_type == submit_2024_actions.ActionTypeNoShowAction {
+ var NoShowAction submit_2024_actions.NoShowAction
+ NoShowAction.Init(actionTable.Bytes, actionTable.Pos)
+ stat.NoShow = true
+
} else if action_type == submit_2024_actions.ActionTypePickupNoteAction {
var pick_up_action submit_2024_actions.PickupNoteAction
pick_up_action.Init(actionTable.Bytes, actionTable.Pos)
@@ -502,12 +507,11 @@
}
score_type := place_action.ScoreType()
auto := place_action.Auto()
+ count_in_cycle := true
if score_type == submit_2024_actions.ScoreTypekAMP && auto {
stat.AmpAuto += 1
} else if score_type == submit_2024_actions.ScoreTypekAMP && !auto {
stat.Amp += 1
- } else if score_type == submit_2024_actions.ScoreTypekAMP_AMPLIFIED && !auto {
- stat.AmpAmplified += 1
} else if score_type == submit_2024_actions.ScoreTypekSPEAKER && !auto {
stat.Speaker += 1
} else if score_type == submit_2024_actions.ScoreTypekSPEAKER && auto {
@@ -516,20 +520,32 @@
stat.SpeakerAmplified += 1
} else if score_type == submit_2024_actions.ScoreTypekDROPPED && auto {
stat.NotesDroppedAuto += 1
+ count_in_cycle = false
} else if score_type == submit_2024_actions.ScoreTypekDROPPED && !auto {
stat.NotesDropped += 1
+ count_in_cycle = false
+ } else if score_type == submit_2024_actions.ScoreTypekSHUTTLED {
+ stat.Shuttled += 1
+ count_in_cycle = false
+ } else if score_type == submit_2024_actions.ScoreTypekOUT_OF_FIELD {
+ stat.OutOfField += 1
+ count_in_cycle = false
} else {
return db.Stats2024{}, errors.New(fmt.Sprintf("Got unknown ObjectType/ScoreLevel/Auto combination"))
}
picked_up = false
- if lastPlacedTime != int64(0) {
- // If this is not the first time we place,
- // start counting cycle time. We define cycle
- // time as the time between placements.
- overall_time += int64(action.Timestamp()) - lastPlacedTime
+ if count_in_cycle {
+ // Assuming dropped, shuttled, and out of field
+ // notes are not counted in total cycle time.
+ if lastPlacedTime != int64(0) {
+ // If this is not the first time we place,
+ // start counting cycle time. We define cycle
+ // time as the time between placements.
+ overall_time += int64(action.Timestamp()) - lastPlacedTime
+ }
cycles += 1
+ lastPlacedTime = int64(action.Timestamp())
}
- lastPlacedTime = int64(action.Timestamp())
} else if action_type == submit_2024_actions.ActionTypeEndMatchAction {
var endMatchAction submit_2024_actions.EndMatchAction
endMatchAction.Init(actionTable.Bytes, actionTable.Pos)
@@ -590,8 +606,9 @@
Speaker: stat.Speaker,
Amp: stat.Amp,
SpeakerAmplified: stat.SpeakerAmplified,
- AmpAmplified: stat.AmpAmplified,
NotesDropped: stat.NotesDropped,
+ Shuttled: stat.Shuttled,
+ OutOfField: stat.OutOfField,
Penalties: stat.Penalties,
TrapNote: stat.TrapNote,
Spotlight: stat.Spotlight,
@@ -600,7 +617,9 @@
OnStage: stat.OnStage,
Harmony: stat.Harmony,
RobotDied: stat.RobotDied,
+ NoShow: stat.NoShow,
CollectedBy: stat.CollectedBy,
+ CompType: stat.CompType,
})
}
@@ -1123,16 +1142,18 @@
requestBytes, err := io.ReadAll(req.Body)
if err != nil {
+ log.Println("Failed to receive submission request from", username)
respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
return
}
request, success := parseRequest(w, requestBytes, "Submit2024Actions", submit_2024_actions.GetRootAsSubmit2024Actions)
if !success {
+ log.Println("Failed to parse submission request from", username)
return
}
- log.Println("Got actions for match", request.MatchNumber(), "team", string(request.TeamNumber()), "from", username)
+ log.Println("Got actions for match", request.MatchNumber(), "team", string(request.TeamNumber()), "type", string(request.CompType()), "from", username)
for i := 0; i < request.ActionsListLength(); i++ {
@@ -1140,7 +1161,7 @@
request.ActionsList(&action, i)
dbAction := db.Action{
- PreScouting: request.PreScouting(),
+ CompType: string(request.CompType()),
TeamNumber: string(request.TeamNumber()),
MatchNumber: request.MatchNumber(),
SetNumber: request.SetNumber(),
@@ -1153,6 +1174,7 @@
// Do some error checking.
if action.Timestamp() < 0 {
+ log.Println("Got action with invalid timestamp (", action.Timestamp(), ") from", username)
respondWithError(w, http.StatusBadRequest, fmt.Sprint(
"Invalid timestamp field value of ", action.Timestamp()))
return
@@ -1160,6 +1182,7 @@
err = handler.db.AddAction(dbAction)
if err != nil {
+ log.Println("Failed to add action from", username, "to the database:", err)
respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to add action to database: ", err))
return
}
@@ -1167,6 +1190,7 @@
stats, err := ConvertActionsToStat2024(request)
if err != nil {
+ log.Println("Failed to add action from", username, "to the database:", err)
respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to convert actions to stats: ", err))
return
}
@@ -1175,6 +1199,7 @@
err = handler.db.AddToStats2024(stats)
if err != nil {
+ log.Println("Failed to submit stats from", username, "to the database:", err)
respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to submit stats2024: ", stats, ": ", err))
return
}
@@ -1182,77 +1207,8 @@
builder := flatbuffers.NewBuilder(50 * 1024)
builder.Finish((&Submit2024ActionsResponseT{}).Pack(builder))
w.Write(builder.FinishedBytes())
-}
-type submitActionsHandler struct {
- db Database
-}
-
-func (handler submitActionsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- // Get the username of the person submitting the data.
- username := parseUsername(req)
-
- requestBytes, err := io.ReadAll(req.Body)
- if err != nil {
- respondWithError(w, http.StatusBadRequest, fmt.Sprint("Failed to read request bytes:", err))
- return
- }
-
- request, success := parseRequest(w, requestBytes, "SubmitActions", submit_actions.GetRootAsSubmitActions)
- if !success {
- return
- }
-
- log.Println("Got actions for match", request.MatchNumber(), "team", string(request.TeamNumber()), "from", username)
-
- for i := 0; i < request.ActionsListLength(); i++ {
-
- var action Action
- request.ActionsList(&action, i)
-
- dbAction := db.Action{
- PreScouting: request.PreScouting(),
- TeamNumber: string(request.TeamNumber()),
- MatchNumber: request.MatchNumber(),
- SetNumber: request.SetNumber(),
- CompLevel: string(request.CompLevel()),
- //TODO: Serialize CompletedAction
- CompletedAction: []byte{},
- Timestamp: action.Timestamp(),
- CollectedBy: username,
- }
-
- // Do some error checking.
- if action.Timestamp() < 0 {
- respondWithError(w, http.StatusBadRequest, fmt.Sprint(
- "Invalid timestamp field value of ", action.Timestamp()))
- return
- }
-
- err = handler.db.AddAction(dbAction)
- if err != nil {
- respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to add action to database: ", err))
- return
- }
- }
-
- stats, err := ConvertActionsToStat(request)
- if err != nil {
- respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to convert actions to stats: ", err))
- return
- }
-
- stats.CollectedBy = username
-
- err = handler.db.AddToStats2023(stats)
- if err != nil {
- respondWithError(w, http.StatusInternalServerError, fmt.Sprint("Failed to submit stats: ", stats, ": ", err))
- return
- }
-
- builder := flatbuffers.NewBuilder(50 * 1024)
- builder.Finish((&SubmitActionsResponseT{}).Pack(builder))
- w.Write(builder.FinishedBytes())
+ log.Println("Successfully added stats from", username)
}
type Delete2024DataScoutingHandler struct {
@@ -1358,7 +1314,6 @@
scoutingServer.Handle("/requests/submit/shift_schedule", submitShiftScheduleHandler{db})
scoutingServer.Handle("/requests/request/shift_schedule", requestShiftScheduleHandler{db})
scoutingServer.Handle("/requests/submit/submit_driver_ranking", SubmitDriverRankingHandler{db})
- scoutingServer.Handle("/requests/submit/submit_actions", submitActionsHandler{db})
scoutingServer.Handle("/requests/submit/submit_2024_actions", submit2024ActionsHandler{db})
scoutingServer.Handle("/requests/delete/delete_2023_data_scouting", Delete2023DataScoutingHandler{db})
scoutingServer.Handle("/requests/delete/delete_2024_data_scouting", Delete2024DataScoutingHandler{db})
diff --git a/scouting/webserver/requests/requests_test.go b/scouting/webserver/requests/requests_test.go
index 6968346..d0e17b8 100644
--- a/scouting/webserver/requests/requests_test.go
+++ b/scouting/webserver/requests/requests_test.go
@@ -7,7 +7,6 @@
"github.com/frc971/971-Robot-Code/scouting/db"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/debug"
- "github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/delete_2023_data_scouting"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/delete_2024_data_scouting"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting"
"github.com/frc971/971-Robot-Code/scouting/webserver/requests/messages/request_2023_data_scouting_response"
@@ -133,20 +132,20 @@
// Pretend that we have some data scouting data.
stats2024: []db.Stats2024{
{
- PreScouting: false, TeamNumber: "5",
+ CompType: "Regular", TeamNumber: "5",
MatchNumber: 1, SetNumber: 1, CompLevel: "qm", StartingQuadrant: 3,
SpeakerAuto: 2, AmpAuto: 4, NotesDroppedAuto: 1, MobilityAuto: true,
- Speaker: 0, Amp: 1, SpeakerAmplified: 2, AmpAmplified: 1,
+ Speaker: 0, Amp: 1, SpeakerAmplified: 2, Shuttled: 1, OutOfField: 2,
NotesDropped: 0, Penalties: 1, TrapNote: true, Spotlight: false, AvgCycle: 233,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "alex",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "alex",
},
{
- PreScouting: false, TeamNumber: "973",
+ CompType: "Regular", TeamNumber: "973",
MatchNumber: 3, SetNumber: 1, CompLevel: "qm", StartingQuadrant: 1,
SpeakerAuto: 0, AmpAuto: 2, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 4, SpeakerAmplified: 3, AmpAmplified: 1,
+ Speaker: 0, Amp: 4, SpeakerAmplified: 3, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 1, TrapNote: true, Spotlight: false, AvgCycle: 120,
- Park: true, OnStage: false, Harmony: false, RobotDied: true, CollectedBy: "bob",
+ Park: true, OnStage: false, Harmony: false, RobotDied: true, NoShow: false, CollectedBy: "bob",
},
},
}
@@ -210,20 +209,28 @@
db := MockDatabase{
stats2024: []db.Stats2024{
{
- PreScouting: false, TeamNumber: "342",
+ CompType: "Regular", TeamNumber: "342",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 1, NotesDroppedAuto: 0, MobilityAuto: true,
- Speaker: 4, Amp: 2, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 4, Amp: 2, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 2,
NotesDropped: 2, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "alex",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "alex",
},
{
- PreScouting: false, TeamNumber: "982",
+ CompType: "Regular", TeamNumber: "132",
+ MatchNumber: 4, SetNumber: 2, CompLevel: "quals", StartingQuadrant: 0,
+ SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
+ Speaker: 0, Amp: 0, SpeakerAmplified: 0, Shuttled: 0, OutOfField: 1,
+ NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
+ Park: false, OnStage: false, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "jeff",
+ },
+ {
+ CompType: "Regular", TeamNumber: "982",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 2, SpeakerAmplified: 3, AmpAmplified: 2,
+ Speaker: 0, Amp: 2, SpeakerAmplified: 3, Shuttled: 1, OutOfField: 0,
NotesDropped: 1, Penalties: 0, TrapNote: false, Spotlight: true, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "george",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "george",
},
},
}
@@ -243,20 +250,28 @@
expected := request_2024_data_scouting_response.Request2024DataScoutingResponseT{
StatsList: []*request_2024_data_scouting_response.Stats2024T{
{
- PreScouting: false, TeamNumber: "342",
+ CompType: "Regular", TeamNumber: "342",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 4,
SpeakerAuto: 1, AmpAuto: 1, NotesDroppedAuto: 0, MobilityAuto: true,
- Speaker: 4, Amp: 2, SpeakerAmplified: 1, AmpAmplified: 0,
+ Speaker: 4, Amp: 2, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 2,
NotesDropped: 2, Penalties: 2, TrapNote: true, Spotlight: true, AvgCycle: 0,
- Park: true, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "alex",
+ Park: true, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "alex",
},
{
- PreScouting: false, TeamNumber: "982",
+ CompType: "Regular", TeamNumber: "132",
+ MatchNumber: 4, SetNumber: 2, CompLevel: "quals", StartingQuadrant: 0,
+ SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
+ Speaker: 0, Amp: 0, SpeakerAmplified: 0, Shuttled: 0, OutOfField: 1,
+ NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
+ Park: false, OnStage: false, Harmony: false, RobotDied: false, NoShow: true, CollectedBy: "jeff",
+ },
+ {
+ CompType: "Regular", TeamNumber: "982",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 2, SpeakerAmplified: 3, AmpAmplified: 2,
+ Speaker: 0, Amp: 2, SpeakerAmplified: 3, Shuttled: 1, OutOfField: 0,
NotesDropped: 1, Penalties: 0, TrapNote: false, Spotlight: true, AvgCycle: 0,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "george",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "george",
},
},
}
@@ -371,12 +386,10 @@
},
{
ActionTaken: &submit_2024_actions.ActionTypeT{
- Type: submit_2024_actions.ActionTypePickupNoteAction,
- Value: &submit_2024_actions.PickupNoteActionT{
- Auto: true,
- },
+ Type: submit_2024_actions.ActionTypeNoShowAction,
+ Value: &submit_2024_actions.NoShowActionT{},
},
- Timestamp: 400,
+ Timestamp: 200,
},
{
ActionTaken: &submit_2024_actions.ActionTypeT{
@@ -428,7 +441,7 @@
ActionTaken: &submit_2024_actions.ActionTypeT{
Type: submit_2024_actions.ActionTypePlaceNoteAction,
Value: &submit_2024_actions.PlaceNoteActionT{
- ScoreType: submit_2024_actions.ScoreTypekAMP_AMPLIFIED,
+ ScoreType: submit_2024_actions.ScoreTypekSHUTTLED,
Auto: false,
},
},
@@ -502,7 +515,7 @@
Timestamp: 4200,
},
},
- PreScouting: false,
+ CompType: "Regular",
}).Pack(builder))
submit2024Actions := submit_2024_actions.GetRootAsSubmit2024Actions(builder.FinishedBytes(), 0)
@@ -513,164 +526,12 @@
}
expected := db.Stats2024{
- PreScouting: false, TeamNumber: "4244",
+ CompType: "Regular", TeamNumber: "4244",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 0, AmpAuto: 1, NotesDroppedAuto: 0, MobilityAuto: true,
- Speaker: 0, Amp: 0, SpeakerAmplified: 1, AmpAmplified: 1,
- NotesDropped: 1, Penalties: 5, TrapNote: false, Spotlight: false, AvgCycle: 633,
- Park: false, OnStage: false, Harmony: true, RobotDied: true, CollectedBy: "",
- }
-
- if expected != response {
- t.Fatal("Expected ", expected, ", but got ", response)
- }
-}
-
-// Validates that we can request the 2023 stats.
-func TestConvertActionsToStat(t *testing.T) {
- builder := flatbuffers.NewBuilder(1024)
- builder.Finish((&submit_actions.SubmitActionsT{
- TeamNumber: "4244",
- MatchNumber: 3,
- SetNumber: 1,
- CompLevel: "quals",
- ActionsList: []*submit_actions.ActionT{
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypeStartMatchAction,
- Value: &submit_actions.StartMatchActionT{
- Position: 1,
- },
- },
- Timestamp: 0,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- Auto: true,
- },
- },
- Timestamp: 400,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- Auto: true,
- },
- },
- Timestamp: 800,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePlaceObjectAction,
- Value: &submit_actions.PlaceObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- ScoreLevel: submit_actions.ScoreLevelkLow,
- Auto: true,
- },
- },
- Timestamp: 2000,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypeMobilityAction,
- Value: &submit_actions.MobilityActionT{
- Mobility: true,
- },
- },
- Timestamp: 2200,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypeAutoBalanceAction,
- Value: &submit_actions.AutoBalanceActionT{
- Docked: true,
- Engaged: true,
- BalanceAttempt: false,
- },
- },
- Timestamp: 2400,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCone,
- Auto: false,
- },
- },
- Timestamp: 2800,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePlaceObjectAction,
- Value: &submit_actions.PlaceObjectActionT{
- ObjectType: submit_actions.ObjectTypekCone,
- ScoreLevel: submit_actions.ScoreLevelkHigh,
- Auto: false,
- },
- },
- Timestamp: 3100,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- Auto: false,
- },
- },
- Timestamp: 3500,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePlaceObjectAction,
- Value: &submit_actions.PlaceObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- ScoreLevel: submit_actions.ScoreLevelkSupercharged,
- Auto: false,
- },
- },
- Timestamp: 3900,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypeEndMatchAction,
- Value: &submit_actions.EndMatchActionT{
- Docked: true,
- Engaged: false,
- BalanceAttempt: true,
- },
- },
- Timestamp: 4200,
- },
- },
- PreScouting: false,
- }).Pack(builder))
-
- submitActions := submit_actions.GetRootAsSubmitActions(builder.FinishedBytes(), 0)
- response, err := ConvertActionsToStat(submitActions)
-
- if err != nil {
- t.Fatal("Failed to convert actions to stats: ", err)
- }
-
- expected := db.Stats2023{
- PreScouting: false,
- TeamNumber: "4244", MatchNumber: 3, SetNumber: 1,
- CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 1,
- MiddleCubesAuto: 0, HighCubesAuto: 0, CubesDroppedAuto: 1,
- LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
- ConesDroppedAuto: 0, LowCubes: 0, MiddleCubes: 0,
- HighCubes: 0, CubesDropped: 0, LowCones: 0,
- MiddleCones: 0, HighCones: 1, ConesDropped: 0, SuperchargedPieces: 1,
- AvgCycle: 950, Mobility: true, DockedAuto: true, EngagedAuto: true,
- BalanceAttemptAuto: false, Docked: true, Engaged: false,
- BalanceAttempt: true, CollectedBy: "",
+ Speaker: 0, Amp: 0, SpeakerAmplified: 1, Shuttled: 1, OutOfField: 0,
+ NotesDropped: 1, Penalties: 5, TrapNote: false, Spotlight: false, AvgCycle: 950,
+ Park: false, OnStage: false, Harmony: true, RobotDied: true, NoShow: true, CollectedBy: "",
}
if expected != response {
@@ -1229,7 +1090,7 @@
Timestamp: 2500,
},
},
- PreScouting: true,
+ CompType: "Prescouting",
}).Pack(builder))
_, err := debug.Submit2024Actions("http://localhost:8080", builder.FinishedBytes())
@@ -1239,7 +1100,7 @@
expectedActions := []db.Action{
{
- PreScouting: true,
+ CompType: "Prescouting",
TeamNumber: "3421",
MatchNumber: 2,
SetNumber: 1,
@@ -1249,7 +1110,7 @@
Timestamp: 1800,
},
{
- PreScouting: true,
+ CompType: "Prescouting",
TeamNumber: "3421",
MatchNumber: 2,
SetNumber: 1,
@@ -1262,12 +1123,12 @@
expectedStats := []db.Stats2024{
db.Stats2024{
- PreScouting: true, TeamNumber: "3421",
+ CompType: "Prescouting", TeamNumber: "3421",
MatchNumber: 2, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 0,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 1, Amp: 0, SpeakerAmplified: 0, AmpAmplified: 0,
+ Speaker: 1, Amp: 0, SpeakerAmplified: 0, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 0, TrapNote: false, Spotlight: false, AvgCycle: 0,
- Park: false, OnStage: false, Harmony: false, RobotDied: false, CollectedBy: "debug_cli",
+ Park: false, OnStage: false, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "debug_cli",
},
}
@@ -1279,254 +1140,30 @@
}
}
-func TestAddingActions(t *testing.T) {
- database := MockDatabase{}
- scoutingServer := server.NewScoutingServer()
- HandleRequests(&database, scoutingServer)
- scoutingServer.Start(8080)
- defer scoutingServer.Stop()
-
- builder := flatbuffers.NewBuilder(1024)
- builder.Finish((&submit_actions.SubmitActionsT{
- TeamNumber: "1234",
- MatchNumber: 4,
- SetNumber: 1,
- CompLevel: "qual",
- ActionsList: []*submit_actions.ActionT{
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- Auto: true,
- },
- },
- Timestamp: 2400,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePlaceObjectAction,
- Value: &submit_actions.PlaceObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- ScoreLevel: submit_actions.ScoreLevelkLow,
- Auto: false,
- },
- },
- Timestamp: 1009,
- },
- },
- PreScouting: true,
- }).Pack(builder))
-
- _, err := debug.SubmitActions("http://localhost:8080", builder.FinishedBytes())
- if err != nil {
- t.Fatal("Failed to submit actions: ", err)
- }
-
- // Make sure that the data made it into the database.
- // TODO: Add this back when we figure out how to add the serialized action into the database.
-
- /* expectedActionsT := []*submit_actions.ActionT{
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePickupObjectAction,
- Value: &submit_actions.PickupObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- Auto: true,
- },
- },
- Timestamp: 2400,
- },
- {
- ActionTaken: &submit_actions.ActionTypeT{
- Type: submit_actions.ActionTypePlaceObjectAction,
- Value: &submit_actions.PlaceObjectActionT{
- ObjectType: submit_actions.ObjectTypekCube,
- ScoreLevel: submit_actions.ScoreLevelkLow,
- Auto: false,
- },
- },
- Timestamp: 1009,
- },
- } */
-
- expectedActions := []db.Action{
- {
- PreScouting: true,
- TeamNumber: "1234",
- MatchNumber: 4,
- SetNumber: 1,
- CompLevel: "qual",
- CollectedBy: "debug_cli",
- CompletedAction: []byte{},
- Timestamp: 2400,
- },
- {
- PreScouting: true,
- TeamNumber: "1234",
- MatchNumber: 4,
- SetNumber: 1,
- CompLevel: "qual",
- CollectedBy: "debug_cli",
- CompletedAction: []byte{},
- Timestamp: 1009,
- },
- }
-
- expectedStats := []db.Stats2023{
- db.Stats2023{
- PreScouting: true,
- TeamNumber: "1234", MatchNumber: 4, SetNumber: 1,
- CompLevel: "qual", StartingQuadrant: 0, LowCubesAuto: 0,
- MiddleCubesAuto: 0, HighCubesAuto: 0, CubesDroppedAuto: 0,
- LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
- ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 0,
- HighCubes: 0, CubesDropped: 0, LowCones: 0,
- MiddleCones: 0, HighCones: 0, ConesDropped: 0, SuperchargedPieces: 0,
- AvgCycle: 0, Mobility: false, DockedAuto: false, EngagedAuto: false,
- BalanceAttemptAuto: false, Docked: false, Engaged: false,
- BalanceAttempt: false, CollectedBy: "debug_cli",
- },
- }
-
- if !reflect.DeepEqual(expectedActions, database.actions) {
- t.Fatal("Expected ", expectedActions, ", but got:", database.actions)
- }
- if !reflect.DeepEqual(expectedStats, database.stats2023) {
- t.Fatal("Expected ", expectedStats, ", but got:", database.stats2023)
- }
-}
-
-// Validates that we can delete stats.
-func TestDeleteFromStats(t *testing.T) {
- database := MockDatabase{
- stats2023: []db.Stats2023{
- {
- TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
- CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
- MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
- LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
- ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
- HighCubes: 2, CubesDropped: 1, LowCones: 1,
- MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
- AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
- BalanceAttemptAuto: false, Docked: false, Engaged: false,
- BalanceAttempt: true, CollectedBy: "isaac",
- },
- {
- TeamNumber: "2343", MatchNumber: 1, SetNumber: 2,
- CompLevel: "quals", StartingQuadrant: 1, LowCubesAuto: 0,
- MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 2,
- LowConesAuto: 0, MiddleConesAuto: 0, HighConesAuto: 0,
- ConesDroppedAuto: 1, LowCubes: 0, MiddleCubes: 0,
- HighCubes: 1, CubesDropped: 0, LowCones: 0,
- MiddleCones: 2, HighCones: 1, ConesDropped: 1, SuperchargedPieces: 0,
- AvgCycle: 53, Mobility: false, DockedAuto: false, EngagedAuto: false,
- BalanceAttemptAuto: true, Docked: false, Engaged: false,
- BalanceAttempt: true, CollectedBy: "unknown",
- },
- },
- actions: []db.Action{
- {
- PreScouting: true,
- TeamNumber: "3634",
- MatchNumber: 1,
- SetNumber: 2,
- CompLevel: "quals",
- CollectedBy: "debug_cli",
- CompletedAction: []byte{},
- Timestamp: 2400,
- },
- {
- PreScouting: true,
- TeamNumber: "2343",
- MatchNumber: 1,
- SetNumber: 2,
- CompLevel: "quals",
- CollectedBy: "debug_cli",
- CompletedAction: []byte{},
- Timestamp: 1009,
- },
- },
- }
- scoutingServer := server.NewScoutingServer()
- HandleRequests(&database, scoutingServer)
- scoutingServer.Start(8080)
- defer scoutingServer.Stop()
-
- builder := flatbuffers.NewBuilder(1024)
- builder.Finish((&delete_2023_data_scouting.Delete2023DataScoutingT{
- CompLevel: "quals",
- MatchNumber: 1,
- SetNumber: 2,
- TeamNumber: "2343",
- }).Pack(builder))
-
- _, err := debug.Delete2023DataScouting("http://localhost:8080", builder.FinishedBytes())
- if err != nil {
- t.Fatal("Failed to delete from data scouting ", err)
- }
-
- expectedActions := []db.Action{
- {
- PreScouting: true,
- TeamNumber: "3634",
- MatchNumber: 1,
- SetNumber: 2,
- CompLevel: "quals",
- CollectedBy: "debug_cli",
- CompletedAction: []byte{},
- Timestamp: 2400,
- },
- }
-
- expectedStats := []db.Stats2023{
- {
- TeamNumber: "3634", MatchNumber: 1, SetNumber: 2,
- CompLevel: "quals", StartingQuadrant: 3, LowCubesAuto: 10,
- MiddleCubesAuto: 1, HighCubesAuto: 1, CubesDroppedAuto: 0,
- LowConesAuto: 1, MiddleConesAuto: 2, HighConesAuto: 1,
- ConesDroppedAuto: 0, LowCubes: 1, MiddleCubes: 1,
- HighCubes: 2, CubesDropped: 1, LowCones: 1,
- MiddleCones: 2, HighCones: 0, ConesDropped: 1, SuperchargedPieces: 0,
- AvgCycle: 34, Mobility: false, DockedAuto: true, EngagedAuto: false,
- BalanceAttemptAuto: false, Docked: false, Engaged: false,
- BalanceAttempt: true, CollectedBy: "isaac",
- },
- }
-
- if !reflect.DeepEqual(expectedActions, database.actions) {
- t.Fatal("Expected ", expectedActions, ", but got:", database.actions)
- }
- if !reflect.DeepEqual(expectedStats, database.stats2023) {
- t.Fatal("Expected ", expectedStats, ", but got:", database.stats2023)
- }
-}
-
// Validates that we can delete 2024 stats.
func TestDeleteFromStats2024(t *testing.T) {
database := MockDatabase{
stats2024: []db.Stats2024{
{
- PreScouting: false, TeamNumber: "746",
+ CompType: "Practice", TeamNumber: "746",
MatchNumber: 3, SetNumber: 1, CompLevel: "quals", StartingQuadrant: 2,
SpeakerAuto: 0, AmpAuto: 1, NotesDroppedAuto: 1, MobilityAuto: true,
- Speaker: 0, Amp: 1, SpeakerAmplified: 1, AmpAmplified: 1,
+ Speaker: 0, Amp: 1, SpeakerAmplified: 1, Shuttled: 0, OutOfField: 2,
NotesDropped: 0, Penalties: 1, TrapNote: true, Spotlight: false, AvgCycle: 233,
- Park: false, OnStage: false, Harmony: true, RobotDied: false, CollectedBy: "alek",
+ Park: false, OnStage: false, Harmony: true, RobotDied: false, NoShow: false, CollectedBy: "alek",
},
{
- PreScouting: false, TeamNumber: "244",
+ CompType: "Regular", TeamNumber: "244",
MatchNumber: 5, SetNumber: 3, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 0, SpeakerAmplified: 3, AmpAmplified: 1,
+ Speaker: 0, Amp: 0, SpeakerAmplified: 3, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 1, TrapNote: false, Spotlight: false, AvgCycle: 120,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "kacey",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "kacey",
},
},
actions: []db.Action{
{
- PreScouting: true,
+ CompType: "Practice",
TeamNumber: "746",
MatchNumber: 3,
SetNumber: 1,
@@ -1536,7 +1173,7 @@
Timestamp: 2400,
},
{
- PreScouting: true,
+ CompType: "Prescouting",
TeamNumber: "244",
MatchNumber: 5,
SetNumber: 3,
@@ -1567,7 +1204,7 @@
expectedActions := []db.Action{
{
- PreScouting: true,
+ CompType: "Prescouting",
TeamNumber: "244",
MatchNumber: 5,
SetNumber: 3,
@@ -1580,12 +1217,12 @@
expectedStats := []db.Stats2024{
{
- PreScouting: false, TeamNumber: "244",
+ CompType: "Regular", TeamNumber: "244",
MatchNumber: 5, SetNumber: 3, CompLevel: "quals", StartingQuadrant: 1,
SpeakerAuto: 0, AmpAuto: 0, NotesDroppedAuto: 0, MobilityAuto: false,
- Speaker: 0, Amp: 0, SpeakerAmplified: 3, AmpAmplified: 1,
+ Speaker: 0, Amp: 0, SpeakerAmplified: 3, Shuttled: 0, OutOfField: 0,
NotesDropped: 0, Penalties: 1, TrapNote: false, Spotlight: false, AvgCycle: 120,
- Park: false, OnStage: true, Harmony: false, RobotDied: false, CollectedBy: "kacey",
+ Park: false, OnStage: true, Harmony: false, RobotDied: false, NoShow: false, CollectedBy: "kacey",
},
}
@@ -1647,10 +1284,10 @@
return results, nil
}
-func (database *MockDatabase) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, preScouting bool) ([]db.Stats2024, error) {
+func (database *MockDatabase) ReturnStats2024ForTeam(teamNumber string, matchNumber int32, setNumber int32, compLevel string, compType string) ([]db.Stats2024, error) {
var results []db.Stats2024
for _, stats := range database.stats2024 {
- if stats.TeamNumber == teamNumber && stats.MatchNumber == matchNumber && stats.SetNumber == setNumber && stats.CompLevel == compLevel && stats.PreScouting == preScouting {
+ if stats.TeamNumber == teamNumber && stats.MatchNumber == matchNumber && stats.SetNumber == setNumber && stats.CompLevel == compLevel && stats.CompType == compType {
results = append(results, stats)
}
}
diff --git a/scouting/www/entry/BUILD b/scouting/www/entry/BUILD
index 24da904..85af3ca 100644
--- a/scouting/www/entry/BUILD
+++ b/scouting/www/entry/BUILD
@@ -24,6 +24,7 @@
# nice not to have a duplicate list here when they're already known in
# the .fbs file.
"ACTIONS": [
+ "NoShowAction",
"EndMatchAction",
"MobilityAction",
"PenaltyAction",
diff --git a/scouting/www/entry/entry.component.css b/scouting/www/entry/entry.component.css
index e646a25..c58a94f 100644
--- a/scouting/www/entry/entry.component.css
+++ b/scouting/www/entry/entry.component.css
@@ -68,3 +68,18 @@
.qrcode {
padding: 0px;
}
+
+.half-button {
+ width: 46%;
+ height: 10vh;
+ margin: 0px 10px 10px 0px;
+}
+
+.half-button-container {
+ display: flex-wrap;
+ padding: 0;
+ justify-content: center;
+ text-align: center;
+ align-content: center;
+ margin: 0;
+}
diff --git a/scouting/www/entry/entry.component.ts b/scouting/www/entry/entry.component.ts
index 41f492c..230bfec 100644
--- a/scouting/www/entry/entry.component.ts
+++ b/scouting/www/entry/entry.component.ts
@@ -13,6 +13,8 @@
import {
StartMatchAction,
StartMatchActionT,
+ NoShowActionT,
+ NoShowAction,
ScoreType,
StageType,
Submit2024Actions,
@@ -51,6 +53,8 @@
| 'QR Code'
| 'Success';
+type CompType = 'PreScouting' | 'Practice' | 'Regular';
+
// TODO(phil): Deduplicate with match_list.component.ts.
const COMP_LEVELS = ['qm', 'ef', 'qf', 'sf', 'f'] as const;
export type CompLevel = typeof COMP_LEVELS[number];
@@ -69,7 +73,7 @@
const QR_CODE_PIECE_SIZES = [150, 300, 450, 600, 750, 900];
// The default index into QR_CODE_PIECE_SIZES.
-const DEFAULT_QR_CODE_PIECE_SIZE_INDEX = QR_CODE_PIECE_SIZES.indexOf(750);
+const DEFAULT_QR_CODE_PIECE_SIZE_INDEX = QR_CODE_PIECE_SIZES.indexOf(450);
// The actions that are purely used for tracking state. They don't actually
// have any permanent meaning and will not be saved in the database.
@@ -93,6 +97,7 @@
readonly StageType = StageType;
readonly ActionT = ActionT;
readonly ActionType = ActionType;
+ readonly NoShowActionT = NoShowActionT;
readonly StartMatchActionT = StartMatchActionT;
readonly MobilityActionT = MobilityActionT;
readonly PickupNoteActionT = PickupNoteActionT;
@@ -106,6 +111,7 @@
@Input() teamNumber: string = '1';
@Input() setNumber: number = 1;
@Input() compLevel: CompLevel = 'qm';
+ @Input() compType: CompType = 'Regular';
@Input() skipTeamSelection = false;
@ViewChild('header') header: ElementRef;
@@ -126,7 +132,6 @@
nextTeamNumber = '';
- preScouting: boolean = false;
matchStartTimestamp: number = 0;
penalties: number = 0;
@@ -181,9 +186,10 @@
// This gets called when the user changes something on the Init screen.
// It makes sure that the user can't click "Next" until the information is
- // valid, or this is for pre-scouting.
+ // valid, or this is for pre-scouting or practice matches.
updateTeamSelectionValidity(): void {
- this.teamSelectionIsValid = this.preScouting || this.matchIsInMatchList();
+ this.teamSelectionIsValid =
+ this.compType != 'Regular' || this.matchIsInMatchList();
}
matchIsInMatchList(): boolean {
@@ -256,6 +262,11 @@
case ActionType.EndAutoPhaseAction:
this.autoPhase = true;
this.section = 'Pickup';
+ break;
+ case ActionType.NoShowAction:
+ this.autoPhase = true;
+ this.section = 'Init';
+ break;
case ActionType.PickupNoteAction:
this.section = 'Pickup';
break;
@@ -323,6 +334,7 @@
}
const teamNumberFb = builder.createString(this.teamNumber);
const compLevelFb = builder.createString(this.compLevel);
+ const compTypeFb = builder.createString(this.compType);
const actionsVector = Submit2024Actions.createActionsListVector(
builder,
@@ -334,7 +346,7 @@
Submit2024Actions.addSetNumber(builder, this.setNumber);
Submit2024Actions.addCompLevel(builder, compLevelFb);
Submit2024Actions.addActionsList(builder, actionsVector);
- Submit2024Actions.addPreScouting(builder, this.preScouting);
+ Submit2024Actions.addCompType(builder, compTypeFb);
builder.finish(Submit2024Actions.endSubmit2024Actions(builder));
return builder.asUint8Array();
@@ -442,7 +454,7 @@
this.autoPhase = true;
this.actionList = [];
this.mobilityCompleted = false;
- this.preScouting = false;
+ this.compType = 'Regular';
this.matchStartTimestamp = 0;
this.selectedValue = 0;
} else {
diff --git a/scouting/www/entry/entry.ng.html b/scouting/www/entry/entry.ng.html
index d95bcec..1b3a966 100644
--- a/scouting/www/entry/entry.ng.html
+++ b/scouting/www/entry/entry.ng.html
@@ -58,13 +58,28 @@
<label>
<input
id="pre_scouting"
- type="checkbox"
- [(ngModel)]="preScouting"
+ name="comp_type"
+ type="radio"
+ [(ngModel)]="compType"
+ value="Prescouting"
(ngModelChange)="updateTeamSelectionValidity()"
/>
Pre-scouting
</label>
</div>
+ <div class="row">
+ <label>
+ <input
+ id="practice_match"
+ name="comp_type"
+ type="radio"
+ [(ngModel)]="compType"
+ value="Practice"
+ (ngModelChange)="updateTeamSelectionValidity()"
+ />
+ Practice Match
+ </label>
+ </div>
<div class="buttons">
<!-- hack to right align the next button -->
<div></div>
@@ -100,6 +115,12 @@
<!-- Creates a responsive stack of full-width, "block buttons". -->
<div class="d-grid gap-5">
<button
+ class="btn btn-warning"
+ (click)="changeSectionTo('Review and Submit'); actionHelper.addNoShowAction({});"
+ >
+ No Show
+ </button>
+ <button
class="btn btn-primary"
[disabled]="!selectedValue"
(click)="changeSectionTo('Pickup'); actionHelper.addStartMatchAction({position: selectedValue});"
@@ -161,14 +182,14 @@
</div>
<button
*ngIf="autoPhase"
- class="btn btn-dark"
+ class="btn btn-primary"
(click)="autoPhase = false; actionHelper.addEndAutoPhaseAction({});"
>
Start Teleop
</button>
<button
*ngIf="!autoPhase"
- class="btn btn-info"
+ class="btn btn-primary"
(click)="changeSectionTo('Endgame'); actionHelper.addEndTeleopPhaseAction({});"
>
Endgame
@@ -194,49 +215,48 @@
>
DEAD
</button>
- <button
- class="btn btn-info"
- (click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kDROPPED});"
- >
- Dropped
- </button>
- <div *ngIf="!autoPhase" class="d-grid gap-1" style="padding: 0">
- <div
- style="
- display: flex-wrap;
- padding: 0;
- justify-content: center;
- text-align: center;
- align-content: center;
- margin: 0;
- "
+ <div class="half-button-container">
+ <button
+ class="btn btn-info half-button"
+ (click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kDROPPED});"
>
+ Dropped
+ </button>
+ <button
+ class="btn btn-info half-button"
+ (click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kOUT_OF_FIELD});"
+ >
+ Out Of Field
+ </button>
+ </div>
+ <div
+ *ngIf="!autoPhase"
+ class="d-grid gap-1"
+ style="padding: 0; margin: 0"
+ >
+ <div class="half-button-container">
<button
- class="btn btn-success"
+ class="btn btn-success half-button"
(click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kAMP});"
- style="width: 48%; height: 12vh; margin: 0px 10px 10px 0px"
>
AMP
</button>
<button
- class="btn btn-warning"
- (click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kAMP_AMPLIFIED});"
- style="width: 48%; height: 12vh; margin: 0px 0px 10px 0px"
+ class="btn btn-warning half-button"
+ (click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kSHUTTLED});"
>
- AMP AMPLIFIED
+ SHUTTLED
</button>
<button
- class="btn btn-success"
+ class="btn btn-success half-button"
(click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kSPEAKER});"
- style="width: 48%; height: 12vh; margin: 0px 10px 0px 0px"
>
SPEAKER
</button>
<button
- class="btn btn-warning"
+ class="btn btn-warning half-button"
(click)="changeSectionTo('Pickup'); actionHelper.addPlaceNoteAction({auto: autoPhase, scoreType: ScoreType.kSPEAKER_AMPLIFIED});"
- style="width: 48%; height: 12vh; margin: 0px 0px 0px 0px"
>
SPEAKER AMPLIFIED
</button>
@@ -283,7 +303,7 @@
</button>
</div>
<button
- class="btn btn-dark"
+ class="btn btn-primary"
*ngIf="autoPhase"
(click)="autoPhase = false; actionHelper.addEndAutoPhaseAction({});"
>
@@ -291,7 +311,7 @@
</button>
<button
*ngIf="!autoPhase"
- class="btn btn-info"
+ class="btn btn-primary"
(click)="changeSectionTo('Endgame'); actionHelper.addEndTeleopPhaseAction({});"
>
Endgame
@@ -384,7 +404,7 @@
</div>
<button
*ngIf="!autoPhase"
- class="btn btn-info"
+ class="btn btn-primary"
(click)="changeSectionTo('Review and Submit'); addPenalties(); actionHelper.addEndMatchAction({stageType: endGameAction, trapNote: noteIsTrapped, spotlight: endGameSpotlight});"
>
End Match
@@ -420,7 +440,7 @@
Revive
</button>
<button
- class="btn btn-info"
+ class="btn btn-primary"
(click)="changeSectionTo('Review and Submit'); addPenalties(); actionHelper.addEndMatchAction({stageType: endGameAction, trapNote: noteIsTrapped, spotlight: endGameSpotlight});"
>
End Match
@@ -430,6 +450,7 @@
<div *ngSwitchCase="'Review and Submit'" id="Review" class="container-fluid">
<div class="row">
<ul id="review_data">
+ <div *ngIf="compType!='Regular'">This is a {{this.compType}} match</div>
<li *ngFor="let action of actionList" style="display: flex">
<div [ngSwitch]="action.actionTakenType" style="padding: 0px">
<span *ngSwitchCase="ActionType.StartMatchAction">
@@ -461,6 +482,7 @@
Mobility: {{(action.actionTaken | cast:
MobilityActionT).mobility}}
</span>
+ <span *ngSwitchCase="ActionType.NoShowAction">NoShow: true</span>
<span *ngSwitchDefault>{{action.actionTakenType}}</span>
<span *ngSwitchCase="ActionType.PenaltyAction">
Penalties: {{(action.actionTaken | cast: