nur wenn xyz genaendert, dann senden

This commit is contained in:
ChK
2026-04-07 09:30:46 +02:00
parent 3d33ecd747
commit a47c168a22
11 changed files with 250 additions and 159 deletions

View File

@@ -2194,3 +2194,6 @@
2026-04-04T21:04:06.238Z ::ffff:172.21.0.5: G91 G1 Y-5 F100 2026-04-04T21:04:06.238Z ::ffff:172.21.0.5: G91 G1 Y-5 F100
2026-04-05T03:31:21.526Z ::ffff:172.21.0.5: FShow 2026-04-05T03:31:21.526Z ::ffff:172.21.0.5: FShow
2026-04-05T03:32:57.698Z ::ffff:172.21.0.5: FShow 2026-04-05T03:32:57.698Z ::ffff:172.21.0.5: FShow
2026-04-06T06:05:17.310Z ::ffff:172.21.0.5: FShow
2026-04-06T06:05:21.815Z ::ffff:172.21.0.5: FShow
2026-04-06T06:05:47.347Z ::ffff:172.21.0.5: FShow

View File

@@ -11175,3 +11175,6 @@
2026-04-05T20:36:01.566Z ::ffff:172.21.0.5: Ping 2026-04-05T20:36:01.566Z ::ffff:172.21.0.5: Ping
2026-04-05T20:36:06.553Z ::ffff:172.21.0.5: Ping 2026-04-05T20:36:06.553Z ::ffff:172.21.0.5: Ping
2026-04-05T20:36:06.563Z ::ffff:172.21.0.5: Ping 2026-04-05T20:36:06.563Z ::ffff:172.21.0.5: Ping
2026-04-06T06:05:26.867Z ::ffff:172.21.0.5: Ping
2026-04-06T06:05:31.886Z ::ffff:172.21.0.5: Ping
2026-04-06T06:05:52.364Z ::ffff:172.21.0.5: Ping

View File

