spin Marker Callibration

This commit is contained in:
chk
2026-06-15 09:23:21 +02:00
parent 375ee4cf69
commit 15d4175fd1
18 changed files with 1191 additions and 239 deletions

197
README.md
View File

@@ -1,105 +1,152 @@
# appRobotHoming
`appRobotHoming` ist die browserbasierte Bedienoberfläche für die WebCam-gestützte
Ermittlung der Roboterpose. Das Frontend bleibt der Einstieg; die eigentliche
Bildverarbeitung läuft hinter der Firewall auf eigenen Services (WebCam,
BodyTracker), die der Homing-Backend als schlanker Proxy anspricht.
Browserbasierte Bedienoberfläche für das kameragestützte **Homing** und die
**Kalibrierung** eines Roboterarms. Das Frontend kommuniziert mit einem Node.js-Backend
(BFF-Proxy), das Kamera-Bilder, ArUco-Erkennung und Gelenk-Winkel-Schätzung
über Python-Skripte orchestriert.
## Architektur im Überblick
## Architektur
```
Browser ──HTTPS──▶ Reverse-Proxy ──HTTPS/WSS──▶ appRobotHoming-Backend
(statisches UI) (öffentliches TLS) (server/server.js, Port 2093)
intern (hinter der Firewall, HTTP):
├──▶ WebCam-Service (Bilder)
├──▶ BodyTracker-Service (Pose)
└──▶ … weitere Schritte (später)
Browser ──HTTPS──▶ Reverse-Proxy ──HTTPS──▶ appRobotHoming-Backend (Port 2093)
server/server.js
intern (HTTP):
├──▶ WebCam-Service (Bilder, NPZ)
└──▶ Robot-Driver (POST /api/state)
```
- **Frontend (`public/`)** statische Seite: zeigt Infos, Buttons und die
Rückmeldungen (Result als JSON + Tree-View, Snapshot-Tabelle, Bilder). Kein
direkter Zugriff auf die internen Services.
- **Backend (`server/server.js`)** BFF-Proxy. Liefert das statische Frontend
aus und stellt eine kleine API bereit, über die das UI an die internen
Services kommt. Läuft auf **HTTPS, Port 2093**.
**Frontend (`public/`):** statische Seiten — Homing, Kalibrierung, Board-Viewer,
Scene-Viewer. Kein direkter Zugriff auf interne Services.
## Ablauf
**Backend (`server/server.js`):** HTTPS-BFF auf Port 2093. Liefert Frontend aus,
orchestriert Python-Skripte (SSE-Stream) und liest/schreibt `robot.json`.
1. Das UI lädt den aktuellen Stand über `GET /api/latest-snapshot`.
2. **Bilder und Kamera-Intrinsics kommen vom WebCam-Service** (eigener Server
hinter der Firewall; die Kamera ist Source of Truth ihrer eigenen Kalibrierung).
3. Auf Knopfdruck schickt das UI eine Pose-Anfrage an `POST /api/estimate`.
4. Der Backend reicht **Bilder + Intrinsics** zur Verarbeitung an den
**BodyTracker** weiter und erhält die Roboterpose zurück.
5. Das Ergebnis wird im UI ausgegeben (JSON, Tree, Tabelle, annotierte Bilder).
6. **Eventuell folgen weitere Schritte** (z. B. Pose an `appRobotDriver` geben).
## Funktionen
Fällt der BodyTracker aus, rechnet das Frontend ersatzweise lokal mit
`public/calculateAngles.js`.
| Seite | Pfad | Beschreibung |
|-------|------|--------------|
| Homing | `/` (`index.html`) | Homing-Run starten, Status, GCode-Ausgabe |
| Kalibrierung | `/calibration.html` | Tabs: Camera NPZ · Board · X-Achse · Arm1-Y · **Marker** |
| Board-Viewer | `/boardViewer.html` | 3D-Viewer: Board-Marker, Skeleton FK, Arm-Marker mit Spin |
| Scene-Viewer | `/sceneViewer.html` | Standalone-Viewer (Datei-Upload, keine Server-Abhängigkeit) |
| Homing-Detail | `/homing.html` | Detail-Ansicht eines Homing-Laufs |
## HTTPS (bewusste Entscheidung)
## Homing-Ablauf
Der Backend läuft selbst auf **HTTPS** auch wenn davor schon ein Reverse-Proxy
die öffentliche TLS-Terminierung übernimmt. Grund: **WebSocket-Verbindungen (WSS)
kommen nur sauber durch den Proxy, wenn auch der Backend-Hop TLS spricht.**
```
Foto alle Kameras
→ 1_detect_aruco_observations.py (ArUco-Erkennung, pro Kamera)
→ 2_estimate_camera_from_observations.py (Kamera-Pose)
→ 3b_corner_marker_poses.py (Marker-Triangulierung)
→ X-Position schätzen (JS: server/homingXEstimate.cjs)
→ 4b_revolute_angle.py Arm1 / Ellbow / Arm2 / Hand (Gelenk-Winkel)
→ POST ROBOT_URL/api/state
```
- Das verwendete Zertifikat ist **self-signed** (`https/`, Passphrase `abcd`).
Das ist Absicht: Dieser Hop ist nur **Proxy ↔ Backend**, nie öffentlich. Die
vertrauenswürdige Kette stellt der vorgelagerte Reverse-Proxy bereit.
- Zugriff im internen Netz z. B. über `https://thinkcentre.local:2093/`.
SSE-Events (`log` / `step` / `analysis` / `done`) streamen den Fortschritt live
ins Frontend. Der Board-Viewer zeigt das Skeleton progressiv nach jedem erkannten Gelenk.
## API (Backend)
Details: [`doc/Homing_ROADMAP.md`](doc/Homing_ROADMAP.md)
## Kalibrierung
Einmaliger Vorgang nach mechanischen Änderungen:
| Schritt | Tab | Ergebnis |
|---------|-----|---------|
| 1 Camera NPZ | Camera NPZ | Kamera-Intrinsics als `.npz` |
| 2 Board | Board | `links.Board.markers` in `robot.json` |
| 3 X-Achse | Robot X Axis | alle Marker-Positionen rotiert |
| 4 Arm1-Y | Arm1 Y | `links.Arm1.jointToParent.origin[1,2]` |
| 5 Arm-Marker | Marker | Spin-Korrektur, Orientierungs-Verifikation |
Details: [`doc/Kalibrierung.md`](doc/Kalibrierung.md) ·
[`doc/Kalibrierung_Marker.md`](doc/Kalibrierung_Marker.md) ·
[`doc/accessRobotAPI.md`](doc/accessRobotAPI.md) (robot.json via Driver)
## robot.json
Zentrale Konfiguration aller Gelenke, Marker und Kinematik-Parameter.
```
ROBOT_JSON = process.env.ROBOT_JSON || 'scripts/robot_1781069752019.json'
```
Enthält: `links.{Link}.markers[].{id, position, normal, size, spin}`,
`links.{Link}.jointToParent`, `defaultPosition`, `robot_test_poses`.
## API-Übersicht
| Endpoint | Methode | Zweck |
|---|---|---|
| `/api/health` | GET | Status + konfigurierte Service-URLs |
| `/api/latest-snapshot` | GET | Aktuelle Bilder/Daten (vom WebCam-Service bzw. lokalem Fallback) |
| `/api/estimate` | POST | Bilder an BodyTracker geben → Pose zurück |
|----------|---------|-------|
| `/api/robot` | GET | robot.json lesen |
| `/api/robot/set-arm-marker-spin` | POST | Spin eines Arm-Markers setzen |
| `/api/robot/set-joint-origin` | POST | Joint-Origin Y/Z setzen |
| `/api/robot/assign-by-z` | POST | Marker nach Z-Bereich zuordnen |
| `/api/robot/adopt-x-axis` | POST | X-Achse übernehmen |
| `/api/board/run` | POST | Board-Pipeline starten (SSE) |
| `/api/board/latest` | GET | Letzter Board-Run (Marker + Robot) |
| `/api/homing/run` | POST | Homing-Lauf starten (SSE) |
| `/api/homing/send-state` | POST | State an Robot-Driver senden |
| `/api/homing/run-data` | GET | Debug-Daten eines Runs |
| `/api/calibration/*` | POST/GET | Kalibrierungs-Session verwalten |
## Konfiguration (Umgebungsvariablen)
## Konfiguration
| Variable | Bedeutung |
|---|---|
| `HTTPS_PORT` | Port des Backends (Default `2093`) |
| `WEBCAM_URL` | Basis-URL des internen WebCam-Services |
| `BODYTRACKER_URL` | Basis-URL des internen BodyTracker-Services |
| `HTTPS_KEY_PATH` / `HTTPS_CERT_PATH` / `HTTPS_PASSPHRASE` | self-signed Cert für den Proxy-Hop |
Ist `WEBCAM_URL` nicht gesetzt, nutzt der Backend lokale Dateien aus
`public/snapshots` als Fallback (Entwicklung ohne Kamera).
|----------|-----------|
| `HTTPS_PORT` | Port (Default `2093`) |
| `WEBCAM_URL` | Interner WebCam-Service |
| `ROBOT_URL` | Interner Robot-Driver |
| `ROBOT_JSON` | Pfad zu robot.json (Default `scripts/robot_1781069752019.json`) |
| `HTTPS_KEY_PATH` / `HTTPS_CERT_PATH` / `HTTPS_PASSPHRASE` | self-signed Cert |
## Dateien & Struktur
- `public/` statisches Frontend (UI, Client-Logik, Anzeige).
- `server/server.js` HTTPS-Backend / BFF-Proxy.
- `https/` self-signed Zertifikate für den Proxy-Hop (nicht eingecheckt).
- `doc/README_WebCam.md` WebCam-Service (Bildquelle).
- `doc/README_BodyTracker.md` BodyTracker-Service (Pose-Ermittlung).
- `doc/ToDo.md` offene Punkte & nächste Umsetzungsschritte.
- `test/` Tests für Berechnung und Auswertung.
```
public/ Frontend (HTML, JS, CSS)
boardViewer.html 3D-Viewer mit Three.js FK, Arm-Markern, Spin-Rendering
sceneViewer.html Standalone-Viewer (nur Datei-Upload)
calibration*.html Kalibrierungs-Tabs (lazy-geladen)
client.js Homing-Frontend-Logik
calibration.js Kalibrierungs-Frontend-Logik
server/
server.js Express-Backend, alle API-Routes
editRobot.js robot.json lesen/schreiben
homingOrchestrator.js Homing-Ablauf (SSE-Stream)
homingXEstimate.cjs X-Schätzung (reine Geometrie, unit-getestet)
spinNormalize.cjs Spin-Normalisierung [0,360) (unit-getestet)
scripts/
robot_1781069752019.json Haupt-Konfiguration (robot.json)
1_detect_aruco_observations.py
2_estimate_camera_from_observations.py
3b_corner_marker_poses.py
4b_revolute_angle.py
test/
homingXEstimate.test.js X-Schätzungs-Geometrie (9 Tests, inkl. Regression)
spinNormalize.test.js Spin-Normalisierung (5 Tests)
yAxisComputeJs.test.js Y-Achsen-Berechnung
yAxisRotation.test.js Rotations-Mathe
doc/
Homing_ROADMAP.md Homing-Ablauf und Implementierungs-Status
Kalibrierung.md Kalibrierungs-Schritte 14
Kalibrierung_Marker.md Arm-Marker: Datenmodell, Spin-Verifikation, Roadmap P1P5
ToDo.md Offene Punkte
```
## Nutzung
```bash
npm install
npm test
npm start # startet den HTTPS-Backend auf Port 2093
npm test # Jest-Tests (14+ Tests)
npm start # HTTPS-Backend auf Port 2093
```
Danach im internen Netz `https://<host>:2093/` öffnen (self-signed → einmalige
Zertifikatswarnung im Browser bestätigen).
Danach: `https://<host>:2093/`
> Hinweis: Das Frontend ist auf den Backend angewiesen `/api/latest-snapshot`
> und `/api/estimate` funktionieren **nicht**, wenn man `index.html` rein
> statisch öffnet. Immer über `npm start` (bzw. den Container) laufen lassen.
## Geplante Erweiterungen
1. Pose an `appRobotDriver` weitergeben.
2. Wenn die Hand nicht erkannt wird: Vorschlag für eine bessere Arm-/Foto-Position.
3. Manuelle Eingabe von `x, y, z, a, b, c, e`.
4. Erkennungsergebnis und Pose klarer im UI ausgeben.
Konkrete nächste Schritte und offene Schnittstellen-Fragen: siehe
[`doc/ToDo.md`](doc/ToDo.md).
> self-signed Zertifikat → einmalige Browser-Warnung bestätigen.
> Frontend benötigt laufendes Backend (API-Calls beim Laden).