From 53db55ba36b8d53fd2b8f44b43ca4b12fecec5c3 Mon Sep 17 00:00:00 2001 From: chk <79915315+ChKendel@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:50:36 +0200 Subject: [PATCH] Initial commit --- README.md | 149 ++ config/robot.json.example | 19 + doc/api_integration.md | 239 +++ doc/robot_json.md | 280 +++ doc/robot_json_pipeline_schema.md | 28 + docker-compose.yaml | 25 + pyproject.toml | 25 + scripts/__init__.py | 23 + scripts/__main__.py | 43 + scripts/api/__init__.py | 12 + scripts/api/__main__.py | 17 + scripts/api/server.py | 83 + scripts/pipeline.py | 180 ++ .../pipeline/1_detect_aruco_observations.py | 608 +++++++ .../2_estimate_camera_from_observations.py | 834 +++++++++ .../3_multiview_bundle_adjustment_v4.py | 1499 +++++++++++++++++ scripts/pipeline/3b_corner_marker_poses.py | 189 +++ .../__pycache__/robot_fk.cpython-311.pyc | Bin 0 -> 17903 bytes scripts/pipeline/pose_estimation.py | 539 ++++++ scripts/pipeline/robot_fk.py | 310 ++++ tests/data/Scene9a/pose.json | 91 + tests/data/Scene9a/render_a.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_a.png | Bin 0 -> 1964004 bytes tests/data/Scene9a/render_b.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_b.png | Bin 0 -> 1844457 bytes tests/data/Scene9a/render_c.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_c.png | Bin 0 -> 1775547 bytes tests/data/Scene9a/render_d.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_d.png | Bin 0 -> 1833271 bytes tests/data/Scene9a/render_e.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_e.png | Bin 0 -> 1795797 bytes tests/data/Scene9a/render_f.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_f.png | Bin 0 -> 2040030 bytes tests/data/Scene9a/render_g.npz | Bin 0 -> 1394 bytes tests/data/Scene9a/render_g.png | Bin 0 -> 1912378 bytes tests/data/robot.json | 468 +++++ tests/fixtures/robot_minimal.json | 19 + tests/test_e2e.py | 123 ++ tests/test_pipeline.py | 57 + 39 files changed, 5860 insertions(+) create mode 100644 README.md create mode 100644 config/robot.json.example create mode 100644 doc/api_integration.md create mode 100644 doc/robot_json.md create mode 100644 doc/robot_json_pipeline_schema.md create mode 100644 docker-compose.yaml create mode 100644 pyproject.toml create mode 100644 scripts/__init__.py create mode 100644 scripts/__main__.py create mode 100644 scripts/api/__init__.py create mode 100644 scripts/api/__main__.py create mode 100644 scripts/api/server.py create mode 100644 scripts/pipeline.py create mode 100644 scripts/pipeline/1_detect_aruco_observations.py create mode 100644 scripts/pipeline/2_estimate_camera_from_observations.py create mode 100644 scripts/pipeline/3_multiview_bundle_adjustment_v4.py create mode 100644 scripts/pipeline/3b_corner_marker_poses.py create mode 100644 scripts/pipeline/__pycache__/robot_fk.cpython-311.pyc create mode 100644 scripts/pipeline/pose_estimation.py create mode 100644 scripts/pipeline/robot_fk.py create mode 100644 tests/data/Scene9a/pose.json create mode 100644 tests/data/Scene9a/render_a.npz create mode 100644 tests/data/Scene9a/render_a.png create mode 100644 tests/data/Scene9a/render_b.npz create mode 100644 tests/data/Scene9a/render_b.png create mode 100644 tests/data/Scene9a/render_c.npz create mode 100644 tests/data/Scene9a/render_c.png create mode 100644 tests/data/Scene9a/render_d.npz create mode 100644 tests/data/Scene9a/render_d.png create mode 100644 tests/data/Scene9a/render_e.npz create mode 100644 tests/data/Scene9a/render_e.png create mode 100644 tests/data/Scene9a/render_f.npz create mode 100644 tests/data/Scene9a/render_f.png create mode 100644 tests/data/Scene9a/render_g.npz create mode 100644 tests/data/Scene9a/render_g.png create mode 100644 tests/data/robot.json create mode 100644 tests/fixtures/robot_minimal.json create mode 100644 tests/test_e2e.py create mode 100644 tests/test_pipeline.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..b246c6c --- /dev/null +++ b/README.md @@ -0,0 +1,149 @@ +# appRobotBodyTrack + +3D-Body-Tracking für Roboter aus Mehrkamera-ArUco-Bildern. + +**Input** +- Bilder: `render_*.png` +- Intrinsics: `render_*.npz` +- Konfiguration: `robot.json` + +**Output** +- Gelenke **R⁷** → `{x, y, z, a, b, c, e}` (mm / Grad) + +--- + +## Interfaces + +Eine Logik, drei Zugänge: + +- **Python** +- **CLI** +- **REST (FastAPI)** + +--- + +## Quickstart + +### Python + +```python +from scripts import estimate_from_dir + +result = estimate_from_dir("data/Scene8", robot_json="robot.json") + +print(result.joints) +print(result.confidence) +``` + +--- + +### CLI + +```bash +pip install -e . + +python -m scripts data/Scene8 --robot robot.json +python -m scripts data/Scene8 --robot robot.json --cameras a,b,d +``` + +--- + +### REST API + +```bash +docker compose up +``` + +**Request:** + +```python +import requests + +resp = requests.post( + "http://localhost:8446/v1/estimate", + files=[ + ("images", ("render_a.png", open("render_a.png", "rb"))), + ("intrinsics", ("render_a.npz", open("render_a.npz", "rb"))), + ], +) + +print(resp.json()["joints"]) +``` + +--- + +## API + +| Endpoint | Methode | Zweck | +|----------|--------|------| +| `/v1/estimate` | POST | Bilder → Gelenke | +| `/v1/health` | GET | Status | +| `/v1/config` | GET | aktive Konfiguration | + +**Response:** + +```json +{ + "joints": {"x": 50.2, "y": -2.1, "z": 94.8, "a": 20.1}, + "confidence": {"x": "high", "b": "low"}, + "residual_rms": 1.45, + "n_markers": 56, + "processing_ms": 1240 +} +``` + +--- + +## Struktur + +``` +. +├── scripts/ +├── config/robot.json +├── tests/ +└── docker-compose.yaml +``` + +--- + +## Deployment (Docker / Portainer) + +**Volume:** +```yaml +- /opt/approbot/config/robot.json:/config/robot.json:ro +``` + +**Healthcheck:** +```bash +curl http://:8446/v1/health +``` + +--- + +## Konfiguration + +Zentrale Datei: **`robot.json`** + +Verwendete Bereiche: +- `links` +- `pose_estimation` +- `vision_config` +- `movements` +- `units` + +--- + +## Stack (minimal) + +- numpy +- scipy +- opencv (aruco) +- fastapi + uvicorn + +--- + +## Naming + +- **BodyTrack** → Tracking (dynamisch) ✅ +- **BodyMap** → Modell / Repräsentation +- **BodySense** → Wahrnehmung (low-level) diff --git a/config/robot.json.example b/config/robot.json.example new file mode 100644 index 0000000..9bafc02 --- /dev/null +++ b/config/robot.json.example @@ -0,0 +1,19 @@ +{ + "_comment": "Kopiere deine robot.json hierher und benenne sie in robot.json um.", + "_comment2": "Die Pipeline liest nur: links, pose_estimation, vision_config, units.", + "_comment3": "Alle anderen Abschnitte (renderingInfo, robot_test_poses) werden ignoriert.", + "units": { "length": "mm", "angle": "deg" }, + "links": [], + "vision_config": { "aruco_dict": "DICT_4X4_250" }, + "pose_estimation": { + "method": "hybrid", + "marker_observation": "corner_pose", + "use_normals": true, + "normal_weight": 100.0, + "robust_loss": "huber", + "huber_delta_mm": 8.0, + "max_iterations": 200, + "min_cameras_per_marker": 2, + "per_link_method": {} + } +} diff --git a/doc/api_integration.md b/doc/api_integration.md new file mode 100644 index 0000000..3b098d6 --- /dev/null +++ b/doc/api_integration.md @@ -0,0 +1,239 @@ +# API Integration — appRobotBodyTrack + +Der Service läuft als HTTP-Server auf Port 8446 und ist von jeder Sprache aus +erreichbar. Alle Requests nutzen `multipart/form-data`. + +--- + +## Endpunkte im Überblick + +| Endpunkt | Methode | Input | Output | +|---|---|---|---| +| `/v1/estimate` | POST | Bilder + Intrinsiken (+ optional robot.json) | Gelenkwinkel JSON | +| `/v1/health` | GET | — | `{"status": "ok", "version": "1.0.0"}` | +| `/v1/config` | GET | — | Aktiver `pose_estimation`-Block | + +--- + +## Python (`requests`) + +```python +import requests + +BASE = "http://localhost:8446" + +# ── Health-Check ──────────────────────────────────────────────── +resp = requests.get(f"{BASE}/v1/health") +print(resp.json()) # {"status": "ok", "version": "1.0.0"} + +# ── Pose-Schätzung ─────────────────────────────────────────────── +# Bilder und zugehörige Intrinsiken in der gleichen Reihenfolge übergeben. +# Dateinamen müssen render_.png / render_.npz sein — +# die ID (a, b, c, ...) verknüpft Bild und Intrinsik intern. + +camera_ids = ["a", "b", "c"] + +files = [] +for cid in camera_ids: + files.append(("images", (f"render_{cid}.png", open(f"render_{cid}.png", "rb"), "image/png"))) + files.append(("intrinsics", (f"render_{cid}.npz", open(f"render_{cid}.npz", "rb"), "application/octet-stream"))) + +resp = requests.post(f"{BASE}/v1/estimate", files=files) +resp.raise_for_status() + +result = resp.json() +print(result["joints"]) # {"x": 50.2, "y": -2.1, "z": 94.8, "a": 20.1, "b": 59.9, "c": 9.0, "e": 3.0} +print(result["confidence"]) # {"x": "high", "b": "low", ...} +print(result["residual_rms"]) # 1.45 +print(result["processing_ms"]) # 1240 +``` + +### robot.json pro Request mitschicken (überschreibt Server-Konfig) + +```python +files.append(("robot_json", ("robot.json", open("robot.json", "rb"), "application/json"))) +resp = requests.post(f"{BASE}/v1/estimate", files=files) +``` + +### Fehlerbehandlung + +```python +resp = requests.post(f"{BASE}/v1/estimate", files=files) + +if resp.status_code == 400: + print("Ungültige Eingabe:", resp.json()["detail"]) +elif resp.status_code == 500: + print("Pipeline-Fehler:", resp.json()["detail"]) +else: + resp.raise_for_status() + joints = resp.json()["joints"] +``` + +### Async mit `httpx` + +```python +import asyncio +import httpx + +async def estimate(camera_ids: list[str]) -> dict: + async with httpx.AsyncClient(base_url="http://localhost:8446") as client: + files = [] + for cid in camera_ids: + files.append(("images", (f"render_{cid}.png", open(f"render_{cid}.png", "rb")))) + files.append(("intrinsics", (f"render_{cid}.npz", open(f"render_{cid}.npz", "rb")))) + resp = await client.post("/v1/estimate", files=files, timeout=60.0) + resp.raise_for_status() + return resp.json() + +result = asyncio.run(estimate(["a", "b", "c"])) +``` + +--- + +## Node.js + +### Native `fetch` + `FormData` (Node 18+, kein extra Paket) + +```js +import { readFileSync } from "fs"; + +const BASE = "http://localhost:8446"; +const cameraIds = ["a", "b", "c"]; + +// ── Health-Check ──────────────────────────────────────────────── +const health = await fetch(`${BASE}/v1/health`); +console.log(await health.json()); // { status: 'ok', version: '1.0.0' } + +// ── Pose-Schätzung ─────────────────────────────────────────────── +const form = new FormData(); + +for (const id of cameraIds) { + form.append( + "images", + new Blob([readFileSync(`render_${id}.png`)], { type: "image/png" }), + `render_${id}.png` + ); + form.append( + "intrinsics", + new Blob([readFileSync(`render_${id}.npz`)], { type: "application/octet-stream" }), + `render_${id}.npz` + ); +} + +const resp = await fetch(`${BASE}/v1/estimate`, { method: "POST", body: form }); + +if (!resp.ok) { + const err = await resp.json(); + throw new Error(`Pipeline-Fehler ${resp.status}: ${err.detail}`); +} + +const result = await resp.json(); +console.log(result.joints); // { x: 50.2, y: -2.1, z: 94.8, a: 20.1, b: 59.9, c: 9.0, e: 3.0 } +console.log(result.confidence); // { x: 'high', b: 'low', ... } +``` + +### `axios` + `form-data` (Node 16 / CommonJS-Umgebungen) + +```bash +npm install axios form-data +``` + +```js +const axios = require("axios"); +const FormData = require("form-data"); +const fs = require("fs"); + +const BASE = "http://localhost:8446"; +const cameraIds = ["a", "b", "c"]; + +const form = new FormData(); +for (const id of cameraIds) { + form.append("images", fs.createReadStream(`render_${id}.png`), `render_${id}.png`); + form.append("intrinsics", fs.createReadStream(`render_${id}.npz`), `render_${id}.npz`); +} + +const resp = await axios.post(`${BASE}/v1/estimate`, form, { + headers: form.getHeaders(), + timeout: 60_000, +}); + +const { joints, confidence, residual_rms, n_markers, processing_ms } = resp.data; +console.log(joints); +``` + +--- + +## Response-Format + +```json +{ + "joints": { + "x": 50.2, + "y": -2.1, + "z": 94.8, + "a": 20.1, + "b": 59.9, + "c": 9.0, + "e": 3.0 + }, + "confidence": { + "x": "high", + "y": "high", + "z": "high", + "a": "high", + "b": "low", + "c": "low", + "e": "low" + }, + "residual_rms": 1.45, + "n_markers": 56, + "processing_ms": 1240 +} +``` + +### Felder + +| Feld | Typ | Einheit | Beschreibung | +|---|---|---|---| +| `joints.x` | float | mm | Linearachse X | +| `joints.y` | float | mm | Linearachse Y | +| `joints.z` | float | mm | Linearachse Z (Höhe) | +| `joints.a` | float | ° | Drehgelenk A | +| `joints.b` | float | ° | Drehgelenk B | +| `joints.c` | float | ° | Drehgelenk C | +| `joints.e` | float | ° | Fingergelenk E | +| `confidence.*` | string | — | `high` / `medium` / `low` / `none` | +| `residual_rms` | float | mm | RMS-Restfehler der Schätzung | +| `n_markers` | int | — | Anzahl triangulierter Marker | +| `processing_ms` | int | ms | Gesamtlaufzeit der Pipeline | + +### Confidence-Stufen + +| Wert | Bedeutung | +|---|---| +| `high` | Gelenk gut durch mehrere Marker beobachtet | +| `medium` | Gelenk beobachtet, aber mit eingeschränkter Geometrie | +| `low` | Nur indirekt oder mit wenigen Markern beobachtet | +| `none` | Gelenk nicht beobachtbar (z.B. alle Marker verdeckt) | + +### HTTP-Fehlercodes + +| Code | Bedeutung | +|---|---| +| `400` | Eingabefehler (fehlende Dateien, falsche Namen, keine robot.json) | +| `500` | Pipeline-Fehler (ArUco nicht gefunden, Triangulation fehlgeschlagen, …) | + +--- + +## Dateinamens-Konvention + +Die Kamera-ID in Dateinamen verknüpft Bild und Intrinsik: + +``` +render_a.png ←→ render_a.npz # Kamera "a" +render_b.png ←→ render_b.npz # Kamera "b" +render_c.png ←→ render_c.npz # Kamera "c" +``` + +Die ID kann ein Buchstabe oder eine kurze alphanumerische Zeichenkette sein. +Reihenfolge der `files`-Liste ist egal — die Zuordnung erfolgt über den Dateinamen. diff --git a/doc/robot_json.md b/doc/robot_json.md new file mode 100644 index 0000000..bc347e9 --- /dev/null +++ b/doc/robot_json.md @@ -0,0 +1,280 @@ +# robot.json — Entwurf und Schema + +## Entwurfsprinzip: Eine Datei pro Roboter + +`robot.json` ist die **zentrale Identitätsdatei** des Roboters. Sie beschreibt +alles, was zum Roboter gehört — Kinematik, Marker, Kamera-Setup, Rendering-Parameter +und Algorithmus-Tuning. Es gibt genau eine Datei pro Roboter. + +``` +robot.json → Pipeline-Service (liest: links, vision_config, pose_estimation, ...) + → Blender-Renderer (liest: links, renderingInfo, robot_test_poses, ...) + → Benchmark-Tools (liest: robot_test_poses, test_camera_positions, ...) +``` + +Jeder Konsument liest nur seine Abschnitte und ignoriert alle anderen stillschweigend. +Das macht `robot.json` **additiv erweiterbar**: neue Tools fügen neue Abschnitte hinzu, +ohne bestehende zu berühren. + +**Roboter wechseln = `robot.json` austauschen.** +Alle Werkzeuge der Umgebung stellen sich damit automatisch auf den neuen Roboter ein. + +--- + +## Abschnitts-Übersicht + +| Abschnitt | Pipeline | Renderer | Benchmark | Beschreibung | +|---|:---:|:---:|:---:|---| +| `units` | ✅ | ✅ | ✅ | Maßeinheiten (mm, deg) | +| `coordinateSystem` | ✅ | ✅ | — | Basis-Koordinatensystem | +| `links` | ✅ | ✅ | — | Kinematische Kette + ArUco-Marker | +| `movements` | ✅ | ✅ | ✅ | Gelenkachsen-Definition, Ausgabeformat | +| `vision_config` | ✅ | — | — | ArUco-Dictionary, Markergröße | +| `pose_estimation` | ✅ | — | — | Algorithmus-Parameter | +| `constraint_rules` | ✅ | — | — | Gelenkwinkel-Grenzen | +| `observation_weighting` | ✅ | — | — | Gewichtung pro Gelenk/Beobachtungstyp | +| `multiview_calculation` | ✅ | — | — | Bundle-Adjustment-Einstellungen | +| `renderingInfo` | — | ✅ | — | Blender-Szene, Kamera-Rig, Materialien | +| `robot_test_poses` | — | ✅ | ✅ | Teststellungen für Rendering / Evaluierung | +| `test_camera_positions` | — | ✅ | ✅ | Kamera-Aufstellungen für Tests | +| `test_camera_targets` | — | ✅ | — | Blickziele der Test-Kameras | +| `state_pose_params` | ✅ | ✅ | — | Parameterraum-Definition (R⁷) | +| `defaultPosition` | ✅ | ✅ | — | Referenz-Nullstellung | + +--- + +## Pflichtabschnitte + +### `units` + +```json +"units": { + "length": "mm", + "angle": "deg" +} +``` + +Definiert die Einheiten für alle Längen- und Winkelangaben in der gesamten Datei. + +--- + +### `links` + +Kinematische Kette des Roboters, von der Basis zum Endeffektor. +Jedes Glied kennt sein Gelenk, seine Transformation in Nullstellung und +die auf ihm montierten ArUco-Marker. + +```json +"links": [ + { + "name": "Base", + "joint": "x", + "joint_type": "prismatic", + "axis": [0, 0, 1], + "T_parent_link_home": [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 100], + [0, 0, 0, 1] + ], + "markers": [ + { + "id": 0, + "size_mm": 60.0, + "T_link_marker": [ + [1, 0, 0, 0], + [0, 1, 0, 50], + [0, 0, 1, 0], + [0, 0, 0, 1] + ] + } + ] + } +] +``` + +| Feld | Typ | Pflicht | Beschreibung | +|---|---|:---:|---| +| `name` | string | ✅ | Name des Glieds | +| `joint` | string | ✅ | Gelenkvariable: `x`, `y`, `z`, `a`, `b`, `c`, `e` | +| `joint_type` | string | ✅ | `"prismatic"` oder `"revolute"` | +| `axis` | [x,y,z] | ✅ | Gelenkachse im Eltern-KS | +| `T_parent_link_home` | 4×4 | ✅ | Transformation Eltern→Glied in Nullstellung | +| `markers` | Array | — | ArUco-Marker auf diesem Glied (kann leer sein) | +| `markers[].id` | int | ✅ | ArUco-Marker-ID | +| `markers[].size_mm` | float | ✅ | Kantenlänge in mm | +| `markers[].T_link_marker` | 4×4 | ✅ | Transformation Glied→Marker-Mittelpunkt | + +--- + +### `movements` + +Definiert die sieben Gelenkachsen des Roboters, ihre physikalischen Grenzen +und wie sie im Output (`robot_state.json`) benannt und geordnet werden. + +```json +"movements": { + "x": { "type": "prismatic", "min_mm": 0, "max_mm": 800 }, + "y": { "type": "prismatic", "min_mm": -400, "max_mm": 400 }, + "z": { "type": "prismatic", "min_mm": 0, "max_mm": 1200 }, + "a": { "type": "revolute", "min_deg": -180,"max_deg": 180 }, + "b": { "type": "revolute", "min_deg": -90, "max_deg": 90 }, + "c": { "type": "revolute", "min_deg": -90, "max_deg": 90 }, + "e": { "type": "revolute", "min_deg": 0, "max_deg": 90 } +} +``` + +--- + +## Pipeline-Abschnitte + +### `vision_config` + +```json +"vision_config": { + "aruco_dict": "DICT_4X4_250", + "marker_size_mm": 20.0 +} +``` + +| Feld | Default | Beschreibung | +|---|---|---| +| `aruco_dict` | `"DICT_4X4_250"` | OpenCV-ArUco-Dictionary | +| `marker_size_mm` | aus `links[].markers[].size_mm` | Globale Fallback-Markergröße | + +--- + +### `pose_estimation` + +Algorithmus-Parameter für die Gelenkwinkelschätzung. +Alle Felder haben Defaults — fehlende Felder werden still ignoriert. + +```json +"pose_estimation": { + "method": "hybrid", + "marker_observation": "corner_pose", + "use_normals": true, + "normal_weight": 100.0, + "robust_loss": "huber", + "huber_delta_mm": 8.0, + "max_iterations": 200, + "min_cameras_per_marker": 2, + "per_link_method": {} +} +``` + +| Feld | Default | Beschreibung | +|---|---|---| +| `method` | `"hybrid"` | `sequential_fk` / `global_ba` / `hybrid` | +| `marker_observation` | `"corner_pose"` | `"corner_pose"` (pos+normal) oder `"center_point"` (pos only) | +| `use_normals` | `true` | Marker-Flächennormalen als Zusatz-Constraint | +| `normal_weight` | `100.0` | Gewicht Normal-Residuen vs. Positions-Residuen | +| `robust_loss` | `"huber"` | `"none"` / `"huber"` / `"cauchy"` | +| `huber_delta_mm` | `8.0` | Huber-Schwelle in mm | +| `max_iterations` | `200` | Bundle-Adjustment-Iterationslimit | +| `min_cameras_per_marker` | `2` | Mindestanzahl Kameras für Triangulation | +| `per_link_method` | `{}` | Override pro Gelenk, z.B. `{"e": "sequential_fk"}` | + +--- + +### `observation_weighting` + +Gewichtung der einzelnen Marker-Beobachtungen in der Schätzung, +z.B. um bekannte schwache Geometrien zu dämpfen. + +```json +"observation_weighting": { + "default": 1.0, + "per_link": { "Hand": 0.5 } +} +``` + +--- + +### `multiview_calculation` + +Einstellungen für Schritt 3 (Bundle Adjustment über alle Kameras). + +```json +"multiview_calculation": { + "lambda_weight": 100.0, + "min_views": 2 +} +``` + +--- + +### `constraint_rules` + +Gelenkwinkel-Abhängigkeiten und -Grenzen, die in der Schätzung als +Hard- oder Soft-Constraints wirken. + +```json +"constraint_rules": [ + { "joint": "b", "min_deg": 0, "max_deg": 180 } +] +``` + +--- + +## Renderer-Abschnitte + +### `renderingInfo` + +Blender-spezifische Szenenparameter: Pfad zur `.blend`-Datei, Materialien, +Beleuchtungssetup, Auflösung und Kamera-Rig-Konfiguration. +Wird von der Pipeline vollständig ignoriert. + +--- + +### `robot_test_poses` + +Liste von Roboterstellungen, die im Renderer gerendert und in der Evaluierung +als Ground-Truth verwendet werden. Jeder Eintrag ist ein vollständiger R⁷-Zustand. + +```json +"robot_test_poses": [ + { "x": 50, "y": 0, "z": 600, "a": 30, "b": 45, "c": 0, "e": 20 }, + { "x": 200, "y": -100, "z": 700, "a": -15, "b": 60, "c": 10, "e": 0 } +] +``` + +--- + +### `test_camera_positions` + +Kamera-Aufstellungen für den Renderer, als Liste von 3D-Positionen und Ausrichtungen. + +--- + +## Extensibilität + +Neue Tools oder Features fügen neue Abschnitte hinzu, ohne bestehende zu ändern: + +```json +{ + "units": { ... }, // alle Tools + "links": [ ... ], // alle Tools + "pose_estimation": { ... },// Pipeline + "renderingInfo": { ... }, // Renderer + "my_new_tool": { ... } // neues Tool — alle anderen ignorieren es +} +``` + +**Versionsregel:** Neue Felder innerhalb bestehender Abschnitte haben immer Defaults. +Felder werden nie entfernt, nur als veraltet markiert. Eine ältere `robot.json` +läuft damit auf einer neueren Pipeline-Version unverändert. + +--- + +## Roboter wechseln + +Um auf einen anderen Roboter umzustellen, wird ausschließlich `robot.json` ausgetauscht: + +``` +robot_A.json → robot.json # Roboter A aktiv +robot_B.json → robot.json # Roboter B aktiv +``` + +Pipeline, Renderer, Benchmark-Tools und Portainer-Stack lesen denselben +Volume-Mount `/config/robot.json` — kein weiterer Eingriff nötig. diff --git a/doc/robot_json_pipeline_schema.md b/doc/robot_json_pipeline_schema.md new file mode 100644 index 0000000..b816f43 --- /dev/null +++ b/doc/robot_json_pipeline_schema.md @@ -0,0 +1,28 @@ +# robot.json — Pipeline-Schema + +> Dieses Dokument beschreibt nur die Pipeline-relevanten Felder. +> Die vollständige Beschreibung aller Abschnitte und das Entwurfsprinzip +> (eine Datei für alle Werkzeuge) steht in [robot_json.md](robot_json.md). + +--- + +## Pipeline-Pflichtfelder + +| Abschnitt | Pflicht | Beschreibung | +|---|:---:|---| +| `units` | ✅ | Maßeinheiten (`mm`, `deg`) | +| `links` | ✅ | Kinematische Kette + ArUco-Marker | +| `vision_config` | ✅ | ArUco-Dictionary, Markergröße | + +## Pipeline-Optionalfelder (alle mit Defaults) + +| Abschnitt | Beschreibung | +|---|---| +| `pose_estimation` | Algorithmus-Parameter | +| `observation_weighting` | Gewichtung pro Glied | +| `multiview_calculation` | Bundle-Adjustment-Einstellungen | +| `constraint_rules` | Gelenkwinkel-Grenzen | +| `movements` | Parameterraum-Definition | + +Alle weiteren Abschnitte (`renderingInfo`, `robot_test_poses`, …) werden von +der Pipeline stillschweigend ignoriert. diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..14573cd --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,25 @@ +services: + pipeline: + build: + context: . + dockerfile_inline: | + FROM python:3.11-slim + WORKDIR /app + COPY . . + RUN pip install --no-cache-dir . + ENV ROBOT_JSON=/config/robot.json + EXPOSE 8446 + HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8446/v1/health')" + CMD ["python", "-m", "scripts.api", \ + "--robot", "/config/robot.json", \ + "--host", "0.0.0.0", "--port", "8446"] + image: approbot/pose-pipeline:1.0.0 + container_name: appRobotBodyTracker + restart: unless-stopped + ports: + - "8446:8446" + volumes: + - ./config/robot.json:/config/robot.json:ro + environment: + - ROBOT_JSON=/config/robot.json diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d137a14 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,25 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.backends.legacy:build" + +[project] +name = "approbot-pipeline" +version = "1.0.0" +description = "Robot pose estimation from multi-camera ArUco images" +readme = "doc/README.md" +requires-python = ">=3.10" +dependencies = [ + "numpy==1.26.4", + "scipy==1.13.1", + "opencv-contrib-python-headless==4.10.0.84", + "fastapi==0.115.0", + "uvicorn[standard]==0.30.6", + "python-multipart==0.0.9", +] + +[project.scripts] +approbot-pipeline = "scripts.__main__:main" + +[tool.setuptools.packages.find] +where = ["."] +include = ["scripts*"] diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..cb9d202 --- /dev/null +++ b/scripts/__init__.py @@ -0,0 +1,23 @@ +""" +scripts +======= +Roboter-Pose-Schätzung aus Mehrkamera-ArUco-Bildern. + +Zwei Interfaces, gleiche Logik darunter: + + (A) Python-Bibliothek — direkt einbindbar: + from scripts import estimate_from_dir, PipelineResult + result = estimate_from_dir("path/to/images", robot_json="robot.json") + print(result.joints) # {"x": 50.2, "y": -2.1, ...} + print(result.confidence) # {"x": "high", "b": "low", ...} + + (B) REST-API — läuft als Service im Docker-Container: + POST /v1/estimate (multipart: images + intrinsics) + GET /v1/health + GET /v1/config + → JSON mit joints, confidence, residual_rms, processing_ms +""" +from .pipeline import estimate_from_dir, PipelineResult + +__version__ = "1.0.0" +__all__ = ["estimate_from_dir", "PipelineResult", "__version__"] diff --git a/scripts/__main__.py b/scripts/__main__.py new file mode 100644 index 0000000..e455825 --- /dev/null +++ b/scripts/__main__.py @@ -0,0 +1,43 @@ +"""Einstiegspunkt: python -m scripts [--robot ...] [--cameras ...]""" +import argparse +import json +import sys + + +def main() -> None: + ap = argparse.ArgumentParser( + description="appRobotBodyTrack: Bilder + robot.json → Gelenkwinkel im R⁷" + ) + ap.add_argument("image_dir", help="Ordner mit render_*.png/jpg und render_*.npz") + ap.add_argument("--robot", default=None, help="Pfad zu robot.json") + ap.add_argument("--evalDir", default=None, help="Ausgabeordner (Standard: temporäres Verzeichnis)") + ap.add_argument("--cameras", default=None, help="Kamera-IDs, kommagetrennt, z.B. a,b,d") + ap.add_argument("--lambdaWeight", type=float, default=100.0) + args = ap.parse_args() + + from scripts import estimate_from_dir + + camera_filter = args.cameras.split(",") if args.cameras else None + try: + result = estimate_from_dir( + args.image_dir, + robot_json=args.robot, + eval_dir=args.evalDir, + lambda_weight=args.lambdaWeight, + camera_filter=camera_filter, + ) + except Exception as exc: + print(f"[ERROR] {exc}", file=sys.stderr) + sys.exit(1) + + print(json.dumps({ + "joints": result.joints, + "confidence": result.confidence, + "n_markers": result.n_markers, + "residual_rms": result.residual_rms, + "processing_ms": result.processing_ms, + }, indent=2, ensure_ascii=False)) + + +if __name__ == "__main__": + main() diff --git a/scripts/api/__init__.py b/scripts/api/__init__.py new file mode 100644 index 0000000..c14bfc7 --- /dev/null +++ b/scripts/api/__init__.py @@ -0,0 +1,12 @@ +"""scripts.api — FastAPI REST-Service.""" +from .server import create_app + + +def start_server( + robot_json=None, + host: str = "0.0.0.0", + port: int = 8080, +) -> None: + import uvicorn + app = create_app(robot_json=robot_json) + uvicorn.run(app, host=host, port=port) diff --git a/scripts/api/__main__.py b/scripts/api/__main__.py new file mode 100644 index 0000000..10c991e --- /dev/null +++ b/scripts/api/__main__.py @@ -0,0 +1,17 @@ +"""Einstiegspunkt: python -m scripts.api [--robot ...] [--host ...] [--port ...]""" +import argparse + +from scripts.api import start_server + + +def main() -> None: + ap = argparse.ArgumentParser(description="approbot-pipeline REST-API starten") + ap.add_argument("--robot", default=None, help="Pfad zu robot.json") + ap.add_argument("--host", default="0.0.0.0") + ap.add_argument("--port", type=int, default=8080) + args = ap.parse_args() + start_server(robot_json=args.robot, host=args.host, port=args.port) + + +if __name__ == "__main__": + main() diff --git a/scripts/api/server.py b/scripts/api/server.py new file mode 100644 index 0000000..cdd4396 --- /dev/null +++ b/scripts/api/server.py @@ -0,0 +1,83 @@ +"""FastAPI REST-API für appRobotBodyTrack.""" +from __future__ import annotations + +import json +import tempfile +from pathlib import Path +from typing import List, Optional + +from fastapi import FastAPI, File, HTTPException, UploadFile +from fastapi.responses import JSONResponse + +from scripts import __version__, estimate_from_dir + +_robot_json: Optional[Path] = None + + +def create_app(robot_json: str | Path | None = None) -> FastAPI: + """App-Fabrik — setzt optionale Server-weite robot.json-Konfig.""" + global _robot_json + if robot_json: + _robot_json = Path(robot_json).resolve() + return _app + + +_app = FastAPI(title="approbot-pipeline", version=__version__) + + +@_app.get("/v1/health") +def health(): + return {"status": "ok", "version": __version__} + + +@_app.get("/v1/config") +def config(): + if _robot_json is None or not _robot_json.exists(): + raise HTTPException(404, "Keine robot.json konfiguriert") + data = json.loads(_robot_json.read_text(encoding="utf-8")) + return data.get("pose_estimation", {}) + + +@_app.post("/v1/estimate") +async def estimate( + images: List[UploadFile] = File(..., description="Kamerabilder (render_.png)"), + intrinsics: List[UploadFile] = File(..., description="Kamera-Intrinsiken (render_.npz)"), + robot_json: Optional[UploadFile] = File(default=None, description="robot.json (überschreibt Server-Konfig)"), +): + """Pose-Schätzung aus Kamerabildern. + + Multipart-Upload: + images[] — render_a.png, render_b.png, ... + intrinsics[] — render_a.npz, render_b.npz, ... (gleiche Reihenfolge) + robot_json — optional, überschreibt die Server-Konfiguration + """ + with tempfile.TemporaryDirectory(prefix="approbot_req_") as tmp: + tmp_path = Path(tmp) + + if robot_json is not None: + rj_path = tmp_path / "robot.json" + rj_path.write_bytes(await robot_json.read()) + elif _robot_json and _robot_json.exists(): + rj_path = _robot_json + else: + raise HTTPException(400, "Keine robot.json angegeben (weder Upload noch Server-Konfig)") + + for img in images: + (tmp_path / img.filename).write_bytes(await img.read()) + for npz in intrinsics: + (tmp_path / npz.filename).write_bytes(await npz.read()) + + try: + result = estimate_from_dir(tmp_path, robot_json=rj_path, eval_dir=tmp_path) + except FileNotFoundError as exc: + raise HTTPException(400, str(exc)) + except Exception as exc: + raise HTTPException(500, str(exc)) + + return JSONResponse({ + "joints": result.joints, + "confidence": result.confidence, + "residual_rms": result.residual_rms, + "n_markers": result.n_markers, + "processing_ms": result.processing_ms, + }) diff --git a/scripts/pipeline.py b/scripts/pipeline.py new file mode 100644 index 0000000..7944015 --- /dev/null +++ b/scripts/pipeline.py @@ -0,0 +1,180 @@ +""" +pipeline.py +=========== +Orchestrator — ruft die Pipeline-Schritte als Subprocess auf und gibt +ein strukturiertes PipelineResult zurück. + +Schritte: + 1 ArUco-Detektion (scripts/1_detect_aruco_observations.py) + 2 Kamera-Posen (scripts/2_estimate_camera_from_observations.py) + 3 Multi-View Triangulation (scripts/3_multiview_bundle_adjustment_v4.py) + 3b Eck-Marker-Posen (scripts/3b_corner_marker_poses.py) + 4 Pose-Estimation (scripts/pose_estimation.py) +""" +from __future__ import annotations + +import glob +import json +import os +import re +import subprocess +import sys +import tempfile +import time +from dataclasses import dataclass, field +from pathlib import Path +from typing import Dict, List, Optional + +SCRIPTS = Path(__file__).parent / "pipeline" +PY = sys.executable + + +@dataclass +class PipelineResult: + """Ergebnis der Pose-Schätzung.""" + joints: Dict[str, float] # x,y,z,a,b,c,e → Wert (mm oder °) + confidence: Dict[str, str] # x,y,z,a,b,c,e → high|medium|low|none + n_markers: int # Anzahl triangulierter Marker + residual_rms: float # Residuum der Schätzung (mm) + processing_ms: float # Laufzeit der Pipeline + robot_state_path: Optional[Path] = None # Pfad zur erzeugten robot_state.json + errors: List[str] = field(default_factory=list) + + +def _run(cmd: list, step: str) -> None: + """Subprocess-Aufruf mit Fehlerbehandlung.""" + r = subprocess.run(cmd, capture_output=True, text=True) + if r.returncode != 0: + raise RuntimeError(f"[{step}] exit {r.returncode}:\n{r.stderr.strip()[-800:]}") + + +def _cam_id(path: str) -> Optional[str]: + m = re.match(r"render_([A-Za-z0-9]+)\.(png|jpg|jpeg)", os.path.basename(path), re.I) + return m.group(1) if m else None + + +def estimate_from_dir( + image_dir: str | Path, + robot_json: str | Path | None = None, + eval_dir: str | Path | None = None, + lambda_weight: float = 100.0, + camera_filter: Optional[List[str]] = None, +) -> PipelineResult: + """ + Pose-Schätzung aus einem Bildordner. + + Parameters + ---------- + image_dir Ordner mit render_*.png und render_*.npz + robot_json Pfad zu robot.json (Default: ROBOT_JSON env oder Exception) + eval_dir Ausgabeordner (Default: temporäres Verzeichnis) + lambda_weight Constraint-Gewicht für Bundle Adjustment + camera_filter Liste von Kamera-IDs; None = alle + + Returns + ------- + PipelineResult + """ + t0 = time.time() + image_dir = Path(image_dir).resolve() + + # robot.json bestimmen + if robot_json is None: + robot_json = os.environ.get("ROBOT_JSON") + if not robot_json: + raise ValueError("robot_json muss angegeben werden oder ROBOT_JSON env gesetzt sein") + robot_json = Path(robot_json).resolve() + + # Ausgabeordner + _tmp = None + if eval_dir is None: + _tmp = tempfile.mkdtemp(prefix="approbot_") + eval_dir = Path(_tmp) + else: + eval_dir = Path(eval_dir).resolve() + eval_dir.mkdir(parents=True, exist_ok=True) + + errors = [] + + try: + # Bilder sammeln + imgs = sorted( + glob.glob(str(image_dir / "render_*.png")) + + glob.glob(str(image_dir / "render_*.PNG")) + + glob.glob(str(image_dir / "render_*.jpg")) + + glob.glob(str(image_dir / "render_*.jpeg")) + ) + if camera_filter: + imgs = [i for i in imgs if _cam_id(i) in set(camera_filter)] + if not imgs: + raise FileNotFoundError(f"Keine render_*.png/jpg in {image_dir}") + + # ── Schritt 1: ArUco-Detektion ────────────────────────────── + for img in imgs: + cid = _cam_id(img) + if not cid: + continue + npz = image_dir / f"render_{cid}.npz" + if not npz.exists(): + npz_candidates = list(image_dir.glob("*.npz")) + if not npz_candidates: + raise FileNotFoundError(f"Keine .npz-Intrinsik in {image_dir}") + npz = npz_candidates[0] + _run([PY, str(SCRIPTS / "1_detect_aruco_observations.py"), + "-i", str(img), "-npz", str(npz), + "-outDir", str(eval_dir), "-robot", str(robot_json), "-cameraId", cid], + "Schritt 1") + + # ── Schritt 2: Kamera-Posen ────────────────────────────────── + dets = sorted(glob.glob(str(eval_dir / "*_aruco_detection.json"))) + if not dets: + raise RuntimeError("Keine ArUco-Detektionen erzeugt (Schritt 1)") + for d in dets: + _run([PY, str(SCRIPTS / "2_estimate_camera_from_observations.py"), + "-i", d, "-robot", str(robot_json), "-outDir", str(eval_dir)], + "Schritt 2") + + # ── Schritt 3: Multi-View Triangulation ────────────────────── + poses = sorted(glob.glob(str(eval_dir / "*_camera_pose.json"))) + if not poses: + raise RuntimeError("Keine Kamera-Posen erzeugt (Schritt 2)") + det_args = sum([["-det", d] for d in dets], []) + pose_args = sum([["-pose", p] for p in poses], []) + _run([PY, str(SCRIPTS / "3_multiview_bundle_adjustment_v4.py"), + "-robot", str(robot_json), "-lambdaWeight", str(lambda_weight)] + + det_args + pose_args, "Schritt 3") + + # ── Schritt 3b: Eck-Marker-Posen ───────────────────────────── + _run([PY, str(SCRIPTS / "3b_corner_marker_poses.py"), + "--evalDir", str(eval_dir), "--robot", str(robot_json)], "Schritt 3b") + + # ── Schritt 4: Pose-Estimation ──────────────────────────────── + marker_poses = eval_dir / "aruco_marker_poses.json" + state_out = eval_dir / "robot_state.json" + _run([PY, str(SCRIPTS / "pose_estimation.py"), + str(marker_poses), "-robot", str(robot_json), "-out", str(state_out)], + "Schritt 4") + + # Ergebnis lesen + state = json.load(open(state_out, "r", encoding="utf-8")) + mv = state.get("movements", {}) + joints = {k: float(v.get("value", 0.0)) for k, v in mv.items() if isinstance(v, dict)} + confidence = {k: str(v.get("confidence", "none")) for k, v in mv.items() if isinstance(v, dict)} + + return PipelineResult( + joints=joints, + confidence=confidence, + n_markers=int(state.get("num_markers", 0)), + residual_rms=float(state.get("residual_rms", 0.0)), + processing_ms=round((time.time() - t0) * 1000), + robot_state_path=state_out, + errors=errors, + ) + + except Exception as exc: + errors.append(str(exc)) + raise + finally: + # Temporäres Verzeichnis bleibt absichtlich erhalten für Debugging; + # Aufrufer kann es über result.robot_state_path.parent aufräumen. + pass diff --git a/scripts/pipeline/1_detect_aruco_observations.py b/scripts/pipeline/1_detect_aruco_observations.py new file mode 100644 index 0000000..e9d591d --- /dev/null +++ b/scripts/pipeline/1_detect_aruco_observations.py @@ -0,0 +1,608 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +import hashlib +import time +import uuid +from typing import Dict, Any + +import cv2 +import numpy as np + + +# ------------------------------------------------------------ +# Utilities +# ------------------------------------------------------------ + + +def resolve_path(path): + path = os.path.expanduser(path) + + # Absoluter Pfad → direkt verwenden + if os.path.isabs(path): + return path + + # Relativer Pfad → absolut machen (auf Basis aktuellem cwd) + return os.path.abspath(path) + +def load_intrinsics_npz(npz_path: str): + data = np.load(npz_path) + + for k in ('camera_matrix', 'mtx', 'K'): + if k in data: + K = data[k].astype(np.float32) + break + else: + raise KeyError('Camera matrix not found in npz') + + for k in ('dist_coeffs', 'dist', 'D'): + if k in data: + D = data[k].astype(np.float32).reshape(-1, 1) + break + else: + D = np.zeros((5, 1), dtype=np.float32) + + return K, D + + +# ------------------------------------------------------------ + +def load_robot_vision_config(robot_json_path: str): + + + + robot_json_path = resolve_path(robot_json_path) + with open(robot_json_path, 'r', encoding='utf-8') as f: + robot = json.load(f) + + vision_config = robot.get('vision_config', {}) + + marker_type = vision_config.get('MarkerType', 'DICT_4X4_250') + marker_size = float(vision_config.get('MarkerSize', 0.025)) + + return { + 'MarkerType': marker_type, + 'MarkerSize': marker_size + } + + +# ------------------------------------------------------------ + +def get_aruco_detector(dict_name: str): + + mapping = { + 'DICT_4X4_250': cv2.aruco.DICT_4X4_250, + 'DICT_5X5_100': cv2.aruco.DICT_5X5_100, + 'DICT_6X6_250': cv2.aruco.DICT_6X6_250, + 'DICT_ARUCO_ORIGINAL': cv2.aruco.DICT_ARUCO_ORIGINAL, + } + + dict_id = mapping.get(dict_name, cv2.aruco.DICT_4X4_250) + + dictionary = cv2.aruco.getPredefinedDictionary(dict_id) + + try: + params = cv2.aruco.DetectorParameters() + except Exception: + params = cv2.aruco.DetectorParameters_create() + + try: + detector = cv2.aruco.ArucoDetector(dictionary, params) + return detector, None + + except Exception: + return None, (dictionary, params) + + +# ------------------------------------------------------------ + +def detect_markers(image, detector_tuple): + + detector, fallback = detector_tuple + + if detector is not None: + + corners, ids, rejected = detector.detectMarkers(image) + + else: + + dictionary, params = fallback + + corners, ids, rejected = cv2.aruco.detectMarkers( + image, + dictionary, + parameters=params + ) + + return corners, ids, rejected + + +# ------------------------------------------------------------ + +def hash_file(path): + + sha = hashlib.sha256() + + with open(path, 'rb') as f: + + while True: + + chunk = f.read(1024 * 1024) + + if not chunk: + break + + sha.update(chunk) + + return sha.hexdigest() + + +# ------------------------------------------------------------ + +def polygon_mask(shape, polygon): + + mask = np.zeros(shape, dtype=np.uint8) + + cv2.fillConvexPoly( + mask, + polygon.astype(np.int32), + 255 + ) + + return mask + + +# ------------------------------------------------------------ + +def shrink_polygon(points, scale=0.80): + + center = np.mean(points, axis=0) + + shrunk = center + (points - center) * scale + + return shrunk.astype(np.float32) + + +# ------------------------------------------------------------ + +def compute_sharpness(gray_image, polygon): + + shrunk = shrink_polygon(polygon, scale=0.80) + + mask = polygon_mask(gray_image.shape, shrunk) + + pixels = gray_image[mask == 255] + + if pixels.size == 0: + return 0.0 + + temp = np.zeros_like(gray_image) + temp[mask == 255] = gray_image[mask == 255] + + lap = cv2.Laplacian(temp, cv2.CV_64F) + + values = lap[mask == 255] + + if values.size == 0: + return 0.0 + + return float(values.var()) + + +# ------------------------------------------------------------ + +def compute_contrast(gray_image, polygon): + + shrunk = shrink_polygon(polygon, scale=0.80) + + mask = polygon_mask(gray_image.shape, shrunk) + + pixels = gray_image[mask == 255] + + if pixels.size == 0: + + return { + 'p05': 0.0, + 'p95': 0.0, + 'dynamic_range': 0.0, + 'mean_gray': 0.0, + 'std_gray': 0.0 + } + + p05 = float(np.percentile(pixels, 5)) + p95 = float(np.percentile(pixels, 95)) + + return { + 'p05': p05, + 'p95': p95, + 'dynamic_range': float(p95 - p05), + 'mean_gray': float(np.mean(pixels)), + 'std_gray': float(np.std(pixels)) + } + + +# ------------------------------------------------------------ + +def compute_edge_ratio(corners): + + edge_lengths = [] + + for k in range(4): + + p1 = corners[k] + p2 = corners[(k + 1) % 4] + + edge_lengths.append( + float(np.linalg.norm(p1 - p2)) + ) + + edge_ratio = ( + max(edge_lengths) / + max(1e-6, min(edge_lengths)) + ) + + return edge_ratio, edge_lengths + + +# ------------------------------------------------------------ + +def compute_geometry_metrics(center, corners, width, height): + + image_center = np.array( + [width / 2.0, height / 2.0], + dtype=np.float32 + ) + + dist_center = np.linalg.norm(center - image_center) + + max_dist = np.linalg.norm(image_center) + + distance_center_norm = float( + dist_center / max(1e-6, max_dist) + ) + + min_x = np.min(corners[:, 0]) + max_x = np.max(corners[:, 0]) + + min_y = np.min(corners[:, 1]) + max_y = np.max(corners[:, 1]) + + border_distance_px = float(min( + min_x, + min_y, + width - max_x, + height - max_y + )) + + return { + 'distance_to_center_norm': distance_center_norm, + 'distance_to_border_px': border_distance_px + } + + +# ------------------------------------------------------------ + +def compute_confidence( + area_px, + sharpness, + edge_ratio, + dynamic_range, + border_distance_px +): + + score = 1.0 + + # area + score *= min(1.0, area_px / 1500.0) + + # sharpness + score *= min(1.0, sharpness / 120.0) + + # edge distortion + score *= 1.0 / max(1.0, edge_ratio) + + # contrast + score *= min(1.0, dynamic_range / 80.0) + + # border distance + score *= min(1.0, max(0.0, border_distance_px) / 50.0) + + score = max(0.0, min(1.0, score)) + + return float(score) + + +# ------------------------------------------------------------ + +def main(): + + parser = argparse.ArgumentParser() + + parser.add_argument( + '-i', + '--image', + required=True + ) + + parser.add_argument( + '-npz', + '--intrinsics', + required=True + ) + + parser.add_argument( + '-robot', + '--robot', + required=True + ) + + parser.add_argument( + '-cameraId', + '--cameraId', + required=True, + type=str + ) + + parser.add_argument( + '-outDir', + '--outDir', + required=True + ) + + args = parser.parse_args() + + out_dir = resolve_path(args.outDir) + os.makedirs(out_dir, exist_ok=True) + + + # -------------------------------------------------------- + # Load robot vision config + # -------------------------------------------------------- + + vision_config = load_robot_vision_config(args.robot) + + marker_type = vision_config['MarkerType'] + marker_size = vision_config['MarkerSize'] + + # -------------------------------------------------------- + # Load image + # -------------------------------------------------------- + + + image_path = resolve_path(args.image) + image = cv2.imread(image_path) + + + if image is None: + raise RuntimeError(f'Cannot read image: {args.image}') + + gray = cv2.cvtColor( + image, + cv2.COLOR_BGR2GRAY + ) + + height, width = gray.shape[:2] + + # -------------------------------------------------------- + # Intrinsics + # -------------------------------------------------------- + + + intrinsics_path = resolve_path(args.intrinsics) + K, D = load_intrinsics_npz(intrinsics_path) + + # -------------------------------------------------------- + # Detection + # -------------------------------------------------------- + + detector_tuple = get_aruco_detector(marker_type) + + corners_list, ids, rejected = detect_markers( + gray, + detector_tuple + ) + + detections = [] + + # -------------------------------------------------------- + # Valid detections + # -------------------------------------------------------- + + if ids is not None: + + ids = ids.flatten().tolist() + + for i, marker_id in enumerate(ids): + + corners = corners_list[i].reshape((4, 2)).astype(np.float32) + + center = corners.mean(axis=0) + + area_px = float( + cv2.contourArea(corners) + ) + + perimeter_px = float( + cv2.arcLength(corners, True) + ) + + edge_ratio, edge_lengths = compute_edge_ratio(corners) + + sharpness = compute_sharpness( + gray, + corners + ) + + contrast = compute_contrast( + gray, + corners + ) + + geometry = compute_geometry_metrics( + center, + corners, + width, + height + ) + + confidence = compute_confidence( + area_px=area_px, + sharpness=sharpness, + edge_ratio=edge_ratio, + dynamic_range=contrast['dynamic_range'], + border_distance_px=geometry['distance_to_border_px'] + ) + + detection = { + + 'observation_id': str(uuid.uuid4()), + + 'type': 'aruco', + + 'marker_id': int(marker_id), + + 'marker_size_m': marker_size, + + 'image_points_px': corners.tolist(), + + 'center_px': center.tolist(), + + 'quality': { + + 'area_px': area_px, + + 'perimeter_px': perimeter_px, + + 'sharpness': { + 'laplacian_var': sharpness + }, + + 'contrast': contrast, + + 'geometry': geometry, + + 'edge_ratio': edge_ratio, + + 'edge_lengths_px': edge_lengths + }, + + 'confidence': confidence + } + + detections.append(detection) + + # -------------------------------------------------------- + # Rejected candidates + # -------------------------------------------------------- + + rejected_candidates = [] + + if rejected is not None: + + for candidate in rejected: + + pts = candidate.reshape((-1, 2)).astype(np.float32) + + center = pts.mean(axis=0) + + area_px = float( + cv2.contourArea(pts) + ) + + rejected_candidates.append({ + + 'image_points_px': pts.tolist(), + + 'center_px': center.tolist(), + + 'area_px': area_px + }) + + # -------------------------------------------------------- + # Final output + # -------------------------------------------------------- + + output = { + + 'schema_version': '1.0', + + 'created_utc': time.strftime( + '%Y-%m-%dT%H:%M:%SZ', + time.gmtime() + ), + + 'vision_config': { + 'MarkerType': marker_type, + 'MarkerSize': marker_size + }, + + 'camera': { + + 'camera_id': args.cameraId, + + 'intrinsics_file': os.path.abspath(args.intrinsics), + + 'camera_matrix': K.tolist(), + + 'distortion_coefficients': D.reshape(-1).tolist() + }, + + 'image': { + + 'image_file': os.path.abspath(args.image), + + 'image_sha256': hash_file(args.image), + + 'width_px': int(width), + + 'height_px': int(height) + }, + + 'aruco': { + + 'dictionary': marker_type, + + 'num_detected_markers': len(detections), + + 'num_rejected_candidates': len(rejected_candidates) + }, + + 'detections': detections, + + 'rejected_candidates': rejected_candidates + } + + # -------------------------------------------------------- + # Output path + # -------------------------------------------------------- + + input_filename = os.path.basename(args.image) + + input_base = os.path.splitext(input_filename)[0] + + out_json = os.path.join( + out_dir, + f'{input_base}_aruco_detection.json' + ) + + # -------------------------------------------------------- + # Save JSON + # -------------------------------------------------------- + + with open(out_json, 'w', encoding='utf-8') as f: + + json.dump( + output, + f, + indent=2 + ) + + print(f'Saved: {out_json}') + + +# ------------------------------------------------------------ + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/scripts/pipeline/2_estimate_camera_from_observations.py b/scripts/pipeline/2_estimate_camera_from_observations.py new file mode 100644 index 0000000..f6197c7 --- /dev/null +++ b/scripts/pipeline/2_estimate_camera_from_observations.py @@ -0,0 +1,834 @@ +#!/usr/bin/env python3 +""" +2_estimate_camera_from_observations.py + +Estimate a single camera pose from ArUco observations stored in +*_aruco_detection.json, using marker world positions from robot.json. + +This follows the same mathematical idea as readTwoImages.py: +1) use detected marker observations, +2) get an initial pose from a rigid transform, +3) refine with Levenberg-Marquardt on normalized reprojection residuals. + +Difference to readTwoImages.py: +- No image processing here. +- Input is the observation JSON created by 1_detect_aruco_observations.py. +- Output is xxx_camera_pose.json. +- Unknown marker reconstruction is intentionally omitted. + +Assumptions: +- robot.json contains a marker list for the board/world frame. +- At minimum, marker positions are present for the reference markers. +- The detection JSON contains camera intrinsics and marker corners. + +Typical usage: + python3 2_estimate_camera_from_observations.py \ + -i frame_0001_aruco_detection.json \ + -robot robot.json \ + -outDir results/ + +Output: + frame_0001_camera_pose.json + +Notes on uncertainty: +- The script computes an approximate 6x6 covariance for the pose parameters + [rvec_x, rvec_y, rvec_z, t_x, t_y, t_z]. +- It also propagates that covariance to camera center uncertainty in world + coordinates and to approximate roll/pitch/yaw uncertainty. +""" + +from __future__ import annotations + +import argparse +import json +import os +import sys +import time +from typing import Any, Dict, List, Optional, Tuple + +import cv2 +import numpy as np + + +# --------------------------------------------------------------------- +# Path / JSON helpers +# --------------------------------------------------------------------- + +def resolve_path(path: str) -> str: + path = os.path.expanduser(path) + if os.path.isabs(path): + return path + return os.path.abspath(path) + + +def load_json(path: str) -> Dict[str, Any]: + with open(resolve_path(path), "r", encoding="utf-8") as f: + return json.load(f) + + +def save_json(path: str, data: Dict[str, Any]) -> None: + with open(resolve_path(path), "w", encoding="utf-8") as f: + json.dump(data, f, indent=2) + + +# --------------------------------------------------------------------- +# Intrinsics +# --------------------------------------------------------------------- + +def load_intrinsics_from_detection(detection: Dict[str, Any]) -> Tuple[np.ndarray, np.ndarray]: + """ + Primary source: the embedded camera intrinsics in the detection JSON. + """ + camera = detection.get("camera", {}) + K = camera.get("camera_matrix", None) + D = camera.get("distortion_coefficients", None) + + if K is None: + raise KeyError("camera_matrix missing in detection JSON.") + if D is None: + D = [0, 0, 0, 0, 0] + + K = np.array(K, dtype=np.float32).reshape(3, 3) + D = np.array(D, dtype=np.float32).reshape(-1, 1) + return K, D + + +# --------------------------------------------------------------------- +# Robot JSON parsing +# --------------------------------------------------------------------- + +def _rotation_matrix_from_any(rotation: Any) -> np.ndarray: + """ + Best-effort parser for marker rotation. + + Supported inputs: + - 3x3 matrix as nested list + - flat 9 list + - dict with keys: + * rotation_matrix / matrix + * rvec / rodriques / rodrigues + * euler_deg / rpy_deg / roll_pitch_yaw_deg + * euler_rad / rpy_rad / roll_pitch_yaw_rad + * quaternion / quat (best-effort, expects [x,y,z,w] unless specified) + - None => identity + + The pose estimator below only needs marker positions, but we keep + this parser for completeness and future extension. + """ + if rotation is None: + return np.eye(3, dtype=np.float32) + + # Direct matrix + if isinstance(rotation, (list, tuple, np.ndarray)): + arr = np.array(rotation, dtype=np.float32) + if arr.shape == (3, 3): + return arr + if arr.size == 9: + return arr.reshape(3, 3).astype(np.float32) + if arr.size == 3: + # Treat as Rodrigues vector + R, _ = cv2.Rodrigues(arr.reshape(3, 1)) + return R.astype(np.float32) + return np.eye(3, dtype=np.float32) + + if isinstance(rotation, dict): + for key in ("rotation_matrix", "matrix"): + if key in rotation: + return _rotation_matrix_from_any(rotation[key]) + + for key in ("rvec", "rodrigues", "rodriques"): + if key in rotation: + v = np.array(rotation[key], dtype=np.float32).reshape(3, 1) + R, _ = cv2.Rodrigues(v) + return R.astype(np.float32) + + def euler_to_R(roll: float, pitch: float, yaw: float, degrees: bool = True) -> np.ndarray: + if degrees: + roll = np.deg2rad(roll) + pitch = np.deg2rad(pitch) + yaw = np.deg2rad(yaw) + cr, sr = np.cos(roll), np.sin(roll) + cp, sp = np.cos(pitch), np.sin(pitch) + cy, sy = np.cos(yaw), np.sin(yaw) + + Rx = np.array([[1, 0, 0], + [0, cr, -sr], + [0, sr, cr]], dtype=np.float32) + Ry = np.array([[cp, 0, sp], + [0, 1, 0], + [-sp, 0, cp]], dtype=np.float32) + Rz = np.array([[cy, -sy, 0], + [sy, cy, 0], + [0, 0, 1]], dtype=np.float32) + # ZYX convention + return (Rz @ Ry @ Rx).astype(np.float32) + + for key in ("euler_deg", "rpy_deg", "roll_pitch_yaw_deg"): + if key in rotation: + vals = np.array(rotation[key], dtype=np.float32).reshape(-1) + if vals.size == 3: + return euler_to_R(float(vals[0]), float(vals[1]), float(vals[2]), degrees=True) + + for key in ("euler_rad", "rpy_rad", "roll_pitch_yaw_rad"): + if key in rotation: + vals = np.array(rotation[key], dtype=np.float32).reshape(-1) + if vals.size == 3: + return euler_to_R(float(vals[0]), float(vals[1]), float(vals[2]), degrees=False) + + for key in ("quaternion", "quat"): + if key in rotation: + q = np.array(rotation[key], dtype=np.float32).reshape(-1) + if q.size == 4: + # Best-effort: try [x,y,z,w] + x, y, z, w = [float(v) for v in q] + R = np.array([ + [1 - 2*y*y - 2*z*z, 2*x*y - 2*z*w, 2*x*z + 2*y*w], + [2*x*y + 2*z*w, 1 - 2*x*x - 2*z*z, 2*y*z - 2*x*w], + [2*x*z - 2*y*w, 2*y*z + 2*x*w, 1 - 2*x*x - 2*y*y] + ], dtype=np.float32) + return R + + return np.eye(3, dtype=np.float32) + + +def get_marker_rotation(marker: Dict[str, Any]) -> np.ndarray: + """ + Flexible rotation extraction. Falls back to identity if absent. + """ + for key in ("rotation", "rotation_matrix", "matrix", "pose_rotation", "orientation"): + if key in marker: + return _rotation_matrix_from_any(marker[key]) + + # Also allow flat pose-style fields + if "rvec" in marker or "rodrigues" in marker: + return _rotation_matrix_from_any({"rvec": marker.get("rvec", marker.get("rodrigues"))}) + if "euler_deg" in marker: + return _rotation_matrix_from_any({"euler_deg": marker["euler_deg"]}) + if "rpy_deg" in marker: + return _rotation_matrix_from_any({"rpy_deg": marker["rpy_deg"]}) + if "quaternion" in marker: + return _rotation_matrix_from_any({"quaternion": marker["quaternion"]}) + + return np.eye(3, dtype=np.float32) + + +def load_marker_lookup(robot_json_path: str) -> Dict[int, Dict[str, Any]]: + """ + Supports the new format: + robot_data["links"]["Board"]["markers"] + + Fallback: + robot_data["Marker"] + """ + robot_json_path = resolve_path(robot_json_path) + with open(robot_json_path, "r", encoding="utf-8") as f: + robot_data = json.load(f) + + length_units = str(robot_data.get("units", {}).get("length", "")).strip().lower() + length_scale = 1.0 + if length_units in ("mm", "millimeter", "millimeters"): + length_scale = 1.0 / 1000.0 + elif length_units in ("cm", "centimeter", "centimeters"): + length_scale = 1.0 / 100.0 + + marker_lookup: Dict[int, Dict[str, Any]] = {} + + links = robot_data.get("links", {}) + board = links.get("Board") + + markers = None + if board and "markers" in board: + markers = board["markers"] + + if not markers: + markers = robot_data.get("Marker", []) + + for marker in markers: + marker_id = int(marker.get("id", -1)) + if marker_id < 0: + continue + + if "position" not in marker: + continue + + pos = marker.get("position") + if pos is None: + continue + + if len(pos) != 3: + continue + + rotation = get_marker_rotation(marker) + + marker_lookup[marker_id] = { + "position": np.array(pos, dtype=np.float32) * np.float32(length_scale), + "rotation": rotation, + "on": marker.get("on", "unknown"), + } + + return marker_lookup + + +def load_robot_marker_size(robot_json_path: str) -> Optional[float]: + """ + Best-effort marker size reader from robot.json. + Returns meters if found, otherwise None. + """ + robot_json_path = resolve_path(robot_json_path) + with open(robot_json_path, "r", encoding="utf-8") as f: + robot_data = json.load(f) + + vision_config = robot_data.get("vision_config", {}) + size = vision_config.get("MarkerSize", None) + if size is None: + return None + try: + return float(size) + except Exception: + return None + + +# --------------------------------------------------------------------- +# Geometry / pose helpers +# --------------------------------------------------------------------- + +def marker_local_corners(marker_size_m: float) -> np.ndarray: + half = marker_size_m / 2.0 + # Same corner order as the readTwoImages.py example + return np.array([ + [-half, half, 0.0], + [ half, half, 0.0], + [ half, -half, 0.0], + [-half, -half, 0.0], + ], dtype=np.float32) + + +def rigid_transform_no_scale(A: np.ndarray, B: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """ + Find R, t such that B ≈ R A + t. + A, B: Nx3 + """ + assert A.shape == B.shape and A.shape[1] == 3, "A and B must be Nx3" + N = A.shape[0] + if N < 2: + raise ValueError("Need at least 2 points; 3+ recommended.") + + centroid_A = A.mean(axis=0) + centroid_B = B.mean(axis=0) + + AA = A - centroid_A + BB = B - centroid_B + + H = AA.T @ BB + U, S, Vt = np.linalg.svd(H) + R = Vt.T @ U.T + + if np.linalg.det(R) < 0: + Vt[-1, :] *= -1 + R = Vt.T @ U.T + + t = centroid_B - R @ centroid_A + return R.astype(np.float32), t.astype(np.float32) + + +def undistort_to_normalized(points_px: np.ndarray, K: np.ndarray, D: np.ndarray) -> np.ndarray: + pts = points_px.reshape(-1, 1, 2).astype(np.float32) + und = cv2.undistortPoints(pts, K, D, P=None) + return und.reshape(-1, 2).astype(np.float32) + + +def rvec_to_R(rvec: np.ndarray) -> np.ndarray: + R, _ = cv2.Rodrigues(rvec.reshape(3, 1)) + return R.astype(np.float32) + + +def R_to_euler_zyx(R: np.ndarray) -> Tuple[float, float, float]: + """ + Return roll, pitch, yaw in degrees using ZYX convention. + """ + yaw = float(np.degrees(np.arctan2(R[1, 0], R[0, 0]))) + sp = np.sqrt(R[2, 1] ** 2 + R[2, 2] ** 2) + pitch = float(np.degrees(np.arctan2(-R[2, 0], sp))) + roll = float(np.degrees(np.arctan2(R[2, 1], R[2, 2]))) + return roll, pitch, yaw + + +def theta_to_camera_pose(theta: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + """ + theta = [omega_x, omega_y, omega_z, t_x, t_y, t_z] + Returns: + R_wc, t_wc, camera_center_world + """ + omega = theta[0:3] + t_wc = theta[3:6].reshape(3, 1).astype(np.float32) + R_wc, _ = cv2.Rodrigues(omega.reshape(3, 1)) + R_wc = R_wc.astype(np.float32) + R_cw = R_wc.T + camera_center_world = (-R_cw @ t_wc).reshape(3) + return R_wc, t_wc.reshape(3), camera_center_world + + +def build_projection_matrix(K: np.ndarray, R: np.ndarray, t: np.ndarray) -> np.ndarray: + return K @ np.hstack([R, t.reshape(3, 1)]) + + +# --------------------------------------------------------------------- +# LM on normalized residuals (same style as readTwoImages.py) +# --------------------------------------------------------------------- + +def pack_params(omega: np.ndarray, t: np.ndarray) -> np.ndarray: + return np.hstack([omega.reshape(3), t.reshape(3)]).astype(np.float64) + + +def unpack_params(theta: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + omega = theta[0:3] + t = theta[3:6] + return omega, t + + +def residuals_centers_normalized(theta: np.ndarray, + X_world: np.ndarray, + obs_norm: np.ndarray) -> np.ndarray: + """ + Residuals in normalized coordinates: + obs_norm - project(R X_world + t) + """ + omega, t = unpack_params(theta) + R_wc = cv2.Rodrigues(omega.reshape(3, 1))[0].astype(np.float64) + X_cam = (R_wc @ X_world.T + t.reshape(3, 1)).T + uv = X_cam[:, :2] / X_cam[:, 2:3] + r = (obs_norm - uv).reshape(-1) + return r + + +def numerical_jacobian(f, theta: np.ndarray, eps: float, *args) -> Tuple[np.ndarray, np.ndarray]: + r0 = f(theta, *args) + m = r0.size + n = theta.size + J = np.zeros((m, n), dtype=np.float64) + for k in range(n): + th = theta.copy() + th[k] += eps + rk = f(th, *args) + J[:, k] = (rk - r0) / eps + return J, r0 + + +def lm_solve(theta0: np.ndarray, + X_world: np.ndarray, + obs_norm: np.ndarray, + max_iter: int = 60, + eps_jac: float = 1e-6, + lambda_init: float = 1e-3) -> Tuple[np.ndarray, Dict[str, List[float]]]: + lam = lambda_init + theta = theta0.copy().astype(np.float64) + history = {"iters": [], "rms": [], "lambda": []} + + for it in range(max_iter): + J, r = numerical_jacobian(residuals_centers_normalized, theta, eps_jac, X_world, obs_norm) + rms = float(np.sqrt(np.mean(r * r))) if r.size else 0.0 + history["iters"].append(it) + history["rms"].append(rms) + history["lambda"].append(lam) + + JTJ = J.T @ J + g = J.T @ r + H = JTJ + lam * np.eye(JTJ.shape[0], dtype=np.float64) + + try: + delta = -np.linalg.solve(H, g) + except np.linalg.LinAlgError: + delta, *_ = np.linalg.lstsq(H, -g, rcond=None) + + theta_trial = theta + delta + r_trial = residuals_centers_normalized(theta_trial, X_world, obs_norm) + rms_trial = float(np.sqrt(np.mean(r_trial * r_trial))) if r_trial.size else rms + + if rms_trial < rms: + theta = theta_trial + lam *= 0.5 + else: + lam *= 2.0 + + if np.linalg.norm(delta) < 1e-10: + break + if abs(rms - rms_trial) < 1e-12: + break + + return theta, history + + +def pose_covariance(theta: np.ndarray, + X_world: np.ndarray, + obs_norm: np.ndarray, + eps_jac: float = 1e-6) -> Tuple[np.ndarray, float, np.ndarray]: + """ + Returns: + cov_theta_6x6, sigma2, residual_vector + """ + J, r = numerical_jacobian(residuals_centers_normalized, theta, eps_jac, X_world, obs_norm) + m = r.size + n = theta.size + dof = max(1, m - n) + sigma2 = float((r @ r) / dof) + + JTJ = J.T @ J + cov = sigma2 * np.linalg.pinv(JTJ) + return cov.astype(np.float64), sigma2, r + + +def propagate_covariance(theta: np.ndarray, + cov_theta: np.ndarray) -> Dict[str, Any]: + """ + Propagate pose covariance to camera center and Euler angle uncertainties. + """ + def camera_center_fn(th: np.ndarray) -> np.ndarray: + _, _, c = theta_to_camera_pose(th) + return c.astype(np.float64) + + def euler_fn(th: np.ndarray) -> np.ndarray: + R_wc, _, _ = theta_to_camera_pose(th) + return np.array(R_to_euler_zyx(R_wc), dtype=np.float64) # deg + + Jc, _ = numerical_jacobian(lambda th, *_: camera_center_fn(th), theta, 1e-6) + cov_center = Jc @ cov_theta @ Jc.T + + Je, _ = numerical_jacobian(lambda th, *_: euler_fn(th), theta, 1e-6) + cov_euler = Je @ cov_theta @ Je.T + + center_std_m = np.sqrt(np.maximum(0.0, np.diag(cov_center))) + euler_std_deg = np.sqrt(np.maximum(0.0, np.diag(cov_euler))) + + # Parameter std directly from covariance + param_std = np.sqrt(np.maximum(0.0, np.diag(cov_theta))) + rvec_std_deg = np.degrees(param_std[0:3]) + tvec_std_m = param_std[3:6] + + return { + "pose_covariance_6x6": cov_theta.tolist(), + "parameter_std": { + "rvec_std_deg": [float(x) for x in rvec_std_deg], + "tvec_std_m": [float(x) for x in tvec_std_m], + }, + "camera_center_std_m": [float(x) for x in center_std_m], + "camera_center_std_mm": [float(x * 1000.0) for x in center_std_m], + "orientation_std_deg": { + "roll": float(euler_std_deg[0]), + "pitch": float(euler_std_deg[1]), + "yaw": float(euler_std_deg[2]), + }, + } + + +# --------------------------------------------------------------------- +# Marker processing +# --------------------------------------------------------------------- + +def build_object_corners_from_world_position(position_m: np.ndarray, + marker_size_m: float) -> np.ndarray: + """ + Marker corners in world coordinates, assuming the marker frame is aligned + with the world frame and only translated to 'position_m'. + + This is the direct analogue of readTwoImages.py using marker center positions. + """ + h = marker_size_m / 2.0 + local = np.array([ + [-h, h, 0.0], + [ h, h, 0.0], + [ h, -h, 0.0], + [-h, -h, 0.0], + ], dtype=np.float32) + return local + position_m.reshape(1, 3) + + +def solve_single_marker_pose(corners_px: np.ndarray, + K: np.ndarray, + D: np.ndarray, + marker_size_m: float) -> Optional[Tuple[np.ndarray, np.ndarray]]: + obj = marker_local_corners(marker_size_m) + success, rvec, tvec = cv2.solvePnP( + obj, + corners_px.astype(np.float32), + K, + D, + flags=cv2.SOLVEPNP_IPPE_SQUARE + ) + if not success: + success, rvec, tvec = cv2.solvePnP( + obj, + corners_px.astype(np.float32), + K, + D, + flags=cv2.SOLVEPNP_ITERATIVE + ) + if not success: + return None + return rvec.reshape(3), tvec.reshape(3) + + +# --------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------- + +def main() -> None: + parser = argparse.ArgumentParser(description="Estimate camera pose from ArUco observation JSON") + parser.add_argument("-i", "--input", required=True, help="*_aruco_detection.json") + parser.add_argument("-robot", "--robot", required=True, help="robot.json with board markers") + parser.add_argument("-outDir", "--outDir", default=None, help="Optional output directory") + parser.add_argument("--minConfidence", type=float, default=0.0, + help="Skip detections below this confidence") + parser.add_argument("--minCommonMarkers", type=int, default=3, + help="Minimum number of world markers required") + parser.add_argument("--maxRmsPx", type=float, default=None, + help="Optional soft warning threshold for final reprojection RMS in pixels") + parser.add_argument("--epsJac", type=float, default=1e-6, help="Finite-difference epsilon") + args = parser.parse_args() + + detection_path = resolve_path(args.input) + robot_path = resolve_path(args.robot) + + detection = load_json(detection_path) + marker_lookup = load_marker_lookup(robot_path) + + K, D = load_intrinsics_from_detection(detection) + + robot_marker_size = load_robot_marker_size(robot_path) + det_marker_size = detection.get("vision_config", {}).get("MarkerSize", None) + if det_marker_size is not None: + marker_size_m = float(det_marker_size) + elif robot_marker_size is not None: + marker_size_m = float(robot_marker_size) + else: + marker_size_m = 0.025 + + detections = detection.get("detections", []) + if not isinstance(detections, list): + raise TypeError("detection['detections'] must be a list") + + used_ids: List[int] = [] + used_world_positions: List[np.ndarray] = [] + used_obs_centers_px: List[np.ndarray] = [] + used_obs_centers_norm: List[np.ndarray] = [] + used_marker_cam_centers: List[np.ndarray] = [] + used_marker_meta: List[Dict[str, Any]] = [] + + sanity_notes: List[str] = [] + + for det in detections: + if det.get("type", "aruco") != "aruco": + continue + + marker_id = int(det.get("marker_id", -1)) + if marker_id < 0: + continue + + if marker_id not in marker_lookup: + continue + + confidence = float(det.get("confidence", 1.0)) + if confidence < args.minConfidence: + continue + + corners = det.get("image_points_px", None) + if corners is None: + continue + + corners_px = np.array(corners, dtype=np.float32).reshape(4, 2) + center_from_corners = corners_px.mean(axis=0) + + center_px = np.array(det.get("center_px", center_from_corners), dtype=np.float32).reshape(2) + center_delta = float(np.linalg.norm(center_from_corners - center_px)) + if center_delta > 0.75: + sanity_notes.append( + f"marker {marker_id}: center_px differs from corner-mean by {center_delta:.2f}px" + ) + + pnp = solve_single_marker_pose(corners_px, K, D, marker_size_m) + if pnp is None: + continue + + rvec_m, tvec_m = pnp + world_pos = marker_lookup[marker_id]["position"].astype(np.float32) + + used_ids.append(marker_id) + used_world_positions.append(world_pos) + used_obs_centers_px.append(center_from_corners.astype(np.float32)) + used_obs_centers_norm.append(undistort_to_normalized(center_from_corners.reshape(1, 2), K, D)[0]) + used_marker_cam_centers.append(tvec_m.astype(np.float32)) + used_marker_meta.append({ + "marker_id": marker_id, + "confidence": confidence, + "center_px": [float(center_from_corners[0]), float(center_from_corners[1])], + "marker_size_m": marker_size_m, + }) + + # Unique / deduplicate by marker_id while preserving order + dedup: Dict[int, int] = {} + uniq_ids: List[int] = [] + uniq_world_positions: List[np.ndarray] = [] + uniq_obs_px: List[np.ndarray] = [] + uniq_obs_norm: List[np.ndarray] = [] + uniq_cam_centers: List[np.ndarray] = [] + uniq_meta: List[Dict[str, Any]] = [] + + for idx, mid in enumerate(used_ids): + if mid in dedup: + continue + dedup[mid] = idx + uniq_ids.append(mid) + uniq_world_positions.append(used_world_positions[idx]) + uniq_obs_px.append(used_obs_centers_px[idx]) + uniq_obs_norm.append(used_obs_centers_norm[idx]) + uniq_cam_centers.append(used_marker_cam_centers[idx]) + uniq_meta.append(used_marker_meta[idx]) + + if len(uniq_ids) < args.minCommonMarkers: + raise RuntimeError( + f"Need at least {args.minCommonMarkers} common markers; found {len(uniq_ids)}: {uniq_ids}" + ) + + X_world = np.stack(uniq_world_positions, axis=0).astype(np.float64) + obs_px = np.stack(uniq_obs_px, axis=0).astype(np.float64) + obs_norm = np.stack(uniq_obs_norm, axis=0).astype(np.float64) + marker_cam_centers = np.stack(uniq_cam_centers, axis=0).astype(np.float64) + + # Initial pose from rigid transform of per-marker camera-frame centers to world positions + # B ≈ R A + t -> world = R * camera + t + R_cw_init, t_cw_init = rigid_transform_no_scale(marker_cam_centers, X_world) + R_wc_init = R_cw_init.T + t_wc_init = -(R_wc_init @ t_cw_init).reshape(3) + + omega_init = cv2.Rodrigues(R_wc_init)[0].reshape(3) + theta0 = pack_params(omega_init, t_wc_init) + + theta_opt, hist = lm_solve( + theta0=theta0, + X_world=X_world, + obs_norm=obs_norm, + max_iter=60, + eps_jac=args.epsJac, + lambda_init=1e-3, + ) + + R_wc, t_wc, camera_center_world = theta_to_camera_pose(theta_opt) + + cov_theta, sigma2, residual_vec = pose_covariance( + theta_opt, X_world, obs_norm, eps_jac=args.epsJac + ) + propagated = propagate_covariance(theta_opt, cov_theta) + + # Exact pixel-space reprojection statistics + proj_pts, _ = cv2.projectPoints( + X_world.reshape(-1, 1, 3).astype(np.float32), + theta_opt[0:3].reshape(3, 1).astype(np.float32), + theta_opt[3:6].reshape(3, 1).astype(np.float32), + K, + D, + ) + proj_pts = proj_pts.reshape(-1, 2) + reproj_err_px = np.linalg.norm(proj_pts - obs_px, axis=1) + rms_px = float(np.sqrt(np.mean(reproj_err_px ** 2))) if reproj_err_px.size else 0.0 + median_px = float(np.median(reproj_err_px)) if reproj_err_px.size else 0.0 + max_px = float(np.max(reproj_err_px)) if reproj_err_px.size else 0.0 + + if args.maxRmsPx is not None and rms_px > args.maxRmsPx: + print(f"[WARN] Final reprojection RMS is {rms_px:.3f}px (threshold {args.maxRmsPx:.3f}px).") + + # Convert outputs + roll, pitch, yaw = R_to_euler_zyx(R_wc) + position_mm = (camera_center_world * 1000.0).astype(float).tolist() + + # Reproject each used marker center for QA + per_marker_results = [] + proj_pts_exact, _ = cv2.projectPoints( + X_world.reshape(-1, 1, 3).astype(np.float32), + theta_opt[0:3].reshape(3, 1).astype(np.float32), + theta_opt[3:6].reshape(3, 1).astype(np.float32), + K, + D, + ) + proj_pts_exact = proj_pts_exact.reshape(-1, 2) + + for idx, mid in enumerate(uniq_ids): + x = proj_pts_exact[idx] + err = float(np.linalg.norm(x - obs_px[idx])) + per_marker_results.append({ + "marker_id": int(mid), + "observed_center_px": [float(obs_px[idx, 0]), float(obs_px[idx, 1])], + "projected_center_px": [float(x[0]), float(x[1])], + "reprojection_error_px": err, + "confidence": float(uniq_meta[idx]["confidence"]), + }) + + # Output directory + in_base = os.path.splitext(os.path.basename(detection_path))[0] + out_name = in_base.replace("_aruco_detection", "_camera_pose") + ".json" + + if args.outDir is not None: + out_dir = resolve_path(args.outDir) + else: + out_dir = os.path.dirname(detection_path) or "." + + os.makedirs(out_dir, exist_ok=True) + out_json = os.path.join(out_dir, out_name) + + output = { + "schema_version": "1.0", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "source": { + "detection_json": detection_path, + "robot_json": robot_path, + }, + "camera": { + "camera_id": detection.get("camera", {}).get("camera_id", "unknown"), + "camera_matrix": K.tolist(), + "distortion_coefficients": D.reshape(-1).tolist(), + }, + "estimation": { + "method": "single_camera_marker_center_lm", + "description": "Rigid init from per-marker pose estimates, followed by LM on normalized marker-center reprojection residuals.", + "marker_size_m": float(marker_size_m), + "num_used_markers": int(len(uniq_ids)), + "used_marker_ids": [int(x) for x in uniq_ids], + "history": hist, + "residual_rms_px": float(rms_px), + "residual_median_px": float(median_px), + "residual_max_px": float(max_px), + "sigma2_normalized": float(sigma2), + }, + "camera_pose": { + "world_to_camera": { + "rotation_matrix": R_wc.tolist(), + "translation_m": [float(x) for x in t_wc.tolist()], + "rvec_rad": [float(x) for x in theta_opt[0:3].tolist()], + }, + "camera_in_world": { + "position_m": [float(x) for x in camera_center_world.tolist()], + "position_mm": [float(x) for x in position_mm], + "orientation_deg": { + "roll": float(roll), + "pitch": float(pitch), + "yaw": float(yaw), + }, + }, + "uncertainty": propagated, + }, + "observations": { + "markers": per_marker_results, + }, + "qa": { + "sanity_notes": sanity_notes, + }, + } + + save_json(out_json, output) + print(f"[INFO] Saved camera pose JSON: {out_json}") + + +if __name__ == "__main__": + try: + main() + except Exception as exc: + print(f"[ERROR] {exc}", file=sys.stderr) + sys.exit(1) diff --git a/scripts/pipeline/3_multiview_bundle_adjustment_v4.py b/scripts/pipeline/3_multiview_bundle_adjustment_v4.py new file mode 100644 index 0000000..0f629b5 --- /dev/null +++ b/scripts/pipeline/3_multiview_bundle_adjustment_v4.py @@ -0,0 +1,1499 @@ +#!/usr/bin/env python3 +""" +3_multiview_bundle_adjustment_v4.py + +Multi-view ArUco marker position optimization with explicit, switchable +degrees-of-freedom constraints. + +Mathematical model +------------------ +We estimate 3D marker positions X_i ∈ R^3 by minimizing + + E(X) = + Σ_{i,c} w_ic || π_c(X_i) - u_ic ||² + + λ_r Σ_j w_j^r || ||X_a - X_b|| - d_j ||² + + λ_rev Σ_k w_k^rev || (X_b - X_a)·a_k - t_k ||² + + λ_pri Σ_m w_m^pri ( ||(X_b - X_a)·u_m - t_u||² + + ||(X_b - X_a)·v_m - t_v||² ) + +where: +- u_ic are observed normalized image coordinates for marker i in camera c +- π_c(.) is the normalized reprojection model +- w_ic are observation weights from detection quality / marker priors / range +- rigid-link constraints preserve internal marker geometry of a link +- revolute joints keep the projection along the joint axis constant +- prismatic joints keep the two orthogonal projection components constant + +Important design choices +------------------------ +- robot.json is used as a kinematic description, not as a direct source of + world-space marker positions. +- constraint families are explicit, switchable, and easy to compare across + versions. +- legacy chain-propagation constraints are retained only as an optional family + and are OFF by default. +- observation weighting remains separate from constraint weighting so both can + be tested independently. + +Dependencies: + numpy, opencv-python, scipy (optional for optimization) + +Example: + python 3_multiview_bundle_adjustment_v4.py ^ + -det cam1_aruco_detection.json cam2_aruco_detection.json cam3_aruco_detection.json ^ + -pose cam1_camera_pose.json cam2_camera_pose.json cam3_camera_pose.json ^ + -robot robot.json ^ + -lambdaWeight 100.0 +""" +from __future__ import annotations + +import argparse +import json +import os +import sys +import time +from dataclasses import dataclass +from itertools import combinations +from typing import Any, Dict, List, Optional, Tuple + +import cv2 +import numpy as np + + +# =================================================================== +# Path / JSON helpers +# =================================================================== + +def resolve_path(path: str) -> str: + path = os.path.expanduser(path) + if os.path.isabs(path): + return path + return os.path.abspath(path) + + +def load_json(path: str) -> Dict[str, Any]: + with open(resolve_path(path), "r", encoding="utf-8") as f: + return json.load(f) + + +def save_json(path: str, data: Dict[str, Any]) -> None: + with open(resolve_path(path), "w", encoding="utf-8") as f: + json.dump(data, f, indent=2) + + +# =================================================================== +# Units +# =================================================================== + +def get_length_scale(robot_data: Dict[str, Any]) -> float: + units = robot_data.get("units", {}) or {} + length_unit = str(units.get("length", "")).strip().lower() + if length_unit in ("mm", "millimeter", "millimeters"): + return 1.0 / 1000.0 + if length_unit in ("cm", "centimeter", "centimeters"): + return 1.0 / 100.0 + return 1.0 + + +# =================================================================== +# Small geometry helpers +# =================================================================== + +def safe_norm(v: np.ndarray, eps: float = 1e-12) -> float: + return float(np.linalg.norm(v) + eps) + + +def normalize_vector(v: np.ndarray, eps: float = 1e-12) -> np.ndarray: + return np.asarray(v, dtype=np.float64) / safe_norm(v, eps) + + +def clamp(v: float, lo: float, hi: float) -> float: + return float(max(lo, min(hi, v))) + + +def principal_axis_id(axis: np.ndarray, threshold: float = 0.95) -> Optional[int]: + """Return 0,1,2 for x,y,z if axis is close enough to a principal axis.""" + a = normalize_vector(np.asarray(axis, dtype=np.float64)) + idx = int(np.argmax(np.abs(a))) + if abs(a[idx]) >= threshold: + return idx + return None + + +def camera_center_from_world_to_cam(R_wc: np.ndarray, t_wc: np.ndarray) -> np.ndarray: + """world_to_camera: X_cam = R_wc * X_world + t_wc; camera center is -R^T t.""" + return -R_wc.T @ t_wc + + +def principal_axis_vector(axis: np.ndarray) -> np.ndarray: + """Convert a near-principal axis to an exact signed principal axis vector.""" + a = normalize_vector(axis) + idx = int(np.argmax(np.abs(a))) + out = np.zeros(3, dtype=np.float64) + out[idx] = 1.0 if a[idx] >= 0 else -1.0 + return normalize_vector(out) + + +def orthonormal_basis_from_axis(axis: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """ + Build two unit vectors orthogonal to axis, with a deterministic orientation. + """ + a = normalize_vector(axis) + ref = np.array([1.0, 0.0, 0.0], dtype=np.float64) + if abs(float(np.dot(a, ref))) > 0.90: + ref = np.array([0.0, 1.0, 0.0], dtype=np.float64) + u = np.cross(a, ref) + if np.linalg.norm(u) < 1e-12: + ref = np.array([0.0, 0.0, 1.0], dtype=np.float64) + u = np.cross(a, ref) + u = normalize_vector(u) + v = normalize_vector(np.cross(a, u)) + return u, v + + +# =================================================================== +# Configuration +# =================================================================== + +@dataclass +class ConstraintRuleConfig: + rigid_distance_enabled: bool = True + rigid_distance_mode: str = "mst" # mst | star | full + rigid_distance_weight: float = 1.0 + + # Revolute joints: keep the projection along the axis constant. + revolute_axis_enabled: bool = True + revolute_axis_max_pairs: int = 2 + revolute_axis_weight: float = 0.5 + + # Prismatic joints: keep the two orthogonal projection components constant. + prismatic_orthogonal_enabled: bool = True + prismatic_orthogonal_max_pairs: int = 2 + prismatic_orthogonal_weight: float = 0.35 + + # Legacy / optional chain propagation, disabled by default. + chain_axis_enabled: bool = False + chain_axis_max_depth: int = 3 + chain_axis_max_pairs: int = 2 + chain_axis_weight: float = 0.3 + + axis_alignment_threshold: float = 0.95 + + strict_unique_marker_ids: bool = False + show_skipped_constraints: bool = True + + enable_observation_weights: bool = True + weight_floor: float = 0.30 + weight_ceiling: float = 3.00 + ref_distance_m: float = 0.75 + ref_marker_size_px: float = 50.0 + use_detection_confidence: bool = True + use_detection_size_px: bool = True + use_initial_range: bool = True + use_marker_size_prior: bool = True + + +def _bool_or_default(value: Any, default: bool) -> bool: + if value is None: + return default + return bool(value) + + +def _float_or_default(value: Any, default: float) -> float: + if value is None: + return default + return float(value) + + +def _int_or_default(value: Any, default: int) -> int: + if value is None: + return default + return int(value) + + +def load_constraint_rule_config(robot_data: Dict[str, Any], args: argparse.Namespace) -> ConstraintRuleConfig: + """ + Merge built-in defaults with optional robot.json constraint_rules and CLI flags. + Backward compatibility: + - joint_axis_projection -> revolute_axis + """ + rules = robot_data.get("constraint_rules", {}) or {} + + cfg = ConstraintRuleConfig() + rigid = rules.get("rigid_distance", {}) or {} + revolute = rules.get("joint_revolute_axis", {}) or rules.get("joint_axis_projection", {}) or {} + prismatic = rules.get("joint_prismatic_orthogonal", {}) or {} + chain = rules.get("chain_axis_projection", {}) or {} + obs = rules.get("observation_weights", {}) or {} + + cfg.rigid_distance_enabled = _bool_or_default(rigid.get("enabled"), cfg.rigid_distance_enabled) + cfg.rigid_distance_mode = str(rigid.get("mode", cfg.rigid_distance_mode)).strip().lower() + cfg.rigid_distance_weight = _float_or_default(rigid.get("weight"), cfg.rigid_distance_weight) + + cfg.revolute_axis_enabled = _bool_or_default(revolute.get("enabled"), cfg.revolute_axis_enabled) + cfg.revolute_axis_max_pairs = _int_or_default(revolute.get("max_pairs"), cfg.revolute_axis_max_pairs) + cfg.revolute_axis_weight = _float_or_default(revolute.get("weight"), cfg.revolute_axis_weight) + + cfg.prismatic_orthogonal_enabled = _bool_or_default(prismatic.get("enabled"), cfg.prismatic_orthogonal_enabled) + cfg.prismatic_orthogonal_max_pairs = _int_or_default(prismatic.get("max_pairs"), cfg.prismatic_orthogonal_max_pairs) + cfg.prismatic_orthogonal_weight = _float_or_default(prismatic.get("weight"), cfg.prismatic_orthogonal_weight) + + cfg.chain_axis_enabled = _bool_or_default(chain.get("enabled"), cfg.chain_axis_enabled) + cfg.chain_axis_max_depth = _int_or_default(chain.get("max_depth"), cfg.chain_axis_max_depth) + cfg.chain_axis_max_pairs = _int_or_default(chain.get("max_pairs"), cfg.chain_axis_max_pairs) + cfg.chain_axis_weight = _float_or_default(chain.get("weight"), cfg.chain_axis_weight) + + cfg.axis_alignment_threshold = _float_or_default( + rules.get("axis_alignment_threshold"), cfg.axis_alignment_threshold + ) + + cfg.enable_observation_weights = _bool_or_default(obs.get("enabled"), cfg.enable_observation_weights) + cfg.weight_floor = _float_or_default(obs.get("weight_floor"), cfg.weight_floor) + cfg.weight_ceiling = _float_or_default(obs.get("weight_ceiling"), cfg.weight_ceiling) + cfg.ref_distance_m = _float_or_default(obs.get("ref_distance_m"), cfg.ref_distance_m) + cfg.ref_marker_size_px = _float_or_default(obs.get("ref_marker_size_px"), cfg.ref_marker_size_px) + cfg.use_detection_confidence = _bool_or_default(obs.get("use_detection_confidence"), cfg.use_detection_confidence) + cfg.use_detection_size_px = _bool_or_default(obs.get("use_detection_size_px"), cfg.use_detection_size_px) + cfg.use_initial_range = _bool_or_default(obs.get("use_initial_range"), cfg.use_initial_range) + cfg.use_marker_size_prior = _bool_or_default(obs.get("use_marker_size_prior"), cfg.use_marker_size_prior) + + if getattr(args, "strictUniqueMarkerIds", False): + cfg.strict_unique_marker_ids = True + if getattr(args, "showSkippedConstraints", False): + cfg.show_skipped_constraints = True + if getattr(args, "noShowSkippedConstraints", False): + cfg.show_skipped_constraints = False + + return cfg + + +# =================================================================== +# Observation / constraint definitions +# =================================================================== + +@dataclass +class Observation: + cam_idx: int + norm_coords: np.ndarray + meta: Dict[str, Any] + + +@dataclass +class MarkerDistanceConstraint: + marker_id_a: int + marker_id_b: int + link_name: str + target_distance_m: float + weight: float = 1.0 + enabled: bool = True + source: str = "rigid_distance" + + +@dataclass +class JointAxisConstraint: + marker_id_parent: int + marker_id_child: int + parent_link: str + child_link: str + joint_axis: np.ndarray + target_delta_along_axis_m: float + weight: float = 1.0 + enabled: bool = True + source: str = "joint_axis_projection" + + +Constraint = MarkerDistanceConstraint | JointAxisConstraint + + +# =================================================================== +# Robot parsing +# =================================================================== + +def parse_robot_markers( + robot_data: Dict[str, Any], + length_scale: float, + strict_unique_marker_ids: bool = False +) -> Tuple[Dict[int, str], Dict[str, List[Dict[str, Any]]], List[str], Dict[int, Dict[str, Any]]]: + links = robot_data.get("links", {}) or {} + + marker_to_link: Dict[int, str] = {} + link_markers: Dict[str, List[Dict[str, Any]]] = {} + issues: List[str] = [] + marker_meta: Dict[int, Dict[str, Any]] = {} + + seen_global: Dict[int, str] = {} + + for link_name, link_data in links.items(): + markers = link_data.get("markers", []) or [] + collected: List[Dict[str, Any]] = [] + seen_local: set[int] = set() + + for idx, marker in enumerate(markers): + marker_id = int(marker.get("id", -1)) + pos = marker.get("position", None) + + if marker_id < 0 or pos is None or len(pos) != 3: + issues.append(f"[WARN] link={link_name}: skipped invalid marker entry at index {idx}") + continue + + if marker_id in seen_local: + msg = f"[WARN] duplicate marker id {marker_id} inside link '{link_name}'" + if strict_unique_marker_ids: + raise ValueError(msg) + issues.append(msg + " -> skipped duplicate inside same link") + continue + + if marker_id in seen_global: + msg = ( + f"[WARN] duplicate marker id {marker_id} appears in link '{link_name}' " + f"and already in link '{seen_global[marker_id]}'" + ) + if strict_unique_marker_ids: + raise ValueError(msg) + issues.append(msg + " -> skipped duplicate occurrence") + continue + + seen_local.add(marker_id) + seen_global[marker_id] = link_name + + pos_raw = np.array(pos, dtype=np.float64) + pos_m = pos_raw * float(length_scale) + + item = { + "id": marker_id, + "name": marker.get("name", f"marker_{marker_id}"), + "position_raw": pos_raw, + "position_m": pos_m, + "normal": np.array(marker.get("normal", [0, 0, 1]), dtype=np.float64), + "size": marker.get("size", None), + "spin": marker.get("spin", None), + } + collected.append(item) + marker_to_link[marker_id] = link_name + marker_meta[marker_id] = { + "link_name": link_name, + "name": item["name"], + "position_m": pos_m, + "normal": item["normal"], + "size": item["size"], + "spin": item["spin"], + } + + link_markers[link_name] = collected + + return marker_to_link, link_markers, issues, marker_meta + + +def get_link_parent_map(robot_data: Dict[str, Any]) -> Dict[str, Optional[str]]: + links = robot_data.get("links", {}) or {} + return {link_name: (link_data.get("parent", None)) for link_name, link_data in links.items()} + + +def get_joint_info(robot_data: Dict[str, Any], child_link: str) -> Dict[str, Any]: + links = robot_data.get("links", {}) or {} + return (links.get(child_link, {}) or {}).get("jointToParent", {}) or {} + + +def get_joint_axis(robot_data: Dict[str, Any], child_link: str) -> Optional[np.ndarray]: + joint = get_joint_info(robot_data, child_link) + axis = joint.get("axis", None) + if axis is None: + return None + axis = np.asarray(axis, dtype=np.float64) + if safe_norm(axis) < 1e-12: + return None + return normalize_vector(axis) + + +def get_vision_marker_size_default(robot_data: Dict[str, Any]) -> float: + vision = robot_data.get("vision_config", {}) or {} + ms = vision.get("MarkerSize", None) + if ms is None: + return 0.025 + return float(ms) + + +# =================================================================== +# Constraint compilation helpers +# =================================================================== + +def get_enabled_link_rule( + robot_data: Dict[str, Any], + link_name: str, + rule_name: str, + default_enabled: bool = True +) -> bool: + overrides = robot_data.get("constraint_overrides", {}) or {} + link_override = overrides.get(link_name, {}) or {} + rule_override = link_override.get(rule_name, {}) or {} + if "enabled" in rule_override: + return bool(rule_override["enabled"]) + return default_enabled + + +def select_anchor_marker_ids( + markers: List[Dict[str, Any]], + axis: Optional[np.ndarray] = None, + max_count: int = 2 +) -> List[int]: + if not markers: + return [] + if len(markers) == 1: + return [int(markers[0]["id"])] + + ids = [int(m["id"]) for m in markers] + pos = np.stack([np.asarray(m["position_m"], dtype=np.float64) for m in markers], axis=0) + + selected: List[int] = [] + + if axis is not None and safe_norm(axis) > 1e-12: + a = normalize_vector(axis) + proj = pos @ a + min_idx = int(np.argmin(proj)) + max_idx = int(np.argmax(proj)) + selected = [ids[min_idx], ids[max_idx]] + else: + centroid = np.mean(pos, axis=0) + d = np.linalg.norm(pos - centroid, axis=1) + min_idx = int(np.argmin(d)) + max_idx = int(np.argmax(d)) + selected = [ids[min_idx], ids[max_idx]] + + if len(selected) < max_count: + for mid in ids: + if mid not in selected: + selected.append(mid) + if len(selected) >= max_count: + break + + out: List[int] = [] + seen: set[int] = set() + for mid in selected: + if mid not in seen: + seen.add(mid) + out.append(mid) + if len(out) >= max_count: + break + return out + + +def mst_edges_for_link(markers: List[Dict[str, Any]]) -> List[Tuple[int, int]]: + n = len(markers) + if n < 2: + return [] + + ids = [int(m["id"]) for m in markers] + pos = np.stack([np.asarray(m["position_m"], dtype=np.float64) for m in markers], axis=0) + in_tree = np.zeros(n, dtype=bool) + in_tree[0] = True + edges: List[Tuple[int, int]] = [] + dist = np.linalg.norm(pos[:, None, :] - pos[None, :, :], axis=2) + + for _ in range(n - 1): + best = None + best_d = float("inf") + for i in range(n): + if not in_tree[i]: + continue + for j in range(n): + if in_tree[j]: + continue + d = float(dist[i, j]) + if d < best_d: + best_d = d + best = (i, j) + if best is None: + break + i, j = best + in_tree[j] = True + edges.append((ids[i], ids[j])) + return edges + + +def compile_rigid_distance_constraints( + robot_data: Dict[str, Any], + link_markers: Dict[str, List[Dict[str, Any]]], + cfg: ConstraintRuleConfig +) -> List[MarkerDistanceConstraint]: + constraints: List[MarkerDistanceConstraint] = [] + + for link_name, markers in link_markers.items(): + if not get_enabled_link_rule(robot_data, link_name, "rigid_distance", cfg.rigid_distance_enabled): + continue + if len(markers) < 2: + continue + + mode = cfg.rigid_distance_mode + if mode == "full": + pairs = [(int(a["id"]), int(b["id"])) for a, b in combinations(markers, 2)] + elif mode == "star": + anchor_ids = select_anchor_marker_ids(markers, axis=None, max_count=1) + anchor_id = anchor_ids[0] + pairs = [] + for m in markers: + mid = int(m["id"]) + if mid != anchor_id: + pairs.append((anchor_id, mid)) + elif mode == "mst": + pairs = mst_edges_for_link(markers) + else: + raise ValueError(f"Unknown rigid_distance_mode='{mode}'. Use mst|star|full.") + + pos_map = {int(m["id"]): np.asarray(m["position_m"], dtype=np.float64) for m in markers} + seen_pairs: set[Tuple[int, int]] = set() + + for mid_a, mid_b in pairs: + if mid_a == mid_b: + continue + key = tuple(sorted((int(mid_a), int(mid_b)))) + if key in seen_pairs: + continue + seen_pairs.add(key) + + pos_a = pos_map[mid_a] + pos_b = pos_map[mid_b] + target = float(np.linalg.norm(pos_b - pos_a)) + + constraints.append( + MarkerDistanceConstraint( + marker_id_a=mid_a, + marker_id_b=mid_b, + link_name=link_name, + target_distance_m=target, + weight=cfg.rigid_distance_weight, + enabled=True, + source=f"rigid_distance:{mode}", + ) + ) + + return constraints + + +def compile_joint_dof_constraints( + robot_data: Dict[str, Any], + link_markers: Dict[str, List[Dict[str, Any]]], + cfg: ConstraintRuleConfig +) -> List[JointAxisConstraint]: + """ + Compile local joint constraints from robot.json. + + Revolute joints: one scalar constraint per anchor pair + (projection along the joint axis stays constant) + + Prismatic joints: two scalar constraints per anchor pair + (the orthogonal projections stay constant) + + Both are emitted as JointAxisConstraint objects so the rest of the + optimization pipeline remains unchanged. + """ + constraints: List[JointAxisConstraint] = [] + links = robot_data.get("links", {}) or {} + + for child_link, child_data in links.items(): + parent_link = child_data.get("parent", None) + if not parent_link: + continue + + joint_info = child_data.get("jointToParent", {}) or {} + joint_type = str(joint_info.get("type", "")).strip().lower() + + joint_axis = get_joint_axis(robot_data, child_link) + if joint_axis is None: + continue + + axis_vec = principal_axis_vector(joint_axis) + + parent_markers = link_markers.get(parent_link, []) + child_markers = link_markers.get(child_link, []) + if len(parent_markers) == 0 or len(child_markers) == 0: + continue + + parent_pos = {int(m["id"]): np.asarray(m["position_m"], dtype=np.float64) for m in parent_markers} + child_pos = {int(m["id"]): np.asarray(m["position_m"], dtype=np.float64) for m in child_markers} + + seen: set[Tuple[int, int]] = set() + + if joint_type == "revolute": + if not get_enabled_link_rule( + robot_data, child_link, "joint_revolute_axis", cfg.revolute_axis_enabled + ): + continue + + max_pairs = max(1, int(cfg.revolute_axis_max_pairs)) + parent_anchor_ids = select_anchor_marker_ids(parent_markers, axis=axis_vec, max_count=max_pairs) + child_anchor_ids = select_anchor_marker_ids(child_markers, axis=axis_vec, max_count=max_pairs) + + for mid_p in parent_anchor_ids: + for mid_c in child_anchor_ids: + if mid_p == mid_c: + continue + key = (mid_p, mid_c) + if key in seen: + continue + seen.add(key) + + delta = child_pos[mid_c] - parent_pos[mid_p] + target = float(np.dot(delta, axis_vec)) + + constraints.append( + JointAxisConstraint( + marker_id_parent=mid_p, + marker_id_child=mid_c, + parent_link=parent_link, + child_link=child_link, + joint_axis=axis_vec, + target_delta_along_axis_m=target, + weight=cfg.revolute_axis_weight, + enabled=True, + source="revolute_axis_projection", + ) + ) + + elif joint_type == "linear": + if not get_enabled_link_rule( + robot_data, child_link, "joint_prismatic_orthogonal", cfg.prismatic_orthogonal_enabled + ): + continue + + max_pairs = max(1, int(cfg.prismatic_orthogonal_max_pairs)) + parent_anchor_ids = select_anchor_marker_ids(parent_markers, axis=axis_vec, max_count=max_pairs) + child_anchor_ids = select_anchor_marker_ids(child_markers, axis=axis_vec, max_count=max_pairs) + basis_u, basis_v = orthonormal_basis_from_axis(axis_vec) + + for mid_p in parent_anchor_ids: + for mid_c in child_anchor_ids: + if mid_p == mid_c: + continue + key = (mid_p, mid_c) + if key in seen: + continue + seen.add(key) + + delta = child_pos[mid_c] - parent_pos[mid_p] + + constraints.append( + JointAxisConstraint( + marker_id_parent=mid_p, + marker_id_child=mid_c, + parent_link=parent_link, + child_link=child_link, + joint_axis=basis_u, + target_delta_along_axis_m=float(np.dot(delta, basis_u)), + weight=cfg.prismatic_orthogonal_weight, + enabled=True, + source="prismatic_orthogonal_projection:u", + ) + ) + constraints.append( + JointAxisConstraint( + marker_id_parent=mid_p, + marker_id_child=mid_c, + parent_link=parent_link, + child_link=child_link, + joint_axis=basis_v, + target_delta_along_axis_m=float(np.dot(delta, basis_v)), + weight=cfg.prismatic_orthogonal_weight, + enabled=True, + source="prismatic_orthogonal_projection:v", + ) + ) + + else: + continue + + return constraints + + + + +def compile_constraints( + robot_data: Dict[str, Any], + length_scale: float, + cfg: ConstraintRuleConfig +) -> Tuple[Dict[int, str], Dict[str, List[Dict[str, Any]]], List[Constraint], List[str], Dict[int, Dict[str, Any]]]: + marker_to_link, link_markers, issues, marker_meta = parse_robot_markers( + robot_data, + length_scale=length_scale, + strict_unique_marker_ids=cfg.strict_unique_marker_ids, + ) + + constraints: List[Constraint] = [] + constraints.extend(compile_rigid_distance_constraints(robot_data, link_markers, cfg)) + constraints.extend(compile_joint_dof_constraints(robot_data, link_markers, cfg)) + + # Legacy optional family, OFF by default. + if cfg.chain_axis_enabled: + constraints.extend(compile_chain_axis_constraints(robot_data, link_markers, cfg)) + + unique_constraints: List[Constraint] = [] + seen_keys: set[Tuple[Any, ...]] = set() + + for c in constraints: + if isinstance(c, MarkerDistanceConstraint): + key = ( + "d", + min(c.marker_id_a, c.marker_id_b), + max(c.marker_id_a, c.marker_id_b), + c.link_name, + round(c.target_distance_m, 9), + ) + else: + key = ( + "j", + c.parent_link, + c.child_link, + c.marker_id_parent, + c.marker_id_child, + tuple(np.round(c.joint_axis, 9).tolist()), + round(c.target_delta_along_axis_m, 9), + ) + if key in seen_keys: + continue + seen_keys.add(key) + unique_constraints.append(c) + + return marker_to_link, link_markers, unique_constraints, issues, marker_meta + + +# =================================================================== +# Observation quality / weighting +# =================================================================== + +def _optional_float(meta: Dict[str, Any], keys: List[str]) -> Optional[float]: + for k in keys: + if k in meta and meta[k] is not None: + try: + return float(meta[k]) + except Exception: + pass + return None + + +def detection_quality_from_metadata(det_obj: Dict[str, Any], cfg: ConstraintRuleConfig) -> float: + q = 1.0 + + if cfg.use_detection_confidence: + conf = _optional_float(det_obj, ["confidence", "score", "quality", "det_confidence"]) + if conf is not None: + q *= clamp(conf, 0.1, 1.0) + + if cfg.use_detection_size_px: + size_px = _optional_float(det_obj, ["size_px", "marker_size_px", "side_px", "side_length_px"]) + if size_px is None and "corners_px" in det_obj and isinstance(det_obj["corners_px"], list): + try: + corners = np.asarray(det_obj["corners_px"], dtype=np.float64).reshape(-1, 2) + if len(corners) >= 4: + edges = [] + for i in range(len(corners)): + p = corners[i] + q2 = corners[(i + 1) % len(corners)] + edges.append(float(np.linalg.norm(q2 - p))) + size_px = float(np.mean(edges)) + except Exception: + size_px = None + if size_px is not None: + q *= clamp(size_px / max(cfg.ref_marker_size_px, 1e-6), 0.25, 3.0) + + sharpness = _optional_float(det_obj, ["sharpness", "corner_sharpness"]) + if sharpness is not None: + q *= clamp(sharpness / 2500.0, 0.5, 1.5) + + normal_alignment = _optional_float(det_obj, ["normal_alignment", "view_cosine", "cos_to_camera"]) + if normal_alignment is not None: + q *= clamp(normal_alignment, 0.3, 1.0) + + return float(q) + + +def marker_size_prior_factor(marker_meta: Dict[str, Any], default_marker_size_m: float) -> float: + size_val = marker_meta.get("size", None) + if size_val is None: + return 1.0 + + try: + size_val = float(size_val) + except Exception: + return 1.0 + + size_m = size_val / 1000.0 if size_val > 1.0 else size_val + ref = max(default_marker_size_m, 1e-6) + return clamp(size_m / ref, 0.7, 1.3) + + +def compute_observation_weights( + marker_observations: Dict[int, List[Observation]], + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]], + initial_positions: Dict[int, np.ndarray], + marker_meta: Dict[int, Dict[str, Any]], + cfg: ConstraintRuleConfig, + robot_data: Dict[str, Any] +) -> Dict[Tuple[int, int], float]: + weights: Dict[Tuple[int, int], float] = {} + default_marker_size_m = get_vision_marker_size_default(robot_data) + + for marker_id, obs_list in marker_observations.items(): + X = initial_positions.get(marker_id, None) + size_prior = marker_size_prior_factor(marker_meta.get(marker_id, {}), default_marker_size_m) + + for obs_idx, obs in enumerate(obs_list): + w = 1.0 + q = detection_quality_from_metadata(obs.meta, cfg) + w *= q + + if cfg.use_marker_size_prior: + w *= size_prior + + if cfg.use_initial_range and X is not None: + _, _, R_wc, t_wc = cameras[obs.cam_idx] + C = camera_center_from_world_to_cam(R_wc, t_wc) + dist = float(np.linalg.norm(X - C)) + if np.isfinite(dist): + w *= clamp(cfg.ref_distance_m / max(dist, 1e-6), 0.4, 2.0) + + weights[(marker_id, obs_idx)] = clamp(w, cfg.weight_floor, cfg.weight_ceiling) + + return weights + + +# =================================================================== +# Multi-view loading +# =================================================================== + +def load_observations_and_poses( + detection_files: List[str], + pose_files: List[str] +) -> Tuple[ + Dict[int, List[Observation]], + List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]], + List[Dict[str, Any]] +]: + if len(detection_files) != len(pose_files): + raise ValueError(f"Mismatch: {len(detection_files)} detections vs {len(pose_files)} poses") + + marker_observations: Dict[int, List[Observation]] = {} + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]] = [] + obs_metadata: List[Dict[str, Any]] = [] + + for cam_idx, (det_file, pose_file) in enumerate(zip(detection_files, pose_files)): + det = load_json(det_file) + pose_data = load_json(pose_file) + + cam_section = det.get("camera", {}) or {} + K = np.array(cam_section.get("camera_matrix", []), dtype=np.float64).reshape(3, 3) + D = np.array(cam_section.get("distortion_coefficients", []), dtype=np.float64).reshape(-1, 1) + + pose_section = pose_data.get("camera_pose", {}) or {} + world_to_cam = pose_section.get("world_to_camera", {}) or {} + R_wc = np.array(world_to_cam.get("rotation_matrix", []), dtype=np.float64).reshape(3, 3) + t_wc = np.array(world_to_cam.get("translation_m", []), dtype=np.float64).reshape(3) + + cameras.append((K, D, R_wc, t_wc)) + + detections = det.get("detections", []) or [] + for det_obj in detections: + marker_id = int(det_obj.get("marker_id", -1)) + if marker_id < 0: + continue + + center_px = np.array(det_obj.get("center_px", []), dtype=np.float64) + if center_px.shape != (2,): + continue + + pts = center_px.reshape(1, 1, 2).astype(np.float32) + und = cv2.undistortPoints(pts, K.astype(np.float32), D.astype(np.float32), P=None) + norm_coords = und.reshape(2).astype(np.float64) + + obs = Observation(cam_idx=cam_idx, norm_coords=norm_coords, meta=dict(det_obj)) + marker_observations.setdefault(marker_id, []).append(obs) + + obs_metadata.append( + { + "detection_file": det_file, + "pose_file": pose_file, + "num_detections": len(detections), + } + ) + + return marker_observations, cameras, obs_metadata + + +# =================================================================== +# Initial triangulation +# =================================================================== + +def triangulate_marker_initial( + marker_id: int, + observations: List[Observation], + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]] +) -> Optional[np.ndarray]: + if len(observations) < 2: + return None + + best_pair = None + best_baseline = -1.0 + + for obs_i, obs_j in combinations(observations, 2): + cam_i, cam_j = obs_i.cam_idx, obs_j.cam_idx + _, _, R1, t1 = cameras[cam_i] + _, _, R2, t2 = cameras[cam_j] + c1 = camera_center_from_world_to_cam(R1, t1) + c2 = camera_center_from_world_to_cam(R2, t2) + baseline = float(np.linalg.norm(c2 - c1)) + if baseline > best_baseline: + best_baseline = baseline + best_pair = (obs_i, obs_j) + + if best_pair is None: + return None + + obs_i, obs_j = best_pair + cam_i, cam_j = obs_i.cam_idx, obs_j.cam_idx + norm_coords_i = obs_i.norm_coords + norm_coords_j = obs_j.norm_coords + + K1, D1, R1, t1 = cameras[cam_i] + K2, D2, R2, t2 = cameras[cam_j] + + x1_px = K1[0, 0] * norm_coords_i[0] + K1[0, 2] + y1_px = K1[1, 1] * norm_coords_i[1] + K1[1, 2] + x2_px = K2[0, 0] * norm_coords_j[0] + K2[0, 2] + y2_px = K2[1, 1] * norm_coords_j[1] + K2[1, 2] + + P1 = K1 @ np.hstack([R1, t1.reshape(3, 1)]) + P2 = K2 @ np.hstack([R2, t2.reshape(3, 1)]) + + try: + X_h = cv2.triangulatePoints( + P1, + P2, + np.array([[x1_px], [y1_px]], dtype=np.float64), + np.array([[x2_px], [y2_px]], dtype=np.float64), + ) + X = (X_h[:3] / X_h[3]).reshape(3).astype(np.float64) + if not np.all(np.isfinite(X)): + return None + return X + except Exception: + return None + + +def initial_triangulation( + marker_observations: Dict[int, List[Observation]], + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]] +) -> Dict[int, np.ndarray]: + triangulated: Dict[int, np.ndarray] = {} + for marker_id, observations in marker_observations.items(): + X = triangulate_marker_initial(marker_id, observations, cameras) + if X is not None: + triangulated[marker_id] = X + return triangulated + + +# =================================================================== +# Weighted residuals / optimization +# =================================================================== + +def bundle_adjustment_residuals( + marker_positions_flat: np.ndarray, + marker_ids: List[int], + marker_observations: Dict[int, List[Observation]], + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]], + constraints: List[Constraint], + obs_weights: Dict[Tuple[int, int], float], + lambda_constraint: float = 100.0 +) -> np.ndarray: + marker_dict: Dict[int, np.ndarray] = {} + for i, marker_id in enumerate(marker_ids): + marker_dict[marker_id] = marker_positions_flat[i * 3:(i + 1) * 3] + + residuals: List[float] = [] + + for marker_id, observations in marker_observations.items(): + if marker_id not in marker_dict: + continue + + X_world = marker_dict[marker_id] + for obs_idx, obs in enumerate(observations): + cam_idx, norm_coords_obs = obs.cam_idx, obs.norm_coords + K, D, R_wc, t_wc = cameras[cam_idx] + X_cam = R_wc @ X_world + t_wc + if X_cam[2] > 1e-6: + proj_norm = X_cam[:2] / X_cam[2] + r = proj_norm - norm_coords_obs + w = float(np.sqrt(obs_weights.get((marker_id, obs_idx), 1.0))) + residuals.append(w * float(r[0])) + residuals.append(w * float(r[1])) + + for constraint in constraints: + if isinstance(constraint, MarkerDistanceConstraint): + if constraint.marker_id_a in marker_dict and constraint.marker_id_b in marker_dict: + pos_a = marker_dict[constraint.marker_id_a] + pos_b = marker_dict[constraint.marker_id_b] + actual_dist = float(np.linalg.norm(pos_b - pos_a)) + residuals.append((actual_dist - constraint.target_distance_m) * constraint.weight * lambda_constraint) + + elif isinstance(constraint, JointAxisConstraint): + if constraint.marker_id_parent in marker_dict and constraint.marker_id_child in marker_dict: + pos_parent = marker_dict[constraint.marker_id_parent] + pos_child = marker_dict[constraint.marker_id_child] + delta = pos_child - pos_parent + actual_delta = float(np.dot(delta, constraint.joint_axis)) + residuals.append((actual_delta - constraint.target_delta_along_axis_m) * constraint.weight * lambda_constraint) + + return np.asarray(residuals, dtype=np.float64) + + +def optimize_with_constraints( + initial_positions: Dict[int, np.ndarray], + marker_observations: Dict[int, List[Observation]], + cameras: List[Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]], + constraints: List[Constraint], + obs_weights: Dict[Tuple[int, int], float], + lambda_constraint: float = 100.0, + max_iterations: int = 50 +) -> Dict[int, np.ndarray]: + try: + from scipy.optimize import least_squares + except ImportError: + print("[WARN] scipy not available, skipping optimization.") + return initial_positions + + marker_ids = sorted(initial_positions.keys()) + if not marker_ids: + return {} + + x0 = np.concatenate([initial_positions[mid] for mid in marker_ids]) + + def residuals_fn(x: np.ndarray) -> np.ndarray: + return bundle_adjustment_residuals( + x, marker_ids, marker_observations, cameras, constraints, obs_weights, lambda_constraint + ) + + print(f"[INFO] Starting optimization with {len(x0)} variables and {len(constraints)} constraints...") + + result = least_squares( + residuals_fn, + x0, + max_nfev=max_iterations * max(1, len(marker_ids)), + verbose=1, + ) + + optimized = {} + for i, marker_id in enumerate(marker_ids): + optimized[marker_id] = result.x[i * 3:(i + 1) * 3] + + print(f"[INFO] Optimization complete. Final cost: {float(np.sum(result.fun ** 2)):.6f}") + return optimized + + +# =================================================================== +# Reporting helpers +# =================================================================== + +def print_constraint_summary(constraints: List[Constraint]) -> None: + num_dist = sum(isinstance(c, MarkerDistanceConstraint) for c in constraints) + num_joint = sum(isinstance(c, JointAxisConstraint) for c in constraints) + num_other = len(constraints) - num_dist - num_joint + extra = f" other={num_other}" if num_other else "" + print(f"[INFO] Constraint summary: total={len(constraints)} distance={num_dist} joint/chain={num_joint}{extra}") + + +def print_constraint_list(constraints: List[Constraint]) -> None: + print("\n[INFO] Constraint list:") + for idx, constraint in enumerate(constraints): + if isinstance(constraint, MarkerDistanceConstraint): + print( + f" [{idx:03d}] DISTANCE | " + f"Link='{constraint.link_name}' | " + f"M{constraint.marker_id_a} <-> M{constraint.marker_id_b} | " + f"Target={constraint.target_distance_m:.6f} m | " + f"Weight={constraint.weight} | " + f"Source={constraint.source}" + ) + elif isinstance(constraint, JointAxisConstraint): + axis_str = np.array2string(constraint.joint_axis, precision=3, suppress_small=True) + print( + f" [{idx:03d}] JOINT_AXIS | " + f"{constraint.parent_link}(M{constraint.marker_id_parent}) -> " + f"{constraint.child_link}(M{constraint.marker_id_child}) | " + f"Axis={axis_str} | " + f"TargetDelta={constraint.target_delta_along_axis_m:.6f} m | " + f"Weight={constraint.weight} | " + f"Source={constraint.source}" + ) + else: + print( + f" [{idx:03d}] {type(constraint).__name__} | " + f"weight={getattr(constraint, 'weight', '?')} | " + f"source={getattr(constraint, 'source', '?')}" + ) + + +def print_constraints_with_errors( + title: str, + constraints: List[Constraint], + positions: Dict[int, np.ndarray], + show_skipped: bool = True +) -> None: + print(f"\n[INFO] {title}") + + active = 0 + skipped = 0 + + for idx, constraint in enumerate(constraints): + if isinstance(constraint, MarkerDistanceConstraint): + if constraint.marker_id_a not in positions or constraint.marker_id_b not in positions: + skipped += 1 + if show_skipped: + print( + f" [{idx:03d}] DISTANCE | " + f"M{constraint.marker_id_a} <-> M{constraint.marker_id_b} | SKIPPED (missing marker)" + ) + continue + + pos_a = positions[constraint.marker_id_a] + pos_b = positions[constraint.marker_id_b] + actual = float(np.linalg.norm(pos_b - pos_a)) + error = actual - constraint.target_distance_m + active += 1 + + print( + f" [{idx:03d}] DISTANCE | " + f"Link='{constraint.link_name}' | " + f"M{constraint.marker_id_a} <-> M{constraint.marker_id_b} | " + f"target={constraint.target_distance_m*1000:.2f} mm | " + f"actual={actual*1000:.2f} mm | " + f"error={error*1000:+.2f} mm" + ) + + elif isinstance(constraint, JointAxisConstraint): + if constraint.marker_id_parent not in positions or constraint.marker_id_child not in positions: + skipped += 1 + if show_skipped: + print( + f" [{idx:03d}] JOINT_AXIS | " + f"M{constraint.marker_id_parent} -> M{constraint.marker_id_child} | SKIPPED (missing marker)" + ) + continue + + pos_parent = positions[constraint.marker_id_parent] + pos_child = positions[constraint.marker_id_child] + delta = pos_child - pos_parent + actual = float(np.dot(delta, constraint.joint_axis)) + error = actual - constraint.target_delta_along_axis_m + active += 1 + + axis_str = np.array2string(constraint.joint_axis, precision=2, suppress_small=True) + print( + f" [{idx:03d}] JOINT_AXIS | " + f"{constraint.parent_link}(M{constraint.marker_id_parent}) -> " + f"{constraint.child_link}(M{constraint.marker_id_child}) | " + f"axis={axis_str} | " + f"target={constraint.target_delta_along_axis_m*1000:.2f} mm | " + f"actual={actual*1000:.2f} mm | " + f"error={error*1000:+.2f} mm" + ) + + print(f"[INFO] Active constraints: {active} | Skipped: {skipped}") + + +def print_observation_weight_summary(obs_weights: Dict[Tuple[int, int], float]) -> None: + if not obs_weights: + print("[INFO] Observation weighting: disabled or empty") + return + values = np.array(list(obs_weights.values()), dtype=np.float64) + print( + "[INFO] Observation weights: " + f"min={values.min():.3f} mean={values.mean():.3f} " + f"median={np.median(values):.3f} max={values.max():.3f}" + ) + + +def serialize_vec3(v: Any) -> List[float]: + arr = np.asarray(v, dtype=np.float64).reshape(3) + n = np.linalg.norm(arr) + if n > 1e-12: + arr = arr / n + return [float(x) for x in arr] + + +# =================================================================== +# Main +# =================================================================== + +def main() -> None: + parser = argparse.ArgumentParser( + description="Multi-view bundle adjustment with rule-based geometric constraints" + ) + parser.add_argument( + "-det", "--detections", + action="append", + required=True, + help="*_aruco_detection.json files" + ) + parser.add_argument( + "-pose", "--poses", + action="append", + required=True, + help="*_camera_pose.json files" + ) + parser.add_argument( + "-robot", "--robot", + required=True, + help="robot.json" + ) + parser.add_argument( + "-outDir", "--outDir", + default=None, + help="Output directory" + ) + parser.add_argument( + "-lambdaWeight", "--lambdaWeight", + type=float, + default=100.0, + help="Constraint weight multiplier" + ) + parser.add_argument( + "--strictUniqueMarkerIds", + action="store_true", + help="Fail if a marker ID appears more than once in robot.json" + ) + parser.add_argument( + "--showSkippedConstraints", + action="store_true", + help="Print skipped constraints in the report" + ) + parser.add_argument( + "--noShowSkippedConstraints", + action="store_true", + help="Hide skipped constraints in the report" + ) + parser.add_argument( + "--saveConstraintReport", + action="store_true", + help="Save constraint report JSON files" + ) + parser.add_argument( + "--saveObservationWeightReport", + action="store_true", + help="Save observation-weight report JSON file" + ) + + args = parser.parse_args() + + if args.showSkippedConstraints and args.noShowSkippedConstraints: + print("[ERROR] Choose only one of --showSkippedConstraints or --noShowSkippedConstraints") + sys.exit(1) + + if len(args.detections) != len(args.poses): + print(f"[ERROR] Mismatch: {len(args.detections)} detection files vs {len(args.poses)} pose files") + sys.exit(1) + + robot_data = load_json(args.robot) + length_scale = get_length_scale(robot_data) + cfg = load_constraint_rule_config(robot_data, args) + + print("[STEP 1] Compile constraints from robot.json structure...") + print( + "[INFO] Constraint families: " + f"rigid_distance={'on' if cfg.rigid_distance_enabled else 'off'}, " + f"revolute={'on' if cfg.revolute_axis_enabled else 'off'}, " + f"prismatic={'on' if cfg.prismatic_orthogonal_enabled else 'off'}, " + f"chain_legacy={'on' if cfg.chain_axis_enabled else 'off'}, " + f"observation_weights={'on' if cfg.enable_observation_weights else 'off'}" + ) + marker_to_link, link_markers, constraints, issues, marker_meta = compile_constraints(robot_data, length_scale, cfg) + + for issue in issues: + print(issue) + + print(f"[INFO] Links with markers: {sum(1 for v in link_markers.values() if len(v) > 0)}") + print(f"[INFO] Unique marker IDs: {len(marker_to_link)}") + print_constraint_summary(constraints) + print_constraint_list(constraints) + + print("\n[STEP 2] Load observations and camera poses...") + marker_observations, cameras, obs_metadata = load_observations_and_poses(args.detections, args.poses) + print(f"[INFO] {len(cameras)} cameras, {len(marker_observations)} observed markers") + print(f"[INFO] Detection files loaded: {len(obs_metadata)}") + + print("\n[STEP 3] Initial triangulation...") + initial_pos = initial_triangulation(marker_observations, cameras) + print(f"[INFO] Triangulated {len(initial_pos)} markers") + + out_dir = args.outDir or os.path.dirname(args.detections[0]) or "." + os.makedirs(resolve_path(out_dir), exist_ok=True) + + # camera poses in world (for viewer frusta): centre C = -R^T t, view axis = R[2] + cameras_section = [] + for idx, (K, D, R_wc, t_wc) in enumerate(cameras): + C = -R_wc.T @ t_wc + cam_id = str(idx) + base = os.path.basename(str(obs_metadata[idx].get("pose_file", ""))) if idx < len(obs_metadata) else "" + if base.startswith("render_") and "_camera_pose" in base: + cam_id = base[len("render_"):base.index("_camera_pose")] + cameras_section.append({ + "camera_id": cam_id, + "position_m": [float(v) for v in C], + "position_mm": [float(v * 1000.0) for v in C], + "direction": [float(v) for v in R_wc[2]], + }) + + initial_output_markers = [] + for marker_id, position in sorted(initial_pos.items()): + normal = marker_meta.get(marker_id, {}).get("normal", None) + initial_output_markers.append( + { + "marker_id": int(marker_id), + "position_m": [float(x) for x in position], + "position_mm": [float(x * 1000.0) for x in position], + "link": marker_to_link.get(marker_id, "unknown"), + "normal": serialize_vec3(normal) if normal is not None else None, + } + ) + + initial_output = { + "schema_version": "1.2", + "stage": "initial_triangulation", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "summary": { + "num_cameras": len(cameras), + "num_markers": len(initial_pos), + "num_constraints": len(constraints), + }, + "cameras": cameras_section, + "markers": initial_output_markers, + } + initial_out_file = os.path.join(out_dir, "aruco_positions_initial.json") + save_json(initial_out_file, initial_output) + print(f"[INFO] Initial triangulation saved to {initial_out_file}") + + obs_weights = compute_observation_weights( + marker_observations=marker_observations, + cameras=cameras, + initial_positions=initial_pos, + marker_meta=marker_meta, + cfg=cfg, + robot_data=robot_data, + ) + print_observation_weight_summary(obs_weights) + + print_constraints_with_errors( + "Constraint list BEFORE optimization", + constraints, + initial_pos, + show_skipped=cfg.show_skipped_constraints, + ) + + print("\n[STEP 4] Bundle adjustment with constraints...") + optimized_pos = optimize_with_constraints( + initial_pos, + marker_observations, + cameras, + constraints, + obs_weights, + lambda_constraint=args.lambdaWeight, + ) + + print_constraints_with_errors( + "Constraint list AFTER optimization", + constraints, + optimized_pos, + show_skipped=cfg.show_skipped_constraints, + ) + + output_markers = [] + for marker_id, position in sorted(optimized_pos.items()): + normal = marker_meta.get(marker_id, {}).get("normal", None) + output_markers.append( + { + "marker_id": int(marker_id), + "position_m": [float(x) for x in position], + "position_mm": [float(x * 1000.0) for x in position], + "link": marker_to_link.get(marker_id, "unknown"), + "normal": serialize_vec3(normal) if normal is not None else None, + } + ) + + output = { + "schema_version": "1.2", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "summary": { + "num_cameras": len(cameras), + "num_markers": len(optimized_pos), + "num_constraints": len(constraints), + }, + "cameras": cameras_section, + "markers": output_markers, + } + out_file = os.path.join(out_dir, "aruco_positions_optimized.json") + save_json(out_file, output) + print(f"\n[INFO] Saved to {out_file}") + + if args.saveConstraintReport: + report = { + "schema_version": "1.0", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "summary": { + "num_constraints": len(constraints), + "num_links_with_markers": sum(1 for v in link_markers.values() if len(v) > 0), + "num_observed_markers": len(marker_observations), + "num_triangulated_markers": len(initial_pos), + "num_optimized_markers": len(optimized_pos), + }, + "constraints": [], + } + for c in constraints: + if isinstance(c, MarkerDistanceConstraint): + report["constraints"].append( + { + "kind": "distance", + "link_name": c.link_name, + "marker_id_a": c.marker_id_a, + "marker_id_b": c.marker_id_b, + "target_distance_m": c.target_distance_m, + "weight": c.weight, + "source": c.source, + } + ) + else: + report["constraints"].append( + { + "kind": "joint_axis", + "parent_link": c.parent_link, + "child_link": c.child_link, + "marker_id_parent": c.marker_id_parent, + "marker_id_child": c.marker_id_child, + "joint_axis": [float(x) for x in c.joint_axis], + "target_delta_along_axis_m": c.target_delta_along_axis_m, + "weight": c.weight, + "source": c.source, + } + ) + report_file = os.path.join(out_dir, "constraint_report.json") + save_json(report_file, report) + print(f"[INFO] Constraint report saved to {report_file}") + + if args.saveObservationWeightReport: + obs_report = { + "schema_version": "1.0", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "summary": { + "num_weighted_observations": len(obs_weights), + }, + "observation_weights": [ + { + "marker_id": int(mid), + "observation_index": int(obs_idx), + "weight": float(w), + } + for (mid, obs_idx), w in sorted(obs_weights.items()) + ], + } + obs_file = os.path.join(out_dir, "observation_weight_report.json") + save_json(obs_file, obs_report) + print(f"[INFO] Observation-weight report saved to {obs_file}") + + +if __name__ == "__main__": + main() diff --git a/scripts/pipeline/3b_corner_marker_poses.py b/scripts/pipeline/3b_corner_marker_poses.py new file mode 100644 index 0000000..f02fd5e --- /dev/null +++ b/scripts/pipeline/3b_corner_marker_poses.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +""" +3b_corner_marker_poses.py +========================= +Produktiver Pipeline-Schritt: leitet aus den 4 ArUco-Ecken jedes Markers eine +volle Marker-Pose ab (Position + gemessene Normale), statt nur den Center zu +triangulieren. + +Validiert in benchmark/stage0_corner_normals.py: die aus triangulierten Ecken +abgeleitete Normale ist ~1 deg genau (Median), auch fuer Finger-Marker. + +Input: + --evalDir Ordner mit render_*_aruco_detection.json + _camera_pose.json + --robot robot.json (fuer marker_id -> link Zuordnung) +Output: + /aruco_marker_poses.json (pro Marker: position, gemessene normal, + 4 triangulierte Ecken, #Kameras, Kantenlaenge) + +Das Format ist kompatibel mit robot_viewer.html (marker_id, position_m/mm, normal) +und mit 9_evaluateMarker.py (position_m), erweitert um die gemessene Orientierung. +""" +from __future__ import annotations + +import argparse +import glob +import json +import os +import re +import time +from typing import Dict, List, Tuple + +import numpy as np +import cv2 + + +# ------------------------------------------------------------------ +# Loading +# ------------------------------------------------------------------ + +def load_cameras(eval_dir: str) -> Dict[str, dict]: + cams: Dict[str, dict] = {} + for det_path in glob.glob(os.path.join(eval_dir, "*_aruco_detection.json")): + base = os.path.basename(det_path) + m = re.match(r"render_([A-Za-z0-9]+)_aruco_detection\.json", base) + if not m: + continue + cam_id = m.group(1) + pose_path = os.path.join(eval_dir, f"render_{cam_id}_camera_pose.json") + if not os.path.exists(pose_path): + print(f"[WARN] no pose for camera {cam_id}, skipping") + continue + det = json.load(open(det_path, "r", encoding="utf-8")) + pose = json.load(open(pose_path, "r", encoding="utf-8")) + K = np.array(det["camera"]["camera_matrix"], dtype=float).reshape(3, 3) + D = np.array(det["camera"]["distortion_coefficients"], dtype=float).reshape(-1, 1) + w2c = pose["camera_pose"]["world_to_camera"] + R = np.array(w2c["rotation_matrix"], dtype=float).reshape(3, 3) + t = np.array(w2c["translation_m"], dtype=float).reshape(3) + markers: Dict[int, np.ndarray] = {} + for d in det.get("detections", []): + pts = d.get("image_points_px") + if pts is not None: + markers[int(d["marker_id"])] = np.array(pts, dtype=float).reshape(4, 2) + cams[cam_id] = dict(K=K, D=D, R=R, t=t, markers=markers) + return cams + + +def load_marker_links(robot_path: str) -> Dict[int, str]: + robot = json.load(open(robot_path, "r", encoding="utf-8")) + out: Dict[int, str] = {} + for link_name, link in (robot.get("links", {}) or {}).items(): + for mk in link.get("markers", []) or []: + mid = int(mk.get("id", -1)) + if mid >= 0: + out[mid] = link_name + return out + + +# ------------------------------------------------------------------ +# Geometry (validated in stage0) +# ------------------------------------------------------------------ + +def triangulate_multiview(observations) -> np.ndarray: + A = [] + for K, D, R, t, uv in observations: + und = cv2.undistortPoints(np.array([[uv]], dtype=np.float32), K, D).reshape(2) + x, y = float(und[0]), float(und[1]) + P = np.hstack([R, t.reshape(3, 1)]) + A.append(x * P[2] - P[0]) + A.append(y * P[2] - P[1]) + _, _, Vt = np.linalg.svd(np.asarray(A, dtype=float)) + X = Vt[-1] + return np.array([np.nan] * 3) if abs(X[3]) < 1e-12 else X[:3] / X[3] + + +def corner_plane_normal(corners3d: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + center = corners3d.mean(axis=0) + _, _, Vt = np.linalg.svd(corners3d - center) + n = Vt[-1] + # ArUco corners clockwise from the front: outward (camera-facing) normal, + # matching the Blender/robot.json convention, points opposite cross(e01,e02). + cross = np.cross(corners3d[1] - corners3d[0], corners3d[2] - corners3d[0]) + if np.dot(n, cross) > 0: + n = -n + nn = np.linalg.norm(n) + return (n / nn if nn > 1e-12 else n), center + + +# ------------------------------------------------------------------ +# Main +# ------------------------------------------------------------------ + +def main() -> None: + ap = argparse.ArgumentParser(description="Derive marker poses (position + measured normal) from ArUco corners") + ap.add_argument("--evalDir", required=True, help="folder with detection + camera_pose JSONs") + ap.add_argument("--robot", required=True, help="robot.json (for marker->link)") + ap.add_argument("--minCams", type=int, default=2, help="min cameras to triangulate a marker") + ap.add_argument("--out", default=None, help="output path (default /aruco_marker_poses.json)") + args = ap.parse_args() + + cams = load_cameras(args.evalDir) + if len(cams) < 2: + print("[ERROR] need >=2 cameras") + return + links = load_marker_links(args.robot) + print(f"[INFO] Cameras: {sorted(cams.keys())} | marker-link entries: {len(links)}") + + marker_cams: Dict[int, List[str]] = {} + for cid, cam in cams.items(): + for mid in cam["markers"]: + marker_cams.setdefault(mid, []).append(cid) + + markers_out = [] + for mid, cam_ids in sorted(marker_cams.items()): + if len(cam_ids) < args.minCams: + continue + corners3d, ok = [], True + for ci in range(4): + obs = [(cams[c]["K"], cams[c]["D"], cams[c]["R"], cams[c]["t"], cams[c]["markers"][mid][ci]) + for c in cam_ids] + X = triangulate_multiview(obs) + if not np.all(np.isfinite(X)): + ok = False + break + corners3d.append(X) + if not ok: + continue + corners3d = np.array(corners3d) + normal, center = corner_plane_normal(corners3d) + edge_mm = float(np.mean([np.linalg.norm(corners3d[(i + 1) % 4] - corners3d[i]) for i in range(4)]) * 1000.0) + + markers_out.append({ + "marker_id": int(mid), + "link": links.get(mid, "unknown"), + "position_m": [float(v) for v in center], + "position_mm": [float(v * 1000.0) for v in center], + "normal": [float(v) for v in normal], + "corners_m": [[float(v) for v in c] for c in corners3d], + "num_cameras": len(cam_ids), + "edge_length_mm": edge_mm, + }) + + # camera poses in world (for viewer frusta): centre C = -R^T t, view axis = R[2] + cameras_out = [] + for cid in sorted(cams.keys()): + cam = cams[cid] + C = -cam["R"].T @ cam["t"] + cameras_out.append({ + "camera_id": cid, + "position_m": [float(v) for v in C], + "position_mm": [float(v * 1000.0) for v in C], + "direction": [float(v) for v in cam["R"][2]], + }) + + out_path = args.out or os.path.join(args.evalDir, "aruco_marker_poses.json") + output = { + "schema_version": "1.1", + "stage": "corner_marker_poses", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "summary": {"num_cameras": len(cams), "num_markers": len(markers_out)}, + "cameras": cameras_out, + "markers": markers_out, + } + json.dump(output, open(out_path, "w", encoding="utf-8"), indent=2) + print(f"[INFO] {len(markers_out)} marker poses -> {out_path}") + + +if __name__ == "__main__": + main() diff --git a/scripts/pipeline/__pycache__/robot_fk.cpython-311.pyc b/scripts/pipeline/__pycache__/robot_fk.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8785e8fff073288650e809e959ec6abf60804f0c GIT binary patch literal 17903 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 L|A!4y$$t7jOk&~C literal 0 HcmV?d00001 diff --git a/scripts/pipeline/pose_estimation.py b/scripts/pipeline/pose_estimation.py new file mode 100644 index 0000000..8bf703c --- /dev/null +++ b/scripts/pipeline/pose_estimation.py @@ -0,0 +1,539 @@ +#!/usr/bin/env python3 +""" +pose_estimation.py +================== +Estimate robot joint angles (x, y, z, a, b, c, e) from triangulated marker +poses, using the kinematic model in robot.json (via robot_fk.py). + +Design +------ +The estimator is parametrised over JOINT VARIABLES, not links. This handles the +tricky cases of this robot family generically: + * Links with zero own markers (Base/x, Hand/b, Palm/c) — their variable is + observable only through descendant markers. + * A variable shared by several links (FingerA & FingerB share 'e'). + * Occluded middle links — global BA reconstructs them from the fingers. + +Four switchable methods (robot.json -> pose_estimation.method): + sequential_vector : analytic per joint from marker-pair / normal vectors (fast) + sequential_fk : block-wise least squares along the chain (robust, 1 marker ok) + global_ba : all variables jointly, position + normal residuals, robust loss + hybrid : sequential_fk init -> global_ba refine (default, most stable) + +Observation input: + marker_observation = "corner_pose" -> aruco_marker_poses.json (pos + measured normal) + marker_observation = "center_point" -> aruco_positions_*.json (pos only) + +Both the engine (estimate_pose) and a CLI (main) live here. +""" +from __future__ import annotations + +import argparse +import json +import math +import os +import sys +import time +from collections import defaultdict +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple + +import numpy as np + +sys.path.insert(0, str(Path(__file__).parent)) +from robot_fk import RobotFK, STATE_KEYS # noqa: E402 + +try: + from scipy.optimize import least_squares + HAVE_SCIPY = True +except ImportError: + HAVE_SCIPY = False + + +# ================================================================== +# Config +# ================================================================== + +DEFAULT_CFG: Dict[str, Any] = { + "method": "hybrid", + "marker_observation": "corner_pose", + "use_normals": True, + "normal_weight": 100.0, + "robust_loss": "huber", + "huber_delta_mm": 8.0, + "max_iterations": 200, + "min_cameras_per_marker": 2, + "finger_block_joints": ["b", "c", "e"], + "per_link_method": {}, +} + + +def load_pose_cfg(robot_data: Dict[str, Any]) -> Dict[str, Any]: + cfg = dict(DEFAULT_CFG) + cfg.update(robot_data.get("pose_estimation", {}) or {}) + return cfg + + +# ================================================================== +# Observations +# ================================================================== + +def load_observations(path: str, use_normals: bool, min_cams: int = 2) -> Dict[int, Dict[str, Any]]: + """ + Load marker observations. Accepts aruco_marker_poses.json (with measured + normal + num_cameras) or aruco_positions_*.json (position only). + Returns: marker_id -> {pos_mm:(3,), normal:(3,)|None, link:str, n_cams:int} + """ + data = json.load(open(path, "r", encoding="utf-8")) + out: Dict[int, Dict[str, Any]] = {} + for m in data.get("markers", []): + mid = int(m.get("marker_id", m.get("id", -1))) + if mid < 0: + continue + n_cams = int(m.get("num_cameras", 99)) + if n_cams < min_cams: + continue + if "position_mm" in m: + pos = np.array(m["position_mm"], dtype=float) + elif "position_m" in m: + pos = np.array(m["position_m"], dtype=float) * 1000.0 + else: + continue + nrm = None + if use_normals and m.get("normal") is not None: + nv = np.array(m["normal"], dtype=float) + nn = np.linalg.norm(nv) + if nn > 1e-9: + nrm = nv / nn + out[mid] = {"pos_mm": pos, "normal": nrm, "link": m.get("link", "?"), "n_cams": n_cams} + return out + + +# ================================================================== +# Kinematic chain analysis +# ================================================================== + +def analyze_chain(fk: RobotFK) -> Dict[str, Any]: + """ + Derive, generically from the FK topology: + ordered_vars : movable joint variables, root->tip order, de-duplicated + var_links : variable -> list of links it drives + link_markers : link -> [model marker ids] + blocks : sequential estimation blocks; each block groups the + zero-marker ancestor variables with the next marker- + bearing joint variable, estimated from that link's own + markers (+ siblings sharing the same variable). + """ + links = fk.links + topo = fk._topo + + link_markers: Dict[str, List[int]] = {} + for ln, ld in links.items(): + ids = [] + for mk in ld.get("markers", []) or []: + if "id" in mk and "position" in mk: + ids.append(int(mk["id"])) + link_markers[ln] = ids + + link_var: Dict[str, str] = {} + for ln, ld in links.items(): + j = ld.get("jointToParent", {}) or {} + if str(j.get("type", "")).lower() in ("revolute", "linear"): + v = str(j.get("variable", "")).lower() + if v: + link_var[ln] = v + + var_type: Dict[str, str] = {} + var_links: Dict[str, List[str]] = defaultdict(list) + for ln, v in link_var.items(): + var_links[v].append(ln) + var_type[v] = str(links[ln].get("jointToParent", {}).get("type", "")).lower() + + ordered_vars: List[str] = [] + for ln in topo: + if ln in link_var and link_var[ln] not in ordered_vars: + ordered_vars.append(link_var[ln]) + + # ---- build blocks ---- + blocks: List[Dict[str, Any]] = [] + var_block: Dict[str, int] = {} + pending: List[str] = [] + for ln in topo: + if ln not in link_var: + continue + v = link_var[ln] + own = link_markers.get(ln, []) + if v in var_block: + # shared variable already in a block -> add this link's markers there + if own: + blocks[var_block[v]]["markers"].extend(own) + continue + if own: + bvars = [] + for x in pending + [v]: + if x not in bvars and x not in var_block: + bvars.append(x) + blocks.append({"vars": bvars, "markers": list(own), "anchor": ln}) + for x in bvars: + var_block[x] = len(blocks) - 1 + pending = [] + else: + if v not in pending: + pending.append(v) + if pending: + blocks.append({"vars": pending, "markers": [], "anchor": None}) + for x in pending: + var_block[x] = len(blocks) - 1 + + return { + "ordered_vars": ordered_vars, + "var_type": var_type, + "var_links": dict(var_links), + "link_markers": link_markers, + "blocks": blocks, + } + + +# ================================================================== +# Residuals +# ================================================================== + +def model_markers(fk: RobotFK, state: Dict[str, float]) -> Dict[int, Dict[str, np.ndarray]]: + T = fk.compute(state) + return fk.all_markers_world(T) # mid -> {world_mm, normal_world, link, local_mm} + + +def residual_vector(state: Dict[str, float], fk: RobotFK, obs: Dict[int, Dict[str, Any]], + marker_ids: List[int], cfg: Dict[str, Any]) -> np.ndarray: + """Position (mm) + optional normal (scaled) residuals over the given markers.""" + model = model_markers(fk, state) + res: List[float] = [] + w_n = float(cfg.get("normal_weight", 30.0)) + use_n = bool(cfg.get("use_normals", True)) + for mid in marker_ids: + if mid not in model or mid not in obs: + continue + mm = model[mid] + dp = np.asarray(mm["world_mm"], float) - obs[mid]["pos_mm"] + res.extend(dp.tolist()) + if use_n and obs[mid]["normal"] is not None and "normal_world" in mm: + dn = (np.asarray(mm["normal_world"], float) - obs[mid]["normal"]) * w_n + res.extend(dn.tolist()) + return np.asarray(res, dtype=float) + + +def _state_from_vec(var_names: List[str], vec: np.ndarray, base: Dict[str, float]) -> Dict[str, float]: + s = dict(base) + for name, val in zip(var_names, vec): + s[name] = float(val) + return s + + +# ================================================================== +# Method: global bundle adjustment +# ================================================================== + +def estimate_global_ba(fk: RobotFK, obs: Dict[int, Dict[str, Any]], var_names: List[str], + x0: Dict[str, float], cfg: Dict[str, Any]) -> Dict[str, float]: + if not HAVE_SCIPY: + print("[WARN] scipy missing — global_ba skipped, returning init") + return dict(x0) + marker_ids = list(obs.keys()) + base = {k: 0.0 for k in STATE_KEYS} + base.update(x0) + vec0 = np.array([base.get(v, 0.0) for v in var_names], dtype=float) + + def fun(vec): + st = _state_from_vec(var_names, vec, base) + return residual_vector(st, fk, obs, marker_ids, cfg) + + loss = cfg.get("robust_loss", "huber") + f_scale = float(cfg.get("huber_delta_mm", 8.0)) + try: + sol = least_squares(fun, vec0, loss=loss, f_scale=f_scale, + max_nfev=int(cfg.get("max_iterations", 200)) * max(1, len(var_names))) + return _state_from_vec(var_names, sol.x, base) + except Exception as exc: + print(f"[WARN] global_ba failed: {exc}") + return dict(base) + + +# ================================================================== +# Method: sequential block-wise FK fit +# ================================================================== + +def _multistart_values(vtype: str) -> List[float]: + # revolute: scan the circle to escape local minima at large angles + if vtype == "revolute": + return [0.0, 60.0, 120.0, 180.0, 240.0, 300.0] + return [0.0] + + +def estimate_sequential_fk(fk: RobotFK, obs: Dict[int, Dict[str, Any]], chain: Dict[str, Any], + cfg: Dict[str, Any]) -> Dict[str, float]: + """Estimate block by block along the chain, freezing already-solved variables.""" + state = {k: 0.0 for k in STATE_KEYS} + var_type = chain["var_type"] + + for block in chain["blocks"]: + bvars = block["vars"] + bmarkers = [m for m in block["markers"] if m in obs] + if not bvars: + continue + if not bmarkers: + # unobservable block: leave at 0, flag later + continue + + if not HAVE_SCIPY: + continue + + base = dict(state) + + def fun(vec, _bvars=bvars, _bm=bmarkers, _base=base): + st = _state_from_vec(_bvars, vec, _base) + return residual_vector(st, fk, obs, _bm, cfg) + + # multi-start over the first revolute variable in the block + starts = [[0.0] * len(bvars)] + lead_type = var_type.get(bvars[0], "linear") + if lead_type == "revolute": + starts = [] + for a0 in _multistart_values("revolute"): + s = [0.0] * len(bvars) + s[0] = a0 + starts.append(s) + + best, best_cost = None, float("inf") + for s0 in starts: + try: + sol = least_squares(fun, np.array(s0, dtype=float), + loss=cfg.get("robust_loss", "huber"), + f_scale=float(cfg.get("huber_delta_mm", 8.0)), + max_nfev=200 * max(1, len(bvars))) + if sol.cost < best_cost: + best_cost, best = sol.cost, sol.x + except Exception: + continue + if best is not None: + for name, val in zip(bvars, best): + state[name] = float(val) + + # wrap revolute angles to (-180, 180] + for v, vt in var_type.items(): + if vt == "revolute": + state[v] = (state[v] + 180.0) % 360.0 - 180.0 + return state + + +# ================================================================== +# Method: sequential analytic vector (per revolute joint) +# ================================================================== + +def estimate_sequential_vector(fk: RobotFK, obs: Dict[int, Dict[str, Any]], chain: Dict[str, Any], + cfg: Dict[str, Any]) -> Dict[str, float]: + """ + Analytic angle from marker geometry where possible. For revolute joints with + >=2 markers on the link, use the perpendicular marker-pair vector. Falls back + to the FK block solver for linear / zero-marker / single-marker cases, so it + always returns a full state (still cheaper than full sequential_fk because + well-populated joints are solved in closed form). + """ + state = {k: 0.0 for k in STATE_KEYS} + var_type = chain["var_type"] + link_markers = chain["link_markers"] + var_links = chain["var_links"] + + for block in chain["blocks"]: + bvars = block["vars"] + if len(bvars) == 1 and var_type.get(bvars[0]) == "revolute": + v = bvars[0] + ln = var_links[v][0] + mids = [m for m in link_markers.get(ln, []) if m in obs] + if len(mids) >= 2: + # model vectors must be expressed in the WORLD frame at angle=0 + # (the link frame is already rotated by the parents y,z,...), so + # use FK marker world positions with this joint set to 0. + state_v0 = dict(state) + state_v0[v] = 0.0 + model_v0 = model_markers(fk, state_v0) + axis_world = fk.joint_axis_world(ln, state_v0) + ang = _angle_from_pairs_world(mids, model_v0, obs, axis_world) + if ang is not None: + state[v] = ang + continue + # fallback: block FK fit for this single block + _fit_single_block(fk, obs, block, var_type, cfg, state) + + for v, vt in var_type.items(): + if vt == "revolute": + state[v] = (state[v] + 180.0) % 360.0 - 180.0 + return state + + +def _angle_from_pairs_world(mids: List[int], model_v0: Dict[int, Dict[str, np.ndarray]], + obs: Dict[int, Dict[str, Any]], axis_world: np.ndarray) -> Optional[float]: + from itertools import combinations + a = np.asarray(axis_world, float) + a = a / (np.linalg.norm(a) + 1e-12) + angs, ws = [], [] + for i, j in combinations(mids, 2): + if i not in model_v0 or j not in model_v0: + continue + vm = np.asarray(model_v0[j]["world_mm"], float) - np.asarray(model_v0[i]["world_mm"], float) # world @ angle 0 + vo = obs[j]["pos_mm"] - obs[i]["pos_mm"] # observed vector (world, mm) + vm_p = vm - np.dot(vm, a) * a + vo_p = vo - np.dot(vo, a) * a + if np.linalg.norm(vm_p) < 5 or np.linalg.norm(vo_p) < 5: + continue + ang = math.atan2(float(np.dot(a, np.cross(vm_p, vo_p))), float(np.dot(vm_p, vo_p))) + angs.append(ang) + ws.append(np.linalg.norm(vm_p) * np.linalg.norm(vo_p)) + if not angs: + return None + s = sum(w * math.sin(x) for w, x in zip(ws, angs)) + c = sum(w * math.cos(x) for w, x in zip(ws, angs)) + return math.degrees(math.atan2(s, c)) + + +def _fit_single_block(fk, obs, block, var_type, cfg, state): + if not HAVE_SCIPY: + return + bvars = block["vars"] + bmarkers = [m for m in block["markers"] if m in obs] + if not bvars or not bmarkers: + return + base = dict(state) + + def fun(vec): + return residual_vector(_state_from_vec(bvars, vec, base), fk, obs, bmarkers, cfg) + + starts = [[0.0] * len(bvars)] + if var_type.get(bvars[0]) == "revolute": + starts = [[a0] + [0.0] * (len(bvars) - 1) for a0 in _multistart_values("revolute")] + best, best_cost = None, float("inf") + for s0 in starts: + try: + sol = least_squares(fun, np.array(s0, float), loss=cfg.get("robust_loss", "huber"), + f_scale=float(cfg.get("huber_delta_mm", 8.0)), max_nfev=200 * max(1, len(bvars))) + if sol.cost < best_cost: + best_cost, best = sol.cost, sol.x + except Exception: + continue + if best is not None: + for name, val in zip(bvars, best): + state[name] = float(val) + + +# ================================================================== +# Dispatch +# ================================================================== + +def observability(chain: Dict[str, Any], obs: Dict[int, Dict[str, Any]]) -> Dict[str, Dict[str, Any]]: + """ + Per-variable confidence from how well its estimation block is determined. + A block groups coupled variables (e.g. b,c,e on the fingers); confidence is + driven by markers-per-variable in that block: + high : >= 2 markers per variable (well over-determined) + medium : >= 1 marker per variable + low : fewer markers than variables (under-determined — distrust!) + none : no markers at all (variable left at 0) + """ + info: Dict[str, Dict[str, Any]] = {} + for block in chain["blocks"]: + seen = [m for m in block["markers"] if m in obs] + nvars = max(1, len(block["vars"])) + ratio = len(seen) / nvars + if len(seen) == 0: + conf = "none" + elif ratio >= 2.0: + conf = "high" + elif ratio >= 1.0: + conf = "medium" + else: + conf = "low" + for v in block["vars"]: + info[v] = {"observable": len(seen) > 0, "n_markers": len(seen), + "block_vars": len(block["vars"]), "confidence": conf, + "block_anchor": block["anchor"]} + return info + + +def estimate_pose(fk: RobotFK, obs: Dict[int, Dict[str, Any]], cfg: Dict[str, Any]) -> Dict[str, Any]: + chain = analyze_chain(fk) + var_names = chain["ordered_vars"] + method = str(cfg.get("method", "hybrid")).lower() + obsv = observability(chain, obs) + + if method == "sequential_vector": + state = estimate_sequential_vector(fk, obs, chain, cfg) + elif method == "sequential_fk": + state = estimate_sequential_fk(fk, obs, chain, cfg) + elif method == "global_ba": + init = estimate_sequential_fk(fk, obs, chain, cfg) # cheap robust init + state = estimate_global_ba(fk, obs, var_names, init, cfg) + else: # hybrid (default) + init = estimate_sequential_fk(fk, obs, chain, cfg) + state = estimate_global_ba(fk, obs, var_names, init, cfg) + + # final residual stats over all observed markers + final_res = residual_vector(state, fk, obs, list(obs.keys()), cfg) + rms = float(np.sqrt(np.mean(final_res ** 2))) if final_res.size else 0.0 + + return {"state": state, "method": method, "observability": obsv, + "residual_rms": rms, "num_markers": len(obs)} + + +# ================================================================== +# CLI +# ================================================================== + +def main() -> None: + ap = argparse.ArgumentParser(description="Estimate robot joint angles from marker poses") + ap.add_argument("markers", help="aruco_marker_poses.json (corner_pose) or aruco_positions_*.json (center)") + ap.add_argument("-robot", "--robot", required=True) + ap.add_argument("-out", "--out", default=None) + ap.add_argument("--method", default=None, help="override robot.json method") + args = ap.parse_args() + + robot_data = json.load(open(args.robot, "r", encoding="utf-8")) + cfg = load_pose_cfg(robot_data) + if args.method: + cfg["method"] = args.method + + fk = RobotFK(robot_data) + obs = load_observations(args.markers, cfg.get("use_normals", True), + int(cfg.get("min_cameras_per_marker", 2))) + print(f"[INFO] method={cfg['method']} | observed markers={len(obs)} | use_normals={cfg.get('use_normals')}") + + result = estimate_pose(fk, obs, cfg) + st = result["state"] + + print("\nEstimated joint values:") + for v in ["x", "y", "z", "a", "b", "c", "e"]: + ob = result["observability"].get(v, {}) + unit = "mm" if v in ("x", "e") else "deg" + conf = ob.get("confidence", "?") + tag = "" if ob.get("observable", False) else " [UNOBSERVABLE -> 0]" + print(f" {v}: {st.get(v, 0.0):8.2f} {unit} (markers={ob.get('n_markers','?')}, conf={conf}){tag}") + print(f"\n[INFO] residual RMS over {result['num_markers']} markers: {result['residual_rms']:.3f}") + + out = { + "schema_version": "1.0", + "created_utc": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), + "method": result["method"], + "movements": {v: {"value": st.get(v, 0.0), + "unit": "mm" if v in ("x", "e") else "deg", + "observable": result["observability"].get(v, {}).get("observable", False), + "confidence": result["observability"].get(v, {}).get("confidence", "none"), + "n_markers": result["observability"].get(v, {}).get("n_markers", 0)} + for v in ["x", "y", "z", "a", "b", "c", "e"]}, + "residual_rms": result["residual_rms"], + "num_markers": result["num_markers"], + } + out_path = args.out or os.path.join(os.path.dirname(args.markers), "robot_state.json") + json.dump(out, open(out_path, "w", encoding="utf-8"), indent=2) + print(f"[INFO] wrote {out_path}") + + +if __name__ == "__main__": + main() diff --git a/scripts/pipeline/robot_fk.py b/scripts/pipeline/robot_fk.py new file mode 100644 index 0000000..2f9a376 --- /dev/null +++ b/scripts/pipeline/robot_fk.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python3 +""" +robot_fk.py +----------- +Minimal forward kinematics engine for the robot.json format. + +Matches the Blender hierarchy used by render_robot.py exactly: + world_T_link = world_T_parent + @ Translate(mountPosition) @ Rotate_xyz(mountRotation) + @ Translate(jointOrigin) @ Rotate_xyz(joint.rotation) + @ T_motion + + T_motion = Rotate(axis, value_deg) for revolute joints + Translate(axis * value_mm) for linear joints + +Units throughout: millimetres, degrees. + +Public API +---------- +fk = RobotFK.from_file("robot.json") + +transforms = fk.compute({"x": 180, "y": 86, "z": -120, + "a": -60, "b": 22, "c": 91, "e": 10}) +# → dict link_name -> 4×4 np.ndarray (world frame, mm) + +p_world = fk.marker_world(transforms, "Arm1", [0, -160, 35]) +# → np.ndarray shape (3,), in mm + +all_m = fk.all_markers_world(transforms) +# → dict marker_id -> {"world_mm", "link", "local_mm"} + +# Cumulative x-offset for a link at all-zero state +# (useful for 4a: x_slider = world_x - local_x - link_x_at_zero) +x0 = fk.link_x_at_zero_state("Arm1") # → float mm +""" + +from __future__ import annotations + +import json +import math +from pathlib import Path +from typing import Any, Dict, List, Optional, Sequence, Tuple + +import numpy as np + +STATE_KEYS = ("x", "y", "z", "a", "b", "c", "e") + + +# ────────────────────────────────────────────────────────────── +# Low-level matrix helpers +# ────────────────────────────────────────────────────────────── + +def _rot_axis_angle(axis: Sequence[float], angle_deg: float) -> np.ndarray: + """3×3 rotation matrix via Rodrigues (axis need not be normalised).""" + ax = np.asarray(axis, dtype=float) + n = float(np.linalg.norm(ax)) + if n < 1e-12: + return np.eye(3) + ax = ax / n + c = math.cos(math.radians(angle_deg)) + s = math.sin(math.radians(angle_deg)) + t = 1.0 - c + x, y, z = ax + return np.array([ + [t*x*x + c, t*x*y - s*z, t*x*z + s*y], + [t*x*y + s*z, t*y*y + c, t*y*z - s*x], + [t*x*z - s*y, t*y*z + s*x, t*z*z + c ], + ]) + + +def _rot_xyz_euler(rx: float, ry: float, rz: float) -> np.ndarray: + """XYZ Euler angles (degrees) → 3×3 — matches Blender XYZ Euler mode.""" + return (_rot_axis_angle([0, 0, 1], rz) + @ _rot_axis_angle([0, 1, 0], ry) + @ _rot_axis_angle([1, 0, 0], rx)) + + +def make_T(R: np.ndarray, t: Sequence[float]) -> np.ndarray: + """4×4 homogeneous transform.""" + T = np.eye(4) + T[:3, :3] = R + T[:3, 3] = np.asarray(t, dtype=float) + return T + + +def transform_point(T: np.ndarray, p: Sequence[float]) -> np.ndarray: + """Apply 4×4 transform to a 3-D point.""" + h = np.array([p[0], p[1], p[2], 1.0]) + return (T @ h)[:3] + + +# ────────────────────────────────────────────────────────────── +# FK engine +# ────────────────────────────────────────────────────────────── + +class RobotFK: + """Forward kinematics for the robot.json format.""" + + def __init__(self, robot_data: Dict[str, Any]): + self.robot = robot_data + self.links: Dict[str, Any] = robot_data.get("links", {}) + self._topo: List[str] = self._topological_sort() + + # ── construction ───────────────────────────────────────── + + @classmethod + def from_file(cls, path) -> "RobotFK": + with open(path, "r", encoding="utf-8") as f: + return cls(json.load(f)) + + def _topological_sort(self) -> List[str]: + parent_map = {n: d.get("parent") for n, d in self.links.items()} + visited, order = set(), [] + + def visit(name: str) -> None: + if name in visited: + return + visited.add(name) + p = parent_map.get(name) + if p and p in self.links: + visit(p) + order.append(name) + + for name in self.links: + visit(name) + return order + + # ── core computation ────────────────────────────────────── + + def compute(self, joint_values: Dict[str, float]) -> Dict[str, np.ndarray]: + """ + Compute link world transforms for the given joint state. + + Parameters + ---------- + joint_values : dict variable_name -> value + Linear joints (x, e): mm + Revolute joints (y, z, a, b, c): degrees + + Returns + ------- + dict link_name -> 4×4 np.ndarray (world frame, mm) + """ + state = {k: 0.0 for k in STATE_KEYS} + for k, v in joint_values.items(): + if k in state: + state[k] = float(v) + + transforms: Dict[str, np.ndarray] = {} + + for link_name in self._topo: + d = self.links[link_name] + parent = d.get("parent") + T_parent = transforms.get(parent, np.eye(4)) if parent else np.eye(4) + + # 1 · Mount (static in parent frame) + mp = d.get("mountPosition", [0, 0, 0]) + mr = d.get("mountRotation", [0, 0, 0]) + T_m = make_T(_rot_xyz_euler(*mr), mp) + + # 2 · Joint origin (pivot point in mount frame) + ji = d.get("jointToParent", {}) or {} + jp = ji.get("origin", [0, 0, 0]) + jr = ji.get("rotation", [0, 0, 0]) + T_j = make_T(_rot_xyz_euler(*jr), jp) + + # 3 · Motion + jtype = str(ji.get("type", "fixed")).lower() + var = str(ji.get("variable", "")).lower() + axis = np.asarray(ji.get("axis", [1, 0, 0]), dtype=float) + val = state.get(var, 0.0) + + if jtype == "revolute": + T_mot = make_T(_rot_axis_angle(axis, val), [0, 0, 0]) + elif jtype == "linear": + n = float(np.linalg.norm(axis)) + u = axis / n if n > 1e-12 else np.array([1.0, 0, 0]) + T_mot = make_T(np.eye(3), u * val) + else: + T_mot = np.eye(4) + + transforms[link_name] = T_parent @ T_m @ T_j @ T_mot + + return transforms + + # ── marker helpers ──────────────────────────────────────── + + @staticmethod + def marker_world(transforms: Dict[str, np.ndarray], + link_name: str, + local_pos: Sequence[float]) -> np.ndarray: + """Transform a local marker position → world (mm).""" + return transform_point(transforms.get(link_name, np.eye(4)), local_pos) + + def all_markers_world(self, + transforms: Dict[str, np.ndarray] + ) -> Dict[int, Dict[str, Any]]: + """ + Returns + ------- + dict marker_id -> {world_mm, local_mm, link, normal_world} + """ + result: Dict[int, Dict[str, Any]] = {} + for lname, ldata in self.links.items(): + T = transforms.get(lname, np.eye(4)) + R = T[:3, :3] + for m in ldata.get("markers", []): + mid = int(m.get("id", -1)) + if mid < 0 or "position" not in m: + continue + loc = np.array(m["position"], dtype=float) + nor = np.array(m.get("normal", [0, 0, 1]), dtype=float) + result[mid] = { + "world_mm": transform_point(T, loc), + "local_mm": loc, + "link": lname, + "normal_world": (R @ nor) / max(np.linalg.norm(R @ nor), 1e-12), + } + return result + + # ── x-axis invariant helpers (used by 4a) ──────────────── + + def link_x_at_zero_state(self, link_name: str) -> float: + """ + Return the world x-coordinate of the link-frame origin + when ALL joint variables are zero. + + For any link reachable via only x-axis rotations (Arm1, Ellbow, Arm2), + this value is constant regardless of the actual revolute angles. + Adding the slider value x_mm gives the true link origin x: + link_origin_world_x = x_mm + link_x_at_zero_state(link_name) + + And for any marker in that link: + marker_world_x = x_mm + link_x_at_zero_state(link_name) + marker_local_x + """ + T = self.compute({k: 0.0 for k in STATE_KEYS}) + return float(T[link_name][0, 3]) + + def joint_origin_world(self, + link_name: str, + joint_state: Dict[str, float]) -> np.ndarray: + """ + World position of the pivot that link_name rotates / slides around. + """ + d = self.links[link_name] + parent = d.get("parent") + T_all = self.compute(joint_state) + T_parent = T_all.get(parent, np.eye(4)) if parent else np.eye(4) + + mp = d.get("mountPosition", [0, 0, 0]) + mr = d.get("mountRotation", [0, 0, 0]) + T_m = make_T(_rot_xyz_euler(*mr), mp) + + ji = d.get("jointToParent", {}) or {} + jp = ji.get("origin", [0, 0, 0]) + jr = ji.get("rotation", [0, 0, 0]) + T_j = make_T(_rot_xyz_euler(*jr), jp) + + return transform_point(T_parent @ T_m @ T_j, [0, 0, 0]) + + def joint_axis_world(self, + link_name: str, + joint_state: Dict[str, float]) -> np.ndarray: + """ + Joint axis of link_name expressed in world frame. + """ + d = self.links[link_name] + parent = d.get("parent") + T_all = self.compute(joint_state) + T_parent = T_all.get(parent, np.eye(4)) if parent else np.eye(4) + + mp = d.get("mountPosition", [0, 0, 0]) + mr = d.get("mountRotation", [0, 0, 0]) + T_m = make_T(_rot_xyz_euler(*mr), mp) + + ji = d.get("jointToParent", {}) or {} + jp = ji.get("origin", [0, 0, 0]) + jr = ji.get("rotation", [0, 0, 0]) + T_j = make_T(_rot_xyz_euler(*jr), jp) + + R_to_pivot = (T_parent @ T_m @ T_j)[:3, :3] + axis_local = np.asarray(ji.get("axis", [1, 0, 0]), dtype=float) + world = R_to_pivot @ axis_local + n = float(np.linalg.norm(world)) + return world / n if n > 1e-12 else world + + # ── utility ─────────────────────────────────────────────── + + def chain(self, link_name: str) -> List[str]: + """Return chain from root to link_name (inclusive).""" + out, cur = [], link_name + while cur: + out.append(cur) + cur = self.links.get(cur, {}).get("parent") + return list(reversed(out)) + + def board_marker_world_positions(self, length_scale: float = 1.0) -> Dict[int, np.ndarray]: + """ + Return known world positions for all Board markers (in mm). + Board is the root, so its marker positions ARE world positions. + length_scale: 1/1000 if robot.json uses mm. + """ + board = self.links.get("Board", {}) + result: Dict[int, np.ndarray] = {} + for m in board.get("markers", []): + mid = int(m.get("id", -1)) + if mid >= 0 and "position" in m: + p = np.array(m["position"], dtype=float) * length_scale + result[mid] = p + return result diff --git a/tests/data/Scene9a/pose.json b/tests/data/Scene9a/pose.json new file mode 100644 index 0000000..9974214 --- /dev/null +++ b/tests/data/Scene9a/pose.json @@ -0,0 +1,91 @@ +{ + "name": "9a", + "position": { + "x": 60, + "y": -2, + "z": 95, + "a": 200, + "b": 60, + "c": 9, + "e": 8 + }, + "rendering": { + "width": 1440, + "height": 1080, + "dofFStop": 11 + }, + "camera_positions": { + "a": [ + -300, + -800, + 800 + ], + "b": [ + 300, + -900, + 1200 + ], + "c": [ + 300, + -900, + 400 + ], + "d": [ + 700, + -800, + 400 + ], + "e": [ + 1200, + -900, + 400 + ], + "f": [ + 500, + -300, + 1400 + ], + "g": [ + -200, + 200, + 1400 + ] + }, + "camera_targets": { + "a": [ + 210, + -100, + 180 + ], + "b": [ + 310, + -80, + 180 + ], + "c": [ + 210, + -100, + 150 + ], + "d": [ + 210, + -100, + 150 + ], + "e": [ + 210, + -100, + 50 + ], + "f": [ + 200, + -200, + 180 + ], + "g": [ + 200, + -200, + 180 + ] + } +} \ No newline at end of file diff --git a/tests/data/Scene9a/render_a.npz b/tests/data/Scene9a/render_a.npz new file mode 100644 index 0000000000000000000000000000000000000000..0584c9a8d0cb9e0973b06710ef5faab510ae8ed3 GIT binary patch literal 1394 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 z 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

