6.2 KiB
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, einRobotMotorPosition) bleiben fest. Das Framework ist für 6-DOF + Greifer ausgelegt. - Ordner:
robot/kinematics/(nichtinverseKinematics/— enthält beide Richtungen) - Klassenname: beschreibend für die physikalische Struktur, z. B.
Arm3SegmentLinearX
Dateistruktur (Zielzustand)
robot/
├── RobotBase.js ← Interface + generische Infrastruktur
├── Robot.js ← dauerhafter Alias: module.exports = RobotBase
├── KinematicsFactory.js ← lädt Kinematik-Klasse anhand Env-Variable
└── kinematics/
├── Arm3SegmentLinearX.js ← aktuelle Implementierung
└── <NextRobot>.js ← zukünftige Implementierungen
Wo ist das Interface?
RobotBase ist das Interface — als abstrakte Basisklasse (JavaScript-Idiom).
Es definiert zwei Dinge:
- Die Infrastruktur, die jede Implementierung erbt (State,
sendCommand, ...) - 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:
// 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):
calculateAngles3D() // Workspace → Motorwinkel (schreibt auf this.*)
calculatePositionFromMotorAngles() // Motorwinkel → Workspace (schreibt auf this.*)
robot/RobotBase.jsanlegen — generische Infrastruktur ausRobot.js- Beide Kinematik-Methoden in
RobotBaseals Stub mitthrow new Error('not implemented') - JSDoc: Interface-Vertrag dokumentieren
rotateAroundAxis()wandert inRobotBaseals geschützte Hilfsmethode
Phase 1 — Arm3SegmentLinearX als erste Implementierung
robot/
├── RobotBase.js
└── kinematics/
└── Arm3SegmentLinearX.js ← bisheriger Robot.js-Kinematik-Teil
robot/kinematics/Arm3SegmentLinearX.jsanlegenclass Arm3SegmentLinearX extends RobotBase- Konstruktor:
constructor(l1, l2, l3)→super()+ Längen calculateAngles3D()— unverändert übernommencalculatePositionFromMotorAngles()— unverändert übernommen
robot/Robot.jswird zum Kompatibilitäts-Alias für die Übergangsperiode:module.exports = require('./kinematics/Arm3SegmentLinearX');- Alle bestehenden Tests müssen grün bleiben — kein Verhalten ändert sich
(
Robot.Kinematics.RoundTrip.test.jsist das primäre Sicherheitsnetz)
Phase 2 — Konfiguration über Umgebungsvariable
# docker-compose.yml
environment:
ROBOT_KINEMATICS: arm3segmentlinearx
ROBOT_KINEMATICS_PARAMS: '{"l1": 250, "l2": 264, "l3": 100}'
ROBOT_KINEMATICS— Bezeichner der Kinematik-Klasse (Default:arm3segmentlinearx)ROBOT_KINEMATICS_PARAMS— JSON mit Konstruktor-ParameternKinematicsFactory.js(createRobotFromEnv), eingebunden instartRobot.js:const robot = createRobotFromEnv(processEnv, { l1: 250, l2: 264, l3: 100 });- Unbekannte Kinematik → klare Fehlermeldung beim Start, kein silent fail
- Neue Variablen ins zentrale Config-Modul aufnehmen (koordinieren mit
ToDo_3_Config) → offen:ToDo_3_Configist noch nicht umgesetzt. Die Factory liestprocess.envvorerst direkt (gleicher Stil wieROBOT_DEFAULT_FEEDRATE); das zentrale Config-Modul kann die beiden Variablen später übernehmen. Indocker-compose.yamlbereits dokumentiert.
Phase 3 — Zweite Kinematik-Implementierung
Erst wenn ein konkreter zweiter Roboter definiert ist.
- Physikalische Spezifikation dokumentieren (DOF, Achsen, Gelenkreihenfolge)
robot/kinematics/<Name>.jsanlegen — nur die zwei Kinematik-Methoden- RoundTrip-Tests für die neue Implementierung schreiben
- Prüfen ob die 7 Motor-Slots ausreichen; falls nicht →
RobotMotorPositionanpassen
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