Hook LED modes up to field state.

This commit is contained in:
Patrick Fairbank
2018-07-21 22:28:22 -07:00
parent 5f457f96ec
commit 738b5a0e7b
11 changed files with 206 additions and 109 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)))

View File

@@ -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"
}

View File

@@ -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)