maked car moks on rapsberry. added handler for route from main server

This commit is contained in:
MaximZaitsev
2016-07-21 15:49:05 +03:00
parent 2520afd3aa
commit 1044a66da0
12 changed files with 360 additions and 130 deletions
+152
View File
@@ -0,0 +1,152 @@
/**
* Created by user on 7/21/16.
*/
const fs = require("fs");
const main = require("./main.js");
const directionClass = main.protoConstructorControl.DirectionRequest;
function Car(uid) {
this.uid = uid;
this.x = 0;
this.y = 0;
this.angle = 0;
this.velocityMove = 0.1;
this.velocityRotation = 10;
this.paused = false;
this.transportError = false;
this.currentDirection = 0;
this.executeTimeLeft = 0;
this.moveList = [];//object of direction and time to execute this direction. field: direction:byte, executeTime:double (seconds)
this.nextMoveListIndex = 0;
this.reset = reset;
this.pause = pause;
this.move = move;
this.setDirection = setDirection;
this.resume = resume;
this.getDirectionByte = getDirectionByte;
this.setPath = setPath;
return this;
}
function reset() {
this.currentDirection = 0;
this.executeTimeLeft = 0;
this.moveList = [];
this.nextMoveListIndex = 0;
}
function pause() {
this.paused = true;
}
function resume() {
this.paused = false;
}
function move(delta) {
var deltaSeconds = delta / 1000;
// console.log("x=" + this.x + " y=" + this.y + " angle=" + this.angle);
if (this.paused) {
return;
}
if (this.executeTimeLeft > 0) {
this.executeTimeLeft -= deltaSeconds;
if (this.currentDirection == this.getDirectionByte(directionClass.Command.left)) {
this.angle += deltaSeconds * this.velocityRotation;
} else if (this.currentDirection == this.getDirectionByte(directionClass.Command.right)) {
this.angle -= deltaSeconds * this.velocityRotation;
} else if (this.currentDirection == this.getDirectionByte(directionClass.Command.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);
}
} else {
if (this.nextMoveListIndex == this.moveList.length) {
//this was last move point
this.setDirection(this.getDirectionByte(directionClass.Command.stop), null)
} else {
var currentMove = this.moveList[this.nextMoveListIndex];
this.currentDirection = currentMove.direction;
this.executeTimeLeft = currentMove.executeTime;
this.setDirection(this.currentDirection, null);
this.nextMoveListIndex++;
}
}
}
//args wayPointsList contains object of points. field {distance, angle_delta}. this fun parse this to move list with field direction and move time with using velocity of move and rotation
function setPath(wayPointsList) {
this.reset();
for (var i = 0; i < wayPointsList.length; i++) {
var currentPoint = wayPointsList[i];
var angle = currentPoint.angle_delta;
var distance = currentPoint.distance;
if (angle != 0) {
//need rotation. check direction left or right
if (angle >= 180) {
this.moveList.push({
"direction": getDirectionByte(directionClass.Command.right),
"executeTime": (angle / this.velocityRotation)
});
} else {
this.moveList.push({
"direction": getDirectionByte(directionClass.Command.left),
"executeTime": (angle / this.velocityRotation)
});
}
}
this.moveList.push({
"direction": getDirectionByte(directionClass.Command.forward),
"executeTime": (distance / this.velocityMove)
});
}
}
function setDirection(directionByte, callBack) {
fs.appendFile(main.transportFilePath, directionByte, "binary", function (error) {
var code = 0;
var errorMsg = "";
console.log(error);
if (error) {
errorMsg = error;
}
if (callBack != null) {
callBack(code, errorMsg)
}
});
}
function getDirectionByte(command) {
resultByte = -1;
switch (command) {
case directionClass.Command.stop:
{
resultByte = "0";
break;
}
case directionClass.Command.forward:
{
resultByte = "1";
break;
}
case directionClass.Command.backward:
{
resultByte = "2";
break;
}
case directionClass.Command.right:
{
resultByte = "3";
break;
}
case directionClass.Command.left:
{
resultByte = "4";
break;
}
}
return resultByte
}
exports.getCar = Car;
-100
View File
@@ -1,100 +0,0 @@
/**
* Created by user on 7/11/16.
*/
const fs = require("fs");
const main = require("./main.js");
const exec = require('child_process').exec;
function loadBin(httpContent, response) {
var uploadClass = main.protoConstructorCarkot.Upload;
var uploadObject = uploadClass.decode(httpContent);
fs.writeFile(main.binFilePath, uploadObject.data.buffer, "binary", function (error) {
var uploadResultClass = main.protoConstructorCarkot.UploadResult;
var code = 0;
var stdErr = "";
if (error) {
code = 2;
stdErr = error.toString();
} else {
code = 0;
var shCommand = main.commandPrefix + " " + main.binFilePath + " " + uploadObject.base;
exec(shCommand, function (error, stdout, stderr) {
if (error) {
code = 1;
console.error(error);
}
var resultObject = new uploadResultClass({
"stdOut": stdout.toString(),
"resultCode": code,
"stdErr": (stderr.toString() + "\n error:" + error)
});
var byteBuffer = resultObject.encode();
var byteArray = [];
for (var i = 0; i < byteBuffer.limit; i++) {
byteArray.push(byteBuffer.buffer[i]);
}
response.writeHead(200, {"Content-Type": "text/plain", "Content-length": byteArray.length});
response.write(new Buffer(byteArray));
response.end();
console.log(shCommand);
});
}
});
}
function other(httpContent, response) {
console.log("other");
response.writeHead(200, {"Content-Type": "text/plain"});
response.end();
}
//контроль машинкой, как с пульта управления
function control(httpContent, response) {
var directionClass = main.protoConstructorControl.Direction;
var directionObject = directionClass.decode(httpContent);
var resultByte;
switch (directionObject.command) {
case directionClass.Command.stop :
{
resultByte = "0";
break;
}
case directionClass.Command.forward :
{
resultByte = "1";
break;
}
case directionClass.Command.backward :
{
resultByte = "2";
break;
}
case directionClass.Command.right :
{
resultByte = "3";
break;
}
case directionClass.Command.left :
{
resultByte = "4";
break;
}
}
console.log("byte for car: " + resultByte);
fs.appendFile(main.transportFilePath, resultByte, "binary", function (error) {
if (error) {
console.log(error);
}
//todo ещё нужно считывать ответ от контроллера и анализировать его (0 или 1) и отправлять
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(new Buffer([0]));
response.end();
});
}
exports.loadBin = loadBin;
exports.other = other;
exports.control = control;
+40
View File
@@ -0,0 +1,40 @@
/**
* Created by user on 7/21/16.
*/
const main = require("./../main.js");
function handle(httpContent, response) {
var directionClass = main.protoConstructorControl.DirectionRequest;
var directionObject = directionClass.decode(httpContent);
var resultByte = main.thisCar.getDirectionByte(directionObject.command);
main.thisCar.reset();
main.thisCar.moveList.push({
"direction": resultByte,
"executeTime": 100000
});
console.log(resultByte);
var directionResponse = new main.protoConstructorControl.DirectionResponse({
"code": 0,
errorMsg: ""
});
var byteBuffer = directionResponse.encode();
var byteArray = [];
for (var i = 0; i < byteBuffer.limit; i++) {
byteArray.push(byteBuffer.buffer[i]);
}
response.writeHead(200, {"Content-Type": "text/plain"});
response.write(new Buffer(byteArray));
response.end();
// main.thisCar.setDirection(resultByte, function (code, errorMsg) {
// var directionResponse = new main.protoConstructorControl.DirectionResponse({
// "code": code,
// errorMsg: errorMsg
// });
// response.writeHead(200, {"Content-Type": "text/plain"});
// response.write(directionResponse.encode().buffer);
// response.end();
// });
}
exports.handler = handle;
+48
View File
@@ -0,0 +1,48 @@
/**
* Created by user on 7/21/16.
*/
const fs = require("fs");
const main = require("./../main.js");
const exec = require('child_process').exec;
function handle(httpContent, response) {
var uploadClass = main.protoConstructorCarkot.Upload;
var uploadObject = uploadClass.decode(httpContent);
fs.writeFile(main.binFilePath, uploadObject.data.buffer, "binary", function (error) {
var uploadResultClass = main.protoConstructorCarkot.UploadResult;
var code = 0;
var stdErr = "";
if (error) {
code = 2;
stdErr = error.toString();
} else {
code = 0;
var shCommand = main.commandPrefix + " " + main.binFilePath + " " + uploadObject.base;
exec(shCommand, function (error, stdout, stderr) {
if (error) {
code = 1;
console.error(error);
}
var resultObject = new uploadResultClass({
"stdOut": stdout.toString(),
"resultCode": code,
"stdErr": (stderr.toString() + "\n error:" + error)
});
var byteBuffer = resultObject.encode();
var byteArray = [];
for (var i = 0; i < byteBuffer.limit; i++) {
byteArray.push(byteBuffer.buffer[i]);
}
response.writeHead(200, {"Content-Type": "text/plain", "Content-length": byteArray.length});
response.write(new Buffer(byteArray));
response.end();
console.log(shCommand);
});
}
});
}
exports.handler = handle;
+13
View File
@@ -0,0 +1,13 @@
/**
* Created by user on 7/21/16.
*/
const main = require("./../main.js");
function handle(httpContent, response) {
var routeClass = main.protoConstructorRoute.RouteRequest;
var routeObject = routeClass.decode(httpContent);
console.log(routeObject)//todo сделать
}
exports.handler = handle;
+33 -17
View File
@@ -1,5 +1,5 @@
/**
* Created by user on 7/11/16.
* Created by maxim zaitsev on 7/11/16.
*/
const server = require("./server.js");
@@ -9,11 +9,12 @@ const protoBuf = require("protobufjs");
const fs = require("fs");
const udev = require("udev");
//parsing command line args
commander
.version('1.0.0')
.option('-p, --proto [path]', 'path to dir with proto files. need here carkot.proto and route.proto. default ./proto/')
.option('-f, --flash [path]', 'path to save bin file with name f.bin. default ./')
.option('-s, --serial [path]', 'path to file that represents MCU serial port default ./serial')
.option('-f, --flash [path]', 'path to save bin file with name flash.bin. default ./')
// .option('-s, --serial [path]', 'path to file that represents MCU serial port default ./serial')//dont need more. use path from udev monitor
.parse(process.argv);
//add slash to end of paths if need
@@ -28,30 +29,38 @@ if (commander.flash) {
}
}
const builderCarkot = protoBuf.loadProtoFile(commander.protopath ? commander.protopath + "carkot.proto" : "./proto/carkot.proto");
const builderControl = protoBuf.loadProtoFile(commander.protopath ? commander.protopath + "route.proto" : "./proto/route.proto");
//classes for protobuf decode/encode
const builderCarkot = protoBuf.loadProtoFile((commander.protopath ? commander.protopath : "./proto/") + "carkot.proto");
const builderControl = protoBuf.loadProtoFile((commander.protopath ? commander.protopath : "./proto/" + "direction.proto"));
const builderRoute = protoBuf.loadProtoFile((commander.protopath ? commander.protopath : "./proto/" + "route.proto"));
var executeShell = "./st-flash";
exports.protoConstructorCarkot = builderCarkot.build("carkot");
exports.protoConstructorControl = builderControl.build("carkot");
exports.protoConstructorRoute = builderRoute.build("carkot");
exports.commandPrefix = executeShell + " write";
exports.binFilePath = (commander.flash ? commander.flash : "./") + "st-flash";
exports.transportFilePath = (commander.serial ? commander.serial : "./serial");
exports.binFilePath = (commander.flash ? commander.flash : "./") + "flash.bin";
exports.transportFilePath = "";
var handlers = require("./handlers.js");
//init this car
var uid = "";//todo connect to srv
var car = require("./Car").getCar(uid);
exports.thisCar = car;
//handlers for client requests
var handle = {};
handle["/"] = handlers.other;
handle["/loadBin"] = handlers.loadBin;
handle["/control"] = handlers.control;
handle["/other"] = handlers.other;
//add handlers to events from udev monitor (add device and remove device)
handle["/loadBin"] = require("./handlers/loadBinHandler").handler;
handle["/control"] = require("./handlers/controlHandler").handler;
handle["/route"] = require("./handlers/setRouteHandler").handler;
exports.transportFilePath = "/dev/ttyACM0";
//add event handlers from udev monitor (add device and remove device)
const monitor = udev.monitor();
monitor.on('add', function (device) {
if (device.ID_VENDOR_ID == "0483" && device.ID_MODEL_ID == "5740" && device.SUBSYSTEM == "tty") {
//mc connected
console.log("connected");
console.log("file=" + device.DEVNAME)
console.log("connected. transport file is " + device.DEVNAME);
exports.transportFilePath = device.DEVNAME;
console.log(device.DEVNAME);
}
});
monitor.on('remove', function (device) {
@@ -61,6 +70,7 @@ monitor.on('remove', function (device) {
}
});
//check of exists st-flash util
if (typeof fs.access == "function") {
fs.access(executeShell, fs.F_OK, function (error) {
if (!error) {
@@ -73,4 +83,10 @@ if (typeof fs.access == "function") {
console.log("warning: you have old version of node.js. Check existence of the file st-flash on root of server dir yourself");
server.start(router.route, handle);
}
// server.start(router.route, handle);
//move car
var delta = 100;
setInterval(moveCar, delta);
function moveCar() {
car.move(delta)
}
+2 -1
View File
@@ -9,7 +9,8 @@
},
"author": "maxim",
"license": "ISC",
"dependencies": {
"devDependencies": {
"udev": "^0.3.0",
"commander": "^2.9.0",
"protobufjs": "^5.0.1"
}
+17
View File
@@ -0,0 +1,17 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Connect";
message ConnectionRequest {
string ip = 1;
int32 port = 2;
}
message ConnectionResponse {
int32 uid = 1;
int32 code = 2;
string errorMsg = 3;
}
+21
View File
@@ -0,0 +1,21 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Direction";
message DirectionRequest {
enum Command {
stop = 0;
forward = 1;
backward = 2;
left = 3;
right = 4;
}
Command command = 1;
}
message DirectionResponse {
int32 code = 1;
string errorMsg = 2;
}
+18
View File
@@ -0,0 +1,18 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "Location";
message LocationResponse {
LocationData locationResponseData = 1;
int32 code = 2;
string errorMsg = 3;
message LocationData {
double x = 1;
double y = 2;
double angle = 3;
}
}
+6 -12
View File
@@ -2,10 +2,10 @@ syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "RouteP";
option java_outer_classname = "Route";
message Route {
repeated WayPoint way_points = 1;
message RouteRequest {
repeated WayPoint way_points = 1;
message WayPoint {
double distance = 2;
@@ -13,13 +13,7 @@ message Route {
}
}
message Direction {
enum Command {
stop = 0;
forward = 1;
backward = 2;
left = 3;
right = 4;
}
Command command = 1;
message RouteResponse {
int32 code = 1;
string errorMsg = 2;
}
+10
View File
@@ -0,0 +1,10 @@
syntax = "proto3";
package carkot;
option java_package = "proto.car";
option java_outer_classname = "RouteDone";
message RouteDoneResponse {
int32 code = 1;
string errorMsg = 2;
}