created kotlin srv, car emulator, car control, coordinate calculate
This commit is contained in:
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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<String>) {
|
||||
|
||||
val protoBuf = require("protobufjs")
|
||||
val controlConstructor = protoBuf.loadProtoFile("./proto/" + "direction.proto").build("carkot")
|
||||
val handlers: MutableMap<String, AbstractHandler> = 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) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
class Udev {
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package carControl
|
||||
|
||||
import Car
|
||||
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
interface RouteExecutor {
|
||||
|
||||
fun executeRoute(route: dynamic)
|
||||
|
||||
}
|
||||
@@ -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<Pair<MoveDirection, Double>> = 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<Pair<MoveDirection, Double>>, currentCommandIdx: Int) {
|
||||
if (currentCommandIdx == commands.size) {
|
||||
thisCar.routeDone()
|
||||
}
|
||||
val currentCommand = commands.get(currentCommandIdx)
|
||||
thisCar.move(currentCommand.first, currentCommand.second, {
|
||||
executeCommand(commands, currentCommandIdx + 1)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* Created by user on 7/26/16.
|
||||
*/
|
||||
fun main(args: Array<String>) {
|
||||
println("hallo!")
|
||||
}
|
||||
|
||||
@native
|
||||
fun require(name:String) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package server
|
||||
|
||||
|
||||
import require
|
||||
import server.handlers.AbstractHandler
|
||||
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
class Server(handlers: MutableMap<String, AbstractHandler>) {
|
||||
|
||||
val http: dynamic
|
||||
val url: dynamic
|
||||
val handlers: MutableMap<String, AbstractHandler>
|
||||
|
||||
init {
|
||||
http = require("http")
|
||||
url = require("url")
|
||||
this.handlers = handlers
|
||||
}
|
||||
|
||||
|
||||
fun start() {
|
||||
|
||||
http.createServer({ request, response ->
|
||||
val content = mutableListOf<Byte>()
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<Byte>, 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)
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package server.handlers.rc
|
||||
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
class Connect {
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package server.handlers.rc
|
||||
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
class Disconnect {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package server.handlers.rc
|
||||
|
||||
/**
|
||||
* Created by user on 7/27/16.
|
||||
*/
|
||||
class Heartbeat {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user