Claude: Reorganzie
This commit is contained in:
160
doc/ToDo.md
Normal file
160
doc/ToDo.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 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:
|
||||
- [ ] Kameras kalibrieren (Schachbrett) → K + Distortion je Kamera. **Achtung:
|
||||
Intrinsics sind auflösungsabhängig** – sie müssen zur **`hires`-Auflösung**
|
||||
passen, die `/api/snapshot/{id}/hires` ausliefert (C270 1280×960,
|
||||
C920 1920×1080).
|
||||
- [ ] Intrinsics in `/api/cameras` je Kamera ausgeben (K, dist, `calib_size`),
|
||||
stabil gekeyt über `id`/`note`-Serial.
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user