5.0 KiB
ToDo 6a — Speed-Steuerung
Ist-Zustand und Defizite
Die Feedrate-Logik ist auf zwei Ebenen defekt:
Ebene 1: calculateSpeeds() berechnet NaN
Robot.calculateSpeeds(oldPos, newPos) liest oldPos.xMotor, oldPos.alpha, oldPos.beta —
diese Properties existieren in RobotMotorPosition nicht. Dort heißen sie x, y, z.
Ergebnis: alle motorSpeeds-Werte sind NaN. Die Methode ist seit ihrer Einführung kaputt
und fällt nur nicht auf, weil ROBOT_USE_SPEED_CALC standardmäßig false ist.
// Zeile ~214 Robot.js — falsch:
this.motorSpeeds.x = (this.xMotor - oldPos.xMotor) / time; // oldPos.xMotor → undefined
this.motorSpeeds.y = (this.alpha - oldPos.alpha) / time; // oldPos.alpha → undefined
this.motorSpeeds.z = (this.beta - oldPos.beta) / time; // oldPos.beta → undefined
// Richtig (RobotMotorPosition-Felder):
this.motorSpeeds.x = (this.xMotor - oldPos.x) / time;
this.motorSpeeds.y = (this.alpha - oldPos.y) / time;
this.motorSpeeds.z = (this.beta - oldPos.z) / time;
Ebene 2: motorSpeeds werden von keinem Sender gelesen
Selbst wenn calculateSpeeds() korrekte Werte lieferte, ignorieren beide Sender die
berechneten Geschwindigkeiten vollständig:
TelnetSenderGRBL: sendetmNew.feedrate(Kartesisch, mm/min) an alle Achsen gleichWSSenderGrbl: sendet immerthis.maxSpeedF, ignoriertmNew.feedratekomplett
Das ist grundsätzlich falsch: Der Roboter hat drei unabhängige GRBL-Controller. Damit die
Fingerspitze mit F1000 mm/min fährt, muss jede Achse mit einer anderen Winkelgeschwindigkeit
drehen — je nachdem, wie weit sie sich für diesen Schritt bewegt. Alle Achsen mit derselben
Feedrate zu befehlen führt zu nicht-linearen Werkzeugbahnen.
Ebene 3: FPoint kodiert Feedrate hart
// GCode.js FPoint — immer f1000, egal was robot.feedrate ist:
var strGCode = `G90 G1 x${robot.x} ... f1000`
Konzept: Korrekte Feedrate-Verteilung
Gesamtziel: Die Kartesische Feedrate F (mm/min) des G-Code-Befehls bestimmt, wie lange
der Bewegungsschritt dauert. Diese Zeit wird auf alle Achsen aufgeteilt.
Zeit = kartesische_Distanz / F_mm_per_min
Achsen-Feedrate[i] = Achsen-Delta[i] / Zeit
(in Grad/min, da GRBL-Achsen typisch in Grad konfiguriert)
Der Sender kennt seine Achse (xAxisGrbl, yAxisGrbl, zAxisGrbl) und kann die passende
Geschwindigkeit aus motorPosition.speeds lesen, wenn diese korrekt befüllt sind.
Pakete
Paket 1: calculateSpeeds() reparieren
- Property-Namen korrigieren:
oldPos.x/y/z/a/b/c/estattoldPos.xMotor/alpha/beta/... - Einheit klären:
motorSpeedsin rad/min oder direkt in Grad/min?- Sender wandeln Motorwinkel bereits von rad → Grad (
* 180/π) für Positionen - Einheitlichste Lösung:
motorSpeedsebenfalls in Grad/min speichern, oder die Umrechnung konsistent im Sender vornehmen
- Sender wandeln Motorwinkel bereits von rad → Grad (
- Grenzfall: Wenn kartesische Distanz null ist (reine Gelenkbewegung), Distanz über Handgelenk-Punkt verwenden — das ist bereits so angelegt, aber mit den falschen Property-Namen
- Unit-Test:
calculateSpeedsmit bekannten Werten, prüfen dass keine NaN entstehen
Paket 2: motorSpeeds in den Sender durchreichen
motorPosition.speedskorrekt befüllen (passiert bereits viathis.motorPosition.speeds = {...this.motorSpeeds}nachcalculateSpeeds)- Sender-Interface (
execCommand): wennROBOT_USE_SPEED_CALCaktiv undmotorPosition.speeds[achse]verfügbar und > 0 → diesen Wert alsFverwenden - Jeder Sender (
TelnetSenderGRBL,WSSenderGrbl) kennt seine Achse und holt die passende Geschwindigkeit ausspeeds:// Beispiel: Sender ist für Achse "a" zuständig const f = (useSpeedCalc && mNew.speeds.a > 0) ? mNew.speeds.a : mNew.feedrate; data += ` f${f.toFixed(2)}`; - Fallback: wenn
ROBOT_USE_SPEED_CALC=falseoder Speeds nicht berechnet →mNew.feedratewie bisher (Rückwärtskompatibilität)
Paket 3: WSSenderGrbl Feedrate-Handling vereinheitlichen
WSSenderGrbl.execCommand()auf dasselbe Feedrate-Schema wieTelnetSenderGRBLumstellen- aktuell: immer
this.maxSpeedF→ ignoriert dasFaus dem G-Code-Befehl komplett - richtig:
mNew.feedrateverwenden (bzw. per-Achse aus Paket 2)
- aktuell: immer
maxSpeedFals Obergrenze behalten (Clamp), nicht als feste Ausgabe
Paket 4: Kleinere Korrekturen
FPointinGCode.receiveFC():robot.feedratestatt hardcodierten1000speichernROBOT_USE_SPEED_CALC-Flag dokumentieren: was ändert sich mit/ohne Flag? Klarer Kommentar inRobot.jsund im README
Betroffene Dateien
robot/Robot.js—calculateSpeeds()bugfix, Einheitenwahlrobot/RobotMotorPosition.js— ggf.speeds-Feld klarer benennenrobot/TelnetSenderGRBL.js— per-Achse Feedrate ausspeedsrobot/WSSenderGrbl.js— Feedrate aufmNew.feedrateumstellen + Clamprobot/GCode.js—FPoint:robot.feedratestatt1000test/GCode.speed.test.js— Tests für NaN-freie Berechnung ergänzen