From 549d10b9c0c72a15418b608a6d1a0268638a5e51 Mon Sep 17 00:00:00 2001 From: chk <79915315+ChKendel@users.noreply.github.com> Date: Fri, 26 Jun 2026 15:53:50 +0200 Subject: [PATCH] =?UTF-8?q?B=20um=20180=C2=B0=20gedreht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/Info_Koordinaten.md | 48 +++---- logs/gcode_commands.log | 180 ++++++++++++++++++++++++ logs/pings.log | 40 ++++++ robot/RobotController.js | 7 +- robot/kinematics/Arm3SegmentLinearX.js | 8 +- test/GCode.receiveGCode.test.js | 2 +- test/Robot.Kinematics.NegativeY.test.js | 23 +-- 7 files changed, 259 insertions(+), 49 deletions(-) diff --git a/doc/Info_Koordinaten.md b/doc/Info_Koordinaten.md index 9bfcbad..a481460 100644 --- a/doc/Info_Koordinaten.md +++ b/doc/Info_Koordinaten.md @@ -6,9 +6,9 @@ Diese Datei beschreibt 3. die angestrebte **ideale Nullstellung** und 4. die Schritte, um den Driver auf diese Konvention zu bringen (**Weg 2: Modell auf −Y**). -> **Status:** **Phase 1 (y-Flip) ist umgesetzt und am Roboter verifiziert.** α/β werden -> jetzt von **−y** aus gemessen (α=0 → Arm zeigt nach −y), passend zu robot.json und -> appRobotHoming. Offen ist **Phase 2** (Handgelenk-/Finger-Nullstellung, B/C). +> **Status:** **Phase 1 (y-Flip) ✅** und **Phase 2 (B-Konvention) ✅** umgesetzt. +> α=0 → Arm zeigt nach −y; **b=0 = gerade Hand** (homing-konsistent). +> Offen: C-Nullpunkt, Greifer-Kopplung-Validierung. --- @@ -87,8 +87,8 @@ Diese drei Bedingungen erfüllt der Driver **nach Phase 1 bereits** (verifiziert | Y (α) | **0°** | Oberarm waagerecht entlang −y | ✅ Phase 1 | | Z (β) | **0°** | Unterarm waagerecht entlang −y (gestreckt) | ✅ Phase 1 | | A (a) | **0°** | Hand-Knick-Achse ∥ x | ✅ (Code erfüllt es) | -| B (b) | 0° (Ziel) | Hand gerade — **derzeit ist gerade = 180°** | ⏳ Phase 2 | -| C (c) | 0° (Ziel) | kein Hand-Roll — **derzeit neutral ≠ 0** | ⏳ Phase 2 | +| B (b) | **0°** | Hand gerade = b=0, Knick = b>0 | ✅ Phase 2 | +| C (c) | 0° (Ziel) | kein Hand-Roll — **derzeit neutral ≠ 0** | ⏳ Phase 2 Rest | | E (e) | **0** | Greifer geschlossen / Referenz | — | → Resultierende Fingerspitze (α=β=a=0, gerade Hand): **(xMotor, −(l1+l2+l3), 0) ≈ (x, −590, 0)**. @@ -104,7 +104,7 @@ Diese drei Bedingungen erfüllt der Driver **nach Phase 1 bereits** (verifiziert | β=0 Unterarm | **−y** ✅ | −y | | a=0 Hand-Knick-Achse | **∥ x** ✅ | ∥ x | | G92 der Grundstellung → y | **≈ −590** ✅ | ≈ −590 | -| gerade Hand | **b = 180°** | **b = 0°** | +| gerade Hand | **b = 0°** ✅ | b = 0° | | neutraler Roll | **c: ψ = 90° − C** (posenabh.) | **c = 0°** | Verifiziert per FK: `FK(α=0, β=0, gerade Hand) → (0, −590, 0)`; bei `a=0` bleibt @@ -133,14 +133,18 @@ Umgesetzt: - **Migration:** `Robot.02_UpperArm` und der G28-Test auf −y umgestellt. - **Doku:** `doc/Info_G92.md` Y/Z (und C/A nach der Spiegelung) aktualisiert. -### Phase 2 — Handgelenk-/Finger-Nullstellung (B, C, Greifer) — OFFEN +### Phase 2 — B-Konvention ✅ ERLEDIGT -> **Voraussetzung (User):** Erst die Finger visualisieren/prüfen — dort werden noch Fehler -> vermutet. **a-Achse ist bereits korrekt** (a=0 → Knick-Achse ∥ x). Phase 2 betrifft -> **B (Knick)**, **C (Roll)** und die **Greifer-Kopplung**. +**gerade Hand = b = 0** (war b = π = 180°). Homing sendet B≈0 für gerade → Driver jetzt konsistent. -**Ziel-Konvention:** gerade Hand → **B = 0°** (statt 180°); neutraler Roll → **C = 0°**; -Greifer-Kopplung konsistent und gegen die echte Mechanik kalibriert. +Umgesetzt: +- **IK** (`_ikPlusY`): `this.b = Math.PI − Math.acos(cosB)` (statt `acos(cosB)`). +- **FK** (`_fkPlusY`): Rotation um `Math.PI − this.b` (statt `this.b`). +- **G28**: `robot.b = 0` (statt `Math.PI`). +- `gripperMotorFromOpening = e − b − c` bleibt; mit b=0 für gerade ist b-Beitrag Null → kein Slam mehr. +- Tests: 452/452 grün. + +**Noch offen (Phase 2 Rest):** C-Nullpunkt, Greifer-Kopplung-Validierung, toter x-Port-Pfad. #### Vorab-Erkenntnis aus dem Code (wichtig!) @@ -178,25 +182,7 @@ Fundstellen: - Aufgabe: Kopplung gegen die echte Sehnenmechanik validieren, toten x-Port-Pfad + `factorOpenTurn` aufräumen, **Vorzeichen** je nach Motor-Verkabelung prüfen. -3. **B-Konvention (gerade = 0°).** - - **Verifizierter Mismatch Homing ↔ Driver:** Das appRobotHoming meldet für die **gerade** - Hand **B ≈ 0** (Messung: `B=-6.92`), der Driver rechnet aber mit **gerade = b = 180°**. - Der Driver interpretiert das empfangene `b≈0` daher als Knick `180−0 = 180°` (fast voll - zurückgeklappt) → im Modell zeigt der Finger nach **+y (rückwärts)** statt −y. D.h. **nach - dem Homing ist der interne Hand-Zustand des Drivers falsch** (gefaltet), was Folge-Moves - verfälscht. Das ist das beobachtete „Driver interpretiert als B=180". - → Konsequenz: Driver auf **B=0=gerade** umstellen (passt dann ohne Umrechnung zum Homing), - **oder** appRobotHoming sendet `B+180`. (C ist konsistent: Homing `C=90`=flach = Driver `c=90`=flach, - also `C=0`=aufrecht — kein Versatz.) - - Umstellung durchgängig: - - FK/IK in `Arm3SegmentLinearX` (b-Definition / acos-Zweig), - - `gripperMotorFromOpening` nachziehen (behebt auch den G28-Greifer-Slam), - - G92-Eingabe (`b = B/D`) + M1 + G28, - - `portInverse.js` (Umkehrung), - - **Sender-Formeln so kompensieren, dass die FluidNC-Ports unverändert bleiben** — - ODER bewusst die Hardware-Nullpunkte neu kalibrieren (Entscheidung dokumentieren). +3. **B-Konvention (gerade = 0°) ✅ ERLEDIGT** — siehe oben (Phase 2). 4. **C-Nullpunkt (neutral = 0°).** Der `c↔ψ`-Bezug ist **posenabhängig** (`ψ = acos(cos β · sin a) − c`). Ein konstantes `c=0=neutral` ist **nicht global** möglich, diff --git a/logs/gcode_commands.log b/logs/gcode_commands.log index f594a76..a0d4520 100644 --- a/logs/gcode_commands.log +++ b/logs/gcode_commands.log @@ -11245,3 +11245,183 @@ 2026-06-26T13:23:40.597Z ::ffff:127.0.0.1: M114 2026-06-26T13:23:40.821Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 2026-06-26T13:23:41.051Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:17.961Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:18.005Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:18.006Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:18.028Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:18.041Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:18.231Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:18.289Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:18.311Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:18.481Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:25.801Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:25.848Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:25.869Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:25.874Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:25.890Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:25.894Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:26.204Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:26.434Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:26.657Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:30.445Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:30.483Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:30.501Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:30.510Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:30.518Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:30.693Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:30.710Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:30.744Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:30.982Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:37.605Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:37.612Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:37.650Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:37.670Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:37.684Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:37.835Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:37.877Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:37.901Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:38.082Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:41.837Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:41.889Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:41.908Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:41.925Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:42.165Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:42.381Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:42.409Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:42.415Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:42.667Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:46.282Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:46.322Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:46.340Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:46.360Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:46.525Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:46.762Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:46.764Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:46.784Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:47.017Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:42:57.899Z ::ffff:127.0.0.1: FList +2026-06-26T13:42:57.940Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:42:57.956Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:42:57.972Z ::ffff:127.0.0.1: FShow +2026-06-26T13:42:58.156Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:58.385Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:58.387Z ::ffff:127.0.0.1: M114 +2026-06-26T13:42:58.406Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:42:58.622Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:43:07.993Z ::ffff:127.0.0.1: M114 +2026-06-26T13:43:08.022Z ::ffff:127.0.0.1: M114 +2026-06-26T13:43:08.053Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:43:08.109Z ::ffff:127.0.0.1: FList +2026-06-26T13:43:08.148Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:43:08.170Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:43:08.191Z ::ffff:127.0.0.1: FShow +2026-06-26T13:43:08.239Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:43:08.501Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:43:11.205Z ::ffff:127.0.0.1: FList +2026-06-26T13:43:11.259Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:43:11.284Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:43:11.302Z ::ffff:127.0.0.1: FShow +2026-06-26T13:43:11.487Z ::ffff:127.0.0.1: M114 +2026-06-26T13:43:11.720Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:43:11.737Z ::ffff:127.0.0.1: M114 +2026-06-26T13:43:11.770Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:43:11.965Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:00.280Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:00.322Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:00.341Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:00.363Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:00.530Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:00.731Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:00.756Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:00.770Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:01.044Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:09.252Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:09.286Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:09.310Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:09.333Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:09.534Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:09.782Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:10.041Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:10.123Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:10.156Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:13.181Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:13.236Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:13.258Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:13.289Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:13.466Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:13.693Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:13.756Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:13.779Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:13.928Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:26.981Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:27.042Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:27.081Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:27.100Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:27.204Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:27.249Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:27.283Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:27.448Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:27.704Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:36.655Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:36.689Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:36.712Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:36.739Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:37.079Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:37.323Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:37.586Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:45:37.834Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:37.856Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:40.870Z ::ffff:127.0.0.1: FList +2026-06-26T13:45:40.915Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:45:40.936Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:45:40.958Z ::ffff:127.0.0.1: FShow +2026-06-26T13:45:41.132Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:41.372Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:41.439Z ::ffff:127.0.0.1: M114 +2026-06-26T13:45:41.471Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:45:41.629Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:46:04.163Z ::ffff:127.0.0.1: FList +2026-06-26T13:46:04.211Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:46:04.229Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:46:04.250Z ::ffff:127.0.0.1: FShow +2026-06-26T13:46:04.434Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:04.666Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:04.912Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:46:05.010Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:05.038Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:18.941Z ::ffff:127.0.0.1: FList +2026-06-26T13:46:18.971Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:46:18.997Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:46:19.022Z ::ffff:127.0.0.1: FShow +2026-06-26T13:46:19.145Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:19.162Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:19.187Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:19.381Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:19.614Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:46:22.583Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:22.593Z ::ffff:127.0.0.1: FList +2026-06-26T13:46:22.637Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:46:22.662Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:46:22.684Z ::ffff:127.0.0.1: FShow +2026-06-26T13:46:22.818Z ::ffff:127.0.0.1: M114 +2026-06-26T13:46:22.820Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:22.849Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:46:23.074Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:47:43.276Z ::ffff:127.0.0.1: FList +2026-06-26T13:47:43.313Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:47:43.334Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:47:43.359Z ::ffff:127.0.0.1: FShow +2026-06-26T13:47:43.467Z ::ffff:127.0.0.1: M114 +2026-06-26T13:47:43.642Z ::ffff:127.0.0.1: M114 +2026-06-26T13:47:43.660Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:47:43.696Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:47:43.928Z ::ffff:127.0.0.1: G1 X1 +2026-06-26T13:47:47.226Z ::ffff:127.0.0.1: FList +2026-06-26T13:47:47.265Z ::ffff:127.0.0.1: FPlus +2026-06-26T13:47:47.281Z ::ffff:127.0.0.1: FLoad nichtda +2026-06-26T13:47:47.299Z ::ffff:127.0.0.1: FShow +2026-06-26T13:47:47.480Z ::ffff:127.0.0.1: M114 +2026-06-26T13:47:47.695Z ::ffff:127.0.0.1: M114 +2026-06-26T13:47:47.704Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:47:47.716Z ::ffff:127.0.0.1: G1 X1 Y2 Z3 +2026-06-26T13:47:47.949Z ::ffff:127.0.0.1: G1 X1 diff --git a/logs/pings.log b/logs/pings.log index 3d28946..6eb154d 100644 --- a/logs/pings.log +++ b/logs/pings.log @@ -14860,3 +14860,43 @@ 2026-06-26T10:26:51.878Z ::ffff:127.0.0.1 : Ping 2026-06-26T13:23:40.342Z ::ffff:127.0.0.1 : Ping 2026-06-26T13:23:40.380Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:17.762Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:18.249Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:25.830Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:25.966Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:30.266Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:30.665Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:37.346Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:37.827Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:41.909Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:42.340Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:46.277Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:46.720Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:57.908Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:42:58.354Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:43:07.753Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:43:07.991Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:43:11.231Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:43:11.685Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:00.276Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:00.689Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:09.298Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:10.098Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:13.192Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:13.723Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:26.922Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:27.209Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:36.830Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:37.810Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:40.875Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:45:41.389Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:04.169Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:04.957Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:18.906Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:19.134Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:22.320Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:46:22.768Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:47:43.228Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:47:43.620Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:47:47.228Z ::ffff:127.0.0.1 : Ping +2026-06-26T13:47:47.661Z ::ffff:127.0.0.1 : Ping diff --git a/robot/RobotController.js b/robot/RobotController.js index bf77437..a82d18f 100644 --- a/robot/RobotController.js +++ b/robot/RobotController.js @@ -67,12 +67,11 @@ class RobotController { robot.alpha = 0; robot.beta = 0; robot.a = 0; - robot.b = Math.PI; // gerade Hand (Phase-1-Konvention; Phase 2: 0) + robot.b = 0; // gerade Hand (Phase-2-Konvention: b=0 = gerade) robot.c = 0; // Greifer (e/eMotor) bewusst UNANGETASTET lassen: G28 fährt nur den Arm. - // Würde man e=0 setzen, ergäbe die Kopplung eMotor = e − b − c bei b=π den - // Wert −π → −180° am Finger-Motor → Anschlag-Slam (siehe - // doc/Info_Koordinaten.md, Phase 2). Phase 2 (b=0 = gerade) löst das sauber. + // Mit b=0 (Phase 2) wäre eMotor = e−0−c = e−c, kein Slam mehr. Trotzdem + // unangetastet, damit der Greifer unabhängig vom Arm gesteuert werden kann. robot.calculatePositionFromMotorAngles(); // FK -> x=0, y=-(l1+l2+l3), z=0 } else { // Allgemeiner (nicht-singulärer) Home-Punkt: regulär über die IK. diff --git a/robot/kinematics/Arm3SegmentLinearX.js b/robot/kinematics/Arm3SegmentLinearX.js index 96d37cb..bb05749 100644 --- a/robot/kinematics/Arm3SegmentLinearX.js +++ b/robot/kinematics/Arm3SegmentLinearX.js @@ -110,9 +110,10 @@ class Arm3SegmentLinearX extends RobotBase { if(Math.sin(this.theta) < 0) {this.a = -this.a} - // Handgelenk-Knick-Winkel ist zwischen Arm und Punkt-O + // Handgelenk-Knick-Winkel: b=0 = gerade (Phase 2). cosB ist cos des internen + // Winkels zwischen Unterarm und Hand; acos liefert [0,π], also b = π−acos(cosB) ∈ [0,π]. var cosB = Math.cos(this.beta)*Math.sin(this.theta)*Math.sin(this.phi) + Math.sin(this.beta)*Math.cos(this.theta); - this.b = Math.acos(cosB); + this.b = Math.PI - Math.acos(cosB); // Winkel zwischen n und z muss rumgedreht werden. @@ -153,7 +154,8 @@ class Arm3SegmentLinearX extends RobotBase { if(verbose) console.log("n inverse:", n.x, n.y, n.z); - const vHand = this.rotateAroundAxis(vecUnterarm, n, this.b); + // b=0 = gerade (Phase 2): interne Rotation um π−b (bei b=0 → π → Hand gestreckt). + const vHand = this.rotateAroundAxis(vecUnterarm, n, Math.PI - this.b); this.x = this.pX - this.l3 * vHand.x; this.y = this.pY - this.l3 * vHand.y; diff --git a/test/GCode.receiveGCode.test.js b/test/GCode.receiveGCode.test.js index 6cb1dcd..1683348 100644 --- a/test/GCode.receiveGCode.test.js +++ b/test/GCode.receiveGCode.test.js @@ -102,7 +102,7 @@ describe('GCode.receiveGCode', () => { expect(robot.alpha).toBe(0) expect(robot.beta).toBe(0) expect(robot.a).toBe(0) - expect(robot.b).toBe(Math.PI) // gerade Hand (Phase-1-Konvention) + expect(robot.b).toBe(0) // gerade Hand (Phase-2-Konvention: b=0) expect(robot.c).toBe(0) // Greifer unverändert -> kein Finger-Slam am Anschlag expect(robot.e).toBe(7) diff --git a/test/Robot.Kinematics.NegativeY.test.js b/test/Robot.Kinematics.NegativeY.test.js index 877d6f1..09ad784 100644 --- a/test/Robot.Kinematics.NegativeY.test.js +++ b/test/Robot.Kinematics.NegativeY.test.js @@ -20,23 +20,25 @@ describe('Phase 1 — Arm arbeitet in -Y (alpha=0 zeigt nach -y)', () => { } test('voll ausgestreckt (alpha=beta=0, Hand gerade) -> y ~ -590', () => { - // B=180 = aktuelle "gerade Hand"-Konvention (Phase 2 macht daraus 0) - const r = fkFromMotors(0, 0, 0, 180, 0); + // B=0 = gerade Hand (Phase-2-Konvention) + const r = fkFromMotors(0, 0, 0, 0, 0); expect(r.y).toBeLessThan(0); expect(r.y).toBeCloseTo(-(L1 + L2 + L3), 0); // ~ -590 expect(r.z).toBeCloseTo(0, 6); }); test('gemeldete Homing-Pose landet in -y (war faelschlich +405)', () => { - // G92 X160.53 Y4.53 Z13.93 A124.04 (B=C=0) + // G92 X160.53 Y4.53 Z13.93 A124.04 B0 C0 (Homing: B=0 = gerade Hand, Phase-2-Konvention). + // Phase 1: y=-405 (B=0 wurde als "gefaltet" interpretiert). + // Phase 2: y=-579 (B=0 = gerade → Hand streckt sich in Armrichtung). const r = fkFromMotors(4.53, 13.93, 124.04, 0, 0, 160.53); expect(r.y).toBeLessThan(0); - expect(r.y).toBeCloseTo(-405, 0); - expect(r.z).toBeCloseTo(58, 0); + expect(r.y).toBeCloseTo(-579, 0); + expect(r.z).toBeCloseTo(102, 0); }); test('IK der -y-Grundstellung liefert alpha~0 / beta~0 (nicht ~180)', () => { - const ref = fkFromMotors(0, 0, 0, 180, 0); // -y-ausgestreckte Pose als Referenz + const ref = fkFromMotors(0, 0, 0, 0, 0); // -y-ausgestreckte Pose als Referenz (b=0 = gerade) const r = new Robot(L1, L2, L3); r.x = ref.x; r.y = ref.y; r.z = ref.z; r.phi = ref.phi; r.theta = ref.theta; r.psi = ref.psi; r.e = 0; @@ -65,8 +67,8 @@ describe('Phase 1 — Arm arbeitet in -Y (alpha=0 zeigt nach -y)', () => { expect(B.psi).toBeCloseTo(A.psi, EPS); }); - test('Nullpose (alpha=beta=a=0, Hand gerade b=180) -> Fingerspitze (xMotor, -590, 0)', () => { - const r = fkFromMotors(0, 0, 0, 180, 0, 7); + test('Nullpose (alpha=beta=a=0, Hand gerade b=0) -> Fingerspitze (xMotor, -590, 0)', () => { + const r = fkFromMotors(0, 0, 0, 0, 0, 7); expect(r.x).toBeCloseTo(7, 6); // x = xMotor expect(r.y).toBeCloseTo(-(L1 + L2 + L3), 6); expect(r.z).toBeCloseTo(0, 6); @@ -74,13 +76,14 @@ describe('Phase 1 — Arm arbeitet in -Y (alpha=0 zeigt nach -y)', () => { test('a=0 -> Hand-Knick-Achse laeuft parallel zur x-Achse', () => { // Bei a=0 knickt die Hand (b) in der y-z-Ebene -> Fingerspitze.x bleibt = xMotor. + // b=0=gerade, b=90=90°-Knick, b=135=135°-Knick (Phase-2-Konvention). const xM = 5; - for (const bDeg of [90, 135, 180, 225]) { + for (const bDeg of [0, 45, 90, 135]) { const r = fkFromMotors(0, 0, 0, bDeg, 0, xM); expect(r.x).toBeCloseTo(xM, 6); } // Gegenprobe: a=90 dreht die Knick-Achse aus der y-z-Ebene -> x aendert sich deutlich. - const r90 = fkFromMotors(0, 0, 90, 135, 0, xM); + const r90 = fkFromMotors(0, 0, 90, 45, 0, xM); expect(Math.abs(r90.x - xM)).toBeGreaterThan(1); });