mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Add pre- and post-match LED modes to indicate field status.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
onclick="commitFoul();">Add Foul</button>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<a class="btn btn-sm btn-warning btn-referee btn-referee-wide"
|
||||
onclick="signalVolunteers();">Signal Volunteers</a>
|
||||
<a class="btn btn-sm btn-success btn-referee btn-referee-wide"
|
||||
onclick="signalReset();">Signal Reset</a>
|
||||
<a class="btn btn-sm btn-info btn-referee btn-referee-wide"
|
||||
|
||||
@@ -213,6 +213,13 @@ func (web *Web) refereeDisplayWebsocketHandler(w http.ResponseWriter, r *http.Re
|
||||
}
|
||||
cards[strconv.Itoa(args.TeamId)] = args.Card
|
||||
continue
|
||||
case "signalVolunteers":
|
||||
if web.arena.MatchState != field.PostMatch {
|
||||
// Don't allow clearing the field until the match is over.
|
||||
continue
|
||||
}
|
||||
web.arena.FieldVolunteers = true
|
||||
continue // Don't reload.
|
||||
case "signalReset":
|
||||
if web.arena.MatchState != field.PostMatch {
|
||||
// Don't allow clearing the field until the match is over.
|
||||
|
||||
Reference in New Issue
Block a user