Files
appRobotDriver/doc/ToDo_12_InverseKinematikConfig_ROADMAP.md

161 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Roadmap 12 — Austauschbare Kinematik
## Ziel
Der `appRobotDriver` soll als generischer G-Code-Treiber für beliebige Roboterarme
funktionieren. Die Kinematik ist der einzige arm-spezifische Teil — alles andere
(G-Code, WebSocket, Sender, Konfiguration) ist roboter-unabhängig.
## Konventionen (festgelegt)
- **Workspace-Koordinaten:** `x, y, z, phi, theta, psi` + `e` (Greifer) — gilt für alle
6-DOF-Arme mit Greifer. Das ist der implizite Vertrag dieses Frameworks.
- **Motoranzahl:** 7 Slots (`x, y, z, a, b, c, e` in `RobotMotorPosition`) bleiben fest.
Das Framework ist für 6-DOF + Greifer ausgelegt.
- **Ordner:** `robot/kinematics/` (nicht `inverseKinematics/` — enthält beide Richtungen)
- **Klassenname:** beschreibend für die physikalische Struktur, z. B. `Arm3SegmentLinearX`
---
## Dateistruktur (Zielzustand)
```
robot/
├── RobotBase.js ← Interface + generische Infrastruktur
├── KinematicsFactory.js ← lädt Kinematik-Klasse anhand Env-Variable
└── kinematics/
├── Arm3SegmentLinearX.js ← aktuelle Implementierung
└── <NextRobot>.js ← zukünftige Implementierungen
```
> **Update (umgesetzt):** Der ursprünglich geplante dauerhafte Kompatibilitäts-Alias
> `robot/Robot.js` wurde **nicht** beibehalten, sondern nach Abschluss von Phase 02
> **entfernt**. Tests importieren direkt `kinematics/Arm3SegmentLinearX` bzw.
> `RobotBase`; Produktivcode geht über `KinematicsFactory`. Die folgenden Abschnitte
> zur Transition über `Robot.js` sind daher historisch.
## Wo ist das Interface?
**`RobotBase` ist das Interface** — als abstrakte Basisklasse (JavaScript-Idiom).
Es definiert zwei Dinge:
1. Die **Infrastruktur**, die jede Implementierung erbt (State, `sendCommand`, ...)
2. Den **Vertrag**: zwei Methoden, die jede Implementierung überschreiben *muss*
`RobotBase` ist die einzige Klasse, die alle anderen Module (`GCode.js`, `InputWS.js`,
Sender, ...) kennen müssen. Sie importieren nie eine konkrete Kinematik.
## Wie greift der restliche Code auf den Roboter zu?
**Heute und während der Transition:**
```
startRobot.js → require('./robot/Robot') → Robot.js (Alias) → Arm3SegmentLinearX
GCode.js → bekommt robot als Parameter → sieht nur RobotBase-Methoden
InputWS.js → bekommt robot als Parameter → sieht nur RobotBase-Methoden
```
`GCode.js`, `InputWS.js` und alle Sender erhalten `robot` bereits als Parameter —
sie importieren `Robot.js` gar nicht. **Für sie ändert sich nichts.**
**Langfristig (nach Abschluss Phase 2):**
```
startRobot.js → KinematicsFactory → instantiiert Arm3SegmentLinearX (oder anderen)
robot/Robot.js → dauerhafter Alias für RobotBase (nicht mehr für eine Implementierung)
```
`robot/Robot.js` bleibt erhalten, zeigt aber auf `RobotBase`:
```js
// robot/Robot.js — dauerhaft
module.exports = require('./RobotBase');
```
Damit kann externer Code weiterhin `require('./robot/Robot')` schreiben und bekommt
die Basisklasse — z. B. für `instanceof`-Checks oder zum Ableiten in Tests.
---
## Phase 0 — `RobotBase` und Interface-Vertrag
`Robot.js` enthält heute zwei Dinge: generische Infrastruktur und arm-spezifische Kinematik.
Der Schnitt:
**`RobotBase` (generisch, nie überschreiben):**
- Zustandsvariablen: `x, y, z, phi, theta, psi, e, feedrate, moveRelative`
- Motor-Zustand: `xMotor, alpha, beta, a, b, c, eMotor` + Changed-Flags
- `sendCommand()`, `createMotorPosition()`, `calculateSpeeds()`
- `cmdReceivers`, `savedPoints`
**Interface-Vertrag (abstrakt, muss überschrieben werden):**
```js
calculateAngles3D() // Workspace → Motorwinkel (schreibt auf this.*)
calculatePositionFromMotorAngles() // Motorwinkel → Workspace (schreibt auf this.*)
```
- [x] `robot/RobotBase.js` anlegen — generische Infrastruktur aus `Robot.js`
- [x] Beide Kinematik-Methoden in `RobotBase` als Stub mit `throw new Error('not implemented')`
- [x] JSDoc: Interface-Vertrag dokumentieren
- [x] `rotateAroundAxis()` wandert in `RobotBase` als geschützte Hilfsmethode
---
## Phase 1 — `Arm3SegmentLinearX` als erste Implementierung
```
robot/
├── RobotBase.js
└── kinematics/
└── Arm3SegmentLinearX.js ← bisheriger Robot.js-Kinematik-Teil
```
- [x] `robot/kinematics/Arm3SegmentLinearX.js` anlegen
- `class Arm3SegmentLinearX extends RobotBase`
- Konstruktor: `constructor(l1, l2, l3)``super()` + Längen
- `calculateAngles3D()` — unverändert übernommen
- `calculatePositionFromMotorAngles()` — unverändert übernommen
- [x] `robot/Robot.js` wurde zunächst Kompatibilitäts-Alias und anschließend
**entfernt** (siehe Update-Hinweis oben). Tests importieren direkt
`./kinematics/Arm3SegmentLinearX`.
- [x] Alle bestehenden Tests müssen grün bleiben — kein Verhalten ändert sich
(`Robot.Kinematics.RoundTrip.test.js` ist das primäre Sicherheitsnetz)
---
## Phase 2 — Konfiguration über Umgebungsvariable
```yaml
# docker-compose.yml
environment:
ROBOT_KINEMATICS: arm3segmentlinearx
ROBOT_KINEMATICS_PARAMS: '{"l1": 250, "l2": 264, "l3": 100}'
```
- [x] `ROBOT_KINEMATICS` — Bezeichner der Kinematik-Klasse (Default: `arm3segmentlinearx`)
- [x] `ROBOT_KINEMATICS_PARAMS` — JSON mit Konstruktor-Parametern
- [x] `KinematicsFactory.js` (`createRobotFromEnv`), eingebunden in `startRobot.js`:
```js
const robot = createRobotFromEnv(processEnv, { l1: 250, l2: 264, l3: 100 });
```
- [x] Unbekannte Kinematik → klare Fehlermeldung beim Start, kein silent fail
- [ ] Neue Variablen ins zentrale Config-Modul aufnehmen (koordinieren mit `ToDo_3_Config`)
→ **offen:** `ToDo_3_Config` ist noch nicht umgesetzt. Die Factory liest `process.env`
vorerst direkt (gleicher Stil wie `ROBOT_DEFAULT_FEEDRATE`); das zentrale Config-Modul
kann die beiden Variablen später übernehmen. In `docker-compose.yaml` bereits dokumentiert.
---
## Phase 3 — Zweite Kinematik-Implementierung
Erst wenn ein konkreter zweiter Roboter definiert ist.
- [ ] Physikalische Spezifikation dokumentieren (DOF, Achsen, Gelenkreihenfolge)
- [ ] `robot/kinematics/<Name>.js` anlegen — nur die zwei Kinematik-Methoden
- [ ] RoundTrip-Tests für die neue Implementierung schreiben
- [ ] Prüfen ob die 7 Motor-Slots ausreichen; falls nicht → `RobotMotorPosition` anpassen
---
## Abhängigkeiten
- Phase 1 ist unabhängig von allen anderen ToDos — kann sofort angegangen werden
- Phase 2 koordiniert mit `ToDo_3_Config`
- Phase 3 hat keine zeitliche Vorgabe — wird bei Bedarf aufgenommen