Multipoint zurück

This commit is contained in:
chk
2026-06-25 20:36:09 +02:00
parent fab7032d56
commit 33dcbe72bf
40 changed files with 32217 additions and 16 deletions

View File

@@ -5,12 +5,12 @@
> Messung beiträgt und *wie stark* sie zählt.
>
> **Status (2026-06-25):** **Qualitäts-Gewichtung** (Doc-Punkt 3 / Schritte 1+2)
> umgesetzt. **Mehrpunkt-Eckresiduen** (Doc-Punkt 1 / Schritte 3+4) umgesetzt
> als Opt-in-Modus `marker_observation="corner_points"` — 12 Eck-Residuen für
> Roboter-Links, 1 Center-Residuum für die (spin-unkalibrierten) Board/Rail-
> Marker auf dem Root-Link. Endgültiges Tuning/Validierung gegen Simulation
> steht aus (siehe Notiz unten). **Einzelkamera-Einbindung** (Doc-Punkt 2 /
> Schritte 5+6) weiterhin **offen** — siehe Status-Spalte unten.
> umgesetzt. **Mehrpunkt-Eckresiduen** (Doc-Punkt 1 / Schritte 3+4) als
> Opt-in-Modus `corner_points` implementiert, aber nach gescheitertem
> Live-Test wieder **DEAKTIVIERT** — robot.json steht auf `corner_pose`
> (bewährter Zustand). Der Code bleibt inaktiv im Repo. Ursache + Vorbedingungen
> für eine erneute Aktivierung: Notiz unten. **Einzelkamera-Einbindung**
> (Doc-Punkt 2 / Schritte 5+6) weiterhin **offen**.
---
@@ -232,7 +232,7 @@ umsetzbar und (wo möglich) einzeln testbar, bevor der nächste beginnt.
| 1 | ✅ erledigt (2026-06-17) | **(Doc-Punkt 3)** `quality`/`confidence` aus `{cam}_aruco_detection.json` bis nach `aruco_marker_poses.json` durchreichen (3b liest es, schreibt ein neues `weight`-Feld pro Marker) | Diff der Ausgabedatei: nur das neue Feld ist zusätzlich da, alles andere (Position, Normale, …) identisch zu vorher — reiner Additivitätstest | **Nein.** Rein additives Feld, kein Pflichtfeld, alte Leser ignorieren es |
| 2 | ✅ erledigt (2026-06-17) | **(Doc-Punkt 3)** `residual_vector()` nutzt das neue Gewicht, hinter einem Schalter (`pose_estimation.use_marker_weight`, Default `false`) | A/B-Vergleich auf den appRobotRendering-Simulationsszenen (mit/ohne Schalter) gegen bekannte Grundwahrheit — genau der Test, der laut Nutzer beim ersten Versuch wenig brachte, jetzt wiederholbar | **Nein bei Default aus.** Mit `true`: Ergebnisse ändern sich gewollt — muss vor Produktiv-Default separat validiert werden |
| 3 | ✅ erledigt (2026-06-25) | **(Doc-Punkt 1)** `robot_fk.py`: neue Methode liefert die 4 lokalen Eckpunkte eines Markers im Weltsystem (Baustein, noch ohne Anbindung) | Isoliert testbar, ganz ohne `5_pose_estimation.py`: gegen die wahren Eckpositionen aus `render_*.json` (Simulation liefert das schon) | **Nein.** Neue, bisher von niemandem aufgerufene Methode |
| 4 | 🟡 Code erledigt (2026-06-25), Tuning offen | **(Doc-Punkt 1)** Neuer `marker_observation`-Modus (z. B. `"corner_points"`) nutzt die 12 Eck-Residuen statt 6 Center/Normal-Residuen | Direkter Vorher/Nachher-Vergleich gegen dieselbe Validierungstabelle wie in `Homing_5_Pose.md` (10 Simulationsposen, bekannte GT) | **Nein als Opt-in** (Default bleibt `"corner_pose"`). Tuning-Punkt: `huber_delta_mm` ist auf die heutige Residuumsgröße kalibriert — mit 12 statt 6 Werten/Marker verschiebt sich die RMS-Größenordnung, müsste neu eingeordnet werden |
| 4 | 🔴 Code da, aber DEAKTIVIERT (live gescheitert 2026-06-25 → robot.json zurück auf `corner_pose`) | **(Doc-Punkt 1)** Neuer `marker_observation`-Modus (z. B. `"corner_points"`) nutzt die 12 Eck-Residuen statt 6 Center/Normal-Residuen | Direkter Vorher/Nachher-Vergleich gegen dieselbe Validierungstabelle wie in `Homing_5_Pose.md` (10 Simulationsposen, bekannte GT) | **Nein als Opt-in** (Default bleibt `"corner_pose"`). Tuning-Punkt: `huber_delta_mm` ist auf die heutige Residuumsgröße kalibriert — mit 12 statt 6 Werten/Marker verschiebt sich die RMS-Größenordnung, müsste neu eingeordnet werden |
| 5 | ⬜ **offen** (Vorarbeit/Guards ✅) | **(Doc-Punkt 2)** 3b nimmt 1-Kamera-Beobachtungen mit auf (rohe 2D-Ecken + Kamera-Referenz), statt sie zu verwerfen | Output-Diff: nur neue Einträge für vorher fehlende Marker, bestehende ≥2-Kamera-Einträge unverändert | **Ja, konkret** — siehe Konsumenten-Recherche direkt unter der Tabelle. Mehrere Stellen brauchen einen Guard, **bevor** dieser Schritt scharf geschaltet wird |
| 6 | ⬜ **offen** | **(Doc-Punkt 2)** `residual_vector()` um Reprojektions-Residuen erweitert; `load_observations()`/`estimate_pose()` lesen zusätzlich Kamerakalibrierung | Zuerst an Simulationsszenen, bei denen gut beobachtete Marker künstlich auf „nur 1 Kamera" reduziert werden (GT bekannt) — saubere Kontrolle, ob das Residuum tatsächlich hilft, bevor reale Finger-Marker überhaupt existieren | **Nein strukturell** (additiver Residuumstyp), aber Regressionsrisiko durch falsche mm/px-Gewichtung — vor Produktiv-Default gegen die bestehende Validierungstabelle gegenprüfen (wie Schritt 4) |
| 7 | ⬜ **offen** | Zusammenführen: ein gemeinsames Gewichtsschema (Quality × Kamera-Anzahl × Residuumstyp) statt drei separater Schalter | End-to-End gegen Simulationsbenchmark **und** die drei realen Fixtures aus `Homing_5_Pose.md` | **Nein**, wenn alle Vorstufen additive Defaults hatten |
@@ -293,13 +293,35 @@ Alle anderen Konsumenten (`homing.js`, `editRobot.js` → `assignByZRange`/`alig
ziehen auch `corner_pose` leicht. Auf bereinigten Markern konvergiert
`corner_points``corner_pose`. → Marker-Zuordnung korrigieren (separate
Kalibrier-Aufgabe).
- **Scharfgeschaltet (2026-06-25, gescopt):** robot.json
`marker_observation: "corner_points"` mit
`corner_point_links: ["Hand","Palm","FingerA","FingerB"]`. D.h. nur Hand/Finger
nutzen die 4 Ecken; Arme behalten Center+Normale, Board nur Center. Auf der
Arm-Capture (ohne Finger-Marker) **byte-identisch** zu `corner_pose` → keine
Regression im bestehenden Pfad. Die Arme können in die Liste, sobald die
A0→Arm1-Fehlzuordnung behoben ist.
- **DEAKTIVIERT (2026-06-25) — Aktivierung am echten Roboter gescheitert,
zurückgedreht.** robot.json steht wieder auf `marker_observation:
"corner_pose"` (der bewährte Zustand). Der `corner_points`-Code bleibt im
Repo, ist aber **inaktiv** (opt-in).
**Was probiert wurde:** `corner_points` mit `corner_point_links:
["Hand","Palm","FingerA","FingerB"]` scharfgeschaltet (nur Hand/Finger über
Ecken, Arme/Board unverändert). Am echten Lauf (data/homing/20260625_175916)
kippte die Hand (`b` 52° → +62°) und `x` wanderte (160 → 110 mm).
**Belegte Ursache (Gegenprobe an denselben Daten):**
- `corner_pose` → gutes Ergebnis (`b`52, `x`≈160); `corner_points` → das
schlechte. Also eindeutig der Modus.
- Die **Eck-Konvention ist NICHT der Fehler**: 2 der 3 Finger-Marker passen am
guten Pose exakt (FingerB #178/#179, ~23 mm, korrekte Eck-Paarung fwd+r0).
- **Eigentliche Ursache: ein einzelner schlechter Marker.** FingerA **#147**
liegt **132 mm neben dem Modell** (Position/Zuordnung in robot.json noch
provisorisch, vgl. Commits „Finger1 Marker"/„zweiter Finger verdreht").
Im Eck-Modus liefert ein Marker **12 statt 3 Residuen** → ein einzelner
Ausreißer hat ~4× Zugkraft und reißt `global_ba` ins falsche Minimum.
`corner_pose` (3 Residuen) dämpft ihn per Huber weg.
**Damit `corner_points` je produktiv taugt, fehlen ZWEI Dinge:**
1. **Daten:** FingerA #147 sauber einmessen / Zuordnung prüfen.
2. **Code-Robustheit:** Ausreißer-Schutz im Eck-Modus (grob daneben liegende
Marker pro Marker auf Center zurückfallen lassen oder verwerfen), sonst
kippt jede reale Aufnahme mit *einem* schlechten Marker. Erst danach
gegen GT (Simulation oder Finger-Capture bekannter Pose), **nicht** live
erneut testen. CLI zum Vergleichen: `--marker-observation corner_points`.
- **Offen (Schritt 4 Tuning):** `huber_delta_mm` ist auf 6 Residuen/Marker
kalibriert; mit 12 verschiebt sich die RMS-Größenordnung. Sauberes A/B + Tuning
der Hand/Finger-Ecken gegen appRobotRendering-Simulations-GT steht aus (hier