mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 13:46:44 -04:00
Hook LED modes up to field state.
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/Team254/cheesy-arena/model"
|
||||
"github.com/Team254/cheesy-arena/partner"
|
||||
"log"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -73,14 +74,15 @@ type Arena struct {
|
||||
AllianceSelectionNotifier *Notifier
|
||||
LowerThirdNotifier *Notifier
|
||||
ReloadDisplaysNotifier *Notifier
|
||||
ScaleLeds led.Controller
|
||||
RedSwitchLeds led.Controller
|
||||
BlueSwitchLeds led.Controller
|
||||
Scale *game.Seesaw
|
||||
RedSwitch *game.Seesaw
|
||||
BlueSwitch *game.Seesaw
|
||||
RedVault *game.Vault
|
||||
BlueVault *game.Vault
|
||||
ScaleLeds led.Controller
|
||||
RedSwitchLeds led.Controller
|
||||
BlueSwitchLeds led.Controller
|
||||
warmupLedMode led.Mode
|
||||
}
|
||||
|
||||
type ArenaStatus struct {
|
||||
@@ -234,9 +236,9 @@ func (arena *Arena) LoadMatch(match *model.Match) error {
|
||||
game.ResetPowerUps()
|
||||
|
||||
// Set a consistent initial value for field element sidedness.
|
||||
arena.Scale.SetSidedness(true)
|
||||
arena.RedSwitch.SetSidedness(true)
|
||||
arena.BlueSwitch.SetSidedness(true)
|
||||
arena.Scale.NearIsRed = true
|
||||
arena.RedSwitch.NearIsRed = true
|
||||
arena.BlueSwitch.NearIsRed = true
|
||||
arena.ScaleLeds.SetSidedness(true)
|
||||
arena.RedSwitchLeds.SetSidedness(true)
|
||||
arena.BlueSwitchLeds.SetSidedness(true)
|
||||
@@ -321,9 +323,9 @@ func (arena *Arena) StartMatch() error {
|
||||
// Configure the field elements with the game-specific data.
|
||||
switchNearIsRed := arena.CurrentMatch.GameSpecificData[0] == 'L'
|
||||
scaleNearIsRed := arena.CurrentMatch.GameSpecificData[1] == 'L'
|
||||
arena.Scale.SetSidedness(scaleNearIsRed)
|
||||
arena.RedSwitch.SetSidedness(switchNearIsRed)
|
||||
arena.BlueSwitch.SetSidedness(switchNearIsRed)
|
||||
arena.Scale.NearIsRed = scaleNearIsRed
|
||||
arena.RedSwitch.NearIsRed = switchNearIsRed
|
||||
arena.BlueSwitch.NearIsRed = switchNearIsRed
|
||||
arena.ScaleLeds.SetSidedness(scaleNearIsRed)
|
||||
arena.RedSwitchLeds.SetSidedness(switchNearIsRed)
|
||||
arena.BlueSwitchLeds.SetSidedness(switchNearIsRed)
|
||||
@@ -411,12 +413,12 @@ func (arena *Arena) Update() {
|
||||
arena.AudienceDisplayScreen = "match"
|
||||
arena.AudienceDisplayNotifier.Notify(nil)
|
||||
arena.sendGameSpecificDataPacket()
|
||||
arena.ScaleLeds.SetMode(led.WarmupMode, led.WarmupMode)
|
||||
arena.RedSwitchLeds.SetMode(led.WarmupMode, led.WarmupMode)
|
||||
arena.BlueSwitchLeds.SetMode(led.WarmupMode, led.WarmupMode)
|
||||
if !arena.MuteMatchSounds {
|
||||
arena.PlaySoundNotifier.Notify("match-warmup")
|
||||
}
|
||||
// Pick an LED warmup mode at random to keep things interesting.
|
||||
allWarmupModes := []led.Mode{led.WarmupMode, led.Warmup2Mode, led.Warmup3Mode, led.Warmup4Mode}
|
||||
arena.warmupLedMode = allWarmupModes[rand.Intn(len(allWarmupModes))]
|
||||
case WarmupPeriod:
|
||||
auto = true
|
||||
enabled = false
|
||||
@@ -509,10 +511,7 @@ func (arena *Arena) Update() {
|
||||
// Handle field sensors/lights/motors.
|
||||
arena.handlePlcInput()
|
||||
arena.handlePlcOutput()
|
||||
|
||||
arena.ScaleLeds.Update()
|
||||
arena.RedSwitchLeds.Update()
|
||||
arena.BlueSwitchLeds.Update()
|
||||
arena.handleLeds()
|
||||
}
|
||||
|
||||
// Loops indefinitely to track and update the arena components.
|
||||
@@ -751,6 +750,73 @@ func (arena *Arena) handlePlcOutput() {
|
||||
// TODO(patrick): Update for 2018.
|
||||
}
|
||||
|
||||
func (arena *Arena) handleLeds() {
|
||||
switch arena.MatchState {
|
||||
case WarmupPeriod:
|
||||
arena.ScaleLeds.SetMode(arena.warmupLedMode, arena.warmupLedMode)
|
||||
arena.RedSwitchLeds.SetMode(arena.warmupLedMode, arena.warmupLedMode)
|
||||
arena.BlueSwitchLeds.SetMode(arena.warmupLedMode, arena.warmupLedMode)
|
||||
case AutoPeriod:
|
||||
fallthrough
|
||||
case TeleopPeriod:
|
||||
fallthrough
|
||||
case EndgamePeriod:
|
||||
handleSeesawTeleopLeds(arena.Scale, &arena.ScaleLeds)
|
||||
handleSeesawTeleopLeds(arena.RedSwitch, &arena.RedSwitchLeds)
|
||||
handleSeesawTeleopLeds(arena.BlueSwitch, &arena.BlueSwitchLeds)
|
||||
case PausePeriod:
|
||||
arena.ScaleLeds.SetMode(led.OffMode, led.OffMode)
|
||||
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)
|
||||
}
|
||||
|
||||
arena.ScaleLeds.Update()
|
||||
arena.RedSwitchLeds.Update()
|
||||
arena.BlueSwitchLeds.Update()
|
||||
}
|
||||
|
||||
func handleSeesawTeleopLeds(seesaw *game.Seesaw, leds *led.Controller) {
|
||||
// Assume the simplest mode to start and consider others in order of increasing complexity.
|
||||
redMode := led.NotOwnedMode
|
||||
blueMode := led.NotOwnedMode
|
||||
|
||||
// Upgrade the mode to ownership based on the physical state of the switch or scale.
|
||||
if seesaw.GetOwnedBy() == game.RedAlliance && seesaw.Kind != game.BlueAlliance {
|
||||
redMode = led.OwnedMode
|
||||
} else if seesaw.GetOwnedBy() == game.BlueAlliance && seesaw.Kind != game.RedAlliance {
|
||||
blueMode = led.OwnedMode
|
||||
}
|
||||
|
||||
// Upgrade the mode if there is an applicable power up.
|
||||
powerUp := game.GetActivePowerUp(time.Now())
|
||||
if powerUp != nil && (seesaw.Kind == game.NeitherAlliance && powerUp.Level >= 2 ||
|
||||
seesaw.Kind == powerUp.Alliance && (powerUp.Level == 1 || powerUp.Level == 3)) {
|
||||
if powerUp.Effect == game.Boost {
|
||||
if powerUp.Alliance == game.RedAlliance {
|
||||
redMode = led.BoostMode
|
||||
} else {
|
||||
blueMode = led.BoostMode
|
||||
}
|
||||
} else {
|
||||
if powerUp.Alliance == game.RedAlliance {
|
||||
redMode = led.ForceMode
|
||||
} else {
|
||||
blueMode = led.ForceMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if seesaw.NearIsRed {
|
||||
leds.SetMode(redMode, blueMode)
|
||||
} else {
|
||||
leds.SetMode(blueMode, redMode)
|
||||
}
|
||||
}
|
||||
|
||||
func (arena *Arena) handleEstop(station string, state bool) {
|
||||
allianceStation := arena.AllianceStations[station]
|
||||
if state {
|
||||
|
||||
@@ -12,11 +12,11 @@ import (
|
||||
const powerUpDurationSec = 10
|
||||
|
||||
// Power up type/effect enum.
|
||||
type effect int
|
||||
type PowerUpEffect int
|
||||
|
||||
const (
|
||||
force effect = iota
|
||||
boost
|
||||
Force PowerUpEffect = iota
|
||||
Boost
|
||||
)
|
||||
|
||||
// Power up state enum.
|
||||
@@ -31,8 +31,8 @@ const (
|
||||
|
||||
type PowerUp struct {
|
||||
Alliance
|
||||
effect
|
||||
level int
|
||||
Effect PowerUpEffect
|
||||
Level int
|
||||
startTime time.Time
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (powerUp *PowerUp) getEndTime() time.Time {
|
||||
}
|
||||
|
||||
// Returns the current active power up, or nil if there isn't one.
|
||||
func getActivePowerUp(currentTime time.Time) *PowerUp {
|
||||
func GetActivePowerUp(currentTime time.Time) *PowerUp {
|
||||
for _, powerUp := range powerUpUses {
|
||||
if powerUp.GetState(currentTime) == Active {
|
||||
return powerUp
|
||||
|
||||
@@ -31,13 +31,13 @@ func TestPowerUpActivate(t *testing.T) {
|
||||
assert.Equal(t, timeAfterStart(45), powerUp2.startTime)
|
||||
}
|
||||
|
||||
assert.Nil(t, getActivePowerUp(timeAfterStart(29.9)))
|
||||
assert.Equal(t, powerUp1, getActivePowerUp(timeAfterStart(30.1)))
|
||||
assert.Equal(t, powerUp1, getActivePowerUp(timeAfterStart(39.9)))
|
||||
assert.Nil(t, getActivePowerUp(timeAfterStart(42)))
|
||||
assert.Equal(t, powerUp2, getActivePowerUp(timeAfterStart(45.1)))
|
||||
assert.Equal(t, powerUp2, getActivePowerUp(timeAfterStart(54.9)))
|
||||
assert.Nil(t, getActivePowerUp(timeAfterStart(55.1)))
|
||||
assert.Nil(t, GetActivePowerUp(timeAfterStart(29.9)))
|
||||
assert.Equal(t, powerUp1, GetActivePowerUp(timeAfterStart(30.1)))
|
||||
assert.Equal(t, powerUp1, GetActivePowerUp(timeAfterStart(39.9)))
|
||||
assert.Nil(t, GetActivePowerUp(timeAfterStart(42)))
|
||||
assert.Equal(t, powerUp2, GetActivePowerUp(timeAfterStart(45.1)))
|
||||
assert.Equal(t, powerUp2, GetActivePowerUp(timeAfterStart(54.9)))
|
||||
assert.Nil(t, GetActivePowerUp(timeAfterStart(55.1)))
|
||||
}
|
||||
|
||||
func TestPowerUpQueue(t *testing.T) {
|
||||
@@ -56,8 +56,8 @@ func TestPowerUpQueue(t *testing.T) {
|
||||
powerUp3 := &PowerUp{Alliance: RedAlliance}
|
||||
assert.NotNil(t, maybeActivatePowerUp(powerUp3, timeAfterStart(81)))
|
||||
|
||||
assert.Equal(t, powerUp1, getActivePowerUp(timeAfterStart(69.9)))
|
||||
assert.Equal(t, powerUp2, getActivePowerUp(timeAfterStart(70.1)))
|
||||
assert.Equal(t, powerUp1, GetActivePowerUp(timeAfterStart(69.9)))
|
||||
assert.Equal(t, powerUp2, GetActivePowerUp(timeAfterStart(70.1)))
|
||||
}
|
||||
|
||||
func timeAfterStart(sec float32) time.Time {
|
||||
|
||||
@@ -19,7 +19,7 @@ const (
|
||||
|
||||
type Seesaw struct {
|
||||
Kind Alliance // Red or blue indicates that it is a switch; neither indicates the scale.
|
||||
nearIsRed bool
|
||||
NearIsRed bool
|
||||
ownerships []*Ownership
|
||||
}
|
||||
|
||||
@@ -30,27 +30,21 @@ type Ownership struct {
|
||||
endTime *time.Time
|
||||
}
|
||||
|
||||
// Sets which side of the scale or switch belongs to which alliance. A value of true indicates that the side nearest the
|
||||
// scoring table is red.
|
||||
func (seesaw *Seesaw) SetSidedness(nearIsRed bool) {
|
||||
seesaw.nearIsRed = nearIsRed
|
||||
}
|
||||
|
||||
// Updates the internal timing state of the scale or switch given the current state of the sensors.
|
||||
func (seesaw *Seesaw) UpdateState(state [2]bool, currentTime time.Time) {
|
||||
ownedBy := NeitherAlliance
|
||||
|
||||
// Check if there is an active force power up for this seesaw.
|
||||
currentPowerUp := getActivePowerUp(currentTime)
|
||||
if currentPowerUp != nil && currentPowerUp.effect == force &&
|
||||
(seesaw.Kind == NeitherAlliance && currentPowerUp.level >= 2 ||
|
||||
(seesaw.Kind == currentPowerUp.Alliance && (currentPowerUp.level == 1 || currentPowerUp.level == 3))) {
|
||||
currentPowerUp := GetActivePowerUp(currentTime)
|
||||
if currentPowerUp != nil && currentPowerUp.Effect == Force &&
|
||||
(seesaw.Kind == NeitherAlliance && currentPowerUp.Level >= 2 ||
|
||||
(seesaw.Kind == currentPowerUp.Alliance && (currentPowerUp.Level == 1 || currentPowerUp.Level == 3))) {
|
||||
ownedBy = currentPowerUp.Alliance
|
||||
} else {
|
||||
// Determine current ownership from sensor state.
|
||||
if state[0] && !state[1] && seesaw.nearIsRed || state[1] && !state[0] && !seesaw.nearIsRed {
|
||||
if state[0] && !state[1] && seesaw.NearIsRed || state[1] && !state[0] && !seesaw.NearIsRed {
|
||||
ownedBy = RedAlliance
|
||||
} else if state[0] && !state[1] && !seesaw.nearIsRed || state[1] && !state[0] && seesaw.nearIsRed {
|
||||
} else if state[0] && !state[1] && !seesaw.NearIsRed || state[1] && !state[0] && seesaw.NearIsRed {
|
||||
ownedBy = BlueAlliance
|
||||
}
|
||||
}
|
||||
@@ -131,9 +125,9 @@ func (ownership *Ownership) getSeconds(startTime, endTime time.Time, ignoreBoost
|
||||
// Find the boost power up applicable to this seesaw and alliance, if it exists.
|
||||
var boostPowerUp *PowerUp
|
||||
for _, powerUp := range powerUpUses {
|
||||
if powerUp.effect == boost && ownership.ownedBy == powerUp.Alliance {
|
||||
if ownership.seesaw.Kind == NeitherAlliance && powerUp.level >= 2 ||
|
||||
ownership.seesaw.Kind != NeitherAlliance && (powerUp.level == 1 || powerUp.level == 3) {
|
||||
if powerUp.Effect == Boost && ownership.ownedBy == powerUp.Alliance {
|
||||
if ownership.seesaw.Kind == NeitherAlliance && powerUp.Level >= 2 ||
|
||||
ownership.seesaw.Kind != NeitherAlliance && (powerUp.Level == 1 || powerUp.Level == 3) {
|
||||
boostPowerUp = powerUp
|
||||
break
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestSecondCounting(t *testing.T) {
|
||||
ResetPowerUps()
|
||||
|
||||
redSwitch := &Seesaw{Kind: RedAlliance}
|
||||
redSwitch.SetSidedness(true)
|
||||
redSwitch.NearIsRed = true
|
||||
|
||||
// Test that there is no accumulation before the start of the match.
|
||||
redSwitch.UpdateState([2]bool{true, false}, timeAfterStart(-20))
|
||||
@@ -70,14 +70,14 @@ func TestForce(t *testing.T) {
|
||||
ResetPowerUps()
|
||||
|
||||
blueSwitch := &Seesaw{Kind: BlueAlliance}
|
||||
blueSwitch.SetSidedness(true)
|
||||
blueSwitch.NearIsRed = true
|
||||
scale := &Seesaw{Kind: NeitherAlliance}
|
||||
scale.SetSidedness(true)
|
||||
scale.NearIsRed = true
|
||||
|
||||
// Force switch only.
|
||||
blueSwitch.UpdateState([2]bool{true, false}, timeAfterStart(0))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(0))
|
||||
powerUp := &PowerUp{Alliance: BlueAlliance, effect: force, level: 1}
|
||||
powerUp := &PowerUp{Alliance: BlueAlliance, Effect: Force, Level: 1}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(2.5))
|
||||
blueSwitch.UpdateState([2]bool{true, false}, timeAfterStart(2.5))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(2.5))
|
||||
@@ -91,7 +91,7 @@ func TestForce(t *testing.T) {
|
||||
assert.Equal(t, 0.0, scale.GetBlueSeconds(timeAfterStart(0), timeAfterStart(15)))
|
||||
|
||||
// Force scale only.
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, effect: force, level: 2}
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, Effect: Force, Level: 2}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(20))
|
||||
blueSwitch.UpdateState([2]bool{true, false}, timeAfterStart(20))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(20))
|
||||
@@ -101,7 +101,7 @@ func TestForce(t *testing.T) {
|
||||
assert.Equal(t, 10.0, scale.GetBlueSeconds(timeAfterStart(20), timeAfterStart(40)))
|
||||
|
||||
// Force both switch and scale.
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, effect: force, level: 3}
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, Effect: Force, Level: 3}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(50))
|
||||
blueSwitch.UpdateState([2]bool{true, false}, timeAfterStart(50))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(50))
|
||||
@@ -115,14 +115,14 @@ func TestBoost(t *testing.T) {
|
||||
ResetPowerUps()
|
||||
|
||||
blueSwitch := &Seesaw{Kind: BlueAlliance}
|
||||
blueSwitch.SetSidedness(true)
|
||||
blueSwitch.NearIsRed = true
|
||||
scale := &Seesaw{Kind: NeitherAlliance}
|
||||
scale.SetSidedness(false)
|
||||
scale.NearIsRed = false
|
||||
|
||||
// Test within continuous ownership period.
|
||||
blueSwitch.UpdateState([2]bool{false, true}, timeAfterStart(20))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(20))
|
||||
powerUp := &PowerUp{Alliance: BlueAlliance, effect: boost, level: 2}
|
||||
powerUp := &PowerUp{Alliance: BlueAlliance, Effect: Boost, Level: 2}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(25))
|
||||
assert.Equal(t, 5.0, scale.GetBlueSeconds(timeAfterStart(0), timeAfterStart(25)))
|
||||
assert.Equal(t, 6.0, scale.GetBlueSeconds(timeAfterStart(0), timeAfterStart(25.5)))
|
||||
@@ -136,7 +136,7 @@ func TestBoost(t *testing.T) {
|
||||
ResetPowerUps()
|
||||
blueSwitch.UpdateState([2]bool{false, false}, timeAfterStart(44))
|
||||
scale.UpdateState([2]bool{false, false}, timeAfterStart(44))
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, effect: boost, level: 3}
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, Effect: Boost, Level: 3}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(45))
|
||||
assert.Equal(t, 0.0, blueSwitch.GetBlueSeconds(timeAfterStart(45), timeAfterStart(50)))
|
||||
assert.Equal(t, 0.0, scale.GetBlueSeconds(timeAfterStart(45), timeAfterStart(50)))
|
||||
@@ -151,7 +151,7 @@ func TestBoost(t *testing.T) {
|
||||
ResetPowerUps()
|
||||
scale.UpdateState([2]bool{false, true}, timeAfterStart(65))
|
||||
assert.Equal(t, 5.0, scale.GetRedSeconds(timeAfterStart(65), timeAfterStart(70)))
|
||||
powerUp = &PowerUp{Alliance: RedAlliance, effect: boost, level: 2}
|
||||
powerUp = &PowerUp{Alliance: RedAlliance, Effect: Boost, Level: 2}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(70))
|
||||
scale.UpdateState([2]bool{false, false}, timeAfterStart(72.5))
|
||||
assert.Equal(t, 10.0, scale.GetRedSeconds(timeAfterStart(65), timeAfterStart(72.5)))
|
||||
@@ -163,7 +163,7 @@ func TestBoost(t *testing.T) {
|
||||
// Test with just the switch.
|
||||
blueSwitch.UpdateState([2]bool{false, true}, timeAfterStart(100))
|
||||
scale.UpdateState([2]bool{true, false}, timeAfterStart(100))
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, effect: boost, level: 1}
|
||||
powerUp = &PowerUp{Alliance: BlueAlliance, Effect: Boost, Level: 1}
|
||||
maybeActivatePowerUp(powerUp, timeAfterStart(100))
|
||||
assert.Equal(t, 20.0, blueSwitch.GetBlueSeconds(timeAfterStart(100), timeAfterStart(110)))
|
||||
assert.Equal(t, 10.0, scale.GetBlueSeconds(timeAfterStart(100), timeAfterStart(110)))
|
||||
|
||||
@@ -35,16 +35,16 @@ func (vault *Vault) UpdateButtons(forceButton, levitateButton, boostButton bool,
|
||||
}
|
||||
|
||||
if forceButton && vault.ForceCubes > 0 && vault.ForcePowerUp == nil {
|
||||
vault.ForcePowerUp = maybeActivatePowerUp(&PowerUp{effect: force, Alliance: vault.Alliance,
|
||||
level: vault.ForceCubes}, currentTime)
|
||||
vault.ForcePowerUp = maybeActivatePowerUp(&PowerUp{Effect: Force, Alliance: vault.Alliance,
|
||||
Level: vault.ForceCubes}, currentTime)
|
||||
if vault.ForcePowerUp != nil {
|
||||
vault.newlyPlayedPowerUp = "force"
|
||||
}
|
||||
}
|
||||
|
||||
if boostButton && vault.BoostCubes > 0 && vault.BoostPowerUp == nil {
|
||||
vault.BoostPowerUp = maybeActivatePowerUp(&PowerUp{effect: boost, Alliance: vault.Alliance,
|
||||
level: vault.BoostCubes}, currentTime)
|
||||
vault.BoostPowerUp = maybeActivatePowerUp(&PowerUp{Effect: Boost, Alliance: vault.Alliance,
|
||||
Level: vault.BoostCubes}, currentTime)
|
||||
if vault.BoostPowerUp != nil {
|
||||
vault.newlyPlayedPowerUp = "boost"
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ func TestVaultForce(t *testing.T) {
|
||||
vault.UpdateButtons(true, false, false, time.Now())
|
||||
if assert.NotNil(t, vault.ForcePowerUp) {
|
||||
assert.Equal(t, BlueAlliance, vault.ForcePowerUp.Alliance)
|
||||
assert.Equal(t, force, vault.ForcePowerUp.effect)
|
||||
assert.Equal(t, 1, vault.ForcePowerUp.level)
|
||||
assert.Equal(t, Force, vault.ForcePowerUp.Effect)
|
||||
assert.Equal(t, 1, vault.ForcePowerUp.Level)
|
||||
}
|
||||
|
||||
// Activation with two cubes.
|
||||
@@ -98,8 +98,8 @@ func TestVaultForce(t *testing.T) {
|
||||
vault.UpdateButtons(true, false, false, time.Now())
|
||||
if assert.NotNil(t, vault.ForcePowerUp) {
|
||||
assert.Equal(t, RedAlliance, vault.ForcePowerUp.Alliance)
|
||||
assert.Equal(t, force, vault.ForcePowerUp.effect)
|
||||
assert.Equal(t, 2, vault.ForcePowerUp.level)
|
||||
assert.Equal(t, Force, vault.ForcePowerUp.Effect)
|
||||
assert.Equal(t, 2, vault.ForcePowerUp.Level)
|
||||
}
|
||||
|
||||
// Activation with three cubes.
|
||||
@@ -110,8 +110,8 @@ func TestVaultForce(t *testing.T) {
|
||||
assert.NotNil(t, vault.ForcePowerUp)
|
||||
if assert.NotNil(t, vault.ForcePowerUp) {
|
||||
assert.Equal(t, BlueAlliance, vault.ForcePowerUp.Alliance)
|
||||
assert.Equal(t, force, vault.ForcePowerUp.effect)
|
||||
assert.Equal(t, 3, vault.ForcePowerUp.level)
|
||||
assert.Equal(t, Force, vault.ForcePowerUp.Effect)
|
||||
assert.Equal(t, 3, vault.ForcePowerUp.Level)
|
||||
}
|
||||
|
||||
vault.UpdateCubes(3000, 0, 0)
|
||||
@@ -136,8 +136,8 @@ func TestVaultBoost(t *testing.T) {
|
||||
vault.UpdateButtons(false, false, true, time.Now())
|
||||
if assert.NotNil(t, vault.BoostPowerUp) {
|
||||
assert.Equal(t, BlueAlliance, vault.BoostPowerUp.Alliance)
|
||||
assert.Equal(t, boost, vault.BoostPowerUp.effect)
|
||||
assert.Equal(t, 1, vault.BoostPowerUp.level)
|
||||
assert.Equal(t, Boost, vault.BoostPowerUp.Effect)
|
||||
assert.Equal(t, 1, vault.BoostPowerUp.Level)
|
||||
}
|
||||
|
||||
// Activation with two cubes.
|
||||
@@ -147,8 +147,8 @@ func TestVaultBoost(t *testing.T) {
|
||||
vault.UpdateButtons(false, false, true, time.Now())
|
||||
if assert.NotNil(t, vault.BoostPowerUp) {
|
||||
assert.Equal(t, RedAlliance, vault.BoostPowerUp.Alliance)
|
||||
assert.Equal(t, boost, vault.BoostPowerUp.effect)
|
||||
assert.Equal(t, 2, vault.BoostPowerUp.level)
|
||||
assert.Equal(t, Boost, vault.BoostPowerUp.Effect)
|
||||
assert.Equal(t, 2, vault.BoostPowerUp.Level)
|
||||
}
|
||||
|
||||
// Activation with three cubes.
|
||||
@@ -159,8 +159,8 @@ func TestVaultBoost(t *testing.T) {
|
||||
assert.NotNil(t, vault.BoostPowerUp)
|
||||
if assert.NotNil(t, vault.BoostPowerUp) {
|
||||
assert.Equal(t, BlueAlliance, vault.BoostPowerUp.Alliance)
|
||||
assert.Equal(t, boost, vault.BoostPowerUp.effect)
|
||||
assert.Equal(t, 3, vault.BoostPowerUp.level)
|
||||
assert.Equal(t, Boost, vault.BoostPowerUp.Effect)
|
||||
assert.Equal(t, 3, vault.BoostPowerUp.Level)
|
||||
}
|
||||
|
||||
vault.UpdateCubes(0, 0, 3000)
|
||||
|
||||
@@ -35,6 +35,6 @@ var colors = map[color][3]byte{
|
||||
black: {0, 0, 0},
|
||||
purpleRed: {200, 0, 50},
|
||||
purpleBlue: {50, 0, 200},
|
||||
dimRed: {100, 0, 0},
|
||||
dimBlue: {0, 0, 100},
|
||||
dimRed: {50, 0, 0},
|
||||
dimBlue: {0, 0, 50},
|
||||
}
|
||||
|
||||
@@ -45,10 +45,14 @@ func (controller *Controller) SetAddress(address string) error {
|
||||
|
||||
// Sets the current LED sequence mode and resets the intra-sequence counter to the beginning.
|
||||
func (controller *Controller) SetMode(nearMode, farMode Mode) {
|
||||
controller.nearStrip.currentMode = nearMode
|
||||
controller.nearStrip.counter = 0
|
||||
controller.farStrip.currentMode = farMode
|
||||
controller.farStrip.counter = 0
|
||||
if nearMode != controller.nearStrip.currentMode {
|
||||
controller.nearStrip.currentMode = nearMode
|
||||
controller.nearStrip.counter = 0
|
||||
}
|
||||
if farMode != controller.farStrip.currentMode {
|
||||
controller.farStrip.currentMode = farMode
|
||||
controller.farStrip.counter = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the current mode if both sides are in the same mode, or off otherwise.
|
||||
|
||||
40
led/mode.go
40
led/mode.go
@@ -23,28 +23,30 @@ const (
|
||||
ForceMode
|
||||
BoostMode
|
||||
RandomMode
|
||||
FadeMode
|
||||
FadeRedBlueMode
|
||||
FadeSingleMode
|
||||
GradientMode
|
||||
BlinkMode
|
||||
)
|
||||
|
||||
var ModeNames = map[Mode]string{
|
||||
OffMode: "Off",
|
||||
RedMode: "Red",
|
||||
GreenMode: "Green",
|
||||
BlueMode: "Blue",
|
||||
WhiteMode: "White",
|
||||
ChaseMode: "Chase",
|
||||
WarmupMode: "Warmup",
|
||||
Warmup2Mode: "Warmup Purple",
|
||||
Warmup3Mode: "Warmup Sneaky",
|
||||
Warmup4Mode: "Warmup Gradient",
|
||||
OwnedMode: "Owned",
|
||||
NotOwnedMode: "Not Owned",
|
||||
ForceMode: "Force",
|
||||
BoostMode: "Boost",
|
||||
RandomMode: "Random",
|
||||
FadeMode: "Fade",
|
||||
GradientMode: "Gradient",
|
||||
BlinkMode: "Blink",
|
||||
OffMode: "Off",
|
||||
RedMode: "Red",
|
||||
GreenMode: "Green",
|
||||
BlueMode: "Blue",
|
||||
WhiteMode: "White",
|
||||
ChaseMode: "Chase",
|
||||
WarmupMode: "Warmup",
|
||||
Warmup2Mode: "Warmup Purple",
|
||||
Warmup3Mode: "Warmup Sneaky",
|
||||
Warmup4Mode: "Warmup Gradient",
|
||||
OwnedMode: "Owned",
|
||||
NotOwnedMode: "Not Owned",
|
||||
ForceMode: "Force",
|
||||
BoostMode: "Boost",
|
||||
RandomMode: "Random",
|
||||
FadeRedBlueMode: "Fade Red/Blue",
|
||||
FadeSingleMode: "Fade Single",
|
||||
GradientMode: "Gradient",
|
||||
BlinkMode: "Blink",
|
||||
}
|
||||
|
||||
49
led/strip.go
49
led/strip.go
@@ -50,8 +50,10 @@ func (strip *strip) updatePixels() {
|
||||
strip.updateBoostMode()
|
||||
case RandomMode:
|
||||
strip.updateRandomMode()
|
||||
case FadeMode:
|
||||
strip.updateFadeMode()
|
||||
case FadeRedBlueMode:
|
||||
strip.updateFadeRedBlueMode()
|
||||
case FadeSingleMode:
|
||||
strip.updateFadeSingleMode()
|
||||
case GradientMode:
|
||||
strip.updateGradientMode()
|
||||
case BlinkMode:
|
||||
@@ -117,6 +119,14 @@ func (strip *strip) getDimColor() color {
|
||||
return dimBlue
|
||||
}
|
||||
|
||||
// Returns a dim version of the opposite primary color (red or blue) of this strip.
|
||||
func (strip *strip) getDimOppositeColor() color {
|
||||
if strip.isRed {
|
||||
return dimBlue
|
||||
}
|
||||
return dimRed
|
||||
}
|
||||
|
||||
// Returns the starting offset for the gradient mode for this strip.
|
||||
func (strip *strip) getGradientStartOffset() int {
|
||||
if strip.isRed {
|
||||
@@ -231,10 +241,13 @@ func (strip *strip) updateOwnedMode() {
|
||||
return
|
||||
}
|
||||
for i := 0; i < numPixels; i++ {
|
||||
if i%pixelSpacing == strip.counter/speedDivisor%pixelSpacing {
|
||||
strip.pixels[i] = colors[strip.getColor()]
|
||||
} else {
|
||||
strip.pixels[i] = colors[black]
|
||||
switch (i + strip.counter/speedDivisor) % pixelSpacing {
|
||||
case 0:
|
||||
fallthrough
|
||||
case 1:
|
||||
strip.pixels[len(strip.pixels)-i-1] = colors[strip.getColor()]
|
||||
default:
|
||||
strip.pixels[len(strip.pixels)-i-1] = colors[black]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -256,9 +269,9 @@ func (strip *strip) updateForceMode() {
|
||||
case 2:
|
||||
fallthrough
|
||||
case 4:
|
||||
strip.pixels[i] = colors[strip.getOppositeColor()]
|
||||
strip.pixels[i] = colors[strip.getColor()]
|
||||
case 3:
|
||||
strip.pixels[i] = colors[strip.getDimColor()]
|
||||
strip.pixels[i] = colors[strip.getDimOppositeColor()]
|
||||
default:
|
||||
strip.pixels[i] = colors[black]
|
||||
}
|
||||
@@ -289,7 +302,7 @@ func (strip *strip) updateRandomMode() {
|
||||
}
|
||||
}
|
||||
|
||||
func (strip *strip) updateFadeMode() {
|
||||
func (strip *strip) updateFadeRedBlueMode() {
|
||||
fadeCycles := 40
|
||||
holdCycles := 10
|
||||
if strip.counter == 4*holdCycles+4*fadeCycles {
|
||||
@@ -317,6 +330,24 @@ func (strip *strip) updateFadeMode() {
|
||||
}
|
||||
}
|
||||
|
||||
func (strip *strip) updateFadeSingleMode() {
|
||||
offCycles := 50
|
||||
fadeCycles := 100
|
||||
if strip.counter == offCycles+2*fadeCycles {
|
||||
strip.counter = 0
|
||||
}
|
||||
|
||||
for i := 0; i < numPixels; i++ {
|
||||
if strip.counter < offCycles {
|
||||
strip.pixels[i] = colors[black]
|
||||
} else if strip.counter < offCycles+fadeCycles {
|
||||
strip.pixels[i] = getFadeColor(black, strip.getColor(), strip.counter-offCycles, fadeCycles)
|
||||
} else if strip.counter < offCycles+2*fadeCycles {
|
||||
strip.pixels[i] = getFadeColor(strip.getColor(), black, strip.counter-offCycles-fadeCycles, fadeCycles)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (strip *strip) updateGradientMode() {
|
||||
for i := 0; i < numPixels; i++ {
|
||||
strip.pixels[numPixels-i-1] = getGradientColor(i+strip.counter, 75)
|
||||
|
||||
Reference in New Issue
Block a user