# OpenSCAD body redesign: notes `body.scad` rebuilds the body of `../fusion360/body-bottom/bottom v59.f3d` (top + bottom plate, PCB, coxa servos; legs are placeholders). ## Source of truth The `top` and `bottom` **solids** in `bottom v59.stp` (inside `bottom v59.f3d_files.zip`). The `top.dxf` / `bottom.dxf` sketches in the same zip are older and differ (front/back notch, side curve, one servo pocket with an extra notch), so they are not used. Coordinates: the plates are written in the original's top-view frame (u, v) = (Fusion x, -Fusion z); `fusion_to_robot()` rotates that by -90° into the robot frame of `robot/Config.h` (X = v forward, Y = -u left). Fusion's up axis is Y; Fusion Y = 0 is the top face of the bottom plate, which is also Z = 0 here. `body.scad` slices were overlaid on the original solid edges at every feature height (plate faces, standoff split, counterbore floor, nut wells, PCB bosses, pivot bosses, battery bay): all match, apart from the fixes below. ## What the original body is - Two 3 mm plates, cavity 27 mm (Z 0..27, top plate Z 27..30). - Outline: arm ends r 19.5 around each coxa axis, concave fillets r 15.5 at the mid arms, quadratic curves at the sides and a notch front/back. Fully symmetric (the "asymmetry" seen earlier came from a stray line near (128, 8) in `bottom.dxf` and construction points at x = 100). - Coxa axes (u, v): corners (±50, ±100), mid (±65, 0) = robot (±100, ±50) and (0, ±65), same as `Config.h`. - Coxa servos (HS-485HB): ears rest on the top plate (Z 30), case hangs in a 41 × 21 pocket down to Z 2. Shaft 10 mm from the outer case end. Ear screw holes ⌀2.5, 48.25 × 10 mm. Corner servos turned 50°. - Under each coxa axis a ⌀14 × 2 mm pivot boss on the bottom plate; the coxa bracket (`hinge1` above / `hinge2` below, leg parts) wraps the plate edge between the servo horn and this boss. - 4 standoffs ⌀15 at (u, v) (±35, ±30), split at Z 13.5: M3 from the top in a ⌀7 counterbore (floor Z 17.5), 8 mm grip, M3 nut in a hex well from below (top of the well Z 9.5). - PCB: long axis along the body, 4 bosses ⌀5 × 1 mm under the top plate on the PCB hole grid (35.78 × 78.96), ⌀2.5 holes (self-tapping M3?), ⌀5 × 1 mm recess on top. PCB top face at Z 26. - Teensy cut-out 23.78 × 66.96, centred. - Slide switch at the front: slot 8 × 16 (v 57..73), ⌀2 screw holes 19 mm apart, "ON"/"OFF" engraved 1 mm, readable from behind the robot. - Battery bay on the bottom plate: rails 3 × 13.5 mm high at |u| 26.06..29.06 (52.1 mm between them), from v -74.21 (open, rear) to 31.79, end stop at v 28.79..31.79. ## Bugs in the original, fixed here - Left-front pivot boss at u = -50.894 instead of -50. - Right-front corner has no coxa servo (only 5 of 6 placed). - Only 2 of 6 legs (the mid legs), plus mirror-naming leftovers and the empty `dontdeleteme` component (nothing to port). - Hex nut wells rotated randomly; now one orientation. ## Leg dimensions (for robot/Config.h and the Unity sim) Measured on the original solids (left mid leg, `bottom-leg v31`): | Item | Value | Config.h today | |------|-------|----------------| | Coxa: coxa axis to femur axis, horizontal | 55.0 mm | `COXA_LEN_MM` 55 (matches) | | Femur: femur axis to knee axis | 100.0 mm | `FEMUR_LEN_MM` 100 (matches) | | Tibia: knee axis to foot ball centre | 150.0 mm | `TIBIA_LEN_MM` 150 (matches) | | Foot ball radius | 5.0 mm + 0.5 mm TPU sock wall (same on the real robot) | not modelled | | Femur/knee axes height | in the coxa's joint plane, 13.5 mm above the bottom plate's top face | coxa pivot at Z 0 (matches if Z 0 = that plane) | | Leg mounts (coxa axes) | (±100, ±50), (0, ±65) | matches | | Original pose | femur 0°, tibia -90° (foot straight under the knee) | | So the link lengths need no change. What the firmware and Unity don't know yet: the ground contact is the foot ball's surface (5 mm + sock from the point the IK places), and the body's underside (coxa bracket lower arm) is 21.5 mm below the joint plane. ## Physical limits Collision sweep of the model's real parts (2D, per joint, in 0.25° steps; cross-checked with full CGAL intersections of body and legs). Joint convention as `robot/Config.h`. | Joint | Range | Stopped by | |-------|-------|-----------| | Coxa, mid legs 1/4 | -66.5° .. 66.5° | coxa bracket shell hits the plate waist | | Coxa, legs 0 (front-right) / 3 (rear-left) | -95.75° .. 66.75° (sideways mount: -35.75 .. 126.75) | same | | Coxa, legs 2 (rear-right) / 5 (front-left) | -66.75° .. 95.75° (sideways mount: -126.75 .. 35.75) | same | | Femur | -101.25° .. 101.25° | femur link hits the coxa bracket | | Tibia | -177° .. 12.75° | rod folds into the femur link / tibia shell hits it | | Servo travel | coxa/femur ±90°, tibia -180..0° | from the `SERVOS` pulse ranges | | Leg width at the joints | 33.7 mm to the horn side + 21.5 mm to the bearing side | neighbours touch at 55.2 mm | Hexagon layout (owner's request): corner legs mounted 60° round from the mid legs (mount angles ±30 / ±90 / ±150); this needs the four corner coxa brackets turned 60° on their servo splines. In the firmware (`Config.h`): per-leg `COXA_MIN_DEG`/`COXA_MAX_DEG`, all ±60 now (the sideways layout needed -32..60 / -60..32 at the corners), femur ±80 and tibia -150..-20 unchanged (inside the physical range), and `LEG_CLEARANCE_MM` 56 (was 30). `sim_smoke` passes; turning on the spot runs at ~77°/s with legs at least 97 mm apart (sideways layout: ~29°/s). ## Unity simulation `export_unity.py` renders the parts into `Hexapod_Simulation_Unity/Assets/HexapodSim/Resources/OpenScadModel/*.bytes` (rerun it after changing the SCAD files). `OpenScadModel.cs` hides the old scene's robot and builds a new rig with the same names at the exact Config.h geometry; `HexapodSimulation.useOpenScadModel` switches it off. `Editor/OpenScadModelSnapshot.cs` renders it in batch mode for checks. ## Remote (`remote.scad`) Rebuilt from `../fusion360/remote/remote v40.f3d` the same way (slices match the original). Bugs fixed: the lid was off by (0.406, 0.21, -0.365) mm (sat in the ledge, posts overlapping the bosses); the display bezel's mesh facets became a clean window; the stray Body12 (an ON-OFF bracket line never cut in) is left out. The display is a Nextion NX4832T035 (3.5" Basic); its board's M3 holes are the lid's 94.2 x 48.5 post grid. Reference parts in `remote.scad`: the joysticks are JH-D400X-R4 (4-axis, X/Y ±25°, twist ±45°, button; owner), mounted with the dust cover on the lid's top face; their M2.5 square is 32.5 mm, so the lid's screw holes moved from the original's 33 mm square to 32.5. The battery is an 18650 UPS/boost board (89 x 22 mm, SMD-holder version, 22.4 mm tall; owner), on the bottom's two d5 standoffs at (±27.9, -15) with the floor slots beside them for a strap; its hole spacing (55.8 mm here) is not confirmed. No collisions. Also from the owner: the bump on top of the middle post is a lanyard loop (the original's tunnel through it is modelled); the square hole is the on/off slide switch, mounted on top (same switch as the robot). Inside: an IMU on the 21 x 9 mm block (assumed GY-521), a USB-C breakout on the side-port block, and a Teensy **4.0** (confirmed by the owner, although `platformio.ini` builds the remote for a 4.1); it has no mounting holes and is placed on the hole-less 8 x 24 mm block as a guess. Open: what the 6 mm x 10 mm holes in the bottom bosses hold (magnets?), and whether the upper two bosses are meant to be asymmetric (x -80.387 / +82.73). ## Notes for future designs - Servo wires barely fit on the real robot: the six servo headers hang above the battery bay, and the front pair sits right over the bay's end stop (X 28.8..31.8, top at Z 13.5). Kept as-is for now; give the plugs and wires more room next time (e.g. a lower or shorter end stop, or a battery that leaves space under the headers). - The nRF24 under the switch is fine on the real robot. ## Open questions 1. Front = switch end (inferred from the ON/OFF text orientation)? 2. PCB direction: `PCB_USB_FRONT` (Teensy USB, 7805 and LED at the front, nRF24 and battery JST at the rear) or reversed? 3. Battery size. The six servo headers hang above the bay (|Y| 14-15 mm) and the JP1/JP4 or JP3/JP6 pair touches the end stop; servo plugs and the battery need to share that space. 4. Leg geometry: in the original the femur servo sits further out than `COXA_LEN_MM` = 55 suggests. Check when porting the legs.