130 lines
5.6 KiB
Markdown
130 lines
5.6 KiB
Markdown
# ToDo 6a — Speed-Steuerung
|
||
|
||
> ## ✅ Status: erledigt (Pakete 1–2)
|
||
>
|
||
> - **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. |
|
||
|
||
```yaml
|
||
# 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
|
||
|
||
- [x] Property-Namen korrigiert: `oldPos.x/y/z/a/b/c/e`
|
||
- [x] `moveTime` berechnen und auf `motorPosition` ablegen
|
||
- [x] Unit-Tests: NaN-Freiheit, exakte Werte, Handgelenk-/Finger-Zweige, Guards
|
||
(`test/Robot.calculateSpeeds.test.js`)
|
||
|
||
### Paket 2: Schalter + koordinierte Feedrate — ✅ ERLEDIGT
|
||
|
||
- [x] `ROBOT_SPEED_MODE`-Schalter (`legacy` Default, `correct`)
|
||
- [x] `TelnetSenderGRBL`: koordinierte Feedrate im Korrekt-Modus, Legacy-Pfad unverändert
|
||
- [x] `portValue()` als isolierte Funktion, per Kreuzprobe gegen den echten Sende-Pfad getestet
|
||
- [x] 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.js` — `calculateSpeeds()` Fix, `moveTime`, Schalter→`useSpeedCalc`
|
||
- `robot/RobotMotorPosition.js` — `moveTime`-Feld
|
||
- `robot/TelnetSenderGRBL.js` — `portValue()`, koordinierte Feedrate, Schalter
|
||
- `test/Robot.calculateSpeeds.test.js` — neu
|
||
- `test/Sender.Telnet.speedMode.test.js` — neu
|