diff --git a/chassis/BOM.md b/chassis/BOM.md index 56d4588..9250597 100644 --- a/chassis/BOM.md +++ b/chassis/BOM.md @@ -1,24 +1,58 @@ # SaltyBot Chassis — Bill of Materials -**Task:** bd-1iy5 -**Rev:** A — 2026-02-28 +**Task:** bd-1iy5 / prototype-baseplate +**Rev:** B — 2026-02-28 (updated with caliper-verified axle measurements) **Agent:** sl-mechanical --- +## ⚠ Axle Measurement Update (Rev B) + +PR #7 (`chassis_frame.scad`) used placeholder values. The table below records the +**caliper-verified** hub motor axle dimensions. All new designs must use these. + +| Feature | Measured | PR #7 placeholder | Delta | +|---------|----------|-------------------|-------| +| Axle base diameter (round, near hub) | **16.11 mm** | 14 mm | +2.11 mm | +| D-cut shaft OD | **15.95 mm** | — (not modelled) | new | +| D-cut flat chord | **13.00 mm** | — | new | +| Total axle protrusion | **65.5 mm** | ~60 mm est. | +5.5 mm | +| Base section length | **15.0 mm** | — | new | +| D-cut section length | **43.35 mm** | — | new | +| Tip / shoulder | **3.0 mm** | — | new | +| Bearing seat collar OD | **37.8 mm** | — | new | +| Tire OD | **254 mm** (10×2.125") | 170 mm motor OD only | — | +| Axle CL height above ground | **127 mm** | 310 mm (wrong) | −183 mm | + +`chassis_frame.scad` should be updated in a follow-on task to match Rev B values. + +--- + ## Structural / Fabricated Parts +### Prototype Base Plate (`prototype_baseplate.scad`) — Rev B + +| # | Part | Qty | Material | Cut size | Notes | +|---|------|-----|----------|----------|-------| +| 1 | Prototype base plate | 1 | 6mm 5052-H32 aluminium **or** 8mm clear acrylic | 680×220mm blank | Laser or CNC; export DXF from `RENDER="plate_2d"` | +| 2 | Dropout clamp — lower (L+R) | 2 | 8mm 6061-T6 aluminium | 90×70mm blank each | Round bore Ø16.51mm; `RENDER="clamp_lower_2d"` | +| 3 | Dropout clamp — upper (L+R) | 2 | 8mm 6061-T6 aluminium | 90×70mm blank each | D-cut bore (Ø16.25mm, 13.6mm flat chord); `RENDER="clamp_upper_2d"` | +| 4 | FC standoff M3×6mm nylon | 4 | Nylon | — | MAMBA F722S vibration isolation | +| 5 | Ø4mm alignment pin | 8 | Steel dowel | 16mm length | Clamp-to-plate alignment (2 per clamp stack) | + +### Full Chassis (`chassis_frame.scad`) — Rev A (placeholder values — pending Rev B update) + | # | Part | Qty | Material | Notes | |---|------|-----|----------|-------| -| 1 | Main deck plate | 1 | 6mm 5052 aluminium plate, 640×220mm | CNC router or waterjet; all holes per `chassis_frame.scad` | -| 2 | Longitudinal rib (front) | 1 | 4mm 5052 aluminium, 600×40mm | Laser-cut; press-fit into deck slots | -| 3 | Longitudinal rib (rear) | 1 | 4mm 5052 aluminium, 600×40mm | Same file, symmetric | -| 4 | Motor fork bracket (L) | 1 | 8mm 6061 aluminium | CNC mill or FDM PETG @100% infill for prototyping | -| 5 | Motor fork bracket (R) | 1 | 8mm 6061 aluminium | Mirror of item 4 | -| 6 | Battery tray | 1 | 3mm PETG FDM or 3mm aluminium fold | `chassis_frame.scad` — `battery_tray()` module | -| 7 | FC mount plate / standoffs | 1 set | PETG or nylon FDM | Includes 4× M3 nylon standoffs, 6mm height | -| 8 | Jetson Nano mount plate | 1 | 4mm 5052 aluminium or 4mm PETG FDM | B01 58×58mm hole pattern | -| 9 | Front bumper bracket | 1 | 5mm PETG FDM | Saddle clamps for 22mm EMT conduit | -| 10 | Rear bumper bracket | 1 | 5mm PETG FDM | Mirror of item 9 | +| 6 | Main deck plate | 1 | 6mm 5052 aluminium plate, 640×220mm | CNC router or waterjet; all holes per `chassis_frame.scad` | +| 7 | Longitudinal rib (front) | 1 | 4mm 5052 aluminium, 600×40mm | Laser-cut; press-fit into deck slots | +| 8 | Longitudinal rib (rear) | 1 | 4mm 5052 aluminium, 600×40mm | Same file, symmetric | +| 9 | Motor fork bracket (L) | 1 | 8mm 6061 aluminium | **Update fork slot to Ø16.51mm before cutting** | +| 10 | Motor fork bracket (R) | 1 | 8mm 6061 aluminium | Mirror of item 9 | +| 11 | Battery tray | 1 | 3mm PETG FDM or 3mm aluminium fold | `chassis_frame.scad` — `battery_tray()` module | +| 12 | FC mount plate / standoffs | 1 set | PETG or nylon FDM | Includes 4× M3 nylon standoffs, 6mm height | +| 13 | Jetson Nano mount plate | 1 | 4mm 5052 aluminium or 4mm PETG FDM | B01 58×58mm hole pattern | +| 14 | Front bumper bracket | 1 | 5mm PETG FDM | Saddle clamps for 22mm EMT conduit | +| 15 | Rear bumper bracket | 1 | 5mm PETG FDM | Mirror of item 14 | --- @@ -26,8 +60,9 @@ | # | Part | Qty | Source / Spec | Notes | |---|------|-----|---------------|-------| -| 11 | Hoverboard hub motor | 2 | Generic 6.5" / 170mm OD, 36V nominal | ~350W each; 14mm flat axle; confirm exact OD before cutting fork slots | -| 12 | Motor hall-sensor cable extension | 2 | 6-pin JST-PH 300mm | Route through deck cable slot | +| 16 | Hoverboard hub motor | 2 | 10×2.125" pneumatic tire, 36V nominal, ~350W | Axle: Ø16.11mm base / Ø15.95mm D-cut / 13mm flat; bearing seat Ø37.8mm — **all caliper-verified** | +| 17 | Motor hall-sensor cable extension | 2 | 6-pin JST-PH 300mm | Route through deck cable slot | +| 18 | Axle lock nut | 4 | M16×1.5 or thread-matched to actual axle tip | Confirm thread at tip before ordering; calipers show Ø≈10mm at tip | --- diff --git a/chassis/prototype_baseplate.scad b/chassis/prototype_baseplate.scad new file mode 100644 index 0000000..8f5a2c4 --- /dev/null +++ b/chassis/prototype_baseplate.scad @@ -0,0 +1,371 @@ +// ============================================================================= +// SaltyBot — Prototype Base Plate +// Agent: sl-mechanical | 2026-02-28 +// +// Laser-cut or CNC-routed flat plate (6mm aluminium or 8mm acrylic). +// Uses CALIPER-VERIFIED hub motor axle measurements — replaces placeholder +// values from chassis_frame.scad (PR #7). +// +// ── VERIFIED AXLE PROFILE (stepped D-cut) ──────────────────────────────────── +// Zone │ Feature │ Diameter / Width │ Length +// ───────┼──────────────────┼────────────────────┼───────── +// Base │ Round (near hub) │ Ø 16.11 mm │ 15.00 mm +// D-cut │ Round OD │ Ø 15.95 mm │ 43.35 mm +// │ Flat chord │ 13.00 mm across │ +// Tip │ Shoulder/end │ — │ 3.00 mm (tip lock nut seat) +// Total │ Hub face → tip │ — │ 65.50 mm +// ───────┼──────────────────┼────────────────────┼───────── +// Bearing seat collar OD: Ø 37.8 mm (hub centre) +// Tire: 10 × 2.125" pneumatic (254 mm OD, 54 mm wide, 35 PSI) +// ============================================================================= + +$fn = 128; + +// ============================================================================= +// AXLE PARAMETERS — caliper-verified (edit only when re-measured) +// ============================================================================= + +AXLE_BASE_DIA = 16.11; // mm round section near hub face +AXLE_BASE_LEN = 15.00; // mm length of base section +AXLE_DCUT_DIA = 15.95; // mm round OD of D-cut zone +AXLE_DCUT_FLAT = 13.00; // mm flat chord width (caliper across flat) +AXLE_DCUT_LEN = 43.35; // mm D-cut section length +AXLE_TIP_LEN = 3.00; // mm tip / shoulder +AXLE_TOTAL = 65.50; // mm total protrusion from hub face +BEARING_SEAT_OD = 37.80; // mm hub centre collar OD + +TIRE_OD = 254.0; // mm 10" × 25.4 +TIRE_WIDTH = 54.0; // mm 2.125" × 25.4 +AXLE_CL_HEIGHT = TIRE_OD / 2; // 127 mm — axle centre above ground + +// ============================================================================= +// PLATE PARAMETERS +// ============================================================================= + +WHEELBASE = 600.0; // mm axle C/L to axle C/L +PLATE_DEPTH = 220.0; // mm front-to-rear +PLATE_OVERHANG = 40.0; // mm plate extends past axle C/L on each side +PLATE_THICK = 6.0; // mm stock thickness (6 mm Al / 8 mm acrylic) + +// Fork (open-ended slot in plate edge) +// Width matched to base-section diameter + 0.4 mm running clearance +FORK_W = AXLE_BASE_DIA + 0.4; // 16.51 mm +FORK_DEPTH = 50.0; // mm slot depth inward from plate edge + +// Clamp block (two-piece sandwich, bolts through plate) +CLAMP_L = 80.0; // mm along axle axis +CLAMP_H = 60.0; // mm across axle (front-to-back of plate) +CLAMP_THICK = 8.0; // mm each clamp layer — 8 mm Al or 10 mm acrylic +CLAMP_BOLT_D = 5.3; // M5 clearance +CLAMP_BOLT_DX = 22.0; // mm bolt ±X from axle C/L +CLAMP_BOLT_DY = 22.0; // mm bolt ±Y from axle C/L (across plate) +CLAMP_ALIGN_D = 4.1; // Ø4 alignment pin clearance + +// D-cut bore clearance (applied to both diameter and flat chord) +DCUT_CL = 0.3; // mm all-round clearance on D-cut profile + +// FC mount — MAMBA F722S 30.5 × 30.5 mm M3 stack +FC_PITCH = 30.5; +FC_HOLE_D = 3.2; + +// Battery area — 24 V pack footprint (mount holes) +BATT_L = 185.0; +BATT_W = 72.0; + +// Utility +M3 = 3.2; M4 = 4.3; M5 = 5.3; + +// ============================================================================= +// COMPUTED GEOMETRY (do not edit directly) +// ============================================================================= + +// D-cut bore geometry (with clearance): +// r = (AXLE_DCUT_DIA + 2·DCUT_CL) / 2 +// fc = AXLE_DCUT_FLAT + 2·DCUT_CL (chord with clearance on each side) +// d = distance from centre to flat = sqrt(r² – (fc/2)²) +DCUT_R = (AXLE_DCUT_DIA + 2*DCUT_CL) / 2; // 8.275 mm +DCUT_FC = AXLE_DCUT_FLAT + 2*DCUT_CL; // 13.60 mm +// DCUT_D computed inside module (OpenSCAD has no sqrt at module-level constant) + +// Plate outer bounds +PLATE_X_HALF = WHEELBASE/2 + PLATE_OVERHANG; // ± 340 mm + +// ============================================================================= +// RENDER CONTROL +// ============================================================================= + +// Set RENDER to one of: +// "assembly" full 3-D preview (default) +// "plate_2d" 2-D projection of base plate (→ DXF) +// "clamp_lower_2d" 2-D projection of lower clamp (→ DXF) +// "clamp_upper_2d" 2-D projection of upper clamp (→ DXF) +RENDER = "assembly"; + +if (RENDER == "assembly") { + assembly(); +} else if (RENDER == "plate_2d") { + projection(cut=true) translate([0,0,-PLATE_THICK/2]) base_plate(); +} else if (RENDER == "clamp_lower_2d") { + 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(); +} + +// ============================================================================= +// ASSEMBLY +// ============================================================================= + +module assembly() { + color("Silver", 0.85) base_plate(); + + for (side = [-1, 1]) { + // Lower clamp sits on top of base plate, below fork slot level + color("SteelBlue", 0.8) + translate([side * WHEELBASE/2, 0, PLATE_THICK]) + clamp_lower(); + + // Upper clamp stacks on top of lower clamp + color("CornflowerBlue", 0.8) + translate([side * WHEELBASE/2, 0, PLATE_THICK + CLAMP_THICK]) + clamp_upper(); + } + + // Reference ghosts (not for export) + %for (side = [-1, 1]) + color("Orange", 0.25) + translate([side * WHEELBASE/2, 0, 0]) + rotate([0, side * 90, 0]) + axle_ghost(); +} + +// ============================================================================= +// BASE PLATE +// ============================================================================= + +module base_plate() { + difference() { + // ── Outer profile (rounded corners via minkowski) ────────────────── + R = 12; // corner radius + linear_extrude(PLATE_THICK) + minkowski() { + square([2*(PLATE_X_HALF - R), PLATE_DEPTH - 2*R], center=true); + circle(r=R); + } + + // ── Fork slots (open at ±X edges) ───────────────────────────────── + // Slot is FORK_W wide, FORK_DEPTH deep, open at plate edge + for (side = [-1, 1]) { + // Round the slot tip (half-circle end) + union() { + translate([side*(PLATE_X_HALF - FORK_DEPTH), + -FORK_W/2, -1]) + cube([FORK_DEPTH + 1, FORK_W, PLATE_THICK + 2]); + // Semicircular slot bottom + translate([side*(PLATE_X_HALF - FORK_DEPTH), 0, -1]) + cylinder(d=FORK_W, h=PLATE_THICK + 2); + } + } + + // ── Clamp bolt through-holes (4 per side × 2 sides) ──────────────── + for (side = [-1, 1]) + for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX]) + for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY]) + translate([side * WHEELBASE/2 + dx, dy, -1]) + cylinder(d=CLAMP_BOLT_D, h=PLATE_THICK + 2); + + // ── Alignment pin holes (Ø4, 2 per clamp side) ───────────────────── + for (side = [-1, 1]) + for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8]) + translate([side * WHEELBASE/2, dy, -1]) + cylinder(d=CLAMP_ALIGN_D, h=PLATE_THICK + 2); + + // ── FC mount holes (MAMBA F722S 30.5 × 30.5 M3) ──────────────────── + for (x = [-FC_PITCH/2, FC_PITCH/2]) + for (y = [-FC_PITCH/2, FC_PITCH/2]) + translate([x, y, -1]) + cylinder(d=FC_HOLE_D, h=PLATE_THICK + 2); + + // ── Battery tray mount holes (M4 × 4 corners) ────────────────────── + for (x = [-BATT_L/2 + 12, BATT_L/2 - 12]) + for (y = [-BATT_W/2 + 10, BATT_W/2 - 10]) + translate([x, y, -1]) + cylinder(d=M4, h=PLATE_THICK + 2); + + // ── Lightening / cable routing slots (3 centre panels) ───────────── + slot_w = 28; + slot_h = PLATE_DEPTH - 80; + for (x = [-130, 0, 130]) + translate([x - slot_w/2, -slot_h/2, -1]) + // Rounded slot via hull + hull() { + translate([slot_w/2, slot_w/2, 0]) cylinder(d=slot_w, h=PLATE_THICK+2); + translate([slot_w/2, slot_h - slot_w/2, 0]) cylinder(d=slot_w, h=PLATE_THICK+2); + } + + // ── Bearing seat relief (36mm slot lets hub collar clear plate edge) ─ + // Prevents Ø37.8mm bearing seat from binding against plate edge. + for (side = [-1, 1]) + translate([side*PLATE_X_HALF - side*(BEARING_SEAT_OD/2 + 2), + -BEARING_SEAT_OD/2, -1]) + cube([BEARING_SEAT_OD/2 + 3, BEARING_SEAT_OD, PLATE_THICK + 2]); + } +} + +// ============================================================================= +// DROPOUT CLAMP — LOWER (round bore, base-section diameter) +// ============================================================================= +// Sits directly on top of the base plate. +// The 16.11 mm round bore captures the base axle section. +// The fork slot in the base plate is reproduced here to allow the axle to +// slide in from the side. + +module clamp_lower() { + difference() { + // Body + 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); + } + + // Round bore — base axle diameter + clearance + translate([0, 0, -1]) + cylinder(d = AXLE_BASE_DIA + 0.4, h = CLAMP_THICK + 2); + + // Open entry slot (matches base plate fork slot — allows slide-in assembly) + translate([-CLAMP_L/2 - 1, -FORK_W/2, -1]) + cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]); + + // Clamp bolt holes + for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX]) + for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY]) + translate([dx, dy, -1]) + cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2); + + // Alignment pin holes + for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8]) + translate([0, dy, -1]) + cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2); + } +} + +// ============================================================================= +// DROPOUT CLAMP — UPPER (D-cut bore, anti-rotation) +// ============================================================================= +// Stacks on top of lower clamp. +// D-cut bore matches the caliper-verified profile: +// Ø 15.95 mm round OD, 13.00 mm flat chord +// Clearance DCUT_CL applied all-round. +// The flat is oriented toward +Y (front of robot) — rotate clamp at assembly +// to match actual flat position on your axles. + +module clamp_upper() { + dcut_r = DCUT_R; + dcut_fc = DCUT_FC; + // Distance from bore CL to flat (chord geometry) + dcut_d = sqrt(pow(dcut_r, 2) - pow(dcut_fc/2, 2)); + + difference() { + // Body (same footprint as lower clamp) + 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); + } + + // D-cut bore: + // 1. Full round circle of radius dcut_r + // 2. Intersect with a box that removes the top (y > dcut_d) + // Net result: D-shape with flat at +Y = dcut_d + translate([0, 0, -1]) + linear_extrude(CLAMP_THICK + 2) + dcut_profile_2d(dcut_r, dcut_d); + + // Open entry slot (same as lower clamp) + translate([-CLAMP_L/2 - 1, -FORK_W/2, -1]) + cube([CLAMP_L/2 + 1, FORK_W, CLAMP_THICK + 2]); + + // Clamp bolt holes + for (dx = [-CLAMP_BOLT_DX, CLAMP_BOLT_DX]) + for (dy = [-CLAMP_BOLT_DY, CLAMP_BOLT_DY]) + translate([dx, dy, -1]) + cylinder(d=CLAMP_BOLT_D, h=CLAMP_THICK + 2); + + // Alignment pin holes + for (dy = [-CLAMP_BOLT_DY + 8, CLAMP_BOLT_DY - 8]) + translate([0, dy, -1]) + cylinder(d=CLAMP_ALIGN_D, h=CLAMP_THICK + 2); + + // Label emboss (orientation marker — "D-CUT" + flat side arrow) + translate([-12, dcut_d + 1, CLAMP_THICK - 0.8]) + linear_extrude(1) + text("D", size=6, font="Liberation Sans:style=Bold", halign="center"); + // Arrow indicating flat direction + translate([8, dcut_d - 1, CLAMP_THICK - 0.8]) + linear_extrude(1) + polygon([[0,0],[4,-3],[4,3]]); + } +} + +// ── 2-D D-cut profile helper ────────────────────────────────────────────────── +// r = bore radius (with clearance already applied) +// flat_d = distance from bore CL to flat (computed from chord geometry) +module dcut_profile_2d(r, flat_d) { + intersection() { + circle(r=r); + // Keep everything from y = -(r+1) up to y = flat_d + translate([-r - 1, -r - 1]) + square([2*(r + 1), r + 1 + flat_d]); + } +} + +// ============================================================================= +// AXLE GHOST (for assembly visualisation) +// ============================================================================= + +module axle_ghost() { + // Bearing seat collar + cylinder(d=BEARING_SEAT_OD, h=12); + // Base zone — round + translate([0, 0, 12]) + cylinder(d=AXLE_BASE_DIA, h=AXLE_BASE_LEN); + // D-cut zone (approximate cylinder for ghost) + translate([0, 0, 12 + AXLE_BASE_LEN]) + cylinder(d=AXLE_DCUT_DIA, h=AXLE_DCUT_LEN); + // Tip + translate([0, 0, 12 + AXLE_BASE_LEN + AXLE_DCUT_LEN]) + cylinder(d=10, h=AXLE_TIP_LEN); +} + +// ============================================================================= +// DXF / FLAT-PATTERN EXPORT GUIDE +// ============================================================================= +// +// PART 1 — Base plate +// openscad prototype_baseplate.scad \ +// -D 'RENDER="plate_2d"' \ +// -o baseplate_plate.dxf +// +// PART 2 — Lower clamp (× 2, one per side) +// openscad prototype_baseplate.scad \ +// -D 'RENDER="clamp_lower_2d"' \ +// -o baseplate_clamp_lower.dxf +// +// PART 3 — Upper clamp (× 2, one per side) +// openscad prototype_baseplate.scad \ +// -D 'RENDER="clamp_upper_2d"' \ +// -o baseplate_clamp_upper.dxf +// +// MATERIAL NOTES +// Base plate: 6 mm 5052-H32 aluminium (preferred) +// 8 mm clear acrylic (quick prototype) +// Clamp blocks: 8 mm 6061-T6 aluminium (preferred — tighter bore tolerance) +// 10 mm PETG FDM (proto only — pre-drill bolt holes) +// +// LASER PARAMETERS (6 mm Al, fibre laser) +// Power: 3 kW | Speed: 1800 mm/min | Assist: N2 +// Min bore dia: 6 mm (M5 holes OK) +// +// DIMENSIONAL NOTES +// Fork slot width (FORK_W): 16.51 mm — verify on actual axle before cut +// D-cut flat clearance (DCUT_CL): 0.3 mm — adjust if axle spins in clamp +// Bearing seat relief: check collar actually clears plate edge before tightening +// =============================================================================