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