PtN$wKPSU_o;`3^7+O3 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�DM|H@RpPbAGQSS#*|KQhW_=9IY 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%0AK#{+jzc50xcy!@MZT_=DKX?}MANqli z@Asm6KLj8ETNI{#oBq5=N90yp5!i^U(`N+Y+;`7<=ZA^mxGdZI)Z$x}hl!_tqnktQ z^u$Sm$MLGFtDLI1;OK{I6>EuhCSSWqidh_QjwL;wzbwF*Q+a8)h;uJe4$3ev^N}%q z*ywW39GYtT%+zz^aIt?m^03dD48&(nW-Os~F7Ah%?Cf=F>p14RoTD3J@?dp-;%=|C z39ro4=6Vn-(W?!d1-V9a-hWdPsJ)g{T`Tx^7O?Oyca79pMX0=*oB>z#gIT|{u=lIA zd0Izmb_I@emQppf7&8uU_e>vdX>h2xXE%o~FW312UikI43J&w)sp~#eNIrat<8@PJ zYcgB<>$sUzIcrO2kC9>%!6mXy?%8BMO!#@HORBrYEQ z)s=@vU|@I7gC)K>8)vRwoU1*VeGgk*H!;>HO$KDo(m!C!zd3$6h-uE~*)}>t;|_Sq zWg6!@@hQ>-?g?0ZY;C-A^?q&M*nJgV5lh`3yzyrZ?72622%WHd5B`&f7op94(O+!k zJe%gx4D{d|cP3id2ix>+I`&XDd!kj_ULypH-~A%!kfQ*D#_XEC{OM0(<#~IR$b`E` zS|)Y!;SnB9Ctjwb`Fw7ciibLD5moajO;=7Pg3x+`yFcaO(^&3X*VW)yVeBiG2QtK< z)87YaM#}+#2cy};I$5R1#5yM-5TAJJ%!lKi%kqU3<|%6GZJFy^AGdc-dHsC?a}}Cf zG1I)b%q9$4X@hO-3KRtFJ_J6W)A(B82UYUFUl+jKkw&Bh9(d*TkWzYY2z>NQx3YO} z3G}|>S;l`1oJVlPeg^t$TkZJK>zL6mO#9%*D6nkXq0?G9S4K5J<2WzK=`aw+M}x@| z@3nGlMb->dzT72+?@x{q9kO0$}US;o?ityJQ@ps$M5@_NcG=5ry+#U_Tyf^uB z1#PWQFMea$9}!wk7kpM{f}1aJ8TG!`ON6DC=-N8e?xppw0_Nx(&+UX==i=C&LyS*d zrz7PvF6*+VPYH27U7Bj^Z!e#^g`!5Zy)|sV9Mtei8I~l6`=jkdvN$=$b6z(RxX(q? z3g?EkiFa|>!Etpz;pX#3$KO8(J@vsQ`1Id7DaLbZQkJY0w?V()(YTp^cjS>*Q+jzz zc$m!L$YHDR*jPB%YOp7@v(!KXoOh1C-Mj14k61!8p5RX}$y=ZMqRY*Uh%MHq zKLqIAul3bv(k0id9J>dxI+u*QN8CTf=3#UYT;csU{t1qglpwubF*msbnuzt9vcxBj zf;HB>BE#FmImJ_0zvz85JcY(?MqQ%p9?^m&jm;>1bscawjyPIv>I z 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

  • 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