robocar-steering/pkg/steering/corrector_test.go

402 lines
8.8 KiB
Go

package steering
import (
"github.com/cyrilix/robocar-protobuf/go/events"
"reflect"
"testing"
)
var (
objectOnMiddleDistant = events.Object{
Type: events.TypeObject_ANY,
Left: 0.4,
Top: 0.1,
Right: 0.6,
Bottom: 0.2,
Confidence: 0.9,
}
objectOnLeftDistant = events.Object{
Type: events.TypeObject_ANY,
Left: 0.1,
Top: 0.09,
Right: 0.3,
Bottom: 0.19,
Confidence: 0.9,
}
objectOnRightDistant = events.Object{
Type: events.TypeObject_ANY,
Left: 0.7,
Top: 0.21,
Right: 0.9,
Bottom: 0.11,
Confidence: 0.9,
}
objectOnMiddleNear = events.Object{
Type: events.TypeObject_ANY,
Left: 0.4,
Top: 0.8,
Right: 0.6,
Bottom: 0.9,
Confidence: 0.9,
}
)
var (
defaultGridMap = GridMap{
DistanceSteps: []float64{0., 0.2, 0.4, 0.6, 0.8, 1.},
SteeringSteps: []float64{-1., -0.66, -0.33, 0., 0.33, 0.66, 1.},
Data: [][]float64{
{0., 0., 0., 0., 0., 0.},
{0., 0., 0., 0., 0., 0.},
{0., 0., 0.25, -0.25, 0., 0.},
{0., 0.25, 0.5, -0.5, -0.25, 0.},
{0.25, 0.5, 1, -1, -0.5, -0.25},
},
}
)
func TestCorrector_AdjustFromObjectPosition(t *testing.T) {
type args struct {
currentSteering float64
objects []*events.Object
}
tests := []struct {
name string
args args
want float64
}{
{
name: "run straight without objects",
args: args{
currentSteering: 0.,
objects: []*events.Object{},
},
want: 0.,
},
{
name: "run to left without objects",
args: args{
currentSteering: -0.9,
objects: []*events.Object{},
},
want: -0.9,
},
{
name: "run to right without objects",
args: args{
currentSteering: 0.9,
objects: []*events.Object{},
}, want: 0.9,
},
{
name: "run straight with 1 distant object",
args: args{
currentSteering: 0.,
objects: []*events.Object{&objectOnMiddleDistant},
},
want: 0.,
},
{
name: "run to left with 1 distant object",
args: args{
currentSteering: -0.9,
objects: []*events.Object{&objectOnMiddleDistant},
},
want: -0.9,
},
{
name: "run to right with 1 distant object",
args: args{
currentSteering: 0.9,
objects: []*events.Object{&objectOnMiddleDistant},
},
want: 0.9,
},
{
name: "run straight with 1 near object",
args: args{
currentSteering: 0.,
objects: []*events.Object{&objectOnMiddleNear},
},
want: 1,
},
{
name: "run to left with 1 near object",
args: args{
currentSteering: -0.9,
objects: []*events.Object{&objectOnMiddleNear},
},
want: -0.4,
},
{
name: "run to right with 1 near object",
args: args{
currentSteering: 0.9,
objects: []*events.Object{&objectOnMiddleNear},
},
want: 0.4,
},
// Todo Object on left/right near/distant
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Corrector{
gridMap: &defaultGridMap,
}
if got := c.AdjustFromObjectPosition(tt.args.currentSteering, tt.args.objects); got != tt.want {
t.Errorf("AdjustFromObjectPosition() = %v, want %v", got, tt.want)
}
})
}
}
func TestCorrector_nearObject(t *testing.T) {
type args struct {
objects []*events.Object
}
tests := []struct {
name string
args args
want *events.Object
wantErr bool
}{
{
name: "List object is empty",
args: args{
objects: []*events.Object{},
},
want: nil,
wantErr: true,
},
{
name: "List with only one object",
args: args{
objects: []*events.Object{&objectOnMiddleNear},
},
want: &objectOnMiddleNear,
wantErr: false,
},
{
name: "List with many objects",
args: args{
objects: []*events.Object{&objectOnLeftDistant, &objectOnMiddleNear, &objectOnRightDistant, &objectOnMiddleDistant},
},
want: &objectOnMiddleNear,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &Corrector{}
got, err := c.nearObject(tt.args.objects)
if (err != nil) != tt.wantErr {
t.Errorf("nearObject() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("nearObject() got = %v, want %v", got, tt.want)
}
})
}
}
func TestNewGridMapFromJson(t *testing.T) {
type args struct {
fileName string
}
tests := []struct {
name string
args args
want *GridMap
wantErr bool
}{
{
name: "default config",
args: args{
fileName: "test_data/config.json",
},
want: &defaultGridMap,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewGridMapFromJson(tt.args.fileName)
if (err != nil) != tt.wantErr {
t.Errorf("NewGridMapFromJson() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(*got, *tt.want) {
t.Errorf("NewGridMapFromJson() got = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(got.SteeringSteps, tt.want.SteeringSteps) {
t.Errorf("NewGridMapFromJson(), bad steering limits: got = %v, want %v", got.SteeringSteps, tt.want.SteeringSteps)
}
if !reflect.DeepEqual(got.DistanceSteps, tt.want.DistanceSteps) {
t.Errorf("NewGridMapFromJson(), bad distance limits: got = %v, want %v", got.DistanceSteps, tt.want.DistanceSteps)
}
})
}
}
func TestGridMap_ValueOf(t *testing.T) {
type fields struct {
DistanceSteps []float64
SteeringSteps []float64
Data [][]float64
}
type args struct {
steering float64
distance float64
}
tests := []struct {
name string
fields fields
args args
want float64
wantErr bool
}{
{
name: "nominal",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: 0.,
distance: 0.,
},
want: 0,
wantErr: false,
},
{
name: "limit distance <",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: 0,
distance: 0.39999,
},
want: 0,
wantErr: false,
},
{
name: "limit distance >",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: 0,
distance: 0.400001,
},
want: -0.25,
wantErr: false,
},
{
name: "limit steering <",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: -0.660001,
distance: 0.85,
},
want: 0.25,
wantErr: false,
},
{
name: "limit steering >",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: -0.66,
distance: 0.85,
},
want: 0.5,
wantErr: false,
},
{
name: "steering < min value",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: defaultGridMap.SteeringSteps[0] - 0.1,
distance: 0.85,
},
wantErr: true,
},
{
name: "steering > max value",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: defaultGridMap.SteeringSteps[len(defaultGridMap.SteeringSteps)-1] + 0.1,
distance: 0.85,
},
wantErr: true,
},
{
name: "distance < min value",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: -0.65,
distance: defaultGridMap.DistanceSteps[0] - 0.1,
},
wantErr: true,
},
{
name: "distance > max value",
fields: fields{
DistanceSteps: defaultGridMap.DistanceSteps,
SteeringSteps: defaultGridMap.SteeringSteps,
Data: defaultGridMap.Data,
},
args: args{
steering: -0.65,
distance: defaultGridMap.DistanceSteps[len(defaultGridMap.DistanceSteps)-1] + 0.1,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &GridMap{
DistanceSteps: tt.fields.DistanceSteps,
SteeringSteps: tt.fields.SteeringSteps,
Data: tt.fields.Data,
}
got, err := f.ValueOf(tt.args.steering, tt.args.distance)
if (err != nil) != tt.wantErr {
t.Errorf("ValueOf() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ValueOf() = %v, want %v", got, tt.want)
}
})
}
}