"""Door robot arm: parts list, clearance proxies, materials, markings, triangle budget (data only). Coordinates: the upright arm frame A at rest (the ref1 pose): X forward (toward the tool), Y the arm's left, Z up, origin = turntable face centre (carriage top in the reference; carriage underside in the ship, where the arm hangs). Sizes and positions are given in ref1 PIXELS (px) where they were measured on the pictures; design_make_json.py turns them into metres (x 0.0022) and into each link's local frame. Ref1 image -> A: X = 1000 - x_img, Z = 1550 - y_img. Lateral (Y) sizes come from ref7 (a BACK view; ref7 px / 2.0 = ref1 px at the turret's depth) and ref2/3/6. 'both' = the part is on both sides (mirror in Y). Parts that are not seen in the pictures but are needed to make the mechanism work (bearings, pins, running gear, hoses) are marked 'added'. shape words: box (x,y,z), rbox (rounded box: x,y,z,radius), cyl (dia, length; axis given), ring (outer dia, inner dia, thickness; axis), disc, tube (dia; path points), cone (dia0, dia1, length), plate2d (outline in the link's X-Z plane, extruded in Y), knurl (dia, length, ribs), U (bent-tube handle: width, height, tube dia). mat: paint_white, gunmetal, steel, rubber, orange (paint/decal), glass_dark (lens), lamp (small indicator glow). """ # ---- the references, for the 'refs' column ---------------------------------------------------------------------- REFS = { "r1": "ref1_side_left (whole arm, left side)", "r2": "ref2_three_quarter_left", "r3": "ref3_three_quarter_right", "r4": "ref4_base_wire_closeup (base, left side, clay+wire)", "r5": "ref5_lower_arm_wire_closeup (left side)", "r6": "ref6_wrist_redline (forearm+wrist from front-left-below; red sketch of version B)", "r7": "ref7_front_base_wire (in fact a BACK view of the base, turret turned 90 deg to the rail)", } def part(pid, name, shape, size, at, refs, mat, note="", both=False, axis=None, units="px", frame="A"): d = dict(id=pid, name=name, shape=shape, size=size, at=at, refs=refs, mat=mat, both=both, units=units, frame=frame) if axis: d["axis"] = axis if note: d["note"] = note return d PARTS = {} # ================================================================================================================ # CARRIAGE (moves along the rail). The reference block, turned over: in the ship the turntable side faces DOWN. # A-frame Z from 0 (turntable face) to -185 px (the side that faces the rail / the deck). Square in plan: 390 x 390 px. # ================================================================================================================ CF = ("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)") PARTS["Carriage"] = [ part("C01", "turntable plate (ref: top plate)", "rbox", [390, 390, 20, 25], [0, 0, -10], "r1 r4 r7", "gunmetal", "rounded corners R25, 3 px chamfer; a raised rounded pad 330x330x4 px in its middle under the slewing ring (r7)"), part("C02", "stacked plates x5", "rbox", [386, 386, 13, 24], [0, 0, -27], "r1 r4 r7", "gunmetal", "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)"), part("C03", "strap band", "rbox", [392, 392, 40, 22], [0, 0, -115], "r1 r4 r7", "gunmetal", "Z -95..-135; on both rail-side faces (+-Y, the cheeks' outer faces in the ship): the dot panels and the strap+buckle"), part("C03a", "dot panels (2 per face, 4 total)", "box", [70, 3, 28], [150, 196, -115], "r4 r7", "gunmetal", "a raised panel at each end of the band; 2 rows x 3 round dimples, dimple dia 7 px, pitch 13 px", both=True), part("C03b", "strap (flat)", "box", [60, 4, 14], [95, 197, -112], "r4 r7", "gunmetal", "between dot panel and buckle", both=True), part("C03c", "buckle chain (5 links per face)", "links", [200, 6, 18], [0, 199, -116], "r4 r7", "steel", "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)", both=True), part("C04", "lower block (ref)", "rbox", [388, 388, 30, 24], [0, 0, -150], "r1 r4 r7", "gunmetal", "Z -135..-165 with one groove line 4 px under its top edge"), part("C05", "skirt with chamfered notch", "rbox", [390, 390, 20, 25], [0, 0, -175], "r4 r7", "gunmetal", "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"), part("C06", "rail channel (cut through C02..C05)", "channel", [0.858, 0.578, 0.285], [0.0, 0.0, -0.2645], "added", "gunmetal", "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", units="m", frame=CF), part("C07", "load wheels x4", "cyl", [0.10, 0.04], [[0.30, -0.254, -0.252], [-0.30, -0.254, -0.252]], "added", "steel", "in the cheeks, axles along Y; they roll on the TOP of the running flanges K01 (ship z -3.93 centre)", both=True, units="m", frame=CF), part("C08", "counter-rollers x4", "cyl", [0.06, 0.035], [[0.30, -0.254, -0.142], [-0.30, -0.254, -0.142]], "added", "steel", "under the running flanges (ship z -4.04 centre); hold the arm's tipping moment", both=True, units="m", frame=CF), part("C09", "side guide rollers x4", "cyl", [0.06, 0.03], [[0.20, -0.309, -0.187], [-0.20, -0.309, -0.187]], "added", "steel", "vertical axles; run on the flanges' outer edges (lateral load)", both=True, units="m", frame=CF), part("C10", "drive motor + gearbox + pinion", "cyl", [0.12, 0.30], [0.0, 0.0, -0.084], "added", "gunmetal", "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", units="m", frame=CF), part("C11", "energy-chain bracket", "box", [0.10, 0.14, 0.05], [0.0, -0.497, -0.387], "added", "steel", "on the inboard cheek top (ship +y); carries the chain's moving end at ship y -5.23", units="m", frame=CF), part("C12", "buffer strike pads x2", "box", [0.02, 0.20, 0.08], [[0.439, 0.0, -0.112], [-0.439, 0.0, -0.112]], "added", "steel", "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", units="m", frame=CF), part("C13", "slewing ring, fixed race", "ring", [270, 240, 8], [0, 0, 4], "r1 r4", "gunmetal", "on C01's pad; 24 bolt heads dia 8 px on a 255 px circle"), ] # ================================================================================================================ # TURRET (J1). Origin turntable face centre. # ================================================================================================================ PARTS["Turret"] = [ part("T01", "slewing ring, turning race", "ring", [262, 0, 22], [0, 0, 15], "r1 r4 r7", "gunmetal", "three stacked rings with 2 V-grooves (r4); hollow centre for the cables (hidden)"), part("T02", "lower block (skirt)", "rbox", [350, 330, 85, 20], [-15, 0, 67], "r1 r2 r3 r4 r7", "paint_white", "X -190..160, Z 25..110; corners R20; seams: one horizontal groove 30 px above its foot"), part("T02a", "back screw strips", "box", [3, 18, 80], [-192, 52, 67], "r7", "paint_white", "two vertical strips on the back face (Y +-52) with 3 round screw heads each (dia 10 px, steel)", both=True), part("T02b", "back latch slot", "box", [3, 40, 85], [-192, 0, 67], "r7", "gunmetal", "a vertical slot in the back face with a bent U-tab (30x60 px, bar 8 px) hooked over its top (r7 centre)"), part("T02c", "side recess", "box", [60, 4, 15], [-30, 166, 45], "r1 r2", "gunmetal", "a horizontal recessed slot (r1 x_img 1030)", both=True), part("T02d", "rear corner glands", "cyl", [30, 22], [-150, 166, 30], "r1 r7", "rubber", "where the side cable pairs end (r1 x_img 1135, y 1530)", both=True, axis="Y"), part("T02e", "front corner screws", "disc", [10, 3], [[160, 120, 60], [160, 120, 85], [160, 120, 100]], "r4", "steel", "three small screw heads up each front corner of the lower block (r4)", both=True, axis="X"), part("T02f", "side slot panel", "rbox", [70, 4, 22, 8], [-80, 166, 50], "r4", "paint_white", "a recessed rounded slot panel low on each side of the lower block (r4, right of the cable)", both=True), part("T03", "front housing", "plate2d", [[250, 110], [250, 290], [200, 340], [60, 350], [-40, 340], [-40, 110]], [0, 0, 0], "r1 r2 r4", "paint_white", "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"), part("T03a", "front housing top plug", "cyl", [25, 12], [150, 0, 355], "r4", "paint_white", "small round plug on the lid", axis="Z"), part("T04", "J2 ears", "rbox", [260, 85, 260, 40], [-155, 172, 235], "r1 r3 r7", "paint_white", "the two side housings that hold the shoulder; inner faces at Y +-130 (the drum turns between them)", both=True), part("T04a", "J2 motor caps", "stack", [[165, 18, "paint_white"], [120, 10, "gunmetal"], [76, 3, "orange"], [70, 14, "gunmetal"], [40, 10, "steel"]], [-155, 215, 235], "r1 r2 r3 r4 r7", "mixed", "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)", both=True, axis="Y"), part("T05", "connector boss", "stack", [[52, 10, "paint_white"], [30, 8, "gunmetal"]], [185, 142, 200], "r1 r2 r4", "mixed", "double ring boss on the front housing side (r1 x_img 815; r4 left of the gland)", axis="Y"), part("T06", "cable port glands (side pairs start)", "stack", [[48, 12, "paint_white"], [32, 20, "rubber"]], [85, 142, 200], "r1 r2 r3 r4", "mixed", "white collar + rubber sleeve; the cable pair leaves here (r1 x_img 915, y 1350)", both=True, axis="Y"), part("T07", "orange hatch marking", "decal", [70, 20], [70, 141, 330], "r1 r2 r3", "orange", "five 45-deg stripes in a thin frame + a thin line above it, on both sides of the front housing", both=True), part("T07a", "warning stripes, lower block", "decal", [30, 35], [-170, 166, 90], "r1", "orange", "small striped square (r1 x_img 1120, y 1460)"), part("T08", "bundle gland (front top)", "stack", [[62, 30, "paint_white"], [48, 12, "rubber"]], [205, 60, 318], "r1 r2 r4", "mixed", "a round collar with a lip on the front housing top (r4); the multi-cable bundle leaves it forward", axis="X"), part("T09", "cable bundle (7 cables)", "tube", [10], [[205, 60, 330], [290, 66, 330], [340, 70, 260], [345, 70, 200]], "r1 r2 r4", "rubber", "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"), part("T10", "bundle clamp block", "rbox", [70, 60, 50, 8], [330, 70, 185], "r1 r2 r4", "paint_white", "two-part clamp with one bolt head (dia 15, steel) and a slot; orange tick on its face (r2)"), part("T11", "belt-drive arm", "rbox", [130, 70, 80, 10], [310, 35, 110], "r1 r2 r4", "paint_white", "white bracket from the front housing forward to the pulley; 3 small bolt heads (r4)"), part("T12", "drive pulley (J1 motor)", "stack", [[78, 40, "paint_white"], [60, 6, "gunmetal"], [40, 10, "gunmetal"], [18, 12, "steel"]], [305, 35, 110], "r1 r2 r3 r4", "mixed", "ringed white pulley (5 grooves) with a dark core and shaft (r1 x_img 695, y 1440)", axis="Y"), part("T12b", "drive motor end cap", "stack", [[58, 12, "paint_white"], [44, 4, "gunmetal"], [30, 6, "glass_dark"]], [250, 75, 110], "r2 r4", "mixed", "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)", axis="Y"), part("T13", "toothed belt", "belt", [30, 8], [[305, 35, 110], [150, 35, 70]], "r1 r4", "rubber", "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"), part("T14", "idler pulley", "stack", [[30, 12, "gunmetal"], [12, 16, "steel"]], [255, 35, 50], "r1 r4", "mixed", "small dark pulley with a bolt (r1 x_img 745)", axis="Y"), part("T15", "side cable pairs (2 x 2 cables)", "tube", [12], [[85, 150, 200], [60, 300, 175], [-40, 330, 110], [-120, 250, 40], [-150, 175, 30]], "r1 r2 r3 r4 r7", "rubber", "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", both=True), part("T16", "dot vent", "box", [40, 3, 25], [120, 142, 115], "r4", "gunmetal", "dark panel with 6x4 round holes dia 4 px (r4, under the housing)"), part("T17", "recessed vent slot", "box", [15, 4, 40], [210, 142, 160], "r4", "gunmetal", "a vertical slot with one sloped edge (r4)", both=True), ] # ================================================================================================================ # LOWER ARM (J2 .. J3). Origin J2 = (-155, 0, 235). Knee (slotted caps) at (-393, 0, 385). J3 at (-550, 0, 830). # ================================================================================================================ PARTS["LowerArm"] = [ part("L01", "drum (J2 barrel)", "cyl", [270, 210], [-155, 0, 235], "r1 r2 r3 r7", "gunmetal", "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)", axis="Y"), part("L02", "root shells", "plate2d", [[-155 + 165, 235], [-155, 235 + 165], [-300, 360], [-330, 235], [-155, 235 - 165]], [0, 0, 0], "r1 r3 r5", "paint_white", "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", both=True), part("L03", "beam J2 -> knee -> crotch", "plate2d", [[-60, 330], [-250, 560], [-330, 640], [-520, 520], [-470, 330], [-330, 230]], [0, 0, 0], "r1 r2 r3 r5", "paint_white", "box section, Y +-205 outer; side outline in X-Z px; seams and raised panels on the sides (r5)"), part("L04", "back channel", "channel", [110, 45], [[-280, 0, 170], [-470, 0, 450], [-560, 0, 740]], "r3 r5 r7", "gunmetal", "recessed channel down the back face (Y +-55, 45 px deep) from the drum to the elbow; the J3 cylinder lies in it"), part("L05", "rungs", "box", [10, 110, 30], [[-280, 0, 170], [-560, 0, 740]], "r1 r2 r5 r7", "gunmetal", "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"), part("L06", "knee bosses", "ring", [250, 200, 20], [-393, 205, 385], "r1 r2 r3 r5", "paint_white", "raised white ring round each slotted cap", both=True, axis="Y"), part("L07", "knee caps (radial slotted)", "stack", [[190, 10, "gunmetal"], [120, 6, "gunmetal"], [90, 6, "gunmetal"], [60, 6, "gunmetal"], [55, 2, "orange"], [25, 8, "steel"]], [-393, 215, 385], "r1 r2 r3 r5", "mixed", "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", both=True, axis="Y"), part("L18", "front dark core + inner cap", "plate2d", [[-330, 500], [-430, 700], [-470, 780], [-400, 760], [-300, 560]], [0, 0, 0], "r1 r5", "gunmetal", "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)"), part("L08", "hexagon outline (orange)", "decal", [50, 50], [-235, 206, 385 - 15], "r1 r2", "orange", "3 px line, left side only (r1 x_img 1235, y 1165)"), part("L09", "triangle outline (orange)", "decal", [18, 18], [-360, 206, 510], "r1 r5", "orange", "small, left side (r1 x_img 1360, y 1040)"), part("L10", "light slot", "box", [18, 6, 140], [-525, 206, 680], "r1 r5", "lamp", "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"), part("L11", "round button", "stack", [[30, 6, "gunmetal"], [22, 8, "paint_white"]], [-485, 206, 535], "r1 r5", "mixed", "domed button, left side (r1 x_img 1485, y 1015)", axis="Y"), part("L12", "stepped side panels", "plate2d", [[-400, 520], [-520, 640], [-560, 780], [-470, 700]], [0, 0, 0], "r1 r5", "paint_white", "raised panels 6 px proud with 45 deg steps and the notch block near the knee top (r5)", both=True), part("L13", "handles (bent tube)", "U", [70, 150, 12], [-470, 185, 380], "r1 r3 r5 r7", "paint_white", "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", both=True), part("L14", "elbow yoke cheeks", "plate2d", [[-470, 700], [-600, 760], [-640, 830], [-550, 915], [-470, 870]], [0, 0, 0], "r1 r2 r5", "paint_white", "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", both=True), part("L15", "elbow caps", "stack", [[140, 12, "paint_white"], [110, 6, "gunmetal"], [100, 12, "gunmetal"], [60, 4, "steel"]], [-550, 205, 830], "r1 r2 r3 r5", "mixed", "black cap with a straight slot 60x12 px across ('minus' screw head) and two small tick notches at 12 and 6 o'clock", both=True, axis="Y"), part("L16", "inner channel guide + hose loop", "box", [40, 60, 60], [-560, 0, 760], "r3", "gunmetal", "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)"), part("L17", "cable gland, back of elbow", "stack", [[34, 10, "paint_white"], [24, 14, "rubber"]], [-640, 60, 800], "r1 r3", "mixed", "twin gland where the two upper-arm cables U09 come in (r1 x_img 1620-1640, y 690-710)", axis="X"), ] # ================================================================================================================ # J3 CYLINDER (the 'rod'). Trunnion at the knee (-393, 0, 385); rod eye on the truss knob (-762, 0, 662) at rest. # ================================================================================================================ PARTS["Cylinder"] = [ part("R01", "barrel", "cyl", [0.075, 0.80], [0.10, 0.0, 0.0], "r1 r3 r5", "gunmetal", "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", 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)"), part("R02", "trunnion block + pin", "box", [0.10, 0.11, 0.10], [0.0, 0.0, 0.0], "added", "gunmetal", "pin dia 0.06 across the lower arm, hidden by the knee caps", 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)"), part("R03", "gland collar", "cyl", [0.085, 0.04], [0.48, 0.0, 0.0], "r1 r3 r5", "steel", "bright ring where the rod leaves the barrel", 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)"), part("R04", "hoses x2", "tube", [0.02], [], "added", "rubber", "from the barrel's two ports into the channel wall; hooked at both ends", units="m"), ] PARTS["Piston"] = [ part("R05", "piston rod", "cyl", [0.05, 0.80], [-0.40, 0.0, 0.0], "r1 r3 r5", "steel", "chrome rod from its eye 0.80 m back to the piston", 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)"), part("R06", "rod eye", "ring", [0.075, 0.05, 0.024], [0.0, 0.0, 0.0], "r1 r3", "steel", "eye on the knob pin between the two truss plates", units="m", frame="Piston object: origin at the rod eye centre"), ] # ================================================================================================================ # UPPER ARM (J3 .. J4). Origin J3 = (-550, 0, 830). Big cap at (-262, 0, 985). Front block x_img 1045..1140. # ================================================================================================================ PARTS["UpperArm"] = [ part("U01", "elbow hub", "cyl", [150, 230], [-550, 0, 830], "r1 r5", "gunmetal", "between the yoke cheeks (Y +-115)", axis="Y"), part("U02", "housing (the hump)", "plate2d", [[-640, 800], [-600, 1010], [-470, 1080], [-330, 1095], [-160, 1095], [-160, 890], [-300, 870], [-470, 800]], [0, 0, 0], "r1 r2 r3 r5", "paint_white", "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"), part("U03", "big caps", "stack", [[165, 14, "paint_white"], [104, 4, "orange"], [100, 10, "glass_dark"], [72, 6, "steel"]], [-262, 112, 985], "r1 r2 r3", "mixed", "white bezel, thin ORANGE ring, a dark glossy recessed disc and a slotted screw head (bar 70x14 px) inside", both=True, axis="Y"), part("U04", "ribbed vents", "box", [100, 6, 55], [-470, 111, 925], "r1 r2 r3 r5", "paint_white", "raised panel with 8 slots 10x45 px, pitch 12 px, inclined 30 deg along the top edge", both=True), part("U05", "indicator lights", "stack", [[33, 4, "gunmetal"], [25, 6, "lamp"]], [-355, 111, 920], "r1 r3", "mixed", "white lens in a dark ring; faint glow", both=True, axis="Y"), part("U06", "small dot", "disc", [8, 2], [-415, 111, 940], "r1", "gunmetal", "", axis="Y"), part("U07", "orange ticks", "decal", [14, 14], [-525, 111, 1010], "r1 r2", "orange", "two small abstract chevrons (the reference has glyphs; no text here)"), part("U08", "twin cable gland", "rbox", [50, 40, 30, 6], [-470, 50, 1020], "r1 r2 r3", "paint_white", "on the top behind the vents; two rubber glands dia 16 px face backward"), part("U09", "two cables over the elbow", "tube", [12], [[-470, 50, 1020], [-640, 55, 1100], [-810, 60, 990], [-760, 62, 860], [-640, 60, 800]], "r1 r2 r3 r5", "rubber", "cross J3: hooked at both ends, middle points blended 50/50 (see the rig); 18 px apart"), part("U10", "truss plates (pair)", "plate2d", [[-560, 860], [-500, 760], [-740, 630], [-790, 680], [-610, 860]], [0, 0, 0], "r1 r2 r3 r5", "paint_white", "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"), part("U11", "knob pin + caps", "knurl", [62, 20, 24], [-762, 46, 662], "r1 r3 r5", "gunmetal", "pin dia 50 px through both plates; knurled caps (24 ribs) on both sides with a dark dome centre dia 25", both=True, axis="Y"), part("U12", "front block (J4 housing)", "rbox", [95, 210, 205, 12], [-92, 0, 992], "r1 r2 r3", "paint_white", "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 (J4 .. J5). Origin F0 = (-35, 0, 937) on the roll axis. WC = (435, 0, 937). # ================================================================================================================ PARTS["Forearm"] = [ part("F01", "roll bearing ring", "ring", [190, 150, 12], [-29, 0, 937], "r1 r2 r6", "gunmetal", "the black thin ring between the upper arm and the forearm", axis="X"), part("F02", "dial housing", "rbox", [250, 190, 195, 30], [90, 0, 947], "r1 r2 r3 r6", "paint_white", "X -35..215, Z 850..1045"), part("F03", "dark side plates", "rbox", [230, 6, 145, 30], [95, 96, 972], "r1 r3 r6", "gunmetal", "rounded plates with a '7'-shaped groove near the rear top corner (r6), a small bolt with a white ring at x_img 1015", both=True), part("F04", "dials", "stack", [[110, 6, "gunmetal"], [85, 4, "gunmetal"], [55, 4, "steel"], [20, 6, "gunmetal"]], [90, 100, 960], "r1 r2 r3 r6", "mixed", "black stepped disc with a '+' cross groove (6 px) through it and 4 notches on the rim (r6)", both=True, axis="Y"), part("F05", "belly", "rbox", [200, 160, 60, 14], [110, 0, 880], "r1 r6", "paint_white", "below the side plates; seam; a flat bar 230x25 px under it (r6)"), part("F06", "orange dot grids", "decal", [26, 14], [180, 96, 940], "r1 r3", "orange", "2 x 3 dots dia 5 px", both=True), part("F07", "J5/J6 motor cylinder", "cyl", [75, 90], [255, 0, 1000], "r1 r2 r6", "paint_white", "ringed (3 grooves) white cylinder, top front, joining the wrist block", axis="X"), part("F08", "hose", "tube", [22], [[200, -10, 870], [260, -10, 860], [330, -10, 870]], "r1 r3 r6", "rubber", "black hose with metal ferrules (dia 28 x 15 px) at both ends and an ORANGE band (6 px) near the front end"), part("F09", "wrist block (fork)", "plate2d", [[215, 1055], [335, 1045], [440, 990], [500, 937], [440, 860], [215, 850]], [0, 0, 0], "r1 r2 r3 r6", "paint_white", "angled housing Y +-75; its front is a fork (cheeks Y +-(55..75)) carrying J5; lobes R 60 round WC"), part("F10", "wrist fin (left)", "rbox", [75, 15, 22, 8], [330, 76, 1015], "r1 r6", "paint_white", "raised rounded bar, inclined 20 deg; right side has an oval recessed slot 70x18 px instead (r3)"), part("F11", "orange triangles + dots", "decal", [35, 25], [345, 76, 975], "r1 r3 r6", "orange", "three small triangles and two dots (left); 2x2 dots (right)", both=True), part("F12", "screw caps", "disc", [15, 5], [[400, 76, 930], [385, 76, 885]], "r1 r6", "paint_white", "two white domes per side", both=True, axis="Y"), part("F13", "bottom handle", "U", [55, 15, 5], [387, 0, 842], "r1 r3 r6", "gunmetal", "flat-bar loop under the wrist block"), part("F14", "J5 caps (wrist round caps)", "stack", [[100, 6, "gunmetal"], [80, 4, "gunmetal"], [60, 4, "gunmetal"], [40, 4, "steel"], [20, 4, "gunmetal"]], [435, 76, 937], "r1 r2 r3 r6", "mixed", "stepped concentric rings on both cheeks", both=True, axis="Y"), part("F15", "wrist top cylinder", "cyl", [45, 40], [320, 0, 1005], "r6", "paint_white", "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", axis="X"), ] PARTS["WristHead"] = [ part("W01", "head drum", "cyl", [95, 106], [435, 0, 937], "r1 r6", "gunmetal", "between the fork cheeks, turns about Y", axis="Y"), part("W02", "neck collar", "cyl", [75, 12], [470, 0, 937], "r1 r6", "gunmetal", "", axis="X"), ] PARTS["Flange"] = [ part("FL1", "knurled ring", "knurl", [72, 25, 36], [482, 0, 937], "r1 r6", "steel", "J6 turns here (r6 knurled neck)", axis="X"), part("FL2", "flange face", "disc", [80, 5], [497, 0, 937], "added", "gunmetal", "6 bolt holes; tools bolt here", axis="X"), ] # ================================================================================================================ # TOOL A: gripper hub + 4 fingers at 90 deg (top, bottom, left, right). Hub X 495..570 (WC + 60..135 px). # Finger (open, ref pose): knuckle at WC+(100, r 78); proximal 88 px at 23 deg outward; distal 70 px; hooked tip. # ================================================================================================================ PARTS["ToolA"] = [ part("A01", "hub", "cyl", [125, 75], [532, 0, 937], "r1 r2 r3 r6", "paint_white", "white body with a black ring at each end, 3 grooves; front face: 4 dark stepped rings (dia 125/100/75/45)", axis="X"), part("A02", "finger brackets x4", "box", [35, 30, 25], [552, 0, 937 + 70], "r1 r2 r3 r6", "gunmetal", "on the hub's front rim at r 70, one per finger"), part("A03", "finger motors x4", "knurl", [30, 65, 24], [580, 0, 937 + 110], "r1 r2 r6", "steel", "knurled cylinder fixed to each bracket, axis in the finger's plane pointing back-outward 20 deg from the tool axis (r1 top finger)"), ] PARTS["Finger"] = [ # one finger, in its own frame: origin knuckle, X along the tool axis, Z radial outward part("A04", "knuckle pin caps", "disc", [24, 6], [0, 0, 0], "r1 r6", "steel", "both sides of the knuckle", axis="Y"), part("A05", "proximal link", "rbox", [88, 18, 22, 5], [44, 0, 0], "r1 r2 r3 r6", "gunmetal", "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"), part("A06", "distal pin caps", "disc", [20, 6], [88, 0, 0], "r1 r6", "steel", "", axis="Y"), part("A07", "distal link + hooked tip", "rbox", [70, 16, 18, 4], [123, 0, 0], "r1 r2 r3 r6", "gunmetal", "tapered 18 -> 10 px; a 15 px hook turned inward at the tip; ridged steel jaw insert on the inner face"), ] # ================================================================================================================ # TOOL B: the red sketch (ref6): flared neck + square plate. Neck X 495..692 px, plate X 692..711 px (door face 720 px = WC + 0.63 m). # ================================================================================================================ PARTS["ToolB"] = [ part("B01", "flared neck", "cone", [70, 133, 197], [593, 0, 937], "r6 (red sketch)", "paint_white", "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", axis="X"), part("B02", "mounting plate", "rbox", [20, 250, 250, 15], [701, 0, 937], "r6 (red sketch)", "gunmetal", "square plate 0.55 x 0.55 x 0.044 m, corner R 0.033, 2 mm chamfers; its door face is flat"), part("B03", "plate bolts x8", "hex", [18, 10], [690, 0, 937], "added", "steel", "M24-size hex heads, 2 per edge on a 0.46 m square"), part("B04", "orange corner ticks", "decal", [20, 20], [690, 0, 937], "added (matches the arm's accents)", "orange", "four small L-ticks at the plate's corners"), ] # ================================================================================================================ # DOOR FIXTURES (follow the door; not part of the arm) # ================================================================================================================ PARTS["DoorFixtureA"] = [ part("DA1", "conformal pad", "pad", [0.32, 0.32, 0.02], [0, 0, 0], "added", "gunmetal", "underside follows the door's inner face (ray-cast), top flat", units="m", frame="fixture local: Z = door normal"), part("DA2", "base plate", "rbox", [0.26, 0.26, 0.03, 0.02], [0, 0, 0.035], "added", "gunmetal", "4 bolts", units="m", frame="fixture local"), part("DA3", "stem", "cyl", [0.08, 0.115], [0, 0, 0.1075], "added", "steel", "", units="m", frame="fixture local"), part("DA4", "grab knob (mushroom head)", "cyl", [0.13, 0.05], [0, 0, 0.19], "added", "steel", "3 mm chamfers; the 4 hooked tips close under it round the stem", units="m", frame="fixture local"), ] PARTS["DoorFixtureB"] = [ part("DB1", "conformal pad", "pad", [0.60, 0.60, 0.02], [0, 0, 0], "added", "gunmetal", "underside follows the door's face; the plate B02 bolts to its flat top", units="m", frame="fixture local"), ] # ================================================================================================================ # RAIL KIT (added to each pocket's rail; the user's rail object is not changed). World metres (AFT; FORE mirrored in x = 3.05). # ================================================================================================================ PARTS["RailKit"] = [ part("K01", "running flanges x2", "box", [6.49, 0.05, 0.03], [-5.790, -6.0488, -3.995], "added", "steel", "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", both=True, units="m", frame="world"), part("K02", "rack", "rack", [5.32, 0.06, 0.04], [-5.565, -5.795, -4.030], "added", "steel", "gear rack bolted under the rail's bottom face over the pinion's travel (x -8.225..-2.905), teeth down, module 12 mm", units="m", frame="world"), part("K03", "end stops x2", "box", [0.13, 0.30, 0.12], [[-8.620, -5.795, -4.07], [-2.525, -5.795, -4.07]], "added", "gunmetal", "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)", units="m", frame="world"), part("K04", "energy-chain tray", "channel", [6.05, 0.40, 0.125], [-5.975, -5.08, -3.84], "added", "gunmetal", "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", units="m", frame="world"), part("K05", "energy chain", "chain", [3.27, 0.10, 0.06], [], "added", "rubber", "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", units="m", frame="world"), ] # Screws: bright steel heads wherever the references show them (turret back strips 6, lower block front corners 6, belt arm 3, # clamp 1, forearm side plate 1 each side, wrist screw caps 4, fixture bolts); cap screws dia 10-15 px unless listed. # ================================================================================================================ # Coarse clearance proxies (oriented boxes per link, ref1 px, rest pose, A frame absolute). design_ik_check.py uses them. # box: centre, half-sizes, and an optional in-plane tilt (deg, about Y: positive turns +X toward +Z). # ================================================================================================================ PROXIES = { # box: c, h (half sizes), tilt; cyl: c, r, hl (half length), ax ('X' | 'Y' | 'Z' in the link frame), tilt "Turret": [ dict(n="lower block", c=[-15, 0, 67], h=[175, 165, 42]), dict(n="front housing", c=[105, 0, 225], h=[145, 140, 120]), dict(n="ear L", c=[-155, 185, 235], r=115, hl=30, ax="Y"), dict(n="ear R", c=[-155, -185, 235], r=115, hl=30, ax="Y"), dict(n="cap L", c=[-155, 224, 235], r=83, hl=10, ax="Y"), dict(n="cap R", c=[-155, -224, 235], r=83, hl=10, ax="Y"), dict(n="belt drive", c=[300, 35, 110], h=[90, 40, 55]), dict(n="cable bundle", c=[285, 62, 270], h=[75, 25, 70]), dict(n="side cables L", c=[-30, 260, 120], h=[120, 75, 90]), dict(n="side cables R", c=[-30, -260, 120], h=[120, 75, 90]), # round parts of the lower arm about J2: their envelope does not change when J2 turns, so they are checked here dict(n="drum envelope", c=[-155, 0, 235], r=120, hl=105, ax="Y"), dict(n="root plates envelope L", c=[-155, 128, 235], r=165, hl=22, ax="Y"), dict(n="root plates envelope R", c=[-155, -128, 235], r=165, hl=22, ax="Y"), ], "LowerArm": [ dict(n="root beam core", c=[-274, 0, 310], h=[140, 55, 110], tilt=-32.2), dict(n="knee caps", c=[-393, 0, 385], r=125, hl=230, ax="Y"), dict(n="beam sides L", c=[-436, 130, 507], h=[140, 75, 110], tilt=-70.6), dict(n="beam sides R", c=[-436, -130, 507], h=[140, 75, 110], tilt=-70.6), dict(n="beam core", c=[-415, 0, 514], h=[140, 55, 88], tilt=-70.6), dict(n="yoke L", c=[-515, 165, 730], h=[150, 40, 100], tilt=-70.6), dict(n="yoke R", c=[-515, -165, 730], h=[150, 40, 100], tilt=-70.6), dict(n="elbow caps", c=[-550, 0, 830], r=85, hl=215, ax="Y"), dict(n="handle L", c=[-552, 185, 385], h=[40, 10, 78]), dict(n="handle R", c=[-552, -185, 385], h=[40, 10, 78]), ], "UpperArm": [ dict(n="hub", c=[-550, 0, 830], r=80, hl=115, ax="Y"), dict(n="housing", c=[-340, 0, 950], h=[220, 110, 105], tilt=28.0), dict(n="front block", c=[-92, 0, 992], h=[50, 105, 103]), dict(n="truss", c=[-656, 0, 746], h=[150, 40, 50], tilt=38.4), dict(n="knob", c=[-762, 0, 662], r=32, hl=60, ax="Y"), dict(n="gland+cables", c=[-640, 55, 960], h=[180, 30, 140]), ], "Forearm": [ dict(n="dial housing", c=[90, 0, 950], h=[125, 100, 100]), dict(n="belly", c=[110, 0, 875], h=[100, 80, 35]), dict(n="motor cyl", c=[255, 0, 1000], r=38, hl=45, ax="X"), dict(n="wrist block", c=[282, 0, 952], h=[63, 80, 103]), dict(n="wrist lower web", c=[407, 0, 873], h=[63, 75, 23]), dict(n="wrist lobe L", c=[435, 65, 937], r=55, hl=10, ax="Y"), dict(n="wrist lobe R", c=[435, -65, 937], r=55, hl=10, ax="Y"), dict(n="hose+handle", c=[300, 0, 850], h=[90, 25, 20]), ], "WristHead": [dict(n="head", c=[435, 0, 937], r=47, hl=53, ax="Y")], "ToolA": [ dict(n="hub", c=[532, 0, 937], r=63, hl=38, ax="X"), dict(n="fingers (closed envelope)", c=[595, 0, 937], r=95, hl=60, ax="X"), dict(n="finger roots", c=[555, 0, 937], r=88, hl=20, ax="X"), dict(n="finger motor top", c=[512, 0, 1026], r=12, hl=28, ax="X", tilt=-18.4), dict(n="finger motor bottom", c=[512, 0, 848], r=12, hl=28, ax="X", tilt=18.4), dict(n="finger motor left", c=[512, 89, 937], r=12, hl=28, ax="X", tiltZ=-18.4), dict(n="finger motor right", c=[512, -89, 937], r=12, hl=28, ax="X", tiltZ=18.4), ], "ToolB": [ dict(n="neck", c=[593, 0, 937], r=66, hl=98, ax="X"), dict(n="plate", c=[701, 0, 937], h=[10, 125, 125]), ], } # ================================================================================================================ MATERIALS = { "M_DoorArm_PaintWhite": dict(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": dict(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.70), "M_DoorArm_Steel": dict(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.50), "M_DoorArm_Rubber": dict(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.40), "M_DoorArm_Orange": dict(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=None), "M_DoorArm_Glass": dict(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=None), "M_DoorArm_Lamp": dict(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=None), "M_DoorArm_Decals": dict(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=None), } MARKINGS = [ dict(id="D01", shape="hexagon outline, 3 px line, 50 px across", where="lower arm left side near the knee (L08)", refs="r1 r2"), dict(id="D02", shape="small triangle outline 18 px", where="lower arm left side (L09)", refs="r1 r5"), dict(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"), dict(id="D04", shape="small striped square (warning)", where="turret lower block left rear (T07a)", refs="r1"), dict(id="D05", shape="2 x 3 dot grid, dots 5 px", where="forearm below the dials, both sides (F06)", refs="r1 r3"), dict(id="D06", shape="three small triangles + two dots", where="wrist block left side (F11)", refs="r1 r6"), dict(id="D07", shape="2 x 2 dots", where="wrist block right side (F11)", refs="r3"), dict(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"), dict(id="D09", shape="four L-shaped corner ticks", where="version B plate corners (B04)", refs="added"), dict(id="D10", shape="thin orange line 20 px", where="turret lower block left (r1 x_img 885, y 1530)", refs="r1"), dict(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", }