Files
appRobotDriver/doc/Info_G92.md
2026-06-25 19:20:14 +02:00

116 lines
5.1 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.
# G92 - Homing
die appRobotHoming ermittelt die Position der Gelenke (per Foto oder sonstigen Infos).
Diese werden wie folgt behandelt und umgerechnet.
---
## Befehlsformat
```
G92 X<mm> Y<°> Z<°> A<°> B<°> C<°> E<mm>
```
| Achse | Bedeutung | Einheit |
|-------|-----------------------------------|---------|
| X | Lineare Schiene (xMotor) | mm |
| Y | Schulterwinkel α (alpha) | Grad |
| Z | Ellenbogenwinkel β (beta) | Grad |
| A | Handgelenk 1 (a) | Grad |
| B | Handgelenk 2 (b) | Grad |
| C | Handgelenk 3 (c) | Grad |
| E | Greifer-Öffnung (ein Finger) | mm |
**Beispiel (tatsächlicher Homing-Aufruf):**
```
G92 X158.14 Y4.19 Z57.74 A91.85 B-45.46 C-69.92 E21.20
```
→ Y = 4,19°, Z = 57,74° usw. — alle Winkel direkt in Grad wie in FluidNC/GCode-Konvention.
---
## Interne Verarbeitung (`RobotController.js`)
Winkel-Achsen werden von Grad nach Radiant umgerechnet (D = 180/π):
```
robot.alpha = Y / D (intern: Radiant)
robot.beta = Z / D
robot.a = A / D
robot.b = B / D
robot.c = C / D
```
X bleibt mm, keine Umrechnung.
**Greifer E** wird **nach** B und C gesetzt, damit die kinematische Kopplung stimmt:
```
robot.e = E (Finger-Öffnung, mm)
robot.eMotor = gripperMotorFromOpening(e) (abgeleiteter Motorwert)
```
Bei `Arm3SegmentLinearX`: `eMotor = e b c` (Sehnenkompensation durch Handgelenk).
Bei `Arm3SegmentRotaryBase`: `eMotor = e` (keine Kopplung).
---
## Variante M92 (intern / Test)
```
M92 X<mm> Y<rad> Z<rad> A<rad> B<rad> C<rad> E<mm>
```
Winkel werden **roh als Radiant** übernommen. Für Skripte und Tests, nicht für Homing aus appRobotHoming.
---
## Weiterleitung an FluidNC-Instanzen
Nach dem Setzen der internen Motorslots ruft `robot.sendCommand('G92')` auf jedem registrierten `TelnetSenderGRBL` `execCommand('G92', mOld, mNew)` auf.
Jede Instanz bekommt ihren eigenen `G92`-Befehl mit den Port-Inverse-Achswerten (Rückumrechnung Radiant → Grad, mit Kopplung):
| Instanz | FluidNC-Achsen | Formel |
|---------|----------------------------|-----------------------------------------------------------|
| base | x = xMotor | direkt mm |
| | y = α → Grad | `alpha × D` |
| | z = β−α → Grad | `(beta alpha) × D` |
| elbow | x = a → Grad | `a × D` |
| hand | x = cb → Grad | `(c b) × D` |
| | y = eMotor | direkt (mm oder gekoppelter Motorwert) |
| | z = b → Grad | `b × D` |
`G92` bekommt **kein** `G90`-Prefix und keinen Vorschub — nur die geänderten Achsen werden angehängt. Jede Instanz übernimmt den Werkstück-Koordinaten-Offset (WPos) ohne Bewegung.
**Hinweis:** Nur Achsen mit gesetztem `*MotorChanged`-Flag werden gesendet. Bleibt ein Wert gegenüber dem letzten Driver-Zustand unverändert, schickt die jeweilige Instanz keinen G92 für diese Achse. Nach einem Neustart des Drivers sind alle Flags gesetzt → alle Achsen werden gesendet.
---
## Reporting (`M114` / Web-UI)
| Feld | Quelle | Einheit | Anzeige in public/app.js |
|--------------------|----------------|---------|------------------------------------------|
| `position.x/y/z` | Workspace | mm | direkt |
| `position.a/b/c` | phi/theta/psi | rad | `× 180/π` → Grad |
| `position.e` | `robot.e` | mm | direkt (Greifer-Öffnung) |
| `motorCounts.x` | xMotor | mm | direkt |
| `motorCounts.y/z` | alpha/beta | rad | `× 180/π` → Grad |
| `motorCounts.a/b/c`| a/b/c | rad | `× 180/π` → Grad |
| `motorCounts.e` | `robot.eMotor` | mm | direkt (abgeleiteter Motorwert) |
---
## Behobene Fehler (Kontext)
**Ursprüngliches Problem:** `G92 X158.14 Y4.19 Z57.74 …` lieferte korrekte X-Werte, aber Y≈240 und Z≈3308 im Ergebnis. Ursache: Winkel wurden als Radiant interpretiert, intern aber mit `× D` auf Grad umgerechnet — doppelte Skalierung.
**Drei Korrekturen:**
1. **Grad-Interpretation:** G92 rechnet Eingabe-Winkel jetzt mit `÷ D` in Radiant um (statt roh zu übernehmen).
2. **Greifer-Motorwert:** `robot.e` (Öffnung) wurde gesetzt, aber `sendCommand()` überträgt `robot.eMotor`. Fix: `eMotor = gripperMotorFromOpening(e)` direkt im G92-Zweig, nach dem Setzen von B/C.
3. **Web-UI-Anzeige:** `state-e` zeigte `motorCounts.e × 180/π` (mm × 57,3 = Unsinn). Fix: zeigt jetzt `position.e` (mm direkt).