Files
appRobotDriver/doc/ToDo_6a_Speed.md
2026-06-09 15:51:30 +02:00

5.6 KiB
Raw Permalink Blame History

ToDo 6a — Speed-Steuerung

Status: erledigt (Pakete 12)

  • Schalter ROBOT_SPEED_MODE (legacy Default = exakt wie bisher, correct = koordiniert)
  • calculateSpeeds()-NaN-Bug behoben + moveTime eingeführt
  • Koordinierte Feedrate im TelnetSenderGRBL (Korrekt-Modus), Legacy-Pfad unangetastet
  • Tests: test/Robot.calculateSpeeds.test.js, test/Sender.Telnet.speedMode.test.js, test/Speed.coordination.test.js

Offen: WS-Sender (Paket 3), FPoint-Feedrate (Paket 4 → ToDo_6b).

Der Schalter: ROBOT_SPEED_MODE

Die Speed-Regelung ist über eine einzige Umgebungsvariable umschaltbar:

Wert Bedeutung
legacy (Default) Alte Speed-Regelung — alles läuft exakt wie bisher. Jeder Sender sendet die kartesische Feedrate F (aus dem G-Code bzw. robot.feedrate) unverändert an alle seine Achsen.
correct Korrekte Speed-Regelung. Jeder Sender erhält eine eigene, koordinierte Feedrate, sodass alle Controller die Bewegung gleichzeitig beenden.
# docker-compose.yml
environment:
  ROBOT_SPEED_MODE: legacy     # oder: correct

Garantie für legacy

Im Legacy-Modus wird der Sende-Pfad der Sender nicht angefasst. Die Feedrate-Zeile entsteht über exakt denselben Code wie bisher. Die bestehenden Sender-Tests (Sender.Telnet.test.js, Sender.Telnet.caseBackward.test.js) prüfen die Ausgabe zeichengenau und sind das Sicherheitsnetz: solange sie grün sind, ist Legacy byte-identisch zu vorher.

Der Korrekt-Modus fügt nur zusätzlich eine alternative Feedrate-Berechnung hinzu, die ausschließlich greift, wenn ROBOT_SPEED_MODE=correct.

Abgrenzung zu ROBOT_USE_SPEED_CALC

ROBOT_USE_SPEED_CALC bleibt der interne Schalter dafür, ob Robot.calculateSpeeds() überhaupt rechnet. Der Korrekt-Modus aktiviert diese Berechnung automatisch. ROBOT_USE_SPEED_CALC allein ändert nicht die Sender-Ausgabe — nur ROBOT_SPEED_MODE=correct tut das. Damit bleibt bestehendes Verhalten erhalten.


Hintergrund: Warum die alte Regelung falsch ist

Der Roboter hat drei unabhängige GRBL/FluidNC-Controller. Im Legacy-Modus bekommen alle dieselbe kartesische Feedrate (z. B. f1000) — unabhängig davon, wie weit sich die jeweilige Achse in diesem Schritt tatsächlich bewegt. Folge: die Achse mit kurzer Bewegung ist viel früher fertig als die mit langer Bewegung, die Bewegungen laufen nicht koordiniert, und die Werkzeugbahn der Fingerspitze ist nicht linear.

Korrekt: Die kartesische Feedrate F bestimmt die Gesamt-Zeit des Schritts:

Bewegungszeit = kartesische_Distanz / F

Sender-Feedrate = Distanz_dieses_Senders / Bewegungszeit

So braucht jeder Controller dieselbe Zeit → die Bewegungen sind koordiniert.


Behobene Defizite (Implementierung dieses ToDos)

1. calculateSpeeds() berechnete NaN — behoben

Robot.calculateSpeeds() las oldPos.xMotor, oldPos.alpha, oldPos.beta — Felder, die in RobotMotorPosition nicht existieren (dort x, y, z). Ergebnis: NaN. Korrigiert auf oldPos.x/y/z. Zusätzlich speichert die Methode jetzt die Bewegungszeit (moveTime), die der Sender für die koordinierte Feedrate braucht.

2. Koordinierte Feedrate im Sender (Korrekt-Modus)

TelnetSenderGRBL berechnet im Korrekt-Modus die Feedrate als Distanz_dieses_Senders / moveTime. Die Distanz wird über portValue() ermittelt — eine reine Funktion, die für jede (GRBL-Port, Roboter-Achse)-Zuordnung den gesendeten Wert liefert (dieselben Formeln wie der Sende-Pfad, aber als isolierte, testbare Funktion).


Pakete

Paket 1: calculateSpeeds() reparieren — ERLEDIGT

  • Property-Namen korrigiert: oldPos.x/y/z/a/b/c/e
  • moveTime berechnen und auf motorPosition ablegen
  • Unit-Tests: NaN-Freiheit, exakte Werte, Handgelenk-/Finger-Zweige, Guards (test/Robot.calculateSpeeds.test.js)

Paket 2: Schalter + koordinierte Feedrate — ERLEDIGT

  • ROBOT_SPEED_MODE-Schalter (legacy Default, correct)
  • TelnetSenderGRBL: koordinierte Feedrate im Korrekt-Modus, Legacy-Pfad unverändert
  • portValue() als isolierte Funktion, per Kreuzprobe gegen den echten Sende-Pfad getestet
  • Korrekt-Modus-Tests + Koordinations-Invariante über alle drei Sender (test/Sender.Telnet.speedMode.test.js, test/Speed.coordination.test.js)

Paket 3: WSSenderGrbl OFFEN (Folge-Schritt)

  • WSSenderGrbl auf denselben Schalter + koordinierte Feedrate bringen
    • WS-Sender ist aktuell nicht in startRobot.js aktiv → kein Produktiv-Risiko
    • Legacy-Verhalten des WS-Senders zunächst unverändert lassen

Paket 4: Aufräumen — OFFEN (Folge-Schritt)

  • FPoint in GCode.receiveFC(): robot.feedrate statt hardcodiertem 1000 → gehört thematisch zur Datei-Logik, wird in ToDo_6b behandelt
  • portValue() perspektivisch auch im Sende-Pfad nutzen (Dedupe der Formeln); bewusst aufgeschoben, um den Legacy-Pfad in diesem Schritt nicht anzufassen

Bekannte Grenze des Korrekt-Modus v1

Die koordinierte Feedrate bildet die euklidische Norm über die Achsen eines Senders. Mischt ein Sender lineare (mm) und winklige (Grad) Achsen, mischt die Norm diese Einheiten — dieselbe Vereinfachung, die GRBL bei gemischten Achsen ohnehin macht. Für eine spätere, einheiten-saubere Behandlung ggf. eigenes ToDo.

Betroffene Dateien

  • robot/Robot.jscalculateSpeeds() Fix, moveTime, Schalter→useSpeedCalc
  • robot/RobotMotorPosition.jsmoveTime-Feld
  • robot/TelnetSenderGRBL.jsportValue(), koordinierte Feedrate, Schalter
  • test/Robot.calculateSpeeds.test.js — neu
  • test/Sender.Telnet.speedMode.test.js — neu