346 lines
16 KiB
JavaScript
Executable File
346 lines
16 KiB
JavaScript
Executable File
/***
|
|
* Receives GCode, processes it and moves the Data to the Roboter-Class
|
|
*/
|
|
const fs = require('fs');
|
|
|
|
|
|
class GCode{
|
|
|
|
static fileName = "GCodeFiles/log.gcode";
|
|
|
|
static containsMCode(s){
|
|
return s.indexOf('M1') == 0
|
|
}
|
|
|
|
static receiveMCode(robot, m){
|
|
|
|
m = m.split(" ");
|
|
if(m[0] == "M1"){
|
|
m.forEach((s) => {
|
|
if(s.includes("X")){ robot.xMotor += Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.xMotor += Number(s.substring(1, s.length));}
|
|
|
|
|
|
if(s.includes("Y")){ robot.alpha += Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.alpha += Number(s.substring(1, s.length));}
|
|
|
|
|
|
if(s.includes("Z")){ robot.beta += Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.beta += Number(s.substring(1, s.length));}
|
|
})
|
|
}
|
|
|
|
console.log("Empfangene Motor-Position (" + robot.xMotor.toPrecision(3)+ ", "+ robot.alpha.toPrecision(3)+ ", "+ robot.beta.toPrecision(3)+ ", "+ robot.a.toPrecision(5) + ", "+ robot.b.toPrecision(5)+ ", "+ robot.c.toPrecision(5)+ ") ");
|
|
robot.sendCommand();
|
|
}
|
|
|
|
static containsCommand(s){
|
|
if(s.indexOf('M1 ') !== -1){return true;} // M1-Commands = G1-Command only for Motor-Coordinates
|
|
if(s.indexOf('G') !== 0){return false;}
|
|
if(s.indexOf('G90') == 0){return true;}
|
|
if(s.indexOf('G91') == 0){return true;}
|
|
if(s.indexOf('G92') == 0){return true;} // G92 - Set Position
|
|
if(s.indexOf('G28') !== -1){return true;}
|
|
if(s.indexOf('G1 ') !== -1){return true;}
|
|
return false;
|
|
}
|
|
|
|
|
|
static getM114(robot){
|
|
let text = '{"position":{ "x":'+robot.x+
|
|
', "y":'+robot.y+
|
|
', "z":'+robot.z+
|
|
', "a":' +robot.phi +
|
|
', "b":' +robot.theta +
|
|
', "c":' +robot.psi + '},' +
|
|
'"motorCounts":{ "x":'+ robot.xMotor +
|
|
', "y":'+ robot.alpha +
|
|
', "z":'+ robot.beta +
|
|
', "a":'+ robot.a +
|
|
', "b":'+ robot.b +
|
|
', "c":'+ robot.c +
|
|
', "e":'+ 0.0 +
|
|
'}}';
|
|
return text;
|
|
}
|
|
|
|
|
|
static toPiMultiple(gCode){
|
|
if(gCode == undefined){return gCode;}
|
|
|
|
var multipleParameters = gCode.split(" ");
|
|
var newGString = "";
|
|
multipleParameters.forEach((paramet) => {
|
|
if(paramet == undefined || !paramet || paramet.length === 0 || paramet == " " || paramet ==""){
|
|
|
|
}
|
|
else if(['A', 'a', 'B', 'b', 'C', 'c','E','e'].includes(paramet.charAt(0)) )
|
|
{
|
|
var numberParameter = Number(paramet.substring(1, paramet.length))
|
|
newGString += " " + paramet[0] + String(numberParameter*Math.PI/180)
|
|
}
|
|
else{
|
|
newGString += " " + paramet;
|
|
}
|
|
});
|
|
return newGString.trim();
|
|
};
|
|
|
|
static receiveGCode(robot, g){
|
|
|
|
if(g == undefined) return;
|
|
|
|
g = g.toString("utf8");
|
|
|
|
var multipleCommands = g.split(" G");
|
|
var doProcessRest = false;
|
|
if(multipleCommands.length > 1){
|
|
doProcessRest = true;
|
|
g = multipleCommands[0];
|
|
}
|
|
|
|
g = g.split(" ");
|
|
|
|
var calculateNew = true;
|
|
var calculateFromMotorCoordinates = false;
|
|
|
|
if(g[0] == "G90") {robot.moveRelative = false; calculateNew = false;}
|
|
else if(g[0] == "G91") {robot.moveRelative = true; calculateNew = false;}
|
|
// G28 - Move to Home Position
|
|
else if(g[0] == "G28") {
|
|
robot.x = 0;
|
|
robot.y = robot.l1 + robot.l2 + robot.l3;
|
|
robot.z = 0;
|
|
robot.phi = -Math.PI/2;
|
|
robot.theta = Math.PI/2;
|
|
robot.psi = 0;
|
|
robot.e = 0;
|
|
}
|
|
else if(g[0] == "G1" && robot.moveRelative){
|
|
g.forEach((s) => {
|
|
if(s.includes("X")){ robot.x += Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.x += Number(s.substring(1, s.length));}
|
|
if(s.includes("Y")){ robot.y += Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.y += Number(s.substring(1, s.length));}
|
|
if(s.includes("Z")){ robot.z += Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.z += Number(s.substring(1, s.length));}
|
|
|
|
|
|
// abc in 2Pi-Angles
|
|
if(s.includes("A")){ robot.phi += Number(s.substring(1, s.length));}
|
|
if(s.includes("a")){ robot.phi += Number(s.substring(1, s.length));}
|
|
if(s.includes("B")){ robot.theta += Number(s.substring(1, s.length));}
|
|
if(s.includes("b")){ robot.theta += Number(s.substring(1, s.length));}
|
|
if(s.includes("C")){ robot.psi += Number(s.substring(1, s.length));}
|
|
if(s.includes("c")){ robot.psi += Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("E")){ robot.e += Number(s.substring(1, s.length));}
|
|
if(s.includes("e")){ robot.e += Number(s.substring(1, s.length));}
|
|
});
|
|
}
|
|
else if(g[0] == "M1" && robot.moveRelative){
|
|
calculateFromMotorCoordinates = true;
|
|
g.forEach((s) => {
|
|
if(s.includes("X")){ robot.xMotor += Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.xMotor += Number(s.substring(1, s.length));}
|
|
if(s.includes("Y")){ robot.alpha += Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.alpha += Number(s.substring(1, s.length));}
|
|
if(s.includes("Z")){ robot.beta += Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.beta += Number(s.substring(1, s.length));}
|
|
|
|
|
|
if(s.includes("A")){ robot.a += Number(s.substring(1, s.length));}
|
|
if(s.includes("a")){ robot.a += Number(s.substring(1, s.length));}
|
|
if(s.includes("B")){ robot.b += Number(s.substring(1, s.length));}
|
|
if(s.includes("b")){ robot.b += Number(s.substring(1, s.length));}
|
|
if(s.includes("C")){ robot.c += Number(s.substring(1, s.length));}
|
|
if(s.includes("c")){ robot.c += Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("E")){ robot.e += Number(s.substring(1, s.length));}
|
|
if(s.includes("e")){ robot.e += Number(s.substring(1, s.length));}
|
|
});
|
|
}
|
|
// Absolute-Positioning
|
|
else if(g[0] == "G1" && !robot.moveRelative){
|
|
g.forEach((s) => {
|
|
if(s.includes("X")){ robot.x = Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.x = Number(s.substring(1, s.length));}
|
|
if(s.includes("Y")){ robot.y = Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.y = Number(s.substring(1, s.length));}
|
|
if(s.includes("Z")){ robot.z = Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.z = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("A")){ robot.phi = Number(s.substring(1, s.length));}
|
|
if(s.includes("a")){ robot.phi = Number(s.substring(1, s.length));}
|
|
if(s.includes("B")){ robot.theta = Number(s.substring(1, s.length));}
|
|
if(s.includes("b")){ robot.theta = Number(s.substring(1, s.length));}
|
|
if(s.includes("C")){ robot.psi = Number(s.substring(1, s.length));}
|
|
if(s.includes("c")){ robot.psi = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("E")){ robot.e = Number(s.substring(1, s.length));}
|
|
if(s.includes("e")){ robot.e = Number(s.substring(1, s.length));}
|
|
});
|
|
}
|
|
else if(g[0] == "M1" && !robot.moveRelative){
|
|
calculateFromMotorCoordinates = true;
|
|
g.forEach((s) => {
|
|
if(s.includes("X")){ robot.xMotor = Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.xMotor = Number(s.substring(1, s.length));}
|
|
if(s.includes("Y")){ robot.alpha = Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.alpha = Number(s.substring(1, s.length));}
|
|
if(s.includes("Z")){ robot.beta = Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.beta = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("A")){ robot.a = Number(s.substring(1, s.length));}
|
|
if(s.includes("a")){ robot.a = Number(s.substring(1, s.length));}
|
|
if(s.includes("B")){ robot.b = Number(s.substring(1, s.length));}
|
|
if(s.includes("b")){ robot.b = Number(s.substring(1, s.length));}
|
|
if(s.includes("C")){ robot.c = Number(s.substring(1, s.length));}
|
|
if(s.includes("c")){ robot.c = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("E")){ robot.e = Number(s.substring(1, s.length));}
|
|
if(s.includes("e")){ robot.e = Number(s.substring(1, s.length));}
|
|
});
|
|
}
|
|
else if(g[0] == "G92"){ // G92 - Set Position
|
|
g.forEach((s) => {
|
|
if(s.includes("X")){ robot.xMotor = Number(s.substring(1, s.length));}
|
|
if(s.includes("x")){ robot.xMotor = Number(s.substring(1, s.length));}
|
|
if(s.includes("Y")){ robot.alpha = Number(s.substring(1, s.length));}
|
|
if(s.includes("y")){ robot.alpha = Number(s.substring(1, s.length));}
|
|
if(s.includes("Z")){ robot.beta = Number(s.substring(1, s.length));}
|
|
if(s.includes("z")){ robot.beta = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("A")){ robot.a = Number(s.substring(1, s.length));}
|
|
if(s.includes("a")){ robot.a = Number(s.substring(1, s.length));}
|
|
if(s.includes("B")){ robot.b = Number(s.substring(1, s.length));}
|
|
if(s.includes("b")){ robot.b = Number(s.substring(1, s.length));}
|
|
if(s.includes("C")){ robot.c = Number(s.substring(1, s.length));}
|
|
if(s.includes("c")){ robot.c = Number(s.substring(1, s.length));}
|
|
|
|
if(s.includes("E")){ robot.e = Number(s.substring(1, s.length));}
|
|
if(s.includes("e")){ robot.e = Number(s.substring(1, s.length));}
|
|
});
|
|
robot.calculatePositionFromMotorAngles();
|
|
calculateNew = false;
|
|
|
|
// ToDo: Send Command to update Position of Robot, because G92 should
|
|
// set the current Position to the given Coordinates without moving the Robot.
|
|
}
|
|
|
|
if(calculateNew && !calculateFromMotorCoordinates){
|
|
robot.calculateAngles3D();
|
|
robot.sendCommand();
|
|
}
|
|
|
|
if(calculateFromMotorCoordinates){
|
|
robot.calculatePositionFromMotorAngles();
|
|
robot.sendCommand();
|
|
}
|
|
|
|
|
|
// verarbeitet alle weiteren Commands in dieser Zeile.
|
|
if(doProcessRest){
|
|
multipleCommands.forEach((cmd) => {
|
|
if(cmd[0] != "G"){
|
|
this.receiveGCode(robot, "G"+cmd);
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////77
|
|
// Commands for Files
|
|
|
|
static removeStringFromFile(fileName, stringToRemove) {
|
|
try {
|
|
const data = fs.readFileSync(fileName, 'utf8');
|
|
const modifiedData = data.replace(new RegExp(stringToRemove, 'g'), '');
|
|
fs.writeFileSync(fileName, modifiedData, 'utf8');
|
|
} catch (err) {
|
|
console.error('Error:', err);
|
|
}
|
|
}
|
|
|
|
static ContainsFilesCommand(message){
|
|
if(message.indexOf('FPoint') !== -1){return true;} // Writes new Point (at end of file)
|
|
if(message.indexOf('FPlus') !== -1){return true;} // go to Next Position in Log File
|
|
if(message.indexOf('FMinus') !== -1){return true;} // go to Previous Position
|
|
if(message.indexOf('FFirst') !== -1){return true;} // set Cursour to First Position of Log File
|
|
if(message.indexOf('FLast') !== -1){return true;} // set Cursour to Last Position of Log File
|
|
|
|
|
|
if(message.indexOf('FShow') !== -1){return true;} // Shows/Sends GCode-File
|
|
if(message.indexOf('FList') !== -1){return true;} // Lists GCode-Files
|
|
if(message.indexOf('FLoad ') !== -1){return true;} // Loads File into Log
|
|
if(message.indexOf('FSave ') !== -1){return true;} // Saves Log to GCode-File
|
|
if(message.indexOf('FClear') !== -1){return true;} // Clears default Log File
|
|
|
|
if(message.indexOf('M20') !== -1){return true;} // M20 - List SD Card-Contents // https://marlinfw.org/docs/gcode/M020.html
|
|
if(message.indexOf('M23') !== -1){return true;} // M23 - Select SD file
|
|
if(message.indexOf('M28') !== -1){return true;} // M28 - Start SD write // M28 [B1] filename
|
|
if(message.indexOf('M29') !== -1){return true;} // M29 - Stop SD write
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
static receiveFC(robot, message){
|
|
|
|
if(message.indexOf('FShow') !== -1){
|
|
try {
|
|
const data = fs.readFileSync(this.fileName, 'utf8');
|
|
const reply = "XYZ__FShow__XYZ" + data; // prepend header
|
|
return reply.replaceAll("G91 ","").replaceAll("G90 ","").replace(/\s?\bt\d+\b\s?/g, '').trim();
|
|
|
|
} catch (err) {
|
|
console.error('Error:', err);
|
|
}
|
|
}
|
|
|
|
if(message.indexOf('FPoint') !== -1){
|
|
|
|
const secondsSinceEpoch = 10*Math.floor(Date.now() / 100);
|
|
|
|
var strGCode = String(`G90 G1 x${robot.x} y${robot.y} z${robot.z} a${(robot.phi*180/Math.PI).toFixed(2)} b${(robot.theta*180/Math.PI).toFixed(2)} c${(robot.psi*180/Math.PI).toFixed(2)} e${(robot.e*180/Math.PI).toFixed(2)} t${secondsSinceEpoch} f1000` )
|
|
this.removeStringFromFile(this.fileName, ';!')
|
|
fs.appendFileSync(this.fileName, strGCode+ ';!'+ '\r\n', 'utf8');
|
|
}
|
|
|
|
if(message.indexOf('FMinus') !== -1 || message.indexOf('FPlus') !== -1){
|
|
let lines = fs.readFileSync(this.fileName, 'utf8').split('\r\n');
|
|
|
|
let lineChange = -1;
|
|
|
|
// Process lines
|
|
for (let i = 0; i < lines.length; i++) {
|
|
if (lines[i].indexOf(';!') !== -1) {
|
|
if(message.indexOf('FMinus') !== -1 && i > 0){
|
|
lines[i - 1] += ';!';
|
|
lines[i] = lines[i].split(';!')[0];
|
|
var gCodePi = this.toPiMultiple(lines[i-1]);
|
|
this.receiveGCode(robot, gCodePi);
|
|
}
|
|
if(message.indexOf('FPlus') !== -1 && i < (lines.length-2) && lineChange == -1){
|
|
lines[i + 1] += ';!';
|
|
lines[i] = lines[i].split(';!')[0];
|
|
lineChange = i+1;
|
|
var gCodePi = this.toPiMultiple(lines[i+1]);
|
|
this.receiveGCode(robot, gCodePi);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write the updated content back
|
|
fs.writeFileSync(this.fileName, lines.join('\r\n'), 'utf8');
|
|
|
|
}
|
|
|
|
return GCode.getM114(robot);
|
|
}
|
|
}
|
|
|
|
module.exports = GCode
|
|
|