@@ -17,16 +17,9 @@ class GCode{
m = m.split(" "); m = m.split(" ");
if(m[0] == "M1"){ if(m[0] == "M1"){
m.forEach((s) => { m.forEach((s) => {
if(s.includes("X")){ robot.xMotor += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.xMotor += Number(s.substring(1, s.length));}
if(s.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));}
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));}
}) })
} }
@@ -118,109 +111,68 @@ class GCode{
} }
else if(g[0] == "G1" && robot.moveRelative){ else if(g[0] == "G1" && robot.moveRelative){
g.forEach((s) => { g.forEach((s) => {
if(s.includes("X")){ robot.x += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.x += Number(s.substring(1, s.length)); robot.xMotorChanged = true;}
if(s.includes("x")){ robot.x += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.y += Number(s.substring(1, s.length)); robot.yMotorChanged = true;}
if(s.includes("Y")){ robot.y += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Z")){ robot.z += Number(s.substring(1, s.length)); robot.zMotorChanged = true;}
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 // abc in 2Pi-Angles
if(s.includes("A")){ robot.phi += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("A")){ robot.phi += Number(s.substring(1, s.length)); robot.aMotorChanged = true;}
if(s.includes("a")){ robot.phi += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("B")){ robot.theta += Number(s.substring(1, s.length)); robot.bMotorChanged = true;}
if(s.includes("B")){ robot.theta += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("C")){ robot.psi += Number(s.substring(1, s.length)); robot.cMotorChanged = true;}
if(s.includes("b")){ robot.theta += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("E")){ robot.e += Number(s.substring(1, s.length)); robot.eMotorChanged = true;}
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){ else if(g[0] == "M1" && robot.moveRelative){
calculateFromMotorCoordinates = true; calculateFromMotorCoordinates = true;
g.forEach((s) => { g.forEach((s) => {
if(s.includes("X")){ robot.xMotor += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.xMotor += Number(s.substring(1, s.length)); robot.xMotorChanged = true;}
if(s.includes("x")){ robot.xMotor += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.alpha += Number(s.substring(1, s.length)); robot.yMotorChanged = true;}
if(s.includes("Y")){ robot.alpha += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Z")){ robot.beta += Number(s.substring(1, s.length)); robot.zMotorChanged = true;}
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.toUpperCase().includes("A")){ robot.a += Number(s.substring(1, s.length)); robot.aMotorChanged = true;}
if(s.includes("A")){ robot.a += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("B")){ robot.b += Number(s.substring(1, s.length)); robot.bMotorChanged = true;}
if(s.includes("a")){ robot.a += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("C")){ robot.c += Number(s.substring(1, s.length)); robot.cMotorChanged = true;}
if(s.includes("B")){ robot.b += Number(s.substring(1, s.length));} if(s.toUpperCase().includes("E")){ robot.e += Number(s.substring(1, s.length)); robot.eMotorChanged = true;}
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 // Absolute-Positioning
else if(g[0] == "G1" && !robot.moveRelative){ else if(g[0] == "G1" && !robot.moveRelative){
g.forEach((s) => { g.forEach((s) => {
if(s.includes("X")){ robot.x = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.x = Number(s.substring(1, s.length)); robot.xMotorChanged = true;}
if(s.includes("x")){ robot.x = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.y = Number(s.substring(1, s.length)); robot.yMotorChanged = true;}
if(s.includes("Y")){ robot.y = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Z")){ robot.z = Number(s.substring(1, s.length)); robot.zMotorChanged = true;}
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.toUpperCase().includes("A")){ robot.phi = Number(s.substring(1, s.length)); robot.aMotorChanged = true;}
if(s.includes("a")){ robot.phi = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("B")){ robot.theta = Number(s.substring(1, s.length)); robot.bMotorChanged = true;}
if(s.includes("B")){ robot.theta = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("C")){ robot.psi = Number(s.substring(1, s.length)); robot.cMotorChanged = true;}
if(s.includes("b")){ robot.theta = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("E")){ robot.e = Number(s.substring(1, s.length)); robot.eMotorChanged = true;}
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){ else if(g[0] == "M1" && !robot.moveRelative){
calculateFromMotorCoordinates = true; calculateFromMotorCoordinates = true;
g.forEach((s) => { g.forEach((s) => {
if(s.includes("X")){ robot.xMotor = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.xMotor = Number(s.substring(1, s.length)); robot.xMotorChanged = true;}
if(s.includes("x")){ robot.xMotor = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.alpha = Number(s.substring(1, s.length)); robot.yMotorChanged = true;}
if(s.includes("Y")){ robot.alpha = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Z")){ robot.beta = Number(s.substring(1, s.length)); robot.zMotorChanged = true;}
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.toUpperCase().includes("A")){ robot.a = Number(s.substring(1, s.length)); robot.aMotorChanged = true;}
if(s.includes("a")){ robot.a = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("B")){ robot.b = Number(s.substring(1, s.length)); robot.bMotorChanged = true;}
if(s.includes("B")){ robot.b = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("C")){ robot.c = Number(s.substring(1, s.length)); robot.cMotorChanged = true;}
if(s.includes("b")){ robot.b = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("E")){ robot.e = Number(s.substring(1, s.length)); robot.eMotorChanged = true;}
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();
} }
else if(g[0] == "M92"){ // G92 - Set Position --- M92 in Radiant else if(g[0] == "M92"){ // G92 - Set Position --- M92 in Radiant
robot.createMotorPosition(); robot.createMotorPosition();
g.forEach((s) => { g.forEach((s) => {
if(s.includes("X")){ robot.xMotor = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("X")){ robot.xMotor = Number(s.substring(1, s.length)); robot.xMotorChanged = true;}
if(s.includes("x")){ robot.xMotor = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Y")){ robot.alpha = Number(s.substring(1, s.length)); robot.yMotorChanged = true;}
if(s.includes("Y")){ robot.alpha = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("Z")){ robot.beta = Number(s.substring(1, s.length)); robot.zMotorChanged = true;}
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.toUpperCase().includes("A")){ robot.a = Number(s.substring(1, s.length)); robot.aMotorChanged = true;}
if(s.includes("a")){ robot.a = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("B")){ robot.b = Number(s.substring(1, s.length)); robot.bMotorChanged = true;}
if(s.includes("B")){ robot.b = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("C")){ robot.c = Number(s.substring(1, s.length)); robot.cMotorChanged = true;}
if(s.includes("b")){ robot.b = Number(s.substring(1, s.length));} if(s.toUpperCase().includes("E")){ robot.e = Number(s.substring(1, s.length)); robot.eMotorChanged = true;}
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(); robot.calculatePositionFromMotorAngles();
calculateNew = false; calculateNew = false;

View File

@@ -1,68 +1,116 @@
const MotorPosition = require('./RobotMotorPosition.js') const MotorPosition = require('./RobotMotorPosition.js')
const telnetSender = require('./TelnetSenderGRBL.js')
class Robot{ class Robot{
constructor(l1, l2, l3) { constructor(l1, l2, l3) {
this.speedX = 200; // mm/min /** @type {number} Bewegungsgeschwindigkeit X-Achse in mm/min */
this.speedY = 200; this.speedX = 200;
/** @type {number} Bewegungsgeschwindigkeit Y-Achse in mm/min */
this.speedY = 200;
/** @type {number} Bewegungsgeschwindigkeit Z-Achse in mm/min */
this.speedZ = 200; this.speedZ = 200;
/** @type {number} Zeitstempel des zuletzt gesendeten Kommandos */
this.lastCommandSend = 0; this.lastCommandSend = 0;
if(this.lastCommandSend == 0){ this.lastCommandSend = Date.now() }; if(this.lastCommandSend == 0){ this.lastCommandSend = Date.now() };
/** @type {boolean} Animation aktiviert */
this.doAnimate = false; this.doAnimate = false;
this.l1 = l1; // Oberarm /** @type {number} Länge des Oberarms in mm */
this.l2 = l2; // Unterarm this.l1 = l1;
this.l3 = l3; // Hand-Länge /** @type {number} Länge des Unterarms in mm */
this.l2 = l2;
/** @type {number} Länge der Hand (Endeffector) in mm */
this.l3 = l3;
// Plan-Koordinaten - XYZ FingerSpitze // Plan-Koordinaten - XYZ FingerSpitze
/** @type {number} X-Position der Fingerspitze in mm */
this.x = 0; this.x = 0;
/** @type {number} Y-Position der Fingerspitze in mm */
this.y = 0; this.y = 0;
/** @type {number} Z-Position der Fingerspitze in mm */
this.z = 0; this.z = 0;
// Plan-Koordinaten - HandRichtung // Plan-Koordinaten - HandRichtung (Euler-Winkel)
this.phi = 0.0; // Euler-Winkel zwischen X-Achse - Laengengrad /** @type {number} Phi - Euler-Winkel (Längengrad): Rotation um Z-Achse in rad */
this.theta = -Math.PI/2; // Euler-Winkel zwischen Z-Achse und P - Breitengrad this.phi = 0.0;
this.psi = 0.0; // Euler-Winkel: Drehung des Handgelenks abweichend vom Breitengrad /** @type {number} Theta - Euler-Winkel (Breitengrad): Neigungswinkel der Handachse in rad */
this.theta = -Math.PI/2;
/** @type {number} Psi - Euler-Winkel: Zusätzliche Drehung des Handgelenks in rad */
this.psi = 0.0;
this.e = 0.0 // Finger-Distance /** @type {number} Finger-Abstands-Einstellung (Öffnungsweite) */
this.e = 0.0;
// Zwischen-Ergebnisse: Hand Punkt (nur für Tests sind die Public) // Zwischen-Ergebnisse: Handgelenk-Punkt (Koordinaten des Handgelenks, nur für Tests public)
/** @type {number} Handgelenk-Position X in mm (berechneter Zwischenwert) */
this.pX = 0.0; this.pX = 0.0;
/** @type {number} Handgelenk-Position Y in mm (berechneter Zwischenwert) */
this.pY = 0.0; this.pY = 0.0;
/** @type {number} Handgelenk-Position Z in mm (berechneter Zwischenwert) */
this.pZ = 0.0; this.pZ = 0.0;
// Motor-Koordinaten - Schulter, Ellebogen, Hand-Dreher // Motor-Koordinaten - Schulter, Ellebogen, Hand-Dreher
/** @type {number} X-Motor-Position (Schulterposition auf X-Schiene) in mm */
this.xMotor = 0; this.xMotor = 0;
this.alpha = 0; // =Y Motor /** @type {number} Alpha - Y-Motor-Winkel (Schulterposition) in rad */
this.beta = 0; // =Z Motor = Winkel die der Unterarm unter der Y-Achse ist. this.alpha = 0;
/** @type {number} Beta - Z-Motor-Winkel (Unterarm-Neigung unter Y-Achse) in rad */
this.beta = 0;
// Motor-Winkel fuer's Handgelenk this.xMotorChanged = false;
this.a = 0; // aMotor am Ellebogen this.yMotorChanged = false;
this.b = 0; // bMotor Handgelenk-Knicker this.zMotorChanged = false;
this.c = 0; // cMotor Hand-Dreher
this.eMotor = 0; // eMotor Finger-Distanz // Motor-Winkel für's Handgelenk
/** @type {number} a-Motor-Winkel: Rotation am Ellbogen in rad */
this.a = 0;
/** @type {number} b-Motor-Winkel: Handgelenk-Knicker-Winkel in rad */
this.b = 0;
/** @type {number} c-Motor-Winkel: Hand-Dreher-Rotation in rad */
this.c = 0;
this.aMotorChanged = false;
this.bMotorChanged = false;
this.cMotorChanged = false;
this.eMotorChanged = false;
/** @type {number} e-Motor-Wert: Finger-Abstands-Motor-Position */
this.eMotor = 0;
/** @type {number} Zeitstempel des letzten verarbeiteten Kommandos */
this.oldCommandTime = Date.now(); this.oldCommandTime = Date.now();
/** @type {Function[]} Array von Visualisierungs-Funktionen */
this.showFunctions = []; this.showFunctions = [];
/** @type {Object[]} Gespeicherte Roboterpositionen/Punkte */
this.savedPoints = []; this.savedPoints = [];
/** @type {number} Index des aktuell angesteuerten Punktes */
this.atPointNr = 0; this.atPointNr = 0;
this.t = 0; // TimeStamp of this Point /** @type {number} Zeitstempel des aktuellen Punktes in ms */
this.t = 0;
/** @type {boolean} Relative oder absolute Bewegung (true = relativ) */
this.moveRelative = true; this.moveRelative = true;
/** @type {Object|null} Python-Sender-Instanz für GCode-Kommunikation */
this.pythonSender = null; this.pythonSender = null;
/** @type {Object[]} Array von Kommando-Empfängern */
this.cmdReceivers = []; this.cmdReceivers = [];
} }
createMotorPosition(){ createMotorPosition(){
this.motorPosition = new MotorPosition(this.xMotor, this.alpha, this.beta, this.a, this.b, this.c, this.eMotor); this.motorPosition = new MotorPosition(this.xMotor, this.alpha, this.beta, this.a, this.b, this.c, this.eMotor);
this.motorPosition.xMotorChanged = this.xMotorChanged;
this.motorPosition.yMotorChanged = this.yMotorChanged;
this.motorPosition.zMotorChanged = this.zMotorChanged;
this.motorPosition.aMotorChanged = this.aMotorChanged;
this.motorPosition.bMotorChanged = this.bMotorChanged;
this.motorPosition.cMotorChanged = this.cMotorChanged;
this.motorPosition.eMotorChanged = this.eMotorChanged;
} }
// Berechnet aus XYZ die Motor-Winkel für den GCode // Berechnet aus XYZ die Motor-Winkel für den GCode
@@ -188,12 +236,7 @@ class Robot{
console.log("Robot.sendCommand: Motor-Pos: x=", this.motorPosition.x.toFixed(3), "yMotor=",this.motorPosition.y.toFixed(3), "zMotor=",this.motorPosition.z.toFixed(3), "aM=", this.motorPosition.a.toFixed(3), "bM=", this.motorPosition.b.toFixed(3), "cM=", this.motorPosition.c.toFixed(3), " e=", this.motorPosition.e.toFixed(3)); console.log("Robot.sendCommand: Motor-Pos: x=", this.motorPosition.x.toFixed(3), "yMotor=",this.motorPosition.y.toFixed(3), "zMotor=",this.motorPosition.z.toFixed(3), "aM=", this.motorPosition.a.toFixed(3), "bM=", this.motorPosition.b.toFixed(3), "cM=", this.motorPosition.c.toFixed(3), " e=", this.motorPosition.e.toFixed(3));
this.cmdReceivers.forEach(receiver => { this.cmdReceivers.forEach(receiver => {
if(cmd == "G1"){
receiver.moveTo(this.motorPositionOld, this.motorPosition);
}
else{
receiver.execCommand(cmd,this.motorPositionOld, this.motorPosition); receiver.execCommand(cmd,this.motorPositionOld, this.motorPosition);
}
}); });
} }
} }

View File

@@ -13,6 +13,14 @@ module.exports = class RobotMotorPosition{
this.e = e; // Finger open this.e = e; // Finger open
this.time = Date.now(); this.time = Date.now();
this.xMotorChanged = false;
this.yMotorChanged = false;
this.zMotorChanged = false;
this.aMotorChanged = false;
this.bMotorChanged = false;
this.cMotorChanged = false;
this.eMotorChanged = false;
} }
} }

View File

@@ -75,27 +75,27 @@ module.exports = class TelnetSenderGRBL{
var data = strCommand.toString("utf-8"); var data = strCommand.toString("utf-8");
if(this.xAxisGrbl == "x"){ if(this.xAxisGrbl == "x" && mNew.xMotorChanged){
data += " x" + (mNew.x).toFixed(2).toString(); data += " x" + (mNew.x).toFixed(2).toString();
} }
if(this.xAxisGrbl == "y"){ if(this.xAxisGrbl == "y" && mNew.yMotorChanged){
data += " x" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " x" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.xAxisGrbl == "z"){ if(this.xAxisGrbl == "z" && mNew.zMotorChanged){
data += " x" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); data += " x" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.xAxisGrbl == "a"){ if(this.xAxisGrbl == "a" && mNew.aMotorChanged){
// This is the case for the Ellbow, when the Motor is connected to the X-Port of the FluidNC // This is the case for the Ellbow, when the Motor is connected to the X-Port of the FluidNC
data += " x" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); data += " x" + (mNew.a * 180 / Math.PI).toFixed(2).toString();
} }
if(this.xAxisGrbl == "b"){ if(this.xAxisGrbl == "b" && (mNew.bMotorChanged || mNew.cMotorChanged)){
data += " x" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " x" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.xAxisGrbl == "c"){ if(this.xAxisGrbl == "c" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
// Runs correctly, substracts the "b" axis, uses the "c" axis to send to the x-Motor wich is in this case the hand-twist // Runs correctly, substracts the "b" axis, uses the "c" axis to send to the x-Motor wich is in this case the hand-twist
data += " x" + ((-1)*mNew.b * 180 / Math.PI + (mNew.c * 180 / Math.PI) ).toFixed(2).toString(); data += " x" + ((-1)*mNew.b * 180 / Math.PI + (mNew.c * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.xAxisGrbl == "e"){ if(this.xAxisGrbl == "e" && mNew.eMotorChanged){
//This is the case for the Hand, when the Open-Close Motor is connected to the X-Port of FluidNC //This is the case for the Hand, when the Open-Close Motor is connected to the X-Port of FluidNC
var handUpDown = mNew.b * 180 * factorTurnLift / Math.PI ; var handUpDown = mNew.b * 180 * factorTurnLift / Math.PI ;
var handTurn = mNew.c*180/Math.PI ; var handTurn = mNew.c*180/Math.PI ;
@@ -104,111 +104,109 @@ module.exports = class TelnetSenderGRBL{
if(this.yAxisGrbl == "x"){ if(this.yAxisGrbl == "x" && mNew.xMotorChanged){
data += " y" + (mNew.x ).toFixed(2).toString(); data += " y" + (mNew.x ).toFixed(2).toString();
} }
if(this.yAxisGrbl == "y"){ if(this.yAxisGrbl == "y" && mNew.yMotorChanged){
data += " y" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " y" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.yAxisGrbl == "z"){ if(this.yAxisGrbl == "z" && mNew.zMotorChanged){
data += " y" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); data += " y" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.yAxisGrbl == "a"){ if(this.yAxisGrbl == "a" && mNew.aMotorChanged){
data += " y" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); data += " y" + (mNew.a * 180 / Math.PI).toFixed(2).toString();
} }
if(this.yAxisGrbl == "b"){ if(this.yAxisGrbl == "b" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " y" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " y" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.yAxisGrbl == "c"){ if(this.yAxisGrbl == "c" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
// This is the case if the hand-rotation-turner is connected to the FluidNC-Y // This is the case if the hand-rotation-turner is connected to the FluidNC-Y
var handUpDown = (mNew.b * 180 / Math.PI ) * factorTurnLift; var handUpDown = (mNew.b * 180 / Math.PI ) * factorTurnLift;
var handTurn = ( mNew.c*180/Math.PI ) ; var handTurn = ( mNew.c*180/Math.PI ) ;
data += " y" + (-1.0*(handUpDown) + handTurn).toFixed(2).toString(); data += " y" + (-1.0*(handUpDown) + handTurn).toFixed(2).toString();
} }
if(this.yAxisGrbl == "e"){ if(this.yAxisGrbl == "e" && (mNew.eMotorChanged)){
data += " y" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); data += " y" + (mNew.e * 180 / Math.PI).toFixed(2).toString();
} }
if(this.zAxisGrbl == "x"){ if(this.zAxisGrbl == "x" && mNew.xMotorChanged){
data += " z" + (mNew.x).toFixed(2).toString(); data += " z" + (mNew.x).toFixed(2).toString();
} }
if(this.zAxisGrbl == "y"){ if(this.zAxisGrbl == "y" && mNew.yMotorChanged){
data += " z" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " z" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.zAxisGrbl == "z"){ if(this.zAxisGrbl == "z" && mNew.zMotorChanged){
data += " z" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); data += " z" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.zAxisGrbl == "a"){ if(this.zAxisGrbl == "a" && mNew.aMotorChanged){
data += " z" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); data += " z" + (mNew.a * 180 / Math.PI).toFixed(2).toString();
} }
if(this.zAxisGrbl == "b"){ if(this.zAxisGrbl == "b" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
// This is the case of the Hand, when the Up-Down-Motor is connected to the FluidNC-Z // This is the case of the Hand, when the Up-Down-Motor is connected to the FluidNC-Z
data += " z" + ( mNew.b * 180 / Math.PI ).toFixed(2).toString(); data += " z" + ( mNew.b * 180 / Math.PI ).toFixed(2).toString();
} }
if(this.zAxisGrbl == "c"){ if(this.zAxisGrbl == "c" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " z" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " z" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.zAxisGrbl == "e"){ if(this.zAxisGrbl == "e" && (mNew.eMotorChanged)){
data += " z" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); data += " z" + (mNew.e * 180 / Math.PI).toFixed(2).toString();
} }
if(this.aAxisGrbl == "x"){ if(this.aAxisGrbl == "x" && mNew.xMotorChanged){
data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.aAxisGrbl == "y"){ if(this.aAxisGrbl == "y" && mNew.yMotorChanged){
data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " a" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.aAxisGrbl == "z"){ if(this.aAxisGrbl == "z" && mNew.zMotorChanged){
data += " a" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); data += " a" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.aAxisGrbl == "a"){ if(this.aAxisGrbl == "a" && mNew.aMotorChanged){
data += " a" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); data += " a" + (mNew.a * 180 / Math.PI).toFixed(2).toString();
} }
if(this.aAxisGrbl == "b"){ if(this.aAxisGrbl == "b" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " a" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " a" + (mNew.b * 180 / Math.PI+(mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.aAxisGrbl == "c"){ if(this.aAxisGrbl == "c" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " a" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " a" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.aAxisGrbl == "e"){ if(this.aAxisGrbl == "e" && mNew.eMotorChanged){
// ToDo Mai 2024 // ToDo Mai 2024
data += " a" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); data += " a" + (mNew.e * 180 / Math.PI).toFixed(2).toString();
} }
if(this.bAxisGrbl == "x" && mNew.xMotorChanged){
if(this.bAxisGrbl == "x"){
data += " b" + (mNew.x).toFixed(2).toString(); data += " b" + (mNew.x).toFixed(2).toString();
} }
if(this.bAxisGrbl == "y"){ if(this.bAxisGrbl == "y" && mNew.yMotorChanged){
data += " b" + (mNew.y * 180 / Math.PI).toFixed(2).toString(); data += " b" + (mNew.y * 180 / Math.PI).toFixed(2).toString();
} }
if(this.bAxisGrbl == "z"){ if(this.bAxisGrbl == "z" && mNew.zMotorChanged){
data += " b" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString(); data += " b" + ((mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI) ).toFixed(2).toString();
} }
if(this.bAxisGrbl == "a"){ if(this.bAxisGrbl == "a" && mNew.aMotorChanged){
data += " b" + (mNew.a * 180 / Math.PI).toFixed(2).toString(); data += " b" + (mNew.a * 180 / Math.PI).toFixed(2).toString();
} }
if(this.bAxisGrbl == "b"){ if(this.bAxisGrbl == "b" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " b" + (mNew.b * 180 / Math.PI).toFixed(2).toString(); data += " b" + (mNew.b * 180 / Math.PI).toFixed(2).toString();
} }
if(this.bAxisGrbl == "c"){ if(this.bAxisGrbl == "c" && (mNew.bMotorChanged || mNew.cMotorChanged || mNew.zMotorChanged)){
data += " b" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString(); data += " b" + (mNew.c * 180 / Math.PI + (mNew.b * 180 / Math.PI) + (mNew.z * 180 / Math.PI) - (mNew.y * 180 / Math.PI)).toFixed(2).toString();
} }
if(this.bAxisGrbl == "e"){ if(this.bAxisGrbl == "e" && mNew.eMotorChanged){
data += " b" + (mNew.e * 180 / Math.PI).toFixed(2).toString(); data += " b" + (mNew.e * 180 / Math.PI).toFixed(2).toString();
} }
if(strCommand == "G1"){
data += " f"+(maxSpeedF.toFixed(2).toString())
}
if(this.tSocket && data.toString("utf-8").length > 3){ if(this.tSocket && data.toString("utf-8").length > 3){
if(strCommand == "G1"){
data += " f"+(maxSpeedF.toFixed(2).toString())
}
if(!this.isTestMode){ console.log("" + this.urlGRBLstr + " gets the message: " + data.toString("utf-8"))} if(!this.isTestMode){ console.log("" + this.urlGRBLstr + " gets the message: " + data.toString("utf-8"))}
this.tSocket.write( data.toString("utf-8") + "\r\n"); this.tSocket.write( data.toString("utf-8") + "\r\n");
} }

View File

@@ -55,7 +55,7 @@ describe("Robot G92", () => {
}); });
// G92 y2.8 z131.0 // G92 y2.8 z131.0
test("ReadPosition -> G92()", () => { test("ReadPosition -> G92() test ob nur bestimmte Achsen gesendet werden", () => {
// === Instanz A: Vorwärts-Kinematik (XYZ -> Motorwinkel) === // === Instanz A: Vorwärts-Kinematik (XYZ -> Motorwinkel) ===
const L1 = 300; const L1 = 300;
@@ -75,14 +75,43 @@ describe("Robot G92", () => {
GCode.receiveGCode(robot,"M92 y0.049 z2.286"); GCode.receiveGCode(robot,"M92 y0.049 z2.286");
const strExpect1 = 'G92 x0.00 y2.81 z128.17\r\n'; //const strExpect1 = 'G92 x0.00 y2.81 z128.17\r\n';
const strExpect1 = 'G92 y2.81 z128.17\r\n'; // x soll eben nicht gesendet werden.
const strExpect2 = 'G92 y2.81 z128.17\r\n'; const strExpect2 = 'G92 y2.81 z128.17\r\n';
allowedValues = [strExpect1, strExpect2]; allowedValues = [strExpect1, strExpect2];
expect(allowedValues).toContain(telnetSender1.tSocket.written); expect(allowedValues).toContain(telnetSender1.tSocket.written);
expect(telnetSender2.tSocket.written.length).toBe(0); // kein GCode für Ellbow
// ("Wenn nur G92 x3 gegeben wird, dann wird trotzdem auch y und z gesendet. schlecht." ); // ("Wenn nur G92 x3 gegeben wird, dann wird trotzdem auch y und z gesendet. schlecht." );
}); });
// G92 y2.8 z131.0
test("ReadPosition -> G92() test ob nur bestimmte Achsen gesendet werden", () => {
// === Instanz A: Vorwärts-Kinematik (XYZ -> Motorwinkel) ===
const L1 = 300;
const L2 = 300;
const L3 = 20;
const robot = new Robot(L1, L2, L3)
var telnetSender1 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 2300, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z");
var telnetSender2 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 5000, xAxisGrbl = "a", yAxisGrbl = null, zAxisGrbl = null);
var telnetSender3 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 5000, xAxisGrbl = "c", yAxisGrbl = "e", zAxisGrbl = "b");
robot.cmdReceivers.push(telnetSender1);
robot.cmdReceivers.push(telnetSender2);
robot.cmdReceivers.push(telnetSender3);
GCode.receiveGCode(robot,"M92 a0.20");
expect(telnetSender1.tSocket.written.length).toBe(0); // kein GCode für XYZ
expect(telnetSender2.tSocket.written).toBe('G92 x11.46\r\n');
expect(telnetSender3.tSocket.written.length).toBe(0); // kein GCode für XYZ
// ("Wenn nur G92 x3 gegeben wird, dann wird trotzdem auch y und z gesendet. schlecht." );
});
}); });

View File

@@ -1,5 +1,6 @@
const GCode = require('../robot/GCode.js'); const GCode = require('../robot/GCode.js');
const Robot = require('../robot/Robot.js');
var TenetSender = require('../robot/TelnetSenderGRBL.js')
test('G91 ist ein GCode Command', () => { test('G91 ist ein GCode Command', () => {
var x = GCode.containsCommand("G91") ; var x = GCode.containsCommand("G91") ;
@@ -12,4 +13,37 @@ test('G28 ist ein GCode Command', () => {
}); });
beforeAll(() => {
jest.spyOn(console, 'log').mockImplementation(() => {})
})
afterAll(() => {
jest.restoreAllMocks()
})
test("ReadPosition -> G1", () => {
const L1 = 300;
const L2 = 300;
const L3 = 20;
const robot = new Robot(L1, L2, L3)
var telnetSender1 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 2300, xAxisGrbl = "x", yAxisGrbl = "y", zAxisGrbl = "z");
var telnetSender2 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 5000, xAxisGrbl = "a", yAxisGrbl = null, zAxisGrbl = null);
var telnetSender3 = new TenetSender(urlGRBL = "test.test", maxSpeedF = 5000, xAxisGrbl = "c", yAxisGrbl = "e", zAxisGrbl = "b");
robot.cmdReceivers.push(telnetSender1);
robot.cmdReceivers.push(telnetSender2);
robot.cmdReceivers.push(telnetSender3);
GCode.receiveGCode(robot,"G1 x120");
expect(telnetSender1.tSocket.written).toContain('G1 x1')
});

View File

@@ -98,8 +98,8 @@ describe('Robot.sendCommand & cmdReceivers', () => {
test('Receiver-Reihenfolge bleibt erhalten', () => { test('Receiver-Reihenfolge bleibt erhalten', () => {
const order = [] const order = []
const r1 = { moveTo: () => order.push('r1') } const r1 = { execCommand: () => order.push('r1') }
const r2 = { moveTo: () => order.push('r2') } const r2 = { execCommand: () => order.push('r2') }
robot.cmdReceivers.push(r1, r2) robot.cmdReceivers.push(r1, r2)
robot.sendCommand() robot.sendCommand()

View File

@@ -19,6 +19,9 @@ describe("TelnetSenderGRBL.execCommand", () => {
// Provide some sample motion data // Provide some sample motion data
const mOld = { x: 0, y: 0, z: 0, a:0, b:0, c:0, e:0 }; // not used in your code const mOld = { x: 0, y: 0, z: 0, a:0, b:0, c:0, e:0 }; // not used in your code
const mNew = { x: 12.34, y: Math.PI/2, z: 0, a:0, b:0, c:0, e:0 }; const mNew = { x: 12.34, y: Math.PI/2, z: 0, a:0, b:0, c:0, e:0 };
mNew.xMotorChanged = true;
mNew.yMotorChanged = true;
mNew.zMotorChanged = true;
sender.execCommand("G1", mOld, mNew); sender.execCommand("G1", mOld, mNew);
@@ -44,6 +47,11 @@ describe("TelnetSenderGRBL.execCommand", () => {
const mOld = { x: 0, y: 0, z: 0, a:Math.PI, b:0, c:0, e:0 }; // not used in your code const mOld = { x: 0, y: 0, z: 0, a:Math.PI, b:0, c:0, e:0 }; // not used in your code
const mNew = { x: 12.34, y: Math.PI/2, z: 0, a:Math.PI/8, b:0, c:0, e:0 }; const mNew = { x: 12.34, y: Math.PI/2, z: 0, a:Math.PI/8, b:0, c:0, e:0 };
mNew.xMotorChanged = true;
mNew.yMotorChanged = true;
mNew.zMotorChanged = true;
mNew.aMotorChanged = true;
sender.execCommand("G1", mOld, mNew); sender.execCommand("G1", mOld, mNew);
// ✅ verify output // ✅ verify output
@@ -66,6 +74,9 @@ describe("TelnetSenderGRBL.execCommand", () => {
// Provide some sample motion data // Provide some sample motion data
const mOld = { x: 0, y: 0, z: 0, a:0, b:0, c:0, e:0 }; // not used in your code const mOld = { x: 0, y: 0, z: 0, a:0, b:0, c:0, e:0 }; // not used in your code
const mNew = { x: 12.34, y: 1.0, z: 2.0, a:0, b:0, c:0, e:0 }; const mNew = { x: 12.34, y: 1.0, z: 2.0, a:0, b:0, c:0, e:0 };
mNew.xMotorChanged = true;
mNew.yMotorChanged = true;
mNew.zMotorChanged = true;
sender.execCommand("G92", mOld, mNew); sender.execCommand("G92", mOld, mNew);

View File

@@ -11,6 +11,16 @@ class MockCmdReceiver {
}) })
} }
execCommand(cmd, oldPos, newPos) {
this.calls.push({
cmd,
oldPos,
newPos
})
}
get callCount() { get callCount() {
return this.calls.length return this.calls.length
} }