6.8 KiB
Koordinatensystem, Roboter-Aufstellung & Nullstellung
Diese Datei beschreibt
- das Koordinatensystem,
- wie der Roboter darin steht,
- die angestrebte ideale Nullstellung und
- die nötigen Schritte, um den Driver auf diese Konvention zu bringen (Weg 2: Modell auf −Y drehen).
Hintergrund / Problem: Das Kinematik-Modell (
Arm3SegmentLinearX) misst die Armwinkel aktuell von +Y (α=0 → Arm zeigt nach +y). Der reale Roboter steht und arbeitet aber in −Y (robot.json:Arm1.skeleton.to = [0,-250,0],coordinateSystem.y = "backward"). Dadurch landet eine fast-waagerechte Grundstellung im Driver bei y ≈ +590 statt −590 — Modell und Hardware sind an der y-Achse gespiegelt.
1. Koordinatensystem
Aus robot.json (coordinateSystem): rechtshändig, Längen mm, Winkel Grad.
| Achse | Richtung | Bedeutung im Aufbau |
|---|---|---|
| x | rechts | entlang der Linearschiene |
| y | „backward" | Arm-Arbeitsrichtung: Arm streckt nach −y |
| z | oben | Höhe |
Seitenansicht (Blick entlang +x):
z
▲
| ■══════════════════════● Arm waagerecht ausgestreckt → Fingerspitze
| Schulter (Ursprung, z=0)
└───────────────────────────────► −y (Arbeitsrichtung)
Draufsicht (Blick von oben, −z):
−y ▲ ● Fingerspitze (Grundstellung y ≈ −590)
│ │
│ │ Arm (Ober- + Unterarm, gestreckt)
│ │
───┼────────────────■─────────────► x (Schiene)
│ Schulter
+y │
2. Wie der Roboter darin steht
Gelenk-Kette (robot.json links):
Board → Base (Schiene x) → Arm1 (Oberarm) → Ellbow → Arm2 (Unterarm) → Hand → Palm → Finger.
- Linearschiene entlang x; die Base fährt darauf (
xMotor, mm). - Schultergelenk (Base→Arm1,
variable y): Drehung in der y-z-Ebene → α. Bei Gelenkwinkel 0 zeigt Arm1 entlang −y (skeleton.to = [0,-250,0]). - Ellbogen (
variable z) → β; Unterarm-Dreher (variable a) → a; Handgelenk-Knick (variable b) → b; Hand-Roll (variable c) → c; Greifer (variable e) → e. - z = 0 im Driver-Modell = Schulterachse. (In der Welt liegt sie ~45 mm über dem Brett — robot.json Joint1-Origin z=45 —, der Driver rechnet schulter-relativ.)
- Armlängen (aus
linksabgeleitet): l1 = 250 (Oberarm), l2 = 250 (Unterarm), l3 ≈ 90 (Hand). Σ ≈ 590 mm.
3. Ideale Nullstellung (Grundstellung)
Definition: Arm waagerecht voll ausgestreckt entlang −y, Hand gerade in Verlängerung des Unterarms, Greifer geschlossen.
Ziel: in dieser Stellung sind alle Gelenkwinkel = 0°.
| Achse | Ideal-Wert | Bedeutung |
|---|---|---|
| X | (frei) | Schienenposition xMotor in mm |
| Y (α) | 0° | Oberarm waagerecht entlang −y |
| Z (β) | 0° | Unterarm waagerecht entlang −y (gestreckt) |
| A (a) | 0° | kein Unterarm-Dreh |
| B (b) | 0° | Hand gerade |
| C (c) | 0° | kein Hand-Roll |
| E (e) | 0 | Greifer geschlossen / Referenz |
→ Resultierende Fingerspitze: (xMotor, −(l1+l2+l3), 0) ≈ (x, −590, 0). (Beobachtet ~−550; Differenz steckt in der l3-Ableitung / Resthandstellung.)
4. Ist-Zustand vs. Ideal
| Aspekt | aktuell (Modell +Y) | ideal (−Y) |
|---|---|---|
| α=0 zeigt nach | +y (FK: y=+410) | −y (y=−410) |
| Grundstellung Y (α) | ≈175° (=180−4,5) | 0° |
| gerade Hand B (b) | 180° | 0° |
| neutraler Roll C (c) | 90° (posenabhängig) | 0° |
| G92 der Grundstellung → y | ≈ +590 | ≈ −590 |
Verifiziert per FK: α=β=0 → y=+410, α=β=180 → y=−410. Die +Y/−Y-Spiegelung
entspricht α→180−α, β→180−β.
5. Schritte, um das zu erreichen (Weg 2)
Reihenfolge nach Workflow: erst Tests (rot), dann Code, dann grün.
Phase 1 — y-Flip (behebt den gemeldeten Bug)
- Tests schreiben (zunächst rot):
- G92 der Grundstellung (α=β=a=b=c=0) → erwartet y ≈ −590 (statt +590).
- Round-Trip:
IK(x=0, y=−550, z, φ, θ)→FK→ identische Pose zurück.
Arm3SegmentLinearXumstellen (α/β von −y aus messen):- FK (
calculatePositionFromMotorAngles): y-Komponenten vonvecBizepsundvecUnterarmnegieren; Handgelenk-Vektoren (n,vHand) undφ = atan2(vHand.y,…)konsistent nachziehen. - IK (
calculateAngles3D):pY,gamma = atan2(pZ, pY), dien-Konstruktion undφentsprechend spiegeln.
- FK (
- Bestehende +Y-Tests auf −Y migrieren (erwartete y-Werte spiegeln).
doc/Info_G92.mdaktualisieren: Y/Z-Konvention auf „0° = waagerecht entlang −y".- Suite grün; Round-Trip + Grundstellung grün.
Phase 2 — Handgelenk auf Null (optional, für echte All-Zero-Grundstellung)
- B-Konvention drehen: gerade Hand = 0° statt 180° (
b → 180°−ban der Schnittstelle; FK/IK + Greifer-KopplungeMotor = e − b − cmit anpassen). - C-Nullpunkt: neutral = 0° statt 90°.
⚠️ Der C↔ψ-Offset ist posenabhängig (
acos(cos β · sin a)); ein global sauberesc=0=neutralbraucht ggf. eine tiefere Umparametrierung des Handgelenks — vor der Umsetzung bewerten. - Tests +
Info_G92.mdnachziehen.
Verifikation (Definition of Done)
- G92 der Grundstellung (alle Winkel 0) → Driver meldet y ≈ −590, z ≈ 0.
- appRobotHoming kann die physisch gemessenen Winkel direkt senden (ohne Spiegelung).
- Volle Test-Suite grün, inkl. Round-Trip und Grundstellungs-Tests.
Anhang: Stand der bisherigen Arbeit
- Der atan2-Fix in der IK (
gamma = Math.atan2(pZ, pY), Arm3SegmentLinearX.js:59) ist umgesetzt und macht die IK mathematisch für −Y-Eingaben korrekt — eine Voraussetzung für Phase 1. Er betrifft nicht den G92/FK-Pfad. - Die Winkel-Konventionen (B/C/E) sind in doc/Info_G92.md dokumentiert; die Y/Z-Konvention dort wird in Phase 1, Schritt 4 angepasst.