# 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.