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>
This commit is contained in:
mangavalkandClaude Opus 5.5 committed 2026-11-14 12:14:32 +01:00
1 parent b1c94e4149
commit 91b5b99fd5
42 files changed
+1560 -20

No files matched your search

+36
View File
@@ -0,0 +1,36 @@
// The whole 2026 hexapod: body (body.scad) plus six legs (leg.scad),
// placed and posed like robot/Config.h. Robot frame: +X forward (switch
// end), +Y left, +Z up, Z = 0 on the bottom plate's top face.
use <body.scad>
use <leg.scad>
/* [Pose] */
// "original" = the Fusion model's pose; "stand" = firmware stance
// (Kinematics::neutralStance(): feet 130 mm out, 150 mm down).
POSE_NAME = "stand"; // [original, stand]
// Optional per-leg override, [coxa, femur, tibia] in degrees, legs 0..5.
POSE_OVERRIDE = [];
// Leg mounts from robot/Config.h: x, y, mount angle (0..2 right, 3..5 left).
// Hexagon layout: corner legs 60 deg round from the mid legs.
LEG_MOUNT = [[100, -50, -30], [0, -65, -90], [-100, -50, -150],
[-100, 50, 150], [0, 65, 90], [100, 50, 30]];
JOINT_PLANE_Z = 13.5; // femur/knee axes, halfway up the body cavity
POSES = [["original", [0, 0, -90]], ["stand", [0, -1.2, -98.3]]];
function base_pose() = [for (p = POSES) if (p[0] == POSE_NAME) p[1]][0];
function leg_pose(i) = len(POSE_OVERRIDE) == 6 ? POSE_OVERRIDE[i] : base_pose();
module robot() {
body_assembly();
for (i = [0:5]) {
m = LEG_MOUNT[i];
p = leg_pose(i);
translate([m[0], m[1], JOINT_PLANE_Z])
if (m[2] > 0) rotate([0, 0, m[2]]) leg(p);
else mirror([0, 1, 0]) rotate([0, 0, -m[2]]) leg([-p[0], p[1], p[2]]);
}
}
robot();