refactoring raspberry server

This commit is contained in:
MaximZaitsev
2016-08-19 11:45:06 +03:00
parent aa36856a0a
commit 3921963424
32 changed files with 412 additions and 522 deletions
+25 -17
View File
@@ -1,24 +1,8 @@
# Car server # 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 ## Deploying car server
*note:* This feature is under development *note:* this script use expect script language. You have to install it
*note:* this script use expect script languane. You have to install it
for install expect on ubuntu for install expect on ubuntu
@@ -31,3 +15,27 @@ for deploy server on car use
where: where:
{ip_addr} - ip address of raspberry. {ip_addr} - ip address of raspberry.
{user_name} and {password} - user name and password for login on 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
+3 -13
View File
@@ -25,26 +25,16 @@ sourceSets {
} }
task copyKotlinLib(type: Copy) { task copyKotlinLib(type: Copy) {
from "${projectDir}/helpers/kotlin.js" from "${projectDir}/kotlinJsRequiredFiles/kotlin.js"
from "${projectDir}/helpers/package.json" from "${projectDir}/kotlinJsRequiredFiles/package.json"
into "${projectDir}/build/js" 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 copyKotlinLib
build.dependsOn copyProtoFiles
compileKotlin2Js.kotlinOptions.outputFile = "${projectDir}/build/js/main.js" compileKotlin2Js.kotlinOptions.outputFile = "${projectDir}/build/js/main.js"
compileKotlin2Js.kotlinOptions.outputPrefix = "${projectDir}/helpers/prefix.js" compileKotlin2Js.kotlinOptions.outputPrefix = "${projectDir}/kotlinJsRequiredFiles/connectKotlinLib.js"
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-js-library:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-js-library:$kotlin_version"
-2
View File
@@ -1,7 +1,5 @@
#!/usr/bin/expect #!/usr/bin/expect
# XXX this script works super slow on eugene's machine
set host "" set host ""
set userName "pi" set userName "pi"
set password "111" set password "111"
+17
View File
@@ -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"
}
}
-2
View File
@@ -1,5 +1,3 @@
#!/bin/bash #!/bin/bash
# TODO main server ip address should be read from configuration file that is
# not overwritten during deploy.
cd build/js cd build/js
node main.js node main.js
-78
View File
@@ -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()
}
}
+27
View File
@@ -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()
}
}
+13 -3
View File
@@ -1,14 +1,23 @@
/** /**
* Created by user on 8/16/16. * 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 serverIp = "127.0.0.1"
private var thisCarIp = "127.0.0.1" private var thisCarIp = "127.0.0.1"
fun loadConfig(): Boolean { 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") val data: String = fs.readFileSync(configFileName, "utf8")
println("reader $data")
data.split("\n").forEach { line -> data.split("\n").forEach { line ->
val keyValue = line.split(":") val keyValue = line.split(":")
if (!line.equals("")) { if (!line.equals("")) {
@@ -16,9 +25,10 @@ class Config(val configFileName: String) {
return false return false
} }
println(keyValue.toString())
when (keyValue[0]) { when (keyValue[0]) {
"ip" -> serverIp = keyValue[1] "mainServerIp" -> serverIp = keyValue[1]
"thisIp" -> thisCarIp = keyValue[1] "thisServerIp" -> thisCarIp = keyValue[1]
} }
} }
} }
+20
View File
@@ -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
}
@@ -0,0 +1,9 @@
/**
* Created by user on 8/18/16.
*/
interface MCConnectObservable<V> {
fun addObserver(MCConnectObserver: MCConnectObserver<V>)
fun removeObserver(MCConnectObserver: MCConnectObserver<V>)
}
@@ -0,0 +1,9 @@
/**
* Created by user on 8/18/16.
*/
interface MCConnectObserver<V> {
fun connect(vararg params: V)
fun disconnect()
}
@@ -79,7 +79,6 @@ class McTransport() {
result += bytes[0].toInt().shl(24) result += bytes[0].toInt().shl(24)
return result return result
} }
} }
private val protoHeaderLength: Int = 4 private val protoHeaderLength: Int = 4
+11 -37
View File
@@ -1,23 +1,21 @@
import control.car.RouteExecutorToUsb
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import net.server.handlers.debug.Memory import net.server.handlers.debug.Memory
import net.server.handlers.flash.LoadBin import net.server.handlers.flash.LoadBin
import net.server.handlers.main.GetLocation import net.server.handlers.main.GetLocation
import net.server.handlers.main.SetRoute import net.server.handlers.main.SetRoute
import net.server.handlers.rc.Connect
import net.server.handlers.rc.Control 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. * Created by user on 7/26/16.
*/ */
val deltaTimeLocationRefresh: Int = 100//ms val deltaTimeLocationRefresh: Int = 100
val carServerPort: Int = 8888 val carServerPort: Int = 8888
val mainServerPort = 7925 val mainServerPort = 7925
val config = Config("config.cfg") val config = Config()
val fs = require("fs") val fs = require("fs")
fun main(args: Array<String>) { fun main(args: Array<String>) {
if (!config.loadConfig()) { if (!config.loadConfig()) {
@@ -26,42 +24,18 @@ fun main(args: Array<String>) {
} }
val handlers: MutableMap<String, AbstractHandler> = mutableMapOf() val handlers: MutableMap<String, AbstractHandler> = 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()) handlers.put("/debug/memoty", Memory())
net.server.start(handlers, carServerPort) net.server.start(handlers, carServerPort)
val udev = Udev() val mcConditionMonitor = McConditionMonitor.instance
udev.start() mcConditionMonitor.start()
MicroController.instance.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
@@ -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<String> {
private val udev: dynamic = require("udev")
private val exec: dynamic = require("child_process").execSync
private val observersList: MutableList<MCConnectObserver<String>> = 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<String>) {
observersList.add(MCConnectObserver)
}
override fun removeObserver(MCConnectObserver: MCConnectObserver<String>) {
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()
}
}
+23
View File
@@ -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()
}
}
+8 -61
View File
@@ -1,7 +1,7 @@
import carControl.ControlImpl import control.emulator.RouteExecutorImpl
import carControl.RouteExecutorImpl import control.car.RouteExecutorToUsb
import carControl.RouteExecutorToUsb
import exceptions.RcControlException import exceptions.RcControlException
import kotlin.js.Date
/** /**
* Created by user on 7/28/16. * Created by user on 7/28/16.
@@ -17,7 +17,7 @@ class MicroController private constructor() {
val modelID: String val modelID: String
var transportFilePath: String var transportFilePath: String
val car: Car val car: CarState
init { init {
this.rcSid = 0 this.rcSid = 0
@@ -27,7 +27,8 @@ class MicroController private constructor() {
this.modelID = "5740" this.modelID = "5740"
this.transportFilePath = "" this.transportFilePath = ""
this.car = Car(RouteExecutorToUsb(), ControlImpl())
this.car = CarState.instance
} }
fun start() { fun start() {
@@ -38,65 +39,11 @@ class MicroController private constructor() {
println("read: " + bytes.toString()) println("read: " + bytes.toString())
} }
setInterval({ this.car.refreshLocation(deltaTimeLocationRefresh) }, deltaTimeLocationRefresh); // 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()
} }
fun connectToServer(thisIp: String, thisPort: Int) { 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()) val bytes = ByteArray(requestObject.getSizeNoTag())
requestObject.writeTo(CodedOutputStream(bytes)) requestObject.writeTo(CodedOutputStream(bytes))
net.sendRequest(js("new Buffer(bytes)"), "/connect", { resultData -> net.sendRequest(js("new Buffer(bytes)"), "/connect", { resultData ->
-60
View File
@@ -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
}
}
}
}
@@ -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)
}
@@ -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)
}
}
@@ -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<Pair<MoveDirection, Int>> = 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<Pair<MoveDirection, Int>>, 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)
})
}
}
@@ -1,4 +1,4 @@
package carControl package control
import RouteRequest import RouteRequest
@@ -1,16 +1,19 @@
package carControl package control.car
import RouteRequest import RouteRequest
import mcTransport import control.RouteExecutor
import encodeInt
import decodeInt
import encodeProtoBuf import encodeProtoBuf
import mcTransport
import CodedOutputStream
class RouteExecutorToUsb : RouteExecutor { class RouteExecutorToUsb : RouteExecutor {
override fun executeRoute(route: RouteRequest) { override fun executeRoute(route: RouteRequest) {
println("Execute Route:") println("Execute Route:")
val routeBytes = encodeProtoBuf(route) val protoSize = route.getSizeNoTag()
val routeBytes = ByteArray(protoSize)
route.writeTo(CodedOutputStream(routeBytes))
mcTransport.setCallBack { bytes -> mcTransport.setCallBack { bytes ->
println("Read $bytes;") println("Read $bytes;")
@@ -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<Pair<MoveDirection, Int>> = 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<Pair<MoveDirection, Int>>, 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()
// }
}
@@ -1,5 +1,7 @@
package net.server.handlers package net.server.handlers
import CodedOutputStream
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
*/ */
@@ -13,6 +15,7 @@ abstract class AbstractHandler {
}) })
} }
abstract fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) abstract fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit)
} }
@@ -1,9 +1,8 @@
package net.server.handlers.debug package net.server.handlers.debug
import CodedInputStream
import DebugRequest import DebugRequest
import DebugResponseMemoryStats import DebugResponseMemoryStats
import MicroController import McState
import encodeProtoBuf import encodeProtoBuf
import mcTransport import mcTransport
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
@@ -23,7 +22,7 @@ class Memory : AbstractHandler {
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
if (!MicroController.instance.isConnected()) { if (!McState.instance.isConnected()) {
println("mc is disconnected!") println("mc is disconnected!")
val responseMessage = toServerObjectBuilder.build() val responseMessage = toServerObjectBuilder.build()
callback.invoke(encodeProtoBuf(responseMessage)) callback.invoke(encodeProtoBuf(responseMessage))
@@ -1,10 +1,12 @@
package net.server.handlers.flash package net.server.handlers.flash
import net.server.handlers.AbstractHandler
import require
import CodedInputStream import CodedInputStream
import Upload
import UploadResult
import encodeProtoBuf import encodeProtoBuf
import mcTransport import mcTransport
import net.server.handlers.AbstractHandler
import require
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
@@ -16,9 +18,9 @@ class LoadBin : AbstractHandler {
val fromServerObjectBuilder: Upload.BuilderUpload val fromServerObjectBuilder: Upload.BuilderUpload
val toServerObjectBuilder: UploadResult.BuilderUploadResult val toServerObjectBuilder: UploadResult.BuilderUploadResult
constructor(fromSrv: Upload.BuilderUpload, toSrv: UploadResult.BuilderUploadResult) : super() { constructor() : super() {
this.fromServerObjectBuilder = fromSrv this.fromServerObjectBuilder = Upload.BuilderUpload(ByteArray(0))
this.toServerObjectBuilder = toSrv this.toServerObjectBuilder = UploadResult.BuilderUploadResult(0)
this.exec = require("child_process").exec this.exec = require("child_process").exec
} }
@@ -1,7 +1,9 @@
package net.server.handlers.main package net.server.handlers.main
import net.server.handlers.AbstractHandler import LocationResponse
import MicroController
import encodeProtoBuf import encodeProtoBuf
import net.server.handlers.AbstractHandler
/** /**
* Created by user on 7/28/16. * Created by user on 7/28/16.
@@ -10,8 +12,9 @@ class GetLocation : AbstractHandler {
val toServerObjectBuilder: LocationResponse.BuilderLocationResponse val toServerObjectBuilder: LocationResponse.BuilderLocationResponse
constructor(toSrv: LocationResponse.BuilderLocationResponse) : super() { constructor() : super() {
this.toServerObjectBuilder = toSrv val defaultLocationData = LocationResponse.LocationData.BuilderLocationData(0, 0, 0).build()
this.toServerObjectBuilder = LocationResponse.BuilderLocationResponse(defaultLocationData, 0)
} }
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
@@ -4,7 +4,8 @@ import CodedInputStream
import MicroController import MicroController
import RouteRequest import RouteRequest
import RouteResponse import RouteResponse
import encodeProtoBuf import control.RouteExecutor
import CodedOutputStream
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
/** /**
@@ -14,25 +15,36 @@ class SetRoute : AbstractHandler {
val fromServerObjectBuilder: RouteRequest.BuilderRouteRequest val fromServerObjectBuilder: RouteRequest.BuilderRouteRequest
val toServerObjectBuilder: RouteResponse.BuilderRouteResponse val toServerObjectBuilder: RouteResponse.BuilderRouteResponse
val routeExecutor: RouteExecutor
constructor(fromSrv: RouteRequest.BuilderRouteRequest, toSrv: RouteResponse.BuilderRouteResponse) : super() { constructor(routeExecutor: RouteExecutor) : super() {
this.fromServerObjectBuilder = fromSrv this.routeExecutor = routeExecutor
this.toServerObjectBuilder = toSrv this.fromServerObjectBuilder = RouteRequest.BuilderRouteRequest(IntArray(0), IntArray(0))
this.toServerObjectBuilder = RouteResponse.BuilderRouteResponse(0)
} }
override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) { override fun getBytesResponse(data: ByteArray, callback: (ByteArray) -> Unit) {
println("set route handler")
val car = MicroController.instance.car val car = MicroController.instance.car
val message = fromServerObjectBuilder.build() val message = fromServerObjectBuilder.build()
message.mergeFrom(CodedInputStream(data)) message.mergeFrom(CodedInputStream(data))
if (!MicroController.instance.isConnected()) { if (!McState.instance.isConnected()) {
println("mc is disconnected!") println("mc is disconnected!")
val responseMessage = toServerObjectBuilder.setCode(16).build() val responseMessage = toServerObjectBuilder.setCode(16).build()
callback.invoke(encodeProtoBuf(responseMessage)) callback.invoke(encodeProtoBuf(responseMessage))
return return
} }
car.routeExecutor.executeRoute(message) routeExecutor.executeRoute(message)
val responseMessage = toServerObjectBuilder.setCode(0).build() val responseMessage = toServerObjectBuilder.setCode(0).build()
callback.invoke(encodeProtoBuf(responseMessage)) callback.invoke(encodeProtoBuf(responseMessage))
} }
fun encodeProtoBuf(protoMessage: RouteResponse): ByteArray {
val protoSize = protoMessage.getSizeNoTag()
val routeBytes = ByteArray(protoSize)
protoMessage.writeTo(CodedOutputStream(routeBytes))
return routeBytes
}
} }
@@ -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))
}
}
@@ -1,12 +1,13 @@
package net.server.handlers.rc package net.server.handlers.rc
import CodedInputStream
import DirectionRequest
import DirectionResponse
import MicroController import MicroController
import carControl.RouteExecutorImpl.MoveDirection import control.emulator.RouteExecutorImpl.MoveDirection
import encodeProtoBuf
import exceptions.RcControlException import exceptions.RcControlException
import net.server.handlers.AbstractHandler import net.server.handlers.AbstractHandler
import DirectionRequest
import CodedInputStream
import encodeProtoBuf
/** /**
* Created by user on 7/27/16. * Created by user on 7/27/16.
@@ -16,9 +17,9 @@ class Control : AbstractHandler {
val fromServerObjectBuilder: DirectionRequest.BuilderDirectionRequest val fromServerObjectBuilder: DirectionRequest.BuilderDirectionRequest
val toServerObjectBuilder: DirectionResponse.BuilderDirectionResponse val toServerObjectBuilder: DirectionResponse.BuilderDirectionResponse
constructor(fromSrv: DirectionRequest.BuilderDirectionRequest, toSrv: DirectionResponse.BuilderDirectionResponse) : super() { constructor() : super() {
this.fromServerObjectBuilder = fromSrv this.fromServerObjectBuilder = DirectionRequest.BuilderDirectionRequest(DirectionRequest.Command.fromIntToCommand(0), 0)
this.toServerObjectBuilder = toSrv this.toServerObjectBuilder = DirectionResponse.BuilderDirectionResponse(0)
} }
override fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) { override fun getBytesResponse(data: ByteArray, callback: (b: ByteArray) -> Unit) {
@@ -46,7 +47,7 @@ class Control : AbstractHandler {
} }
val resultCode: Int val resultCode: Int
try { try {
MicroController.instance.RcMove(command, sid) // MicroController.instance.RcMove(command, sid)
resultCode = 0 resultCode = 0
} catch (e: RcControlException) { } catch (e: RcControlException) {
resultCode = 12 resultCode = 12
@@ -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))
}
}
@@ -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))
}
}