G92 > send-to-ESP
This commit is contained in:
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@@ -11,6 +11,22 @@
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"restart": true,
|
||||
"timeout": 10000
|
||||
},
|
||||
{
|
||||
"name": "Debug npm test",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npm",
|
||||
"runtimeArgs": ["run", "test"],
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Debug current test file",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/node_modules/jest/bin/jest.js",
|
||||
"args": ["--runInBand", "${file}"],
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2192,3 +2192,5 @@
|
||||
2026-04-04T21:04:06.177Z ::ffff:172.21.0.5: G91 G1 Y-5 F100
|
||||
2026-04-04T21:04:06.206Z ::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:32:57.698Z ::ffff:172.21.0.5: FShow
|
||||
|
||||
3128
logs/pings.log
3128
logs/pings.log
File diff suppressed because it is too large
Load Diff
113
public/allApps.css
Normal file
113
public/allApps.css
Normal file
@@ -0,0 +1,113 @@
|
||||
/* =========================================================
|
||||
allApps.css — Gemeinsames UI-Fundament für alle Robot-Apps
|
||||
(layout-neutral)
|
||||
========================================================= */
|
||||
|
||||
/* ---------- Design Tokens ---------- */
|
||||
:root {
|
||||
--bg: #0b1c2d;
|
||||
--panel: #132c44;
|
||||
--border: #0e1822;
|
||||
--text: #e0e6ed;
|
||||
--muted: #9aa6b2;
|
||||
--accent: #a4bbd4;
|
||||
|
||||
--radius: 8px;
|
||||
--gap: 16px;
|
||||
--border-subtle: rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
/* ---------- Reset & Base ---------- */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 16px;
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont,
|
||||
"Segoe UI", Roboto, Inter, Arial, sans-serif;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#dddddd -20%,
|
||||
var(--bg) 130%
|
||||
);
|
||||
color: var(--text);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ---------- Headings ---------- */
|
||||
h1 {
|
||||
margin: 0 0 16px;
|
||||
font-size: 20px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* ---------- Sections Container ---------- */
|
||||
/* Grid-Spalten werden von der jeweiligen App definiert */
|
||||
.sections {
|
||||
display: grid;
|
||||
gap: var(--gap);
|
||||
}
|
||||
|
||||
/* ---------- Section Card ---------- */
|
||||
.section {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
padding: 22px 20px;
|
||||
}
|
||||
|
||||
/* Semantische Breitenklassen (wirken nur,
|
||||
wenn die App ein entsprechendes Grid definiert) */
|
||||
.section.full {}
|
||||
.section.half {}
|
||||
.section.quarter {}
|
||||
.section.eighth {}
|
||||
|
||||
/* ---------- Section Header / Collapse ---------- */
|
||||
.section > h2 {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* Collapse Arrow */
|
||||
.section > h2::after {
|
||||
content: "▼";
|
||||
font-size: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
/* Collapsed state */
|
||||
.section.collapsed > h2::after {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
/* Hide content when collapsed */
|
||||
.section.collapsed > :not(h2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ---------- Generic Lists ---------- */
|
||||
.section ul {
|
||||
margin: 10px 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.section li {
|
||||
padding: 4px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
@@ -5,25 +5,26 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Robot Driver Info</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Math&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="allApps.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Robot Driver Status</h1>
|
||||
<!--<h1>Robot Driver Status</h1>-->
|
||||
|
||||
<div class="sections">
|
||||
<div id="status" class="section half" data-id="clients">
|
||||
<h2>Verbundene WebClients</h2>
|
||||
<h2>WebClients</h2>
|
||||
<ul id="clients"></ul>
|
||||
</div>
|
||||
|
||||
<div id="senders" class="section half" data-id="senders">
|
||||
<h2>Verbundene FluidNC-Controller</h2>
|
||||
<h2>FluidNC-Controller</h2>
|
||||
<ul id="senderList"></ul>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="driverState" class="section half" data-id="driver">
|
||||
<h2>Zustand Driver</h2>
|
||||
<h2>Position Driver</h2>
|
||||
<ul class="state-grid">
|
||||
<li><span>X</span><span id="state-x">–</span></li>
|
||||
<li><span>Y</span><span id="state-y">–</span></li>
|
||||
@@ -40,7 +41,7 @@
|
||||
|
||||
|
||||
<div id="motorState" class="section half" data-id="motors">
|
||||
<h2>Zustand Motoren</h2>
|
||||
<h2>Postion Motoren</h2>
|
||||
<ul class="state-grid">
|
||||
<li><span>X</span><span id="motor-x">–</span></li>
|
||||
<li><span>Y</span><span id="motor-y">–</span></li>
|
||||
@@ -57,12 +58,12 @@
|
||||
|
||||
|
||||
<div id="commands" class="section" data-id="commands">
|
||||
<h2>Letzte Commands</h2>
|
||||
<h2>Commands</h2>
|
||||
<ul id="commandList"></ul>
|
||||
</div>
|
||||
|
||||
<div id="pings" class="section" data-id="pings">
|
||||
<h2>Letzte Ping Nachrichten</h2>
|
||||
<h2>Ping Messages</h2>
|
||||
<ul id="pingList"></ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
:root {
|
||||
--bg: #0b1c2d;
|
||||
--panel: #132c44;
|
||||
--border: #1e3b58;
|
||||
--border: #0e1822;
|
||||
--text: #e0e6ed;
|
||||
--accent: #6fb3ff;
|
||||
--accent: #a4bbd4;
|
||||
}
|
||||
|
||||
* {
|
||||
|
||||
@@ -202,7 +202,8 @@ class GCode{
|
||||
if(s.includes("e")){ robot.e = Number(s.substring(1, s.length));}
|
||||
});
|
||||
}
|
||||
else if(g[0] == "G92"){ // G92 - Set Position
|
||||
else if(g[0] == "M92"){ // G92 - Set Position --- M92 in Radiant
|
||||
robot.createMotorPosition();
|
||||
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));}
|
||||
@@ -226,6 +227,7 @@ class GCode{
|
||||
|
||||
// ToDo: Send Command to update Position of Robot, because G92 should
|
||||
// set the current Position to the given Coordinates without moving the Robot.
|
||||
robot.sendCommand("G92");
|
||||
}
|
||||
|
||||
if(calculateNew && !calculateFromMotorCoordinates){
|
||||
|
||||
@@ -180,7 +180,7 @@ class Robot{
|
||||
while(this.theta < -Math.PI){this.theta += 2*Math.PI}
|
||||
}
|
||||
|
||||
sendCommand(){
|
||||
sendCommand(cmd="G1"){
|
||||
if(this.motorPosition == null){this.createMotorPosition() }
|
||||
this.motorPositionOld = this.motorPosition;
|
||||
this.createMotorPosition()
|
||||
@@ -188,7 +188,12 @@ 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));
|
||||
|
||||
this.cmdReceivers.forEach(receiver => {
|
||||
receiver.moveTo(this.motorPositionOld, this.motorPosition);
|
||||
if(cmd == "G1"){
|
||||
receiver.moveTo(this.motorPositionOld, this.motorPosition);
|
||||
}
|
||||
else{
|
||||
receiver.execCommand(cmd,this.motorPositionOld, this.motorPosition);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,8 +204,9 @@ module.exports = class TelnetSenderGRBL{
|
||||
data += " b" + (mNew.e * 180 / Math.PI).toFixed(2).toString();
|
||||
}
|
||||
|
||||
data += " f"+(maxSpeedF.toFixed(2).toString())
|
||||
|
||||
if(strCommand == "G1"){
|
||||
data += " f"+(maxSpeedF.toFixed(2).toString())
|
||||
}
|
||||
|
||||
if(this.tSocket && data.toString("utf-8").length > 3){
|
||||
if(!this.isTestMode){ console.log("" + this.urlGRBLstr + " gets the message: " + data.toString("utf-8"))}
|
||||
|
||||
@@ -187,6 +187,15 @@ const infoServer = https.createServer(httpsOptions, (req, res) => {
|
||||
res.writeHead(200, {'Content-Type': 'text/css'});
|
||||
res.end(data);
|
||||
}
|
||||
}); } else if (req.url === '/allApps.css') {
|
||||
fs.readFile('./public/allApps.css', (err, data) => {
|
||||
if (err) {
|
||||
res.writeHead(404);
|
||||
res.end('Not found');
|
||||
} else {
|
||||
res.writeHead(200, {'Content-Type': 'text/css'});
|
||||
res.end(data);
|
||||
}
|
||||
});
|
||||
} else if (req.url === '/api/status') {
|
||||
const status = {
|
||||
@@ -196,8 +205,8 @@ const infoServer = https.createServer(httpsOptions, (req, res) => {
|
||||
{name: 'Elbow', status: telnetSender2?.tSocket ? 'connected' : 'disconnected'},
|
||||
{name: 'Hand', status: telnetSender3?.tSocket ? 'connected' : 'disconnected'}
|
||||
],
|
||||
lastCommands: getLastLines('./logs/gcode_commands.log', 10),
|
||||
lastPings: getLastLines('./logs/pings.log', 10)
|
||||
lastCommands: getLastLines('./logs/gcode_commands.log', 15),
|
||||
lastPings: getLastLines('./logs/pings.log', 15)
|
||||
};
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
res.end(JSON.stringify(status));
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
// __tests__/Robot.inverseKinematics.test.js
|
||||
const Robot = require('../robot/Robot.js');
|
||||
const GCode = require('../robot/GCode.js');
|
||||
var TenetSender = require('../robot/TelnetSenderGRBL.js')
|
||||
|
||||
describe("Robot G92", () => {
|
||||
|
||||
beforeAll(() => {
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {})
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
|
||||
test("ReadPosition -> calculatePositionFromMotorAngles()", () => {
|
||||
|
||||
// === Instanz A: Vorwärts-Kinematik (XYZ -> Motorwinkel) ===
|
||||
@@ -26,7 +35,7 @@ describe("Robot G92", () => {
|
||||
|
||||
A.calculateAngles3D();
|
||||
|
||||
var strGCode = `G92 X${A.xMotor} Y${A.alpha} Z${A.beta} A${A.a} B${A.b} C${A.c}`
|
||||
var strGCode = `M92 X${A.xMotor} Y${A.alpha} Z${A.beta} A${A.a} B${A.b} C${A.c}`
|
||||
|
||||
|
||||
const T = new Robot(L1, L2, L3)
|
||||
@@ -44,5 +53,36 @@ describe("Robot G92", () => {
|
||||
|
||||
|
||||
});
|
||||
|
||||
// G92 y2.8 z131.0
|
||||
test("ReadPosition -> G92()", () => {
|
||||
|
||||
// === 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 y0.049 z2.286");
|
||||
|
||||
const strExpect1 = 'G92 x0.00 y2.81 z128.17\r\n';
|
||||
const strExpect2 = 'G92 y2.81 z128.17\r\n';
|
||||
|
||||
allowedValues = [strExpect1, strExpect2];
|
||||
expect(allowedValues).toContain(telnetSender1.tSocket.written);
|
||||
|
||||
// ("Wenn nur G92 x3 gegeben wird, dann wird trotzdem auch y und z gesendet. schlecht." );
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ describe("TelnetSenderGRBL.execCommand", () => {
|
||||
sender.execCommand("G92", mOld, mNew);
|
||||
|
||||
// ✅ verify output
|
||||
expect(sender.tSocket.written).toBe("G92 x12.34 y57.30 z57.30 f2300.00\r\n");
|
||||
expect(sender.tSocket.written).toBe("G92 x12.34 y57.30 z57.30\r\n");
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user