Files
hexapod-robot/2026-current/hardware/openscad/PLANNING.md
T
mangavalkandClaude Opus 5.5 91b5b99fd5 2026: OpenSCAD robot and remote, physical joint limits, model in Unity
hardware/openscad/ rebuilds the broken Fusion models as OpenSCAD:
body (top/bottom plate, standoffs, battery bay, switch), legs (coxa
bracket, femur link, tibia, horn adapters, TPU socks, servo cables),
the whole robot, and the remote (shell, lid, Nextion 3.5", JH-D400X-R4
sticks, 18650 UPS board, IMU, Teensy 4.0, USB-C breakout). Every part
was checked by slicing against the original STEP solids; the original's
bugs are fixed and listed in PLANNING.md.

The robot now uses a hexagon leg layout (corner legs 60 deg round from
the mid legs; the corner coxa brackets need turning on their splines).
Physical limits from a collision sweep of the model are in Config.h:
per-leg coxa limits and LEG_CLEARANCE_MM 56 (a leg is 55.2 mm wide at
the joints); the sim API exports them (version 7). sim_smoke passes.

Unity loads the model (export_unity.py -> Resources/OpenScadModel,
OpenScadModel.cs builds a new rig in place of the old scene's robot).
The PCB model's mounting holes now use the exact EasyEDA grid. README
shows renders of both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-14 12:14:32 +01:00

8.3 KiB
Raw Blame History

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.