fix: base plate dimensions 270x240mm per spec (issue #18)
Both chassis files corrected. Previous dimensions were wrong: prototype_baseplate.scad: was 680x130mm → now 270x240mm chassis_frame.scad: was 640x220mm → now 270x240mm Geometry recalculated for 270x240mm envelope: PLATE_W = 270mm (axle direction) PLATE_D = 240mm (front-to-rear) PLATE_X_HALF = 135mm (plate edge / axle entry) FORK_SLOT_D = 50mm → AXLE_X = 85mm from plate centre Axle-to-axle = 170mm (2 × 85mm) Wheels extend beyond plate edges as expected: Tire at X = ±(85 ± 27) = ±58–112mm, plate edge at ±135mm ✓ Mount positions recalculated for smaller plate: Dropout clamp bolt holes: X = ±(85±22) = ±63 and ±107mm ✓ (all within ±135mm) Stem flange bolts: r=33mm BC, at (±33,0) and (0,±33) ✓ FC mount: X = -40mm offset, holes at ±15mm ✓ Wiring slots: Y = ±55mm (clear of stem flange bolts at ±33mm) Lightening ovals: Y = ±80mm in open front/rear corridors Bumper length: 300mm (was 660mm, now PLATE_D + 60) Longitudinal ribs: 270mm long (was 600mm) chassis_frame.scad also updated: AXLE_HEIGHT corrected: 310mm → 127mm (TIRE_OD/2) Axle dimensions: 14mm → 16.11mm, flat 10mm → 13.00mm AXLE_X for fork bracket positioning Motor fork bracket logic cleaned up (no more negative cube dimensions) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fb3c8c863a
commit
6ea4b56471
@ -1,340 +1,339 @@
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// SaltyBot — Parametric Chassis Frame
|
// SaltyBot — Full Chassis Frame (Rev B — correct 270 × 240 mm envelope)
|
||||||
// Task: bd-1iy5
|
// Agent: sl-mechanical | 2026-02-28 | Fixes issue #18
|
||||||
// Agent: sl-mechanical
|
|
||||||
// Date: 2026-02-28
|
|
||||||
//
|
//
|
||||||
// Self-balancing two-wheeled robot chassis
|
// Parametric OpenSCAD model. Plate geometry corrected per issue #18:
|
||||||
// Requirements:
|
// Width (axle direction, X): 270 mm ← was wrong 640 mm
|
||||||
// - 600mm wheelbase
|
// Depth (front-to-rear, Y): 240 mm ← was wrong 220 mm
|
||||||
// - 2x hoverboard hub motors (170mm OD)
|
// Wheels extend beyond plate edges — expected.
|
||||||
// - STM32 MAMBA F722S FC mount (30.5x30.5mm pattern)
|
//
|
||||||
// - Battery tray (24V 4Ah — ~180x70x50mm pack)
|
// Motor axle dimensions updated to caliper-verified values (see PR #7 / #11).
|
||||||
// - Jetson Nano B01 mount plate (100x80mm, M3 holes)
|
//
|
||||||
// - Front/rear bumper brackets
|
// NOTE: For the prototype, use prototype_baseplate.scad + stem_battery_clamp.scad.
|
||||||
|
// This file models the full machined chassis for production reference.
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
// ─── RENDER QUALITY ──────────────────────────────────────────────────────────
|
|
||||||
$fn = 64;
|
$fn = 64;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// PARAMETERS — edit here to adjust the whole model
|
// PLATE DIMENSIONS ← primary parameters fixed for issue #18
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
// ── Wheelbase / overall geometry ─────────────────────────────────────────────
|
PLATE_W = 270.0; // mm width (axle / left-right direction)
|
||||||
WHEELBASE = 600; // mm, center-to-center axle distance (lateral)
|
PLATE_D = 240.0; // mm depth (front-to-rear)
|
||||||
FRAME_WIDTH = 220; // mm, front-to-back depth of main deck
|
DECK_THICK = 6.0; // mm deck plate thickness
|
||||||
DECK_THICKNESS = 6; // mm, main deck plate thickness
|
WALL_T = 4.0; // mm general wall / rib thickness
|
||||||
WALL_T = 4; // mm, general wall thickness for brackets/ribs
|
|
||||||
|
|
||||||
// ── Hub motor parameters ─────────────────────────────────────────────────────
|
// Fork slot geometry — slot opens at plate edge, axle seats at bottom
|
||||||
MOTOR_OD = 170; // mm, motor housing outer diameter
|
FORK_SLOT_D = 50.0; // mm fork slot depth (inward from plate edge)
|
||||||
MOTOR_AXLE_D = 14; // mm, axle bolt diameter
|
PLATE_X_HALF = PLATE_W / 2; // 135 mm — plate half-width / edge
|
||||||
MOTOR_AXLE_FLAT = 10; // mm, axle flat-to-flat (for anti-rotation)
|
AXLE_X = PLATE_X_HALF - FORK_SLOT_D; // 85 mm — axle C/L from plate centre
|
||||||
MOTOR_FORK_WIDTH = 24; // mm, dropout slot width (fits 10-14mm axle + spacers)
|
|
||||||
MOTOR_FORK_DEPTH = 60; // mm, dropout slot depth from fork tip
|
|
||||||
MOTOR_FORK_H = 80; // mm, total height of motor fork bracket
|
|
||||||
MOTOR_FORK_T = 8; // mm, fork plate thickness
|
|
||||||
AXLE_HEIGHT = 310; // mm, axle CL above ground (motor radius + clearance)
|
|
||||||
|
|
||||||
// ── FC mount (MAMBA F722S — 30.5 × 30.5 mm M3 pattern) ──────────────────────
|
|
||||||
FC_MOUNT_SPACING = 30.5; // mm, hole pattern pitch
|
|
||||||
FC_MOUNT_HOLE_D = 3.2; // mm, M3 clearance
|
|
||||||
FC_STANDOFF_H = 6; // mm, standoff height
|
|
||||||
FC_PAD_T = 3; // mm, mounting pad thickness
|
|
||||||
|
|
||||||
// ── Battery tray (24V 4Ah LiPo / LiFePO4) ───────────────────────────────────
|
|
||||||
BATT_L = 185; // mm, cell pack length
|
|
||||||
BATT_W = 72; // mm, cell pack width
|
|
||||||
BATT_H = 52; // mm, cell pack height
|
|
||||||
BATT_WALL = 3; // mm, tray wall thickness
|
|
||||||
BATT_FLOOR = 4; // mm, tray floor thickness
|
|
||||||
BATT_STRAP_W = 20; // mm, Velcro strap slot width
|
|
||||||
BATT_STRAP_T = 2; // mm, strap slot depth
|
|
||||||
|
|
||||||
// ── Jetson Nano B01 mount plate ──────────────────────────────────────────────
|
|
||||||
// B01 carrier board hole pattern: 58 x 58 mm M3 (inner) + corner pass-throughs
|
|
||||||
JETSON_HOLE_PITCH = 58; // mm, M3 mounting hole pattern
|
|
||||||
JETSON_HOLE_D = 3.2; // mm
|
|
||||||
JETSON_PLATE_L = 105; // mm, plate length
|
|
||||||
JETSON_PLATE_W = 90; // mm, plate width
|
|
||||||
JETSON_PLATE_T = 4; // mm, plate thickness
|
|
||||||
JETSON_STANDOFF_H = 8; // mm
|
|
||||||
|
|
||||||
// ── Bumper bracket ────────────────────────────────────────────────────────────
|
|
||||||
BUMPER_L = WHEELBASE + 60; // mm, bumper rail length (overhangs wheel CL)
|
|
||||||
BUMPER_H = 40; // mm, bracket vertical height
|
|
||||||
BUMPER_T = 5; // mm, bracket plate thickness
|
|
||||||
BUMPER_TUBE_OD = 22; // mm, 3/4" EMT conduit OD for bumper rail
|
|
||||||
|
|
||||||
// ── Rib / gusset parameters ───────────────────────────────────────────────────
|
|
||||||
RIB_W = 20; // mm, longitudinal rib width
|
|
||||||
RIB_H = 40; // mm, rib height below deck
|
|
||||||
RIB_T = 4; // mm, rib plate thickness (laser/router cut)
|
|
||||||
|
|
||||||
// ── Fastener helpers ─────────────────────────────────────────────────────────
|
|
||||||
M3_D = 3.2;
|
|
||||||
M4_D = 4.3;
|
|
||||||
M5_D = 5.3;
|
|
||||||
M6_D = 6.5;
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// MAIN ASSEMBLY — comment/uncomment parts as needed
|
// HUB MOTOR — VERIFIED AXLE DIMENSIONS (caliper)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
color("Silver", 0.9) main_deck();
|
AXLE_BASE_DIA = 16.11; // mm round section near hub
|
||||||
color("DimGray") motor_fork(side= 1); // right (+X)
|
AXLE_BASE_LEN = 15.00;
|
||||||
color("DimGray") motor_fork(side=-1); // left (-X)
|
AXLE_DCUT_DIA = 15.95; // mm D-cut round OD
|
||||||
color("SteelBlue") battery_tray();
|
AXLE_DCUT_FLAT = 13.00; // mm flat chord
|
||||||
color("OliveDrab") fc_mount_plate();
|
AXLE_DCUT_LEN = 43.35;
|
||||||
color("DarkOrange") jetson_mount_plate();
|
AXLE_TOTAL = 65.50; // mm protrusion from hub face
|
||||||
color("Tomato") bumper_bracket(front= 1);
|
BEARING_SEAT_OD = 37.80; // mm hub centre collar OD
|
||||||
color("Tomato") bumper_bracket(front=-1);
|
TIRE_OD = 254.0; // mm 10 × 2.125" pneumatic
|
||||||
color("WhiteSmoke") longitudinal_ribs();
|
TIRE_WIDTH = 54.0; // mm
|
||||||
|
|
||||||
|
AXLE_HEIGHT = TIRE_OD / 2; // 127 mm — axle C/L above ground
|
||||||
|
|
||||||
|
// Fork slot width (base section + clearance)
|
||||||
|
FORK_SLOT_W = AXLE_BASE_DIA + 0.4; // 16.51 mm
|
||||||
|
|
||||||
|
// Vertical motor fork bracket
|
||||||
|
FORK_BKT_H = 100.0; // mm bracket height below deck to axle level
|
||||||
|
FORK_BKT_T = 8.0; // mm bracket plate thickness
|
||||||
|
FORK_BKT_W = 28.0; // mm bracket width (Y)
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// MODULES
|
// FC MOUNT — MAMBA F722S 30.5 × 30.5 mm M3
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
FC_PITCH = 30.5;
|
||||||
|
FC_HOLE_D = 3.2;
|
||||||
|
FC_STANDOFF = 6.0;
|
||||||
|
FC_X = -40.0; // mm from plate centre (front of plate)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// BATTERY TRAY (legacy flat — superseded by stem carousel architecture)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
BATT_L = 185.0;
|
||||||
|
BATT_W = 72.0;
|
||||||
|
BATT_H = 52.0;
|
||||||
|
BATT_WALL = 3.0;
|
||||||
|
BATT_FLOOR = 4.0;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// JETSON NANO B01 MOUNT
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
JETSON_PITCH = 58.0;
|
||||||
|
JETSON_HOLE_D = 3.2;
|
||||||
|
JETSON_PL = 100.0;
|
||||||
|
JETSON_PW = 86.0;
|
||||||
|
JETSON_PT = 4.0;
|
||||||
|
JETSON_STOFF = 8.0;
|
||||||
|
JETSON_X = 50.0; // mm from plate centre (rear)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// BUMPER BRACKETS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
BUMPER_L = PLATE_D + 60; // 300 mm — spans plate depth + 30 mm each end
|
||||||
|
BUMPER_H = 40.0;
|
||||||
|
BUMPER_T = 5.0;
|
||||||
|
BUMPER_TUBE_OD = 22.0; // 3/4" EMT
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// LONGITUDINAL RIBS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
RIB_T = 4.0;
|
||||||
|
RIB_H = 40.0;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// FASTENERS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
M3 = 3.2; M4 = 4.3; M5 = 5.3;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// ASSEMBLY
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
color("Silver", 0.90) main_deck();
|
||||||
|
color("DimGray", 1.00) motor_fork_bracket(side= 1);
|
||||||
|
color("DimGray", 1.00) motor_fork_bracket(side=-1);
|
||||||
|
color("SteelBlue", 1.00) battery_tray();
|
||||||
|
color("OliveDrab", 1.00) fc_mount_plate();
|
||||||
|
color("DarkOrange", 1.00) jetson_mount_plate();
|
||||||
|
color("Tomato", 1.00) bumper_bracket(front= 1);
|
||||||
|
color("Tomato", 1.00) bumper_bracket(front=-1);
|
||||||
|
color("WhiteSmoke", 1.00) longitudinal_ribs();
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// MAIN DECK (270 × 240 mm)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
// ─── Main deck plate ─────────────────────────────────────────────────────────
|
|
||||||
module main_deck() {
|
module main_deck() {
|
||||||
|
R = 10;
|
||||||
difference() {
|
difference() {
|
||||||
// Deck plate
|
linear_extrude(DECK_THICK)
|
||||||
translate([-WHEELBASE/2 - MOTOR_FORK_T, -FRAME_WIDTH/2, 0])
|
minkowski() {
|
||||||
cube([WHEELBASE + 2*MOTOR_FORK_T, FRAME_WIDTH, DECK_THICKNESS]);
|
square([PLATE_W - 2*R, PLATE_D - 2*R], center=true);
|
||||||
|
circle(r=R);
|
||||||
|
}
|
||||||
|
|
||||||
// Lightening holes — 3 rows × 4 cols
|
// Fork slots (open at ±X plate edges)
|
||||||
for (x = [-WHEELBASE/3, 0, WHEELBASE/3])
|
for (side = [-1, 1]) {
|
||||||
for (y = [-FRAME_WIDTH/4, FRAME_WIDTH/4])
|
translate([side*(PLATE_X_HALF - FORK_SLOT_D), -FORK_SLOT_W/2, -1])
|
||||||
translate([x, y, -1])
|
cube([FORK_SLOT_D + 1, FORK_SLOT_W, DECK_THICK + 2]);
|
||||||
cylinder(d=50, h=DECK_THICKNESS+2);
|
translate([side*(PLATE_X_HALF - FORK_SLOT_D), 0, -1])
|
||||||
|
cylinder(d=FORK_SLOT_W, h=DECK_THICK + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bearing seat relief
|
||||||
|
for (side = [-1, 1])
|
||||||
|
translate([side*(PLATE_X_HALF - BEARING_SEAT_OD/2 - 1),
|
||||||
|
-BEARING_SEAT_OD/2, -1])
|
||||||
|
cube([BEARING_SEAT_OD/2 + 2, BEARING_SEAT_OD, DECK_THICK + 2]);
|
||||||
|
|
||||||
|
// Fork bracket bolt holes (M5 × 4 per side)
|
||||||
|
for (side = [-1, 1])
|
||||||
|
for (dx = [-15, 15])
|
||||||
|
for (dy = [-12, 12])
|
||||||
|
translate([side * AXLE_X + dx, dy, -1])
|
||||||
|
cylinder(d=M5, h=DECK_THICK + 2);
|
||||||
|
|
||||||
// FC mount holes
|
// FC mount holes
|
||||||
fc_mount_holes(z_offset=-1, depth=DECK_THICKNESS+2);
|
fc_holes(z=-1, h=DECK_THICK+2);
|
||||||
|
|
||||||
// Battery tray floor cutout for wire pass-through
|
// Battery tray anchor holes
|
||||||
translate([-BATT_L/2 + 40, -BATT_W/2 + 40, -1])
|
for (x = [-BATT_L/2 + 12, BATT_L/2 - 12])
|
||||||
cube([BATT_L - 80, BATT_W - 80, DECK_THICKNESS+2]);
|
for (y = [-BATT_W/2 + 10, BATT_W/2 - 10])
|
||||||
|
translate([x, y, -1]) cylinder(d=M4, h=DECK_THICK+2);
|
||||||
|
|
||||||
|
// Lightening ovals (front/rear open zones)
|
||||||
|
for (dy = [-80, 80])
|
||||||
|
hull() {
|
||||||
|
translate([ 25, dy, -1]) cylinder(d=22, h=DECK_THICK+2);
|
||||||
|
translate([-25, dy, -1]) cylinder(d=22, h=DECK_THICK+2);
|
||||||
|
}
|
||||||
|
|
||||||
// Cable routing slots
|
// Cable routing slots
|
||||||
for (x = [-60, 60])
|
for (dy = [-55, 55])
|
||||||
translate([x, -FRAME_WIDTH/2 - 1, -1])
|
hull() {
|
||||||
cube([14, 18, DECK_THICKNESS+2]);
|
translate([ 12, dy, -1]) cylinder(d=12, h=DECK_THICK+2);
|
||||||
|
translate([-12, dy, -1]) cylinder(d=12, h=DECK_THICK+2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Longitudinal ribs (×2, symmetric F/R) ───────────────────────────────────
|
// =============================================================================
|
||||||
|
// LONGITUDINAL RIBS (×2)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
module longitudinal_ribs() {
|
module longitudinal_ribs() {
|
||||||
for (y = [-FRAME_WIDTH/2 + RIB_W/2 + WALL_T,
|
rib_y = PLATE_D/2 - WALL_T - RIB_T/2;
|
||||||
FRAME_WIDTH/2 - RIB_W/2 - WALL_T])
|
for (y = [-rib_y, rib_y])
|
||||||
translate([-WHEELBASE/2, y - RIB_T/2, -RIB_H])
|
translate([-PLATE_W/2, y - RIB_T/2, -RIB_H])
|
||||||
cube([WHEELBASE, RIB_T, RIB_H]);
|
cube([PLATE_W, RIB_T, RIB_H]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Motor fork dropout bracket ──────────────────────────────────────────────
|
// =============================================================================
|
||||||
// Mounts to deck edge; provides a CNC-milled or FDM dropout slot for the axle.
|
// MOTOR FORK BRACKET (vertical, bolts to deck edge at ±PLATE_X_HALF)
|
||||||
// `side` = +1 (right/+X) or -1 (left/-X)
|
// =============================================================================
|
||||||
module motor_fork(side = 1) {
|
|
||||||
x_pos = side * (WHEELBASE/2);
|
|
||||||
|
|
||||||
translate([x_pos, 0, 0]) {
|
module motor_fork_bracket(side = 1) {
|
||||||
|
translate([side * PLATE_X_HALF, 0, 0]) {
|
||||||
|
s = side;
|
||||||
difference() {
|
difference() {
|
||||||
union() {
|
union() {
|
||||||
// Vertical fork body
|
// Main bracket plate (extends below deck)
|
||||||
translate([side*(DECK_THICKNESS/2), -MOTOR_FORK_WIDTH/2 - 4, -MOTOR_FORK_H])
|
translate([s > 0 ? 0 : -FORK_BKT_T,
|
||||||
cube([side * MOTOR_FORK_T, MOTOR_FORK_WIDTH + 8, MOTOR_FORK_H + DECK_THICKNESS]);
|
-FORK_BKT_W/2, -FORK_BKT_H])
|
||||||
|
cube([FORK_BKT_T, FORK_BKT_W, FORK_BKT_H + DECK_THICK]);
|
||||||
|
|
||||||
// Gusset triangles
|
// Diagonal gussets
|
||||||
for (g = [-1, 1])
|
for (gy = [-1, 1])
|
||||||
translate([side*(DECK_THICKNESS/2), g*(MOTOR_FORK_WIDTH/2 + 2), -MOTOR_FORK_H])
|
translate([s > 0 ? 0 : -FORK_BKT_T,
|
||||||
linear_extrude(height=MOTOR_FORK_T)
|
gy * FORK_BKT_W/2, -FORK_BKT_H/2])
|
||||||
polygon([[0,0],[0, g*20],[side*-30, 0]]);
|
linear_extrude(FORK_BKT_T)
|
||||||
|
polygon([[0,0],[0, gy*20],[s * -25, 0]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Axle dropout slot (open at bottom)
|
// Axle dropout slot (open at bracket bottom)
|
||||||
translate([side*(DECK_THICKNESS/2) - 1,
|
translate([s > 0 ? -1 : -FORK_BKT_T - 1,
|
||||||
-MOTOR_AXLE_FLAT/2,
|
-AXLE_BASE_DIA/2 - 0.2, -FORK_BKT_H])
|
||||||
-MOTOR_FORK_DEPTH - MOTOR_AXLE_D/2])
|
cube([FORK_BKT_T + 2, AXLE_BASE_DIA + 0.4, FORK_SLOT_D + 1]);
|
||||||
cube([MOTOR_FORK_T + 2, MOTOR_AXLE_FLAT, MOTOR_FORK_DEPTH + 1]);
|
translate([s > 0 ? -1 : -FORK_BKT_T - 1,
|
||||||
|
0, -FORK_BKT_H + FORK_SLOT_D])
|
||||||
|
rotate([-90, 0, 0])
|
||||||
|
cylinder(d=AXLE_BASE_DIA + 0.4,
|
||||||
|
h=FORK_BKT_T + 2, center=true);
|
||||||
|
|
||||||
// Axle through-hole at slot top
|
// Deck attachment bolts (M5 × 4)
|
||||||
translate([side*(DECK_THICKNESS/2) - 1, 0,
|
for (dy = [-12, 12])
|
||||||
-MOTOR_FORK_DEPTH - MOTOR_AXLE_D/2])
|
for (dz = [DECK_THICK * 0.3, DECK_THICK * 0.7])
|
||||||
|
translate([s > 0 ? -1 : -FORK_BKT_T - 1, dy, dz])
|
||||||
rotate([0, 90, 0])
|
rotate([0, 90, 0])
|
||||||
cylinder(d=MOTOR_AXLE_D + 1, h=MOTOR_FORK_T + 2);
|
cylinder(d=M5, h=FORK_BKT_T + 2);
|
||||||
|
|
||||||
// Bolt holes for deck attachment (M5 × 4)
|
|
||||||
for (y = [-20, 20])
|
|
||||||
for (z = [4, 12])
|
|
||||||
translate([side*(DECK_THICKNESS/2) - 1, y, z - MOTOR_FORK_H + MOTOR_FORK_H/2])
|
|
||||||
rotate([0, 90, 0])
|
|
||||||
cylinder(d=M5_D, h=MOTOR_FORK_T + 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Battery tray ─────────────────────────────────────────────────────────────
|
// =============================================================================
|
||||||
// Positioned in centre of deck, recessed 10mm below deck surface
|
// FC MOUNT HELPERS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
module fc_holes(z=0, h=10) {
|
||||||
|
for (x = [FC_X - FC_PITCH/2, FC_X + FC_PITCH/2])
|
||||||
|
for (y = [-FC_PITCH/2, FC_PITCH/2])
|
||||||
|
translate([x, y, z]) cylinder(d=FC_HOLE_D, h=h);
|
||||||
|
}
|
||||||
|
|
||||||
|
module fc_mount_plate() {
|
||||||
|
translate([FC_X, 0, 0]) {
|
||||||
|
difference() {
|
||||||
|
union() {
|
||||||
|
for (x = [-FC_PITCH/2, FC_PITCH/2])
|
||||||
|
for (y = [-FC_PITCH/2, FC_PITCH/2])
|
||||||
|
translate([x, y, DECK_THICK]) cylinder(d=8, h=FC_STANDOFF);
|
||||||
|
translate([-(FC_PITCH/2+8), -(FC_PITCH/2+8), DECK_THICK])
|
||||||
|
cube([FC_PITCH+16, FC_PITCH+16, 3]);
|
||||||
|
}
|
||||||
|
fc_holes(z=DECK_THICK-1, h=FC_STANDOFF+4);
|
||||||
|
fc_holes(z=-1, h=DECK_THICK+2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// BATTERY TRAY
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
module battery_tray() {
|
module battery_tray() {
|
||||||
z_base = -BATT_FLOOR - BATT_H - 5; // hang below deck
|
z_base = -BATT_FLOOR - BATT_H - 5;
|
||||||
translate([-BATT_L/2 - BATT_WALL, -BATT_W/2 - BATT_WALL, z_base]) {
|
translate([-BATT_L/2 - BATT_WALL, -BATT_W/2 - BATT_WALL, z_base]) {
|
||||||
difference() {
|
difference() {
|
||||||
// Outer tray body
|
cube([BATT_L+2*BATT_WALL, BATT_W+2*BATT_WALL, BATT_H+BATT_FLOOR]);
|
||||||
cube([BATT_L + 2*BATT_WALL,
|
|
||||||
BATT_W + 2*BATT_WALL,
|
|
||||||
BATT_H + BATT_FLOOR]);
|
|
||||||
|
|
||||||
// Inner cavity
|
|
||||||
translate([BATT_WALL, BATT_WALL, BATT_FLOOR])
|
translate([BATT_WALL, BATT_WALL, BATT_FLOOR])
|
||||||
cube([BATT_L, BATT_W, BATT_H + 1]);
|
cube([BATT_L, BATT_W, BATT_H+1]);
|
||||||
|
for (x = [BATT_L/2-30, BATT_L/2+8])
|
||||||
// Strap slots (2× longitudinal)
|
translate([x, -1, BATT_FLOOR+BATT_H/2-10])
|
||||||
for (x = [BATT_L/2 - BATT_STRAP_W*2,
|
cube([20, BATT_W+2*BATT_WALL+2, 20]);
|
||||||
BATT_L/2 + BATT_STRAP_W])
|
for (i = [0:1])
|
||||||
translate([x, -1, BATT_FLOOR + BATT_H/2 - BATT_STRAP_W/2])
|
translate([BATT_WALL+12+i*68, BATT_WALL+8, -1])
|
||||||
cube([BATT_STRAP_W, BATT_W + 2*BATT_WALL + 2, BATT_STRAP_W]);
|
cube([38, BATT_W-16, BATT_FLOOR+2]);
|
||||||
|
for (x=[10,BATT_L+BATT_WALL-2]) for (y=[10,BATT_W+BATT_WALL-2])
|
||||||
// Ventilation slots bottom (3×)
|
translate([x,y,BATT_H+BATT_FLOOR-1]) cylinder(d=M4,h=BATT_FLOOR+2);
|
||||||
for (i = [0:2])
|
|
||||||
translate([BATT_WALL + 20 + i*50, BATT_WALL + 10, -1])
|
|
||||||
cube([30, BATT_W - 20, BATT_FLOOR + 2]);
|
|
||||||
|
|
||||||
// Mount holes to deck (M4 × 4 corners)
|
|
||||||
for (x = [10, BATT_L + BATT_WALL - 2])
|
|
||||||
for (y = [10, BATT_W + BATT_WALL - 2])
|
|
||||||
translate([x, y, BATT_H + BATT_FLOOR - 1])
|
|
||||||
cylinder(d=M4_D, h=BATT_FLOOR + 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── FC mount holes helper ────────────────────────────────────────────────────
|
// =============================================================================
|
||||||
module fc_mount_holes(z_offset=0, depth=10) {
|
// JETSON NANO B01 MOUNT PLATE
|
||||||
// MAMBA F722S: 30.5×30.5 mm M3 pattern, centred at origin
|
// =============================================================================
|
||||||
for (x = [-FC_MOUNT_SPACING/2, FC_MOUNT_SPACING/2])
|
|
||||||
for (y = [-FC_MOUNT_SPACING/2, FC_MOUNT_SPACING/2])
|
|
||||||
translate([x, y, z_offset])
|
|
||||||
cylinder(d=FC_MOUNT_HOLE_D, h=depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── FC mount plate (raised 40mm above deck centre) ──────────────────────────
|
|
||||||
module fc_mount_plate() {
|
|
||||||
fc_x = -50; // offset toward front from deck centre
|
|
||||||
fc_y = 0;
|
|
||||||
plate_z = DECK_THICKNESS + FC_STANDOFF_H;
|
|
||||||
|
|
||||||
translate([fc_x, fc_y, 0]) {
|
|
||||||
difference() {
|
|
||||||
union() {
|
|
||||||
// Mount pads with standoffs
|
|
||||||
for (x = [-FC_MOUNT_SPACING/2, FC_MOUNT_SPACING/2])
|
|
||||||
for (y = [-FC_MOUNT_SPACING/2, FC_MOUNT_SPACING/2]) {
|
|
||||||
translate([x, y, DECK_THICKNESS])
|
|
||||||
cylinder(d=8, h=FC_STANDOFF_H); // standoff column
|
|
||||||
translate([x - 5, y - 5, DECK_THICKNESS])
|
|
||||||
cube([10, 10, FC_PAD_T]); // pad base
|
|
||||||
}
|
|
||||||
// Base plate
|
|
||||||
translate([-FC_MOUNT_SPACING/2 - 8, -FC_MOUNT_SPACING/2 - 8, DECK_THICKNESS])
|
|
||||||
cube([FC_MOUNT_SPACING + 16, FC_MOUNT_SPACING + 16, FC_PAD_T]);
|
|
||||||
}
|
|
||||||
// M3 through-holes in standoffs
|
|
||||||
fc_mount_holes(z_offset=DECK_THICKNESS - 1, depth=FC_STANDOFF_H + FC_PAD_T + 2);
|
|
||||||
|
|
||||||
// Deck anchor holes
|
|
||||||
fc_mount_holes(z_offset=-1, depth=DECK_THICKNESS + 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─── Jetson Nano B01 mount plate ─────────────────────────────────────────────
|
|
||||||
// Positioned rear of deck, elevated on standoffs
|
|
||||||
module jetson_mount_plate() {
|
module jetson_mount_plate() {
|
||||||
jet_x = 60; // offset toward rear
|
translate([JETSON_X, 0, 0]) {
|
||||||
jet_y = 0;
|
|
||||||
plate_z = DECK_THICKNESS + JETSON_STANDOFF_H;
|
|
||||||
|
|
||||||
translate([jet_x, jet_y, 0]) {
|
|
||||||
difference() {
|
difference() {
|
||||||
union() {
|
union() {
|
||||||
// Mounting plate
|
translate([-JETSON_PL/2, -JETSON_PW/2, DECK_THICK+JETSON_STOFF])
|
||||||
translate([-JETSON_PLATE_L/2, -JETSON_PLATE_W/2, DECK_THICKNESS + JETSON_STANDOFF_H])
|
cube([JETSON_PL, JETSON_PW, JETSON_PT]);
|
||||||
cube([JETSON_PLATE_L, JETSON_PLATE_W, JETSON_PLATE_T]);
|
for (x=[-JETSON_PITCH/2, JETSON_PITCH/2])
|
||||||
|
for (y=[-JETSON_PITCH/2, JETSON_PITCH/2])
|
||||||
// Four standoff columns
|
translate([x,y,DECK_THICK]) cylinder(d=6, h=JETSON_STOFF);
|
||||||
for (x = [-JETSON_HOLE_PITCH/2, JETSON_HOLE_PITCH/2])
|
|
||||||
for (y = [-JETSON_HOLE_PITCH/2, JETSON_HOLE_PITCH/2])
|
|
||||||
translate([x, y, DECK_THICKNESS])
|
|
||||||
cylinder(d=6, h=JETSON_STANDOFF_H);
|
|
||||||
}
|
}
|
||||||
|
for (x=[-JETSON_PITCH/2, JETSON_PITCH/2])
|
||||||
// B01 M3 hole pattern (58×58 mm)
|
for (y=[-JETSON_PITCH/2, JETSON_PITCH/2])
|
||||||
for (x = [-JETSON_HOLE_PITCH/2, JETSON_HOLE_PITCH/2])
|
translate([x,y,DECK_THICK-1])
|
||||||
for (y = [-JETSON_HOLE_PITCH/2, JETSON_HOLE_PITCH/2])
|
cylinder(d=JETSON_HOLE_D, h=JETSON_STOFF+JETSON_PT+2);
|
||||||
translate([x, y, DECK_THICKNESS - 1])
|
for (i=[-1,0,1])
|
||||||
cylinder(d=JETSON_HOLE_D, h=JETSON_STANDOFF_H + JETSON_PLATE_T + 2);
|
translate([i*22-8,-JETSON_PW/2+8,DECK_THICK+JETSON_STOFF-1])
|
||||||
|
cube([16, JETSON_PW-16, JETSON_PT+2]);
|
||||||
// Ventilation / cable routing slots in plate
|
for (x=[-JETSON_PL/2+8, JETSON_PL/2-8])
|
||||||
for (i = [-1, 0, 1])
|
for (y=[-JETSON_PW/2+8, JETSON_PW/2-8])
|
||||||
translate([i*25 - 10, -JETSON_PLATE_W/2 + 10,
|
translate([x,y,-1]) cylinder(d=M3, h=DECK_THICK+2);
|
||||||
DECK_THICKNESS + JETSON_STANDOFF_H - 1])
|
|
||||||
cube([20, JETSON_PLATE_W - 20, JETSON_PLATE_T + 2]);
|
|
||||||
|
|
||||||
// Deck anchor holes (M3 × 4 corners of plate)
|
|
||||||
for (x = [-JETSON_PLATE_L/2 + 8, JETSON_PLATE_L/2 - 8])
|
|
||||||
for (y = [-JETSON_PLATE_W/2 + 8, JETSON_PLATE_W/2 - 8])
|
|
||||||
translate([x, y, -1])
|
|
||||||
cylinder(d=M3_D, h=DECK_THICKNESS + 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Bumper bracket ───────────────────────────────────────────────────────────
|
// =============================================================================
|
||||||
// `front` = +1 (front) or -1 (rear)
|
// BUMPER BRACKETS (front / rear)
|
||||||
module bumper_bracket(front = 1) {
|
// =============================================================================
|
||||||
y_pos = front * (FRAME_WIDTH/2);
|
|
||||||
|
|
||||||
translate([0, y_pos, 0]) {
|
module bumper_bracket(front = 1) {
|
||||||
|
yp = front * PLATE_D/2;
|
||||||
|
translate([0, yp, 0]) {
|
||||||
difference() {
|
difference() {
|
||||||
union() {
|
union() {
|
||||||
// Horizontal mounting rail plate
|
|
||||||
translate([-BUMPER_L/2, front*(BUMPER_T/2), 0])
|
translate([-BUMPER_L/2, front*(BUMPER_T/2), 0])
|
||||||
cube([BUMPER_L, BUMPER_T, BUMPER_H]);
|
cube([BUMPER_L, BUMPER_T, BUMPER_H]);
|
||||||
|
for (x=[-BUMPER_L/2+4, BUMPER_L/2-BUMPER_T-4])
|
||||||
// Vertical gussets at ends
|
translate([x, front*BUMPER_T, 0]) cube([BUMPER_T, 16, BUMPER_H]);
|
||||||
for (x = [-BUMPER_L/2 + 5, BUMPER_L/2 - BUMPER_T - 5])
|
for (x=[-BUMPER_L/3, 0, BUMPER_L/3])
|
||||||
translate([x, front*(BUMPER_T), 0])
|
translate([x-BUMPER_TUBE_OD/2-2,
|
||||||
cube([BUMPER_T, 20, BUMPER_H]);
|
front*(BUMPER_T+10),
|
||||||
|
BUMPER_H-BUMPER_TUBE_OD/2-4])
|
||||||
// Bumper tube saddle clamps (×3 evenly spaced)
|
|
||||||
for (x = [-BUMPER_L/3, 0, BUMPER_L/3])
|
|
||||||
translate([x - BUMPER_TUBE_OD/2 - 2,
|
|
||||||
front*(BUMPER_T + 15),
|
|
||||||
BUMPER_H - BUMPER_TUBE_OD/2 - 5])
|
|
||||||
difference() {
|
difference() {
|
||||||
cube([BUMPER_TUBE_OD + 4, BUMPER_TUBE_OD/2 + 4, BUMPER_TUBE_OD + 4]);
|
cube([BUMPER_TUBE_OD+4, BUMPER_TUBE_OD/2+4, BUMPER_TUBE_OD+4]);
|
||||||
translate([BUMPER_TUBE_OD/2 + 2, -1, BUMPER_TUBE_OD/2 + 2])
|
translate([BUMPER_TUBE_OD/2+2,-1,BUMPER_TUBE_OD/2+2])
|
||||||
rotate([-90, 0, 0])
|
rotate([-90,0,0])
|
||||||
cylinder(d=BUMPER_TUBE_OD, h=BUMPER_TUBE_OD/2 + 6);
|
cylinder(d=BUMPER_TUBE_OD, h=BUMPER_TUBE_OD/2+6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (x=[-BUMPER_L/2+16, -BUMPER_L/6, BUMPER_L/6, BUMPER_L/2-16])
|
||||||
// Deck mounting holes (M5 × 6 along length)
|
translate([x, yp*0.001, -1]) cylinder(d=M5, h=BUMPER_H+2);
|
||||||
for (x = [-BUMPER_L/2 + 20, -BUMPER_L/6, BUMPER_L/6, BUMPER_L/2 - 20])
|
|
||||||
translate([x, y_pos * 0.001, -1])
|
|
||||||
cylinder(d=M5_D, h=BUMPER_H + 2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
|
||||||
// DIMENSIONS / ANNOTATIONS (2D cross-section reference)
|
|
||||||
// =============================================================================
|
|
||||||
// Uncomment to render a side-view dimension guide:
|
|
||||||
//
|
|
||||||
// %translate([0, FRAME_WIDTH/2 + 30, 0]) {
|
|
||||||
// color("Blue") {
|
|
||||||
// cube([WHEELBASE, 1, 1]); // wheelbase span
|
|
||||||
// translate([0,0,0]) text(str("Wheelbase: ", WHEELBASE, "mm"), size=12);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -1,96 +1,104 @@
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
// SaltyBot — Prototype Base Plate (Rev C — compact, stem-mount)
|
// SaltyBot — Prototype Base Plate (Rev D — correct 270 × 240 mm envelope)
|
||||||
// Agent: sl-mechanical | 2026-02-28
|
// Agent: sl-mechanical | 2026-02-28 | Fixes issue #18
|
||||||
//
|
//
|
||||||
// Laser-cut or CNC-routed flat plate (6 mm Al / 8 mm acrylic).
|
// Laser-cut or CNC-routed flat plate (6 mm Al / 8 mm acrylic).
|
||||||
// Uses CALIPER-VERIFIED hub motor axle measurements (see PR #7 / #11).
|
|
||||||
//
|
//
|
||||||
// ARCHITECTURE CHANGE (Rev C):
|
// PLATE DIMENSIONS (per spec, issue #18)
|
||||||
// Batteries are NO LONGER on the base plate.
|
// Width (axle direction, X): 270 mm
|
||||||
// They stand vertically on a central stem via stem_battery_clamp.scad.
|
// Depth (front-to-rear, Y): 240 mm
|
||||||
// The base plate is now compact — only axle dropouts + stem socket + FC mount.
|
// Wheels extend beyond plate edges — expected.
|
||||||
//
|
//
|
||||||
// ── AXLE PROFILE (stepped D-cut, caliper-verified) ───────────────────────────
|
// MOTOR AXLE GEOMETRY
|
||||||
// Zone │ Feature │ Ø / Width │ Length
|
// Plate edge = axle entry point (X = ±135 mm from plate centre)
|
||||||
// ───────┼──────────────────┼────────────────────┼──────────
|
// Fork slot depth = 50 mm inward → axle C/L seated at X = ±85 mm
|
||||||
// Base │ Round (near hub) │ Ø 16.11 mm │ 15.00 mm
|
// Axle-to-axle distance = 170 mm
|
||||||
// D-cut │ Round OD │ Ø 15.95 mm │ 43.35 mm
|
// Tires (Ø254 mm, 54 mm wide) at X = ±(85 ± 27) = ±58 – 112 mm ← clear of ±135 edge
|
||||||
// │ Flat chord │ 13.00 mm │
|
//
|
||||||
// Tip │ Shoulder/end │ — │ 3.00 mm
|
// VERIFIED AXLE PROFILE (caliper)
|
||||||
// Total │ Hub face → tip │ — │ 65.50 mm
|
// Base section: Ø 16.11 mm, 15 mm long
|
||||||
|
// D-cut zone: Ø 15.95 mm, 13 mm flat chord, 43.35 mm long
|
||||||
|
// Tip: 3 mm
|
||||||
|
// Total: 65.5 mm from hub face
|
||||||
// Bearing seat collar: Ø 37.8 mm
|
// Bearing seat collar: Ø 37.8 mm
|
||||||
// Tire: 10 × 2.125" pneumatic (Ø 254 mm, 35 PSI)
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
$fn = 128;
|
$fn = 128;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// PLATE DIMENSIONS ← primary parameters for issue #18 fix
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
PLATE_W = 270.0; // mm width (axle / left-right direction)
|
||||||
|
PLATE_D = 240.0; // mm depth (front-to-rear)
|
||||||
|
PLATE_THICK = 6.0; // mm stock thickness
|
||||||
|
|
||||||
|
// Derived
|
||||||
|
PLATE_X_HALF = PLATE_W / 2; // 135 mm — plate edge
|
||||||
|
FORK_DEPTH = 50.0; // mm fork slot depth (inward from edge)
|
||||||
|
AXLE_X = PLATE_X_HALF - FORK_DEPTH; // 85 mm — axle C/L from plate centre
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// AXLE PARAMETERS — caliper-verified
|
// AXLE PARAMETERS — caliper-verified
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
AXLE_BASE_DIA = 16.11;
|
AXLE_BASE_DIA = 16.11; AXLE_BASE_LEN = 15.00;
|
||||||
AXLE_BASE_LEN = 15.00;
|
AXLE_DCUT_DIA = 15.95; AXLE_DCUT_FLAT = 13.00; AXLE_DCUT_LEN = 43.35;
|
||||||
AXLE_DCUT_DIA = 15.95;
|
AXLE_TIP_LEN = 3.00; AXLE_TOTAL = 65.50;
|
||||||
AXLE_DCUT_FLAT = 13.00;
|
|
||||||
AXLE_DCUT_LEN = 43.35;
|
|
||||||
AXLE_TIP_LEN = 3.00;
|
|
||||||
AXLE_TOTAL = 65.50;
|
|
||||||
BEARING_SEAT_OD = 37.80;
|
BEARING_SEAT_OD = 37.80;
|
||||||
TIRE_OD = 254.0;
|
TIRE_OD = 254.0; // 10" × 25.4 mm
|
||||||
AXLE_CL_HEIGHT = TIRE_OD / 2; // 127 mm above ground
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// PLATE PARAMETERS
|
// DROPOUT CLAMP PARAMETERS
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
WHEELBASE = 600.0; // mm axle C/L to axle C/L
|
FORK_W = AXLE_BASE_DIA + 0.4; // 16.51 mm fork slot width
|
||||||
// Plate depth now driven only by structural + FC needs (no battery footprint).
|
|
||||||
PLATE_DEPTH = 130.0; // mm front-to-rear
|
|
||||||
PLATE_OVERHANG = 40.0; // mm plate past axle C/L each side
|
|
||||||
PLATE_THICK = 6.0; // mm
|
|
||||||
|
|
||||||
// Fork slot
|
CLAMP_L = 80.0; // mm clamp length along axle axis
|
||||||
FORK_W = AXLE_BASE_DIA + 0.4; // 16.51 mm
|
// outer end at AXLE_X + CLAMP_L/2 = 85+40 = 125 mm
|
||||||
FORK_DEPTH = 50.0;
|
// plate edge at 135 mm → 10 mm margin ✓
|
||||||
|
CLAMP_H = 60.0; // mm clamp height (front-to-rear, in Y)
|
||||||
|
CLAMP_THICK = 8.0; // mm each clamp layer
|
||||||
|
CLAMP_BOLT_D = 5.3; // M5 clearance
|
||||||
|
CLAMP_BOLT_DX = 22.0; // mm bolt offset ±X from axle C/L
|
||||||
|
// inner bolt at AXLE_X - 22 = 63 mm ✓
|
||||||
|
// outer bolt at AXLE_X + 22 = 107 mm < 135 mm ✓
|
||||||
|
CLAMP_BOLT_DY = 22.0; // mm bolt offset ±Y from axle C/L
|
||||||
|
CLAMP_ALIGN_D = 4.1; // Ø4 alignment pin clearance
|
||||||
|
|
||||||
// Dropout clamp (two-piece sandwich)
|
DCUT_CL = 0.3; // mm D-cut bore clearance (all-round)
|
||||||
CLAMP_L = 80.0;
|
DCUT_R = (AXLE_DCUT_DIA + 2*DCUT_CL) / 2;
|
||||||
CLAMP_H = 60.0;
|
DCUT_FC = AXLE_DCUT_FLAT + 2*DCUT_CL;
|
||||||
CLAMP_THICK = 8.0;
|
|
||||||
CLAMP_BOLT_D = 5.3; // M5
|
|
||||||
CLAMP_BOLT_DX = 22.0;
|
|
||||||
CLAMP_BOLT_DY = 22.0;
|
|
||||||
CLAMP_ALIGN_D = 4.1; // Ø4 pin
|
|
||||||
|
|
||||||
// D-cut bore clearance
|
|
||||||
DCUT_CL = 0.3;
|
|
||||||
|
|
||||||
// FC mount — MAMBA F722S 30.5 × 30.5 mm M3
|
|
||||||
FC_PITCH = 30.5;
|
|
||||||
FC_HOLE_D = 3.2;
|
|
||||||
// FC is offset toward front of plate (away from stem)
|
|
||||||
FC_X_OFFSET = -40.0; // mm from plate centre (negative = front/motor side)
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// STEM SOCKET PARAMETERS
|
// STEM SOCKET
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
STEM_OD = 38.1; // mm 1.5" EMT conduit OD
|
STEM_OD = 38.1; // mm 1.5" EMT conduit OD
|
||||||
STEM_BORE = STEM_OD + 0.5; // 38.6 mm with clearance
|
STEM_BORE = STEM_OD + 0.5;
|
||||||
// Flange ring (laser-cut, bolts above + below plate to grip tube):
|
STEM_FLANGE_OD = 82.0; // mm flange ring OD
|
||||||
STEM_FLANGE_OD = 82.0; // mm flange outer diameter
|
STEM_FLANGE_BC = 66.0; // mm M5 bolt circle diameter (r = 33 mm)
|
||||||
STEM_FLANGE_BC = 66.0; // mm bolt circle diameter (4× M5 at 90°)
|
STEM_FLANGE_T = 6.0; // mm = PLATE_THICK
|
||||||
STEM_FLANGE_T = 6.0; // mm = PLATE_THICK (flush-mount)
|
|
||||||
// Stem position: at plate centre (X=0, Y=0)
|
// Verify flange bolts clear all other holes:
|
||||||
|
// Flange bolts at (±33, 0) and (0, ±33)
|
||||||
|
// Clamp bolts at (±63, ±22) and (±107, ±22)
|
||||||
|
// FC holes centred at (-40, 0) spanning X = ±55.25, Y = ±15.25
|
||||||
|
// All separations are adequate ✓
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// FC MOUNT — MAMBA F722S 30.5 × 30.5 mm M3
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
FC_PITCH = 30.5;
|
||||||
|
FC_HOLE_D = 3.2;
|
||||||
|
FC_X_OFFSET = -40.0; // mm front of plate (−X); FC at (−40, 0) within ±135 ✓
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// UTILITIES
|
// UTILITIES
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
M3 = 3.2; M4 = 4.3; M5 = 5.3;
|
M3 = 3.2; M4 = 4.3; M5 = 5.3;
|
||||||
PLATE_X_HALF = WHEELBASE/2 + PLATE_OVERHANG; // ± 340 mm
|
|
||||||
DCUT_R = (AXLE_DCUT_DIA + 2*DCUT_CL) / 2;
|
|
||||||
DCUT_FC = AXLE_DCUT_FLAT + 2*DCUT_CL;
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// RENDER CONTROL
|
// RENDER CONTROL
|
||||||
@ -100,21 +108,15 @@ DCUT_FC = AXLE_DCUT_FLAT + 2*DCUT_CL;
|
|||||||
// "plate_2d" DXF — base plate
|
// "plate_2d" DXF — base plate
|
||||||
// "clamp_lower_2d" DXF — lower dropout clamp (× 2)
|
// "clamp_lower_2d" DXF — lower dropout clamp (× 2)
|
||||||
// "clamp_upper_2d" DXF — upper dropout clamp (× 2)
|
// "clamp_upper_2d" DXF — upper dropout clamp (× 2)
|
||||||
// "stem_flange_2d" DXF — stem flange ring (× 2, one above + one below plate)
|
// "stem_flange_2d" DXF — stem flange ring (× 2)
|
||||||
|
|
||||||
RENDER = "assembly";
|
RENDER = "assembly";
|
||||||
|
|
||||||
if (RENDER == "assembly") {
|
if (RENDER == "assembly") assembly();
|
||||||
assembly();
|
else if (RENDER == "plate_2d") projection(cut=true) translate([0,0,-PLATE_THICK/2]) base_plate();
|
||||||
} else if (RENDER == "plate_2d") {
|
else if (RENDER == "clamp_lower_2d") projection(cut=true) translate([0,0,-CLAMP_THICK/2]) clamp_lower();
|
||||||
projection(cut=true) translate([0,0,-PLATE_THICK/2]) base_plate();
|
else if (RENDER == "clamp_upper_2d") projection(cut=true) translate([0,0,-CLAMP_THICK/2]) clamp_upper();
|
||||||
} else if (RENDER == "clamp_lower_2d") {
|
else if (RENDER == "stem_flange_2d") projection(cut=true) translate([0,0,-STEM_FLANGE_T/2]) stem_flange();
|
||||||
projection(cut=true) translate([0,0,-CLAMP_THICK/2]) clamp_lower();
|
|
||||||
} else if (RENDER == "clamp_upper_2d") {
|
|
||||||
projection(cut=true) translate([0,0,-CLAMP_THICK/2]) clamp_upper();
|
|
||||||
} else if (RENDER == "stem_flange_2d") {
|
|
||||||
projection(cut=true) translate([0,0,-STEM_FLANGE_T/2]) stem_flange();
|
|
||||||
}
|
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// ASSEMBLY
|
// ASSEMBLY
|
||||||
@ -125,119 +127,115 @@ module assembly() {
|
|||||||
|
|
||||||
for (side = [-1, 1]) {
|
for (side = [-1, 1]) {
|
||||||
color("SteelBlue", 0.80)
|
color("SteelBlue", 0.80)
|
||||||
translate([side * WHEELBASE/2, 0, PLATE_THICK])
|
translate([side * AXLE_X, 0, PLATE_THICK])
|
||||||
clamp_lower();
|
clamp_lower();
|
||||||
color("CornflowerBlue", 0.80)
|
color("CornflowerBlue", 0.80)
|
||||||
translate([side * WHEELBASE/2, 0, PLATE_THICK + CLAMP_THICK])
|
translate([side * AXLE_X, 0, PLATE_THICK + CLAMP_THICK])
|
||||||
clamp_upper();
|
clamp_upper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stem flange rings (above and below plate)
|
// Stem flanges (above and below plate)
|
||||||
color("DimGray", 0.70)
|
color("DimGray", 0.70) translate([0, 0, -STEM_FLANGE_T]) stem_flange();
|
||||||
translate([0, 0, -STEM_FLANGE_T])
|
color("DimGray", 0.70) translate([0, 0, PLATE_THICK]) stem_flange();
|
||||||
stem_flange();
|
|
||||||
color("DimGray", 0.70)
|
|
||||||
translate([0, 0, PLATE_THICK])
|
|
||||||
stem_flange();
|
|
||||||
|
|
||||||
// Reference ghosts
|
// Ghosts — not exported
|
||||||
%color("Orange", 0.25)
|
%color("Orange", 0.25)
|
||||||
translate([0, 0, PLATE_THICK + STEM_FLANGE_T])
|
translate([0, 0, PLATE_THICK + STEM_FLANGE_T])
|
||||||
cylinder(d=STEM_OD, h=800); // vertical stem
|
cylinder(d=STEM_OD, h=900);
|
||||||
|
|
||||||
%for (side = [-1, 1])
|
%for (side = [-1, 1])
|
||||||
color("Tomato", 0.2)
|
color("Tomato", 0.20)
|
||||||
translate([side * WHEELBASE/2, 0, 0])
|
translate([side * PLATE_X_HALF, 0, 0])
|
||||||
rotate([0, side*90, 0])
|
rotate([0, side * (-90), 0]) // axle projects inward from plate edge
|
||||||
axle_ghost();
|
axle_ghost();
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// BASE PLATE (Part A — compact)
|
// BASE PLATE (Part A — 270 × 240 mm)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
module base_plate() {
|
module base_plate() {
|
||||||
R = 12; // corner radius
|
R = 10; // corner radius
|
||||||
difference() {
|
difference() {
|
||||||
// ── Outer profile ──
|
// ── Outer profile (minkowski rounded corners) ──────────────────────
|
||||||
linear_extrude(PLATE_THICK)
|
linear_extrude(PLATE_THICK)
|
||||||
minkowski() {
|
minkowski() {
|
||||||
square([2*(PLATE_X_HALF - R), PLATE_DEPTH - 2*R], center=true);
|
square([PLATE_W - 2*R, PLATE_D - 2*R], center=true);
|
||||||
circle(r=R);
|
circle(r=R);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Fork slots (open at ±X edges, semicircular tip) ──────────────
|
// ── Fork slots (open at ±X plate edges, semicircular tip) ──────────
|
||||||
|
// Slot width FORK_W, depth FORK_DEPTH inward from plate edge.
|
||||||
|
// Axle seats in the semicircle at X = ±(PLATE_X_HALF − FORK_DEPTH) = ±85 mm.
|
||||||
for (side = [-1, 1]) {
|
for (side = [-1, 1]) {
|
||||||
translate([side*(PLATE_X_HALF - FORK_DEPTH), -FORK_W/2, -1])
|
// Rectangular slot body
|
||||||
cube([FORK_DEPTH + 1, FORK_W, PLATE_THICK + 2]);
|
translate([side * (PLATE_X_HALF - FORK_DEPTH), -FORK_W/2, -1])
|
||||||
translate([side*(PLATE_X_HALF - FORK_DEPTH), 0, -1])
|
cube([side > 0 ? FORK_DEPTH + 1 : FORK_DEPTH + 1,
|
||||||
|
FORK_W, PLATE_THICK + 2]);
|
||||||
|
// Semicircular slot tip (axle seat)
|
||||||
|
translate([side * (PLATE_X_HALF - FORK_DEPTH), 0, -1])
|
||||||
cylinder(d=FORK_W, h=PLATE_THICK + 2);
|
cylinder(d=FORK_W, h=PLATE_THICK + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Bearing seat relief (prevents Ø37.8 mm collar binding on edge) ─
|
// ── Bearing seat relief (prevents Ø37.8 mm hub collar contacting edge) ─
|
||||||
for (side = [-1, 1])
|
for (side = [-1, 1])
|
||||||
translate([side*PLATE_X_HALF - side*(BEARING_SEAT_OD/2 + 1),
|
translate([side * (PLATE_X_HALF - BEARING_SEAT_OD/2 - 1),
|
||||||
-BEARING_SEAT_OD/2, -1])
|
-BEARING_SEAT_OD/2, -1])
|
||||||
cube([BEARING_SEAT_OD/2 + 2, BEARING_SEAT_OD, PLATE_THICK + 2]);
|
cube([BEARING_SEAT_OD/2 + 2, BEARING_SEAT_OD, PLATE_THICK + 2]);
|
||||||
|
|
||||||
// ── Dropout clamp bolt through-holes ─────────────────────────────
|
// ── Dropout clamp bolt through-holes ───────────────────────────────
|
||||||
for (side = [-1, 1])
|
for (side = [-1, 1])
|
||||||
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
||||||
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
||||||
translate([side*WHEELBASE/2 + dx, dy, -1])
|
translate([side * AXLE_X + dx, dy, -1])
|
||||||
cylinder(d=CLAMP_BOLT_D, h=PLATE_THICK + 2);
|
cylinder(d=CLAMP_BOLT_D, h=PLATE_THICK + 2);
|
||||||
|
|
||||||
// ── Alignment pin holes (Ø4) ──────────────────────────────────────
|
// ── Alignment pin holes (Ø4 × 2 per clamp) ─────────────────────────
|
||||||
for (side = [-1, 1])
|
for (side = [-1, 1])
|
||||||
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
||||||
translate([side*WHEELBASE/2, dy, -1])
|
translate([side * AXLE_X, dy, -1])
|
||||||
cylinder(d=CLAMP_ALIGN_D, h=PLATE_THICK + 2);
|
cylinder(d=CLAMP_ALIGN_D, h=PLATE_THICK + 2);
|
||||||
|
|
||||||
// ── Stem socket bore ──────────────────────────────────────────────
|
// ── Stem socket bore ─────────────────────────────────────────────────
|
||||||
translate([0, 0, -1])
|
translate([0, 0, -1]) cylinder(d=STEM_BORE, h=PLATE_THICK + 2);
|
||||||
cylinder(d=STEM_BORE, h=PLATE_THICK + 2);
|
|
||||||
|
|
||||||
// ── Stem flange bolt holes (4× M5, 90° pattern on STEM_FLANGE_BC) ─
|
// ── Stem flange bolt holes (4× M5 at 90° on Ø66 BC) ────────────────
|
||||||
for (a = [0, 90, 180, 270])
|
for (a = [0, 90, 180, 270])
|
||||||
rotate([0, 0, a])
|
rotate([0, 0, a])
|
||||||
translate([STEM_FLANGE_BC/2, 0, -1])
|
translate([STEM_FLANGE_BC/2, 0, -1])
|
||||||
cylinder(d=M5, h=PLATE_THICK + 2);
|
cylinder(d=M5, h=PLATE_THICK + 2);
|
||||||
|
|
||||||
// ── FC mount (MAMBA F722S 30.5 × 30.5 M3) ────────────────────────
|
// ── FC mount holes (MAMBA F722S 30.5 × 30.5 M3) ────────────────────
|
||||||
for (x = [FC_X_OFFSET - FC_PITCH/2, FC_X_OFFSET + FC_PITCH/2])
|
for (x = [FC_X_OFFSET - FC_PITCH/2, FC_X_OFFSET + FC_PITCH/2])
|
||||||
for (y = [-FC_PITCH/2, FC_PITCH/2])
|
for (y = [-FC_PITCH/2, FC_PITCH/2])
|
||||||
translate([x, y, -1])
|
translate([x, y, -1]) cylinder(d=FC_HOLE_D, h=PLATE_THICK + 2);
|
||||||
cylinder(d=FC_HOLE_D, h=PLATE_THICK + 2);
|
|
||||||
|
|
||||||
// ── Wiring / cable pass-through slots (2×, flanking stem) ─────────
|
// ── Wiring / cable pass-through slots (flanking stem) ───────────────
|
||||||
for (dy = [-30, 30])
|
// Placed at Y = ±55 mm (clear of stem flange bolts at ±33 mm and clamp at ±22 mm)
|
||||||
|
for (dy = [-55, 55])
|
||||||
hull() {
|
hull() {
|
||||||
translate([15, dy, -1]) cylinder(d=14, h=PLATE_THICK + 2);
|
translate([ 12, dy, -1]) cylinder(d=12, h=PLATE_THICK + 2);
|
||||||
translate([-15, dy, -1]) cylinder(d=14, h=PLATE_THICK + 2);
|
translate([-12, dy, -1]) cylinder(d=12, h=PLATE_THICK + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Lightening slots (between FC zone and dropout zones) ──────────
|
// ── Lightening holes (2× in open areas between stem and clamp zones) ─
|
||||||
for (sx = [-1, 1]) {
|
// At X = 0, Y = ±80 mm (front/rear open corridor)
|
||||||
// One slot each side of stem, in the structural corridor
|
for (dy = [-80, 80])
|
||||||
lx = sx * (WHEELBASE/4);
|
|
||||||
hull() {
|
hull() {
|
||||||
translate([lx, -(PLATE_DEPTH/2 - 22), -1]) cylinder(d=18, h=PLATE_THICK+2);
|
translate([ 20, dy, -1]) cylinder(d=20, h=PLATE_THICK + 2);
|
||||||
translate([lx, (PLATE_DEPTH/2 - 22), -1]) cylinder(d=18, h=PLATE_THICK+2);
|
translate([-20, dy, -1]) cylinder(d=20, h=PLATE_THICK + 2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// STEM FLANGE RING (laser-cut, qty 2 — one above, one below plate)
|
// STEM FLANGE RING (laser-cut, qty 2)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
module stem_flange() {
|
module stem_flange() {
|
||||||
difference() {
|
difference() {
|
||||||
cylinder(d=STEM_FLANGE_OD, h=STEM_FLANGE_T);
|
cylinder(d=STEM_FLANGE_OD, h=STEM_FLANGE_T);
|
||||||
// Stem bore (tight fit — tube presses into flange)
|
translate([0, 0, -1]) cylinder(d=STEM_BORE, h=STEM_FLANGE_T + 2);
|
||||||
translate([0, 0, -1])
|
|
||||||
cylinder(d=STEM_BORE, h=STEM_FLANGE_T + 2);
|
|
||||||
// 4× M5 flange bolts
|
|
||||||
for (a = [0, 90, 180, 270])
|
for (a = [0, 90, 180, 270])
|
||||||
rotate([0, 0, a])
|
rotate([0, 0, a])
|
||||||
translate([STEM_FLANGE_BC/2, 0, -1])
|
translate([STEM_FLANGE_BC/2, 0, -1])
|
||||||
@ -246,7 +244,7 @@ module stem_flange() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// DROPOUT CLAMP — LOWER (round bore, base-section diameter)
|
// DROPOUT CLAMP — LOWER (round bore, base section)
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
module clamp_lower() {
|
module clamp_lower() {
|
||||||
@ -255,16 +253,13 @@ module clamp_lower() {
|
|||||||
translate([-CLAMP_L/2 + CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
translate([-CLAMP_L/2 + CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
||||||
translate([ CLAMP_L/2 - CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
translate([ CLAMP_L/2 - CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
||||||
}
|
}
|
||||||
// Round bore (base zone)
|
translate([0,0,-1]) cylinder(d=AXLE_BASE_DIA + 0.4, h=CLAMP_THICK + 2);
|
||||||
translate([0, 0, -1]) cylinder(d=AXLE_BASE_DIA + 0.4, h=CLAMP_THICK + 2);
|
// Open entry slot (axle slides in from plate edge)
|
||||||
// Slide-in slot (open toward wheel side)
|
|
||||||
translate([-CLAMP_L/2 - 1, -FORK_W/2, -1])
|
translate([-CLAMP_L/2 - 1, -FORK_W/2, -1])
|
||||||
cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]);
|
cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]);
|
||||||
// Clamp bolts
|
|
||||||
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
||||||
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
||||||
translate([dx, dy, -1]) cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2);
|
translate([dx, dy, -1]) cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2);
|
||||||
// Alignment pins
|
|
||||||
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
||||||
translate([0, dy, -1]) cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2);
|
translate([0, dy, -1]) cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2);
|
||||||
}
|
}
|
||||||
@ -275,41 +270,31 @@ module clamp_lower() {
|
|||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
module clamp_upper() {
|
module clamp_upper() {
|
||||||
dcut_r = DCUT_R;
|
dcut_d = sqrt(pow(DCUT_R, 2) - pow(DCUT_FC/2, 2));
|
||||||
dcut_d = sqrt(pow(dcut_r, 2) - pow(DCUT_FC/2, 2));
|
|
||||||
|
|
||||||
difference() {
|
difference() {
|
||||||
hull() {
|
hull() {
|
||||||
translate([-CLAMP_L/2 + CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
translate([-CLAMP_L/2 + CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
||||||
translate([ CLAMP_L/2 - CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
translate([ CLAMP_L/2 - CLAMP_H/2, 0, 0]) cylinder(d=CLAMP_H, h=CLAMP_THICK);
|
||||||
}
|
}
|
||||||
// D-cut bore
|
translate([0,0,-1])
|
||||||
translate([0, 0, -1])
|
linear_extrude(CLAMP_THICK + 2) dcut_profile_2d(DCUT_R, dcut_d);
|
||||||
linear_extrude(CLAMP_THICK + 2)
|
|
||||||
dcut_profile_2d(dcut_r, dcut_d);
|
|
||||||
// Slide-in slot
|
|
||||||
translate([-CLAMP_L/2 - 1, -FORK_W/2, -1])
|
translate([-CLAMP_L/2 - 1, -FORK_W/2, -1])
|
||||||
cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]);
|
cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]);
|
||||||
// Clamp bolts
|
|
||||||
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX])
|
||||||
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY])
|
||||||
translate([dx, dy, -1]) cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2);
|
translate([dx, dy, -1]) cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2);
|
||||||
// Alignment pins
|
|
||||||
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8])
|
||||||
translate([0, dy, -1]) cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2);
|
translate([0, dy, -1]) cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2);
|
||||||
// Orientation emboss
|
// Orientation marker (triangle pointing toward flat)
|
||||||
translate([0, dcut_d + 1.5, CLAMP_THICK - 0.8])
|
translate([0, dcut_d + 1.5, CLAMP_THICK - 0.8])
|
||||||
linear_extrude(1)
|
linear_extrude(1) polygon([[0,0],[-3,-5],[3,-5]]);
|
||||||
polygon([[0,0],[-3,-5],[3,-5]]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── D-cut 2D profile helper ───────────────────────────────────────────────────
|
|
||||||
module dcut_profile_2d(r, flat_d) {
|
module dcut_profile_2d(r, flat_d) {
|
||||||
intersection() {
|
intersection() {
|
||||||
circle(r=r);
|
circle(r=r);
|
||||||
translate([-r - 1, -r - 1])
|
translate([-r-1, -r-1]) square([2*(r+1), r+1+flat_d]);
|
||||||
square([2*(r+1), r + 1 + flat_d]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,25 +309,22 @@ module axle_ghost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// DXF EXPORT
|
// DXF EXPORT COMMANDS
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
//
|
//
|
||||||
// Part 1 — Base plate:
|
// Base plate (270 × 240 mm, 6 mm Al or 8 mm acrylic):
|
||||||
// openscad prototype_baseplate.scad -D 'RENDER="plate_2d"' -o baseplate.dxf
|
// openscad prototype_baseplate.scad -D 'RENDER="plate_2d"' -o baseplate.dxf
|
||||||
//
|
//
|
||||||
// Part 2 — Dropout clamp, lower (× 2):
|
// Dropout clamp lower (× 2):
|
||||||
// openscad prototype_baseplate.scad -D 'RENDER="clamp_lower_2d"' -o clamp_lower.dxf
|
// openscad prototype_baseplate.scad -D 'RENDER="clamp_lower_2d"' -o clamp_lower.dxf
|
||||||
//
|
//
|
||||||
// Part 3 — Dropout clamp, upper (× 2):
|
// Dropout clamp upper (× 2):
|
||||||
// openscad prototype_baseplate.scad -D 'RENDER="clamp_upper_2d"' -o clamp_upper.dxf
|
// openscad prototype_baseplate.scad -D 'RENDER="clamp_upper_2d"' -o clamp_upper.dxf
|
||||||
//
|
//
|
||||||
// Part 4 — Stem flange ring (× 2, one each side of plate):
|
// Stem flange ring (× 2):
|
||||||
// openscad prototype_baseplate.scad -D 'RENDER="stem_flange_2d"' -o stem_flange.dxf
|
// openscad prototype_baseplate.scad -D 'RENDER="stem_flange_2d"' -o stem_flange.dxf
|
||||||
//
|
//
|
||||||
// Materials:
|
// PLATE BLANK: 280 × 250 mm (10 mm oversized each side for datum + clamping)
|
||||||
// Plate + flanges : 6 mm 5052-H32 aluminium (preferred)
|
// CLAMP BLANKS: 90 × 70 mm each
|
||||||
// 8 mm clear acrylic (quick proto)
|
// FLANGE BLANKS: Ø90 mm disc each
|
||||||
// Dropout clamps : 8 mm 6061-T6 aluminium
|
|
||||||
// Stem tube : 38.1 mm OD × 1.5 mm wall 6061-T6 (or 1.5" EMT)
|
|
||||||
// Cut stem to ~1050 mm — allows batteries from ~100 mm to ~950 mm height.
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user