Skip to content

Commit

Permalink
[test] Add tests for ball placement and fixed some issues
Browse files Browse the repository at this point in the history
  • Loading branch information
g3force committed Sep 15, 2018
1 parent 194f6f1 commit 2778b61
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 8 deletions.
33 changes: 25 additions & 8 deletions internal/app/controller/placementPos.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,32 @@ func (e *Engine) BallPlacementPos() *Location {

switch event.Type {
case GameEventBallLeftFieldTouchLine:
return e.validateProtoLocation(event.Details.BallLeftFieldTouchLine.Location)
if event.Details.BallLeftFieldTouchLine.Location != nil {
location := mapProtoLocation(event.Details.BallLeftFieldTouchLine.Location)
x := e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLine
if math.Abs(location.X) > x {
location.X = math.Copysign(x, location.X)
}
y := e.Geometry.FieldWidth/2 - e.Geometry.PlacementOffsetTouchLine
location.Y = math.Copysign(y, location.Y)
return e.validateLocation(location)
}
return nil
case GameEventBallLeftFieldGoalLine:
if event.Details.BallLeftFieldGoalLine.Location != nil && e.isGoalKick(event) {
if event.Details.BallLeftFieldGoalLine.Location != nil {
location := mapProtoLocation(event.Details.BallLeftFieldGoalLine.Location)
maxX := e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLineGoalKick
if math.Abs(location.X) > maxX {
location.X = math.Copysign(maxX, location.X)
var x float64
if e.isGoalKick(event) {
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLineGoalKick
} else {
x = e.Geometry.FieldLength/2 - e.Geometry.PlacementOffsetGoalLine
}
location.X = math.Copysign(x, location.X)
y := e.Geometry.FieldWidth/2 - e.Geometry.PlacementOffsetTouchLine
location.Y = math.Copysign(y, location.Y)
return e.validateLocation(location)
}
return e.validateProtoLocation(event.Details.BallLeftFieldGoalLine.Location)
return nil
case GameEventIcing:
return e.validateProtoLocation(event.Details.Icing.KickLocation)
case GameEventGoal:
Expand Down Expand Up @@ -129,9 +144,11 @@ func (e *Engine) validateLocation(location *Location) *Location {

func (e *Engine) movePositionOutOfDefenseArea(location *Location) {
maxX := e.Geometry.FieldLength/2 - e.Geometry.DefenseAreaDepth - e.Geometry.PlacementOffsetDefenseArea
minY := e.Geometry.DefenseAreaWidth + e.Geometry.PlacementOffsetDefenseArea
minY := e.Geometry.DefenseAreaWidth/2 + e.Geometry.PlacementOffsetDefenseArea
if math.Abs(location.X) > maxX && math.Abs(location.Y) < minY {
if math.Abs(maxX-math.Abs(location.X)) < math.Abs(minY-math.Abs(location.Y)) {
diffX := math.Abs(maxX - math.Abs(location.X))
diffY := math.Abs(minY - math.Abs(location.Y))
if diffX < diffY {
location.X = math.Copysign(maxX, location.X)
} else {
location.Y = math.Copysign(minY, location.Y)
Expand Down
135 changes: 135 additions & 0 deletions internal/app/controller/placementPos_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package controller

import (
"github.com/RoboCup-SSL/ssl-game-controller/pkg/refproto"
"math"
"testing"
)

func TestEngine_BallPlacementPos(t *testing.T) {
config := DefaultConfig()
engine := NewEngine(config.Game)
engine.State.TeamState[TeamYellow].OnPositiveHalf = true
engine.State.TeamState[TeamBlue].OnPositiveHalf = false
engine.Geometry.PlacementOffsetTouchLine = 0.2
engine.Geometry.PlacementOffsetGoalLine = 0.3 // avoid confusion with touchLine value
engine.Geometry.PlacementOffsetGoalLineGoalKick = 1.0
fw := engine.Geometry.FieldWidth
fl := engine.Geometry.FieldLength
dd := engine.Geometry.DefenseAreaDepth
dw := engine.Geometry.DefenseAreaWidth
ot := engine.Geometry.PlacementOffsetTouchLine
og := engine.Geometry.PlacementOffsetGoalLine
ogg := engine.Geometry.PlacementOffsetGoalLineGoalKick
od := engine.Geometry.PlacementOffsetDefenseArea

// ball left field touch line
setBallLeftFieldTouchLine(&engine, Location{0, fw / 2}.toProto())
assertSimilar(t, &engine, Location{0, fw/2 - ot})

setBallLeftFieldTouchLine(&engine, Location{0.1, fw / 2}.toProto())
assertSimilar(t, &engine, Location{0.1, fw/2 - ot})

setBallLeftFieldTouchLine(&engine, Location{0, 42}.toProto())
assertSimilar(t, &engine, Location{0, fw/2 - ot})

setBallLeftFieldTouchLine(&engine, Location{0, 1}.toProto())
assertSimilar(t, &engine, Location{0, fw/2 - ot})

setBallLeftFieldTouchLine(&engine, Location{0, -fw / 2}.toProto())
assertSimilar(t, &engine, Location{0, -(fw/2 - ot)})

setBallLeftFieldTouchLine(&engine, Location{fl / 2, fw / 2}.toProto())
assertSimilar(t, &engine, Location{fl/2 - og, fw/2 - ot})

setBallLeftFieldTouchLine(&engine, Location{-fl / 2, fw / 2}.toProto())
assertSimilar(t, &engine, Location{-(fl/2 - og), fw/2 - ot})

// ball left field goal line
setBallLeftFieldGoalLine(&engine, Location{fl / 2, fw / 2}.toProto(), TeamYellow)
assertSimilar(t, &engine, Location{fl/2 - ogg, fw/2 - ot})

setBallLeftFieldGoalLine(&engine, Location{-fl / 2, fw / 2}.toProto(), TeamYellow)
assertSimilar(t, &engine, Location{-(fl/2 - og), fw/2 - ot})

setBallLeftFieldGoalLine(&engine, Location{fl / 2, fw / 4}.toProto(), TeamYellow)
assertSimilar(t, &engine, Location{fl/2 - ogg, fw/2 - ot})

setBallLeftFieldGoalLine(&engine, Location{fl / 2, fw / 4}.toProto(), TeamBlue)
assertSimilar(t, &engine, Location{fl/2 - og, fw/2 - ot})

setBallLeftFieldGoalLine(&engine, Location{fl / 2, 0}.toProto(), TeamBlue)
assertSimilar(t, &engine, Location{fl/2 - og, fw/2 - ot})

setBallLeftFieldGoalLine(&engine, Location{fl / 2, -fw}.toProto(), TeamBlue)
assertSimilar(t, &engine, Location{fl/2 - og, -(fw/2 - ot)})

// bot crash unique
setBotCrashUnique(&engine, Location{0, 0}.toProto())
assertSimilar(t, &engine, Location{0, 0})

setBotCrashUnique(&engine, Location{1, -2}.toProto())
assertSimilar(t, &engine, Location{1, -2})

setBotCrashUnique(&engine, Location{1, -42}.toProto())
assertSimilar(t, &engine, Location{1, -(fw/2 - ot)})

setBotCrashUnique(&engine, Location{1, 42}.toProto())
assertSimilar(t, &engine, Location{1, fw/2 - ot})

setBotCrashUnique(&engine, Location{fl / 2, -42}.toProto())
assertSimilar(t, &engine, Location{fl/2 - og, -(fw/2 - ot)})

setBotCrashUnique(&engine, Location{-fl / 2, -42}.toProto())
assertSimilar(t, &engine, Location{-(fl/2 - og), -(fw/2 - ot)})

setBotCrashUnique(&engine, Location{42, 0}.toProto())
assertSimilar(t, &engine, Location{fl/2 - dd - od, 0})

setBotCrashUnique(&engine, Location{fl/2 - 0.1, dw/2 - 0.1}.toProto())
assertSimilar(t, &engine, Location{fl/2 - og, dw/2 + od})

setBotCrashUnique(&engine, Location{fl/2 - dd, dw/2 - 0.1}.toProto())
assertSimilar(t, &engine, Location{fl/2 - dd - od, dw/2 - 0.1})
}

func assertSimilar(t *testing.T, engine *Engine, expected Location) {
placementPos := engine.BallPlacementPos()
if !similar(expected, *placementPos) {
t.Fatalf("Expected placement pos to be %v, but was %v", expected, *placementPos)
}
}

func setBallLeftFieldTouchLine(engine *Engine, eventLocation *refproto.Location) {
var byTeam = TeamYellow.toProto()
engine.State.GameEvents = []*GameEvent{{
Type: GameEventBallLeftFieldTouchLine,
Details: GameEventDetails{
BallLeftFieldTouchLine: &refproto.GameEvent_BallLeftFieldEvent{
ByTeam: &byTeam,
Location: eventLocation}}}}
}

func setBallLeftFieldGoalLine(engine *Engine, eventLocation *refproto.Location, placingTeam Team) {
var byTeam = placingTeam.Opposite().toProto()
engine.State.GameEvents = []*GameEvent{{
Type: GameEventBallLeftFieldGoalLine,
Details: GameEventDetails{
BallLeftFieldGoalLine: &refproto.GameEvent_BallLeftFieldEvent{
ByTeam: &byTeam,
Location: eventLocation}}}}
}

func setBotCrashUnique(engine *Engine, eventLocation *refproto.Location) {
var byTeam = TeamYellow.toProto()
engine.State.GameEvents = []*GameEvent{{
Type: GameEventBotCrashUnique,
Details: GameEventDetails{
BotCrashUnique: &refproto.GameEvent_BotCrashUnique{
ByTeam: &byTeam,
Location: eventLocation}}}}
}

func similar(l1 Location, l2 Location) bool {
return math.Abs(l1.X-l2.X) < 1e-4 && math.Abs(l1.Y-l2.Y) < 1e-4
}
9 changes: 9 additions & 0 deletions internal/app/controller/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,12 @@ type Location struct {
X float64
Y float64
}

func (l Location) toProto() (p *refproto.Location) {
p = new(refproto.Location)
p.X = new(float32)
p.Y = new(float32)
*p.X = float32(l.X)
*p.Y = float32(l.Y)
return
}

0 comments on commit 2778b61

Please sign in to comment.