/*** * Receives GCode, processes it and moves the Data to the Roboter-Class */ const fs = require('fs'); const GCodeParser = require('./GCodeParser'); 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.toUpperCase().includes("X")){ robot.xMotor += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.alpha += Number(s.substring(1, s.length));} if(s.toUpperCase().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){ const commands = GCodeParser.parse(g); if (!commands.length) return; commands.forEach(parsed => { if (!parsed || !parsed.command) { return; } const cmd = parsed.command; const params = parsed.params || {}; if (cmd === 'G90') { robot.moveRelative = false; return; } if (cmd === 'G91') { robot.moveRelative = true; return; } if (cmd === '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; robot.calculateAngles3D(); robot.sendCommand(); return; } if (cmd === 'G1') { if (robot.moveRelative) { if (Number.isFinite(params.X)) { robot.x += params.X; robot.xMotorChanged = true; } if (Number.isFinite(params.Y)) { robot.y += params.Y; robot.yMotorChanged = true; } if (Number.isFinite(params.Z)) { robot.z += params.Z; robot.zMotorChanged = true; } if (Number.isFinite(params.A)) { robot.phi += params.A; robot.aMotorChanged = true; } if (Number.isFinite(params.B)) { robot.theta += params.B; robot.bMotorChanged = true; } if (Number.isFinite(params.C)) { robot.psi += params.C; robot.cMotorChanged = true; } if (Number.isFinite(params.E)) { robot.e += params.E; robot.eMotorChanged = true; } if (Number.isFinite(params.F)) { robot.feedrate = params.F; } } else { if (Number.isFinite(params.X)) { robot.x = params.X; robot.xMotorChanged = true; } if (Number.isFinite(params.Y)) { robot.y = params.Y; robot.yMotorChanged = true; } if (Number.isFinite(params.Z)) { robot.z = params.Z; robot.zMotorChanged = true; } if (Number.isFinite(params.A)) { robot.phi = params.A; robot.aMotorChanged = true; } if (Number.isFinite(params.B)) { robot.theta = params.B; robot.bMotorChanged = true; } if (Number.isFinite(params.C)) { robot.psi = params.C; robot.cMotorChanged = true; } if (Number.isFinite(params.E)) { robot.e = params.E; robot.eMotorChanged = true; } if (Number.isFinite(params.F)) { robot.feedrate = params.F; } } robot.calculateAngles3D(); robot.sendCommand(); return; } if (cmd === 'M1') { if (robot.moveRelative) { if (Number.isFinite(params.X)) { robot.xMotor += params.X; robot.xMotorChanged = true; } if (Number.isFinite(params.Y)) { robot.alpha += params.Y; robot.yMotorChanged = true; } if (Number.isFinite(params.Z)) { robot.beta += params.Z; robot.zMotorChanged = true; } if (Number.isFinite(params.A)) { robot.a += params.A; robot.aMotorChanged = true; } if (Number.isFinite(params.B)) { robot.b += params.B; robot.bMotorChanged = true; } if (Number.isFinite(params.C)) { robot.c += params.C; robot.cMotorChanged = true; } if (Number.isFinite(params.E)) { robot.e += params.E; robot.eMotorChanged = true; } } else { if (Number.isFinite(params.X)) { robot.xMotor = params.X; robot.xMotorChanged = true; } if (Number.isFinite(params.Y)) { robot.alpha = params.Y; robot.yMotorChanged = true; } if (Number.isFinite(params.Z)) { robot.beta = params.Z; robot.zMotorChanged = true; } if (Number.isFinite(params.A)) { robot.a = params.A; robot.aMotorChanged = true; } if (Number.isFinite(params.B)) { robot.b = params.B; robot.bMotorChanged = true; } if (Number.isFinite(params.C)) { robot.c = params.C; robot.cMotorChanged = true; } if (Number.isFinite(params.E)) { robot.e = params.E; robot.eMotorChanged = true; } } robot.calculatePositionFromMotorAngles(); robot.sendCommand(); return; } if (cmd === 'M92') { robot.createMotorPosition(); if (Number.isFinite(params.X)) { robot.xMotor = params.X; robot.xMotorChanged = true; } if (Number.isFinite(params.Y)) { robot.alpha = params.Y; robot.yMotorChanged = true; } if (Number.isFinite(params.Z)) { robot.beta = params.Z; robot.zMotorChanged = true; } if (Number.isFinite(params.A)) { robot.a = params.A; robot.aMotorChanged = true; } if (Number.isFinite(params.B)) { robot.b = params.B; robot.bMotorChanged = true; } if (Number.isFinite(params.C)) { robot.c = params.C; robot.cMotorChanged = true; } if (Number.isFinite(params.E)) { robot.e = params.E; robot.eMotorChanged = true; } robot.calculatePositionFromMotorAngles(); robot.sendCommand('G92'); return; } }); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////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