Claude: Lens-Distortions

This commit is contained in:
chk
2026-06-02 11:37:29 +02:00
parent ac81c2e0cb
commit 5ad956be81
91 changed files with 31707 additions and 23702 deletions

View File

@@ -0,0 +1,420 @@
# Docker Containerization Roadmap
## Ziel
Die Blender-Rendering-Pipeline soll vollständig containerisiert und später in eine verteilte Job-Infrastruktur integriert werden.
Wichtige Randbedingungen:
* Blender-Container sollen nur laufen, wenn tatsächlich Renderaufträge vorhanden sind.
* Verschiedene Jobtypen sollen unterschiedliche Container verwenden können.
* Die Infrastruktur soll zukünftig nicht nur Blender-Rendering, sondern auch andere Workloads (AI-Training, STL-Verarbeitung, Datensatz-Generierung, Batch-Konvertierungen usw.) unterstützen.
* Die Ausführung soll auf mehreren PCs/Worker-Nodes möglich sein.
* Die bestehende Python-Logik soll möglichst unverändert bleiben.
---
# Review / Bewertung
**Gesamteinschätzung:** schlüssig und machbar. Die Zielarchitektur (Redis-Queue +
Nomad-Scheduler, Container nur bei Bedarf, mehrere Workload-Typen, horizontale Skalierung)
ist tragfähig und zukunftssicher. Es fehlen einige technische Punkte, die unten ergänzt sind.
## Wichtigste Korrektur: Renderer und Pipeline sind ZWEI Container, nicht einer
Phase 1 spricht von „Rendering-Pipeline **+** Analyse-Pipeline" in *einem* Container.
Das sollte getrennt werden — die beiden haben grundverschiedene Profile:
| | Render-Container | Pipeline-Container |
|---|---|---|
| Image | `approbot/blender-renderer` | `approbot/pose-pipeline` |
| Basis | Blender 4.5 + bpy + cv2 + numpy (~12 GB) | `python:3.11-slim` + numpy/scipy/opencv (~200 MB) |
| GPU | ja (Cycles, CUDA/OPTIX) | nein |
| Zweck | **Test-Datengenerator** (nur Sim/Dev) | **Produkt** (läuft auch mit echten Webcam-Fotos!) |
| Änderungsrate | selten | häufig |
| CI-tauglich | nein (schwer, GPU) | ja (schnell, headless) |
Das ist keine Kosmetik: Die **Pipeline ist das eigentliche Deliverable** (Roboter-Pose
aus Fotos) und wird real deployed; der Renderer ist nur Werkzeug zur Testdaten-Erzeugung.
Getrennt heißt: die Pipeline bleibt schlank, schnell CI-testbar und ohne Blender-Ballast
deploybar; der Renderer wird nur dort gestartet, wo eine GPU steht.
**Datenaustausch** zwischen beiden: gemeinsames Volume (Phase 13), später Object-Storage
(MinIO/S3) im verteilten Betrieb.
## Technische Schlüsselpunkte (bisher nicht in der Roadmap)
1. **cv2 in Blenders Python:** `render_robot.py` importiert `cv2` (ArUco-Generierung).
Blender bringt sein *eigenes* gebündeltes Python mit — `opencv-python` muss **dort**
installiert werden (`<blender>/python/bin/python -m pip install opencv-python`),
nicht ins System-Python. Häufige Stolperfalle.
2. **ArUco = opencv-contrib:** Die Pipeline nutzt `cv2.aruco`. Im Pipeline-Container
`opencv-contrib-python-headless` verwenden (nicht Basis-`opencv-python`), Version pinnen.
3. **robot.json-Mutation ist im Parallelbetrieb ein Race:** `render_Loop.py` schreibt
pro Render in die *gemeinsame* `robot.json` (Kamera, Pose, Auflösung). Laufen mehrere
Render-Jobs parallel auf einem Node, überschreiben sie sich gegenseitig. Im Job-Modell
muss jeder Job seine Parameter aus dem **Job-Payload** bekommen und in eine **eigene
temporäre Config** schreiben — nicht in die geteilte robot.json. (Architektur-Fix,
gehört *vor* Phase 4.)
4. **GPU im Container & Scheduler:** `--gpus all` + NVIDIA Container Toolkit; Nomad braucht
das GPU-Device-Plugin, damit Render-Jobs nur auf GPU-Nodes landen. CPU-Fallback (Cycles
`device='CPU'`) als Sicherheitsnetz behalten.
5. **Versionen pinnen:** Blender 4.5.x exakt, `requirements.txt` mit festen Versionen
(numpy/scipy/opencv) — sonst driften die Mess-Ergebnisse (vgl. der fy-Intrinsik-Bug).
6. **Job-Granularität:** `{"jobType":"blender-render","pose":8}` rendert 7 Kameras pro Job.
Feinkörniger (1 Job = 1 Kamera) parallelisiert besser über mehrere Nodes — abwägen.
## Empfehlung: MVP vor Nomad
Redis + Nomad ist die richtige End-Vision, aber als Zwischenstufe genügt **docker-compose
mit zwei Images + Profiles** (Renderer on-demand via `docker compose run`, Pipeline als
schneller Service / CI-Step). Damit sind getrennte Container + Phase 13 produktiv nutzbar,
bevor die verteilte Orchestrierung (Phase 58) aufgebaut wird.
---
# Phase 1 Dockerisierung der bestehenden Rendering-Pipeline
## Ziel
Die aktuelle Blender-Pipeline läuft vollständig innerhalb eines Docker-Containers.
### Aufgaben
* [x] Dockerfile erstellen → **in zwei aufteilen:** `Dockerfile.renderer` (Blender) + `Dockerfile.pipeline` (slim Python)
* [x] docker-compose.yaml erstellen
* [ ] cv2 in Blenders gebündeltem Python installieren (für ArUco-Generierung)
* [ ] requirements.txt für den Pipeline-Container (numpy, scipy, opencv-contrib-python-headless), Versionen gepinnt
* [ ] Blender 4.5 Container erfolgreich starten
* [ ] render_loop.py innerhalb des Containers ausführen
* [ ] render_robot.py innerhalb des Containers ausführen
* [ ] STL-Import validieren
* [ ] PNG-Ausgabe validieren
* [ ] NPZ-Ausgabe validieren
* [ ] Pipeline auf PNG-Ausgaben ermöglichen
* [ ] markers.json validieren
### Ergebnis
Zwei Container: `blender-renderer` erzeugt Bilder/npz/Ground-Truth, `pose-pipeline`
wertet sie aus — beide reproduzierbar, über ein gemeinsames Daten-Volume verbunden.
---
# Phase 2 Pfad-Unabhängigkeit
## Ziel
Alle absoluten Benutzerpfade entfernen.
### Aktuelle Situation
Beispiel:
```python
Path.home() / "SynologyDrive" / ...
```
### Ziel
Container-interne Pfade verwenden:
```text
/workspace/data
/workspace/setup
/workspace/output
```
### Aufgaben
* [ ] ROBOT_JSON_FILE auf Containerpfade umstellen
* [ ] OUTPUT_FILE auf Containerpfade umstellen
* [ ] STL-Suche auf Containerpfade umstellen
* [ ] Konfiguration über Environment-Variablen ermöglichen
* [ ] **render_robot.py: Config-Pfad per env (`ROBOT_JSON`)** statt hardcodiert; und
**render_Loop.py: pro Render eine *temporäre* Config schreiben** statt die geteilte
robot.json zu mutieren (Voraussetzung für parallele Jobs, siehe Schlüsselpunkt 3)
* [ ] BLENDER_EXE per env/PATH (aktuell hardcodierter Windows-Pfad)
### Ergebnis
Die Pipeline ist vollständig unabhängig vom lokalen Benutzerprofil und parallel-tauglich.
---
# Phase 3 Repository-Struktur bereinigen
## Ziel
Klare Trennung zwischen Code, Daten und Ergebnissen.
### Zielstruktur
```text
appRobotRendering/
├── data/
│ ├── robot/
│ ├── simulation/
│ └── surfaces/
├── setup/
│ └── generateSets/
│ ├── render_loop.py
│ ├── render_robot.py
│ ├── Dockerfile
│ └── docker-compose.yaml
├── jobs/
└── output/
```
### Aufgaben
* [ ] Verzeichnisstruktur vereinheitlichen
* [ ] Dokumentation ergänzen
* [ ] Mountpoints definieren
---
# Phase 4 Job-Modell einführen
## Ziel
Rendering-Aufträge werden als eigenständige Jobs beschrieben.
### Beispiel
```json
{
"jobType": "blender-render",
"pose": 8
}
```
### Spätere Erweiterungen
```json
{
"jobType": "dataset-generation"
}
```
```json
{
"jobType": "stl-conversion"
}
```
```json
{
"jobType": "ai-training"
}
```
### Aufgaben
* [ ] Job-Format definieren
* [ ] Job-Metadaten definieren
* [ ] Retry-Konzept definieren
* [ ] Statusmodell definieren
### Status
```text
queued
running
completed
failed
timeout
```
---
# Phase 5 Redis als Queue
## Ziel
Entkopplung zwischen Auftragserzeugung und Ausführung.
### Aufgaben
* [ ] Redis bereitstellen
* [ ] Job-Queue definieren
* [ ] Job-Status speichern
* [ ] Retry-Mechanismus definieren
### Hinweis
Redis startet keine Worker.
Redis dient ausschließlich als:
* Queue
* Statusspeicher
* Kommunikationsschicht
---
# Phase 6 Nomad Scheduler
## Ziel
Container werden nur bei tatsächlichem Bedarf gestartet.
### Architektur
```text
Job Producer
Redis
Nomad
Docker Container
```
### Aufgaben
* [ ] Nomad Server aufsetzen
* [ ] Worker-Nodes registrieren
* [ ] Docker Driver aktivieren
* [ ] Batch-Jobs definieren
### Ergebnis
Nomad entscheidet:
* welcher Node frei ist
* welcher Container gestartet wird
* wann ein Container beendet wird
---
# Phase 7 Blender als Nomad Batch Job
## Ziel
Blender läuft nur während der Bearbeitung eines Auftrags.
### Beispiel
```text
Job:
blender-render
Container:
approbot/blender-renderer:latest
```
Ablauf:
1. Job wird eingereicht
2. Nomad startet Blender-Container
3. Rendering läuft
4. Ergebnisse werden gespeichert
5. Container beendet sich
6. Ressourcen werden freigegeben
### Ergebnis
Keine dauerhaft laufenden Blender-Worker.
---
# Phase 8 Multi-Container Plattform
## Ziel
Beliebige Jobtypen auf derselben Infrastruktur ausführen.
### Beispiele
#### Blender Rendering
```text
Container:
approbot/blender-renderer
```
#### AI Training
```text
Container:
approbot/trainer
```
#### STL Processing
```text
Container:
approbot/stl-worker
```
#### Dataset Generation
```text
Container:
approbot/dataset-worker
```
### Ergebnis
Der verwendete Container wird durch den Jobtyp bestimmt.
---
# Zielarchitektur
```text
Nomad
┌────────────────┼────────────────┐
│ │ │
Blender Job AI Job Dataset Job
│ │ │
Blender Training Dataset Worker
Container Container Container
└────────────────┼────────────────┘
Docker
Worker Nodes (PCs)
```
Eigenschaften:
* keine dauerhaft laufenden Blender-Container
* unterschiedliche Container pro Jobtyp
* horizontale Skalierung auf mehrere PCs
* saubere Trennung von Scheduling und Ausführung
* zukünftige Erweiterbarkeit für beliebige Workloads
---
# Offene Punkte / nicht vergessen
* **Cluster-Storage:** geteiltes NFS/Volume (einfach) vs. Object-Storage MinIO/S3
(entkoppelt Nodes, skaliert). Ab >1 Worker-Node bevorzugt Object-Storage.
* **robot.json als geteilter Mutable-State auflösen** (Schlüsselpunkt 3) — Voraussetzung
für parallele Render-Jobs auf einem Node.
* **Reproduzierbarkeit:** Blender- und Python-Versionen pinnen; `requirements.txt` einchecken.
* **GPU-Headless:** prüfen, ob Cycles im Container EGL braucht; sonst CPU-Fallback verifizieren.
* **CI-Hook:** Pipeline-Container in CI → `benchmark/run_benchmark.py` gegen Ground-Truth
bei jedem Commit (schnell, ohne Blender) — fängt Regressionen wie den fy-Bug automatisch.
* **Monitoring/Logs:** Job-Logs zentral (stdout → Nomad/Loki), Render-Zeiten messen.
* **Image-Registry:** private Registry (Harbor o. Ä.) für die `approbot/*`-Images.