diff --git a/car_srv/kotlinSrv/README.md b/car_srv/kotlinSrv/README.md index b21f14c64da..d7954f447a0 100644 --- a/car_srv/kotlinSrv/README.md +++ b/car_srv/kotlinSrv/README.md @@ -1,24 +1,8 @@ # Car server -## Building - -move to this directory - - $ ./build.sh - -This command run gradle build and execute *npm install* for downloading used js modules. - -## Run car server - -for run server you can use script - - $ ./run.sh - ## Deploying car server -*note:* This feature is under development - -*note:* this script use expect script languane. You have to install it +*note:* this script use expect script language. You have to install it for install expect on ubuntu @@ -31,3 +15,27 @@ for deploy server on car use where: {ip_addr} - ip address of raspberry. {user_name} and {password} - user name and password for login on raspberry + + +## Config file + +on root of compile files (~/server/ after deploy or ./build/js/) you can create +config file config.cfg. options write as key:value. +all available options. here value - its default value +mainServerIp:127.0.0.1 +thisServerIp:127.0.0.1 + + +## Building and run (for start on local computer) + +move to this directory + + $ ./build.sh + +This command run gradle build and execute *npm install* for downloading used js modules. + +for run server you can use script + + $ ./run.sh + + diff --git a/car_srv/kotlinSrv/build.gradle b/car_srv/kotlinSrv/build.gradle index 9c7a13f0899..2c9746fc79e 100644 --- a/car_srv/kotlinSrv/build.gradle +++ b/car_srv/kotlinSrv/build.gradle @@ -25,26 +25,16 @@ sourceSets { } task copyKotlinLib(type: Copy) { - from "${projectDir}/helpers/kotlin.js" - from "${projectDir}/helpers/package.json" + from "${projectDir}/kotlinJsRequiredFiles/kotlin.js" + from "${projectDir}/kotlinJsRequiredFiles/package.json" into "${projectDir}/build/js" } -task copyProtoFiles(type: Copy) { - - from "${projectDir}/../../proto/carkot.proto" - from "${projectDir}/../../proto/server_car/" - - into "${projectDir}/build/js/proto" -} - - build.dependsOn copyKotlinLib -build.dependsOn copyProtoFiles compileKotlin2Js.kotlinOptions.outputFile = "${projectDir}/build/js/main.js" -compileKotlin2Js.kotlinOptions.outputPrefix = "${projectDir}/helpers/prefix.js" +compileKotlin2Js.kotlinOptions.outputPrefix = "${projectDir}/kotlinJsRequiredFiles/connectKotlinLib.js" dependencies { compile "org.jetbrains.kotlin:kotlin-js-library:$kotlin_version" diff --git a/car_srv/kotlinSrv/deploy.sh b/car_srv/kotlinSrv/deploy.sh index b12b3e9df7a..ff5d3e619a7 100755 --- a/car_srv/kotlinSrv/deploy.sh +++ b/car_srv/kotlinSrv/deploy.sh @@ -1,7 +1,5 @@ #!/usr/bin/expect -# XXX this script works super slow on eugene's machine - set host "" set userName "pi" set password "111" diff --git a/car_srv/kotlinSrv/package.json b/car_srv/kotlinSrv/package.json new file mode 100644 index 00000000000..a97f563a17d --- /dev/null +++ b/car_srv/kotlinSrv/package.json @@ -0,0 +1,17 @@ +{ + "name": "CarServer", + "version": "1.0.0", + "description": "", + "main": "main.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node main.js" + }, + "author": "maxim", + "license": "ISC", + "devDependencies": { + "udev": "^0.3.0", + "commander": "^2.9.0", + "protobufjs": "^5.0.1" + } +} diff --git a/car_srv/kotlinSrv/run.sh b/car_srv/kotlinSrv/run.sh index e034474f354..a7fadf55606 100755 --- a/car_srv/kotlinSrv/run.sh +++ b/car_srv/kotlinSrv/run.sh @@ -1,5 +1,3 @@ #!/bin/bash -# TODO main server ip address should be read from configuration file that is -# not overwritten during deploy. cd build/js node main.js diff --git a/car_srv/kotlinSrv/src/Car.kt b/car_srv/kotlinSrv/src/Car.kt deleted file mode 100644 index 4498dd987ce..00000000000 --- a/car_srv/kotlinSrv/src/Car.kt +++ /dev/null @@ -1,78 +0,0 @@ -import carControl.Control -import carControl.RouteExecutor -import carControl.RouteExecutorImpl.MoveDirection - -private val MOVE_VELOCITY = 0.3278 -private val ROTATION_VELOCITY = 12.3 - -// TODO make Car class mutable state saving entity -// that almost doesn't have behavior -/** - * Created by user on 7/27/16. - */ -class Car constructor(val routeExecutor: RouteExecutor, val controller: Control) { - //position - var x: Double - var y: Double - var angle: Double - - var moveDirection: MoveDirection = MoveDirection.STOP - - - init { - this.x = 0.0 - this.y = 0.0 - this.angle = 0.0 - } - - fun stopCar() { - move(MoveDirection.STOP, 0, {}) - } - - fun refreshLocation(delta: Int) { - val deltaSeconds = delta.toDouble() / 1000 - when (moveDirection) { - MoveDirection.FORWARD -> { - this.x += MOVE_VELOCITY * deltaSeconds * Math.cos(this.angle * Math.PI / 180); - this.y += MOVE_VELOCITY * deltaSeconds * Math.sin(this.angle * Math.PI / 180); - } - MoveDirection.BACKWARD -> { - this.x -= MOVE_VELOCITY * deltaSeconds * Math.cos(this.angle * Math.PI / 180); - this.y -= MOVE_VELOCITY * deltaSeconds * Math.sin(this.angle * Math.PI / 180); - } - MoveDirection.LEFT -> this.angle += ROTATION_VELOCITY * deltaSeconds - MoveDirection.RIGHT -> this.angle -= ROTATION_VELOCITY * deltaSeconds - else -> { - - } - } -// println("x=$x; y=$y; angle=$angle") - } - - fun routeDone() { - controller.stopCar() - } - - fun move(moveDirection: MoveDirection, value: Int, 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, MOVE_VELOCITY), callBack) - } else { - controller.delay(getTimeForMoving(value, ROTATION_VELOCITY), callBack) - } - } - } - - fun getTimeForMoving(value: Int, velocity: Double): Int { - return (1000 * Math.abs(value.toDouble()) / velocity).toInt() - } -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/CarState.kt b/car_srv/kotlinSrv/src/CarState.kt new file mode 100644 index 00000000000..1cc8e1bace2 --- /dev/null +++ b/car_srv/kotlinSrv/src/CarState.kt @@ -0,0 +1,27 @@ +import control.RouteExecutor +import control.emulator.RouteExecutorImpl.MoveDirection + +private val MOVE_VELOCITY = 0.3278 +private val ROTATION_VELOCITY = 12.3 + +// TODO make Car class mutable state saving entity +// that almost doesn't have behavior +/** + * Created by user on 7/27/16. + */ +class CarState private constructor() { + //position + var x: Double + var y: Double + var angle: Double + + init { + this.x = 0.0 + this.y = 0.0 + this.angle = 0.0 + } + + companion object { + val instance = CarState() + } +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/Config.kt b/car_srv/kotlinSrv/src/Config.kt index 72f6a57d4fb..48b9f9b70e3 100644 --- a/car_srv/kotlinSrv/src/Config.kt +++ b/car_srv/kotlinSrv/src/Config.kt @@ -1,14 +1,23 @@ /** * Created by user on 8/16/16. */ -class Config(val configFileName: String) { +class Config(val configFileName: String = "config.cfg") { private var serverIp = "127.0.0.1" private var thisCarIp = "127.0.0.1" fun loadConfig(): Boolean { + + try { + fs.accessSync(configFileName, fs.F_OK); + } catch (e: dynamic) { + // create it + fs.openSync(configFileName, "w") + } + val data: String = fs.readFileSync(configFileName, "utf8") + println("reader $data") data.split("\n").forEach { line -> val keyValue = line.split(":") if (!line.equals("")) { @@ -16,9 +25,10 @@ class Config(val configFileName: String) { return false } + println(keyValue.toString()) when (keyValue[0]) { - "ip" -> serverIp = keyValue[1] - "thisIp" -> thisCarIp = keyValue[1] + "mainServerIp" -> serverIp = keyValue[1] + "thisServerIp" -> thisCarIp = keyValue[1] } } } diff --git a/car_srv/kotlinSrv/src/JSImport.kt b/car_srv/kotlinSrv/src/JSImport.kt new file mode 100644 index 00000000000..9f4848f51b2 --- /dev/null +++ b/car_srv/kotlinSrv/src/JSImport.kt @@ -0,0 +1,20 @@ +/** + * Created by user on 8/18/16. + */ + +@native +fun require(name: String): dynamic = noImpl + +@native +fun setInterval(callBack: () -> Unit, ms: Int): dynamic = noImpl + +@native +fun setTimeout(callBack: () -> Unit, ms: Int): dynamic = noImpl + +fun encodeProtoBuf(protoMessage: dynamic): ByteArray { + val protoSize = protoMessage.getSizeNoTag() + val routeBytes = ByteArray(protoSize) + + protoMessage.writeTo(CodedOutputStream(routeBytes)) + return routeBytes +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/MCConnectObservable.kt b/car_srv/kotlinSrv/src/MCConnectObservable.kt new file mode 100644 index 00000000000..db9c4308321 --- /dev/null +++ b/car_srv/kotlinSrv/src/MCConnectObservable.kt @@ -0,0 +1,9 @@ +/** + * Created by user on 8/18/16. + */ +interface MCConnectObservable { + + fun addObserver(MCConnectObserver: MCConnectObserver) + fun removeObserver(MCConnectObserver: MCConnectObserver) + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/MCConnectObserver.kt b/car_srv/kotlinSrv/src/MCConnectObserver.kt new file mode 100644 index 00000000000..12e07fc0e2e --- /dev/null +++ b/car_srv/kotlinSrv/src/MCConnectObserver.kt @@ -0,0 +1,9 @@ +/** + * Created by user on 8/18/16. + */ +interface MCConnectObserver { + + fun connect(vararg params: V) + fun disconnect() + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/McTransport.kt b/car_srv/kotlinSrv/src/MCConnection.kt similarity index 99% rename from car_srv/kotlinSrv/src/McTransport.kt rename to car_srv/kotlinSrv/src/MCConnection.kt index 4a2ba26fc5c..e264eea6cd0 100644 --- a/car_srv/kotlinSrv/src/McTransport.kt +++ b/car_srv/kotlinSrv/src/MCConnection.kt @@ -79,7 +79,6 @@ class McTransport() { result += bytes[0].toInt().shl(24) return result } - } private val protoHeaderLength: Int = 4 diff --git a/car_srv/kotlinSrv/src/Main.kt b/car_srv/kotlinSrv/src/Main.kt index 4986ff5710d..601c572f9d1 100644 --- a/car_srv/kotlinSrv/src/Main.kt +++ b/car_srv/kotlinSrv/src/Main.kt @@ -1,23 +1,21 @@ +import control.car.RouteExecutorToUsb import net.server.handlers.AbstractHandler import net.server.handlers.debug.Memory import net.server.handlers.flash.LoadBin import net.server.handlers.main.GetLocation import net.server.handlers.main.SetRoute -import net.server.handlers.rc.Connect import net.server.handlers.rc.Control -import net.server.handlers.rc.Disconnect -import net.server.handlers.rc.Heartbeat /** * Created by user on 7/26/16. */ -val deltaTimeLocationRefresh: Int = 100//ms +val deltaTimeLocationRefresh: Int = 100 val carServerPort: Int = 8888 val mainServerPort = 7925 -val config = Config("config.cfg") +val config = Config() val fs = require("fs") fun main(args: Array) { if (!config.loadConfig()) { @@ -26,42 +24,18 @@ fun main(args: Array) { } val handlers: MutableMap = mutableMapOf() - // TODO remove injection of all internal builders from here - handlers.put("/rc/control", Control(DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.fromIntToCommand(0), 0), DirectionResponse.BuilderDirectionResponse(0))) - handlers.put("/rc/connect", Connect(SessionUpResponse.BuilderSessionUpResponse(0, 0))) - handlers.put("/rc/disconnect", Disconnect(SessionDownRequest.BuilderSessionDownRequest(0), SessionDownResponse.BuilderSessionDownResponse(0))) - handlers.put("/rc/heartbeat", Heartbeat(HeartBeatRequest.BuilderHeartBeatRequest(0), HeartBeatResponse.BuilderHeartBeatResponse(0))) - - handlers.put("/loadBin", LoadBin(Upload.BuilderUpload(ByteArray(0)), UploadResult.BuilderUploadResult(0))) - - handlers.put("/route", SetRoute(RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)), RouteResponse.BuilderRouteResponse(0))) - handlers.put("/getLocation", GetLocation(LocationResponse.BuilderLocationResponse(LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build(), 0))) - + val routeExecutor = RouteExecutorToUsb() + handlers.put("/rc/control", Control()) + handlers.put("/loadBin", LoadBin()) + handlers.put("/route", SetRoute(routeExecutor)) + handlers.put("/getLocation", GetLocation()) handlers.put("/debug/memoty", Memory()) net.server.start(handlers, carServerPort) - val udev = Udev() - udev.start() + val mcConditionMonitor = McConditionMonitor.instance + mcConditionMonitor.start() MicroController.instance.start() -} - -// TODO move this dump of arbitrary functions that don't have any relation to -// to Main.kt from Main.kt - -fun encodeProtoBuf(protoMessage: dynamic): ByteArray { - val protoSize = protoMessage.getSizeNoTag() - val routeBytes = ByteArray(protoSize) - - protoMessage.writeTo(CodedOutputStream(routeBytes)) - return routeBytes -} - -@native -fun require(name: String): dynamic = noImpl -@native -fun setInterval(callBack: () -> Unit, ms: Int) : dynamic = noImpl -@native -fun setTimeout(callBack: () -> Unit, ms: Int) : dynamic = noImpl \ No newline at end of file +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/McConditionMonitor.kt b/car_srv/kotlinSrv/src/McConditionMonitor.kt new file mode 100644 index 00000000000..1da22a83f9b --- /dev/null +++ b/car_srv/kotlinSrv/src/McConditionMonitor.kt @@ -0,0 +1,83 @@ +/** + * Created by user on 7/27/16. + * observable class, check mc condition and notify observers about changes + */ +class McConditionMonitor private constructor() : MCConnectObservable { + + private val udev: dynamic = require("udev") + private val exec: dynamic = require("child_process").execSync + private val observersList: MutableList> = arrayListOf() + + fun start() { + val monitor = udev.monitor() + monitor.on("add", { device -> + if (isOurMcDevice(device)) { + connectDevice(device) + } + }) + + monitor.on("remove", { device -> + if (isOurMcDevice(device)) { + disconnectDevice() + } + }) + + readFileIfMcConnected() + } + + override fun addObserver(MCConnectObserver: MCConnectObserver) { + observersList.add(MCConnectObserver) + } + + override fun removeObserver(MCConnectObserver: MCConnectObserver) { + observersList.remove(MCConnectObserver) + } + + private fun notifyMCConnect(nodeName: String) { + for (observer in observersList) { + observer.connect(nodeName) + } + } + + private fun notifyMCDisconnect() { + for (observer in observersList) { + observer.disconnect() + } + } + + private fun isOurMcDevice(device: dynamic): Boolean { + val microController = MicroController.instance + return (device.ID_VENDOR_ID == microController.vendorID) + && (device.ID_MODEL_ID == microController.modelID) + && (device.SUBSYSTEM == "tty") + } + + private fun disconnectDevice() { + println("mc disconnected") + notifyMCDisconnect() + } + + private fun connectDevice(device: dynamic) { + val transportFile: String = device.DEVNAME + mcTransport.initStreams(transportFile) + McState.instance.connect() + println("mc connected. transport file is " + transportFile) + exec("stty -F $transportFile raw -echo -echoe -echok") + notifyMCConnect(transportFile) + } + + private fun readFileIfMcConnected() { + val allTtyDevices = udev.list("tty") + for (device in allTtyDevices) { + if (isOurMcDevice(device)) { + connectDevice(device) + break + } + } + } + + companion object { + val instance = McConditionMonitor() + } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/McState.kt b/car_srv/kotlinSrv/src/McState.kt new file mode 100644 index 00000000000..d2887a6355f --- /dev/null +++ b/car_srv/kotlinSrv/src/McState.kt @@ -0,0 +1,23 @@ +/** + * Created by user on 8/18/16. + */ +class McState { + + + private var connected = false + + + fun isConnected(): Boolean { + return connected + } + + fun connect() { + this.connected = true + } + + + companion object { + val instance = McState() + } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/MicroController.kt b/car_srv/kotlinSrv/src/MicroController.kt index ef58b0672e1..624a9e1b1a0 100644 --- a/car_srv/kotlinSrv/src/MicroController.kt +++ b/car_srv/kotlinSrv/src/MicroController.kt @@ -1,7 +1,7 @@ -import carControl.ControlImpl -import carControl.RouteExecutorImpl -import carControl.RouteExecutorToUsb +import control.emulator.RouteExecutorImpl +import control.car.RouteExecutorToUsb import exceptions.RcControlException +import kotlin.js.Date /** * Created by user on 7/28/16. @@ -17,7 +17,7 @@ class MicroController private constructor() { val modelID: String var transportFilePath: String - val car: Car + val car: CarState init { this.rcSid = 0 @@ -27,7 +27,8 @@ class MicroController private constructor() { this.modelID = "5740" this.transportFilePath = "" - this.car = Car(RouteExecutorToUsb(), ControlImpl()) + + this.car = CarState.instance } fun start() { @@ -38,65 +39,11 @@ class MicroController private constructor() { println("read: " + bytes.toString()) } - setInterval({ this.car.refreshLocation(deltaTimeLocationRefresh) }, deltaTimeLocationRefresh); - setInterval({ - if (needDropRC()) { - dropRC() - } - }, 500) - } - - fun dropRC() { - this.rcSid = 0 - car.stopCar() - } - - fun disconnectRC(sid: Int) { - if (sid != rcSid) { - throw RcControlException() - } - dropRC() - } - - fun RcMove(command: RouteExecutorImpl.MoveDirection, sid: Int) { - if (sid != this.rcSid) { - throw RcControlException() - } - car.move(command, 0, {}) - rcHeartBeat(sid) - } - - fun needDropRC(): Boolean { - return Date().getTime() > (rcLastRequest + 1000) && controlledByRC() - } - - fun connectRC(): Int { - if (controlledByRC()) { - throw RcControlException() - } - val sid = (Math.random() * 100000).toInt() - this.rcSid = sid - rcHeartBeat(sid) - return sid - } - - fun controlledByRC(): Boolean { - return (rcSid != 0) - } - - fun isConnected(): Boolean { - return transportFilePath != "" - } - - fun rcHeartBeat(sid: Int) { - if (sid != this.rcSid) { - throw RcControlException() - } - rcLastRequest = Date().getTime() +// setInterval({ this.car.refreshLocation(deltaTimeLocationRefresh) }, deltaTimeLocationRefresh); } fun connectToServer(thisIp: String, thisPort: Int) { - val requestObject = ConnectionRequest.BuilderConnectionRequest(config.getCarIp().split(".").map { str -> parseInt(str, 10) }.toIntArray(), carServerPort).build() + val requestObject = ConnectionRequest.BuilderConnectionRequest(thisIp.split(".").map { str -> parseInt(str, 10) }.toIntArray(), thisPort).build() val bytes = ByteArray(requestObject.getSizeNoTag()) requestObject.writeTo(CodedOutputStream(bytes)) net.sendRequest(js("new Buffer(bytes)"), "/connect", { resultData -> diff --git a/car_srv/kotlinSrv/src/Udev.kt b/car_srv/kotlinSrv/src/Udev.kt deleted file mode 100644 index f5982402ced..00000000000 --- a/car_srv/kotlinSrv/src/Udev.kt +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Created by user on 7/27/16. - */ -class Udev { - - val udev: dynamic - val exec: dynamic - - init { - udev = require("udev") - exec = require("child_process").execSync - } - - fun start() { - val monitor = udev.monitor() - monitor.on("add", { device -> - if (isOurMcDevice(device)) { - connectDevice(device) - } - }) - - monitor.on("remove", { device -> - if (isOurMcDevice(device)) { - disconnectDevice() - } - }) - - readFileIfMcConnected() - } - - fun isOurMcDevice(device: dynamic): Boolean { - val microController = MicroController.instance - return (device.ID_VENDOR_ID == microController.vendorID) - && (device.ID_MODEL_ID == microController.modelID) - && (device.SUBSYSTEM == "tty") - } - - fun disconnectDevice() { - println("mc disconnected") - MicroController.instance.transportFilePath = "" - mcTransport.closeStreams() - } - - fun connectDevice(device: dynamic) { - println("mc connected. transport file is " + device.DEVNAME) - MicroController.instance.transportFilePath = device.DEVNAME; - mcTransport.initStreams(device.DEVNAME) - exec("stty -F ${MicroController.instance.transportFilePath} raw -echo -echoe -echok") - } - - fun readFileIfMcConnected() { - val allTtyDevices = udev.list("tty") - for (device in allTtyDevices) { - if (isOurMcDevice(device)) { - connectDevice(device) - break - } - } - } -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/Control.kt b/car_srv/kotlinSrv/src/carControl/Control.kt deleted file mode 100644 index 87db626b71c..00000000000 --- a/car_srv/kotlinSrv/src/carControl/Control.kt +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index f72d95ba39d..00000000000 --- a/car_srv/kotlinSrv/src/carControl/ControlImpl.kt +++ /dev/null @@ -1,43 +0,0 @@ -package carControl - -import MicroController -import mcTransport -import fs -import setTimeout - - -/** - * Created by user on 7/27/16. - */ -class ControlImpl : Control { - - - override fun moveCarLeft() { - println("move left") - mcTransport.sendBytes(4) - } - - override fun moveCarRight() { - println("move rigth") - mcTransport.sendBytes(3) - } - - override fun moveCarForward() { - println("move forward") - mcTransport.sendBytes(1) - } - - override fun moveCarBackward() { - println("move backward") - mcTransport.sendBytes(2) - } - - override fun stopCar() { - println("stopped") - mcTransport.sendBytes(0) - } - - override fun delay(ms: Int, callBack: () -> Unit) { - setTimeout(callBack, ms) - } -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt b/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt deleted file mode 100644 index c310077f31b..00000000000 --- a/car_srv/kotlinSrv/src/carControl/RouteExecutorImpl.kt +++ /dev/null @@ -1,56 +0,0 @@ -package carControl - -import RouteRequest - -/** - * Created by user on 7/27/16. - */ -class RouteExecutorImpl : RouteExecutor { - - enum class MoveDirection { - LEFT, - RIGHT, - FORWARD, - BACKWARD, - STOP - } - - override fun executeRoute(route: RouteRequest) { - val angles = route.angles - val distances = route.distances - val commands: MutableList> = mutableListOf() - for (i in 0..angles.size - 1) { - val angle: Int = angles[i] - val distance: Int = distances[i] - if (angle != 0) { - val command = if (angle > 180) { - MoveDirection.RIGHT - } else { - MoveDirection.LEFT - } - commands.add(Pair(command, angle)) - } - if (distance != 0) { - val command = if (distance > 0) { - MoveDirection.FORWARD - } else { - MoveDirection.BACKWARD - } - commands.add(Pair(command, distance)) - } - } - commands.add(Pair(MoveDirection.STOP, 0)) - executeCommand(commands, 0) - } - - fun executeCommand(commands: List>, currentCommandIdx: Int) { - if (currentCommandIdx == commands.size) { - MicroController.instance.car.routeDone() - } - val currentCommand = commands.get(currentCommandIdx) - MicroController.instance.car.move(currentCommand.first, currentCommand.second, { - executeCommand(commands, currentCommandIdx + 1) - }) - } - -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/carControl/RouteExecutor.kt b/car_srv/kotlinSrv/src/control/RouteExecutor.kt similarity index 87% rename from car_srv/kotlinSrv/src/carControl/RouteExecutor.kt rename to car_srv/kotlinSrv/src/control/RouteExecutor.kt index ea68eceae7c..01b23ee0a93 100644 --- a/car_srv/kotlinSrv/src/carControl/RouteExecutor.kt +++ b/car_srv/kotlinSrv/src/control/RouteExecutor.kt @@ -1,4 +1,4 @@ -package carControl +package control import RouteRequest diff --git a/car_srv/kotlinSrv/src/carControl/RouteExecutorToUsb.kt b/car_srv/kotlinSrv/src/control/car/RouteExecutorToUsb.kt similarity index 60% rename from car_srv/kotlinSrv/src/carControl/RouteExecutorToUsb.kt rename to car_srv/kotlinSrv/src/control/car/RouteExecutorToUsb.kt index 8dccf3f7e5e..2f75f1e1c09 100644 --- a/car_srv/kotlinSrv/src/carControl/RouteExecutorToUsb.kt +++ b/car_srv/kotlinSrv/src/control/car/RouteExecutorToUsb.kt @@ -1,16 +1,19 @@ -package carControl +package control.car import RouteRequest -import mcTransport -import encodeInt -import decodeInt +import control.RouteExecutor import encodeProtoBuf +import mcTransport +import CodedOutputStream class RouteExecutorToUsb : RouteExecutor { override fun executeRoute(route: RouteRequest) { println("Execute Route:") - val routeBytes = encodeProtoBuf(route) + val protoSize = route.getSizeNoTag() + val routeBytes = ByteArray(protoSize) + + route.writeTo(CodedOutputStream(routeBytes)) mcTransport.setCallBack { bytes -> println("Read $bytes;") diff --git a/car_srv/kotlinSrv/src/control/emulator/RouteExecutorImpl.kt b/car_srv/kotlinSrv/src/control/emulator/RouteExecutorImpl.kt new file mode 100644 index 00000000000..f7df8d962ab --- /dev/null +++ b/car_srv/kotlinSrv/src/control/emulator/RouteExecutorImpl.kt @@ -0,0 +1,110 @@ +package control.emulator + +import RouteRequest +import control.RouteExecutor + +/** + * Created by user on 7/27/16. + */ +class RouteExecutorImpl : RouteExecutor { + + enum class MoveDirection { + LEFT, + RIGHT, + FORWARD, + BACKWARD, + STOP + } + + override fun executeRoute(route: RouteRequest) { + val angles = route.angles + val distances = route.distances + val commands: MutableList> = mutableListOf() + for (i in 0..angles.size - 1) { + val angle: Int = angles[i] + val distance: Int = distances[i] + if (angle != 0) { + val command = if (angle > 180) { + MoveDirection.RIGHT + } else { + MoveDirection.LEFT + } + commands.add(Pair(command, angle)) + } + if (distance != 0) { + val command = if (distance > 0) { + MoveDirection.FORWARD + } else { + MoveDirection.BACKWARD + } + commands.add(Pair(command, distance)) + } + } + commands.add(Pair(MoveDirection.STOP, 0)) + executeCommand(commands, 0) + } + + fun executeCommand(commands: List>, currentCommandIdx: Int) { +// if (currentCommandIdx == commands.size) { +// MicroController.instance.car.routeDone() +// } +// val currentCommand = commands.get(currentCommandIdx) +// MicroController.instance.car.move(currentCommand.first, currentCommand.second, { +// executeCommand(commands, currentCommandIdx + 1) +// }) + } + +// var moveDirection: MoveDirection = MoveDirection.STOP +// +// fun stopCar() { +// move(MoveDirection.STOP, 0, {}) +// } +// +// fun refreshLocation(delta: Int) { +// val deltaSeconds = delta.toDouble() / 1000 +// when (moveDirection) { +// MoveDirection.FORWARD -> { +// this.x += MOVE_VELOCITY * deltaSeconds * Math.cos(this.angle * Math.PI / 180); +// this.y += MOVE_VELOCITY * deltaSeconds * Math.sin(this.angle * Math.PI / 180); +// } +// MoveDirection.BACKWARD -> { +// this.x -= MOVE_VELOCITY * deltaSeconds * Math.cos(this.angle * Math.PI / 180); +// this.y -= MOVE_VELOCITY * deltaSeconds * Math.sin(this.angle * Math.PI / 180); +// } +// MoveDirection.LEFT -> this.angle += ROTATION_VELOCITY * deltaSeconds +// MoveDirection.RIGHT -> this.angle -= ROTATION_VELOCITY * deltaSeconds +// else -> { +// +// } +// } +//// println("x=$x; y=$y; angle=$angle") +// } +// +// fun routeDone() { +// controller.stopCar() +// } +// +// fun move(moveDirection: MoveDirection, value: Int, 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, MOVE_VELOCITY), callBack) +// } else { +// controller.delay(getTimeForMoving(value, ROTATION_VELOCITY), callBack) +// } +// } +// } +// +// fun getTimeForMoving(value: Int, velocity: Double): Int { +// return (1000 * Math.abs(value.toDouble()) / velocity).toInt() +// } + +} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/net/server/handlers/AbstractHandler.kt b/car_srv/kotlinSrv/src/net/server/handlers/AbstractHandler.kt index 1cbc00d36d4..94bc0b6695a 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/AbstractHandler.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/AbstractHandler.kt @@ -1,5 +1,7 @@ package net.server.handlers +import CodedOutputStream + /** * Created by user on 7/27/16. */ @@ -13,6 +15,7 @@ abstract class AbstractHandler { }) } + abstract fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) } \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/net/server/handlers/debug/Memory.kt b/car_srv/kotlinSrv/src/net/server/handlers/debug/Memory.kt index f6b23c88f2e..3e4336be722 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/debug/Memory.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/debug/Memory.kt @@ -1,9 +1,8 @@ package net.server.handlers.debug -import CodedInputStream import DebugRequest import DebugResponseMemoryStats -import MicroController +import McState import encodeProtoBuf import mcTransport import net.server.handlers.AbstractHandler @@ -23,7 +22,7 @@ class Memory : AbstractHandler { override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { - if (!MicroController.instance.isConnected()) { + if (!McState.instance.isConnected()) { println("mc is disconnected!") val responseMessage = toServerObjectBuilder.build() callback.invoke(encodeProtoBuf(responseMessage)) diff --git a/car_srv/kotlinSrv/src/net/server/handlers/flash/LoadBin.kt b/car_srv/kotlinSrv/src/net/server/handlers/flash/LoadBin.kt index 0878f3215f5..145970e9ac3 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/flash/LoadBin.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/flash/LoadBin.kt @@ -1,10 +1,12 @@ package net.server.handlers.flash -import net.server.handlers.AbstractHandler -import require import CodedInputStream +import Upload +import UploadResult import encodeProtoBuf import mcTransport +import net.server.handlers.AbstractHandler +import require /** * Created by user on 7/27/16. @@ -16,9 +18,9 @@ class LoadBin : AbstractHandler { val fromServerObjectBuilder: Upload.BuilderUpload val toServerObjectBuilder: UploadResult.BuilderUploadResult - constructor(fromSrv: Upload.BuilderUpload, toSrv: UploadResult.BuilderUploadResult) : super() { - this.fromServerObjectBuilder = fromSrv - this.toServerObjectBuilder = toSrv + constructor() : super() { + this.fromServerObjectBuilder = Upload.BuilderUpload(ByteArray(0)) + this.toServerObjectBuilder = UploadResult.BuilderUploadResult(0) this.exec = require("child_process").exec } diff --git a/car_srv/kotlinSrv/src/net/server/handlers/main/GetLocation.kt b/car_srv/kotlinSrv/src/net/server/handlers/main/GetLocation.kt index 466f987f89c..6f5c4e4fb4f 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/main/GetLocation.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/main/GetLocation.kt @@ -1,7 +1,9 @@ package net.server.handlers.main -import net.server.handlers.AbstractHandler +import LocationResponse +import MicroController import encodeProtoBuf +import net.server.handlers.AbstractHandler /** * Created by user on 7/28/16. @@ -10,8 +12,9 @@ class GetLocation : AbstractHandler { val toServerObjectBuilder: LocationResponse.BuilderLocationResponse - constructor(toSrv: LocationResponse.BuilderLocationResponse) : super() { - this.toServerObjectBuilder = toSrv + constructor() : super() { + val defaultLocationData = LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build() + this.toServerObjectBuilder = LocationResponse.BuilderLocationResponse(defaultLocationData, 0) } override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { diff --git a/car_srv/kotlinSrv/src/net/server/handlers/main/SetRoute.kt b/car_srv/kotlinSrv/src/net/server/handlers/main/SetRoute.kt index 716db0144a3..553f5c36694 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/main/SetRoute.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/main/SetRoute.kt @@ -4,7 +4,8 @@ import CodedInputStream import MicroController import RouteRequest import RouteResponse -import encodeProtoBuf +import control.RouteExecutor +import CodedOutputStream import net.server.handlers.AbstractHandler /** @@ -14,25 +15,36 @@ class SetRoute : AbstractHandler { val fromServerObjectBuilder: RouteRequest.BuilderRouteRequest val toServerObjectBuilder: RouteResponse.BuilderRouteResponse + val routeExecutor: RouteExecutor - constructor(fromSrv: RouteRequest.BuilderRouteRequest, toSrv: RouteResponse.BuilderRouteResponse) : super() { - this.fromServerObjectBuilder = fromSrv - this.toServerObjectBuilder = toSrv + constructor(routeExecutor: RouteExecutor) : super() { + this.routeExecutor = routeExecutor + this.fromServerObjectBuilder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0)) + this.toServerObjectBuilder = RouteResponse.BuilderRouteResponse(0) } override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { + println("set route handler") val car = MicroController.instance.car val message = fromServerObjectBuilder.build() message.mergeFrom(CodedInputStream(data)) - if (!MicroController.instance.isConnected()) { + if (!McState.instance.isConnected()) { println("mc is disconnected!") val responseMessage = toServerObjectBuilder.setCode(16).build() callback.invoke(encodeProtoBuf(responseMessage)) return } - car.routeExecutor.executeRoute(message) + routeExecutor.executeRoute(message) val responseMessage = toServerObjectBuilder.setCode(0).build() callback.invoke(encodeProtoBuf(responseMessage)) } + fun encodeProtoBuf(protoMessage: RouteResponse): ByteArray { + val protoSize = protoMessage.getSizeNoTag() + val routeBytes = ByteArray(protoSize) + + protoMessage.writeTo(CodedOutputStream(routeBytes)) + return routeBytes + } + } \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/net/server/handlers/rc/Connect.kt b/car_srv/kotlinSrv/src/net/server/handlers/rc/Connect.kt deleted file mode 100644 index 5363804ac7e..00000000000 --- a/car_srv/kotlinSrv/src/net/server/handlers/rc/Connect.kt +++ /dev/null @@ -1,32 +0,0 @@ -package net.server.handlers.rc - -import exceptions.RcControlException -import net.server.handlers.AbstractHandler -import encodeProtoBuf - -/** - * Created by user on 7/27/16. - */ -class Connect : AbstractHandler { - - val toServerObjectBuilder: SessionUpResponse.BuilderSessionUpResponse - - constructor(toSrv: SessionUpResponse.BuilderSessionUpResponse) : super() { - this.toServerObjectBuilder = toSrv - } - - override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { - val resultCode: Int - val sid: Int; - try { - sid = MicroController.instance.connectRC() - resultCode = 0 - } catch (e: RcControlException) { - resultCode = 13 - sid = 0 - } - val responseMessage = toServerObjectBuilder.setCode(resultCode).setSid(sid).build() - callback.invoke(encodeProtoBuf(responseMessage)) - } - -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/net/server/handlers/rc/Control.kt b/car_srv/kotlinSrv/src/net/server/handlers/rc/Control.kt index 75ed9fc8eed..8229eb18ae1 100644 --- a/car_srv/kotlinSrv/src/net/server/handlers/rc/Control.kt +++ b/car_srv/kotlinSrv/src/net/server/handlers/rc/Control.kt @@ -1,12 +1,13 @@ package net.server.handlers.rc +import CodedInputStream +import DirectionRequest +import DirectionResponse import MicroController -import carControl.RouteExecutorImpl.MoveDirection +import control.emulator.RouteExecutorImpl.MoveDirection +import encodeProtoBuf import exceptions.RcControlException import net.server.handlers.AbstractHandler -import DirectionRequest -import CodedInputStream -import encodeProtoBuf /** * Created by user on 7/27/16. @@ -16,9 +17,9 @@ class Control : AbstractHandler { val fromServerObjectBuilder: DirectionRequest.BuilderDirectionRequest val toServerObjectBuilder: DirectionResponse.BuilderDirectionResponse - constructor(fromSrv: DirectionRequest.BuilderDirectionRequest, toSrv: DirectionResponse.BuilderDirectionResponse) : super() { - this.fromServerObjectBuilder = fromSrv - this.toServerObjectBuilder = toSrv + constructor() : super() { + this.fromServerObjectBuilder = DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.fromIntToCommand(0), 0) + this.toServerObjectBuilder = DirectionResponse.BuilderDirectionResponse(0) } override fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) { @@ -46,7 +47,7 @@ class Control : AbstractHandler { } val resultCode: Int try { - MicroController.instance.RcMove(command, sid) +// MicroController.instance.RcMove(command, sid) resultCode = 0 } catch (e: RcControlException) { resultCode = 12 diff --git a/car_srv/kotlinSrv/src/net/server/handlers/rc/Disconnect.kt b/car_srv/kotlinSrv/src/net/server/handlers/rc/Disconnect.kt deleted file mode 100644 index 31b09f00b80..00000000000 --- a/car_srv/kotlinSrv/src/net/server/handlers/rc/Disconnect.kt +++ /dev/null @@ -1,35 +0,0 @@ -package net.server.handlers.rc - -import exceptions.RcControlException -import net.server.handlers.AbstractHandler -import CodedInputStream -import encodeProtoBuf - -/** - * Created by user on 7/27/16. - */ -class Disconnect : AbstractHandler { - - val fromServerObjectBuilder: SessionDownRequest.BuilderSessionDownRequest - val toServerObjectBuilder: SessionDownResponse.BuilderSessionDownResponse - - constructor(fromSrv: SessionDownRequest.BuilderSessionDownRequest, toSrv: SessionDownResponse.BuilderSessionDownResponse) : super() { - this.fromServerObjectBuilder = fromSrv - this.toServerObjectBuilder = toSrv - } - - override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { - - val message = fromServerObjectBuilder.build() - message.mergeFrom(CodedInputStream(data)) - val resultCode: Int - try { - MicroController.instance.disconnectRC(message.sid) - resultCode = 0 - } catch (e: RcControlException) { - resultCode = 12 - } - val responseMessage = toServerObjectBuilder.setCode(resultCode).build() - callback.invoke(encodeProtoBuf(responseMessage)) - } -} \ No newline at end of file diff --git a/car_srv/kotlinSrv/src/net/server/handlers/rc/Heartbeat.kt b/car_srv/kotlinSrv/src/net/server/handlers/rc/Heartbeat.kt deleted file mode 100644 index 465a524ced0..00000000000 --- a/car_srv/kotlinSrv/src/net/server/handlers/rc/Heartbeat.kt +++ /dev/null @@ -1,34 +0,0 @@ -package net.server.handlers.rc - -import exceptions.RcControlException -import net.server.handlers.AbstractHandler -import CodedInputStream -import encodeProtoBuf - -/** - * Created by user on 7/27/16. - */ -class Heartbeat : AbstractHandler { - - val fromServerObjectBuilder: HeartBeatRequest.BuilderHeartBeatRequest - val toServerObjectBuilder: HeartBeatResponse.BuilderHeartBeatResponse - - constructor(fromSrv: HeartBeatRequest.BuilderHeartBeatRequest, toSrv: HeartBeatResponse.BuilderHeartBeatResponse) : super() { - this.fromServerObjectBuilder = fromSrv - this.toServerObjectBuilder = toSrv - } - - override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { - val message = fromServerObjectBuilder.build() - message.mergeFrom(CodedInputStream(data)) - val resultCode: Int - try { - MicroController.instance.rcHeartBeat(message.sid) - resultCode = 0 - } catch (e: RcControlException) { - resultCode = 12 - } - val responseMessage = toServerObjectBuilder.setCode(resultCode).build() - callback.invoke(encodeProtoBuf(responseMessage)) - } -} \ No newline at end of file