{
 "meta": {
  "asset": "DoorRobotArm",
  "date": "2026-10-18",
  "status": "scale-up 1.6x and door-centre attach (the Coder), from design_base.json by build/dra_scaleup.py",
  "standalone": true,
  "user_words": [
   "3d model this in blender. Understand the picture references and rig it accordingly and mechanically.",
   "according to the open and close animation fit it to the scene ... also consider the rail accordingly.",
   "do 2 version with and without the grab limbs shown in the red lined picture ... dont miss details",
   "this will be standalone project dont add on the ship yet"
  ]
 },
 "scale": {
  "m_per_ref1_px": 0.0022,
  "how": "chosen so the hanging arm reaches its door with good joint angles (design_search*.py); ref1 pixels x 0.0022 = metres; the whole arm uses this one scale"
 },
 "scene": {
  "context_file": "source/ship_context_2026-10-16.blend",
  "context_json": "source/ship_context_2026-10-16.json",
  "note": "objects in the context file are in no scene: link them into a scene before evaluating animation",
  "deck_underside_z": -3.755,
  "rail": {
   "AFT": [
    -9.0348,
    -3.12
   ],
   "FORE": [
    9.22,
    15.1348
   ],
   "y": [
    -4.16608,
    -3.43392
   ],
   "z": [
    -4.163,
    -3.755
   ],
   "usable_AFT": [
    -9.0348,
    -3.12
   ],
   "usable_FORE": [
    9.22,
    15.1348
   ],
   "beam": "the arm's own rail beam (DoorArm_<door> | rail beam), 0.732 x 0.408 m, from the pocket's end wall to 0.03 m short of the deck's edge, its top on the deck's underside; the user's rail boxes are hidden",
   "stops": {
    "buffer": 0.048,
    "gap": 0.0165,
    "end_plate": 0.0192,
    "note": "end stops at both travel ends: rubber buffer on a steel block; at the inner end the block is the beam's end plate"
   }
  },
  "end_wall_faces_x": {
   "AFT": -9.0348,
   "FORE": 15.1348
  },
  "mirror_plane_x": 3.05,
  "door_frames": {
   "closed": 1,
   "retracted_inboard": 12,
   "open": 48,
   "close_starts": 72,
   "retracted_again": 108,
   "closed_again": 120,
   "fps": 30
  },
  "lamps": {
   "AFT_housing": [
    [
     -0.8231,
     -7.6437,
     -3.8468
    ],
    [
     1.0069,
     -6.9727,
     -3.5723
    ]
   ],
   "FORE_housing": [
    [
     5.0931,
     -7.6437,
     -3.8468
    ],
    [
     6.9231,
     -6.9727,
     -3.5723
    ]
   ]
  }
 },
 "kinematics": {
  "scale_m_per_px": 0.0022,
  "frame_A": "upright arm frame at rest: origin turntable face centre, +X forward (toward the tool), +Y the arm's left, +Z up (away from the carriage). In the ship the arm hangs: ArmRoot = carriage underside centre rotated 180 deg about world X (A's +Z = world -Z, A's +Y = world -y).",
  "joints": {
   "J1": {
    "name": "turret yaw",
    "parent": "ArmRoot",
    "origin": [
     0,
     0,
     0
    ],
    "axis": "+Z",
    "channel": "rotation_euler[2]",
    "sign": 1,
    "limits": [
     -185.0,
     185.0
    ],
    "ref": "turntable (ref1 x_img 1000)"
   },
   "J2": {
    "name": "shoulder pitch",
    "parent": "Turret",
    "origin": [
     -0.5456,
     0.0,
     0.8272
    ],
    "axis": "-Y",
    "channel": "rotation_euler[1]",
    "sign": -1,
    "limits": [
     -72.0,
     43.0
    ],
    "ref": "perforated drum + orange-ring side caps (1155,1315)"
   },
   "J3": {
    "name": "elbow pitch",
    "parent": "LowerArm",
    "origin": [
     -1.936,
     0.0,
     2.9216
    ],
    "axis": "-Y",
    "channel": "rotation_euler[1]",
    "sign": -1,
    "limits": [
     -28.75,
     66.0
    ],
    "ref": "black slotted elbow cap (1550,720); driven by the J3 cylinder"
   },
   "J4": {
    "name": "forearm roll",
    "parent": "UpperArm",
    "origin": [
     0.24672,
     0.0,
     3.29824
    ],
    "axis": "+X",
    "channel": "rotation_euler[0]",
    "sign": 1,
    "limits": [
     -170,
     170
    ],
    "ref": "ringed roll section ahead of the upper arm's big cap (x_img 1025-1045)"
   },
   "J5": {
    "name": "wrist pitch",
    "parent": "Forearm",
    "origin": [
     2.232,
     0.0,
     3.29824
    ],
    "axis": "+Y",
    "channel": "rotation_euler[1]",
    "sign": 1,
    "limits": [
     -90.5,
     120.0
    ],
    "ref": "wrist round cap with concentric rings (565,613) = wrist centre WC"
   },
   "J6": {
    "name": "flange roll",
    "parent": "WristHead",
    "origin": [
     2.232,
     0.0,
     3.29824
    ],
    "axis": "+X",
    "channel": "rotation_euler[0]",
    "sign": 1,
    "limits": [
     -170,
     170
    ],
    "ref": "knurled neck ring / gripper hub turns about the tool axis"
   }
  },
  "L2": 2.513906,
  "d4": 4.168,
  "a3": 0.37664,
  "L3": 4.184983,
  "beta_rad": 0.09012,
  "phi_l0_rad": 2.156857,
  "j2_r": 0.5456,
  "j2_h": 0.8272,
  "wc_rest_A": [
   2.232,
   0.0,
   3.29824
  ],
  "j3_rest_A": [
   -1.936,
   0.0,
   2.9216
  ],
  "flange_from_wc": 0.2112,
  "rod": {
   "trunnion_rest_A": [
    -1.38336,
    0.0,
    1.3552
   ],
   "knob_rest_A": [
    -2.599883,
    0.0,
    2.47557
   ],
   "trunnion_in_lower": [
    -0.83776,
    0.0,
    0.528
   ],
   "knob_in_upper": [
    -0.663883,
    0.0,
    -0.44603
   ],
   "length_rest": 1.653831,
   "type": "double-acting hydraulic cylinder on a middle trunnion (the knee pin); barrel 0.480 m behind and 0.800 m ahead of the trunnion; rod 1.280 m from its eye to the piston; bore floor 0.432 m behind the trunnion",
   "rod_len": 1.28,
   "bore": [
    -0.432,
    0.8
   ],
   "stroke_window_build_units": [
    0.535,
    1.26
   ]
  },
  "scale_note": "the part builders work in build units (ref1 px x 0.0022 m); the meshes are scaled 1.60x about the turntable face; every number in this file is in metres after the scale"
 },
 "doors": {
  "AFT": {
   "door": "Moonpool_Door_Aft",
   "side": 1,
   "closed_location": [
    0.2216,
    -6.1,
    -7.503
   ],
   "open_x": -5.91791,
   "closed_x": 0.22163,
   "retracted_y": -4.88,
   "closed_y": -6.1,
   "z": -7.503,
   "rail": "DoorArm_AFT | rail beam",
   "end_wall": "Pocket AFT | conformal closed end",
   "attach_local": [
    -0.08578,
    -0.70531,
    -0.61791
   ],
   "normal_local": [
    0.0,
    0.742230952,
    0.670144141
   ],
   "tool_axes_world": {
    "x_t": [
     -0.0,
     -0.742230952,
     -0.670144141
    ],
    "y_t": [
     -1.0,
     0.0,
     0.0
    ],
    "z_t": [
     0.0,
     0.670144141,
     -0.742230952
    ]
   },
   "tool_roll_deg": 180.0,
   "tool_axes_C": {
    "x_t": [
     -0.0,
     0.742230952,
     0.670144141
    ],
    "y_t": [
     -1.0,
     0.0,
     0.0
    ],
    "z_t": [
     0.0,
     -0.670144141,
     0.742230952
    ]
   },
   "carriage": {
    "c_closed": -3.8709,
    "c_open": -5.5,
    "travel": 1.6291,
    "formula": "c = c_open + (door_x - open_x) * (c_closed - c_open) / (closed_x - open_x)",
    "A": -3.929709,
    "B": 0.265346,
    "note": "c = A + B * door_x; the carriage runs at B of the door's speed"
   },
   "wrist_branch": -1,
   "wc_local": {
    "A": [
     -0.08578,
     0.042859,
     0.057595
    ],
    "B": [
     -0.08578,
     -0.31267,
     -0.263404
    ]
   },
   "tool_roll_A_deg": 10.0,
   "tool_axes_world_A": {
    "x_t": [
     -0.0,
     -0.742230952,
     -0.670144141
    ],
    "y_t": [
     -0.984807753,
     0.116369309,
     -0.128887052
    ],
    "z_t": [
     0.173648178,
     0.659963146,
     -0.730954796
    ]
   },
   "tool_axes_C_A": {
    "x_t": [
     -0.0,
     0.742230952,
     0.670144141
    ],
    "y_t": [
     -0.984807753,
     -0.116369309,
     0.128887052
    ],
    "z_t": [
     0.173648178,
     -0.659963146,
     0.730954796
    ]
   },
   "attach_note": "the door's centre: the middle of its length (local x) and of its curved inner face by arc length (build/door_centre.json)"
  },
  "FORE": {
   "door": "Moonpool_Door_Fore",
   "side": -1,
   "closed_location": [
    5.8784,
    -6.1,
    -7.503
   ],
   "open_x": 12.01791,
   "closed_x": 5.87837,
   "retracted_y": -4.88,
   "closed_y": -6.1,
   "z": -7.503,
   "rail": "DoorArm_FORE | rail beam",
   "end_wall": "Pocket FORE | conformal closed end",
   "attach_local": [
    0.08578,
    -0.70531,
    -0.61791
   ],
   "normal_local": [
    0.0,
    0.742230952,
    0.670144141
   ],
   "tool_axes_world": {
    "x_t": [
     -0.0,
     -0.742230952,
     -0.670144141
    ],
    "y_t": [
     -1.0,
     0.0,
     0.0
    ],
    "z_t": [
     0.0,
     0.670144141,
     -0.742230952
    ]
   },
   "tool_roll_deg": 180.0,
   "tool_axes_C": {
    "x_t": [
     -0.0,
     0.742230952,
     0.670144141
    ],
    "y_t": [
     -1.0,
     0.0,
     0.0
    ],
    "z_t": [
     0.0,
     -0.670144141,
     0.742230952
    ]
   },
   "carriage": {
    "c_closed": 9.9709,
    "c_open": 11.6,
    "travel": 1.6291,
    "formula": "c = c_open + (door_x - open_x) * (c_closed - c_open) / (closed_x - open_x)",
    "A": 8.4111,
    "B": 0.265346,
    "note": "c = A + B * door_x; the carriage runs at B of the door's speed"
   },
   "wrist_branch": -1,
   "wc_local": {
    "A": [
     0.08578,
     0.042859,
     0.057595
    ],
    "B": [
     0.08578,
     -0.31267,
     -0.263404
    ]
   },
   "tool_roll_A_deg": -10.0,
   "tool_axes_world_A": {
    "x_t": [
     -0.0,
     -0.742230952,
     -0.670144141
    ],
    "y_t": [
     -0.984807753,
     -0.116369309,
     0.128887052
    ],
    "z_t": [
     -0.173648178,
     0.659963146,
     -0.730954796
    ]
   },
   "tool_axes_C_A": {
    "x_t": [
     -0.0,
     0.742230952,
     0.670144141
    ],
    "y_t": [
     -0.984807753,
     0.116369309,
     -0.128887052
    ],
    "z_t": [
     -0.173648178,
     -0.659963146,
     0.730954796
    ]
   },
   "attach_note": "the door's centre: the middle of its length (local x) and of its curved inner face by arc length (build/door_centre.json)"
  }
 },
 "tools": {
  "A": {
   "name": "gripper (grab limbs)",
   "d_t": 1.008,
   "wc_to_flange": 0.2112,
   "hub_len": 0.264,
   "hub_dia": 0.44,
   "stud_head_centre_from_wc": 0.704,
   "door_pad": 0.032,
   "note": "WC -> door face along the approach axis: version A as before, x 1.6",
   "pad_size": 0.512
  },
  "B": {
   "name": "plate (red sketch, ref6)",
   "d_t": 0.529,
   "wc_to_flange": 0.2112,
   "neck_len": 0.208,
   "neck_dia": [
    0.2464,
    0.416
   ],
   "plate": [
    1.2,
    1.2,
    0.0704
   ],
   "door_pad": 0.0394,
   "note": "WC -> door face: flange 0.2112 + neck 0.208 + plate 0.0704 + pad top 0.0394 (the pad is 1.3 m square, 12 mm thick where the hollow face rises most, at its edges); B solves its own pose",
   "pad_size": 1.3
  }
 },
 "carriage": {
  "size": {
   "along_rail": 1.3728,
   "across": 1.3728,
   "height": 0.6512,
   "ref_px": [
    390,
    390,
    185
   ]
  },
  "underside_z": -4.4382,
  "top_z": -3.787,
  "centre_y": -3.8,
  "travel_ends": {
   "AFT": [
    -5.5,
    -3.8709
   ],
   "FORE": [
    9.9709,
    11.6
   ]
  }
 },
 "energy_chain": {
  "AFT": {
   "fixed_x": -4.6854,
   "length": 1.8,
   "bend_radius": 0.24,
   "pitch": 0.12,
   "links": 15,
   "y_moving_run": -2.896,
   "y_fixed_run": -2.416,
   "bend_toward": -1,
   "moving_offset": 0.0,
   "z_bottom": -3.971,
   "z_top": -3.811,
   "link_size": [
    0.12,
    0.096,
    0.16
   ],
   "tray": {
    "x": [
     -6.026,
     -3.711
    ],
    "y": [
     -2.976,
     -2.336
    ],
    "floor_top_z": -3.979,
    "wall_top_z": -3.795,
    "end_slant": {
     "at_y": [
      -2.976,
      -2.336
     ],
     "x": [
      -3.711,
      -3.711
     ]
    },
    "note": "only where the chain runs (the travel is 1.63 m); square ends, well under the deck"
   },
   "check": "the loop's far end stays inside the tray and both runs keep >= 0 length over the whole travel"
  },
  "FORE": {
   "fixed_x": 10.7855,
   "length": 1.8,
   "bend_radius": 0.24,
   "pitch": 0.12,
   "links": 15,
   "y_moving_run": -2.896,
   "y_fixed_run": -2.416,
   "bend_toward": 1,
   "moving_offset": 0.0,
   "z_bottom": -3.971,
   "z_top": -3.811,
   "link_size": [
    0.12,
    0.096,
    0.16
   ],
   "tray": {
    "x": [
     9.811,
     12.126
    ],
    "y": [
     -2.976,
     -2.336
    ],
    "floor_top_z": -3.979,
    "wall_top_z": -3.795,
    "end_slant": {
     "at_y": [
      -2.976,
      -2.336
     ],
     "x": [
      9.811,
      9.811
     ]
    },
    "note": "only where the chain runs (the travel is 1.63 m); square ends, well under the deck"
   },
   "check": "the loop's far end stays inside the tray and both runs keep >= 0 length over the whole travel"
  }
 },
 "parts": {
  "Carriage": [
   {
    "id": "C01",
    "name": "turntable plate (ref: top plate)",
    "shape": "rbox",
    "size": [
     390,
     390,
     20,
     25
    ],
    "at": [
     0,
     0,
     -10
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "rounded corners R25, 3 px chamfer; a raised rounded pad 330x330x4 px in its middle under the slewing ring (r7)"
   },
   {
    "id": "C02",
    "name": "stacked plates x5",
    "shape": "rbox",
    "size": [
     386,
     386,
     13,
     24
    ],
    "at": [
     0,
     0,
     -27
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "five plates 13 px thick with 2.5 px V-grooves between them (Z -20..-95); alternate plates inset 2 px; worn lighter edges (r1-3 show scratched paint on the dark carriage)"
   },
   {
    "id": "C03",
    "name": "strap band",
    "shape": "rbox",
    "size": [
     392,
     392,
     40,
     22
    ],
    "at": [
     0,
     0,
     -115
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "Z -95..-135; on both rail-side faces (+-Y, the cheeks' outer faces in the ship): the dot panels and the strap+buckle"
   },
   {
    "id": "C03a",
    "name": "dot panels (2 per face, 4 total)",
    "shape": "box",
    "size": [
     70,
     3,
     28
    ],
    "at": [
     150,
     196,
     -115
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "a raised panel at each end of the band; 2 rows x 3 round dimples, dimple dia 7 px, pitch 13 px"
   },
   {
    "id": "C03b",
    "name": "strap (flat)",
    "shape": "box",
    "size": [
     60,
     4,
     14
    ],
    "at": [
     95,
     197,
     -112
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "between dot panel and buckle"
   },
   {
    "id": "C03c",
    "name": "buckle chain (5 links per face)",
    "shape": "links",
    "size": [
     200,
     6,
     18
    ],
    "at": [
     0,
     199,
     -116
    ],
    "refs": "r4 r7",
    "mat": "steel",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "five articulated flat links, each 42x18x6 px with rounded ends and 2 pins; the two outer pairs angle down 12 deg, the centre link sits 10 px lower (the strap sags); static (no rig)"
   },
   {
    "id": "C04",
    "name": "lower block (ref)",
    "shape": "rbox",
    "size": [
     388,
     388,
     30,
     24
    ],
    "at": [
     0,
     0,
     -150
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "Z -135..-165 with one groove line 4 px under its top edge"
   },
   {
    "id": "C05",
    "name": "skirt with chamfered notch",
    "shape": "rbox",
    "size": [
     390,
     390,
     20,
     25
    ],
    "at": [
     0,
     0,
     -175
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "Z -165..-185; on the +-Y faces the middle 55% is cut back 15 px with 45 deg chamfers (the 'feet' at the ends); a thin raised line runs round the face 4 px from the edge"
   },
   {
    "id": "C06",
    "name": "rail channel (cut through C02..C05)",
    "shape": "channel",
    "size": [
     0.858,
     0.578,
     0.285
    ],
    "at": [
     0.0,
     0.0,
     -0.2645
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "U channel along X for the rail + running flanges, 0.578 m wide, from the cheek tops (ship z -3.775) down to ship z -4.06 (clears the rack by 0.01); pockets in its floor and cheeks for the rollers and the pinion; made with loops/extrusion, no boolean; the cheeks either side are 0.140 m thick"
   },
   {
    "id": "C07",
    "name": "load wheels x4",
    "shape": "cyl",
    "size": [
     0.1,
     0.04
    ],
    "at": [
     [
      0.3,
      -0.254,
      -0.252
     ],
     [
      -0.3,
      -0.254,
      -0.252
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "in the cheeks, axles along Y; they roll on the TOP of the running flanges K01 (ship z -3.93 centre)"
   },
   {
    "id": "C08",
    "name": "counter-rollers x4",
    "shape": "cyl",
    "size": [
     0.06,
     0.035
    ],
    "at": [
     [
      0.3,
      -0.254,
      -0.142
     ],
     [
      -0.3,
      -0.254,
      -0.142
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "under the running flanges (ship z -4.04 centre); hold the arm's tipping moment"
   },
   {
    "id": "C09",
    "name": "side guide rollers x4",
    "shape": "cyl",
    "size": [
     0.06,
     0.03
    ],
    "at": [
     [
      0.2,
      -0.309,
      -0.187
     ],
     [
      -0.2,
      -0.309,
      -0.187
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "vertical axles; run on the flanges' outer edges (lateral load)"
   },
   {
    "id": "C10",
    "name": "drive motor + gearbox + pinion",
    "shape": "cyl",
    "size": [
     0.12,
     0.3
    ],
    "at": [
     0.0,
     0.0,
     -0.084
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "axis along Y under the rail; pinion dia 0.096 (module 12, 8 teeth) meshes with the rack K02 from below; the motor's end cap (dia 0.12, steel bolt ring, thin orange ring) shows on the carriage's outboard face"
   },
   {
    "id": "C11",
    "name": "energy-chain bracket",
    "shape": "box",
    "size": [
     0.1,
     0.14,
     0.05
    ],
    "at": [
     0.0,
     -0.497,
     -0.387
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "on the inboard cheek top (ship +y); carries the chain's moving end at ship y -5.23"
   },
   {
    "id": "C12",
    "name": "buffer strike pads x2",
    "shape": "box",
    "size": [
     0.02,
     0.2,
     0.08
    ],
    "at": [
     [
      0.439,
      0.0,
      -0.112
     ],
     [
      -0.439,
      0.0,
      -0.112
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "steel pads on both end faces below the rail (ship z -4.11..-4.03), where the rail's end-stop buffers K03 meet them"
   },
   {
    "id": "C13",
    "name": "slewing ring, fixed race",
    "shape": "ring",
    "size": [
     270,
     240,
     8
    ],
    "at": [
     0,
     0,
     4
    ],
    "refs": "r1 r4",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "on C01's pad; 24 bolt heads dia 8 px on a 255 px circle"
   }
  ],
  "Turret": [
   {
    "id": "T01",
    "name": "slewing ring, turning race",
    "shape": "ring",
    "size": [
     262,
     0,
     22
    ],
    "at": [
     0,
     0,
     15
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "three stacked rings with 2 V-grooves (r4); hollow centre for the cables (hidden)"
   },
   {
    "id": "T02",
    "name": "lower block (skirt)",
    "shape": "rbox",
    "size": [
     350,
     330,
     85,
     20
    ],
    "at": [
     -15,
     0,
     67
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "X -190..160, Z 25..110; corners R20; seams: one horizontal groove 30 px above its foot"
   },
   {
    "id": "T02a",
    "name": "back screw strips",
    "shape": "box",
    "size": [
     3,
     18,
     80
    ],
    "at": [
     -192,
     52,
     67
    ],
    "refs": "r7",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "two vertical strips on the back face (Y +-52) with 3 round screw heads each (dia 10 px, steel)"
   },
   {
    "id": "T02b",
    "name": "back latch slot",
    "shape": "box",
    "size": [
     3,
     40,
     85
    ],
    "at": [
     -192,
     0,
     67
    ],
    "refs": "r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "a vertical slot in the back face with a bent U-tab (30x60 px, bar 8 px) hooked over its top (r7 centre)"
   },
   {
    "id": "T02c",
    "name": "side recess",
    "shape": "box",
    "size": [
     60,
     4,
     15
    ],
    "at": [
     -30,
     166,
     45
    ],
    "refs": "r1 r2",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "a horizontal recessed slot (r1 x_img 1030)"
   },
   {
    "id": "T02d",
    "name": "rear corner glands",
    "shape": "cyl",
    "size": [
     30,
     22
    ],
    "at": [
     -150,
     166,
     30
    ],
    "refs": "r1 r7",
    "mat": "rubber",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "where the side cable pairs end (r1 x_img 1135, y 1530)"
   },
   {
    "id": "T02e",
    "name": "front corner screws",
    "shape": "disc",
    "size": [
     10,
     3
    ],
    "at": [
     [
      160,
      120,
      60
     ],
     [
      160,
      120,
      85
     ],
     [
      160,
      120,
      100
     ]
    ],
    "refs": "r4",
    "mat": "steel",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "three small screw heads up each front corner of the lower block (r4)"
   },
   {
    "id": "T02f",
    "name": "side slot panel",
    "shape": "rbox",
    "size": [
     70,
     4,
     22,
     8
    ],
    "at": [
     -80,
     166,
     50
    ],
    "refs": "r4",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "a recessed rounded slot panel low on each side of the lower block (r4, right of the cable)"
   },
   {
    "id": "T03",
    "name": "front housing",
    "shape": "plate2d",
    "size": [
     [
      250,
      110
     ],
     [
      250,
      290
     ],
     [
      200,
      340
     ],
     [
      60,
      350
     ],
     [
      -40,
      340
     ],
     [
      -40,
      110
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "side outline in X-Z (px) extruded Y +-140; top front edge chamfered 50 px; a lid 130x6 px on top (x_img 870-1000); two horizontal seams and one vertical seam on each side; fillets 6 px"
   },
   {
    "id": "T03a",
    "name": "front housing top plug",
    "shape": "cyl",
    "size": [
     25,
     12
    ],
    "at": [
     150,
     0,
     355
    ],
    "refs": "r4",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Z",
    "note": "small round plug on the lid"
   },
   {
    "id": "T04",
    "name": "J2 ears",
    "shape": "rbox",
    "size": [
     260,
     85,
     260,
     40
    ],
    "at": [
     -155,
     172,
     235
    ],
    "refs": "r1 r3 r7",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "the two side housings that hold the shoulder; inner faces at Y +-130 (the drum turns between them)"
   },
   {
    "id": "T04a",
    "name": "J2 motor caps",
    "shape": "stack",
    "size": [
     [
      165,
      18,
      "paint_white"
     ],
     [
      120,
      10,
      "gunmetal"
     ],
     [
      76,
      3,
      "orange"
     ],
     [
      70,
      14,
      "gunmetal"
     ],
     [
      40,
      10,
      "steel"
     ]
    ],
    "at": [
     -155,
     215,
     235
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "a stack of rings on each ear's outer face (outer dia, height px, material): white bezel, dark ring, thin ORANGE ring, dark stepped hub with 3 rings, hex bolt in the centre (r1: the orange-ring cap at x_img 1155)"
   },
   {
    "id": "T05",
    "name": "connector boss",
    "shape": "stack",
    "size": [
     [
      52,
      10,
      "paint_white"
     ],
     [
      30,
      8,
      "gunmetal"
     ]
    ],
    "at": [
     185,
     142,
     200
    ],
    "refs": "r1 r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "double ring boss on the front housing side (r1 x_img 815; r4 left of the gland)"
   },
   {
    "id": "T06",
    "name": "cable port glands (side pairs start)",
    "shape": "stack",
    "size": [
     [
      48,
      12,
      "paint_white"
     ],
     [
      32,
      20,
      "rubber"
     ]
    ],
    "at": [
     85,
     142,
     200
    ],
    "refs": "r1 r2 r3 r4",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "white collar + rubber sleeve; the cable pair leaves here (r1 x_img 915, y 1350)"
   },
   {
    "id": "T07",
    "name": "orange hatch marking",
    "shape": "decal",
    "size": [
     70,
     20
    ],
    "at": [
     70,
     141,
     330
    ],
    "refs": "r1 r2 r3",
    "mat": "orange",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "five 45-deg stripes in a thin frame + a thin line above it, on both sides of the front housing"
   },
   {
    "id": "T07a",
    "name": "warning stripes, lower block",
    "shape": "decal",
    "size": [
     30,
     35
    ],
    "at": [
     -170,
     166,
     90
    ],
    "refs": "r1",
    "mat": "orange",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "small striped square (r1 x_img 1120, y 1460)"
   },
   {
    "id": "T08",
    "name": "bundle gland (front top)",
    "shape": "stack",
    "size": [
     [
      62,
      30,
      "paint_white"
     ],
     [
      48,
      12,
      "rubber"
     ]
    ],
    "at": [
     205,
     60,
     318
    ],
    "refs": "r1 r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "a round collar with a lip on the front housing top (r4); the multi-cable bundle leaves it forward"
   },
   {
    "id": "T09",
    "name": "cable bundle (7 cables)",
    "shape": "tube",
    "size": [
     10
    ],
    "at": [
     [
      205,
      60,
      330
     ],
     [
      290,
      66,
      330
     ],
     [
      340,
      70,
      260
     ],
     [
      345,
      70,
      200
     ]
    ],
    "refs": "r1 r2 r4",
    "mat": "rubber",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "7 black cables dia 10 px in a hexagonal pack (dia 34 px), arcing forward and down to the clamp T10; cable ends enter T11"
   },
   {
    "id": "T10",
    "name": "bundle clamp block",
    "shape": "rbox",
    "size": [
     70,
     60,
     50,
     8
    ],
    "at": [
     330,
     70,
     185
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "two-part clamp with one bolt head (dia 15, steel) and a slot; orange tick on its face (r2)"
   },
   {
    "id": "T11",
    "name": "belt-drive arm",
    "shape": "rbox",
    "size": [
     130,
     70,
     80,
     10
    ],
    "at": [
     310,
     35,
     110
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "white bracket from the front housing forward to the pulley; 3 small bolt heads (r4)"
   },
   {
    "id": "T12",
    "name": "drive pulley (J1 motor)",
    "shape": "stack",
    "size": [
     [
      78,
      40,
      "paint_white"
     ],
     [
      60,
      6,
      "gunmetal"
     ],
     [
      40,
      10,
      "gunmetal"
     ],
     [
      18,
      12,
      "steel"
     ]
    ],
    "at": [
     305,
     35,
     110
    ],
    "refs": "r1 r2 r3 r4",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "ringed white pulley (5 grooves) with a dark core and shaft (r1 x_img 695, y 1440)"
   },
   {
    "id": "T12b",
    "name": "drive motor end cap",
    "shape": "stack",
    "size": [
     [
      58,
      12,
      "paint_white"
     ],
     [
      44,
      4,
      "gunmetal"
     ],
     [
      30,
      6,
      "glass_dark"
     ]
    ],
    "at": [
     250,
     75,
     110
    ],
    "refs": "r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "the J1 motor's end on the belt arm's outer side, coaxial with the pulley: white ring, dark ring, dark lens (r2 turret crop)"
   },
   {
    "id": "T13",
    "name": "toothed belt",
    "shape": "belt",
    "size": [
     30,
     8
    ],
    "at": [
     [
      305,
      35,
      110
     ],
     [
      150,
      35,
      70
     ]
    ],
    "refs": "r1 r4",
    "mat": "rubber",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "black belt 30 px wide from the pulley T12 back to a hidden pulley in the lower block (x_img 850); teeth on the outside every 12 px (r4: rectangular lugs); static"
   },
   {
    "id": "T14",
    "name": "idler pulley",
    "shape": "stack",
    "size": [
     [
      30,
      12,
      "gunmetal"
     ],
     [
      12,
      16,
      "steel"
     ]
    ],
    "at": [
     255,
     35,
     50
    ],
    "refs": "r1 r4",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "small dark pulley with a bolt (r1 x_img 745)"
   },
   {
    "id": "T15",
    "name": "side cable pairs (2 x 2 cables)",
    "shape": "tube",
    "size": [
     12
    ],
    "at": [
     [
      85,
      150,
      200
     ],
     [
      60,
      300,
      175
     ],
     [
      -40,
      330,
      110
     ],
     [
      -120,
      250,
      40
     ],
     [
      -150,
      175,
      30
     ]
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "rubber",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "two cables per side side by side 25 px apart; loop out to Y +-330 (r7) and down to T02d; rubber ferrules at both ends"
   },
   {
    "id": "T16",
    "name": "dot vent",
    "shape": "box",
    "size": [
     40,
     3,
     25
    ],
    "at": [
     120,
     142,
     115
    ],
    "refs": "r4",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "dark panel with 6x4 round holes dia 4 px (r4, under the housing)"
   },
   {
    "id": "T17",
    "name": "recessed vent slot",
    "shape": "box",
    "size": [
     15,
     4,
     40
    ],
    "at": [
     210,
     142,
     160
    ],
    "refs": "r4",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "a vertical slot with one sloped edge (r4)"
   }
  ],
  "LowerArm": [
   {
    "id": "L01",
    "name": "drum (J2 barrel)",
    "shape": "cyl",
    "size": [
     270,
     210
    ],
    "at": [
     -155,
     0,
     235
    ],
    "refs": "r1 r2 r3 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "turns with the lower arm between the turret ears; perforated: side faces 24 holes dia 14 px on a 210 px circle; barrel face 2 rows x 24 holes dia 16 px at Y +-55 (r7); holes are blind recesses 8 px deep (quad rings)"
   },
   {
    "id": "L02",
    "name": "root shells",
    "shape": "plate2d",
    "size": [
     [
      10,
      235
     ],
     [
      -155,
      400
     ],
     [
      -300,
      360
     ],
     [
      -330,
      235
     ],
     [
      -155,
      70
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "the white side shells round the drum (R 160 about J2, white rim ring visible round the drum in r1), Y +-205 outer, blending into the beam L03"
   },
   {
    "id": "L03",
    "name": "beam J2 -> knee -> crotch",
    "shape": "plate2d",
    "size": [
     [
      -60,
      330
     ],
     [
      -250,
      560
     ],
     [
      -330,
      640
     ],
     [
      -520,
      520
     ],
     [
      -470,
      330
     ],
     [
      -330,
      230
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "box section, Y +-205 outer; side outline in X-Z px; seams and raised panels on the sides (r5)"
   },
   {
    "id": "L04",
    "name": "back channel",
    "shape": "channel",
    "size": [
     110,
     45
    ],
    "at": [
     [
      -280,
      0,
      170
     ],
     [
      -470,
      0,
      450
     ],
     [
      -560,
      0,
      740
     ]
    ],
    "refs": "r3 r5 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "recessed channel down the back face (Y +-55, 45 px deep) from the drum to the elbow; the J3 cylinder lies in it"
   },
   {
    "id": "L05",
    "name": "rungs",
    "shape": "box",
    "size": [
     10,
     110,
     30
    ],
    "at": [
     [
      -280,
      0,
      170
     ],
     [
      -560,
      0,
      740
     ]
    ],
    "refs": "r1 r2 r5 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "cross ribs every 20 px along the channel (about 40); in r1/r2 they show as the dashed strip on the arm's upper edge"
   },
   {
    "id": "L06",
    "name": "knee bosses",
    "shape": "ring",
    "size": [
     250,
     200,
     20
    ],
    "at": [
     -393,
     205,
     385
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "raised white ring round each slotted cap"
   },
   {
    "id": "L07",
    "name": "knee caps (radial slotted)",
    "shape": "stack",
    "size": [
     [
      190,
      10,
      "gunmetal"
     ],
     [
      120,
      6,
      "gunmetal"
     ],
     [
      90,
      6,
      "gunmetal"
     ],
     [
      60,
      6,
      "gunmetal"
     ],
     [
      55,
      2,
      "orange"
     ],
     [
      25,
      8,
      "steel"
     ]
    ],
    "at": [
     -393,
     215,
     385
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "black disc with 10 radial slots (35x12 px, open at the rim like teeth, at r 70), a stepped inner hub, a thin ORANGE ring and a bolt; they cover the J3 cylinder's trunnion pin"
   },
   {
    "id": "L18",
    "name": "front dark core + inner cap",
    "shape": "plate2d",
    "size": [
     [
      -330,
      500
     ],
     [
      -430,
      700
     ],
     [
      -470,
      780
     ],
     [
      -400,
      760
     ],
     [
      -300,
      560
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "between the side shells on the lower arm's front a dark core shows (r1: the black region under the upper arm; r5: dark plates with two round bosses dia 20 px and small bolt heads); an inner round cap dia 45 px at (-380, 0, 645) (r1 x_img 1380, y 905)"
   },
   {
    "id": "L08",
    "name": "hexagon outline (orange)",
    "shape": "decal",
    "size": [
     50,
     50
    ],
    "at": [
     -235,
     206,
     370
    ],
    "refs": "r1 r2",
    "mat": "orange",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "3 px line, left side only (r1 x_img 1235, y 1165)"
   },
   {
    "id": "L09",
    "name": "triangle outline (orange)",
    "shape": "decal",
    "size": [
     18,
     18
    ],
    "at": [
     -360,
     206,
     510
    ],
    "refs": "r1 r5",
    "mat": "orange",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "small, left side (r1 x_img 1360, y 1040)"
   },
   {
    "id": "L10",
    "name": "light slot",
    "shape": "box",
    "size": [
     18,
     6,
     140
    ],
    "at": [
     -525,
     206,
     680
    ],
    "refs": "r1 r5",
    "mat": "lamp",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "recessed slot inclined along the arm with a pale bar inside (r1 x_img 1505-1550, y 800-940); left side only; very faint glow"
   },
   {
    "id": "L11",
    "name": "round button",
    "shape": "stack",
    "size": [
     [
      30,
      6,
      "gunmetal"
     ],
     [
      22,
      8,
      "paint_white"
     ]
    ],
    "at": [
     -485,
     206,
     535
    ],
    "refs": "r1 r5",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "domed button, left side (r1 x_img 1485, y 1015)"
   },
   {
    "id": "L12",
    "name": "stepped side panels",
    "shape": "plate2d",
    "size": [
     [
      -400,
      520
     ],
     [
      -520,
      640
     ],
     [
      -560,
      780
     ],
     [
      -470,
      700
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r5",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "raised panels 6 px proud with 45 deg steps and the notch block near the knee top (r5)"
   },
   {
    "id": "L13",
    "name": "handles (bent tube)",
    "shape": "U",
    "size": [
     70,
     150,
     12
    ],
    "at": [
     -470,
     185,
     380
    ],
    "refs": "r1 r3 r5 r7",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "on the back face near each side edge at knee height, standing out backward 70 px; the outer leg has a segmented sleeve of 5 rings (r5); two small mounting blocks 18x18x12 px"
   },
   {
    "id": "L14",
    "name": "elbow yoke cheeks",
    "shape": "plate2d",
    "size": [
     [
      -470,
      700
     ],
     [
      -600,
      760
     ],
     [
      -640,
      830
     ],
     [
      -550,
      915
     ],
     [
      -470,
      870
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r5",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "two cheeks Y +-(125..205) from the crotch (55% of knee->J3) to J3, rounded R 85 round J3; the upper arm turns between them"
   },
   {
    "id": "L15",
    "name": "elbow caps",
    "shape": "stack",
    "size": [
     [
      140,
      12,
      "paint_white"
     ],
     [
      110,
      6,
      "gunmetal"
     ],
     [
      100,
      12,
      "gunmetal"
     ],
     [
      60,
      4,
      "steel"
     ]
    ],
    "at": [
     -550,
     205,
     830
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "black cap with a straight slot 60x12 px across ('minus' screw head) and two small tick notches at 12 and 6 o'clock"
   },
   {
    "id": "L16",
    "name": "inner channel guide + hose loop",
    "shape": "box",
    "size": [
     40,
     60,
     60
    ],
    "at": [
     -560,
     0,
     760
    ],
    "refs": "r3",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "in the channel's upper end (r3: a threaded rod and a white sliding block); here: the J3 cylinder's hose loop and a guide block (added)"
   },
   {
    "id": "L17",
    "name": "cable gland, back of elbow",
    "shape": "stack",
    "size": [
     [
      34,
      10,
      "paint_white"
     ],
     [
      24,
      14,
      "rubber"
     ]
    ],
    "at": [
     -640,
     60,
     800
    ],
    "refs": "r1 r3",
    "mat": "mixed",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "twin gland where the two upper-arm cables U09 come in (r1 x_img 1620-1640, y 690-710)"
   }
  ],
  "Cylinder": [
   {
    "id": "R01",
    "name": "barrel",
    "shape": "cyl",
    "size": [
     0.075,
     0.8
    ],
    "at": [
     0.1,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "black barrel from 0.30 m behind the trunnion to 0.50 m ahead of it (middle trunnion), on the line to the knob; the part behind the trunnion stays inside the lower arm channel"
   },
   {
    "id": "R02",
    "name": "trunnion block + pin",
    "shape": "box",
    "size": [
     0.1,
     0.11,
     0.1
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "pin dia 0.06 across the lower arm, hidden by the knee caps"
   },
   {
    "id": "R03",
    "name": "gland collar",
    "shape": "cyl",
    "size": [
     0.085,
     0.04
    ],
    "at": [
     0.48,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "bright ring where the rod leaves the barrel"
   },
   {
    "id": "R04",
    "name": "hoses x2",
    "shape": "tube",
    "size": [
     0.02
    ],
    "at": [],
    "refs": "added",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "A",
    "note": "from the barrel's two ports into the channel wall; hooked at both ends"
   }
  ],
  "Piston": [
   {
    "id": "R05",
    "name": "piston rod",
    "shape": "cyl",
    "size": [
     0.05,
     0.8
    ],
    "at": [
     -0.4,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Piston object: origin at the rod eye centre; at = (s, 0, 0) with s along the rod axis u (negative = into the barrel)",
    "note": "chrome rod from its eye 0.80 m back to the piston"
   },
   {
    "id": "R06",
    "name": "rod eye",
    "shape": "ring",
    "size": [
     0.075,
     0.05,
     0.024
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r3",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Piston object: origin at the rod eye centre",
    "note": "eye on the knob pin between the two truss plates"
   }
  ],
  "UpperArm": [
   {
    "id": "U01",
    "name": "elbow hub",
    "shape": "cyl",
    "size": [
     150,
     230
    ],
    "at": [
     -550,
     0,
     830
    ],
    "refs": "r1 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "between the yoke cheeks (Y +-115)"
   },
   {
    "id": "U02",
    "name": "housing (the hump)",
    "shape": "plate2d",
    "size": [
     [
      -640,
      800
     ],
     [
      -600,
      1010
     ],
     [
      -470,
      1080
     ],
     [
      -330,
      1095
     ],
     [
      -160,
      1095
     ],
     [
      -160,
      890
     ],
     [
      -300,
      870
     ],
     [
      -470,
      800
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "side outline X-Z px, Y +-110; a raised spine along the top; a dark recess strip along the lower edge (x_img 1380-1500); seams"
   },
   {
    "id": "U03",
    "name": "big caps",
    "shape": "stack",
    "size": [
     [
      165,
      14,
      "paint_white"
     ],
     [
      104,
      4,
      "orange"
     ],
     [
      100,
      10,
      "glass_dark"
     ],
     [
      72,
      6,
      "steel"
     ]
    ],
    "at": [
     -262,
     112,
     985
    ],
    "refs": "r1 r2 r3",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "white bezel, thin ORANGE ring, a dark glossy recessed disc and a slotted screw head (bar 70x14 px) inside"
   },
   {
    "id": "U04",
    "name": "ribbed vents",
    "shape": "box",
    "size": [
     100,
     6,
     55
    ],
    "at": [
     -470,
     111,
     925
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "raised panel with 8 slots 10x45 px, pitch 12 px, inclined 30 deg along the top edge"
   },
   {
    "id": "U05",
    "name": "indicator lights",
    "shape": "stack",
    "size": [
     [
      33,
      4,
      "gunmetal"
     ],
     [
      25,
      6,
      "lamp"
     ]
    ],
    "at": [
     -355,
     111,
     920
    ],
    "refs": "r1 r3",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "white lens in a dark ring; faint glow"
   },
   {
    "id": "U06",
    "name": "small dot",
    "shape": "disc",
    "size": [
     8,
     2
    ],
    "at": [
     -415,
     111,
     940
    ],
    "refs": "r1",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y"
   },
   {
    "id": "U07",
    "name": "orange ticks",
    "shape": "decal",
    "size": [
     14,
     14
    ],
    "at": [
     -525,
     111,
     1010
    ],
    "refs": "r1 r2",
    "mat": "orange",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "two small abstract chevrons (the reference has glyphs; no text here)"
   },
   {
    "id": "U08",
    "name": "twin cable gland",
    "shape": "rbox",
    "size": [
     50,
     40,
     30,
     6
    ],
    "at": [
     -470,
     50,
     1020
    ],
    "refs": "r1 r2 r3",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "on the top behind the vents; two rubber glands dia 16 px face backward"
   },
   {
    "id": "U09",
    "name": "two cables over the elbow",
    "shape": "tube",
    "size": [
     12
    ],
    "at": [
     [
      -470,
      50,
      1020
     ],
     [
      -640,
      55,
      1100
     ],
     [
      -810,
      60,
      990
     ],
     [
      -760,
      62,
      860
     ],
     [
      -640,
      60,
      800
     ]
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "rubber",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "cross J3: hooked at both ends, middle points blended 50/50 (see the rig); 18 px apart"
   },
   {
    "id": "U10",
    "name": "truss plates (pair)",
    "shape": "plate2d",
    "size": [
     [
      -560,
      860
     ],
     [
      -500,
      760
     ],
     [
      -740,
      630
     ],
     [
      -790,
      680
     ],
     [
      -610,
      860
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "two plates Y +-(14..40) behind the elbow down to the knob; raised rim 8 px; 4 triangular cut-outs alternating (the 'ANN' pattern), dark backing visible through them; the rod eye sits between the plates"
   },
   {
    "id": "U11",
    "name": "knob pin + caps",
    "shape": "knurl",
    "size": [
     62,
     20,
     24
    ],
    "at": [
     -762,
     46,
     662
    ],
    "refs": "r1 r3 r5",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "pin dia 50 px through both plates; knurled caps (24 ribs) on both sides with a dark dome centre dia 25"
   },
   {
    "id": "U12",
    "name": "front block (J4 housing)",
    "shape": "rbox",
    "size": [
     95,
     210,
     205,
     12
    ],
    "at": [
     -92,
     0,
     992
    ],
    "refs": "r1 r2 r3",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "X -140..-45; 3 ring grooves round it; a small square button (x_img 1090, y 520), a small white indicator rectangle 18x10 px (x_img 1155, y 545, lamp), a dark bolt (x_img 1150, y 650)"
   }
  ],
  "Forearm": [
   {
    "id": "F01",
    "name": "roll bearing ring",
    "shape": "ring",
    "size": [
     190,
     150,
     12
    ],
    "at": [
     -29,
     0,
     937
    ],
    "refs": "r1 r2 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "the black thin ring between the upper arm and the forearm"
   },
   {
    "id": "F02",
    "name": "dial housing",
    "shape": "rbox",
    "size": [
     250,
     190,
     195,
     30
    ],
    "at": [
     90,
     0,
     947
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "X -35..215, Z 850..1045"
   },
   {
    "id": "F03",
    "name": "dark side plates",
    "shape": "rbox",
    "size": [
     230,
     6,
     145,
     30
    ],
    "at": [
     95,
     96,
     972
    ],
    "refs": "r1 r3 r6",
    "mat": "gunmetal",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "rounded plates with a '7'-shaped groove near the rear top corner (r6), a small bolt with a white ring at x_img 1015"
   },
   {
    "id": "F04",
    "name": "dials",
    "shape": "stack",
    "size": [
     [
      110,
      6,
      "gunmetal"
     ],
     [
      85,
      4,
      "gunmetal"
     ],
     [
      55,
      4,
      "steel"
     ],
     [
      20,
      6,
      "gunmetal"
     ]
    ],
    "at": [
     90,
     100,
     960
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "black stepped disc with a '+' cross groove (6 px) through it and 4 notches on the rim (r6)"
   },
   {
    "id": "F05",
    "name": "belly",
    "shape": "rbox",
    "size": [
     200,
     160,
     60,
     14
    ],
    "at": [
     110,
     0,
     880
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "below the side plates; seam; a flat bar 230x25 px under it (r6)"
   },
   {
    "id": "F06",
    "name": "orange dot grids",
    "shape": "decal",
    "size": [
     26,
     14
    ],
    "at": [
     180,
     96,
     940
    ],
    "refs": "r1 r3",
    "mat": "orange",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "2 x 3 dots dia 5 px"
   },
   {
    "id": "F07",
    "name": "J5/J6 motor cylinder",
    "shape": "cyl",
    "size": [
     75,
     90
    ],
    "at": [
     255,
     0,
     1000
    ],
    "refs": "r1 r2 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "ringed (3 grooves) white cylinder, top front, joining the wrist block"
   },
   {
    "id": "F08",
    "name": "hose",
    "shape": "tube",
    "size": [
     22
    ],
    "at": [
     [
      200,
      -10,
      870
     ],
     [
      260,
      -10,
      860
     ],
     [
      330,
      -10,
      870
     ]
    ],
    "refs": "r1 r3 r6",
    "mat": "rubber",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "black hose with metal ferrules (dia 28 x 15 px) at both ends and an ORANGE band (6 px) near the front end"
   },
   {
    "id": "F09",
    "name": "wrist block (fork)",
    "shape": "plate2d",
    "size": [
     [
      215,
      1055
     ],
     [
      335,
      1045
     ],
     [
      440,
      990
     ],
     [
      500,
      937
     ],
     [
      440,
      860
     ],
     [
      215,
      850
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "angled housing Y +-75; its front is a fork (cheeks Y +-(55..75)) carrying J5; lobes R 60 round WC"
   },
   {
    "id": "F10",
    "name": "wrist fin (left)",
    "shape": "rbox",
    "size": [
     75,
     15,
     22,
     8
    ],
    "at": [
     330,
     76,
     1015
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "raised rounded bar, inclined 20 deg; right side has an oval recessed slot 70x18 px instead (r3)"
   },
   {
    "id": "F11",
    "name": "orange triangles + dots",
    "shape": "decal",
    "size": [
     35,
     25
    ],
    "at": [
     345,
     76,
     975
    ],
    "refs": "r1 r3 r6",
    "mat": "orange",
    "both": true,
    "units": "px",
    "frame": "A",
    "note": "three small triangles and two dots (left); 2x2 dots (right)"
   },
   {
    "id": "F12",
    "name": "screw caps",
    "shape": "disc",
    "size": [
     15,
     5
    ],
    "at": [
     [
      400,
      76,
      930
     ],
     [
      385,
      76,
      885
     ]
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "two white domes per side"
   },
   {
    "id": "F13",
    "name": "bottom handle",
    "shape": "U",
    "size": [
     55,
     15,
     5
    ],
    "at": [
     387,
     0,
     842
    ],
    "refs": "r1 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "flat-bar loop under the wrist block"
   },
   {
    "id": "F14",
    "name": "J5 caps (wrist round caps)",
    "shape": "stack",
    "size": [
     [
      100,
      6,
      "gunmetal"
     ],
     [
      80,
      4,
      "gunmetal"
     ],
     [
      60,
      4,
      "gunmetal"
     ],
     [
      40,
      4,
      "steel"
     ],
     [
      20,
      4,
      "gunmetal"
     ]
    ],
    "at": [
     435,
     76,
     937
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "mixed",
    "both": true,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "stepped concentric rings on both cheeks"
   },
   {
    "id": "F15",
    "name": "wrist top cylinder",
    "shape": "cyl",
    "size": [
     45,
     40
    ],
    "at": [
     320,
     0,
     1005
    ],
    "refs": "r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "short cylinder with a black band on the wrist block top; kept outside 0.25 m of the wrist centre on the upper side, where the tool swings"
   }
  ],
  "WristHead": [
   {
    "id": "W01",
    "name": "head drum",
    "shape": "cyl",
    "size": [
     95,
     106
    ],
    "at": [
     435,
     0,
     937
    ],
    "refs": "r1 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "between the fork cheeks, turns about Y"
   },
   {
    "id": "W02",
    "name": "neck collar",
    "shape": "cyl",
    "size": [
     75,
     12
    ],
    "at": [
     470,
     0,
     937
    ],
    "refs": "r1 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X"
   }
  ],
  "Flange": [
   {
    "id": "FL1",
    "name": "knurled ring",
    "shape": "knurl",
    "size": [
     72,
     25,
     36
    ],
    "at": [
     482,
     0,
     937
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "J6 turns here (r6 knurled neck)"
   },
   {
    "id": "FL2",
    "name": "flange face",
    "shape": "disc",
    "size": [
     80,
     5
    ],
    "at": [
     497,
     0,
     937
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "6 bolt holes; tools bolt here"
   }
  ],
  "ToolA": [
   {
    "id": "A01",
    "name": "hub",
    "shape": "cyl",
    "size": [
     125,
     75
    ],
    "at": [
     532,
     0,
     937
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "white body with a black ring at each end, 3 grooves; front face: 4 dark stepped rings (dia 125/100/75/45)"
   },
   {
    "id": "A02",
    "name": "finger brackets x4",
    "shape": "box",
    "size": [
     35,
     30,
     25
    ],
    "at": [
     552,
     0,
     1007
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "on the hub's front rim at r 70, one per finger"
   },
   {
    "id": "A03",
    "name": "finger motors x4",
    "shape": "knurl",
    "size": [
     30,
     65,
     24
    ],
    "at": [
     580,
     0,
     1047
    ],
    "refs": "r1 r2 r6",
    "mat": "steel",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "knurled cylinder fixed to each bracket, axis in the finger's plane pointing back-outward 20 deg from the tool axis (r1 top finger)"
   }
  ],
  "Finger": [
   {
    "id": "A04",
    "name": "knuckle pin caps",
    "shape": "disc",
    "size": [
     24,
     6
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y",
    "note": "both sides of the knuckle"
   },
   {
    "id": "A05",
    "name": "proximal link",
    "shape": "rbox",
    "size": [
     88,
     18,
     22,
     5
    ],
    "at": [
     44,
     0,
     0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "with a ribbed rubber boot (8 ribs, dia 26, 45 px long) on its middle and a threaded tendon rod dia 5 px along its outer side"
   },
   {
    "id": "A06",
    "name": "distal pin caps",
    "shape": "disc",
    "size": [
     20,
     6
    ],
    "at": [
     88,
     0,
     0
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "Y"
   },
   {
    "id": "A07",
    "name": "distal link + hooked tip",
    "shape": "rbox",
    "size": [
     70,
     16,
     18,
     4
    ],
    "at": [
     123,
     0,
     0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "tapered 18 -> 10 px; a 15 px hook turned inward at the tip; ridged steel jaw insert on the inner face"
   }
  ],
  "ToolB": [
   {
    "id": "B01",
    "name": "flared neck",
    "shape": "cone",
    "size": [
     70,
     133,
     197
    ],
    "at": [
     593,
     0,
     937
    ],
    "refs": "r6 (red sketch)",
    "mat": "paint_white",
    "both": false,
    "units": "px",
    "frame": "A",
    "axis": "X",
    "note": "trumpet-shaped: the sketch's two lines spread from the wrist to the plate (the sketch is a 3/4 view looking along the tool, so the neck shows short); 0.434 m long so the plate's face lands where version A grips (both versions share one arm pose); straight for its first 60%, flaring over the last 40%; two ring grooves; fillet into the plate"
   },
   {
    "id": "B02",
    "name": "mounting plate",
    "shape": "rbox",
    "size": [
     20,
     250,
     250,
     15
    ],
    "at": [
     701,
     0,
     937
    ],
    "refs": "r6 (red sketch)",
    "mat": "gunmetal",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "square plate 0.55 x 0.55 x 0.044 m, corner R 0.033, 2 mm chamfers; its door face is flat"
   },
   {
    "id": "B03",
    "name": "plate bolts x8",
    "shape": "hex",
    "size": [
     18,
     10
    ],
    "at": [
     690,
     0,
     937
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "M24-size hex heads, 2 per edge on a 0.46 m square"
   },
   {
    "id": "B04",
    "name": "orange corner ticks",
    "shape": "decal",
    "size": [
     20,
     20
    ],
    "at": [
     690,
     0,
     937
    ],
    "refs": "added (matches the arm's accents)",
    "mat": "orange",
    "both": false,
    "units": "px",
    "frame": "A",
    "note": "four small L-ticks at the plate's corners"
   }
  ],
  "DoorFixtureA": [
   {
    "id": "DA1",
    "name": "conformal pad",
    "shape": "pad",
    "size": [
     0.32,
     0.32,
     0.02
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local: Z = door normal",
    "note": "underside follows the door's inner face (ray-cast), top flat"
   },
   {
    "id": "DA2",
    "name": "base plate",
    "shape": "rbox",
    "size": [
     0.26,
     0.26,
     0.03,
     0.02
    ],
    "at": [
     0,
     0,
     0.035
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "4 bolts"
   },
   {
    "id": "DA3",
    "name": "stem",
    "shape": "cyl",
    "size": [
     0.08,
     0.115
    ],
    "at": [
     0,
     0,
     0.1075
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "fixture local"
   },
   {
    "id": "DA4",
    "name": "grab knob (mushroom head)",
    "shape": "cyl",
    "size": [
     0.13,
     0.05
    ],
    "at": [
     0,
     0,
     0.19
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "3 mm chamfers; the 4 hooked tips close under it round the stem"
   }
  ],
  "DoorFixtureB": [
   {
    "id": "DB1",
    "name": "conformal pad",
    "shape": "pad",
    "size": [
     0.6,
     0.6,
     0.02
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "underside follows the door's face; the plate B02 bolts to its flat top"
   }
  ],
  "RailKit": [
   {
    "id": "K01",
    "name": "running flanges x2",
    "shape": "box",
    "size": [
     6.49,
     0.05,
     0.03
    ],
    "at": [
     -5.79,
     -6.0488,
     -3.995
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "world",
    "note": "flat bars bolted to both side faces at the rail's bottom, x -9.0348..-2.5453, z -4.010..-3.980, protruding 0.05 (y -6.0738..-6.0238 and -5.5662..-5.5162); bolt heads (M16) every 0.25 m on their outer faces"
   },
   {
    "id": "K02",
    "name": "rack",
    "shape": "rack",
    "size": [
     5.32,
     0.06,
     0.04
    ],
    "at": [
     -5.565,
     -5.795,
     -4.03
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "gear rack bolted under the rail's bottom face over the pinion's travel (x -8.225..-2.905), teeth down, module 12 mm"
   },
   {
    "id": "K03",
    "name": "end stops x2",
    "shape": "box",
    "size": [
     0.13,
     0.3,
     0.12
    ],
    "at": [
     [
      -8.62,
      -5.795,
      -4.07
     ],
     [
      -2.525,
      -5.795,
      -4.07
     ]
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "wall end: steel block x -8.685..-8.585 bolted under the rail + rubber buffer x -8.585..-8.555; inner end: rubber buffer x -2.575..-2.545 + steel block x -2.545..-2.475 bolted to the rail's end face and underside; both z -4.13..-4.01 between the flanges; the carriage's end faces (strike pads C12) stop 10 mm short of the buffers at its travel ends (c -8.1158 / -3.0143)"
   },
   {
    "id": "K04",
    "name": "energy-chain tray",
    "shape": "channel",
    "size": [
     6.05,
     0.4,
     0.125
    ],
    "at": [
     -5.975,
     -5.08,
     -3.84
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "a shallow tray hung under the deck on the inboard side: y -5.28..-4.88, floor top at z -3.895, walls to -3.78, x -9.00 to a slanted well-side end (x -2.95 at y -5.28, -3.08 at y -4.88: >= 0.05 m short of the moon pool well's rounded edge); hangers to the deck every 0.8 m"
   },
   {
    "id": "K05",
    "name": "energy chain",
    "shape": "chain",
    "size": [
     3.27,
     0.1,
     0.06
    ],
    "at": [],
    "refs": "added",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "lying on its side in the tray (bend axis vertical), 44 links of pitch 0.075 m (link 0.075 x 0.06 x 0.10 high), length 3.30 m, bend radius 0.15 m; runs at y -5.23 (moving, carriage side) and -4.93 (fixed); fixed end at x -5.565 (mid travel), moving end on the carriage bracket C11; the loop travels x -8.40..-5.70; links are rigid objects driven by simple expressions of the carriage x"
   }
  ]
 },
 "materials": {
  "M_DoorArm_PaintWhite": {
   "parts": "all white shells (turret, lower arm, upper arm, forearm, wrist block, hub, neck, handles)",
   "look": "satin off-white powder coat, fine orange-peel relief, low wear (clean ship: a few chips on exposed edges, light grime in crevices)",
   "source": "pd_look.paint(grey=(0.80,0.80,0.78), metallic=0.0, rough=(0.38,0.55), wear=0.25, grime=0.18, dust=0.10, coat=0.30) on the Poly Haven blue_metal_plate scan (models/pressure-door/source_polyhaven), its light/dark, roughness and normal only",
   "tile_m": 1.25
  },
  "M_DoorArm_Gunmetal": {
   "parts": "carriage, drum, caps' dark rings, side plates, dials, wrist head, gripper fingers, plate B, rail kit, door fixtures",
   "look": "dark gunmetal painted metal, worn lighter on the carriage's edges (r1-r3 show scratches on the carriage)",
   "source": "pd_look 'gunmetal' style: grey=(0.21,0.215,0.23), metallic 0.92, rough (0.26,0.50); carriage wear 0.65, others 0.45",
   "tile_m": 0.7
  },
  "M_DoorArm_Steel": {
   "parts": "screws, pins, bolts, piston rod (chrome), gland collar, knurled rings, wheels, rack, flanges, buckle links",
   "look": "bright machined steel; piston rod near-mirror (rough 0.12)",
   "source": "pd_look.steel(rough=(0.14,0.35)) with the ModSci_Engineer pack's T_Metal_Brushed_N.png normal",
   "tile_m": 0.5
  },
  "M_DoorArm_Rubber": {
   "parts": "cables, hose, belt, finger boots, buffers, energy chain links, gland sleeves",
   "look": "black rubber / nylon, rough 0.62-0.78, a fine noise normal",
   "source": "pd_look.dark(tint=(0.025,0.025,0.027), rough=(0.62,0.78), metallic 0)",
   "tile_m": 0.4
  },
  "M_DoorArm_Orange": {
   "parts": "the thin ring parts in the cap stacks (J2 caps, knee caps, big caps, motor cap), hose band",
   "look": "safety orange paint sRGB (0.93, 0.36, 0.08), satin rough 0.45, slight wear",
   "source": "flat colour under the masks atlas",
   "tile_m": null
  },
  "M_DoorArm_Glass": {
   "parts": "the big caps' dark recessed discs (U03)",
   "look": "dark glossy lens, rough 0.08, a faint coppery rim reflection",
   "source": "Principled, base (0.02,0.02,0.022), coat 1.0",
   "tile_m": null
  },
  "M_DoorArm_Lamp": {
   "parts": "indicator lights U05, U12 rectangle, light slot L10",
   "look": "pale cool white, emission 2-4 W/m2 equivalent (a small indicator, not a light source)",
   "source": "flat emissive",
   "tile_m": null
  },
  "M_DoorArm_Decals": {
   "parts": "all flat markings (hexagon, triangles, dots, hatch stripes, chevrons)",
   "look": "orange paint shapes on an alpha-tested atlas",
   "source": "T_DoorArm_Decals.png (1024 x 1024, made by script: vector shapes, no text)",
   "tile_m": null
  }
 },
 "markings": [
  {
   "id": "D01",
   "shape": "hexagon outline, 3 px line, 50 px across",
   "where": "lower arm left side near the knee (L08)",
   "refs": "r1 r2"
  },
  {
   "id": "D02",
   "shape": "small triangle outline 18 px",
   "where": "lower arm left side (L09)",
   "refs": "r1 r5"
  },
  {
   "id": "D03",
   "shape": "hatch: 5 diagonal stripes in a thin frame + a line above",
   "where": "turret front housing both sides (T07)",
   "refs": "r1 r2 r3"
  },
  {
   "id": "D04",
   "shape": "small striped square (warning)",
   "where": "turret lower block left rear (T07a)",
   "refs": "r1"
  },
  {
   "id": "D05",
   "shape": "2 x 3 dot grid, dots 5 px",
   "where": "forearm below the dials, both sides (F06)",
   "refs": "r1 r3"
  },
  {
   "id": "D06",
   "shape": "three small triangles + two dots",
   "where": "wrist block left side (F11)",
   "refs": "r1 r6"
  },
  {
   "id": "D07",
   "shape": "2 x 2 dots",
   "where": "wrist block right side (F11)",
   "refs": "r3"
  },
  {
   "id": "D08",
   "shape": "two small chevrons / ticks (stand-ins for the reference's glyphs)",
   "where": "upper arm near the vents, both sides (U07)",
   "refs": "r1 r2 r3"
  },
  {
   "id": "D09",
   "shape": "four L-shaped corner ticks",
   "where": "version B plate corners (B04)",
   "refs": "added"
  },
  {
   "id": "D10",
   "shape": "thin orange line 20 px",
   "where": "turret lower block left (r1 x_img 885, y 1530)",
   "refs": "r1"
  },
  {
   "id": "RULE",
   "shape": "no letters, numbers, logos, maker or brand text anywhere",
   "where": "all",
   "refs": "project rule"
  }
 ],
 "tri_budget": {
  "Carriage (incl. running gear, straps, dot panels)": 14000,
  "Turret (incl. belt drive, glands, caps)": 26000,
  "Turret cables (bundle + 2 pairs)": 6000,
  "LowerArm (drum with holes, shells, channel rungs, caps, handles)": 34000,
  "Cylinder + Piston + hoses": 3000,
  "UpperArm (housing, caps, vents, truss, knob)": 24000,
  "UpperArm cables over the elbow": 2500,
  "Forearm (dial housing, dials, wrist block, hose, handle)": 20000,
  "WristHead + Flange": 4000,
  "ToolA hub + 4 fingers": 18000,
  "ToolB neck + plate + bolts": 4000,
  "Door fixtures A + B": 2500,
  "Rail kit per rail (flanges, rack, stops, tray)": 7000,
  "Energy chain (44 links)": 5500,
  "TOTAL per arm, version A (without the rail kit)": 151500,
  "TOTAL per arm, version B (without the rail kit)": 137500,
  "note": "LOD0; bevels as 2-segment chamfers on visible edges (the bake's bevel normal rounds them), cylinders 32-48 sides for caps >= 0.2 m, 16-24 for small parts; LOD1 at 50%, LOD2 at 20% made in Unreal"
 },
 "fingers": {
  "units": "ref1 px in the tool frame (x 0.0022 = m); X' along the tool axis from the wrist centre, r radial",
  "knuckle": [
   107.0,
   79.0
  ],
  "proximal_len": 82.0,
  "distal_len": 70.0,
  "hook": {
   "length": 18.0,
   "bend_deg": -84.2,
   "thickness": 10
  },
  "open": {
   "proximal_deg": 24.7,
   "distal_abs_deg": 4.9,
   "pin": [
    181.5,
    113.3
   ],
   "hook_base": [
    251.2,
    119.2
   ],
   "tip": [
    254.6,
    101.6
   ]
  },
  "closed": {
   "proximal_deg": 10.0,
   "distal_abs_deg": -50.8,
   "pin": [
    187.8,
    93.2
   ],
   "hook_base": [
    232.0,
    39.0
   ],
   "tip": [
    219.3,
    26.3
   ]
  },
  "grip": {
   "proximal_turn_deg": -14.7,
   "distal_turn_deg": -41.0,
   "control": "g in 0..1 (0 open as in ref1-3, 1 closed on the knob); proximal angle = g * proximal_turn, distal angle = g * distal_turn, both turning the finger toward the tool axis"
  },
  "knob": {
   "head_centre": 200.0,
   "head_radius": 29.5,
   "head_thickness": 23.0,
   "stem_radius": 13.6
  },
  "clearances_px": {
   "hook_edge_behind_head": 2.77,
   "hook_edge_above_stem": 7.67,
   "distal_link_over_head_rim": 25.63,
   "tips_of_neighbour_fingers": 27.15
  },
  "clearances_m": {
   "hook_edge_behind_head": 0.0061,
   "hook_edge_above_stem": 0.0169,
   "distal_link_over_head_rim": 0.0564,
   "tips_of_neighbour_fingers": 0.0597
  },
  "objects": {
   "top": {
    "hinge_axis": "+Y",
    "proximal_channel": "rotation_euler[1]",
    "sign": 1
   },
   "bottom": {
    "hinge_axis": "+Y",
    "proximal_channel": "rotation_euler[1]",
    "sign": -1
   },
   "left": {
    "hinge_axis": "+Z",
    "proximal_channel": "rotation_euler[2]",
    "sign": -1
   },
   "right": {
    "hinge_axis": "+Z",
    "proximal_channel": "rotation_euler[2]",
    "sign": 1
   },
   "note": "angle = sign * g * |turn| toward the tool axis (proximal 14.7 deg, distal 41.0 deg); the distal object is a child of the proximal, origin on the distal pin, same channel and sign; g = DoorArm | CONTROLS['grip'] (ship scene default 1.0 = closed on the knob)"
  }
 },
 "controls": {
  "object": "DoorArm | CONTROLS",
  "props": {
   "version": {
    "default": 0,
    "values": {
     "0": "A gripper (grab limbs)",
     "1": "B plate (red sketch)"
    }
   },
   "grip": {
    "default": 1.0,
    "range": [
     0.0,
     1.0
    ],
    "note": "version A fingers: 0 open, 1 closed on the knob"
   }
  },
  "version_drivers": {
   "A_parts_expr": "v > 0.5",
   "B_parts_expr": "v < 0.5",
   "paths": [
    "hide_viewport",
    "hide_render"
   ],
   "A_parts": [
    "tool A hub",
    "finger * proximal",
    "finger * distal",
    "door fixture A"
   ],
   "B_parts": [
    "tool B",
    "door fixture B"
   ],
   "note": "v reads DoorArm | CONTROLS['version']; both arms switch together; the arm pose does not change (both tools share the wrist centre)"
  },
  "door_fixture_drivers": "fixture.location[i] = door.location[i] + fixture_offset[i] (three simple drivers per fixture); rotation constant (the door never turns); fixture_offset = attach_local; the fixture's local +Z is the door's inner-face normal"
 },
 "showroom": {
  "scene": "DoorArm | Showroom",
  "arms": {
   "A": {
    "root": "Showroom | arm A",
    "location": [
     -3.04,
     0.0,
     1.6192
    ],
    "tool": "A",
    "fingers": "open (g = 0)"
   },
   "B": {
    "root": "Showroom | arm B",
    "location": [
     3.0321,
     0.0,
     1.6192
    ],
    "tool": "B"
   }
  },
  "how": "linked duplicates (shared mesh data) of every arm mesh at rest (all joints 0 = the ref1 pose), upright, no drivers; both stand on one floor rail like the references",
  "floor_rail": {
   "profile": "the ship rail turned over: box 0.458 x 0.335 m with the K01 flanges and the K02 rack on its TOP",
   "length": 7.0,
   "z": [
    0.25,
    0.585
   ],
   "posts": "square tubes 0.12 x 0.12, every 2.2 m, rail bottom 0.25 m above the floor (ref1 has short posts)",
   "note": "the carriage straddles the rail's top 0.255 m exactly as it hangs in the ship; its turntable face is at z 0.585 + 0.020 + 0.407 = 1.012"
  },
  "studio": {
   "floor": "light grey cyclorama (floor + 6 m radius cove), grey 0.55 linear, rough 0.6",
   "lights": [
    "key: area 2 x 2 m, front-left high, 800 W",
    "fill: area 3 x 3 m, right, 300 W",
    "rim: area 1 x 4 m behind, 500 W"
   ],
   "world": "flat grey 0.35, strength 0.4",
   "note": "matches the soft grey studio of ref1-3"
  }
 },
 "cables": {
  "elbow_pair": {
   "objects": [
    "cable elbow 1",
    "cable elbow 2"
   ],
   "curve": "Bezier, 5 points, bevel radius 0.013 (dia 0.026), 8 sides, the two cables 0.040 apart",
   "route": "from the twin gland U08 on the upper arm top, up and back over the elbow (0.22 m above the housing), down into the twin gland L17 on the lower arm's back just behind the elbow (ref1 shows the loop behind the elbow)",
   "hooks": "P0,P1 -> empty on the upper arm; P3,P4 -> empty on the lower arm; P2 -> empty with Copy Transforms to a mid empty on the upper arm (influence 1.0) then to one on the lower arm (influence 0.5): halfway blend, no Python",
   "check": "sample each curve every 2 cm at every frame: >= 15 mm from all link meshes except at its two glands",
   "export": "converted to mesh; weights upper_arm 1 -> 0 and lower_arm 0 -> 1 along the length (smoothstep)"
  },
  "cylinder_hoses": {
   "objects": [
    "J3 hose rear",
    "J3 hose front"
   ],
   "hooks": "one end on the cylinder, one on the lower arm channel wall",
   "note": "the cylinder only turns -5.2..+1.3 deg in the lower arm"
  },
  "static": "turret bundle (7), turret side pairs (2 x 2), forearm hose: plain meshes inside their link (no joint between their ends)"
 },
 "objects": {
  "naming": "'DoorArm_<AFT|FORE> | <part>' for each arm; 'DoorArm | <name>' for shared things; 'Showroom | ...' in the showroom",
  "per_arm": [
   {
    "name": "DoorArm_AFT",
    "kind": "EMPTY (rig root)",
    "parent": null,
    "location": "(0, -5.795, -4.182) world",
    "rotation": "(180 deg, 0, 0)",
    "note": "static"
   },
   {
    "name": "| carriage",
    "kind": "MESH",
    "parent": "rig root",
    "origin": "turntable face centre",
    "moves": "location.x = c"
   },
   {
    "name": "| turret",
    "kind": "MESH",
    "parent": "carriage",
    "origin": "J1 (turntable face centre)",
    "moves": "rotation_euler.z = q1"
   },
   {
    "name": "| lower arm",
    "kind": "MESH",
    "parent": "turret",
    "origin": "J2",
    "moves": "rotation_euler.y = -q2"
   },
   {
    "name": "| J3 cylinder",
    "kind": "MESH",
    "parent": "lower arm",
    "origin": "trunnion (knee)",
    "moves": "rotation_euler.y = -cyl"
   },
   {
    "name": "| J3 piston",
    "kind": "MESH",
    "parent": "J3 cylinder",
    "origin": "rod eye centre",
    "moves": "location.x, location.z"
   },
   {
    "name": "| upper arm",
    "kind": "MESH",
    "parent": "lower arm",
    "origin": "J3",
    "moves": "rotation_euler.y = -q3"
   },
   {
    "name": "| forearm",
    "kind": "MESH",
    "parent": "upper arm",
    "origin": "J4 axis at the roll ring",
    "moves": "rotation_euler.x = q4"
   },
   {
    "name": "| wrist head",
    "kind": "MESH",
    "parent": "forearm",
    "origin": "WC (J5)",
    "moves": "rotation_euler.y = q5"
   },
   {
    "name": "| flange",
    "kind": "MESH",
    "parent": "wrist head",
    "origin": "WC",
    "moves": "rotation_euler.x = q6"
   },
   {
    "name": "| tool A hub",
    "kind": "MESH",
    "parent": "flange",
    "origin": "WC",
    "moves": "no (version A)"
   },
   {
    "name": "| finger <top|bottom|left|right> proximal",
    "kind": "MESH",
    "parent": "tool A hub",
    "origin": "knuckle pin",
    "moves": "grip"
   },
   {
    "name": "| finger <...> distal",
    "kind": "MESH",
    "parent": "its proximal",
    "origin": "distal pin",
    "moves": "grip"
   },
   {
    "name": "| tool B",
    "kind": "MESH",
    "parent": "flange",
    "origin": "WC",
    "moves": "no (version B)"
   },
   {
    "name": "| cable elbow 1/2",
    "kind": "CURVE",
    "parent": "lower arm",
    "moves": "hooks"
   },
   {
    "name": "| J3 hose rear/front",
    "kind": "CURVE",
    "parent": "lower arm",
    "moves": "hooks"
   },
   {
    "name": "| door fixture A / B",
    "kind": "MESH",
    "parent": null,
    "origin": "attach point on the door face, +Z = face normal",
    "moves": "location from the door"
   },
   {
    "name": "| rail kit",
    "kind": "MESH",
    "parent": null,
    "origin": "world origin",
    "moves": "static (flanges, rack, stops, tray, hangers, chain fixed bracket)"
   },
   {
    "name": "| chain tray",
    "kind": "EMPTY",
    "parent": null,
    "origin": "world origin",
    "moves": "static (parent of the links)"
   },
   {
    "name": "| chain link 00..43",
    "kind": "MESH (linked duplicates)",
    "parent": "| chain tray",
    "origin": "link centre",
    "moves": "location.x/y, rotation_euler.z"
   },
   {
    "name": "| IK1 target .. IK6 wrist angles, | chain solver",
    "kind": "EMPTY (solver, hidden)",
    "parent": null,
    "moves": "custom properties driven"
   }
  ],
  "shared": [
   {
    "name": "DoorArm | CONTROLS",
    "kind": "EMPTY",
    "props": [
     "version",
     "grip"
    ]
   }
  ],
  "rest_rule": "every moving object: rotation 0 and scale 1 at rest (rest = the ref1 pose, all q = 0); meshes are modelled in that pose",
  "merge_rule": "each link's static parts are joined into the link's one mesh (several material slots); no booleans; quads; UV0 = atlas (bake), UV_Tile = metres (tiling scans)"
 },
 "collections": {
  "DoorArm | AFT": "rig root, all AFT moving meshes and curves",
  "DoorArm | FORE": "the same for the FORE door",
  "DoorArm | solver (hidden)": "the 14 solver empties (7 per arm), hidden in viewport and render",
  "DoorArm | rail kit": "both rail kits and both chains",
  "DoorArm | door fixtures": "fixtures A and B for both doors",
  "DoorArm | collision": "UCX_ hulls (eye off in the view layer, hide_render on)",
  "CONTEXT | ship (reference only)": "the ship context objects, linked into the fit scene, never exported",
  "Showroom | arms": "showroom scene only",
  "Showroom | studio": "floor rail, cyclorama, lights, cameras"
 },
 "scenes": {
  "DoorArm | Ship fit": "frames 1-120, 30 fps, markers CLOSED 1, RETRACTED INBOARD 12, OPEN / PANELS IN POCKETS 48, CLOSE 108",
  "DoorArm | Showroom": "frame 1, both versions side by side, upright"
 },
 "build": {
  "entry": "build/build.py -- <stage> (each stage one headless call under 9 minutes; renders and bakes in their own calls)",
  "stages": [
   {
    "stage": "context",
    "does": "new file; link the ship context objects into 'CONTEXT | ship'; scenes, frame range, fps, markers; save DoorRobotArm.blend (back up first)"
   },
   {
    "stage": "parts",
    "does": "model every part in the parts list per link (one module per link), join per link, origins on axes, two UV layers"
   },
   {
    "stage": "rig",
    "does": "hierarchy for both arms, solver empties and all drivers from design.json['drivers'], fingers, version switch, fixtures, cable hooks; assert every driver is_simple_expression and is_valid"
   },
   {
    "stage": "check",
    "does": "real-mesh check frames 1-120 both doors both versions (BVH overlap between every pair of moving meshes and against the context and the rail kit, like vessel-interior/build/door_arms.check); pose error; piston on knob; chain; writes build/check_report.json and fails on any crossing"
   },
   {
    "stage": "surfaces",
    "does": "materials (pressure-door/build/pd_look.py paint/steel/dark), decal atlas, masks bake (separate calls per atlas)"
   },
   {
    "stage": "showroom",
    "does": "showroom scene with linked duplicates, floor rail, studio, lights, cameras"
   },
   {
    "stage": "ucx",
    "does": "UCX_ convex hulls per link from design_parts.PROXIES (box and 16-sided prisms)"
   },
   {
    "stage": "export",
    "does": "FBX for Unreal (see export) + DoorRobotArm_layout.json"
   },
   {
    "stage": "renders",
    "does": "Cycles renders listed in renders (several calls)"
   }
  ],
  "libraries": [
   "models/pressure-door/build/pd_lib.py (lathe, rbox, finish)",
   "models/pressure-door/build/pd_look.py (paint, steel, dark)",
   "models/docking-arm/build/surfaces.py (masks atlas bake, tiling UV in metres)",
   "models/vessel-interior/build/boarding_gate.py (_crossing for BVH checks)",
   "models/machine-parts-kit, models/hardsurface-kit (part shapes to read)"
  ]
 },
 "checks": [
  "every driver: is_simple_expression and is_valid (the prototype has 172 per arm, all pass)",
  "frames 1-120 both doors both versions: tool contact point on the door target < 0.5 mm, axes < 0.1 deg",
  "joint angles inside kinematics.joints[*].limits; |q5| >= 30 deg; elbow inner angle 32..115 deg; WC >= 0.5 m from the J1 axis",
  "J3 piston eye on the knob < 0.5 mm; piston inside the barrel; barrel rear inside the lower arm",
  "no mesh crossing between any two moving parts or against the context, the rail kit, the doors (design clearance targets: >= 0.008 m for the tool against the wrist lobes, >= 0.10 m elsewhere; contact allowed only plate-pad-door and the hooks under the knob, 6 mm)",
  "carriage inside its travel; its end faces 10 mm short of the buffers at the travel ends",
  "chain: link spacing = pitch (<= 1 mm on the bend chord), first link at the carriage, all links inside the tray",
  "version switch: A parts hidden for v=1, B parts hidden for v=0, viewport and render",
  "game-ready audit: quads (n-gons only on flat caps, triangulated), no booleans, UV0 + UV_Tile on every mesh, rotation 0 / scale 1 at rest"
 ],
 "renders": {
  "showroom": [
   {
    "name": "DoorArm_showroom_ref1_side",
    "like": "ref1",
    "camera": "arm A side on from its left (+Y), level with the elbow, 85 mm"
   },
   {
    "name": "DoorArm_showroom_ref2_34left",
    "like": "ref2",
    "camera": "front-left three-quarter, slightly below the forearm"
   },
   {
    "name": "DoorArm_showroom_ref3_34right",
    "like": "ref3",
    "camera": "right three-quarter from the back-right, truss and rod side"
   },
   {
    "name": "DoorArm_showroom_ref4_base",
    "like": "ref4",
    "camera": "close-up of carriage, turret, belt drive, cable bundle, left side"
   },
   {
    "name": "DoorArm_showroom_ref5_lowerarm",
    "like": "ref5",
    "camera": "close-up of the lower arm: knee cap, elbow cap, truss, rod, handle"
   },
   {
    "name": "DoorArm_showroom_ref6_wrist_A",
    "like": "ref6",
    "camera": "forearm and wrist from front-left-below, version A"
   },
   {
    "name": "DoorArm_showroom_ref6_wrist_B",
    "like": "ref6 red sketch",
    "camera": "the same camera, version B (neck + plate)"
   },
   {
    "name": "DoorArm_showroom_ref7_back",
    "like": "ref7",
    "camera": "back view of the base, low"
   },
   {
    "name": "DoorArm_showroom_side_by_side",
    "like": "side by side",
    "camera": "both arms, wide"
   }
  ],
  "in_scene": {
   "frames": [
    1,
    12,
    30,
    48,
    90
   ],
   "versions": [
    "A",
    "B"
   ],
   "doors": "both arms in every frame",
   "cameras": [
    "pocket AFT from inboard (y -1.5, z -5.0) looking outboard at the arm",
    "along the AFT rail from the well toward the end wall",
    "the same two for FORE"
   ],
   "light": "the pocket is dark: two area lights (1 x 4 m, 600 W) under the deck inboard of each rail, a soft fill from the well; the docking lamps keep their own emission",
   "engine": "Cycles, GPU (HIP), 256 samples + denoise"
  },
  "out": "previews/"
 },
 "bake": {
  "uv0": "one atlas per arm (all link meshes, both tools, fixtures, chain link, rail kit): 4096 x 4096, about 512 px per metre on the large shells",
  "maps": {
   "T_DoorArm_Masks": "R occlusion, G convex edges (wear), B cavities (grime); Cycles bake, 128 samples",
   "T_DoorArm_BevelNormal": "rounded-edge normal (bevel shader, radius 4 mm), tangent space OpenGL",
   "T_DoorArm_Decals": "1024 x 1024 RGBA, the marking shapes (no text), alpha-tested"
  },
  "tiling": "UV_Tile in metres: paint 1.25 m repeat, gunmetal 0.70, steel 0.50, rubber 0.40",
  "calls": "each bake in its own headless call (< 9 min); save images with relative paths (bpy.path.relpath)"
 },
 "export": {
  "decision": "Object hierarchy in Blender (each moving part its own object, pivot on its axis, drivers on object channels: what the user's Blender runs without Python and what the project's other rigs do). For Unreal the export stage builds a deform armature from it: one bone per moving object (head at the object's origin, same axes), every link mesh joined into one skinned mesh with weight 1.0 to its bone (rigid), the elbow cables weighted 1 -> 0 between upper and lower arm, the chain links one bone each; the 120 frames are baked from the object matrices to bone keys",
  "files": {
   "skeletal_A": "fbx/SK_DoorRobotArm_A.fbx (mesh + skeleton)",
   "skeletal_B": "fbx/SK_DoorRobotArm_B.fbx (same skeleton; finger bones unweighted)",
   "anims": "fbx/A_DoorRobotArm_AFT_OpenClose.fbx, A_DoorRobotArm_FORE_OpenClose.fbx (frames 1-120, 30 fps), A_DoorRobotArm_Grip.fbx (g 0 -> 1, 15 frames)",
   "fixtures": "fbx/SM_DoorArm_FixtureA.fbx, SM_DoorArm_FixtureB.fbx (attach to the door actor)",
   "rail_kit": "fbx/SM_DoorArm_RailKit.fbx (static); the chain links ride in the skeletal mesh",
   "static_parts": "fbx/parts/SM_DoorArm_<link>.fbx with UCX_ hulls (for a Blueprint build, if preferred)"
  },
  "settings": "FBX: Z up, -Y forward as the project's other exports; apply unit scale; add_leaf_bones False; bake_anim True; only the arm's collections (never CONTEXT); the rig root carries the hang (180 deg about X) so in Unreal it is the root bone's rotation",
  "unreal": "play the door's open/close timeline and the matching AnimSequence together (the solution is fixed by the door's 120 frames); switch versions by swapping SK_..._A / _B (one skeleton)"
 },
 "parts_m": {
  "Carriage": [
   {
    "id": "C01",
    "name": "turntable plate (ref: top plate)",
    "shape": "rbox",
    "size": [
     0.858,
     0.858,
     0.044,
     0.055
    ],
    "at": [
     0.0,
     0.0,
     -0.022
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "rounded corners R25, 3 px chamfer; a raised rounded pad 330x330x4 px in its middle under the slewing ring (r7)"
   },
   {
    "id": "C02",
    "name": "stacked plates x5",
    "shape": "rbox",
    "size": [
     0.8492,
     0.8492,
     0.0286,
     0.0528
    ],
    "at": [
     0.0,
     0.0,
     -0.0594
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "five plates 13 px thick with 2.5 px V-grooves between them (Z -20..-95); alternate plates inset 2 px; worn lighter edges (r1-3 show scratched paint on the dark carriage)"
   },
   {
    "id": "C03",
    "name": "strap band",
    "shape": "rbox",
    "size": [
     0.8624,
     0.8624,
     0.088,
     0.0484
    ],
    "at": [
     0.0,
     0.0,
     -0.253
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "Z -95..-135; on both rail-side faces (+-Y, the cheeks' outer faces in the ship): the dot panels and the strap+buckle"
   },
   {
    "id": "C03a",
    "name": "dot panels (2 per face, 4 total)",
    "shape": "box",
    "size": [
     0.154,
     0.0066,
     0.0616
    ],
    "at": [
     0.33,
     0.4312,
     -0.253
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "a raised panel at each end of the band; 2 rows x 3 round dimples, dimple dia 7 px, pitch 13 px"
   },
   {
    "id": "C03b",
    "name": "strap (flat)",
    "shape": "box",
    "size": [
     0.132,
     0.0088,
     0.0308
    ],
    "at": [
     0.209,
     0.4334,
     -0.2464
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "between dot panel and buckle"
   },
   {
    "id": "C03c",
    "name": "buckle chain (5 links per face)",
    "shape": "links",
    "size": [
     0.44,
     0.0132,
     0.0396
    ],
    "at": [
     0.0,
     0.4378,
     -0.2552
    ],
    "refs": "r4 r7",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "five articulated flat links, each 42x18x6 px with rounded ends and 2 pins; the two outer pairs angle down 12 deg, the centre link sits 10 px lower (the strap sags); static (no rig)"
   },
   {
    "id": "C04",
    "name": "lower block (ref)",
    "shape": "rbox",
    "size": [
     0.8536,
     0.8536,
     0.066,
     0.0528
    ],
    "at": [
     0.0,
     0.0,
     -0.33
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "Z -135..-165 with one groove line 4 px under its top edge"
   },
   {
    "id": "C05",
    "name": "skirt with chamfered notch",
    "shape": "rbox",
    "size": [
     0.858,
     0.858,
     0.044,
     0.055
    ],
    "at": [
     0.0,
     0.0,
     -0.385
    ],
    "refs": "r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "Z -165..-185; on the +-Y faces the middle 55% is cut back 15 px with 45 deg chamfers (the 'feet' at the ends); a thin raised line runs round the face 4 px from the edge"
   },
   {
    "id": "C06",
    "name": "rail channel (cut through C02..C05)",
    "shape": "channel",
    "size": [
     0.858,
     0.578,
     0.285
    ],
    "at": [
     0.0,
     0.0,
     -0.2645
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "U channel along X for the rail + running flanges, 0.578 m wide, from the cheek tops (ship z -3.775) down to ship z -4.06 (clears the rack by 0.01); pockets in its floor and cheeks for the rollers and the pinion; made with loops/extrusion, no boolean; the cheeks either side are 0.140 m thick"
   },
   {
    "id": "C07",
    "name": "load wheels x4",
    "shape": "cyl",
    "size": [
     0.1,
     0.04
    ],
    "at": [
     [
      0.3,
      -0.254,
      -0.252
     ],
     [
      -0.3,
      -0.254,
      -0.252
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "in the cheeks, axles along Y; they roll on the TOP of the running flanges K01 (ship z -3.93 centre)"
   },
   {
    "id": "C08",
    "name": "counter-rollers x4",
    "shape": "cyl",
    "size": [
     0.06,
     0.035
    ],
    "at": [
     [
      0.3,
      -0.254,
      -0.142
     ],
     [
      -0.3,
      -0.254,
      -0.142
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "under the running flanges (ship z -4.04 centre); hold the arm's tipping moment"
   },
   {
    "id": "C09",
    "name": "side guide rollers x4",
    "shape": "cyl",
    "size": [
     0.06,
     0.03
    ],
    "at": [
     [
      0.2,
      -0.309,
      -0.187
     ],
     [
      -0.2,
      -0.309,
      -0.187
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "vertical axles; run on the flanges' outer edges (lateral load)"
   },
   {
    "id": "C10",
    "name": "drive motor + gearbox + pinion",
    "shape": "cyl",
    "size": [
     0.12,
     0.3
    ],
    "at": [
     0.0,
     0.0,
     -0.084
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "axis along Y under the rail; pinion dia 0.096 (module 12, 8 teeth) meshes with the rack K02 from below; the motor's end cap (dia 0.12, steel bolt ring, thin orange ring) shows on the carriage's outboard face"
   },
   {
    "id": "C11",
    "name": "energy-chain bracket",
    "shape": "box",
    "size": [
     0.1,
     0.14,
     0.05
    ],
    "at": [
     0.0,
     -0.497,
     -0.387
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "on the inboard cheek top (ship +y); carries the chain's moving end at ship y -5.23"
   },
   {
    "id": "C12",
    "name": "buffer strike pads x2",
    "shape": "box",
    "size": [
     0.02,
     0.2,
     0.08
    ],
    "at": [
     [
      0.439,
      0.0,
      -0.112
     ],
     [
      -0.439,
      0.0,
      -0.112
     ]
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Carriage object in metres: A axes (X along the rail, Y = ship -y, Z = ship DOWN), origin at the turntable face centre; ship world = (c + X, -5.795 - Y, -4.182 - Z)",
    "note": "steel pads on both end faces below the rail (ship z -4.11..-4.03), where the rail's end-stop buffers K03 meet them"
   },
   {
    "id": "C13",
    "name": "slewing ring, fixed race",
    "shape": "ring",
    "size": [
     0.594,
     0.528,
     0.0176
    ],
    "at": [
     0.0,
     0.0,
     0.0088
    ],
    "refs": "r1 r4",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Carriage object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "on C01's pad; 24 bolt heads dia 8 px on a 255 px circle"
   }
  ],
  "Turret": [
   {
    "id": "T01",
    "name": "slewing ring, turning race",
    "shape": "ring",
    "size": [
     0.5764,
     0.0,
     0.0484
    ],
    "at": [
     0.0,
     0.0,
     0.033
    ],
    "refs": "r1 r4 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "three stacked rings with 2 V-grooves (r4); hollow centre for the cables (hidden)"
   },
   {
    "id": "T02",
    "name": "lower block (skirt)",
    "shape": "rbox",
    "size": [
     0.77,
     0.726,
     0.187,
     0.044
    ],
    "at": [
     -0.033,
     0.0,
     0.1474
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "X -190..160, Z 25..110; corners R20; seams: one horizontal groove 30 px above its foot"
   },
   {
    "id": "T02a",
    "name": "back screw strips",
    "shape": "box",
    "size": [
     0.0066,
     0.0396,
     0.176
    ],
    "at": [
     -0.4224,
     0.1144,
     0.1474
    ],
    "refs": "r7",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "two vertical strips on the back face (Y +-52) with 3 round screw heads each (dia 10 px, steel)"
   },
   {
    "id": "T02b",
    "name": "back latch slot",
    "shape": "box",
    "size": [
     0.0066,
     0.088,
     0.187
    ],
    "at": [
     -0.4224,
     0.0,
     0.1474
    ],
    "refs": "r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "a vertical slot in the back face with a bent U-tab (30x60 px, bar 8 px) hooked over its top (r7 centre)"
   },
   {
    "id": "T02c",
    "name": "side recess",
    "shape": "box",
    "size": [
     0.132,
     0.0088,
     0.033
    ],
    "at": [
     -0.066,
     0.3652,
     0.099
    ],
    "refs": "r1 r2",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "a horizontal recessed slot (r1 x_img 1030)"
   },
   {
    "id": "T02d",
    "name": "rear corner glands",
    "shape": "cyl",
    "size": [
     0.066,
     0.0484
    ],
    "at": [
     -0.33,
     0.3652,
     0.066
    ],
    "refs": "r1 r7",
    "mat": "rubber",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "where the side cable pairs end (r1 x_img 1135, y 1530)"
   },
   {
    "id": "T02e",
    "name": "front corner screws",
    "shape": "disc",
    "size": [
     0.022,
     0.0066
    ],
    "at": [
     [
      0.352,
      0.264,
      0.132
     ],
     [
      0.352,
      0.264,
      0.187
     ],
     [
      0.352,
      0.264,
      0.22
     ]
    ],
    "refs": "r4",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "X",
    "note": "three small screw heads up each front corner of the lower block (r4)"
   },
   {
    "id": "T02f",
    "name": "side slot panel",
    "shape": "rbox",
    "size": [
     0.154,
     0.0088,
     0.0484,
     0.0176
    ],
    "at": [
     -0.176,
     0.3652,
     0.11
    ],
    "refs": "r4",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "a recessed rounded slot panel low on each side of the lower block (r4, right of the cable)"
   },
   {
    "id": "T03",
    "name": "front housing",
    "shape": "plate2d",
    "size": [
     [
      0.55,
      0.242
     ],
     [
      0.55,
      0.638
     ],
     [
      0.44,
      0.748
     ],
     [
      0.132,
      0.77
     ],
     [
      -0.088,
      0.748
     ],
     [
      -0.088,
      0.242
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "side outline in X-Z (px) extruded Y +-140; top front edge chamfered 50 px; a lid 130x6 px on top (x_img 870-1000); two horizontal seams and one vertical seam on each side; fillets 6 px",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "T03a",
    "name": "front housing top plug",
    "shape": "cyl",
    "size": [
     0.055,
     0.0264
    ],
    "at": [
     0.33,
     0.0,
     0.781
    ],
    "refs": "r4",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Z",
    "note": "small round plug on the lid"
   },
   {
    "id": "T04",
    "name": "J2 ears",
    "shape": "rbox",
    "size": [
     0.572,
     0.187,
     0.572,
     0.088
    ],
    "at": [
     -0.341,
     0.3784,
     0.517
    ],
    "refs": "r1 r3 r7",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "the two side housings that hold the shoulder; inner faces at Y +-130 (the drum turns between them)"
   },
   {
    "id": "T04a",
    "name": "J2 motor caps",
    "shape": "stack",
    "size": [
     [
      0.363,
      0.0396,
      "paint_white"
     ],
     [
      0.264,
      0.022,
      "gunmetal"
     ],
     [
      0.1672,
      0.0066,
      "orange"
     ],
     [
      0.154,
      0.0308,
      "gunmetal"
     ],
     [
      0.088,
      0.022,
      "steel"
     ]
    ],
    "at": [
     -0.341,
     0.473,
     0.517
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "a stack of rings on each ear's outer face (outer dia, height px, material): white bezel, dark ring, thin ORANGE ring, dark stepped hub with 3 rings, hex bolt in the centre (r1: the orange-ring cap at x_img 1155)"
   },
   {
    "id": "T05",
    "name": "connector boss",
    "shape": "stack",
    "size": [
     [
      0.1144,
      0.022,
      "paint_white"
     ],
     [
      0.066,
      0.0176,
      "gunmetal"
     ]
    ],
    "at": [
     0.407,
     0.3124,
     0.44
    ],
    "refs": "r1 r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "double ring boss on the front housing side (r1 x_img 815; r4 left of the gland)"
   },
   {
    "id": "T06",
    "name": "cable port glands (side pairs start)",
    "shape": "stack",
    "size": [
     [
      0.1056,
      0.0264,
      "paint_white"
     ],
     [
      0.0704,
      0.044,
      "rubber"
     ]
    ],
    "at": [
     0.187,
     0.3124,
     0.44
    ],
    "refs": "r1 r2 r3 r4",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "white collar + rubber sleeve; the cable pair leaves here (r1 x_img 915, y 1350)"
   },
   {
    "id": "T07",
    "name": "orange hatch marking",
    "shape": "decal",
    "size": [
     0.154,
     0.044
    ],
    "at": [
     0.154,
     0.3102,
     0.726
    ],
    "refs": "r1 r2 r3",
    "mat": "orange",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "five 45-deg stripes in a thin frame + a thin line above it, on both sides of the front housing"
   },
   {
    "id": "T07a",
    "name": "warning stripes, lower block",
    "shape": "decal",
    "size": [
     0.066,
     0.077
    ],
    "at": [
     -0.374,
     0.3652,
     0.198
    ],
    "refs": "r1",
    "mat": "orange",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "small striped square (r1 x_img 1120, y 1460)"
   },
   {
    "id": "T08",
    "name": "bundle gland (front top)",
    "shape": "stack",
    "size": [
     [
      0.1364,
      0.066,
      "paint_white"
     ],
     [
      0.1056,
      0.0264,
      "rubber"
     ]
    ],
    "at": [
     0.451,
     0.132,
     0.6996
    ],
    "refs": "r1 r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "X",
    "note": "a round collar with a lip on the front housing top (r4); the multi-cable bundle leaves it forward"
   },
   {
    "id": "T09",
    "name": "cable bundle (7 cables)",
    "shape": "tube",
    "size": [
     0.022
    ],
    "at": [
     [
      0.451,
      0.132,
      0.726
     ],
     [
      0.638,
      0.1452,
      0.726
     ],
     [
      0.748,
      0.154,
      0.572
     ],
     [
      0.759,
      0.154,
      0.44
     ]
    ],
    "refs": "r1 r2 r4",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "7 black cables dia 10 px in a hexagonal pack (dia 34 px), arcing forward and down to the clamp T10; cable ends enter T11"
   },
   {
    "id": "T10",
    "name": "bundle clamp block",
    "shape": "rbox",
    "size": [
     0.154,
     0.132,
     0.11,
     0.0176
    ],
    "at": [
     0.726,
     0.154,
     0.407
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "two-part clamp with one bolt head (dia 15, steel) and a slot; orange tick on its face (r2)"
   },
   {
    "id": "T11",
    "name": "belt-drive arm",
    "shape": "rbox",
    "size": [
     0.286,
     0.154,
     0.176,
     0.022
    ],
    "at": [
     0.682,
     0.077,
     0.242
    ],
    "refs": "r1 r2 r4",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "white bracket from the front housing forward to the pulley; 3 small bolt heads (r4)"
   },
   {
    "id": "T12",
    "name": "drive pulley (J1 motor)",
    "shape": "stack",
    "size": [
     [
      0.1716,
      0.088,
      "paint_white"
     ],
     [
      0.132,
      0.0132,
      "gunmetal"
     ],
     [
      0.088,
      0.022,
      "gunmetal"
     ],
     [
      0.0396,
      0.0264,
      "steel"
     ]
    ],
    "at": [
     0.671,
     0.077,
     0.242
    ],
    "refs": "r1 r2 r3 r4",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "ringed white pulley (5 grooves) with a dark core and shaft (r1 x_img 695, y 1440)"
   },
   {
    "id": "T12b",
    "name": "drive motor end cap",
    "shape": "stack",
    "size": [
     [
      0.1276,
      0.0264,
      "paint_white"
     ],
     [
      0.0968,
      0.0088,
      "gunmetal"
     ],
     [
      0.066,
      0.0132,
      "glass_dark"
     ]
    ],
    "at": [
     0.55,
     0.165,
     0.242
    ],
    "refs": "r2 r4",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "the J1 motor's end on the belt arm's outer side, coaxial with the pulley: white ring, dark ring, dark lens (r2 turret crop)"
   },
   {
    "id": "T13",
    "name": "toothed belt",
    "shape": "belt",
    "size": [
     0.066,
     0.0176
    ],
    "at": [
     [
      0.671,
      0.077,
      0.242
     ],
     [
      0.33,
      0.077,
      0.154
     ]
    ],
    "refs": "r1 r4",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "black belt 30 px wide from the pulley T12 back to a hidden pulley in the lower block (x_img 850); teeth on the outside every 12 px (r4: rectangular lugs); static"
   },
   {
    "id": "T14",
    "name": "idler pulley",
    "shape": "stack",
    "size": [
     [
      0.066,
      0.0264,
      "gunmetal"
     ],
     [
      0.0264,
      0.0352,
      "steel"
     ]
    ],
    "at": [
     0.561,
     0.077,
     0.11
    ],
    "refs": "r1 r4",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "small dark pulley with a bolt (r1 x_img 745)"
   },
   {
    "id": "T15",
    "name": "side cable pairs (2 x 2 cables)",
    "shape": "tube",
    "size": [
     0.0264
    ],
    "at": [
     [
      0.187,
      0.33,
      0.44
     ],
     [
      0.132,
      0.66,
      0.385
     ],
     [
      -0.088,
      0.726,
      0.242
     ],
     [
      -0.264,
      0.55,
      0.088
     ],
     [
      -0.33,
      0.385,
      0.066
     ]
    ],
    "refs": "r1 r2 r3 r4 r7",
    "mat": "rubber",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "two cables per side side by side 25 px apart; loop out to Y +-330 (r7) and down to T02d; rubber ferrules at both ends"
   },
   {
    "id": "T16",
    "name": "dot vent",
    "shape": "box",
    "size": [
     0.088,
     0.0066,
     0.055
    ],
    "at": [
     0.264,
     0.3124,
     0.253
    ],
    "refs": "r4",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "dark panel with 6x4 round holes dia 4 px (r4, under the housing)"
   },
   {
    "id": "T17",
    "name": "recessed vent slot",
    "shape": "box",
    "size": [
     0.033,
     0.0088,
     0.088
    ],
    "at": [
     0.462,
     0.3124,
     0.352
    ],
    "refs": "r4",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "Turret object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "a vertical slot with one sloped edge (r4)"
   }
  ],
  "LowerArm": [
   {
    "id": "L01",
    "name": "drum (J2 barrel)",
    "shape": "cyl",
    "size": [
     0.594,
     0.462
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r2 r3 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "turns with the lower arm between the turret ears; perforated: side faces 24 holes dia 14 px on a 210 px circle; barrel face 2 rows x 24 holes dia 16 px at Y +-55 (r7); holes are blind recesses 8 px deep (quad rings)"
   },
   {
    "id": "L02",
    "name": "root shells",
    "shape": "plate2d",
    "size": [
     [
      0.363,
      0.0
     ],
     [
      0.0,
      0.363
     ],
     [
      -0.319,
      0.275
     ],
     [
      -0.385,
      0.0
     ],
     [
      0.0,
      -0.363
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "the white side shells round the drum (R 160 about J2, white rim ring visible round the drum in r1), Y +-205 outer, blending into the beam L03",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "L03",
    "name": "beam J2 -> knee -> crotch",
    "shape": "plate2d",
    "size": [
     [
      0.209,
      0.209
     ],
     [
      -0.209,
      0.715
     ],
     [
      -0.385,
      0.891
     ],
     [
      -0.803,
      0.627
     ],
     [
      -0.693,
      0.209
     ],
     [
      -0.385,
      -0.011
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "box section, Y +-205 outer; side outline in X-Z px; seams and raised panels on the sides (r5)",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "L04",
    "name": "back channel",
    "shape": "channel",
    "size": [
     0.242,
     0.099
    ],
    "at": [
     [
      -0.275,
      0.0,
      -0.143
     ],
     [
      -0.693,
      0.0,
      0.473
     ],
     [
      -0.891,
      0.0,
      1.111
     ]
    ],
    "refs": "r3 r5 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "recessed channel down the back face (Y +-55, 45 px deep) from the drum to the elbow; the J3 cylinder lies in it"
   },
   {
    "id": "L05",
    "name": "rungs",
    "shape": "box",
    "size": [
     0.022,
     0.242,
     0.066
    ],
    "at": [
     [
      -0.275,
      0.0,
      -0.143
     ],
     [
      -0.891,
      0.0,
      1.111
     ]
    ],
    "refs": "r1 r2 r5 r7",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "cross ribs every 20 px along the channel (about 40); in r1/r2 they show as the dashed strip on the arm's upper edge"
   },
   {
    "id": "L06",
    "name": "knee bosses",
    "shape": "ring",
    "size": [
     0.55,
     0.44,
     0.044
    ],
    "at": [
     -0.5236,
     0.451,
     0.33
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "raised white ring round each slotted cap"
   },
   {
    "id": "L07",
    "name": "knee caps (radial slotted)",
    "shape": "stack",
    "size": [
     [
      0.418,
      0.022,
      "gunmetal"
     ],
     [
      0.264,
      0.0132,
      "gunmetal"
     ],
     [
      0.198,
      0.0132,
      "gunmetal"
     ],
     [
      0.132,
      0.0132,
      "gunmetal"
     ],
     [
      0.121,
      0.0044,
      "orange"
     ],
     [
      0.055,
      0.0176,
      "steel"
     ]
    ],
    "at": [
     -0.5236,
     0.473,
     0.33
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "black disc with 10 radial slots (35x12 px, open at the rim like teeth, at r 70), a stepped inner hub, a thin ORANGE ring and a bolt; they cover the J3 cylinder's trunnion pin"
   },
   {
    "id": "L18",
    "name": "front dark core + inner cap",
    "shape": "plate2d",
    "size": [
     [
      -0.385,
      0.583
     ],
     [
      -0.605,
      1.023
     ],
     [
      -0.693,
      1.199
     ],
     [
      -0.539,
      1.155
     ],
     [
      -0.319,
      0.715
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "between the side shells on the lower arm's front a dark core shows (r1: the black region under the upper arm; r5: dark plates with two round bosses dia 20 px and small bolt heads); an inner round cap dia 45 px at (-380, 0, 645) (r1 x_img 1380, y 905)",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "L08",
    "name": "hexagon outline (orange)",
    "shape": "decal",
    "size": [
     0.11,
     0.11
    ],
    "at": [
     -0.176,
     0.4532,
     0.297
    ],
    "refs": "r1 r2",
    "mat": "orange",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "3 px line, left side only (r1 x_img 1235, y 1165)"
   },
   {
    "id": "L09",
    "name": "triangle outline (orange)",
    "shape": "decal",
    "size": [
     0.0396,
     0.0396
    ],
    "at": [
     -0.451,
     0.4532,
     0.605
    ],
    "refs": "r1 r5",
    "mat": "orange",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "small, left side (r1 x_img 1360, y 1040)"
   },
   {
    "id": "L10",
    "name": "light slot",
    "shape": "box",
    "size": [
     0.0396,
     0.0132,
     0.308
    ],
    "at": [
     -0.814,
     0.4532,
     0.979
    ],
    "refs": "r1 r5",
    "mat": "lamp",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "recessed slot inclined along the arm with a pale bar inside (r1 x_img 1505-1550, y 800-940); left side only; very faint glow"
   },
   {
    "id": "L11",
    "name": "round button",
    "shape": "stack",
    "size": [
     [
      0.066,
      0.0132,
      "gunmetal"
     ],
     [
      0.0484,
      0.0176,
      "paint_white"
     ]
    ],
    "at": [
     -0.726,
     0.4532,
     0.66
    ],
    "refs": "r1 r5",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "domed button, left side (r1 x_img 1485, y 1015)"
   },
   {
    "id": "L12",
    "name": "stepped side panels",
    "shape": "plate2d",
    "size": [
     [
      -0.539,
      0.627
     ],
     [
      -0.803,
      0.891
     ],
     [
      -0.891,
      1.199
     ],
     [
      -0.693,
      1.023
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r5",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "raised panels 6 px proud with 45 deg steps and the notch block near the knee top (r5)",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "L13",
    "name": "handles (bent tube)",
    "shape": "U",
    "size": [
     0.154,
     0.33,
     0.0264
    ],
    "at": [
     -0.693,
     0.407,
     0.319
    ],
    "refs": "r1 r3 r5 r7",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "on the back face near each side edge at knee height, standing out backward 70 px; the outer leg has a segmented sleeve of 5 rings (r5); two small mounting blocks 18x18x12 px"
   },
   {
    "id": "L14",
    "name": "elbow yoke cheeks",
    "shape": "plate2d",
    "size": [
     [
      -0.693,
      1.023
     ],
     [
      -0.979,
      1.155
     ],
     [
      -1.067,
      1.309
     ],
     [
      -0.869,
      1.496
     ],
     [
      -0.693,
      1.397
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r5",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "two cheeks Y +-(125..205) from the crotch (55% of knee->J3) to J3, rounded R 85 round J3; the upper arm turns between them",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "L15",
    "name": "elbow caps",
    "shape": "stack",
    "size": [
     [
      0.308,
      0.0264,
      "paint_white"
     ],
     [
      0.242,
      0.0132,
      "gunmetal"
     ],
     [
      0.22,
      0.0264,
      "gunmetal"
     ],
     [
      0.132,
      0.0088,
      "steel"
     ]
    ],
    "at": [
     -0.869,
     0.451,
     1.309
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "black cap with a straight slot 60x12 px across ('minus' screw head) and two small tick notches at 12 and 6 o'clock"
   },
   {
    "id": "L16",
    "name": "inner channel guide + hose loop",
    "shape": "box",
    "size": [
     0.088,
     0.132,
     0.132
    ],
    "at": [
     -0.891,
     0.0,
     1.155
    ],
    "refs": "r3",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "note": "in the channel's upper end (r3: a threaded rod and a white sliding block); here: the J3 cylinder's hose loop and a guide block (added)"
   },
   {
    "id": "L17",
    "name": "cable gland, back of elbow",
    "shape": "stack",
    "size": [
     [
      0.0748,
      0.022,
      "paint_white"
     ],
     [
      0.0528,
      0.0308,
      "rubber"
     ]
    ],
    "at": [
     -1.067,
     0.132,
     1.243
    ],
    "refs": "r1 r3",
    "mat": "mixed",
    "both": false,
    "units": "m",
    "frame": "LowerArm object (origin [-0.341, 0.0, 0.517] m in the arm frame A at rest)",
    "axis": "X",
    "note": "twin gland where the two upper-arm cables U09 come in (r1 x_img 1620-1640, y 690-710)"
   }
  ],
  "Cylinder": [
   {
    "id": "R01",
    "name": "barrel",
    "shape": "cyl",
    "size": [
     0.075,
     0.8
    ],
    "at": [
     0.1,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "black barrel from 0.30 m behind the trunnion to 0.50 m ahead of it (middle trunnion), on the line to the knob; the part behind the trunnion stays inside the lower arm channel"
   },
   {
    "id": "R02",
    "name": "trunnion block + pin",
    "shape": "box",
    "size": [
     0.1,
     0.11,
     0.1
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "pin dia 0.06 across the lower arm, hidden by the knee caps"
   },
   {
    "id": "R03",
    "name": "gland collar",
    "shape": "cyl",
    "size": [
     0.085,
     0.04
    ],
    "at": [
     0.48,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Cylinder object: origin at the trunnion; at = (s, 0, 0) with s measured along the rod axis u = (-0.7997, 0, 0.6003) (lower-arm rest axes, toward the knob)",
    "note": "bright ring where the rod leaves the barrel"
   },
   {
    "id": "R04",
    "name": "hoses x2",
    "shape": "tube",
    "size": [
     0.02
    ],
    "at": [],
    "refs": "added",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "A",
    "note": "from the barrel's two ports into the channel wall; hooked at both ends"
   }
  ],
  "Piston": [
   {
    "id": "R05",
    "name": "piston rod",
    "shape": "cyl",
    "size": [
     0.05,
     0.8
    ],
    "at": [
     -0.4,
     0.0,
     0.0
    ],
    "refs": "r1 r3 r5",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Piston object: origin at the rod eye centre; at = (s, 0, 0) with s along the rod axis u (negative = into the barrel)",
    "note": "chrome rod from its eye 0.80 m back to the piston"
   },
   {
    "id": "R06",
    "name": "rod eye",
    "shape": "ring",
    "size": [
     0.075,
     0.05,
     0.024
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r3",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Piston object: origin at the rod eye centre",
    "note": "eye on the knob pin between the two truss plates"
   }
  ],
  "UpperArm": [
   {
    "id": "U01",
    "name": "elbow hub",
    "shape": "cyl",
    "size": [
     0.33,
     0.506
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r5",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "between the yoke cheeks (Y +-115)"
   },
   {
    "id": "U02",
    "name": "housing (the hump)",
    "shape": "plate2d",
    "size": [
     [
      -0.198,
      -0.066
     ],
     [
      -0.11,
      0.396
     ],
     [
      0.176,
      0.55
     ],
     [
      0.484,
      0.583
     ],
     [
      0.858,
      0.583
     ],
     [
      0.858,
      0.132
     ],
     [
      0.55,
      0.088
     ],
     [
      0.176,
      -0.066
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "side outline X-Z px, Y +-110; a raised spine along the top; a dark recess strip along the lower edge (x_img 1380-1500); seams",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "U03",
    "name": "big caps",
    "shape": "stack",
    "size": [
     [
      0.363,
      0.0308,
      "paint_white"
     ],
     [
      0.2288,
      0.0088,
      "orange"
     ],
     [
      0.22,
      0.022,
      "glass_dark"
     ],
     [
      0.1584,
      0.0132,
      "steel"
     ]
    ],
    "at": [
     0.6336,
     0.2464,
     0.341
    ],
    "refs": "r1 r2 r3",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "white bezel, thin ORANGE ring, a dark glossy recessed disc and a slotted screw head (bar 70x14 px) inside"
   },
   {
    "id": "U04",
    "name": "ribbed vents",
    "shape": "box",
    "size": [
     0.22,
     0.0132,
     0.121
    ],
    "at": [
     0.176,
     0.2442,
     0.209
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "raised panel with 8 slots 10x45 px, pitch 12 px, inclined 30 deg along the top edge"
   },
   {
    "id": "U05",
    "name": "indicator lights",
    "shape": "stack",
    "size": [
     [
      0.0726,
      0.0088,
      "gunmetal"
     ],
     [
      0.055,
      0.0132,
      "lamp"
     ]
    ],
    "at": [
     0.429,
     0.2442,
     0.198
    ],
    "refs": "r1 r3",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "white lens in a dark ring; faint glow"
   },
   {
    "id": "U06",
    "name": "small dot",
    "shape": "disc",
    "size": [
     0.0176,
     0.0044
    ],
    "at": [
     0.297,
     0.2442,
     0.242
    ],
    "refs": "r1",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "axis": "Y"
   },
   {
    "id": "U07",
    "name": "orange ticks",
    "shape": "decal",
    "size": [
     0.0308,
     0.0308
    ],
    "at": [
     0.055,
     0.2442,
     0.396
    ],
    "refs": "r1 r2",
    "mat": "orange",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "two small abstract chevrons (the reference has glyphs; no text here)"
   },
   {
    "id": "U08",
    "name": "twin cable gland",
    "shape": "rbox",
    "size": [
     0.11,
     0.088,
     0.066,
     0.0132
    ],
    "at": [
     0.176,
     0.11,
     0.418
    ],
    "refs": "r1 r2 r3",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "on the top behind the vents; two rubber glands dia 16 px face backward"
   },
   {
    "id": "U09",
    "name": "two cables over the elbow",
    "shape": "tube",
    "size": [
     0.0264
    ],
    "at": [
     [
      0.176,
      0.11,
      0.418
     ],
     [
      -0.198,
      0.121,
      0.594
     ],
     [
      -0.572,
      0.132,
      0.352
     ],
     [
      -0.462,
      0.1364,
      0.066
     ],
     [
      -0.198,
      0.132,
      -0.066
     ]
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "cross J3: hooked at both ends, middle points blended 50/50 (see the rig); 18 px apart"
   },
   {
    "id": "U10",
    "name": "truss plates (pair)",
    "shape": "plate2d",
    "size": [
     [
      -0.022,
      0.066
     ],
     [
      0.11,
      -0.154
     ],
     [
      -0.418,
      -0.44
     ],
     [
      -0.528,
      -0.33
     ],
     [
      -0.132,
      0.066
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r5",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "two plates Y +-(14..40) behind the elbow down to the knob; raised rim 8 px; 4 triangular cut-outs alternating (the 'ANN' pattern), dark backing visible through them; the rod eye sits between the plates",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "U11",
    "name": "knob pin + caps",
    "shape": "knurl",
    "size": [
     0.1364,
     0.044,
     24
    ],
    "at": [
     -0.4664,
     0.1012,
     -0.3696
    ],
    "refs": "r1 r3 r5",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "pin dia 50 px through both plates; knurled caps (24 ribs) on both sides with a dark dome centre dia 25"
   },
   {
    "id": "U12",
    "name": "front block (J4 housing)",
    "shape": "rbox",
    "size": [
     0.209,
     0.462,
     0.451,
     0.0264
    ],
    "at": [
     1.0076,
     0.0,
     0.3564
    ],
    "refs": "r1 r2 r3",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "UpperArm object (origin [-1.21, 0.0, 1.826] m in the arm frame A at rest)",
    "note": "X -140..-45; 3 ring grooves round it; a small square button (x_img 1090, y 520), a small white indicator rectangle 18x10 px (x_img 1155, y 545, lamp), a dark bolt (x_img 1150, y 650)"
   }
  ],
  "Forearm": [
   {
    "id": "F01",
    "name": "roll bearing ring",
    "shape": "ring",
    "size": [
     0.418,
     0.33,
     0.0264
    ],
    "at": [
     0.0132,
     0.0,
     0.0
    ],
    "refs": "r1 r2 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "the black thin ring between the upper arm and the forearm"
   },
   {
    "id": "F02",
    "name": "dial housing",
    "shape": "rbox",
    "size": [
     0.55,
     0.418,
     0.429,
     0.066
    ],
    "at": [
     0.275,
     0.0,
     0.022
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "X -35..215, Z 850..1045"
   },
   {
    "id": "F03",
    "name": "dark side plates",
    "shape": "rbox",
    "size": [
     0.506,
     0.0132,
     0.319,
     0.066
    ],
    "at": [
     0.286,
     0.2112,
     0.077
    ],
    "refs": "r1 r3 r6",
    "mat": "gunmetal",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "rounded plates with a '7'-shaped groove near the rear top corner (r6), a small bolt with a white ring at x_img 1015"
   },
   {
    "id": "F04",
    "name": "dials",
    "shape": "stack",
    "size": [
     [
      0.242,
      0.0132,
      "gunmetal"
     ],
     [
      0.187,
      0.0088,
      "gunmetal"
     ],
     [
      0.121,
      0.0088,
      "steel"
     ],
     [
      0.044,
      0.0132,
      "gunmetal"
     ]
    ],
    "at": [
     0.275,
     0.22,
     0.0506
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "black stepped disc with a '+' cross groove (6 px) through it and 4 notches on the rim (r6)"
   },
   {
    "id": "F05",
    "name": "belly",
    "shape": "rbox",
    "size": [
     0.44,
     0.352,
     0.132,
     0.0308
    ],
    "at": [
     0.319,
     0.0,
     -0.1254
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "below the side plates; seam; a flat bar 230x25 px under it (r6)"
   },
   {
    "id": "F06",
    "name": "orange dot grids",
    "shape": "decal",
    "size": [
     0.0572,
     0.0308
    ],
    "at": [
     0.473,
     0.2112,
     0.0066
    ],
    "refs": "r1 r3",
    "mat": "orange",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "2 x 3 dots dia 5 px"
   },
   {
    "id": "F07",
    "name": "J5/J6 motor cylinder",
    "shape": "cyl",
    "size": [
     0.165,
     0.198
    ],
    "at": [
     0.638,
     0.0,
     0.1386
    ],
    "refs": "r1 r2 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "ringed (3 grooves) white cylinder, top front, joining the wrist block"
   },
   {
    "id": "F08",
    "name": "hose",
    "shape": "tube",
    "size": [
     0.0484
    ],
    "at": [
     [
      0.517,
      -0.022,
      -0.1474
     ],
     [
      0.649,
      -0.022,
      -0.1694
     ],
     [
      0.803,
      -0.022,
      -0.1474
     ]
    ],
    "refs": "r1 r3 r6",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "black hose with metal ferrules (dia 28 x 15 px) at both ends and an ORANGE band (6 px) near the front end"
   },
   {
    "id": "F09",
    "name": "wrist block (fork)",
    "shape": "plate2d",
    "size": [
     [
      0.55,
      0.2596
     ],
     [
      0.814,
      0.2376
     ],
     [
      1.045,
      0.1166
     ],
     [
      1.177,
      0.0
     ],
     [
      1.045,
      -0.1694
     ],
     [
      0.55,
      -0.1914
     ]
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "angled housing Y +-75; its front is a fork (cheeks Y +-(55..75)) carrying J5; lobes R 60 round WC",
    "size_note": "outline (x, z) in the link frame, metres"
   },
   {
    "id": "F10",
    "name": "wrist fin (left)",
    "shape": "rbox",
    "size": [
     0.165,
     0.033,
     0.0484,
     0.0176
    ],
    "at": [
     0.803,
     0.1672,
     0.1716
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "raised rounded bar, inclined 20 deg; right side has an oval recessed slot 70x18 px instead (r3)"
   },
   {
    "id": "F11",
    "name": "orange triangles + dots",
    "shape": "decal",
    "size": [
     0.077,
     0.055
    ],
    "at": [
     0.836,
     0.1672,
     0.0836
    ],
    "refs": "r1 r3 r6",
    "mat": "orange",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "three small triangles and two dots (left); 2x2 dots (right)"
   },
   {
    "id": "F12",
    "name": "screw caps",
    "shape": "disc",
    "size": [
     0.033,
     0.011
    ],
    "at": [
     [
      0.957,
      0.1672,
      -0.0154
     ],
     [
      0.924,
      0.1672,
      -0.1144
     ]
    ],
    "refs": "r1 r6",
    "mat": "paint_white",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "two white domes per side"
   },
   {
    "id": "F13",
    "name": "bottom handle",
    "shape": "U",
    "size": [
     0.121,
     0.033,
     0.011
    ],
    "at": [
     0.9284,
     0.0,
     -0.209
    ],
    "refs": "r1 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "flat-bar loop under the wrist block"
   },
   {
    "id": "F14",
    "name": "J5 caps (wrist round caps)",
    "shape": "stack",
    "size": [
     [
      0.22,
      0.0132,
      "gunmetal"
     ],
     [
      0.176,
      0.0088,
      "gunmetal"
     ],
     [
      0.132,
      0.0088,
      "gunmetal"
     ],
     [
      0.088,
      0.0088,
      "steel"
     ],
     [
      0.044,
      0.0088,
      "gunmetal"
     ]
    ],
    "at": [
     1.034,
     0.1672,
     0.0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "mixed",
    "both": true,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "stepped concentric rings on both cheeks"
   },
   {
    "id": "F15",
    "name": "wrist top cylinder",
    "shape": "cyl",
    "size": [
     0.099,
     0.088
    ],
    "at": [
     0.781,
     0.0,
     0.1496
    ],
    "refs": "r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "Forearm object (origin [-0.077, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "short cylinder with a black band on the wrist block top; kept outside 0.25 m of the wrist centre on the upper side, where the tool swings"
   }
  ],
  "WristHead": [
   {
    "id": "W01",
    "name": "head drum",
    "shape": "cyl",
    "size": [
     0.209,
     0.2332
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "WristHead object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "between the fork cheeks, turns about Y"
   },
   {
    "id": "W02",
    "name": "neck collar",
    "shape": "cyl",
    "size": [
     0.165,
     0.0264
    ],
    "at": [
     0.077,
     0.0,
     0.0
    ],
    "refs": "r1 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "WristHead object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X"
   }
  ],
  "Flange": [
   {
    "id": "FL1",
    "name": "knurled ring",
    "shape": "knurl",
    "size": [
     0.1584,
     0.055,
     36
    ],
    "at": [
     0.1034,
     0.0,
     0.0
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Flange object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "J6 turns here (r6 knurled neck)"
   },
   {
    "id": "FL2",
    "name": "flange face",
    "shape": "disc",
    "size": [
     0.176,
     0.011
    ],
    "at": [
     0.1364,
     0.0,
     0.0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Flange object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "6 bolt holes; tools bolt here"
   }
  ],
  "ToolA": [
   {
    "id": "A01",
    "name": "hub",
    "shape": "cyl",
    "size": [
     0.275,
     0.165
    ],
    "at": [
     0.2134,
     0.0,
     0.0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "ToolA object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "white body with a black ring at each end, 3 grooves; front face: 4 dark stepped rings (dia 125/100/75/45)"
   },
   {
    "id": "A02",
    "name": "finger brackets x4",
    "shape": "box",
    "size": [
     0.077,
     0.066,
     0.055
    ],
    "at": [
     0.2574,
     0.0,
     0.154
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "ToolA object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "on the hub's front rim at r 70, one per finger"
   },
   {
    "id": "A03",
    "name": "finger motors x4",
    "shape": "knurl",
    "size": [
     0.066,
     0.143,
     24
    ],
    "at": [
     0.319,
     0.0,
     0.242
    ],
    "refs": "r1 r2 r6",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "ToolA object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "knurled cylinder fixed to each bracket, axis in the finger's plane pointing back-outward 20 deg from the tool axis (r1 top finger)"
   }
  ],
  "Finger": [
   {
    "id": "A04",
    "name": "knuckle pin caps",
    "shape": "disc",
    "size": [
     0.0528,
     0.0132
    ],
    "at": [
     0.0,
     0.0,
     0.0
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Finger object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y",
    "note": "both sides of the knuckle"
   },
   {
    "id": "A05",
    "name": "proximal link",
    "shape": "rbox",
    "size": [
     0.1936,
     0.0396,
     0.0484,
     0.011
    ],
    "at": [
     0.0968,
     0.0,
     0.0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Finger object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "with a ribbed rubber boot (8 ribs, dia 26, 45 px long) on its middle and a threaded tendon rod dia 5 px along its outer side"
   },
   {
    "id": "A06",
    "name": "distal pin caps",
    "shape": "disc",
    "size": [
     0.044,
     0.0132
    ],
    "at": [
     0.1936,
     0.0,
     0.0
    ],
    "refs": "r1 r6",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "Finger object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "axis": "Y"
   },
   {
    "id": "A07",
    "name": "distal link + hooked tip",
    "shape": "rbox",
    "size": [
     0.154,
     0.0352,
     0.0396,
     0.0088
    ],
    "at": [
     0.2706,
     0.0,
     0.0
    ],
    "refs": "r1 r2 r3 r6",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "Finger object (origin [0.0, 0.0, 0.0] m in the arm frame A at rest)",
    "note": "tapered 18 -> 10 px; a 15 px hook turned inward at the tip; ridged steel jaw insert on the inner face"
   }
  ],
  "ToolB": [
   {
    "id": "B01",
    "name": "flared neck",
    "shape": "cone",
    "size": [
     0.154,
     0.2926,
     0.4334
    ],
    "at": [
     0.3476,
     0.0,
     0.0
    ],
    "refs": "r6 (red sketch)",
    "mat": "paint_white",
    "both": false,
    "units": "m",
    "frame": "ToolB object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "axis": "X",
    "note": "trumpet-shaped: the sketch's two lines spread from the wrist to the plate (the sketch is a 3/4 view looking along the tool, so the neck shows short); 0.434 m long so the plate's face lands where version A grips (both versions share one arm pose); straight for its first 60%, flaring over the last 40%; two ring grooves; fillet into the plate"
   },
   {
    "id": "B02",
    "name": "mounting plate",
    "shape": "rbox",
    "size": [
     0.044,
     0.55,
     0.55,
     0.033
    ],
    "at": [
     0.5852,
     0.0,
     0.0
    ],
    "refs": "r6 (red sketch)",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "ToolB object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "square plate 0.55 x 0.55 x 0.044 m, corner R 0.033, 2 mm chamfers; its door face is flat"
   },
   {
    "id": "B03",
    "name": "plate bolts x8",
    "shape": "hex",
    "size": [
     0.0396,
     0.022
    ],
    "at": [
     0.561,
     0.0,
     0.0
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "ToolB object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "M24-size hex heads, 2 per edge on a 0.46 m square"
   },
   {
    "id": "B04",
    "name": "orange corner ticks",
    "shape": "decal",
    "size": [
     0.044,
     0.044
    ],
    "at": [
     0.561,
     0.0,
     0.0
    ],
    "refs": "added (matches the arm's accents)",
    "mat": "orange",
    "both": false,
    "units": "m",
    "frame": "ToolB object (origin [0.957, 0.0, 2.0614] m in the arm frame A at rest)",
    "note": "four small L-ticks at the plate's corners"
   }
  ],
  "DoorFixtureA": [
   {
    "id": "DA1",
    "name": "conformal pad",
    "shape": "pad",
    "size": [
     0.32,
     0.32,
     0.02
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local: Z = door normal",
    "note": "underside follows the door's inner face (ray-cast), top flat"
   },
   {
    "id": "DA2",
    "name": "base plate",
    "shape": "rbox",
    "size": [
     0.26,
     0.26,
     0.03,
     0.02
    ],
    "at": [
     0,
     0,
     0.035
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "4 bolts"
   },
   {
    "id": "DA3",
    "name": "stem",
    "shape": "cyl",
    "size": [
     0.08,
     0.115
    ],
    "at": [
     0,
     0,
     0.1075
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "fixture local"
   },
   {
    "id": "DA4",
    "name": "grab knob (mushroom head)",
    "shape": "cyl",
    "size": [
     0.13,
     0.05
    ],
    "at": [
     0,
     0,
     0.19
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "3 mm chamfers; the 4 hooked tips close under it round the stem"
   }
  ],
  "DoorFixtureB": [
   {
    "id": "DB1",
    "name": "conformal pad",
    "shape": "pad",
    "size": [
     0.6,
     0.6,
     0.02
    ],
    "at": [
     0,
     0,
     0
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "fixture local",
    "note": "underside follows the door's face; the plate B02 bolts to its flat top"
   }
  ],
  "RailKit": [
   {
    "id": "K01",
    "name": "running flanges x2",
    "shape": "box",
    "size": [
     6.49,
     0.05,
     0.03
    ],
    "at": [
     -5.79,
     -6.0488,
     -3.995
    ],
    "refs": "added",
    "mat": "steel",
    "both": true,
    "units": "m",
    "frame": "world",
    "note": "flat bars bolted to both side faces at the rail's bottom, x -9.0348..-2.5453, z -4.010..-3.980, protruding 0.05 (y -6.0738..-6.0238 and -5.5662..-5.5162); bolt heads (M16) every 0.25 m on their outer faces"
   },
   {
    "id": "K02",
    "name": "rack",
    "shape": "rack",
    "size": [
     5.32,
     0.06,
     0.04
    ],
    "at": [
     -5.565,
     -5.795,
     -4.03
    ],
    "refs": "added",
    "mat": "steel",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "gear rack bolted under the rail's bottom face over the pinion's travel (x -8.225..-2.905), teeth down, module 12 mm"
   },
   {
    "id": "K03",
    "name": "end stops x2",
    "shape": "box",
    "size": [
     0.13,
     0.3,
     0.12
    ],
    "at": [
     [
      -8.62,
      -5.795,
      -4.07
     ],
     [
      -2.525,
      -5.795,
      -4.07
     ]
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "wall end: steel block x -8.685..-8.585 bolted under the rail + rubber buffer x -8.585..-8.555; inner end: rubber buffer x -2.575..-2.545 + steel block x -2.545..-2.475 bolted to the rail's end face and underside; both z -4.13..-4.01 between the flanges; the carriage's end faces (strike pads C12) stop 10 mm short of the buffers at its travel ends (c -8.1158 / -3.0143)"
   },
   {
    "id": "K04",
    "name": "energy-chain tray",
    "shape": "channel",
    "size": [
     6.05,
     0.4,
     0.125
    ],
    "at": [
     -5.975,
     -5.08,
     -3.84
    ],
    "refs": "added",
    "mat": "gunmetal",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "a shallow tray hung under the deck on the inboard side: y -5.28..-4.88, floor top at z -3.895, walls to -3.78, x -9.00 to a slanted well-side end (x -2.95 at y -5.28, -3.08 at y -4.88: >= 0.05 m short of the moon pool well's rounded edge); hangers to the deck every 0.8 m"
   },
   {
    "id": "K05",
    "name": "energy chain",
    "shape": "chain",
    "size": [
     3.27,
     0.1,
     0.06
    ],
    "at": [],
    "refs": "added",
    "mat": "rubber",
    "both": false,
    "units": "m",
    "frame": "world",
    "note": "lying on its side in the tray (bend axis vertical), 44 links of pitch 0.075 m (link 0.075 x 0.06 x 0.10 high), length 3.30 m, bend radius 0.15 m; runs at y -5.23 (moving, carriage side) and -4.93 (fixed); fixed end at x -5.565 (mid travel), moving end on the carriage bracket C11; the loop travels x -8.40..-5.70; links are rigid objects driven by simple expressions of the carriage x"
   }
  ]
 },
 "drivers": {
  "AFT": {
   "solver_empties": [
    "DoorArm_AFT | IK1 target",
    "DoorArm_AFT | IK2 yaw",
    "DoorArm_AFT | IK3 shoulder",
    "DoorArm_AFT | IK4 elbow",
    "DoorArm_AFT | IK5 wrist matrix",
    "DoorArm_AFT | IK6 wrist angles",
    "DoorArm_AFT | chain solver"
   ],
   "joint_and_solver_drivers": [
    {
     "target": "DoorArm_AFT | IK1 target",
     "path": "[\"c\"]",
     "index": null,
     "expr": "-3.929709 + 0.265346*dx",
     "vars": [
      [
       "dx",
       "Moonpool_Door_Aft",
       "location[0]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK1 target",
     "path": "[\"X\"]",
     "index": null,
     "expr": "0.734654*dx + 3.843929",
     "vars": [
      [
       "dx",
       "Moonpool_Door_Aft",
       "location[0]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK1 target",
     "path": "[\"Y\"]",
     "index": null,
     "expr": "-3.842859 - dy",
     "vars": [
      [
       "dy",
       "Moonpool_Door_Aft",
       "location[1]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK1 target",
     "path": "[\"H\"]",
     "index": null,
     "expr": "-4.495795 - dz",
     "vars": [
      [
       "dz",
       "Moonpool_Door_Aft",
       "location[2]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK2 yaw",
     "path": "[\"q1\"]",
     "index": null,
     "expr": "atan2(Y, X)",
     "vars": [
      [
       "X",
       "DoorArm_AFT | IK1 target",
       "[\"X\"]"
      ],
      [
       "Y",
       "DoorArm_AFT | IK1 target",
       "[\"Y\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK2 yaw",
     "path": "[\"R\"]",
     "index": null,
     "expr": "sqrt(X*X + Y*Y) + 0.5456",
     "vars": [
      [
       "X",
       "DoorArm_AFT | IK1 target",
       "[\"X\"]"
      ],
      [
       "Y",
       "DoorArm_AFT | IK1 target",
       "[\"Y\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK2 yaw",
     "path": "[\"Hh\"]",
     "index": null,
     "expr": "H - 0.8272",
     "vars": [
      [
       "H",
       "DoorArm_AFT | IK1 target",
       "[\"H\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK3 shoulder",
     "path": "[\"phi_l\"]",
     "index": null,
     "expr": "atan2(Hh, R) + acos(clamp((-11.19435933 + R*R + Hh*Hh) / (5.027812*sqrt(R*R + Hh*Hh)), -1, 1))",
     "vars": [
      [
       "R",
       "DoorArm_AFT | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_AFT | IK2 yaw",
       "[\"Hh\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK3 shoulder",
     "path": "[\"q2\"]",
     "index": null,
     "expr": "atan2(Hh, R) + acos(clamp((-11.19435933 + R*R + Hh*Hh) / (5.027812*sqrt(R*R + Hh*Hh)), -1, 1)) - 2.156857",
     "vars": [
      [
       "R",
       "DoorArm_AFT | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_AFT | IK2 yaw",
       "[\"Hh\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK4 elbow",
     "path": "[\"phi_f\"]",
     "index": null,
     "expr": "atan2(Hh - 2.513906*sin(phi_l), R - 2.513906*cos(phi_l)) - 0.09012",
     "vars": [
      [
       "R",
       "DoorArm_AFT | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_AFT | IK2 yaw",
       "[\"Hh\"]"
      ],
      [
       "phi_l",
       "DoorArm_AFT | IK3 shoulder",
       "[\"phi_l\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK4 elbow",
     "path": "[\"q3\"]",
     "index": null,
     "expr": "atan2(Hh - 2.513906*sin(phi_l), R - 2.513906*cos(phi_l)) - 0.09012 - phi_l + 2.156857",
     "vars": [
      [
       "R",
       "DoorArm_AFT | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_AFT | IK2 yaw",
       "[\"Hh\"]"
      ],
      [
       "phi_l",
       "DoorArm_AFT | IK3 shoulder",
       "[\"phi_l\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"M11\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*-0 + sin(q1)*0.742230952) + sin(phi_f)*0.670144141",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_AFT | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"M21\"]",
     "index": null,
     "expr": "-sin(q1)*-0 + cos(q1)*0.742230952",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"M31\"]",
     "index": null,
     "expr": "cos(phi_f)*0.670144141 - sin(phi_f)*(cos(q1)*-0 + sin(q1)*0.742230952)",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_AFT | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"M12\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*-1 + sin(q1)*0) + sin(phi_f)*0",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_AFT | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"M13\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*0 + sin(q1)*-0.670144141) + sin(phi_f)*0.742230952",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_AFT | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"kx\"]",
     "index": null,
     "expr": "-0.55264 + -0.663883*cos(q3) - -0.44603*sin(q3)",
     "vars": [
      [
       "q3",
       "DoorArm_AFT | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK5 wrist matrix",
     "path": "[\"kz\"]",
     "index": null,
     "expr": "1.5664 + -0.663883*sin(q3) + -0.44603*cos(q3)",
     "vars": [
      [
       "q3",
       "DoorArm_AFT | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK6 wrist angles",
     "path": "[\"q5\"]",
     "index": null,
     "expr": "-acos(clamp(M11, -1, 1))",
     "vars": [
      [
       "M11",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"M11\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK6 wrist angles",
     "path": "[\"q4\"]",
     "index": null,
     "expr": "atan2(-M21, M31)",
     "vars": [
      [
       "M21",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"M21\"]"
      ],
      [
       "M31",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"M31\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK6 wrist angles",
     "path": "[\"q6\"]",
     "index": null,
     "expr": "atan2(-M12, -M13)",
     "vars": [
      [
       "M12",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"M12\"]"
      ],
      [
       "M13",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"M13\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK6 wrist angles",
     "path": "[\"L\"]",
     "index": null,
     "expr": "sqrt(kx*kx + kz*kz)",
     "vars": [
      [
       "kx",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"kx\"]"
      ],
      [
       "kz",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"kz\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | IK6 wrist angles",
     "path": "[\"cyl\"]",
     "index": null,
     "expr": "atan2(kz, kx) - 2.397316952",
     "vars": [
      [
       "kx",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"kx\"]"
      ],
      [
       "kz",
       "DoorArm_AFT | IK5 wrist matrix",
       "[\"kz\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | carriage",
     "path": "location",
     "index": 0,
     "expr": "c",
     "vars": [
      [
       "c",
       "DoorArm_AFT | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | turret",
     "path": "rotation_euler",
     "index": 2,
     "expr": "q1",
     "vars": [
      [
       "q1",
       "DoorArm_AFT | IK2 yaw",
       "[\"q1\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | lower arm",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-q2",
     "vars": [
      [
       "q2",
       "DoorArm_AFT | IK3 shoulder",
       "[\"q2\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | upper arm",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-q3",
     "vars": [
      [
       "q3",
       "DoorArm_AFT | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | forearm",
     "path": "rotation_euler",
     "index": 0,
     "expr": "q4",
     "vars": [
      [
       "q4",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"q4\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | wrist head",
     "path": "rotation_euler",
     "index": 1,
     "expr": "q5",
     "vars": [
      [
       "q5",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"q5\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | flange",
     "path": "rotation_euler",
     "index": 0,
     "expr": "q6",
     "vars": [
      [
       "q6",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"q6\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | J3 cylinder",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-cyl",
     "vars": [
      [
       "cyl",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"cyl\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | J3 piston",
     "path": "location",
     "index": 0,
     "expr": "-1.216523 + -0.7355787636*(L - 1.653831051)",
     "vars": [
      [
       "L",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"L\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | J3 piston",
     "path": "location",
     "index": 2,
     "expr": "1.12037 + 0.6774392095*(L - 1.653831051)",
     "vars": [
      [
       "L",
       "DoorArm_AFT | IK6 wrist angles",
       "[\"L\"]"
      ]
     ]
    }
   ],
   "chain_link_drivers": [
    {
     "target": "DoorArm_AFT | chain solver",
     "path": "[\"M\"]",
     "index": null,
     "expr": "c + 0",
     "vars": [
      [
       "c",
       "DoorArm_AFT | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain solver",
     "path": "[\"a\"]",
     "index": null,
     "expr": "(4.6854 - -1*c + 1.046017763) / 2",
     "vars": [
      [
       "c",
       "DoorArm_AFT | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain solver",
     "path": "[\"bx\"]",
     "index": null,
     "expr": "c + 0 + -1*(4.6854 - -1*c + 1.046017763) / 2",
     "vars": [
      [
       "c",
       "DoorArm_AFT | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 00",
     "path": "location",
     "index": 0,
     "expr": "M + -0.06 if 0.06 < a else (bx + -0.24*sin(clamp((0.06 - a) / 0.24, 0, 3.141592654)) if 0.06 < a + 0.7539822369 else bx + 1*(0.06 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 00",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.06 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 00",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.06 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 01",
     "path": "location",
     "index": 0,
     "expr": "M + -0.18 if 0.18 < a else (bx + -0.24*sin(clamp((0.18 - a) / 0.24, 0, 3.141592654)) if 0.18 < a + 0.7539822369 else bx + 1*(0.18 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 01",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.18 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 01",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.18 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 02",
     "path": "location",
     "index": 0,
     "expr": "M + -0.3 if 0.3 < a else (bx + -0.24*sin(clamp((0.3 - a) / 0.24, 0, 3.141592654)) if 0.3 < a + 0.7539822369 else bx + 1*(0.3 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 02",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.3 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 02",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.3 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 03",
     "path": "location",
     "index": 0,
     "expr": "M + -0.42 if 0.42 < a else (bx + -0.24*sin(clamp((0.42 - a) / 0.24, 0, 3.141592654)) if 0.42 < a + 0.7539822369 else bx + 1*(0.42 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 03",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.42 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 03",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.42 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 04",
     "path": "location",
     "index": 0,
     "expr": "M + -0.54 if 0.54 < a else (bx + -0.24*sin(clamp((0.54 - a) / 0.24, 0, 3.141592654)) if 0.54 < a + 0.7539822369 else bx + 1*(0.54 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 04",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.54 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 04",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.54 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 05",
     "path": "location",
     "index": 0,
     "expr": "M + -0.66 if 0.66 < a else (bx + -0.24*sin(clamp((0.66 - a) / 0.24, 0, 3.141592654)) if 0.66 < a + 0.7539822369 else bx + 1*(0.66 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 05",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.66 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 05",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.66 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 06",
     "path": "location",
     "index": 0,
     "expr": "M + -0.78 if 0.78 < a else (bx + -0.24*sin(clamp((0.78 - a) / 0.24, 0, 3.141592654)) if 0.78 < a + 0.7539822369 else bx + 1*(0.78 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 06",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.78 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 06",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.78 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 07",
     "path": "location",
     "index": 0,
     "expr": "M + -0.9 if 0.9 < a else (bx + -0.24*sin(clamp((0.9 - a) / 0.24, 0, 3.141592654)) if 0.9 < a + 0.7539822369 else bx + 1*(0.9 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 07",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.9 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 07",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((0.9 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 08",
     "path": "location",
     "index": 0,
     "expr": "M + -1.02 if 1.02 < a else (bx + -0.24*sin(clamp((1.02 - a) / 0.24, 0, 3.141592654)) if 1.02 < a + 0.7539822369 else bx + 1*(1.02 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 08",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.02 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 08",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.02 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 09",
     "path": "location",
     "index": 0,
     "expr": "M + -1.14 if 1.14 < a else (bx + -0.24*sin(clamp((1.14 - a) / 0.24, 0, 3.141592654)) if 1.14 < a + 0.7539822369 else bx + 1*(1.14 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 09",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.14 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 09",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.14 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 10",
     "path": "location",
     "index": 0,
     "expr": "M + -1.26 if 1.26 < a else (bx + -0.24*sin(clamp((1.26 - a) / 0.24, 0, 3.141592654)) if 1.26 < a + 0.7539822369 else bx + 1*(1.26 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 10",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.26 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 10",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.26 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 11",
     "path": "location",
     "index": 0,
     "expr": "M + -1.38 if 1.38 < a else (bx + -0.24*sin(clamp((1.38 - a) / 0.24, 0, 3.141592654)) if 1.38 < a + 0.7539822369 else bx + 1*(1.38 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 11",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.38 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 11",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.38 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 12",
     "path": "location",
     "index": 0,
     "expr": "M + -1.5 if 1.5 < a else (bx + -0.24*sin(clamp((1.5 - a) / 0.24, 0, 3.141592654)) if 1.5 < a + 0.7539822369 else bx + 1*(1.5 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 12",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.5 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 12",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.5 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 13",
     "path": "location",
     "index": 0,
     "expr": "M + -1.62 if 1.62 < a else (bx + -0.24*sin(clamp((1.62 - a) / 0.24, 0, 3.141592654)) if 1.62 < a + 0.7539822369 else bx + 1*(1.62 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 13",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.62 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 13",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.62 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 14",
     "path": "location",
     "index": 0,
     "expr": "M + -1.74 if 1.74 < a else (bx + -0.24*sin(clamp((1.74 - a) / 0.24, 0, 3.141592654)) if 1.74 < a + 0.7539822369 else bx + 1*(1.74 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 14",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.74 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_AFT | chain link 14",
     "path": "rotation_euler",
     "index": 2,
     "expr": "3.141592654 + -1*clamp((1.74 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_AFT | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_AFT | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_AFT | chain solver",
       "[\"bx\"]"
      ]
     ]
    }
   ],
   "piston_rest_location": [
    -1.216523,
    0.0,
    1.12037
   ],
   "rod_axis": [
    -0.735579,
    0.0,
    0.677439
   ],
   "rod_L0": 1.653831,
   "cyl_beta0_rad": 2.397317
  },
  "FORE": {
   "solver_empties": [
    "DoorArm_FORE | IK1 target",
    "DoorArm_FORE | IK2 yaw",
    "DoorArm_FORE | IK3 shoulder",
    "DoorArm_FORE | IK4 elbow",
    "DoorArm_FORE | IK5 wrist matrix",
    "DoorArm_FORE | IK6 wrist angles",
    "DoorArm_FORE | chain solver"
   ],
   "joint_and_solver_drivers": [
    {
     "target": "DoorArm_FORE | IK1 target",
     "path": "[\"c\"]",
     "index": null,
     "expr": "8.4111 + 0.265346*dx",
     "vars": [
      [
       "dx",
       "Moonpool_Door_Fore",
       "location[0]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK1 target",
     "path": "[\"X\"]",
     "index": null,
     "expr": "0.734654*dx + -8.32532",
     "vars": [
      [
       "dx",
       "Moonpool_Door_Fore",
       "location[0]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK1 target",
     "path": "[\"Y\"]",
     "index": null,
     "expr": "-3.842859 - dy",
     "vars": [
      [
       "dy",
       "Moonpool_Door_Fore",
       "location[1]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK1 target",
     "path": "[\"H\"]",
     "index": null,
     "expr": "-4.495795 - dz",
     "vars": [
      [
       "dz",
       "Moonpool_Door_Fore",
       "location[2]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK2 yaw",
     "path": "[\"q1\"]",
     "index": null,
     "expr": "atan2(Y, X)",
     "vars": [
      [
       "X",
       "DoorArm_FORE | IK1 target",
       "[\"X\"]"
      ],
      [
       "Y",
       "DoorArm_FORE | IK1 target",
       "[\"Y\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK2 yaw",
     "path": "[\"R\"]",
     "index": null,
     "expr": "sqrt(X*X + Y*Y) + 0.5456",
     "vars": [
      [
       "X",
       "DoorArm_FORE | IK1 target",
       "[\"X\"]"
      ],
      [
       "Y",
       "DoorArm_FORE | IK1 target",
       "[\"Y\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK2 yaw",
     "path": "[\"Hh\"]",
     "index": null,
     "expr": "H - 0.8272",
     "vars": [
      [
       "H",
       "DoorArm_FORE | IK1 target",
       "[\"H\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK3 shoulder",
     "path": "[\"phi_l\"]",
     "index": null,
     "expr": "atan2(Hh, R) + acos(clamp((-11.19435933 + R*R + Hh*Hh) / (5.027812*sqrt(R*R + Hh*Hh)), -1, 1))",
     "vars": [
      [
       "R",
       "DoorArm_FORE | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_FORE | IK2 yaw",
       "[\"Hh\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK3 shoulder",
     "path": "[\"q2\"]",
     "index": null,
     "expr": "atan2(Hh, R) + acos(clamp((-11.19435933 + R*R + Hh*Hh) / (5.027812*sqrt(R*R + Hh*Hh)), -1, 1)) - 2.156857",
     "vars": [
      [
       "R",
       "DoorArm_FORE | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_FORE | IK2 yaw",
       "[\"Hh\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK4 elbow",
     "path": "[\"phi_f\"]",
     "index": null,
     "expr": "atan2(Hh - 2.513906*sin(phi_l), R - 2.513906*cos(phi_l)) - 0.09012",
     "vars": [
      [
       "R",
       "DoorArm_FORE | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_FORE | IK2 yaw",
       "[\"Hh\"]"
      ],
      [
       "phi_l",
       "DoorArm_FORE | IK3 shoulder",
       "[\"phi_l\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK4 elbow",
     "path": "[\"q3\"]",
     "index": null,
     "expr": "atan2(Hh - 2.513906*sin(phi_l), R - 2.513906*cos(phi_l)) - 0.09012 - phi_l + 2.156857",
     "vars": [
      [
       "R",
       "DoorArm_FORE | IK2 yaw",
       "[\"R\"]"
      ],
      [
       "Hh",
       "DoorArm_FORE | IK2 yaw",
       "[\"Hh\"]"
      ],
      [
       "phi_l",
       "DoorArm_FORE | IK3 shoulder",
       "[\"phi_l\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"M11\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*-0 + sin(q1)*0.742230952) + sin(phi_f)*0.670144141",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_FORE | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"M21\"]",
     "index": null,
     "expr": "-sin(q1)*-0 + cos(q1)*0.742230952",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"M31\"]",
     "index": null,
     "expr": "cos(phi_f)*0.670144141 - sin(phi_f)*(cos(q1)*-0 + sin(q1)*0.742230952)",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_FORE | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"M12\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*-1 + sin(q1)*0) + sin(phi_f)*0",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_FORE | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"M13\"]",
     "index": null,
     "expr": "cos(phi_f)*(cos(q1)*0 + sin(q1)*-0.670144141) + sin(phi_f)*0.742230952",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ],
      [
       "phi_f",
       "DoorArm_FORE | IK4 elbow",
       "[\"phi_f\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"kx\"]",
     "index": null,
     "expr": "-0.55264 + -0.663883*cos(q3) - -0.44603*sin(q3)",
     "vars": [
      [
       "q3",
       "DoorArm_FORE | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK5 wrist matrix",
     "path": "[\"kz\"]",
     "index": null,
     "expr": "1.5664 + -0.663883*sin(q3) + -0.44603*cos(q3)",
     "vars": [
      [
       "q3",
       "DoorArm_FORE | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK6 wrist angles",
     "path": "[\"q5\"]",
     "index": null,
     "expr": "-acos(clamp(M11, -1, 1))",
     "vars": [
      [
       "M11",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"M11\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK6 wrist angles",
     "path": "[\"q4\"]",
     "index": null,
     "expr": "atan2(-M21, M31)",
     "vars": [
      [
       "M21",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"M21\"]"
      ],
      [
       "M31",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"M31\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK6 wrist angles",
     "path": "[\"q6\"]",
     "index": null,
     "expr": "atan2(-M12, -M13)",
     "vars": [
      [
       "M12",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"M12\"]"
      ],
      [
       "M13",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"M13\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK6 wrist angles",
     "path": "[\"L\"]",
     "index": null,
     "expr": "sqrt(kx*kx + kz*kz)",
     "vars": [
      [
       "kx",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"kx\"]"
      ],
      [
       "kz",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"kz\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | IK6 wrist angles",
     "path": "[\"cyl\"]",
     "index": null,
     "expr": "atan2(kz, kx) - 2.397316952",
     "vars": [
      [
       "kx",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"kx\"]"
      ],
      [
       "kz",
       "DoorArm_FORE | IK5 wrist matrix",
       "[\"kz\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | carriage",
     "path": "location",
     "index": 0,
     "expr": "c",
     "vars": [
      [
       "c",
       "DoorArm_FORE | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | turret",
     "path": "rotation_euler",
     "index": 2,
     "expr": "q1",
     "vars": [
      [
       "q1",
       "DoorArm_FORE | IK2 yaw",
       "[\"q1\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | lower arm",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-q2",
     "vars": [
      [
       "q2",
       "DoorArm_FORE | IK3 shoulder",
       "[\"q2\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | upper arm",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-q3",
     "vars": [
      [
       "q3",
       "DoorArm_FORE | IK4 elbow",
       "[\"q3\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | forearm",
     "path": "rotation_euler",
     "index": 0,
     "expr": "q4",
     "vars": [
      [
       "q4",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"q4\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | wrist head",
     "path": "rotation_euler",
     "index": 1,
     "expr": "q5",
     "vars": [
      [
       "q5",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"q5\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | flange",
     "path": "rotation_euler",
     "index": 0,
     "expr": "q6",
     "vars": [
      [
       "q6",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"q6\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | J3 cylinder",
     "path": "rotation_euler",
     "index": 1,
     "expr": "-cyl",
     "vars": [
      [
       "cyl",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"cyl\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | J3 piston",
     "path": "location",
     "index": 0,
     "expr": "-1.216523 + -0.7355787636*(L - 1.653831051)",
     "vars": [
      [
       "L",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"L\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | J3 piston",
     "path": "location",
     "index": 2,
     "expr": "1.12037 + 0.6774392095*(L - 1.653831051)",
     "vars": [
      [
       "L",
       "DoorArm_FORE | IK6 wrist angles",
       "[\"L\"]"
      ]
     ]
    }
   ],
   "chain_link_drivers": [
    {
     "target": "DoorArm_FORE | chain solver",
     "path": "[\"M\"]",
     "index": null,
     "expr": "c + 0",
     "vars": [
      [
       "c",
       "DoorArm_FORE | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain solver",
     "path": "[\"a\"]",
     "index": null,
     "expr": "(10.7855 - 1*c + 1.046017763) / 2",
     "vars": [
      [
       "c",
       "DoorArm_FORE | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain solver",
     "path": "[\"bx\"]",
     "index": null,
     "expr": "c + 0 + 1*(10.7855 - 1*c + 1.046017763) / 2",
     "vars": [
      [
       "c",
       "DoorArm_FORE | IK1 target",
       "[\"c\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 00",
     "path": "location",
     "index": 0,
     "expr": "M + 0.06 if 0.06 < a else (bx + 0.24*sin(clamp((0.06 - a) / 0.24, 0, 3.141592654)) if 0.06 < a + 0.7539822369 else bx + -1*(0.06 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 00",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.06 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 00",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.06 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 01",
     "path": "location",
     "index": 0,
     "expr": "M + 0.18 if 0.18 < a else (bx + 0.24*sin(clamp((0.18 - a) / 0.24, 0, 3.141592654)) if 0.18 < a + 0.7539822369 else bx + -1*(0.18 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 01",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.18 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 01",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.18 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 02",
     "path": "location",
     "index": 0,
     "expr": "M + 0.3 if 0.3 < a else (bx + 0.24*sin(clamp((0.3 - a) / 0.24, 0, 3.141592654)) if 0.3 < a + 0.7539822369 else bx + -1*(0.3 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 02",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.3 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 02",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.3 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 03",
     "path": "location",
     "index": 0,
     "expr": "M + 0.42 if 0.42 < a else (bx + 0.24*sin(clamp((0.42 - a) / 0.24, 0, 3.141592654)) if 0.42 < a + 0.7539822369 else bx + -1*(0.42 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 03",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.42 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 03",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.42 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 04",
     "path": "location",
     "index": 0,
     "expr": "M + 0.54 if 0.54 < a else (bx + 0.24*sin(clamp((0.54 - a) / 0.24, 0, 3.141592654)) if 0.54 < a + 0.7539822369 else bx + -1*(0.54 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 04",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.54 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 04",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.54 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 05",
     "path": "location",
     "index": 0,
     "expr": "M + 0.66 if 0.66 < a else (bx + 0.24*sin(clamp((0.66 - a) / 0.24, 0, 3.141592654)) if 0.66 < a + 0.7539822369 else bx + -1*(0.66 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 05",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.66 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 05",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.66 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 06",
     "path": "location",
     "index": 0,
     "expr": "M + 0.78 if 0.78 < a else (bx + 0.24*sin(clamp((0.78 - a) / 0.24, 0, 3.141592654)) if 0.78 < a + 0.7539822369 else bx + -1*(0.78 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 06",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.78 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 06",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.78 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 07",
     "path": "location",
     "index": 0,
     "expr": "M + 0.9 if 0.9 < a else (bx + 0.24*sin(clamp((0.9 - a) / 0.24, 0, 3.141592654)) if 0.9 < a + 0.7539822369 else bx + -1*(0.9 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 07",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((0.9 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 07",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((0.9 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 08",
     "path": "location",
     "index": 0,
     "expr": "M + 1.02 if 1.02 < a else (bx + 0.24*sin(clamp((1.02 - a) / 0.24, 0, 3.141592654)) if 1.02 < a + 0.7539822369 else bx + -1*(1.02 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 08",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.02 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 08",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.02 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 09",
     "path": "location",
     "index": 0,
     "expr": "M + 1.14 if 1.14 < a else (bx + 0.24*sin(clamp((1.14 - a) / 0.24, 0, 3.141592654)) if 1.14 < a + 0.7539822369 else bx + -1*(1.14 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 09",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.14 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 09",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.14 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 10",
     "path": "location",
     "index": 0,
     "expr": "M + 1.26 if 1.26 < a else (bx + 0.24*sin(clamp((1.26 - a) / 0.24, 0, 3.141592654)) if 1.26 < a + 0.7539822369 else bx + -1*(1.26 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 10",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.26 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 10",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.26 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 11",
     "path": "location",
     "index": 0,
     "expr": "M + 1.38 if 1.38 < a else (bx + 0.24*sin(clamp((1.38 - a) / 0.24, 0, 3.141592654)) if 1.38 < a + 0.7539822369 else bx + -1*(1.38 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 11",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.38 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 11",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.38 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 12",
     "path": "location",
     "index": 0,
     "expr": "M + 1.5 if 1.5 < a else (bx + 0.24*sin(clamp((1.5 - a) / 0.24, 0, 3.141592654)) if 1.5 < a + 0.7539822369 else bx + -1*(1.5 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 12",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.5 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 12",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.5 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 13",
     "path": "location",
     "index": 0,
     "expr": "M + 1.62 if 1.62 < a else (bx + 0.24*sin(clamp((1.62 - a) / 0.24, 0, 3.141592654)) if 1.62 < a + 0.7539822369 else bx + -1*(1.62 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 13",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.62 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 13",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.62 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 14",
     "path": "location",
     "index": 0,
     "expr": "M + 1.74 if 1.74 < a else (bx + 0.24*sin(clamp((1.74 - a) / 0.24, 0, 3.141592654)) if 1.74 < a + 0.7539822369 else bx + -1*(1.74 - a - 0.7539822369))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 14",
     "path": "location",
     "index": 1,
     "expr": "-2.656 + -0.24*cos(clamp((1.74 - a) / 0.24, 0, 3.141592654))",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    },
    {
     "target": "DoorArm_FORE | chain link 14",
     "path": "rotation_euler",
     "index": 2,
     "expr": "0 + 1*clamp((1.74 - a) / 0.24, 0, 3.141592654)",
     "vars": [
      [
       "M",
       "DoorArm_FORE | chain solver",
       "[\"M\"]"
      ],
      [
       "a",
       "DoorArm_FORE | chain solver",
       "[\"a\"]"
      ],
      [
       "bx",
       "DoorArm_FORE | chain solver",
       "[\"bx\"]"
      ]
     ]
    }
   ],
   "piston_rest_location": [
    -1.216523,
    0.0,
    1.12037
   ],
   "rod_axis": [
    -0.735579,
    0.0,
    0.677439
   ],
   "rod_L0": 1.653831,
   "cyl_beta0_rad": 2.397317
  }
 },
 "verified": {
  "ik_check_AFT_A": {
   "frames": 120,
   "pose_err_mm": 0.001430511474609375,
   "pose_err_deg": 0.031278627784669236,
   "limits_ok": true,
   "carriage": [
    -8.1158,
    -3.0143
   ],
   "carriage_ok": true,
   "min_abs_q5_deg": 39.974586025325074,
   "elbow_inner_deg": [
    38.2302,
    91.732
   ],
   "wc_from_J1_axis_min": 0.736734285946799,
   "reach_ratio": [
    0.3616,
    0.7266
   ],
   "joints": {
    "J1": [
     32.734,
     82.365
    ],
    "J2": [
     -52.915,
     9.769
    ],
    "J3": [
     -24.391,
     29.111
    ],
    "J4": [
     -52.538,
     -10.834
    ],
    "J5": [
     -74.401,
     -39.975
    ],
    "J6": [
     11.544,
     52.316
    ]
   },
   "max_step_deg": {
    "J1": 3.785,
    "J2": 3.3,
    "J3": 4.059,
    "J4": 2.994,
    "J5": 2.414,
    "J6": 3.189
   },
   "rod": {
    "length": [
     0.716,
     1.2445
    ],
    "cyl_angle_deg": [
     -5.2453,
     1.2994
    ],
    "piston": [
     -0.084,
     0.4445
    ],
    "rear_in_lower_max": -0.121
   },
   "clearance_lowest": [
    [
     "Turret | lower block  x  kit | end stop inner",
     0.107,
     120
    ],
    [
     "Turret | side cables R  x  kit | end stop inner",
     0.118,
     1
    ],
    [
     "Turret | side cables L  x  kit | end stop wall",
     0.118,
     46
    ],
    [
     "Turret | lower block  x  kit | end stop wall",
     0.1206,
     72
    ],
    [
     "ToolA | fingers (closed envelope)  x  Moonpool_Door_Aft",
     0.1423,
     120
    ],
    [
     "Turret | side cables L  x  Pocket AFT | conformal closed end",
     0.1447,
     48
    ]
   ],
   "self_lowest": [
    [
     "ToolA | hub  x  Forearm | wrist lobe L",
     0.0088,
     78
    ],
    [
     "ToolA | hub  x  Forearm | wrist lobe R",
     0.0088,
     78
    ],
    [
     "ToolA | finger motor left  x  Forearm | wrist lobe L",
     0.0115,
     44
    ],
    [
     "ToolA | finger motor right  x  Forearm | wrist lobe R",
     0.0115,
     44
    ],
    [
     "ToolA | finger motor top  x  Forearm | wrist lobe R",
     0.0287,
     108
    ],
    [
     "ToolA | finger motor bottom  x  Forearm | wrist lobe L",
     0.0287,
     108
    ]
   ]
  },
  "ik_check_AFT_B": {
   "frames": 120,
   "pose_err_mm": 0.001430511474609375,
   "pose_err_deg": 0.031278627784669236,
   "limits_ok": true,
   "carriage": [
    -8.1158,
    -3.0143
   ],
   "carriage_ok": true,
   "min_abs_q5_deg": 39.974586025325074,
   "elbow_inner_deg": [
    38.2302,
    91.732
   ],
   "wc_from_J1_axis_min": 0.736734285946799,
   "reach_ratio": [
    0.3616,
    0.7266
   ],
   "joints": {
    "J1": [
     32.734,
     82.365
    ],
    "J2": [
     -52.915,
     9.769
    ],
    "J3": [
     -24.391,
     29.111
    ],
    "J4": [
     -52.538,
     -10.834
    ],
    "J5": [
     -74.401,
     -39.975
    ],
    "J6": [
     11.544,
     52.316
    ]
   },
   "max_step_deg": {
    "J1": 3.785,
    "J2": 3.3,
    "J3": 4.059,
    "J4": 2.994,
    "J5": 2.414,
    "J6": 3.189
   },
   "rod": {
    "length": [
     0.716,
     1.2445
    ],
    "cyl_angle_deg": [
     -5.2453,
     1.2994
    ],
    "piston": [
     -0.084,
     0.4445
    ],
    "rear_in_lower_max": -0.121
   },
   "clearance_lowest": [
    [
     "ToolB | plate  x  Moonpool_Door_Aft",
     0.017,
     1
    ],
    [
     "ToolB | neck  x  Moonpool_Door_Aft",
     0.0643,
     120
    ],
    [
     "Turret | lower block  x  kit | end stop inner",
     0.107,
     120
    ],
    [
     "Turret | side cables R  x  kit | end stop inner",
     0.118,
     1
    ],
    [
     "Turret | side cables L  x  kit | end stop wall",
     0.118,
     46
    ],
    [
     "Turret | lower block  x  kit | end stop wall",
     0.1206,
     72
    ]
   ],
   "self_lowest": [
    [
     "ToolB | neck  x  Forearm | wrist lobe L",
     0.011,
     78
    ],
    [
     "ToolB | neck  x  Forearm | wrist lobe R",
     0.011,
     94
    ],
    [
     "UpperArm | truss  x  LowerArm | beam core",
     0.0806,
     120
    ],
    [
     "UpperArm | knob  x  LowerArm | beam sides R",
     0.0855,
     1
    ],
    [
     "UpperArm | gland+cables  x  LowerArm | yoke L",
     0.088,
     120
    ],
    [
     "LowerArm | knee caps  x  Turret | ear L",
     0.0909,
     3
    ]
   ]
  },
  "ik_check_FORE_A": {
   "frames": 120,
   "pose_err_mm": 0.0020230487285229134,
   "pose_err_deg": 0.027976455118293345,
   "limits_ok": true,
   "carriage": [
    9.1143,
    14.2158
   ],
   "carriage_ok": true,
   "min_abs_q5_deg": 39.9745502519982,
   "elbow_inner_deg": [
    38.2302,
    91.732
   ],
   "wc_from_J1_axis_min": 0.7367340192795938,
   "reach_ratio": [
    0.3616,
    0.7266
   ],
   "joints": {
    "J1": [
     97.635,
     147.266
    ],
    "J2": [
     -52.915,
     9.769
    ],
    "J3": [
     -24.391,
     29.111
    ],
    "J4": [
     10.834,
     52.538
    ],
    "J5": [
     -74.401,
     -39.975
    ],
    "J6": [
     -52.316,
     -11.544
    ]
   },
   "max_step_deg": {
    "J1": 3.785,
    "J2": 3.3,
    "J3": 4.059,
    "J4": 2.994,
    "J5": 2.414,
    "J6": 3.189
   },
   "rod": {
    "length": [
     0.716,
     1.2445
    ],
    "cyl_angle_deg": [
     -5.2453,
     1.2994
    ],
    "piston": [
     -0.084,
     0.4445
    ],
    "rear_in_lower_max": -0.121
   },
   "clearance_lowest": [
    [
     "Turret | lower block  x  kit | end stop inner",
     0.107,
     120
    ],
    [
     "Turret | side cables L  x  kit | end stop inner",
     0.118,
     1
    ],
    [
     "Turret | side cables R  x  kit | end stop wall",
     0.118,
     46
    ],
    [
     "Turret | lower block  x  kit | end stop wall",
     0.1206,
     72
    ],
    [
     "ToolA | fingers (closed envelope)  x  Moonpool_Door_Fore",
     0.1441,
     120
    ],
    [
     "Turret | side cables R  x  Pocket FORE | conformal closed end",
     0.1447,
     48
    ]
   ],
   "self_lowest": [
    [
     "ToolA | hub  x  Forearm | wrist lobe L",
     0.0088,
     85
    ],
    [
     "ToolA | hub  x  Forearm | wrist lobe R",
     0.0088,
     85
    ],
    [
     "ToolA | finger motor left  x  Forearm | wrist lobe L",
     0.0115,
     44
    ],
    [
     "ToolA | finger motor right  x  Forearm | wrist lobe R",
     0.0115,
     44
    ],
    [
     "ToolA | finger motor top  x  Forearm | wrist lobe L",
     0.0287,
     108
    ],
    [
     "ToolA | finger motor bottom  x  Forearm | wrist lobe R",
     0.0287,
     108
    ]
   ]
  },
  "ik_check_FORE_B": {
   "frames": 120,
   "pose_err_mm": 0.0020230487285229134,
   "pose_err_deg": 0.027976455118293345,
   "limits_ok": true,
   "carriage": [
    9.1143,
    14.2158
   ],
   "carriage_ok": true,
   "min_abs_q5_deg": 39.9745502519982,
   "elbow_inner_deg": [
    38.2302,
    91.732
   ],
   "wc_from_J1_axis_min": 0.7367340192795938,
   "reach_ratio": [
    0.3616,
    0.7266
   ],
   "joints": {
    "J1": [
     97.635,
     147.266
    ],
    "J2": [
     -52.915,
     9.769
    ],
    "J3": [
     -24.391,
     29.111
    ],
    "J4": [
     10.834,
     52.538
    ],
    "J5": [
     -74.401,
     -39.975
    ],
    "J6": [
     -52.316,
     -11.544
    ]
   },
   "max_step_deg": {
    "J1": 3.785,
    "J2": 3.3,
    "J3": 4.059,
    "J4": 2.994,
    "J5": 2.414,
    "J6": 3.189
   },
   "rod": {
    "length": [
     0.716,
     1.2445
    ],
    "cyl_angle_deg": [
     -5.2453,
     1.2994
    ],
    "piston": [
     -0.084,
     0.4445
    ],
    "rear_in_lower_max": -0.121
   },
   "clearance_lowest": [
    [
     "ToolB | plate  x  Moonpool_Door_Fore",
     0.0194,
     120
    ],
    [
     "ToolB | neck  x  Moonpool_Door_Fore",
     0.066,
     1
    ],
    [
     "Turret | lower block  x  kit | end stop inner",
     0.107,
     120
    ],
    [
     "Turret | side cables L  x  kit | end stop inner",
     0.118,
     1
    ],
    [
     "Turret | side cables R  x  kit | end stop wall",
     0.118,
     46
    ],
    [
     "Turret | lower block  x  kit | end stop wall",
     0.1206,
     72
    ]
   ],
   "self_lowest": [
    [
     "ToolB | neck  x  Forearm | wrist lobe L",
     0.011,
     78
    ],
    [
     "ToolB | neck  x  Forearm | wrist lobe R",
     0.011,
     78
    ],
    [
     "UpperArm | truss  x  LowerArm | beam core",
     0.0806,
     120
    ],
    [
     "UpperArm | knob  x  LowerArm | beam sides R",
     0.0855,
     1
    ],
    [
     "UpperArm | gland+cables  x  LowerArm | yoke L",
     0.088,
     120
    ],
    [
     "LowerArm | knee caps  x  Turret | ear L",
     0.0909,
     3
    ]
   ]
  },
  "driver_proto_AFT": {
   "door": "AFT",
   "drivers": 172,
   "not_simple_or_invalid": [],
   "frames": 120,
   "tip_err_mm": 0.05463,
   "axis_err_deg": 0.0,
   "piston_eye_err_mm": 0.00128,
   "q_vs_python_deg": 0.00313,
   "chain": {
    "pitch_err_mm": 0.779,
    "first_link_from_carriage_mm": 0.0,
    "outside_tray_mm": 0.0,
    "loop_x": [
     -8.4003,
     -3.0518
    ]
   },
   "version_switch": {
    "0": {
     "A_hidden": false,
     "B_hidden": true,
     "A_hide_render": false,
     "B_hide_render": true
    },
    "1": {
     "A_hidden": true,
     "B_hidden": false,
     "A_hide_render": true,
     "B_hide_render": false
    }
   }
  },
  "driver_proto_FORE": {
   "door": "FORE",
   "drivers": 172,
   "not_simple_or_invalid": [],
   "frames": 120,
   "tip_err_mm": 0.05483,
   "axis_err_deg": 0.0,
   "piston_eye_err_mm": 0.00197,
   "q_vs_python_deg": 0.00313,
   "chain": {
    "pitch_err_mm": 0.78,
    "first_link_from_carriage_mm": 0.0,
    "outside_tray_mm": 0.0,
    "loop_x": [
     9.1518,
     14.5002
    ]
   },
   "version_switch": {
    "0": {
     "A_hidden": false,
     "B_hidden": true,
     "A_hide_render": false,
     "B_hide_render": true
    },
    "1": {
     "A_hidden": true,
     "B_hidden": false,
     "A_hide_render": true,
     "B_hide_render": false
    }
   }
  }
 },
 "scale_up": {
  "date": "2026-10-18",
  "S": 1.6,
  "rail_y": -3.8,
  "anchor_z": -3.755,
  "upper_dx_build": 0.2312,
  "k_fore": 1.2,
  "knob": [
   0.84,
   -4.5
  ],
  "build_units": {
   "J2": [
    -0.341,
    0.0,
    0.517
   ],
   "J3": [
    -1.21,
    0.0,
    1.826
   ],
   "J4": [
    0.1542,
    0.0,
    2.0614
   ],
   "WC": [
    1.395,
    0.0,
    2.0614
   ],
   "TRUNNION": [
    -0.8646,
    0.0,
    0.847
   ],
   "KNOB": [
    -1.624927,
    0.0,
    1.547231
   ]
  },
  "bands": {
   "upper arm": {
    "default": [
     0.817,
     0.839
    ]
   },
   "forearm": {
    "default": [
     0.598,
     0.598
    ],
    "F07": [
     0.523,
     0.535
    ],
    "F02": [
     0.54,
     0.58
    ],
    "F08": [
     0.65,
     0.71
    ],
    "F08f": [
     0.7,
     0.7
    ]
   }
  },
  "lengths_m": {
   "lower_arm": 2.513906,
   "upper_arm": 2.214977,
   "forearm": 1.98528,
   "j3_to_wc": 4.184983
  },
  "length_changes_pct": {
   "upper_arm": 19.63,
   "forearm": 20.0,
   "lower_arm": 0.0,
   "j3_to_wc": 20.0
  },
  "plate_B": 1.2,
  "pad_B": 1.3,
  "pad_top_B": 0.0394,
  "d_t": {
   "A": 1.008,
   "B": 0.529
  },
  "c_closed_AFT": -3.8709,
  "c_open_AFT": -5.5,
  "rail_end_AFT": -3.12,
  "j3_limits": [
   -28.75,
   66.0
  ],
  "j1_limits": [
   -185.0,
   185.0
  ],
  "j2_limits": [
   -72.0,
   43.0
  ],
  "j5_limits": [
   -90.5,
   120.0
  ],
  "tool_roll_A_deg": {
   "AFT": 10.0,
   "FORE": -10.0
  },
  "proof": {
   "file": "build/fit3d_proof.json",
   "design": {
    "S": 1.6,
    "rail_y": -3.8,
    "stroke": [
     -30.25,
     65.5
    ],
    "k_upper": 1.2,
    "k_fore": 1.2,
    "knob": [
     0.86,
     -2.0
    ],
    "j1": [
     -185.0,
     185.0
    ]
   },
   "c_closed": -3.871,
   "c_open": -5.5,
   "note": "proved with the upper arm's J4 at 1.2 x (J4 - J3); built with J4 0.2312 along x (the same J3 -> wrist centre length, its angle 1.04 deg lower: q3 1.04 deg higher everywhere, still >= 6.2 deg inside the limits)"
  },
  "why": "DESIGN.md, addendum 2026-10-18 scale-up and door-centre attach"
 }
}