From befa5c560795978c075dfe583b0a8e4ed41a2078 Mon Sep 17 00:00:00 2001 From: MaximZaitsev Date: Wed, 27 Jul 2016 16:56:44 +0300 Subject: [PATCH] created kotlin srv, car emulator, car control, coordinate calculate --- car_srv/kotlinSrv/src/Car.kt | 80 +++++++++++++++++++ car_srv/kotlinSrv/src/Main.kt | 38 +++++++++ car_srv/kotlinSrv/src/Udev.kt | 5 ++ car_srv/kotlinSrv/src/carControl/Control.kt | 17 ++++ .../kotlinSrv/src/carControl/ControlImpl.kt | 63 +++++++++++++++ .../kotlinSrv/src/carControl/RouteExecutor.kt | 12 +++ .../src/carControl/RouteExecutorImpl.kt | 55 +++++++++++++ car_srv/kotlinSrv/src/main.kt | 11 --- car_srv/kotlinSrv/src/server/Server.kt | 46 +++++++++++ .../src/server/handlers/AbstractHandler.kt | 40 ++++++++++ .../src/server/handlers/flash/LoadBin.kt | 20 +++++ .../src/server/handlers/rc/Connect.kt | 7 ++ .../src/server/handlers/rc/Control.kt | 40 ++++++++++ .../src/server/handlers/rc/Disconnect.kt | 8 ++ .../src/server/handlers/rc/Heartbeat.kt | 8 ++ 15 files changed, 439 insertions(+), 11 deletions(-) create mode 100644 car_srv/kotlinSrv/src/Car.kt create mode 100644 car_srv/kotlinSrv/src/Main.kt create mode 100644 car_srv/kotlinSrv/src/Udev.kt create mode 100644 car_srv/kotlinSrv/src/carControl/Control.kt create mode 100644 car_srv/kotlinSrv/src/carControl/ControlImpl.kt create mode 100644 car_srv/kotlinSrv/src/carControl/RouteExecutor.kt create mode 100644 car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt delete mode 100644 car_srv/kotlinSrv/src/main.kt create mode 100644 car_srv/kotlinSrv/src/server/Server.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/AbstractHandler.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/flash/LoadBin.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/rc/Connect.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/rc/Control.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/rc/Disconnect.kt create mode 100644 car_srv/kotlinSrv/src/server/handlers/rc/Heartbeat.kt diff --git a/car_srv/kotlinSrv/src/Car.kt b/car_srv/kotlinSrv/src/Car.kt new file mode 100644 index 00000000000..bbd9dd08808 --- /dev/null +++ b/car_srv/kotlinSrv/src/Car.kt @@ -0,0 +1,80 @@ +import carControl.Control +import carControl.RouteExecutor +import carControl.RouteExecutorImpl.MoveDirection + +/** + * Created by user on 7/27/16. + */ +class Car constructor(routeExecutor: RouteExecutor, controller: Control) { + + + val velocityMove = 0.1 + val velocityRotation = 5.0 + + //position + var x: Double + var y: Double + var angle: Double + + var moveDirection: MoveDirection = MoveDirection.STOP + var startMoveOn: Int = 0 + + + val routeExecutor: RouteExecutor + val controller: Control + + init { + this.routeExecutor = routeExecutor + this.controller = controller + this.x = 0.0 + this.y = 0.0 + this.angle = 0.0 + } + + fun refreshLocation(delta: Int) { + val deltaSeconds = delta.toDouble() / 1000 + when (moveDirection) { + MoveDirection.FORWARD -> { + this.x += this.velocityMove * deltaSeconds * Math.cos(this.angle * Math.PI / 180); + this.y += this.velocityMove * deltaSeconds * Math.sin(this.angle * Math.PI / 180); + } + MoveDirection.BACKWARD -> { + this.x -= this.velocityMove * deltaSeconds * Math.cos(this.angle * Math.PI / 180); + this.y -= this.velocityMove * deltaSeconds * Math.sin(this.angle * Math.PI / 180); + } + MoveDirection.LEFT -> this.angle += velocityRotation * deltaSeconds + MoveDirection.RIGHT -> this.angle -= velocityRotation * deltaSeconds + else -> { + + } + } + println("x=$x; y=$y; angle=$angle") + } + + fun routeDone() { + controller.stopCar() + } + + fun move(moveDirection: MoveDirection, value: Double, callBack: () -> Unit) { + //value - angle for rotation command and distance for forward/backward command + this.moveDirection = moveDirection + when (moveDirection) { + MoveDirection.STOP -> controller.stopCar() + MoveDirection.FORWARD -> controller.moveCarForward() + MoveDirection.BACKWARD -> controller.moveCarBackward() + MoveDirection.LEFT -> controller.moveCarLeft() + MoveDirection.RIGHT -> controller.moveCarRight() + } + if (moveDirection != MoveDirection.STOP) { + if (moveDirection == MoveDirection.FORWARD || moveDirection == MoveDirection.BACKWARD) { + controller.delay(getTimeForMoving(value, velocityMove), callBack) + } else { + controller.delay(getTimeForMoving(value, velocityMove), callBack) + } + } + } + + fun getTimeForMoving(value: Double, velocity: Double): Int { + return 1000 * (Math.abs(value) * velocity).toInt() + } +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/Main.kt b/car_srv/kotlinSrv/src/Main.kt new file mode 100644 index 00000000000..75bfd9611ae --- /dev/null +++ b/car_srv/kotlinSrv/src/Main.kt @@ -0,0 +1,38 @@ +import carControl.ControlImpl +import carControl.RouteExecutorImpl +import server.Server +import server.handlers.AbstractHandler +import server.handlers.flash.LoadBin +import server.handlers.rc.Control + +/** + * Created by user on 7/26/16. + */ + +var transportFilePath: String = "./test"//todo init on start after start udev +val thisCar = Car(RouteExecutorImpl(), ControlImpl()) +val deltaTimeLocationRefresh: Int = 100//ms + +fun main(args: Array) { + + val protoBuf = require("protobufjs") + val controlConstructor = protoBuf.loadProtoFile("./proto/" + "direction.proto").build("carkot") + val handlers: MutableMap = mutableMapOf() + handlers.put("/control", Control(controlConstructor.DirectionRequest, controlConstructor.DirectionResponse)) + + val srv = Server(handlers) + srv.start() + + + setInterval({ thisCar.refreshLocation(deltaTimeLocationRefresh) }, deltaTimeLocationRefresh); +} + +@native +fun require(name: String): dynamic { + return null +} + +@native +fun setInterval(callBack: () -> Unit, ms: Int) { + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/Udev.kt b/car_srv/kotlinSrv/src/Udev.kt new file mode 100644 index 00000000000..72c176987a7 --- /dev/null +++ b/car_srv/kotlinSrv/src/Udev.kt @@ -0,0 +1,5 @@ +/** + * Created by user on 7/27/16. + */ +class Udev { +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/Control.kt b/car_srv/kotlinSrv/src/carControl/Control.kt new file mode 100644 index 00000000000..87db626b71c --- /dev/null +++ b/car_srv/kotlinSrv/src/carControl/Control.kt @@ -0,0 +1,17 @@ +package carControl + +/** + * Created by user on 7/27/16. + */ +interface Control { + + fun moveCarLeft() + fun moveCarRight() + fun moveCarForward() + fun moveCarBackward() + + fun stopCar() + + fun delay(ms: Int, callBack:()->Unit) + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/ControlImpl.kt b/car_srv/kotlinSrv/src/carControl/ControlImpl.kt new file mode 100644 index 00000000000..c896ea06069 --- /dev/null +++ b/car_srv/kotlinSrv/src/carControl/ControlImpl.kt @@ -0,0 +1,63 @@ +package carControl + +import require +import transportFilePath + + +/** + * Created by user on 7/27/16. + */ +class ControlImpl : Control { + + val fs: dynamic; + + init { + this.fs = require("fs") + } + + override fun moveCarLeft() { + println("move left") + writeToFile(4) + } + + override fun moveCarRight() { + println("move rigth") + writeToFile(3) + } + + override fun moveCarForward() { + println("move forward") + writeToFile(1) + } + + override fun moveCarBackward() { + println("move backward") + writeToFile(2) + } + + override fun stopCar() { + println("stopped") + writeToFile(0) + } + + override fun delay(ms: Int, callBack: () -> Unit) { + setTimeOut(callBack, ms) + } + + @native + fun setTimeOut(callBack: () -> Unit, ms: Int) { + + } + + + fun writeToFile(byte: Byte) { + fs.appendFile(transportFilePath, byte.toString(), "binary", { err -> + if (err) { + println("error") + } else { + println("ok") + } + }) + } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/RouteExecutor.kt b/car_srv/kotlinSrv/src/carControl/RouteExecutor.kt new file mode 100644 index 00000000000..954c6a264b8 --- /dev/null +++ b/car_srv/kotlinSrv/src/carControl/RouteExecutor.kt @@ -0,0 +1,12 @@ +package carControl + +import Car + +/** + * Created by user on 7/27/16. + */ +interface RouteExecutor { + + fun executeRoute(route: dynamic) + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt b/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt new file mode 100644 index 00000000000..1fe457d707f --- /dev/null +++ b/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt @@ -0,0 +1,55 @@ +package carControl + +import thisCar + +/** + * Created by user on 7/27/16. + */ +class RouteExecutorImpl : RouteExecutor { + + enum class MoveDirection { + LEFT, + RIGHT, + FORWARD, + BACKWARD, + STOP + } + + override fun executeRoute(route: dynamic) { + val wayPoints = route.way_points + val commands: MutableList> = mutableListOf() + for (wayPoint in wayPoints) { + val angle: Double = wayPoint.angle_delta + val distance: Double = wayPoint.distance + if (angle != 0.0) { + val command = if (angle > 180) { + MoveDirection.RIGHT + } else { + MoveDirection.LEFT + } + commands.add(Pair(command, angle)) + } + if (distance != 0.0) { + val command = if (distance > 0) { + MoveDirection.FORWARD + } else { + MoveDirection.BACKWARD + } + commands.add(Pair(command, distance)) + } + } + commands.add(Pair(MoveDirection.STOP, 0.0)) + executeCommand(commands, 0) + } + + fun executeCommand(commands: List>, currentCommandIdx: Int) { + if (currentCommandIdx == commands.size) { + thisCar.routeDone() + } + val currentCommand = commands.get(currentCommandIdx) + thisCar.move(currentCommand.first, currentCommand.second, { + executeCommand(commands, currentCommandIdx + 1) + }) + } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/main.kt b/car_srv/kotlinSrv/src/main.kt deleted file mode 100644 index 67774548219..00000000000 --- a/car_srv/kotlinSrv/src/main.kt +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Created by user on 7/26/16. - */ -fun main(args: Array) { - println("hallo!") -} - -@native -fun require(name:String) { - -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/Server.kt b/car_srv/kotlinSrv/src/server/Server.kt new file mode 100644 index 00000000000..17084777afc --- /dev/null +++ b/car_srv/kotlinSrv/src/server/Server.kt @@ -0,0 +1,46 @@ +package server + + +import require +import server.handlers.AbstractHandler + +/** + * Created by user on 7/27/16. + */ +class Server(handlers: MutableMap) { + + val http: dynamic + val url: dynamic + val handlers: MutableMap + + init { + http = require("http") + url = require("url") + this.handlers = handlers + } + + + fun start() { + + http.createServer({ request, response -> + val content = mutableListOf() + val urlName = url.parse(request.url).pathname; + val handler = handlers.get(urlName) + request.on("data", { + data -> + for (i in 0..data.length - 1) { + content.add(data[i]) + } + }) + request.on("end", { + if (handler != null) { + handler.execute(content, response) + } else { + //todo write error on incorrect url + response.end() + } + }) + }).listen(8888) + } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/handlers/AbstractHandler.kt b/car_srv/kotlinSrv/src/server/handlers/AbstractHandler.kt new file mode 100644 index 00000000000..69f327a9d5f --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/AbstractHandler.kt @@ -0,0 +1,40 @@ +package server.handlers + +/** + * Created by user on 7/27/16. + */ +abstract class AbstractHandler(protoDecoder: dynamic, protoEncoder: dynamic) { + + val protoDecoder: dynamic + val protoEncoder: dynamic + + init { + this.protoDecoder = protoDecoder + this.protoEncoder = protoEncoder + } + + + fun execute(data: List, response: dynamic) { + + val message = protoDecoder.decode(data.toByteArray()) + val resultMessage: dynamic = {} + js("resultMessage = {}")//todo bad? + val afterExecute: () -> Unit = { + val protoEn = this.protoEncoder//temporarily:) + val resultMsg = resultMessage + val resultObject = js("new protoEn(resultMsg)") + + val resultBuffer = resultObject.encode() + val byteArray = ByteArray(resultBuffer.limit); + for (i in 0..resultBuffer.limit - 1) { + byteArray[i] = resultBuffer.buffer[i] + } + response.write(js("new Buffer(byteArray)")) + response.end() + } + makeResult(message, resultMessage, afterExecute) + } + + abstract fun makeResult(message: dynamic, resultMessage: dynamic, finalCallback: () -> Unit) + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/handlers/flash/LoadBin.kt b/car_srv/kotlinSrv/src/server/handlers/flash/LoadBin.kt new file mode 100644 index 00000000000..577fcece933 --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/flash/LoadBin.kt @@ -0,0 +1,20 @@ +package server.handlers.flash + +import server.handlers.AbstractHandler +import require + +/** + * Created by user on 7/27/16. + */ +class LoadBin : AbstractHandler { + + val fs: dynamic + + constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) { + this.fs = require("fs") + } + + override fun makeResult(message: dynamic, resultList: dynamic, finalCallback: () -> Unit) { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} diff --git a/car_srv/kotlinSrv/src/server/handlers/rc/Connect.kt b/car_srv/kotlinSrv/src/server/handlers/rc/Connect.kt new file mode 100644 index 00000000000..71cde01438e --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/rc/Connect.kt @@ -0,0 +1,7 @@ +package server.handlers.rc + +/** + * Created by user on 7/27/16. + */ +class Connect { +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/handlers/rc/Control.kt b/car_srv/kotlinSrv/src/server/handlers/rc/Control.kt new file mode 100644 index 00000000000..14fdc14c247 --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/rc/Control.kt @@ -0,0 +1,40 @@ +package server.handlers.rc + +import carControl.RouteExecutorImpl +import server.handlers.AbstractHandler +import thisCar +import carControl.RouteExecutorImpl.MoveDirection + +/** + * Created by user on 7/27/16. + */ +class Control : AbstractHandler { + + constructor(protoDecoder: dynamic, protoEncoder: dynamic) : super(protoDecoder, protoEncoder) + + override fun makeResult(message: dynamic, resultMessage: dynamic, finalCallback: () -> Unit) { + val commandNumber = message.command + resultMessage.code = 0 + resultMessage.errorMsg = "" + val command = when (commandNumber) { + protoDecoder.Command.stop -> { + MoveDirection.STOP + } + protoDecoder.Command.forward -> { + MoveDirection.FORWARD + } + protoDecoder.Command.backward -> { + MoveDirection.BACKWARD + } + protoDecoder.Command.right -> { + MoveDirection.RIGHT + } + protoDecoder.Command.left -> { + MoveDirection.LEFT + } + else -> MoveDirection.STOP + } + thisCar.move(command, 0.0, {}) + finalCallback.invoke() + } +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/handlers/rc/Disconnect.kt b/car_srv/kotlinSrv/src/server/handlers/rc/Disconnect.kt new file mode 100644 index 00000000000..7f8d7bf43e3 --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/rc/Disconnect.kt @@ -0,0 +1,8 @@ +package server.handlers.rc + +/** + * Created by user on 7/27/16. + */ +class Disconnect { + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/server/handlers/rc/Heartbeat.kt b/car_srv/kotlinSrv/src/server/handlers/rc/Heartbeat.kt new file mode 100644 index 00000000000..e66d9af048b --- /dev/null +++ b/car_srv/kotlinSrv/src/server/handlers/rc/Heartbeat.kt @@ -0,0 +1,8 @@ +package server.handlers.rc + +/** + * Created by user on 7/27/16. + */ +class Heartbeat { + +} \ No newline at end of file