Files
appRobotHoming/doc/ToDo.md
2026-06-10 09:39:32 +02:00

159 lines
7.3 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.
# ToDo appRobotHoming
Nächste Schritte für den Umbau zum statischen Frontend + HTTPS-BFF-Proxy.
Kontext/Architektur: siehe [`../README.md`](../README.md).
Reihenfolge ist grob nach Priorität sortiert. Offene Entscheidungen sind als
**Frage** markiert die müssen vor der Umsetzung geklärt werden.
---
## 1. HTTPS wieder zum Laufen bringen (blockierend)
**Diagnose abgeschlossen (2026-06-08):**
- Backend läuft auf 2093, aber als **HTTP** (`http://…:2093/` → 200 + UI;
`https://…:2093/` → keine Antwort). Es ist der **Container** (docker-compose):
`/api/health` meldet `webcamUrl: http://appRobotWebcam:8444`.
- Der Code ist korrekt: `https/localhost.key` + `localhost.pem` mit Passphrase
`abcd` laden lokal **einwandfrei** in `https.createServer`.
- **Root Cause:** Die Cert-Dateien **fehlen im Container**. `.gitignore` schließt
`*.key`/`*.pem`/`*.pfx` aus → nicht in git → der Mount
`/home/chk/Documents/appRobotHoming` auf `thinkcentre` hat sie nicht →
`createHttpsServer()` scheitert an `fsPromises.access()` → **stiller
HTTP-Fallback** (`server/server.js`, `createHttpsServer``return null`).
**Gewählte Lösung (Entscheidung): Cert reist mit dem Repo/Volume.**
Das self-signed Cert sichert nur den Hop **Proxy ↔ Backend** und hat keinen
echten Wert (nie öffentlich). Daher darf es mit ins Repo und kommt über den
bestehenden `/app`-Volume-Mount automatisch in den Container.
- [x] `.gitignore`: gezielte Ausnahme `!https/localhost.key` + `!https/localhost.pem`
(Schutz für alle anderen Schlüssel bleibt bestehen). → erledigt.
- [ ] `https/localhost.key` + `https/localhost.pem` committen.
- [ ] Deploy-Host `thinkcentre:/home/chk/Documents/appRobotHoming/` aktualisieren
(git pull bzw. Dateien bereitstellen), damit der Container sie sieht.
- [ ] Verifizieren: `https://thinkcentre.local:2093/api/health` antwortet über
**HTTPS** (aktuell nur HTTP).
Optional (separat, nicht Teil der Entscheidung):
- [ ] Passphrase/Pfad konsequent aus dem Env (`HTTPS_KEY_PATH`/`HTTPS_CERT_PATH`/
`HTTPS_PASSPHRASE`) statt hartkodiert.
- [ ] Stillen HTTP-Fallback lauter machen (klar loggen / hart abbrechen statt
unbemerkt HTTP) dieser Fallback hat den Bug verschleiert.
- [ ] Reverse-Proxy prüfen: Leitet er WSS-Upgrade-Header korrekt an
`https://…:2093` weiter?
---
## 2. WebCam-Bilder über die dokumentierte API holen → **entschieden: Option B**
`server/server.js` ruft aktuell `WEBCAM_URL + /api/latest-snapshot` auf diesen
Endpoint gibt es **nicht**. **Entscheidung:** Der Homing-Backend setzt das Bundle
selbst aus den dokumentierten Endpoints zusammen (kein neuer Endpoint im
WebCam-Service).
Service läuft und ist erreichbar unter `http://thinkcentre.local:8444`
(→ `WEBCAM_URL`). Real verifizierte Contracts:
- `GET /api/cameras`
```json
{"cameras":[
{"id":"cam0","name":"Kamera 0","position":"front","stream":true,"hires":true, ...},
{"id":"cam1","name":"Kamera 1","position":"left", "stream":true,"hires":true, ...},
{"id":"cam2","name":"Kamera 2","position":"right","stream":true,"hires":true, ...}
]}
```
- `GET /api/snapshot/{id}/hires` → `200 image/jpeg` (cam0/cam1 ~1280px, cam2 1920px).
- `GET /health` → Status + `state`/`hasFrame` pro Kamera.
Umsetzung in `server/server.js` (`/api/latest-snapshot`):
- [ ] `GET {WEBCAM_URL}/api/cameras` holen → Kameraliste (mit `hires:true` filtern).
- [ ] Für jede Kamera **parallel** `GET {WEBCAM_URL}/api/snapshot/{id}/hires` →
JPEG, als base64 + `id`/`position` ins Bundle.
- [ ] Bundle ans UI zurückgeben (statt der bisherigen CSV-Annahme). Reihenfolge/
Zuordnung über `id`+`position` stabil halten (wichtig für §3).
- Hinweis: Die alte CSV/`_annotated.jpg`/JSON-Marker-Erkennung kommt **nicht**
von der Webcam. Für den BodyTracker-Pfad ist sie ohnehin redundant
(BodyTracker macht ArUco selbst); sie bleibt nur für den lokalen Fallback
`public/calculateAngles.js` relevant.
---
## 3. Intrinsics-Fluss → **entschieden: WebCam liefert Intrinsics mit**
**Klarstellung der Datentypen** (im Altcode unter „Intrinsics" vermischt):
| Typ | Beispiel | Quelle | statisch |
|---|---|---|---|
| **Kamera-Intrinsics** (K, Distortion) | das echte „NPZ" | Kalibrierung | ✅ pro Kamera |
| **Extrinsics** (`position_mm`, `orientation_deg`) | in `_two_cam.json` | wird gelöst | ❌ Output |
| **Marker-3D-Posen** | in `_two_cam.json` | trianguliert | ❌ Output |
Das, was `server/server.js` heute als `robotIntrinsics` (= `_two_cam.json`)
schickt, sind **Extrinsics + triangulierte Marker** also **BodyTracker-Output**,
fälschlich als Input verschickt. Muss raus.
Die WebCam liefert aktuell **kein** NPZ (alle Intrinsics-Endpoints → 404). Der
BodyTracker hält in `/v1/config` nur Solver-Parameter, keine Intrinsics.
**Entscheidung:** Die Kamera-Intrinsics leben beim **WebCam-Service** (Source of
Truth) und werden mitgeliefert. Homing reicht sie an den BodyTracker durch.
Aufgaben WebCam-Service:
- [x] **Kalibrierung vorhanden** (verifiziert 2026-06-10): `/api/cameras` liefert
`calibrationUrl` für alle 3 Kameras (cam0/cam1/cam2). `.npz`-Abruf über
`GET /api/cameras/{id}/calibration` → `application/octet-stream` funktioniert.
Kein Neu-Kalibrieren nötig.
Aufgaben Homing-Backend (`server/server.js`):
- [ ] `robotIntrinsics`/`_two_cam.json`-Pfad aus `/api/estimate` entfernen.
- [ ] Pro Kamera Bild + zugehörige Intrinsics paaren (über `id`) und an
`BODYTRACKER/v1/estimate` weiterreichen. **N Kameras** (aktuell 3), nicht
fix 2.
Aufgaben BodyTracker (wir besitzen ihn):
- [ ] `/v1/estimate` so anpassen, dass er Intrinsics **als JSON je Kamera**
annimmt (kein `.npz`-Zwang) erspart NPZ-Erzeugung in Node. Format
gemeinsam festzurren (K 3×3 oder fx/fy/cx/cy, dist k1,k2,p1,p2,k3,
`image_size`).
---
## 4. Aufräumen (Altlasten aus der WSS/HTTPS-Server-Ära)
- [ ] `docker-compose.yaml`: `WSS_VIDEO_DRIVER`, `WSS_URL`, `HTTPS_PORT`-Doppelung
und `depends_on: appRobotDriver` prüfen/entfernen. Behalten: `WEBCAM_URL`,
`BODYTRACKER_URL`, Port-Mapping `2093`, Cert-Volume.
- [ ] `package.json` → `description` ist veraltet („verbindet zu WSS, sendet
Befehle").
- [ ] Command-Buttons in `public/index.html` (HOME/STOP/STATUS/RESET/PING/
GCodeMotor) rufen `window.sendCommand` **das ist nirgends definiert**
(alter WSS-Transport). Entweder neuen Transport anbinden (gehört zu
Erweiterung „Pose an appRobotDriver") oder bis dahin deaktivieren.
- [ ] `public/snapshots` (Fallback) ist leer → `findLatestSnapshotFile()` liefert
`null` → 404. Beispiel-Datensatz ablegen **oder** Fallback dokumentiert
abschalten.
---
## 5. Frontend / UX (geplante Erweiterungen)
- [ ] Erkennungsergebnis + erkannte Pose klarer ausgeben (statt nur Roh-JSON).
- [ ] Manuelle Eingabe von `x, y, z, a, b, c, e`.
- [ ] Wenn Hand nicht erkannt: Vorschlag für bessere Arm-/Foto-Position.
- [ ] Pose an `appRobotDriver` weitergeben (neuer Schritt nach BodyTracker;
ggf. der WSS-Pfad, für den HTTPS gebraucht wird).
---
## Definition of Done (erster Meilenstein)
1. `https://<host>:2093/` liefert das statische UI über **HTTPS**.
2. `GET /api/latest-snapshot` liefert reale Bilder/Daten vom WebCam-Service.
3. `POST /api/estimate` liefert eine Pose vom BodyTracker und zeigt sie im UI.
4. Keine toten Buttons / keine WSS-Altlasten in Compose & package.json.