diff --git a/field/arena.go b/field/arena.go index 791fded..50466f4 100644 --- a/field/arena.go +++ b/field/arena.go @@ -53,6 +53,7 @@ type Arena struct { RedRealtimeScore *RealtimeScore BlueRealtimeScore *RealtimeScore lastDsPacketTime time.Time + FieldVolunteers bool FieldReset bool AudienceDisplayScreen string SavedMatch *model.Match @@ -83,6 +84,8 @@ type Arena struct { RedSwitchLeds led.Controller BlueSwitchLeds led.Controller warmupLedMode led.Mode + lastRedAllianceReady bool + lastBlueAllianceReady bool } type ArenaStatus struct { @@ -227,6 +230,7 @@ func (arena *Arena) LoadMatch(match *model.Match) error { // Reset the realtime scores. arena.RedRealtimeScore = NewRealtimeScore() arena.BlueRealtimeScore = NewRealtimeScore() + arena.FieldVolunteers = false arena.FieldReset = false arena.Scale = &game.Seesaw{Kind: game.NeitherAlliance} arena.RedSwitch = &game.Seesaw{Kind: game.RedAlliance} @@ -249,6 +253,13 @@ func (arena *Arena) LoadMatch(match *model.Match) error { arena.AllianceStationDisplayScreen = "match" arena.AllianceStationDisplayNotifier.Notify(nil) + // Set the initial state of the lights. + arena.ScaleLeds.SetMode(led.OffMode, led.OffMode) + arena.RedSwitchLeds.SetMode(led.RedMode, led.RedMode) + arena.BlueSwitchLeds.SetMode(led.BlueMode, led.BlueMode) + arena.lastRedAllianceReady = false + arena.lastBlueAllianceReady = false + return nil } @@ -607,15 +618,10 @@ func (arena *Arena) checkCanStartMatch() error { if arena.MatchState != PreMatch { return fmt.Errorf("Cannot start match while there is a match still in progress or with results pending.") } - for _, allianceStation := range arena.AllianceStations { - if allianceStation.Estop { - return fmt.Errorf("Cannot start match while an emergency stop is active.") - } - if !allianceStation.Bypass { - if allianceStation.DsConn == nil || !allianceStation.DsConn.RobotLinked { - return fmt.Errorf("Cannot start match until all robots are connected or bypassed.") - } - } + + err := arena.checkAllianceStationsReady("R1", "R2", "R3", "B1", "B2", "B3") + if err != nil { + return err } if arena.EventSettings.PlcAddress != "" { @@ -630,6 +636,22 @@ func (arena *Arena) checkCanStartMatch() error { return nil } +func (arena *Arena) checkAllianceStationsReady(stations ...string) error { + for _, station := range stations { + allianceStation := arena.AllianceStations[station] + if allianceStation.Estop { + return fmt.Errorf("Cannot start match while an emergency stop is active.") + } + if !allianceStation.Bypass { + if allianceStation.DsConn == nil || !allianceStation.DsConn.RobotLinked { + return fmt.Errorf("Cannot start match until all robots are connected or bypassed.") + } + } + } + + return nil +} + func (arena *Arena) sendDsPacket(auto bool, enabled bool) { for _, allianceStation := range arena.AllianceStations { dsConn := allianceStation.DsConn @@ -752,6 +774,22 @@ func (arena *Arena) handlePlcOutput() { func (arena *Arena) handleLeds() { switch arena.MatchState { + case PreMatch: + // Turn off each alliance switch if all teams become ready. + if arena.checkAllianceStationsReady("R1", "R2", "R3") == nil && !arena.lastRedAllianceReady { + arena.RedSwitchLeds.SetMode(led.OffMode, led.OffMode) + arena.lastRedAllianceReady = true + } else if arena.checkAllianceStationsReady("R1", "R2", "R3") != nil && arena.lastRedAllianceReady { + arena.RedSwitchLeds.SetMode(led.RedMode, led.RedMode) + arena.lastRedAllianceReady = false + } + if arena.checkAllianceStationsReady("B1", "B2", "B3") == nil && !arena.lastBlueAllianceReady { + arena.BlueSwitchLeds.SetMode(led.OffMode, led.OffMode) + arena.lastBlueAllianceReady = true + } else if arena.checkAllianceStationsReady("B1", "B2", "B3") != nil && arena.lastBlueAllianceReady { + arena.BlueSwitchLeds.SetMode(led.BlueMode, led.BlueMode) + arena.lastBlueAllianceReady = false + } case WarmupPeriod: arena.ScaleLeds.SetMode(arena.warmupLedMode, arena.warmupLedMode) arena.RedSwitchLeds.SetMode(arena.warmupLedMode, arena.warmupLedMode) @@ -769,9 +807,15 @@ func (arena *Arena) handleLeds() { arena.RedSwitchLeds.SetMode(led.OffMode, led.OffMode) arena.BlueSwitchLeds.SetMode(led.OffMode, led.OffMode) case PostMatch: - arena.ScaleLeds.SetMode(led.FadeSingleMode, led.FadeSingleMode) - arena.RedSwitchLeds.SetMode(led.FadeSingleMode, led.FadeSingleMode) - arena.BlueSwitchLeds.SetMode(led.FadeSingleMode, led.FadeSingleMode) + mode := led.FadeSingleMode + if arena.FieldReset { + mode = led.GreenMode + } else if arena.FieldVolunteers { + mode = led.PurpleMode + } + arena.ScaleLeds.SetMode(mode, mode) + arena.RedSwitchLeds.SetMode(mode, mode) + arena.BlueSwitchLeds.SetMode(mode, mode) } arena.ScaleLeds.Update() diff --git a/led/mode.go b/led/mode.go index b07560d..ffea02c 100644 --- a/led/mode.go +++ b/led/mode.go @@ -13,6 +13,7 @@ const ( GreenMode BlueMode WhiteMode + PurpleMode ChaseMode WarmupMode Warmup2Mode @@ -35,6 +36,7 @@ var ModeNames = map[Mode]string{ GreenMode: "Green", BlueMode: "Blue", WhiteMode: "White", + PurpleMode: "Purple", ChaseMode: "Chase", WarmupMode: "Warmup", Warmup2Mode: "Warmup Purple", diff --git a/led/strip.go b/led/strip.go index aca5696..27aad28 100644 --- a/led/strip.go +++ b/led/strip.go @@ -30,6 +30,8 @@ func (strip *strip) updatePixels() { strip.updateSingleColorMode(blue) case WhiteMode: strip.updateSingleColorMode(white) + case PurpleMode: + strip.updateSingleColorMode(purple) case ChaseMode: strip.updateChaseMode() case WarmupMode: diff --git a/static/js/referee_display.js b/static/js/referee_display.js index 0af8f33..ab0b7c1 100644 --- a/static/js/referee_display.js +++ b/static/js/referee_display.js @@ -79,6 +79,11 @@ var cycleCard = function(cardButton) { $(cardButton).attr("data-card", newCard); }; +// Signals to the volunteers that they may enter the field. +var signalVolunteers = function() { + websocket.send("signalVolunteers"); +}; + // Signals to the teams that they may enter the field. var signalReset = function() { websocket.send("signalReset"); diff --git a/templates/referee_display.html b/templates/referee_display.html index e5f5317..98be4c6 100644 --- a/templates/referee_display.html +++ b/templates/referee_display.html @@ -72,6 +72,8 @@ onclick="commitFoul();">Add Foul
+ Signal Volunteers Signal Reset