diff --git a/data/robot/robot.json b/data/robot/robot.json deleted file mode 100644 index b9b760c..0000000 --- a/data/robot/robot.json +++ /dev/null @@ -1,2441 +0,0 @@ -{ - "coordinateSystem": { - "handedness": "right", - "x": "right", - "y": "backward", - "z": "up" - }, - "units": { - "length": "mm", - "rotation": "degree" - }, - "vision_config": { - "MarkerType": "DICT_4X4_250", - "MarkerSize": 0.025 - }, - "renderingInfo": { - "width": 1280, - "height": 720, - "renderDefaults": { - "width": 1280, - "height": 720, - "dofFStop": 11 - }, - "cameraPosition__1": [ - -10, - -800, - 500 - ], - "cameraPosition__2": [ - -500, - 300, - 1200 - ], - "cameraPosition__3": [ - -200, - -900, - 200 - ], - "cameraPosition__4": [ - 1200, - 200, - 300 - ], - "cameraPosition_a": [ - -300, - -800, - 500 - ], - "cameraPosition": [ - -200, - 200, - 1400 - ], - "cameraPosition_c": [ - 600, - -500, - 600 - ], - "cameraTarget": [ - 200, - -200, - 180 - ], - "cameraUpVector": [ - 0, - 0, - 1 - ], - "lightPosition": [ - -500, - -500, - 500 - ], - "lightTarget": [ - 0, - 0, - 0 - ], - "lightUpVector": [ - 0, - 0, - 1 - ], - "metric": "mm", - "showSkeleton": true, - "showMarkers": true, - "backgroundColor": [ - 0.7, - 0.85, - 1.0 - ], - "backgroundStrength": 0.2, - "sunEnergy": 0.35, - "areaEnergy": 120, - "exposure": -1.5, - "lensDirt": true, - "lensDirtStrength": 0.08, - "dofEnabled": true, - "dofFStop": 11.0, - "arucoDust": true, - "arucoDustStrength": 1.6, - "markerOffsetMaxMm": 4.0, - "markerOffsetSeed": 0, - "markerRotationMaxDeg": 3, - "motionBlur": true, - "motionBlurMaxPx": 5.5, - "focalErrorPct": 0.5, - "principalErrorPx": 3.0, - "residualDistortion": [ - 0.02, - -0.01 - ], - "localizedBlur": false, - "localizedBlurStrength": 0.15, - "vignette": true, - "vignetteStrength": 0.08, - "sensorNoise": true, - "sensorNoiseStrength": 0.01, - "lensDistortion": true, - "lensDistortionStrength": 0.002, - "materials": { - "wood": { - "baseColor": [ - 0.72, - 0.52, - 0.33 - ], - "roughness": 0.85, - "metallic": 0.0 - }, - "plaWhite": { - "baseColor": [ - 0.95, - 0.95, - 0.95 - ], - "roughness": 0.45, - "metallic": 0.0 - }, - "steel": { - "baseColor": [ - 0.72, - 0.72, - 0.75 - ], - "roughness": 0.25, - "metallic": 1.0 - }, - "powderCoatBlue": { - "baseColor": [ - 0.15, - 0.25, - 0.7 - ], - "roughness": 0.55, - "metallic": 0.0 - }, - "defaultPlastic": { - "baseColor": [ - 0.95, - 0.95, - 0.95 - ], - "roughness": 0.4, - "metallic": 0.0 - }, - "skeletonRed": { - "baseColor": [ - 0.85, - 0.2, - 0.2 - ], - "roughness": 0.35, - "metallic": 0.0 - }, - "markerBlack": { - "baseColor": [ - 0.04, - 0.04, - 0.04 - ], - "roughness": 0.8, - "metallic": 0.0 - } - }, - "skeletonDefaults": { - "radius": 4, - "color": [ - 0.85, - 0.2, - 0.2 - ] - }, - "markerDefaults": { - "size": 25, - "thickness": 1, - "color": [ - 0.04, - 0.04, - 0.04 - ] - }, - "defaultPosition": { - "x": 80, - "y": 20, - "z": 80, - "a": -120, - "b": 23, - "c": 9, - "e": 3 - } - }, - "defaultPosition__": { - "x": 10, - "y": 4, - "z": 20, - "a": 10, - "b": 2, - "c": 9, - "e": 1 - }, - "defaultPosition": { - "x": 50, - "y": 4, - "z": 176, - "a": 20, - "b": 60, - "c": 9, - "e": 5 - }, - "recognized": { - "x": null, - "y": null, - "z": null, - "a": null, - "b": null, - "c": null, - "e": null - }, - "constraint_rules": { - "rigid_distance": { - "enabled": true, - "mode": "mst", - "weight": 1.0 - }, - "joint_axis_projection": { - "enabled": true, - "max_pairs": 2, - "weight": 0.35 - }, - "chain_axis_projection": { - "enabled": false, - "max_depth": 3, - "max_pairs": 2, - "weight": 0.15 - }, - "axis_alignment_threshold": 0.95 - }, - "observation_weighting": { - "enabled": true, - "distance_weight": true, - "marker_size_weight": true, - "view_angle_weight": true - }, - "multiview_calculation": { - "combine_mode": "mean", - "size_ref_px": 50.0, - "border_ref_px": 120.0, - "center_ref_norm": 0.01, - "sharpness_ref": 2500.0, - "homography_ref": 0.18, - "size_factor": 0.3, - "aspect_factor": 0.3, - "border_factor": 0.01, - "center_factor": 0.01, - "sharpness_factor": 0.5, - "homography_factor": 0.2, - "normal_visibility_factor": 0.01, - "spin_factor": 0.3, - "weight_floor": 0.3 - }, - "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, - "finger_block_joints": [ - "b", - "c", - "e" - ], - "per_link_method": {} - }, - "robot_test_poses": { - "4": { - "x": 70, - "y": 50, - "z": -70, - "a": 120, - "b": 50, - "c": 30, - "e": 20 - }, - "5": { - "x": 180, - "y": 86, - "z": -120, - "a": -60, - "b": 22, - "c": 91, - "e": 10 - }, - "6": { - "x": 80, - "y": 20, - "z": 80, - "a": -120, - "b": 23, - "c": 9, - "e": 3 - }, - "7": { - "x": 30, - "y": -2, - "z": 95, - "a": 20, - "b": 23, - "c": 9, - "e": 9 - }, - "8": { - "x": 50, - "y": -2, - "z": 95, - "a": 20, - "b": 60, - "c": 9, - "e": 3 - }, - "9": { - "x": 60, - "y": -2, - "z": 95, - "a": 200, - "b": 60, - "c": 9, - "e": 8 - }, - "9a": { - "x": 60, - "y": -2, - "z": 95, - "a": 200, - "b": 60, - "c": 9, - "e": 8, - "rendering": { - "width": 1440, - "height": 1080, - "dofFStop": 11 - } - }, - "9b": { - "x": 60, - "y": -2, - "z": 95, - "a": 200, - "b": 60, - "c": 9, - "e": 8, - "rendering": { - "width": 4896, - "height": 3264, - "dofFStop": 5.6 - } - }, - "10": { - "x": 120, - "y": 60, - "z": -110, - "a": 20, - "b": 30, - "c": 180, - "e": 4 - }, - "11": { - "x": 50, - "y": 4, - "z": 176, - "a": 20, - "b": 60, - "c": 9, - "e": 5 - }, - "12": { - "x": 50, - "y": 0, - "z": 178, - "a": 210, - "b": 80, - "c": 90, - "e": 6 - } - }, - "test_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 - ] - }, - "test_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 - ] - }, - "movements": { - "x": null, - "y": null, - "z": null, - "a": null, - "b": null, - "c": null, - "e": null - }, - "state_pose_params": { - "numbers_of_Elements_to_consider_start": 3, - "numbers_of_Elements_to_consider_final": 5, - "solver_in_between_geometrical": false, - "solver_after_geometrical": false, - "geometric_passes_per_stage": 2, - "revolute_search_coarse_deg": 5.0, - "revolute_search_fine_deg": 1.0, - "root_pose_min_markers": 3, - "use_marker_normals_flip_tiebreak": true, - "normal_flip_weight": 0.05 - }, - "links": { - "Board": { - "parent": null, - "size": [ - 1000, - 200, - 25 - ], - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "skeleton": { - "from": [ - 0, - 0, - 16 - ], - "to": [ - 1000, - 0, - 16 - ], - "radius": 4, - "color": [ - 0.85, - 0.2, - 0.2 - ] - }, - "markers": [ - { - "id": 210, - "position": [ - 20, - -20, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 211, - "position": [ - 250, - -10, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 215, - "position": [ - 250, - -90, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 214, - "position": [ - 350, - -10, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 208, - "position": [ - 350, - -90, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 206, - "position": [ - 650, - -10, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 205, - "position": [ - 750, - -90, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 207, - "position": [ - 750, - -10, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 217, - "position": [ - 650, - -90, - 0.3 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 46, - "position": [ - 536.71, - 185.44, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90, - "info": "is placed on a white paper, A0_60Arucos_25mm_Seet223.pdf, with the following marker placements:" - }, - { - "id": 47, - "position": [ - 344.23, - -286.54, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 48, - "position": [ - 688.69, - -320.72, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 49, - "position": [ - 1006.0, - 158.33, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 50, - "position": [ - 573.41, - 211.86, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 51, - "position": [ - 167.8, - -172.08, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 52, - "position": [ - 94.68, - 208.66, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 53, - "position": [ - 486.25, - 212.24, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 54, - "position": [ - 342.27, - -330.59, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 55, - "position": [ - 283.72, - -262.58, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 56, - "position": [ - 498.68, - 168.67, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 57, - "position": [ - 602.86, - -364.05, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 58, - "position": [ - 50.09, - -218.11, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 59, - "position": [ - 626.21, - -278.75, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 60, - "position": [ - 434.36, - 283.81, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 61, - "position": [ - -22.42, - 335.83, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 62, - "position": [ - 404.7, - -175.1, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 63, - "position": [ - 777.4, - -236.15, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 64, - "position": [ - -21.27, - -188.23, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 65, - "position": [ - 803.39, - -297.37, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 66, - "position": [ - 209.75, - -363.23, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 67, - "position": [ - 523.07, - 267.04, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 68, - "position": [ - 573.73, - 170.64, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 69, - "position": [ - 7.61, - -281.21, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 70, - "position": [ - 601.87, - 300.33, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 71, - "position": [ - 749.75, - -284.01, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 72, - "position": [ - 440.99, - 194.32, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 73, - "position": [ - 221.73, - 333.11, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 74, - "position": [ - 93.78, - 144.5, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 75, - "position": [ - -25.7, - 194.58, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 76, - "position": [ - 685.21, - 166.8, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 77, - "position": [ - 18.19, - 191.57, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 78, - "position": [ - 823.11, - -344.38, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 79, - "position": [ - 312.3, - -159.11, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 80, - "position": [ - 863.59, - -335.92, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 81, - "position": [ - 132.14, - 169.03, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 82, - "position": [ - 219.16, - 297.24, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 83, - "position": [ - 44.16, - 339.22, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 84, - "position": [ - 407.49, - 258.42, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 85, - "position": [ - 504.58, - -312.75, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 86, - "position": [ - 362.89, - 292.01, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 87, - "position": [ - 943.63, - -245.76, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 88, - "position": [ - 765.87, - 316.04, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 89, - "position": [ - 988.02, - -369.14, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 90, - "position": [ - 643.17, - 316.43, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 91, - "position": [ - 723.35, - 328.05, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 92, - "position": [ - 645.09, - -184.84, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 93, - "position": [ - 934.88, - 143.6, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 94, - "position": [ - 875.7, - 173.65, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 95, - "position": [ - 186.04, - -274.07, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 96, - "position": [ - 369.77, - -186.49, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 97, - "position": [ - 304.35, - -359.67, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 98, - "position": [ - 575.27, - 315.06, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 99, - "position": [ - 959.16, - -321.55, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 100, - "position": [ - 803.25, - 172.36, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 101, - "position": [ - 117.7, - 298.66, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 102, - "position": [ - 649.69, - -223.0, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 103, - "position": [ - 105.71, - -187.71, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 104, - "position": [ - 826.71, - 239.16, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - }, - { - "id": 105, - "position": [ - 524.84, - -266.25, - -27.3 - ], - "normal": [ - 0, - 0, - 1 - ], - "spin": 90 - } - ], - "model": [ - { - "stlFile": "surfaces/Board.stl", - "originOfModel": [ - 0, - 0, - 0 - ], - "rotationOfModelDegree": [ - 0, - 0, - -90 - ], - "material": "wood" - }, - { - "stlFile": "surfaces/BoardRail.stl", - "originOfModel": [ - 0, - 0, - 0 - ], - "rotationOfModelDegree": [ - 0, - 0, - -90 - ], - "material": "steel" - } - ] - }, - "Base": { - "parent": "Board", - "size": [ - 150, - 200, - 150 - ], - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [ - 1, - 0, - 0 - ], - "origin": [ - 0, - 0, - 16 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "x" - }, - "skeleton": { - "from": [ - 0, - 108, - 45 - ], - "to": [ - 110, - 108, - 45 - ], - "radius": 4, - "color": [ - 0.2, - 0.8, - 0.2 - ] - }, - "markers": [], - "model": [ - { - "stlFile": "surfaces/Base.stl", - "originOfModel": [ - -30, - 0, - -35 - ], - "rotationOfModelDegree": [ - 0, - 0, - 0 - ], - "material": "plaWhite" - } - ] - }, - "Arm1": { - "parent": "Base", - "size": [ - 70, - 250, - 70 - ], - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Joint1", - "type": "revolute", - "axis": [ - -1, - 0, - 0 - ], - "origin": [ - 110, - 108, - 45 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "y" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 0, - -250, - 0 - ], - "radius": 4, - "color": [ - 0.2, - 0.2, - 0.9 - ] - }, - "markers": [ - { - "id": 198, - "name": "aruco_198", - "position": [ - 0, - -160, - 35 - ], - "normal": [ - 0, - 0, - 1 - ], - "size": 25, - "spin": 0 - }, - { - "id": 229, - "name": "aruco_229", - "position": [ - 0, - -250, - 35 - ], - "normal": [ - 0, - 0, - 1 - ], - "size": 25, - "spin": 0 - }, - { - "id": 242, - "name": "aruco_242", - "position": [ - 0, - -250, - -35 - ], - "normal": [ - 0, - 0, - -1 - ], - "size": 25, - "spin": 0 - }, - { - "id": 243, - "name": "aruco_243", - "position": [ - 0, - -285, - 0 - ], - "normal": [ - 0, - -1, - 0 - ], - "size": 25, - "spin": 0 - } - ], - "model": [ - { - "stlFile": "surfaces/Holm.stl", - "originOfModel__": [ - -25, - 29, - -28.5 - ], - "originOfModel": [ - -29, - 25, - 28.5 - ], - "rotationOfModelDegree__": [ - 0, - 0, - 0 - ], - "rotationOfModelDegree": [ - 180, - 0, - -90 - ], - "material": "powderCoatBlue" - } - ] - }, - "Ellbow": { - "parent": "Arm1", - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Joint2", - "type": "revolute", - "axis": [ - -1, - 0, - 0 - ], - "origin": [ - 0, - -250, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "z" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 90, - 0, - 0 - ], - "radius": 4, - "color": [ - 0.9, - 0.2, - 0.2 - ] - }, - "model": [ - { - "stlFile": "surfaces/Ellebogen.stl", - "originOfModel": [ - 90, - 0, - 0 - ], - "rotationOfModelDegree": [ - 0, - -90, - -90 - ], - "material": "defaultPlastic" - } - ], - "markers": [ - { - "id": 244, - "name": "aruco_244", - "position": [ - 125, - 0, - 0 - ], - "normal": [ - 1, - 0, - 0 - ], - "size": 25, - "spin": 0 - }, - { - "id": 245, - "name": "aruco_245", - "position": [ - 90, - 0, - -35 - ], - "normal": [ - 0, - 0, - -1 - ], - "size": 25, - "spin": 0 - }, - { - "id": 246, - "name": "aruco_246", - "position": [ - 90, - 0, - 35 - ], - "normal": [ - 0, - 0, - 1 - ], - "size": 25 - }, - { - "id": 247, - "name": "aruco_247", - "position": [ - 52.5, - 0, - 35 - ], - "normal": [ - 0, - 0, - 1 - ], - "size": 25 - }, - { - "id": 248, - "name": "aruco_248", - "position": [ - 52.5, - 0, - -35 - ], - "normal": [ - 0, - 0, - -1 - ], - "size": 25 - }, - { - "id": 232, - "name": "aruco_232", - "position": [ - 90, - 24.75, - -24.75 - ], - "normal": [ - 0, - 1, - -1 - ], - "size": 25 - }, - { - "id": 231, - "name": "aruco_231", - "position": [ - 90, - 24.75, - 24.75 - ], - "normal": [ - 0, - 1, - 1 - ], - "size": 25 - } - ] - }, - "Arm2": { - "parent": "Ellbow", - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Joint3", - "type": "revolute", - "axis": [ - 0, - -1, - 0 - ], - "origin": [ - 90, - 0, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "a" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 0, - -250, - 0 - ], - "radius": 4, - "color": [ - 0.95, - 0.85, - 0.2 - ] - }, - "model": [ - { - "stlFile": "surfaces/Unterarm.stl", - "originOfModel": [ - 0, - -250, - 0 - ], - "rotationOfModelDegree": [ - 180, - 0, - -90 - ], - "material": "defaultPlastic" - } - ], - "markers": [ - { - "id": 120, - "position": [ - 24.75, - -112, - -24.75 - ], - "normal": [ - 1, - 0, - -1 - ] - }, - { - "id": 122, - "name": "aruco_122", - "position": [ - -35, - -112, - 0 - ], - "normal": [ - -1, - 0, - 0 - ] - }, - { - "id": 218, - "name": "aruco_218", - "position": [ - 35, - -112, - 0 - ], - "normal": [ - 1, - 0, - 0 - ] - }, - { - "id": 113, - "name": "aruco_113", - "position": [ - 0, - -182, - 30 - ], - "normal": [ - 0, - 0, - 1 - ] - }, - { - "id": 114, - "name": "aruco_114", - "position": [ - 24.75, - -182, - -24.75 - ], - "normal": [ - 1, - 0, - -1 - ] - }, - { - "id": 115, - "name": "aruco_115", - "position": [ - -24.75, - -182, - -24.75 - ], - "normal": [ - -1, - 0, - -1 - ] - }, - { - "id": 124, - "name": "aruco_124", - "position": [ - -35, - -219, - 0 - ], - "normal": [ - -1, - 0, - 0 - ] - }, - { - "id": 219, - "name": "aruco_219", - "position": [ - 35, - -219, - 0 - ], - "normal": [ - 1, - 0, - 0 - ] - } - ] - }, - "Hand": { - "parent": "Arm2", - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Joint4", - "type": "revolute", - "axis": [ - 1, - 0, - 0 - ], - "origin": [ - 0, - -250, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "b" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 0, - -35, - 0 - ], - "radius": 4, - "color": [ - 0.95, - 0.55, - 0.15 - ] - } - }, - "Palm": { - "parent": "Hand", - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Joint3", - "type": "revolute", - "axis": [ - 0, - -1, - 0 - ], - "origin": [ - 0, - 0, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "c" - }, - "skeleton": { - "from": [ - -50, - -35, - 0 - ], - "to": [ - 50, - -35, - 0 - ], - "radius": 7, - "color": [ - 0.95, - 0.2, - 0.2 - ] - } - }, - "FingerA": { - "parent": "Palm", - "size": [ - 80, - 60, - 20 - ], - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [ - 1, - 0, - 0 - ], - "origin": [ - 4, - -35, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "e" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 0, - -60, - 0 - ], - "radius": 4, - "color": [ - 0.2, - 0.8, - 0.2 - ] - }, - "markers": [ - { - "id": 40, - "position": [ - 12, - -24, - -17.1 - ], - "normal": [ - -10.98, - 0, - -23.56 - ] - }, - { - "id": 41, - "position": [ - 1.5, - -2.2, - 25.8 - ], - "normal": [ - 0, - -25.6, - 9.5 - ] - }, - { - "id": 42, - "position": [ - 13.9, - -40, - 0 - ], - "normal": [ - 1, - -0.35, - 0.4 - ], - "spin": 27 - } - ], - "model": [ - { - "stlFile": "surfaces/Finger.stl", - "originOfModel": [ - 24, - 0, - -9.1 - ], - "rotationOfModelDegree": [ - 90, - -90, - 0 - ], - "material": "defaultPlastic" - } - ] - }, - "FingerB": { - "parent": "Palm", - "size": [ - 80, - 60, - 20 - ], - "mountPosition": [ - 0, - 0, - 0 - ], - "mountRotation": [ - 0, - 0, - 0 - ], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [ - -1, - 0, - 0 - ], - "origin": [ - -4, - -35, - 0 - ], - "rotation": [ - 0, - 0, - 0 - ], - "variable": "e" - }, - "skeleton": { - "from": [ - 0, - 0, - 0 - ], - "to": [ - 0, - -60, - 0 - ], - "radius": 4, - "color": [ - 0.2, - 0.8, - 0.2 - ] - }, - "markers": [ - { - "id": 43, - "position": [ - -12, - -24, - 17.1 - ], - "normal": [ - 10.98, - 0, - 23.56 - ], - "spin": 90 - }, - { - "id": 44, - "position": [ - -1.5, - -2.2, - -25.8 - ], - "normal": [ - 0, - -25.6, - -9.5 - ], - "spin": 90 - }, - { - "id": 45, - "position": [ - -13.9, - -40, - 0 - ], - "normal": [ - -1, - -0.35, - -0.4 - ], - "spin": -27 - } - ], - "model": [ - { - "stlFile": "surfaces/Finger.stl", - "originOfModel": [ - -24, - 0, - 9.1 - ], - "rotationOfModelDegree": [ - 90, - 90, - 0 - ], - "material": "defaultPlastic" - } - ] - } - } -} \ No newline at end of file diff --git a/data/robot/robot_running_2026_05_30.json b/data/robot/robot_running_2026_05_30.json deleted file mode 100644 index 49fbe47..0000000 --- a/data/robot/robot_running_2026_05_30.json +++ /dev/null @@ -1,595 +0,0 @@ -{ - "coordinateSystem": { - "handedness": "right", - "x": "right", - "y": "backward", - "z": "up" - }, - "units": { - "length": "mm", - "rotation": "degree" - }, - "vision_config": { - "MarkerType": "DICT_4X4_250", - "MarkerSize": 0.025 - }, - "renderingInfo": { - "width": 1280, - "height": 720, - "cameraPosition__1": [-10, -800, 500], - "cameraPosition__2": [-500, 300, 1200], - "cameraPosition__3": [-200, -900, 200], - "cameraPosition__4": [1200, 200, 300], - "cameraPosition_a":[-300, -800,500], - "cameraPosition":[300, -500,1450], - "cameraPosition_c":[600, -500,600], - "cameraTarget": [210, -200, 180], - "cameraUpVector": [0, 0, 1], - "lightPosition": [-500, -500, 500], - "lightTarget": [0, 0, 0], - "lightUpVector": [0, 0, 1], - "metric": "mm", - "showSkeleton": true, - "showMarkers": true, - "backgroundColor": [0.70, 0.85, 1.0], - "backgroundStrength": 0.20, - "sunEnergy": 0.35, - "areaEnergy": 120, - "exposure": -1.5, - "lensDirt": true, - "lensDirtStrength": 0.08, - "dofEnabled": true, - "dofFStop": 11, - "arucoDust": false, - "arucoDustStrength": 0.00005, - "localizedBlur": false, - "localizedBlurStrength": 0.15, - "vignette": true, - "vignetteStrength": 0.08, - - "sensorNoise": true, - "sensorNoiseStrength": 0.01, - - "lensDistortion": true, - "lensDistortionStrength": 0.002, - "materials": { - "wood": { - "baseColor": [0.72, 0.52, 0.33], - "roughness": 0.85, - "metallic": 0.0 - }, - "plaWhite": { - "baseColor": [0.95, 0.95, 0.95], - "roughness": 0.45, - "metallic": 0.0 - }, - "steel": { - "baseColor": [0.72, 0.72, 0.75], - "roughness": 0.25, - "metallic": 1.0 - }, - "powderCoatBlue": { - "baseColor": [0.15, 0.25, 0.7], - "roughness": 0.55, - "metallic": 0.0 - }, - "defaultPlastic": { - "baseColor": [0.95, 0.95, 0.95], - "roughness": 0.4, - "metallic": 0.0 - }, - "skeletonRed": { - "baseColor": [0.85, 0.20, 0.20], - "roughness": 0.35, - "metallic": 0.0 - }, - "markerBlack": { - "baseColor": [0.04, 0.04, 0.04], - "roughness": 0.80, - "metallic": 0.0 - } - }, - "skeletonDefaults": { - "radius": 4, - "color": [0.85, 0.20, 0.20] - }, - "markerDefaults": { - "size": 25, - "thickness": 1, - "color": [0.04, 0.04, 0.04] - } - }, - "defaultPosition__": { - "x": 10, - "y": 4, - "z": 20, - "a": 10, - "b": 2, - "c": 9, - "e": 1 - }, - "defaultPosition": { - "x": 180, - "y": 86, - "z": -120, - "a": -60, - "b": 22, - "c": 91, - "e": 10 - }, - "recognized": { - "x": null, - "y": null, - "z": null, - "a": null, - "b": null, - "c": null, - "e": null - }, - "constraint_rules": { - - "rigid_distance": { - "enabled": true, - "mode": "mst", - "weight": 1.0 - }, - - "joint_axis_projection": { - "enabled": true, - "max_pairs": 2, - "weight": 0.35 - }, - - "chain_axis_projection": { - "enabled": false, - "max_depth": 3, - "max_pairs": 2, - "weight": 0.15 - }, - - "axis_alignment_threshold": 0.95 - }, - "observation_weighting": { - "enabled": true, - "distance_weight": true, - "marker_size_weight": true, - "view_angle_weight": true - }, - "multiview_calculation": { - "combine_mode": "mean", - "size_ref_px": 50.0, - "border_ref_px": 120.0, - "center_ref_norm": 0.01, - "sharpness_ref": 2500.0, - "homography_ref": 0.18, - "size_factor": 0.3, - "aspect_factor": 0.3, - "border_factor": 0.01, - "center_factor": 0.01, - "sharpness_factor": 0.5, - "homography_factor": 0.2, - "normal_visibility_factor": 0.01, - "spin_factor": 0.3, - "weight_floor": 0.3 - }, - "robot_test_poses": { - "sim04": {"x": 70, "y": 50,"z": -70,"a": 120,"b": 50,"c": 30,"e": 20}, - "sim05": {"x": 180,"y": 86,"z": -120,"a": -60,"b": 22,"c": 91,"e": 10}, - "sim06": {"x": 80, "y": 20, "z": 80, "a": -120, "b": 23, "c": 9, "e": 3}, - "sim07": {"x": 30, "y": -2, "z": 95, "a": 20, "b": 23, "c": 9, "e": 9}, - "sim08": {"x": 50, "y": -2, "z": 95, "a": 20, "b": 60, "c": 9, "e": 3}, - "sim09": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8}, - "sim09a": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8}, - "sim09b": {"x": 60, "y": -2, "z": 95, "a": 200, "b": 60, "c": 9, "e": 8}, - "sim010": {"x": 120, "y": 60, "z": -110, "a": 20, "b": 30, "c": 180, "e": 4}, - "sim011": {"x": 50, "y": 4, "z": 176, "a": 20, "b": 60, "c": 9, "e": 5}, - "sim012": {"x": 50, "y": 0, "z": 178, "a": 210, "b": 80, "c": 90, "e": 6} - }, - "movements": { - "x": null, - "y": null, - "z": null, - "a": null, - "b": null, - "c": null, - "e": null - }, - "state_pose_params":{ - "numbers_of_Elements_to_consider_start": 3, - "numbers_of_Elements_to_consider_final": 4, - "solver_in_between_geometrical": false, - "solver_after_geometrical": false, - "geometric_passes_per_stage": 2, - "revolute_search_coarse_deg": 5.0, - "revolute_search_fine_deg": 1.0, - "root_pose_min_markers": 3, - "use_marker_normals_flip_tiebreak": true, - "normal_flip_weight": 0.05 - }, - "links": { - "Board": { - "parent": null, - "size": [1000, 200, 25], - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - "skeleton": { - "from": [0, 0, 16], - "to": [1000, 0, 16], - "radius": 4, - "color": [0.85, 0.20, 0.20] - }, - "markers":[ - {"id":210,"position":[20, -20, 0.3], "normal":[0,0,1]}, - {"id":211,"position":[250, -10, 0.3], "normal":[0,0,1]}, - {"id":215,"position":[250, -90, 0.3], "normal":[0,0,1]}, - {"id":214,"position":[350, -10, 0.3], "normal":[0,0,1]}, - {"id":208,"position":[350, -90, 0.3], "normal":[0,0,1]}, - {"id":206,"position":[650, -10, 0.3], "normal":[0,0,1]}, - {"id":205,"position":[750, -90, 0.3], "normal":[0,0,1]}, - {"id":207,"position":[750, -10, 0.3], "normal":[0,0,1]}, - {"id":217,"position":[650, -90, 0.3], "normal":[0,0,1]}, - - {"id": 46, "position": [536.71, 185.44, -27.3], "normal": [0, 0, 1], "spin": 90, "info": "is placed on a white paper, A0_60Arucos_25mm_Seet223.pdf, with the following marker placements:"}, - {"id": 47, "position": [344.23, -286.54, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 48, "position": [688.69, -320.72, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 49, "position": [1006.0, 158.33, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 50, "position": [573.41, 211.86, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 51, "position": [167.8, -172.08, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 52, "position": [94.68, 208.66, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 53, "position": [486.25, 212.24, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 54, "position": [342.27, -330.59, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 55, "position": [283.72, -262.58, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 56, "position": [498.68, 168.67, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 57, "position": [602.86, -364.05, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 58, "position": [50.09, -218.11, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 59, "position": [626.21, -278.75, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 60, "position": [434.36, 283.81, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 61, "position": [-22.42, 335.83, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 62, "position": [404.7, -175.1, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 63, "position": [777.4, -236.15, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 64, "position": [-21.27, -188.23, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 65, "position": [803.39, -297.37, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 66, "position": [209.75, -363.23, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 67, "position": [523.07, 267.04, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 68, "position": [573.73, 170.64, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 69, "position": [7.61, -281.21, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 70, "position": [601.87, 300.33, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 71, "position": [749.75, -284.01, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 72, "position": [440.99, 194.32, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 73, "position": [221.73, 333.11, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 74, "position": [93.78, 144.5, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 75, "position": [-25.7, 194.58, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 76, "position": [685.21, 166.8, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 77, "position": [18.19, 191.57, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 78, "position": [823.11, -344.38, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 79, "position": [312.3, -159.11, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 80, "position": [863.59, -335.92, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 81, "position": [132.14, 169.03, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 82, "position": [219.16, 297.24, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 83, "position": [44.16, 339.22, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 84, "position": [407.49, 258.42, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 85, "position": [504.58, -312.75, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 86, "position": [362.89, 292.01, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 87, "position": [943.63, -245.76, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 88, "position": [765.87, 316.04, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 89, "position": [988.02, -369.14, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 90, "position": [643.17, 316.43, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 91, "position": [723.35, 328.05, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 92, "position": [645.09, -184.84, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 93, "position": [934.88, 143.6, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 94, "position": [875.7, 173.65, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 95, "position": [186.04, -274.07, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 96, "position": [369.77, -186.49, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 97, "position": [304.35, -359.67, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 98, "position": [575.27, 315.06, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 99, "position": [959.16, -321.55, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 100, "position": [803.25, 172.36, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 101, "position": [117.7, 298.66, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 102, "position": [649.69, -223.0, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 103, "position": [105.71, -187.71, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 104, "position": [826.71, 239.16, -27.3], "normal": [0, 0, 1], "spin": 90}, - {"id": 105, "position": [524.84, -266.25, -27.3], "normal": [0, 0, 1], "spin": 90} - ], - "model": [ - { - "stlFile": "surfaces/Board.stl", - "originOfModel": [0, 0, 0], - "rotationOfModelDegree": [0, 0, -90], - "material": "wood" - }, - { - "stlFile": "surfaces/BoardRail.stl", - "originOfModel": [0, 0, 0], - "rotationOfModelDegree": [0, 0, -90], - "material": "steel" - } - ] - }, - "Base": { - "parent": "Board", - "size": [150, 200, 150], - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [1, 0, 0], - "origin": [0, 0, 16], - "rotation": [0, 0, 0], - "variable": "x" - }, - "skeleton": { - "from": [0, 108, 45], - "to": [110, 108, 45], - "radius": 4, - "color": [0.20, 0.80, 0.20] - }, - "markers": [ - ], - "model": [ - { - "stlFile": "surfaces/Base.stl", - "originOfModel": [-30, 0, -35], - "rotationOfModelDegree": [0, 0, 0], - "material": "plaWhite" - } - ] - }, - "Arm1": { - "parent": "Base", - "size": [70, 250, 70], - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - "jointToParent": { - "name": "Joint1", - "type": "revolute", - "axis": [-1, 0, 0], - "origin": [110, 108, 45], - "rotation": [0, 0, 0], - "variable": "y" - }, - "skeleton": { - "from": [0, 0, 0], - "to": [0, -250, 0], - "radius": 4, - "color": [0.20, 0.20, 0.90] - }, - "markers": [ - { - "id": 198, - "name": "aruco_198", - "position": [0, -160, 35], - "normal": [0, 0, 1], - "size": 25, - "spin": 0 - }, - { - "id": 229, - "name": "aruco_229", - "position": [0, -250, 35], - "normal": [0, 0, 1], - "size": 25, - "spin": 0 - }, - { - "id": 242, - "name": "aruco_242", - "position": [0, -250, -35], - "normal": [0, 0, -1], - "size": 25, - "spin": 0 - }, - { - "id": 243, - "name": "aruco_243", - "position": [0, -285, 0], - "normal": [0, -1, 0], - "size": 25, - "spin": 0 - } - ], - "model": [ - { - "stlFile": "surfaces/Holm.stl", - "originOfModel__": [-25,29,-28.5], - "originOfModel": [-29,25,28.5], - "rotationOfModelDegree__": [0, 0, 0], - "rotationOfModelDegree": [180, 0, -90], - "material": "powderCoatBlue" - } - ] - }, - "Ellbow": { - "parent": "Arm1", - - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - - "jointToParent": { - "name": "Joint2", - "type": "revolute", - "axis": [-1, 0, 0], - "origin": [0, -250, 0], - "rotation": [0, 0, 0], - "variable": "z" - }, - - "skeleton": { - "from": [0, 0, 0], - "to": [90, 0, 0], - "radius": 4, - "color": [0.90, 0.20, 0.20] - }, - "model": [ - { - "stlFile": "surfaces/Ellebogen.stl", - "originOfModel": [90,0,0], - "rotationOfModelDegree": [0,-90,-90], - "material": "defaultPlastic" - } - ], - "markers": [ - {"id": 244, "name": "aruco_244", "position": [125, 0, 0], "normal": [1, 0, 0], "size": 25, "spin": 0}, - {"id": 245, "name": "aruco_245", "position": [90, 0, -35], "normal": [0, 0, -1], "size": 25, "spin": 0}, - {"id": 246, "name": "aruco_246", "position": [90, 0, 35], "normal": [0, 0, 1], "size": 25}, - {"id": 247, "name": "aruco_247", "position": [52.5, 0, 35], "normal": [0, 0, 1], "size": 25}, - {"id": 248, "name": "aruco_248", "position": [52.5, 0, -35], "normal": [0, 0, -1], "size": 25}, - {"id": 232, "name": "aruco_232", "position": [90, 24.75, -24.75], "normal": [0, 1, -1], "size": 25}, - {"id": 231, "name": "aruco_231", "position": [90, 24.75, 24.75], "normal": [0, 1, 1], "size": 25} - ] - - }, - "Arm2": { - "parent": "Ellbow", - - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - - "jointToParent": { - "name": "Joint3", - "type": "revolute", - "axis": [0, -1, 0], - "origin": [90, 0, 0], - "rotation": [0, 0, 0], - "variable": "a" - }, - - "skeleton": { - "from": [0, 0, 0], - "to": [0, -250, 0], - "radius": 4, - "color": [0.95, 0.85, 0.20] - }, - "model": [ - { - "stlFile": "surfaces/Unterarm.stl", - "originOfModel": [0,-250,0], - "rotationOfModelDegree": [180, 0, -90], - "material": "defaultPlastic" - } - ], - "markers":[ - - {"id":120, "position":[24.75, -112, -24.75],"normal":[1,0,-1]}, - {"id":122, "name": "aruco_122", "position":[-35,-112,0], "normal":[-1,0,0]}, - {"id":218, "name": "aruco_218", "position":[35,-112,0], "normal":[1,0,0]}, - {"id":113, "name": "aruco_113", "position":[0, -182, 30],"normal":[0,0,1]}, - {"id":114, "name": "aruco_114", "position":[ 24.75, -182, -24.75],"normal":[ 1,0,-1]}, - {"id":115, "name": "aruco_115", "position":[-24.75, -182, -24.75],"normal":[-1,0,-1]}, - {"id":124, "name": "aruco_124", "position":[-35,-219,0], "normal":[-1,0,0]}, - {"id":219, "name": "aruco_219", "position":[35,-219,0], "normal":[1,0,0]} - - ] - }, - "Hand": { - "parent": "Arm2", - - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - - "jointToParent": { - "name": "Joint4", - "type": "revolute", - "axis": [1, 0, 0], - "origin": [0, -250, 0], - "rotation": [0, 0, 0], - "variable": "b" - }, - - "skeleton": { - "from": [0, 0, 0], - "to": [0, -35, 0], - "radius": 4, - "color": [0.95, 0.55, 0.15] - } - }, - "Palm": { - "parent": "Hand", - - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - - "jointToParent": { - "name": "Joint3", - "type": "revolute", - "axis": [0, -1, 0], - "origin": [0, 0, 0], - "rotation": [0, 0, 0], - "variable": "c" - }, - - "skeleton": { - "from": [-50, -35, 0], - "to": [50, -35, 0], - "radius": 7, - "color": [0.95, 0.20, 0.20] - } - }, - "FingerA": { - "parent": "Palm", - "size": [80, 60, 20], - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [1, 0, 0], - "origin": [4, -35,0], - "rotation": [0, 0, 0], - "variable": "e" - }, - "skeleton": { - "from": [0, 0,0], - "to": [0, -60, 0], - "radius": 4, - "color": [0.20, 0.80, 0.20] - }, - "markers":[ - {"id":40,"position":[12,-24,-17.1],"normal":[-10.98,0,-23.56]}, - {"id":41,"position":[1.5,-2.2,25.8],"normal":[0,-25.6,9.5]}, - {"id":42,"position":[13.9,-40,0],"normal":[1,-0.35,0.40], "spin": 27} - ], - "model": [ - { - "stlFile": "surfaces/Finger.stl", - "originOfModel": [24,0,-9.1], - "rotationOfModelDegree": [90, -90,0], - "material": "defaultPlastic" - } - ] - }, - "FingerB": { - "parent": "Palm", - "size": [80, 60, 20], - "mountPosition": [0, 0, 0], - "mountRotation": [0, 0, 0], - "jointToParent": { - "name": "Slider", - "type": "linear", - "axis": [-1, 0, 0], - "origin": [-4, -35,0], - "rotation": [0, 0, 0], - "variable": "e" - }, - "skeleton": { - "from": [0, 0,0], - "to": [0, -60, 0], - "radius": 4, - "color": [0.20, 0.80, 0.20] - }, - "markers":[ - {"id":43,"position":[-12,-24,17.1],"normal":[10.98,0,23.56], "spin":90 }, - {"id":44,"position":[-1.5,-2.2,-25.8],"normal":[0,-25.6,-9.5], "spin":90}, - {"id":45,"position":[-13.9,-40,0],"normal":[-1,-0.35,-0.40], "spin": -27} - ], - "model": [ - { - "stlFile": "surfaces/Finger.stl", - "originOfModel": [-24,0,9.1], - "rotationOfModelDegree": [90, 90,0], - "material": "defaultPlastic" - } - ] - } - } -} \ No newline at end of file diff --git a/data/robot/surfaces/Base.stl b/data/robot/surfaces/Base.stl deleted file mode 100644 index 6ba6f3f..0000000 Binary files a/data/robot/surfaces/Base.stl and /dev/null differ diff --git a/data/robot/surfaces/Board.stl b/data/robot/surfaces/Board.stl deleted file mode 100644 index c6fd521..0000000 Binary files a/data/robot/surfaces/Board.stl and /dev/null differ diff --git a/data/robot/surfaces/BoardRail.stl b/data/robot/surfaces/BoardRail.stl deleted file mode 100644 index 9a1579a..0000000 Binary files a/data/robot/surfaces/BoardRail.stl and /dev/null differ diff --git a/data/robot/surfaces/Ellebogen.3mf b/data/robot/surfaces/Ellebogen.3mf deleted file mode 100644 index f9cafc0..0000000 Binary files a/data/robot/surfaces/Ellebogen.3mf and /dev/null differ diff --git a/data/robot/surfaces/Ellebogen.stl b/data/robot/surfaces/Ellebogen.stl deleted file mode 100644 index 3289c3f..0000000 Binary files a/data/robot/surfaces/Ellebogen.stl and /dev/null differ diff --git a/data/robot/surfaces/Finger.stl b/data/robot/surfaces/Finger.stl deleted file mode 100644 index 073934e..0000000 Binary files a/data/robot/surfaces/Finger.stl and /dev/null differ diff --git a/data/robot/surfaces/Holm.stl b/data/robot/surfaces/Holm.stl deleted file mode 100644 index 2d4bddb..0000000 Binary files a/data/robot/surfaces/Holm.stl and /dev/null differ diff --git a/data/robot/surfaces/Unterarm.3mf b/data/robot/surfaces/Unterarm.3mf deleted file mode 100644 index 50c04b4..0000000 Binary files a/data/robot/surfaces/Unterarm.3mf and /dev/null differ diff --git a/data/robot/surfaces/Unterarm.stl b/data/robot/surfaces/Unterarm.stl deleted file mode 100644 index d50d5ca..0000000 Binary files a/data/robot/surfaces/Unterarm.stl and /dev/null differ diff --git a/data/robot/surfaces/boden.jpg b/data/robot/surfaces/boden.jpg deleted file mode 100644 index f9c65ab..0000000 Binary files a/data/robot/surfaces/boden.jpg and /dev/null differ diff --git a/doc/Homing_ROADMAP.md b/doc/Homing_ROADMAP.md index d2c31e1..20f72be 100644 --- a/doc/Homing_ROADMAP.md +++ b/doc/Homing_ROADMAP.md @@ -8,374 +8,322 @@ ## Was ist Homing? -Homing = der Roboter weiss **nicht**, wo er ist. +Homing = der Roboter weiss **nicht**, wo er ist. Die Kameras schauen auf das Board + die ArUco-Marker am Roboter und berechnen daraus die vollständige Pose aller Gelenke — ohne mechanische Endschalter. -Homing läuft bei **jedem** Einschalten ab, also muss es schnell und robust sein. +Homing läuft bei **jedem** Einschalten ab: schnell, robust, vollautomatisch. Kalibrierung hingegen läuft nur nach mechanischen Änderungen (≈ einmalig). --- -## Voraussetzungen (Kalibrierung muss abgeschlossen sein) +## Kinematik-Kette (aus `robot.json → links`) -| Was | Wo gespeichert | Status | -|-----|----------------|--------| -| Kamera-Intrinsik (NPZ) | `data/calibration/camX_calibration.npz` | ✅ | -| Board-Marker-Positionen | `robot.json → links.Board.markers[]` | ✅ | -| X-Achsen-Richtung | `robot.json → links.*.position` (rotiert) | ✅ | -| **Arm1-Gelenkursprung Y/Z** | `robot.json → links.Arm1.jointToParent.origin[1,2]` | 🔶 in Arbeit | -| Arm-Marker-Zuordnung | `robot.json → links.Arm1/Ellbow/Arm2/Hand.markers[]` | ❌ offen | +``` +Board (ROOT, fest) ← Referenz aller Kameras +│ +├── Base linear x axis=[1,0,0] ← Slider-Position +├── Arm1 revolute y axis=[-1,0,0] ← Schultergelenk +├── Ellbow revolute z axis=[-1,0,0] ← Ellbogen +├── Arm2 revolute a axis=[0,-1,0] ← Unterarm-Drehung +├── Hand revolute b axis=[1,0,0] ← Handgelenk +├── Palm revolute c axis=[0,-1,0] ← Handfläche +└── FingerA/B linear e axis=±[1,0,0] ← Greifer (symmetrisch) +``` -> **Schlüssel-Erkenntnis:** Sobald `Arm1.jointToParent.origin` korrekt gesetzt ist (aus -> der Y-Achsen-Kalibrierung), ist die gesamte Kinematikkette in `robot.json` geometrisch -> definiert. Dann kann Homing starten. +**Resultat-State:** `{ x_mm, y_deg, z_deg, a_deg, b_deg, c_deg, e_mm }` --- -## Kinematik-Kette (aus `robot.json`) +## Voraussetzungen (Kalibrierung) -``` -Board (ROOT, fest) -│ -├── Base linear variable=x axis=[1,0,0] origin=[0,0,16] -│ → Slider-Position entlang Board-X -│ -├── Arm1 revolute variable=y axis=[-1,0,0] origin=[110, 108*, 45*] -│ → Schultergelenk (heben/senken) *aus Y-Achsen-Kalib. -│ -├── Ellbow revolute variable=z axis=[-1,0,0] origin=[0,-250,0] -│ → Ellbogen (relativ zu Arm1-Ende) -│ -├── Arm2 revolute variable=a axis=[0,-1,0] origin=[90,0,0] -│ → Unterarm-Drehung -│ -├── Hand revolute variable=b axis=[1,0,0] origin=[0,-250,0] -│ → Handgelenk -│ -├── Palm revolute variable=c axis=[0,-1,0] origin=[0,0,0] -│ → Handflächen-Rotation -│ -└── FingerA/B linear variable=e axis=±[1,0,0] origin=[±4,-35,0] - → Greifer (symmetrisch) -``` +| Was | Mechanismus | Status | +|-----|-------------|--------| +| Kamera-Intrinsik (NPZ) | `calibration.html` → Tab Camera NPZ | ✅ fertig | +| Board-Marker-Positionen | `calibration.html` → Tab Board | ✅ fertig | +| X-Achsen-Richtung | `calibration.html` → Tab Robot X-Axis | ✅ fertig | +| **Arm1 Joint-Origin Y/Z** | `calibration.html` → Tab Arm1 → Button „Joint-Origin Y/Z übernehmen" | ✅ **Button vorhanden, ausführbar** | +| Arm-Marker in robot.json | Manuell eintragen (links.Arm1/Ellbow/Arm2/Hand.markers) | 🔶 Nutzer trägt ein | -**Gelenkvariablen:** `x` (mm), `y z a b c` (Grad), `e` (mm) +> **Kalibrierung gilt als abgeschlossen** sobald der Arm1-Button geklickt und +> die Arm-Marker eingetragen sind. --- -## Homing-Ablauf (Schritt für Schritt) +## robot.json – Ladestrategie -### Schritt 1 — Snapshot aufnehmen - -**Was:** Alle Kameras gleichzeitig ein Foto. - -**Script:** — (direkt via Webcam-API) - -**UI-Aktion:** Button `[Foto aufnehmen]` - -**Ausgabe:** -- `cam0.jpg`, `cam1.jpg`, `cam2.jpg` im aktuellen Run-Verzeichnis -- **Snapshots-Sektion:** Kamerabilder erscheinen - ---- - -### Schritt 2 — ArUco-Marker erkennen - -**Was:** Pixel-Koordinaten aller sichtbaren Marker in jedem Kamerabild. - -**Script:** `1_detect_aruco_observations.py` - -```bash -python 1_detect_aruco_observations.py \ - -i cam0.jpg cam1.jpg cam2.jpg \ - -robot robot.json \ - -outDir data/homing/TIMESTAMP/ +### Aktuell: lokale Datei +``` +ROBOT_JSON = process.env.ROBOT_JSON || 'scripts/robot_1781069752019.json' ``` -**Output-Dateien:** -- `cam0_aruco_detection.json` — Marker-IDs + Pixel-Ecken + Kamera-Pose-Kandidaten +### Geplant: vom Driver per API +Der Driver-Service (ROBOT_URL) kennt die aktuelle Roboter-Konfiguration. +Lademechanismus (bereits implementiertes Muster aus `ROBOT_URL`/`BODYTRACKER_URL`): -**Snapshot CSV:** Tabelle: MarkerID | Kamera | px-Koordinaten | confidence - -**Fehlerfälle:** -- Marker verdeckt → weniger Marker in CSV sichtbar -- Schlechte Beleuchtung → confidence niedrig - ---- - -### Schritt 3 — Kamera-Posen schätzen - -**Was:** Aus den Board-Markern (fix im Raum) die extrinsische Lage jeder Kamera -berechnen. - -**Script:** `2_estimate_camera_from_observations.py` - -```bash -python 2_estimate_camera_from_observations.py \ - -i data/homing/TIMESTAMP/ \ - -robot robot.json \ - -outDir data/homing/TIMESTAMP/ +``` +GET ROBOT_URL/api/robot/config → robot.json Inhalt ``` -**Output-Dateien:** -- `cam0_camera_pose.json` — 4×4 Transformationsmatrix Kamera→Welt - -**Analysis & Reasoning:** Reprojektions-Fehler pro Kamera (sollte < 3 px) - -**Fehlerfälle:** -- Zu wenig Board-Marker sichtbar (< 3) → Kamera-Pose nicht berechenbar -- Hoher Reprojektions-Fehler → Kalibrierung möglicherweise veraltet - ---- - -### Schritt 3b — 3D-Marker-Positionen triangulieren - -**Was:** Aus den Kamera-Posen und den Pixel-Koordinaten die echten 3D-Positionen -aller Marker berechnen (inkl. Arm-Marker). - -**Script:** `3b_corner_marker_poses.py` - -```bash -python 3b_corner_marker_poses.py \ - -i data/homing/TIMESTAMP/ \ - -robot robot.json \ - --outDir data/homing/TIMESTAMP/ -``` - -**Output-Dateien:** -- `aruco_marker_poses.json` — für jeden Marker: `position_mm`, `normal`, `corners_m`, `link` - -**Snapshot CSV:** Vollständige Marker-Tabelle mit triangulierten 3D-Positionen - -**Fehlerfälle:** -- Marker nur in 1 Kamera → keine Triangulation möglich (braucht ≥ 2) - ---- - -### Schritt 4 — Gelenkwinkel bestimmen - -Zwei Methoden — **4b** ist sequenziell und robuster: - -#### Methode A — Vollständige State-Schätzung (schnell) - -**Script:** `4_robotState_estimation_v6.py` - -```bash -python 4_robotState_estimation_v6.py \ - aruco_marker_poses.json \ - --robot robot.json \ - --output homing_state.json -``` - -Schätzt alle Gelenke in einem Durchlauf mit geometrischen Gleichungen -(Kabsch-Fit, Projektions-Residuen, 2D-Winkel). - -#### Methode B — Sequenziell Gelenk für Gelenk (robuster) - -**Script:** `4b_revolute_angle.py` — einmal pro Gelenk, von root nach tip: - -```bash -# Slider-Position (x) aus Board-Markern bekannt → manuell oder aus 4a -python 4b_revolute_angle.py --robot robot.json --aruco aruco_marker_poses.json \ - --link Arm1 --x-mm 180 --output state_arm1.json - -python 4b_revolute_angle.py --robot robot.json --aruco aruco_marker_poses.json \ - --link Ellbow --from-state state_arm1.json --output state_ellbow.json - -python 4b_revolute_angle.py --robot robot.json --aruco aruco_marker_poses.json \ - --link Arm2 --from-state state_ellbow.json --output state_arm2.json - -python 4b_revolute_angle.py --robot robot.json --aruco aruco_marker_poses.json \ - --link Hand --from-state state_arm2.json --output state_hand.json -``` - -Jedes `--from-state` enthält den akkumulierten Gelenk-State aus allen -vorherigen Schritten. - -**Warum sequenziell?** Arm2-Winkel kann nur korrekt berechnet werden wenn -Arm1 und Ellbow bereits bekannt sind (der Weltachsenvektor des Arm2-Joints -ändert sich mit den vorherigen Gelenkwinkeln). - -**Output-JSON-Struktur (pro Schritt):** -```json -{ - "link": "Arm1", - "joint": "y", - "mean_angle_deg": 23.4, - "circular_std_deg": 0.8, - "num_pairs": 6, - "joint_origin_world_mm": [290, 108, 45], - "joint_axis_world": [-1, 0, 0], - "accumulated_state": { "x": 180, "y": 23.4, "z": null, "a": null, ... } +**Implementierung (Backend `server.js`):** +```javascript +async function loadRobotConfig() { + if (ROBOT_URL) { + // Vom Driver holen + const res = await fetch(new URL('/api/robot/config', ROBOT_URL)); + return res.json(); + } + // Fallback: lokale Datei + return JSON.parse(await fs.readFile(ROBOT_JSON, 'utf8')); } ``` -**Analysis & Reasoning:** Gelenk-für-Gelenk-Ergebnis als JSON-Baum +**Konsequenz für Homing:** Das Homing-Script bekommt robot.json als +temporäre Datei (bereits vorhandenes Muster: `ROBOT_JSON` als Pfad an Python). +Falls ROBOT_URL konfiguriert: zuerst fetch → temp-Datei schreiben → Script aufrufen. -**Fehlerfälle:** -- `circular_std_deg` > 5° → Marker-Konfiguration fragwürdig, Messung wiederholen -- `num_pairs` < 2 → Arm-Marker nicht genug sichtbar +**Priorität:** Kann nach dem restlichen Homing implementiert werden. +Solange ROBOT_URL nicht konfiguriert, läuft alles mit der lokalen Datei. --- -### Schritt 5 (optional) — Kamera-Z verfeinern +## X-Position (Slider) – Bestimmung -**Was:** Kamera-Höhe (Z) ist aus Board-Markern schlecht bestimmt (Board ist flach). -Wenn Ellbow-Winkel bekannt → FK-Vorhersage als Z-Referenz nutzen. +Die Slider-Position `x` wird **nicht** manuell eingegeben, sondern aus den +triangulierten Marker-Positionen berechnet (nach Schritt 3b). -**Script:** `5_camera_z_refine.py` +**Ansatz:** Die absolute X-Position eines bekannten Arm-Markers im +Board-Koordinatensystem enthält direkt die Slider-Information — +alle anderen Gelenke sind rotatorisch und verschieben den Marker nicht +entlang der X-Achse des Boards. -```bash -python 5_camera_z_refine.py \ - --angle state_ellbow.json \ - --robot robot.json \ - --aruco aruco_marker_poses.json \ - -pose cam0_camera_pose.json \ - -pose cam1_camera_pose.json \ - --outDir data/homing/TIMESTAMP/ +Alternativ: Schwerpunkt der Board-nahen A0-Marker projiziert auf die X-Achse +(robust, braucht keine Arm-Marker). + +**In `4b_revolute_angle.py`:** `--x-mm` wird aus `aruco_marker_poses.json` +berechnet und als erstes Argument übergeben. Alle weiteren 4b-Aufrufe +nutzen `--from-state` des vorherigen Schritts. + +--- + +## Homing-Ablauf (Script-Kette) + +``` +[Foto] → [1_detect] → [2_camera] → [3b_poses] + │ + ▼ + [4b Arm1] + [4b Ellbow] + [4b Arm2] + [4b Hand] + │ + ▼ + State-JSON + {x,y,z,a,b,c,e} + │ + ▼ + POST ROBOT_URL/api/state ``` -**Output:** Korrigierte `*_camera_pose_v8.json` + `z_correction.json` - -**Wann nötig:** Wenn Residuen in Schritt 4 systematisch in Z-Richtung driften. +**Strategie:** `4b_revolute_angle.py` sequenziell, Link für Link von root nach tip. +X-Position (`--x-mm`) wird aus den triangulierten Board-Marker-Positionen bestimmt. --- -### Schritt 6 — Ergebnis senden +## Implementierungsplan: Homing-UI -**Was:** Vollständigen Joint-State an Roboter-Controller übermitteln. +### Phase 1 — Backend-Route `POST /api/homing/run` -**UI-Aktion:** Button `[An Roboter senden]` +**Datei:** `server/server.js` (neue Route) + `server/homingOrchestrator.js` (neue Datei) -**Body:** `{ x, y, z, a, b, c, e }` -→ `POST ROBOT_URL/api/state` (oder Motion-Controller-Protokoll) +**Ablauf als SSE-Stream:** -**Result – Raw JSON:** -```json -{ - "status": "ok", - "timestamp": "2026-06-13T19:00:00", - "state": { "x": 180.0, "y": 23.4, "z": -12.1, "a": 5.0, "b": 0.0, "c": 0.0, "e": 0.0 }, - "confidence": { "y_std_deg": 0.8, "z_std_deg": 1.2 } +```javascript +// server/homingOrchestrator.js +export async function runHoming({ robotJsonPath, boardDataDir, send, options }) { + + // 1. Snapshot (Webcam-API) + send({ type: 'step', step: 1, text: 'Foto aufnehmen …' }); + const runDir = await takeSnapshot(); // WEBCAM_URL + + // 2. Marker erkennen + send({ type: 'step', step: 2, text: 'Marker erkennen …' }); + await runScript(['1_detect_aruco_observations.py', + '-i', ...camImages, '-robot', robotJsonPath, '-outDir', runDir], send); + + // 3. Kamera-Posen + send({ type: 'step', step: 3, text: 'Kamera-Posen schätzen …' }); + await runScript(['2_estimate_camera_from_observations.py', + '-i', runDir, '-robot', robotJsonPath, '-outDir', runDir], send); + + // 3b. 3D-Triangulation + send({ type: 'step', step: 4, text: '3D-Positionen triangulieren …' }); + await runScript(['3b_corner_marker_poses.py', + '-i', runDir, '-robot', robotJsonPath, '--outDir', runDir], send); + + // 4. X-Position aus triangulierten Board-Markern bestimmen + const xMm = estimateXFromMarkers(arucoJson); // aus position_mm der A0-Marker + + // 4b. Gelenkwinkel sequenziell, Link für Link + const links = ['Arm1', 'Ellbow', 'Arm2', 'Hand']; + let fromState = null; + for (const link of links) { + send({ type: 'step', text: `Gelenkwinkel ${link} …` }); + const args = ['4b_revolute_angle.py', + '--robot', robotJsonPath, '--aruco', arucoJson, + '--link', link, + '--output', path.join(runDir, `state_${link}.json`), + ]; + if (fromState) args.push('--from-state', fromState); + else args.push('--x-mm', String(xMm)); + fromState = await runScript(args, send); + } + + // Ergebnis + const finalState = JSON.parse(fs.readFileSync(fromState)); + send({ type: 'done', state: finalState.accumulated_state, runDir }); } ``` -**Result – Tree View:** Gelenk-Werte als lesbare Tabelle +**Route:** +```javascript +app.post('/api/homing/run', async (req, res) => { + // SSE-Header + res.setHeader('Content-Type', 'text/event-stream'); + const send = (data) => res.write(`data: ${JSON.stringify(data)}\n\n`); + await runHoming({ robotJsonPath: ROBOT_JSON, boardDataDir, send }); + res.end(); +}); ---- - -## UI-Seitenstruktur (analog index.html) - -``` -┌─────────────────────────────────────────┐ -│ AKTIONEN │ -│ [Foto aufnehmen] [Homing berechnen] │ -│ [An Roboter senden] │ -├─────────────────────────────────────────┤ -│ AUSGABE / LOG │ -│ Schritt-für-Schritt Log aller Scripts │ -├─────────────────────────────────────────┤ -│ ANALYSIS & REASONING │ -│ Kamera-Posen, Reprojektionsfehler, │ -│ Gelenk-Schätzungen je Schritt als JSON │ -├──────────────────┬──────────────────────┤ -│ RESULT – RAW JSON │ RESULT – TREE │ -│ Vollst. State-JSON │ Gelenk-Tabelle │ -├─────────────────────────────────────────┤ -│ SNAPSHOT CSV │ -│ Tabelle aller Marker: ID, Position, │ -│ Link, Residual, num_cameras │ -├─────────────────────────────────────────┤ -│ SNAPSHOTS (Bilder) │ -│ Annotierte Kamerabilder mit Markern │ -└─────────────────────────────────────────┘ +app.post('/api/homing/send-state', async (req, res) => { + // Sendet { x, y, z, a, b, c, e } an ROBOT_URL/api/state +}); ``` --- -## Offene Punkte (Voraussetzungen für Homing) +### Phase 2 — Frontend `public/homing.html` -### 🔶 A — Arm-Marker in robot.json eintragen +Neue Seite (zugänglich von `index.html` via Link-Button, wie `calibration.html`). -Die Arm-Links haben noch **keine Marker** in `robot.json` (links.Arm1/Ellbow/Arm2/Hand.markers). +**Sektionen (identisches Muster wie `index.html`):** -Mögliche Quellen: -- Aus der Y-Achsen-Kalibrierung: Marker 197, 218, 219 wurden als rotierend erkannt - → diese können mit relativen Positionen in den jeweiligen Links eingetragen werden -- Mit `4b_revolute_angle.py` lässt sich pro Link prüfen, welche Marker - "zu diesem Link gehören" (paarweise Baseline-Methode) +``` +┌──────────────────────────────────────────────────────┐ +│ AKTIONEN │ +│ [📷 Foto & Homing berechnen] │ +│ [✅ An Roboter senden] (disabled bis Ergebnis) │ +│ Status-Badge: ○ Warte ● Läuft ✓ Fertig ✗ Fehler │ +├──────────────────────────────────────────────────────┤ +│ AUSGABE / LOG │ +│ Schritt-für-Schritt Log aller Scripts (SSE-Stream) │ +│ Fortschritt: ──── Schritt 3/6 ──── │ +├──────────────────────────────────────────────────────┤ +│ ANALYSIS & REASONING │ +│ Zwischenergebnisse je Script als JSON │ +│ { camera_reprojection_px, arm1_std_deg, … } │ +├──────────────────┬───────────────────────────────────┤ +│ RESULT RAW JSON │ RESULT TREE VIEW │ +│ { │ x (Slider): 180.0 mm │ +│ "x": 180.0, │ y (Arm1): +23.4° │ +│ "y": 23.4, │ z (Ellbow): -12.1° │ +│ ... │ a (Arm2): +5.0° │ +│ } │ b (Hand): 0.0° │ +│ │ c (Palm): 0.0° │ +│ │ e (Greifer): 0.0 mm │ +├──────────────────┴───────────────────────────────────┤ +│ SNAPSHOT CSV (Marker-Tabelle) │ +│ ID │ Link │ x mm │ y mm │ z mm │ Residual │ │ +│ 218 │ Arm2 │ 229.1 │ 118.5 │ 48.3 │ 2.1 mm │ │ +├──────────────────────────────────────────────────────┤ +│ SNAPSHOTS (annotierte Kamerabilder) │ +│ [cam0] [cam1] [cam2] │ +└──────────────────────────────────────────────────────┘ +``` -**Aktion:** Für jedes Arm-Segment mind. 2 Marker bestimmen und in robot.json eintragen. +**Schlüssel-Implementierungsdetails:** -### 🔶 B — Arm1.jointToParent.origin[Y, Z] finalisieren +```javascript +// homing.js (client) -Aus der Arm1-Y-Achsen-Kalibrierung (calibration_arm.html): -- Berechneter Wert: Y ≈ 115.6 mm, Z ≈ 50.3 mm -- Aktueller Wert in robot.json: origin = [110, 108, 45] -- **Aktion:** Button „Joint-Origin Y/Z übernehmen" klicken → schreibt in robot.json +// SSE-Stream vom Backend empfangen +async function runHoming() { + const response = await fetch('/api/homing/run', { method: 'POST' }); + await readSseStream(response, appendLog, (evt) => { + if (evt.type === 'step') { updateProgress(evt); } + if (evt.type === 'analysis') { showAnalysis(evt.data); } + if (evt.type === 'done') { + showResult(evt.state); + enableSendButton(evt.state); + } + }); +} -### 🔶 C — X-Position (Slider) im Homing - -Die Slider-Position `x` ist für `4b_revolute_angle.py --x-mm` nötig. -Optionen: -1. Mechanischer Anschlag / Encoder → immer bekannt -2. Aus Board-Markern schätzen (funktioniert wenn A0-Marker sichtbar) -3. Manuell eingeben (Fallback) - -### 🔶 D — Homing-Seite implementieren - -Eine neue `homing.html`-Seite (oder Tab in `calibration.html`) die: -- Die Script-Kette 1 → 2 → 3b → 4b(je Link) → (5) als SSE-Stream orchestriert -- Alle Ausgabe-Sektionen wie in index.html befüllt -- „An Roboter senden" Button mit finalem State-JSON verdrahtet +// Ergebnis an Roboter senden +async function sendToRobot(state) { + await fetch('/api/homing/send-state', { + method: 'POST', + body: JSON.stringify({ state }), + }); +} +``` --- -## Script-Abhängigkeitsgraph +### Phase 3 — robot.json via Driver-API + +**Voraussetzung:** ROBOT_URL ist konfiguriert und der Driver hat `GET /api/robot/config`. + +**Implementierung in `server.js`:** +```javascript +// Beim Start oder on-demand: robot.json vom Driver laden +async function fetchRobotConfig() { + if (!ROBOT_URL) return; // lokale Datei reicht + const res = await fetch(new URL('/api/robot/config', ROBOT_URL)); + if (!res.ok) return; // Fallback auf lokale Datei + const data = await res.json(); + // Temporär in data/robot/robot_live.json cachen + await fs.writeFile(ROBOT_JSON_LIVE, JSON.stringify(data, null, 2)); +} +``` + +**Auswirkung:** Nur `ROBOT_JSON` Variable ändern — alle Scripts bekommen +automatisch die aktuelle Konfiguration. + +--- + +## Reihenfolge der Implementierung ``` -Kamera-Snapshot - │ - ▼ -[1] detect_aruco → cam*_aruco_detection.json - │ - ▼ -[2] estimate_camera → cam*_camera_pose.json - │ (aus Board-Markern) - ▼ -[3b] corner_marker_poses → aruco_marker_poses.json - │ (alle Marker trianguliert) - ├──────────────────────────────────────┐ - ▼ ▼ -[4b] revolute Arm1 [4] state_v6 (alternativ) - │ -[4b] revolute Ellbow ──► [5] camera_z_refine (optional, nutzt Ellbow) - │ -[4b] revolute Arm2 - │ -[4b] revolute Hand - │ - ▼ - State-JSON {x, y, z, a, b, c, e} - │ - ▼ - → Roboter-Controller +[Jetzt] Arm-Marker eintragen (Nutzer) + → Arm1 Joint-Origin Button klicken (bereits ausführbar) + +[1] POST /api/homing/run + homingOrchestrator.js + → Script-Kette als SSE orchestrieren + → Minimale UI: nur Log + Raw JSON + +[2] public/homing.html + → Vollständige UI mit allen Sektionen + → Link von index.html + +[3] POST /api/homing/send-state + → ROBOT_URL/api/state aufrufen (analog zu robotActions.js) + +[4] robot.json via Driver-API (wenn ROBOT_URL verfügbar) + → Nur wenn Driver den Endpunkt implementiert ``` --- ## Status-Tabelle -| Schritt | Script | Status | Blockiert durch | -|---------|--------|--------|-----------------| -| 1 Snapshot | Webcam-API | ✅ vorhanden | — | -| 2 Marker erkennen | `1_detect_aruco.py` | ✅ vorhanden | — | -| 3 Kamera-Pose | `2_estimate_camera.py` | ✅ vorhanden | — | -| 3b Triangulation | `3b_corner_marker_poses.py` | ✅ vorhanden | — | -| 4 State-Schätzung | `4_robotState_estimation_v6.py` | ✅ vorhanden | Arm-Marker fehlen | -| 4b Sequenziell | `4b_revolute_angle.py` | ✅ vorhanden | Arm-Marker fehlen | -| 5 Z-Verfeinern | `5_camera_z_refine.py` | ✅ vorhanden | Ellbow-Marker fehlen | -| **Arm1-Origin** | calibration_arm.html | 🔶 bereit | Joint-Origin Y/Z übernehmen | -| **Arm-Marker** | robot.json | ❌ fehlen | manuelle Zuordnung | -| **Homing-UI** | homing.html | ❌ fehlt | erst nach Markern sinnvoll | +| Schritt | Was | Status | +|---------|-----|--------| +| Scripts 1, 2, 3b, 4b | Homing-Scripts | ✅ vorhanden | +| Kalibrierung | Kamera, Board, X-Achse | ✅ fertig | +| Arm1 Joint-Origin | Button in calibration_arm.html | ✅ **ausführbar** | +| Arm-Marker | robot.json links.Arm1/… .markers | 🔶 Nutzer trägt ein | +| `/api/homing/run` | Backend-Orchestrierung | ❌ zu implementieren | +| `homing.html` | Frontend-UI | ❌ zu implementieren | +| `/api/homing/send-state` | State an Roboter | ❌ zu implementieren | +| robot.json via API | Driver-Integration | ⏳ nach allem anderen |