From ba70a330f30f390f65f7f4107a15d07dd5b124bb Mon Sep 17 00:00:00 2001 From: MaximZaitsev Date: Wed, 7 Sep 2016 17:39:39 +0300 Subject: [PATCH] copied emulator logic to main server, add parsing cl args, add JSAP lib --- server/build.gradle | 3 + server/room_config_example.xml | 9 ++ server/src/main/java/ClUtils.kt | 33 +++++ server/src/main/java/ServerMain.kt | 36 ++++- .../main/java/algorithm/AbstractAlgorithm.kt | 1 + .../clInterface/executor/DebugInformation.kt | 4 + .../main/java/clInterface/executor/Explore.kt | 4 + .../java/clInterface/executor/RouteMetric.kt | 7 +- .../main/java/clInterface/executor/Sonar.kt | 3 +- server/src/main/java/net/car/Dropper.kt | 4 + server/src/main/java/objects/Car.kt | 35 +---- server/src/main/java/objects/CarReal.kt | 40 ++++++ server/src/main/java/objects/Environment.kt | 2 +- .../main/java/objects/emulator/CarEmulator.kt | 130 ++++++++++++++++++ .../java/objects/emulator/EmulatedRoom.kt | 44 ++++++ .../java/objects/emulator/EmulatedWall.kt | 27 ++++ .../objects/emulator/ListenableFutureImpl.kt | 54 ++++++++ server/src/main/java/objects/emulator/Rng.kt | 28 ++++ .../main/java/roomScanner/CarController.kt | 4 +- .../src/main/java/roomScanner/RoomScanner.kt | 2 +- 20 files changed, 428 insertions(+), 42 deletions(-) create mode 100644 server/room_config_example.xml create mode 100644 server/src/main/java/ClUtils.kt create mode 100644 server/src/main/java/objects/CarReal.kt create mode 100644 server/src/main/java/objects/emulator/CarEmulator.kt create mode 100644 server/src/main/java/objects/emulator/EmulatedRoom.kt create mode 100644 server/src/main/java/objects/emulator/EmulatedWall.kt create mode 100644 server/src/main/java/objects/emulator/ListenableFutureImpl.kt create mode 100644 server/src/main/java/objects/emulator/Rng.kt diff --git a/server/build.gradle b/server/build.gradle index f0ed28fbfc1..4caea80f077 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -46,12 +46,15 @@ jar { "Main-Class": "ServerMainKt") } + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile group: 'org.asynchttpclient', name: 'async-http-client', version: '2.0.0-RC9' + compile group: "com.martiansoftware", name: "jsap", version: "2.1" compile files ("../proto/compiler/build/protokot-runtime.jar") } diff --git a/server/room_config_example.xml b/server/room_config_example.xml new file mode 100644 index 00000000000..badaf03b020 --- /dev/null +++ b/server/room_config_example.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/server/src/main/java/ClUtils.kt b/server/src/main/java/ClUtils.kt new file mode 100644 index 00000000000..e9c8bb583a7 --- /dev/null +++ b/server/src/main/java/ClUtils.kt @@ -0,0 +1,33 @@ +import com.martiansoftware.jsap.FlaggedOption +import com.martiansoftware.jsap.JSAP +import com.martiansoftware.jsap.StringParser +import com.martiansoftware.jsap.Switch + +fun setClOptions(clParser: JSAP) { + val optEmulator = Switch("emulator", 'e', "emulator") + val optUseRandom = Switch("random", 'r', "random") + val optSeedForRandom = getOption("seed", JSAP.LONG_PARSER, "1111", 's', "seed") + val optTestRoom = getOption("test room", JSAP.STRING_PARSER, "", null, "room") + val optHelp = getOption("help", JSAP.BOOLEAN_PARSER, "false", null, "help") + + clParser.registerParameter(optEmulator) + clParser.registerParameter(optUseRandom) + clParser.registerParameter(optSeedForRandom) + clParser.registerParameter(optTestRoom) + clParser.registerParameter(optHelp) +} + +fun getOption(name: String, parser: StringParser, default: String, shortFlag: Char?, longFlag: String, required: Boolean = false): FlaggedOption { + val result = FlaggedOption(name) + .setStringParser(parser) + .setDefault(default) + .setRequired(required) + if (shortFlag != null) { + result.setShortFlag(shortFlag) + } + if (!longFlag.equals("")) { + result.setLongFlag(longFlag) + } + + return result +} diff --git a/server/src/main/java/ServerMain.kt b/server/src/main/java/ServerMain.kt index 6580a7988fe..0d18bfbfe76 100644 --- a/server/src/main/java/ServerMain.kt +++ b/server/src/main/java/ServerMain.kt @@ -1,11 +1,36 @@ -import roomScanner.CarController -import roomScanner.RoomScanner import clInterface.DebugClInterface +import com.martiansoftware.jsap.JSAP import net.car.Dropper import net.car.client.Client +import objects.CarReal import objects.Environment +import objects.emulator.CarEmulator +import objects.emulator.EmulatedRoom +import objects.emulator.Rng +import roomScanner.CarController +import roomScanner.RoomScanner fun main(args: Array) { + + val clParser = JSAP() + setClOptions(clParser) + val argsConfig = clParser.parse(args) + if (!argsConfig.success() || argsConfig.getBoolean("help")) { + println(clParser.getHelp()) + return + } + if (argsConfig.getBoolean("emulator")) { + val pathToRoomConfig = argsConfig.getString("test room") + val randomSeed = argsConfig.getLong("seed") + val useRandom = argsConfig.getBoolean("random") + val carUid = 1 + val emulatedRoom = EmulatedRoom.EmulatedRoomFromFile(pathToRoomConfig) + if (emulatedRoom == null) { + println("error parsin room from file $pathToRoomConfig") + return + } + Environment.map.put(carUid, CarEmulator(carUid, emulatedRoom, useRandom, Rng(randomSeed))) + } var roomScanner: RoomScanner? = null val carServer = net.car.server.Server.createCarServerThread() val webServer = net.web.server.Server.createWebServerThread() @@ -16,8 +41,10 @@ fun main(args: Array) { if (args.contains("--scan")) { Environment.onCarConnect { car -> - roomScanner = RoomScanner(CarController(car)) - roomScanner!!.start() + if (car is CarReal) { + roomScanner = RoomScanner(CarController(car)) + roomScanner!!.start() + } } } @@ -29,4 +56,5 @@ fun main(args: Array) { Client.shutDownClient() roomScanner?.interrupt() + } diff --git a/server/src/main/java/algorithm/AbstractAlgorithm.kt b/server/src/main/java/algorithm/AbstractAlgorithm.kt index caa9dbe691f..616f728b429 100644 --- a/server/src/main/java/algorithm/AbstractAlgorithm.kt +++ b/server/src/main/java/algorithm/AbstractAlgorithm.kt @@ -7,6 +7,7 @@ import SonarResponse import algorithm.geometry.Angle import algorithm.geometry.AngleData import objects.Car +import objects.CarReal import roomScanner.CarController.Direction.* import java.util.* import java.util.concurrent.TimeUnit diff --git a/server/src/main/java/clInterface/executor/DebugInformation.kt b/server/src/main/java/clInterface/executor/DebugInformation.kt index 3e1ab2ff8c9..8257689c390 100644 --- a/server/src/main/java/clInterface/executor/DebugInformation.kt +++ b/server/src/main/java/clInterface/executor/DebugInformation.kt @@ -6,6 +6,7 @@ import DebugResponseMemoryStats import DebugResponseSonarStats import roomScanner.serialize import net.car.client.Client +import objects.CarReal import objects.Environment import java.rmi.UnexpectedException @@ -14,6 +15,9 @@ class DebugInformation : CommandExecutor { override fun execute(command: String) { val params = command.split(" ") val car = Environment.map[params[1].toInt()]!! + if (!(car is CarReal)) { + return + } val type = DebugRequest.Type.fromIntToType(params[2].toInt()) val request = DebugRequest.BuilderDebugRequest(type).build() diff --git a/server/src/main/java/clInterface/executor/Explore.kt b/server/src/main/java/clInterface/executor/Explore.kt index 586d2c985bc..ccc129f223f 100644 --- a/server/src/main/java/clInterface/executor/Explore.kt +++ b/server/src/main/java/clInterface/executor/Explore.kt @@ -5,6 +5,7 @@ import roomScanner.serialize import SonarExploreAngleRequest import SonarExploreAngleResponse import net.car.client.Client +import objects.CarReal import objects.Environment class Explore : CommandExecutor { @@ -12,6 +13,9 @@ class Explore : CommandExecutor { override fun execute(command: String) { val params = command.split(" ") val car = Environment.map[params[1].toInt()]!! + if (!(car is CarReal)) { + return + } val angle = params[2].toInt() val window = params[3].toInt() diff --git a/server/src/main/java/clInterface/executor/RouteMetric.kt b/server/src/main/java/clInterface/executor/RouteMetric.kt index ddc1d904a34..007be46c0a7 100644 --- a/server/src/main/java/clInterface/executor/RouteMetric.kt +++ b/server/src/main/java/clInterface/executor/RouteMetric.kt @@ -4,6 +4,7 @@ import CodedOutputStream import RouteMetricRequest import net.car.client.Client import objects.Car +import objects.CarReal import objects.Environment import java.net.ConnectException @@ -39,7 +40,11 @@ class RouteMetric : CommandExecutor { val requestBytes = ByteArray(routeMessage.getSizeNoTag()) routeMessage.writeTo(CodedOutputStream(requestBytes)) try { - car.carConnection.sendRequest(Client.Request.ROUTE_METRIC, requestBytes) + routeMessage.distances.forEachIndexed { idx, distance -> + val direction = roomScanner.CarController.Direction.values() + .filter { it.id == routeMessage.directions[idx] }.first() + car.moveCar(distance, direction).get() + } } catch (e: ConnectException) { synchronized(Environment, { Environment.map.remove(id) diff --git a/server/src/main/java/clInterface/executor/Sonar.kt b/server/src/main/java/clInterface/executor/Sonar.kt index 675e3e03ecb..240257b9fca 100644 --- a/server/src/main/java/clInterface/executor/Sonar.kt +++ b/server/src/main/java/clInterface/executor/Sonar.kt @@ -2,7 +2,6 @@ package clInterface.executor import CodedOutputStream import SonarRequest -import net.car.client.Client import objects.Car import objects.Environment import java.net.ConnectException @@ -35,7 +34,7 @@ class Sonar : CommandExecutor { val requestBytes = ByteArray(requestMessage.getSizeNoTag()) requestMessage.writeTo(CodedOutputStream(requestBytes)) try { - car.carConnection.sendRequest(Client.Request.SONAR, requestBytes) + car.scan(requestMessage.angles, requestMessage.attempts.first(), requestMessage.windowSize, requestMessage.smoothing) } catch (e: ConnectException) { synchronized(Environment, { Environment.map.remove(id) diff --git a/server/src/main/java/net/car/Dropper.kt b/server/src/main/java/net/car/Dropper.kt index 5092899a124..d0e71a2fa88 100644 --- a/server/src/main/java/net/car/Dropper.kt +++ b/server/src/main/java/net/car/Dropper.kt @@ -1,6 +1,7 @@ package net.car import net.car.client.Client +import objects.CarReal import objects.Environment import java.net.ConnectException import kotlin.concurrent.thread @@ -34,6 +35,9 @@ object Dropper { for (key in environment.map.keys) { try { val carValue = environment.map[key] ?: continue + if (!(carValue is CarReal)) { + continue + } carValue.carConnection.sendRequest(Client.Request.PING, ByteArray(0)) } catch (e: ConnectException) { environment.map.remove(key) diff --git a/server/src/main/java/objects/Car.kt b/server/src/main/java/objects/Car.kt index 76d679d3605..e29b186af79 100644 --- a/server/src/main/java/objects/Car.kt +++ b/server/src/main/java/objects/Car.kt @@ -1,44 +1,17 @@ package objects -import CodedOutputStream -import RouteMetricRequest import SonarRequest -import net.car.client.Client import org.asynchttpclient.ListenableFuture import org.asynchttpclient.Response -import roomScanner.CarController.Direction -import roomScanner.serialize +import roomScanner.CarController -class Car constructor(val uid: Int, host: String, port: Int) { - - private val CHARGE_CORRECTION = 1.0//on full charge ok is 0.83 - 0.86 +abstract class Car(val uid: Int) { var x = 0.0 var y = 0.0 var angle = 0.0 - val carConnection = CarConnection(host, port) - fun moveCar(distance: Int, direction: Direction): ListenableFuture { + abstract fun moveCar(distance: Int, direction: CarController.Direction): ListenableFuture - val route = RouteMetricRequest.BuilderRouteMetricRequest( - IntArray(1, { (distance * CHARGE_CORRECTION).toInt() }), IntArray(1, { direction.id })) - val bytesRoute = ByteArray(route.getSizeNoTag()) - route.writeTo(CodedOutputStream(bytesRoute)) - return carConnection.sendRequest(Client.Request.ROUTE_METRIC, bytesRoute) - } - - fun scan(angles: IntArray, attempts: Int, windowSize: Int, smoothing: SonarRequest.Smoothing): ListenableFuture { - val message = SonarRequest.BuilderSonarRequest( - angles = angles, - attempts = IntArray(angles.size, { attempts }), - smoothing = smoothing, - windowSize = windowSize) - .build() - val data = serialize(message.getSizeNoTag(), { message.writeTo(it) }) - return carConnection.sendRequest(Client.Request.SONAR, data) - } - - override fun toString(): String { - return "$uid ; x:$x; y:$y; target:$angle" - } + abstract fun scan(angles: IntArray, attempts: Int, windowSize: Int, smoothing: SonarRequest.Smoothing): ListenableFuture } \ No newline at end of file diff --git a/server/src/main/java/objects/CarReal.kt b/server/src/main/java/objects/CarReal.kt new file mode 100644 index 00000000000..68e7f705e3a --- /dev/null +++ b/server/src/main/java/objects/CarReal.kt @@ -0,0 +1,40 @@ +package objects + +import CodedOutputStream +import RouteMetricRequest +import SonarRequest +import net.car.client.Client +import org.asynchttpclient.ListenableFuture +import org.asynchttpclient.Response +import roomScanner.CarController.Direction +import roomScanner.serialize + +class CarReal(uid: Int, host: String, port: Int) : Car(uid) { + + private val CHARGE_CORRECTION = 1.0//on full charge ok is 0.83 - 0.86 + val carConnection = CarConnection(host, port) + + override fun moveCar(distance: Int, direction: Direction): ListenableFuture { + + val route = RouteMetricRequest.BuilderRouteMetricRequest( + IntArray(1, { (distance * CHARGE_CORRECTION).toInt() }), IntArray(1, { direction.id })) + val bytesRoute = ByteArray(route.getSizeNoTag()) + route.writeTo(CodedOutputStream(bytesRoute)) + return carConnection.sendRequest(Client.Request.ROUTE_METRIC, bytesRoute) + } + + override fun scan(angles: IntArray, attempts: Int, windowSize: Int, smoothing: SonarRequest.Smoothing): ListenableFuture { + val message = SonarRequest.BuilderSonarRequest( + angles = angles, + attempts = IntArray(angles.size, { attempts }), + smoothing = smoothing, + windowSize = windowSize) + .build() + val data = serialize(message.getSizeNoTag(), { message.writeTo(it) }) + return carConnection.sendRequest(Client.Request.SONAR, data) + } + + override fun toString(): String { + return "$uid ; x:$x; y:$y; target:$angle" + } +} \ No newline at end of file diff --git a/server/src/main/java/objects/Environment.kt b/server/src/main/java/objects/Environment.kt index a12b6b4b752..537484f0a03 100644 --- a/server/src/main/java/objects/Environment.kt +++ b/server/src/main/java/objects/Environment.kt @@ -8,7 +8,7 @@ object Environment { @Synchronized fun connectCar(host: String, port: Int): Int { uid++ - val car = Car(uid, host, port) + val car = CarReal(uid, host, port) onConnect.forEach { it(car) } map.put(uid, car) return uid diff --git a/server/src/main/java/objects/emulator/CarEmulator.kt b/server/src/main/java/objects/emulator/CarEmulator.kt new file mode 100644 index 00000000000..de7cd393515 --- /dev/null +++ b/server/src/main/java/objects/emulator/CarEmulator.kt @@ -0,0 +1,130 @@ +package objects.emulator + +import SonarRequest +import SonarResponse +import algorithm.geometry.Angle +import algorithm.geometry.Line +import algorithm.geometry.Vector +import objects.Car +import org.asynchttpclient.ListenableFuture +import org.asynchttpclient.Response +import roomScanner.CarController +import roomScanner.CarController.Direction.* +import roomScanner.serialize + +class CarEmulator(uid: Int, val testRoom: EmulatedRoom, val useRandom: Boolean, val randomGenerator: Rng) : Car(uid) { + + private var xReal = 0 + private var yReal = 0 + private var angleReal = Angle(0) + + override fun moveCar(distance: Int, direction: CarController.Direction): ListenableFuture { + val coef = if (useRandom) randomGenerator.nextInt(900, 1100).toDouble() / 1000.0 else 1.0 + val distanceWithRandom = (coef * distance).toInt() + when (direction) { + FORWARD -> { + xReal += (Math.cos(angleReal.rads()) * distanceWithRandom).toInt() + yReal += (Math.sin(angleReal.rads()) * distanceWithRandom).toInt() + } + BACKWARD -> { + xReal -= (Math.cos(angleReal.rads()) * distanceWithRandom).toInt() + yReal -= (Math.sin(angleReal.rads()) * distanceWithRandom).toInt() + } + LEFT -> angleReal += Angle(distanceWithRandom) + RIGHT -> angleReal -= Angle(distanceWithRandom) + } + println("x=$xReal y=$yReal angle=${angleReal.degs()}") + return ListenableFutureImpl(ByteArray(0)) + } + + override fun scan(angles: IntArray, attempts: Int, windowSize: Int, smoothing: SonarRequest.Smoothing): ListenableFuture { + + + val xSensor0 = xReal.toInt() + val ySensor0 = yReal.toInt() + val carAngle = angleReal + + val distances = arrayListOf() + angles.forEach { angle -> + val angleFinal = getSensorAngle(angle, carAngle.degs()) + val xSensor1: Int + 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] + when (angleFinal) { + 90 -> { + xSensor1 = xSensor0 + ySensor1 = (ySensor0 + 1).toDouble() + } + 270 -> { + xSensor1 = xSensor0 + ySensor1 = (ySensor0 - 1).toDouble() + } + in (90..270) -> { + xSensor1 = xSensor0 - 1 + ySensor1 = ySensor0 + (xSensor1 - xSensor0) * Math.tan(angleFinal * Math.PI / 180) + } + else -> { + xSensor1 = xSensor0 + 1 + ySensor1 = ySensor0 + (xSensor1 - xSensor0) * Math.tan(angleFinal * Math.PI / 180) + } + } + val sensorLine = Line(ySensor0 - ySensor1, xSensor1.toDouble() - xSensor0, + xSensor0 * ySensor1 - ySensor0 * xSensor1) + + val sensorVector = Vector(xSensor0.toDouble(), ySensor0.toDouble(), xSensor1.toDouble(), ySensor1) + val distance = getDistance(xSensor0, ySensor0, sensorLine, sensorVector) + if (distance == -1) { + distances.add(distance) + } else { + val delta = if (useRandom) randomGenerator.nextInt(-2, 2) else 0//return one of -2 -1 0 1 or 2 + distances.add(distance + delta) + } + } + + val responseMessage = SonarResponse.BuilderSonarResponse(distances.toIntArray()).build() + val bytes = serialize(responseMessage.getSizeNoTag(), { responseMessage.writeTo(it) }) + + return ListenableFutureImpl(bytes) + } + + private fun getDistance(xSensor0: Int, ySensor0: Int, sensorLine: Line, sensorVector: Vector): Int { + var result = Long.MAX_VALUE + for (wall in testRoom.emulatedWalls) { + 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 + } + } + return result.toInt() + } + + + private fun getSensorAngle(requestAngle: Int, carAngle: Int): Int { + var angleTmp = carAngle - requestAngle + while (angleTmp < 0) { + angleTmp += 360 + } + return angleTmp % 360 + } +} + diff --git a/server/src/main/java/objects/emulator/EmulatedRoom.kt b/server/src/main/java/objects/emulator/EmulatedRoom.kt new file mode 100644 index 00000000000..486f7b96ef0 --- /dev/null +++ b/server/src/main/java/objects/emulator/EmulatedRoom.kt @@ -0,0 +1,44 @@ +package objects.emulator + +import org.w3c.dom.Node +import java.io.File +import javax.xml.parsers.DocumentBuilderFactory + +class EmulatedRoom() { + val emulatedWalls = arrayListOf() + + constructor(EmulatedWalls: Collection) : this() { + this.emulatedWalls.addAll(EmulatedWalls) + } + + companion object { + fun EmulatedRoomFromFile(pathToFile: String): EmulatedRoom? { + + val factory = DocumentBuilderFactory.newInstance() + val builder = factory.newDocumentBuilder() + val doc = builder.parse(File(pathToFile)) + val root = doc.getDocumentElement() + val rootChild = root.childNodes + var walls: Node? = null + for (i in 0..rootChild.length - 1) { + val node = rootChild.item(i) + if (node.nodeType == Node.ELEMENT_NODE) { + walls = node + break + } + } + walls ?: return null + val wallsChild = walls.childNodes + val result = EmulatedRoom() + for (i in 0..wallsChild.length - 1) { + val wall = wallsChild.item(i) + if (wall.nodeType != Node.ELEMENT_NODE) { + continue + } + val EmulatedWall = EmulatedWall.wallFromXml(wall) ?: return null + result.emulatedWalls.add(EmulatedWall) + } + return result + } + } +} diff --git a/server/src/main/java/objects/emulator/EmulatedWall.kt b/server/src/main/java/objects/emulator/EmulatedWall.kt new file mode 100644 index 00000000000..95c90609ffb --- /dev/null +++ b/server/src/main/java/objects/emulator/EmulatedWall.kt @@ -0,0 +1,27 @@ +package objects.emulator + +import algorithm.geometry.Line +import org.w3c.dom.Node + +class EmulatedWall constructor(val line: Line, val xFrom: Int, val xTo: Int, val yFrom: Int, val yTo: Int) { + + companion object { + fun wallFromXml(wall: Node): EmulatedWall? { + val points = wall.attributes + val startX: Int + val endX: Int + val endY: Int + val startY: Int + try { + startX = points.getNamedItem("startX").nodeValue.toInt() + startY = points.getNamedItem("startY").nodeValue.toInt() + endX = points.getNamedItem("endX").nodeValue.toInt() + endY = points.getNamedItem("endY").nodeValue.toInt() + } catch (e: NumberFormatException) { + return null + } + val line = Line((startY - endY).toDouble(), (endX - startX).toDouble(), (startX * endY - startY * endX).toDouble()) + return EmulatedWall(line, startX, endX, startY, endY) + } + } +} \ No newline at end of file diff --git a/server/src/main/java/objects/emulator/ListenableFutureImpl.kt b/server/src/main/java/objects/emulator/ListenableFutureImpl.kt new file mode 100644 index 00000000000..e75bba54a45 --- /dev/null +++ b/server/src/main/java/objects/emulator/ListenableFutureImpl.kt @@ -0,0 +1,54 @@ +package objects.emulator + +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import org.asynchttpclient.ListenableFuture +import org.asynchttpclient.Response +import org.asynchttpclient.netty.EagerResponseBodyPart +import org.asynchttpclient.netty.NettyResponse +import java.util.concurrent.CompletableFuture +import java.util.concurrent.Executor +import java.util.concurrent.TimeUnit + +class ListenableFutureImpl(bytes: ByteArray) : ListenableFuture { + + val response = NettyResponse(null, null, listOf(EagerResponseBodyPart(Unpooled.copiedBuffer(bytes), true))) + + override fun done() { + + } + + override fun cancel(p0: Boolean): Boolean { + return false + } + + override fun touch() { + } + + override fun get(): Response { + return response + } + + override fun get(p0: Long, p1: TimeUnit): Response { + return response + } + + override fun addListener(listener: Runnable?, exec: Executor?): ListenableFuture { + return this + } + + override fun abort(t: Throwable?) { + } + + override fun isDone(): Boolean { + return true + } + + override fun toCompletableFuture(): CompletableFuture { + throw UnsupportedOperationException("not implemented") + } + + override fun isCancelled(): Boolean { + return false + } +} \ No newline at end of file diff --git a/server/src/main/java/objects/emulator/Rng.kt b/server/src/main/java/objects/emulator/Rng.kt new file mode 100644 index 00000000000..ab181a17381 --- /dev/null +++ b/server/src/main/java/objects/emulator/Rng.kt @@ -0,0 +1,28 @@ +package objects.emulator + +class Rng(seed: Long) { + var curState = seed + val a = 1664525L + val c = 1013904223L + val mod = 2147483648L + + fun abs(value: Long): Long { + if (value < 0) + return -value + return value + } + + fun nextInt(): Int { + val res = curState + curState = abs(a * curState + c) % mod + return (res % mod).toInt() + } + + fun nextInt(min_val: Int, max_val: Int): Int { + val rand = nextInt() + val size = max_val - min_val + 1 + val randInRange = rand % size + val res = randInRange + min_val + return res + } +} \ No newline at end of file diff --git a/server/src/main/java/roomScanner/CarController.kt b/server/src/main/java/roomScanner/CarController.kt index db39b840645..acedf355022 100644 --- a/server/src/main/java/roomScanner/CarController.kt +++ b/server/src/main/java/roomScanner/CarController.kt @@ -5,9 +5,9 @@ import RouteMetricRequest import SonarRequest import SonarResponse import net.car.client.Client -import objects.Car +import objects.CarReal -class CarController(var car: Car) { +class CarController(var car: CarReal) { enum class Direction(val id: Int) { FORWARD(0), BACKWARD(1), diff --git a/server/src/main/java/roomScanner/RoomScanner.kt b/server/src/main/java/roomScanner/RoomScanner.kt index e4e1fc53200..13f5910c258 100644 --- a/server/src/main/java/roomScanner/RoomScanner.kt +++ b/server/src/main/java/roomScanner/RoomScanner.kt @@ -6,7 +6,7 @@ class RoomScanner(val controller: CarController) : Thread() { private val GHOST_LEVEL = 50 override fun run() { - println("Car connected ${controller.car.carConnection.host}") + println("CarReal connected ${controller.car.carConnection.host}") for (i in 1..100) { step() println(plot(points))