refactoring car emulator

This commit is contained in:
MaximZaitsev
2016-08-23 09:32:21 +03:00
parent e5dbadcb83
commit fea116a8a5
5 changed files with 70 additions and 44 deletions
@@ -3,14 +3,15 @@ package control.emulator
import CarState import CarState
import RouteRequest import RouteRequest
import RouteResponse import RouteResponse
import SonarRequest
import SonarResponse import SonarResponse
import control.Controller import control.Controller
import encodeProtoBuf import encodeProtoBuf
import geometry.Line
import geometry.Vector
import room.Room import room.Room
import room.Line
import setTimeout import setTimeout
import kotlin.Pair import kotlin.Pair
import SonarRequest
class ControllerEmulator : Controller { class ControllerEmulator : Controller {
@@ -55,12 +56,7 @@ class ControllerEmulator : Controller {
val distances = arrayListOf<Int>() val distances = arrayListOf<Int>()
angles.forEach { angle -> angles.forEach { angle ->
//need angle in [0,360) val angleFinal = getSensorAngle(angle, carAngle)
var angleTmp = carAngle - angle
while (angleTmp < 0) {
angleTmp += 360
}
val angleFinal = angleTmp % 360
val xSensor1: Int val xSensor1: Int
val ySensor1: Double val ySensor1: Double
//tg can be equal to inf if angle = 90 or 270. it vertical line. x1 = x0, y1 = y0+-[any number. eg 1] //tg can be equal to inf if angle = 90 or 270. it vertical line. x1 = x0, y1 = y0+-[any number. eg 1]
@@ -78,42 +74,13 @@ class ControllerEmulator : Controller {
ySensor1 = ySensor0 + (xSensor1 - xSensor0) * Math.tan(angleFinal * Math.PI / 180) ySensor1 = ySensor0 + (xSensor1 - xSensor0) * Math.tan(angleFinal * Math.PI / 180)
} }
} }
val sensorLine = Line(ySensor0 - ySensor1, xSensor1.toDouble() - xSensor0, xSensor0 * ySensor1 - ySensor0 * xSensor1) val sensorLine = Line(ySensor0 - ySensor1, xSensor1.toDouble() - xSensor0,
val sensorVectorX = xSensor1 - xSensor0 xSensor0 * ySensor1 - ySensor0 * xSensor1)
val sensorVectorY = ySensor1 - ySensor0
var distance = Int.MAX_VALUE
for (wall in Room.walls) {
val wallLine = wall.line
val coef = sensorLine.A * wallLine.B - sensorLine.B * wallLine.A
if (Math.abs(coef) < 0.01) {
//line is parallel.
continue
}
val xIntersection = (sensorLine.B * wallLine.C - wallLine.B * sensorLine.C) / coef
val yIntersection = (sensorLine.C * wallLine.A - wallLine.C * sensorLine.A) / coef
//filters by direction and intersection position val sensorVector = Vector(xSensor0.toDouble(), ySensor0.toDouble(), xSensor1.toDouble(), ySensor1)
val IntersectionVectorX = xIntersection - xSensor0 val distance = getDistance(xSensor0, ySensor0, sensorLine, sensorVector)
val IntersectionVectorY = yIntersection - ySensor0 if (distance == -1) {
if (IntersectionVectorX * sensorVectorX + IntersectionVectorY * sensorVectorY < 0) { distances.add(distance)
continue
}
val wallVectorXTo = wall.xTo - xIntersection
val wallVectorYTo = wall.yTo - yIntersection
val wallVectorXFrom = wall.xFrom - xIntersection
val wallVectorYFrom = wall.yFrom - yIntersection
if (wallVectorXTo * wallVectorXFrom + wallVectorYTo * wallVectorYFrom > 0) {
continue
}
val currentDistance = Math.round(Math.sqrt(Math.pow(xIntersection - xSensor0, 2.0)
+ Math.pow(yIntersection - ySensor0, 2.0)))
if (currentDistance < distance) {
distance = currentDistance
}
}
println("dist $distance")
if (distance < 5 || distance > 500) {
distances.add(-1)
} else { } else {
val delta = getRandomIntFrom(IntArray(5, { x -> x - 2 }))//return one of -2 -1 0 1 or 2 val delta = getRandomIntFrom(IntArray(5, { x -> x - 2 }))//return one of -2 -1 0 1 or 2
distances.add(distance + delta) distances.add(distance + delta)
@@ -124,6 +91,49 @@ class ControllerEmulator : Controller {
callBack.invoke(bytesMessage) callBack.invoke(bytesMessage)
} }
private fun getDistance(xSensor0: Int, ySensor0: Int, sensorLine: Line, sensorVector: Vector): Int {
var result = Int.MAX_VALUE
for (wall in Room.walls) {
val wallLine = wall.line
val slope = sensorLine.A * wallLine.B - sensorLine.B * wallLine.A
if (Math.abs(slope) < 0.01) {
//line is parallel.
continue
}
val xIntersection = (sensorLine.B * wallLine.C - wallLine.B * sensorLine.C) / slope
val yIntersection = (sensorLine.C * wallLine.A - wallLine.C * sensorLine.A) / slope
//filters by direction and intersection position
val intersectionVector = Vector(xSensor0.toDouble(), ySensor0.toDouble(), xIntersection, yIntersection)
if (intersectionVector.scalarProduct(sensorVector) < 0) {
continue
}
val wallVector1 = Vector(xIntersection, yIntersection, wall.xTo.toDouble(), wall.yTo.toDouble())
val wallVector2 = Vector(xIntersection, yIntersection, wall.xFrom.toDouble(), wall.yFrom.toDouble())
if (wallVector1.scalarProduct(wallVector2) > 0) {
continue
}
val currentDistance = Math.round(Math.sqrt(Math.pow(xIntersection - xSensor0, 2.0)
+ Math.pow(yIntersection - ySensor0, 2.0)))
if (currentDistance < result) {
result = currentDistance
}
}
if (result < 5 || result > 500) {
return -1
}
return result
}
//return sensor angle in [0, 360) with considering car rotation
private fun getSensorAngle(requestAngle: Int, carAngle: Int): Int {
var angleTmp = carAngle - requestAngle
while (angleTmp < 0) {
angleTmp += 360
}
return angleTmp % 360
}
//return random int from array //return random int from array
private fun getRandomIntFrom(values: IntArray): Int { private fun getRandomIntFrom(values: IntArray): Int {
val randomValue = (Math.random() * 1000).toInt()//value in [0,999] val randomValue = (Math.random() * 1000).toInt()//value in [0,999]
@@ -1,4 +1,4 @@
package room package geometry
class Line(val A: Double, val B: Double, val C: Double) { class Line(val A: Double, val B: Double, val C: Double) {
} }
+12
View File
@@ -0,0 +1,12 @@
package geometry
class Vector constructor(val x: Double, val y: Double) {
constructor(x1: Double, y1: Double, x2: Double, y2: Double) : this(x2 - x1, y2 - y1)
fun scalarProduct(vector: Vector): Double {
return this.x * vector.x + this.y * vector.y
}
}
+2
View File
@@ -1,5 +1,7 @@
package room package room
import geometry.Line
object Room { object Room {
val upLine = Line(0.0, 1.0, -300.0) val upLine = Line(0.0, 1.0, -300.0)
+2
View File
@@ -1,5 +1,7 @@
package room package room
import geometry.Line
class Wall constructor(val line: Line, val xFrom: Int, val xTo: Int, val yFrom: Int, val yTo: Int) { class Wall constructor(val line: Line, val xFrom: Int, val xTo: Int, val yFrom: Int, val yTo: Int) {
} }