// ============================================================ // rover_motor_mount.scad — SaltyRover Drive Motor Brackets // Rev A 2026-03-01 sl-mechanical // ============================================================ // L-bracket that bolts to the deck edge and positions the drive // motor axle at the correct height. Print or CNC 4×. // // Default values from BOM.md (caliper-verified hoverboard motor): // Axle base OD: 16.11 mm // D-cut OD: 15.95 mm (flat chord 13.00 mm) // Bearing seat OD: 37.80 mm // Axle CL above gnd: 127 mm // Tire OD: 254 mm (10×2.125") // // Bracket geometry (all dims in mm): // Vertical flange — bolts to deck edge (2× M5 SHCS) // Horizontal arm — extends BRKT_REACH beyond deck edge // to position axle CL at TRACK_W/2 // Axle channel — open-bottom dropout slot for easy // motor install/removal; retained by // a separate clamping plate (×1 per bracket) // Bearing recess — 37.8 mm recess on inboard face // // ⚠ VERIFY before printing / CNC: // AXLE_D, AXLE_FLAT, BEARING_OD from caliper measurement. // DECK_BOT_H = GND_CLR + BATT_FLOOR_T + BATT_PACK_H. // Adjust BRKT_REACH so TRACK_W matches chassis layout. // // Print orientation: flange face flat on bed. // Material: PETG or PC, 5 perims, 60% infill. // Alternative: CNC-routed 10mm 6061-T6 aluminium plate. // // RENDER options: // "assembly" bracket + clamp plate + phantom motor axle // "bracket" main L-bracket for printing/CNC // "clamp_plate" axle retention clamp plate (print 4×) // "bracket_2d" bracket floor projection → DXF // ============================================================ RENDER = "assembly"; // ── Axle / motor (BOM.md caliper-verified) ──────────────── AXLE_D = 16.11; // axle base section OD (round) AXLE_FLAT = 13.00; // D-cut flat chord width AXLE_D_DCUT = 15.95; // D-cut section OD BEARING_OD = 37.80; // bearing seat collar OD BEARING_D = BEARING_OD + 1.0; // bore clearance for bearing seat BEARING_H = 8.0; // bearing recess depth on inboard face AXLE_H = 127.0; // axle CL above ground TIRE_OD = 254.0; // 10×2.125" tire outer diameter // Dropout slot dims DROP_W = AXLE_D + 2.0; // slot width (axle + 1 mm each side) DROP_D = AXLE_H; // slot depth from bracket bottom (full height) // ── Bracket geometry ───────────────────────────────────── // Deck geometry (must match saltyrover_chassis.scad) GND_CLR = 50.0; BATT_FLOOR_T = 3.0; BATT_PACK_H = 56.0; DECK_T = 8.0; DECK_BOT_H = GND_CLR + BATT_FLOOR_T + BATT_PACK_H; // 109 mm DECK_TOP_H = DECK_BOT_H + DECK_T; // 117 mm // Axle height relative to deck top: AXLE_ABOVE_DECK = AXLE_H - DECK_TOP_H; // ~10 mm // Bracket reach beyond deck edge to motor axle CL BRKT_REACH = 40.0; // motor CL is BRKT_REACH mm outside deck edge // (TRACK_W/2 - ROVER_W/2 = 270 - 240 = 30 mm + // bearing housing clearance margin = 40 mm) // Bracket plate dimensions BRKT_T = 10.0; // bracket plate thickness BRKT_H_ABOVE = AXLE_ABOVE_DECK + BEARING_OD/2 + 8.0; // above deck top BRKT_H_BELOW = DECK_T + 12.0; // below deck bottom BRKT_TOTAL_H = BRKT_H_ABOVE + BRKT_H_BELOW; // full height // Width of bracket arm (fore-aft direction) BRKT_W = 60.0; // covers motor fore-aft attachment bolts // Flange for deck attachment FLANGE_T = 8.0; // flange plate thickness FLANGE_DEPTH = 20.0; // how deep flange sits on deck face (Y direction) // M5 bolt holes: 2× through flange (deck attachment) M5_D = 5.3; MOT_BOLT_SPC = 30.0; // matches saltyrover_chassis.scad MOT_BOLT_SPC // Clamping plate (retains axle in dropout slot) CLAMP_T = 6.0; // clamp plate thickness CLAMP_W = DROP_W + 12.0; CLAMP_H = BEARING_D + 12.0; CLAMP_BOLT_D= 4.3; // M4 clearance CLAMP_BOLT_SPC = CLAMP_W - 10.0; // Gusset (triangular fillet between flange and arm) GUSSET_T = 8.0; $fn = 64; e = 0.01; // ───────────────────────────────────────────────────────── // motor_bracket() // Main L-bracket. Coordinate: Z=0 at deck top. // Bracket outboard face at X=0 (deck edge). // Bracket arm extends +X toward motor. // ───────────────────────────────────────────────────────── module motor_bracket() { axle_z = AXLE_ABOVE_DECK; // axle CL in bracket coords difference() { union() { // ── Vertical arm (extends +X from deck edge) ── translate([0, -BRKT_W/2, -BRKT_H_BELOW]) cube([BRKT_REACH + BRKT_T, BRKT_W, BRKT_TOTAL_H]); // ── Vertical flange (sits against deck edge, -X side) ── translate([-FLANGE_DEPTH, -BRKT_W/2, -BRKT_H_BELOW]) cube([FLANGE_DEPTH, BRKT_W, BRKT_TOTAL_H]); // ── Gusset (arm to flange transition) ── translate([0, -BRKT_W/2, axle_z - GUSSET_T/2]) linear_extrude(GUSSET_T) polygon([ [0, 0], [BRKT_REACH/2, 0], [0, BRKT_W] ]); } // ── Axle dropout slot (open at bottom, centered on arm tip) ── translate([BRKT_REACH, -DROP_W/2, -BRKT_H_BELOW - e]) cube([BRKT_T + e, DROP_W, AXLE_H + 2*e]); // ── Axle round bore at slot top ── translate([BRKT_REACH, 0, axle_z]) rotate([0, 90, 0]) cylinder(d=AXLE_D + 1.0, h=BRKT_T + 2*e); // ── D-cut anti-rotation flat (matches axle flat chord) ── translate([BRKT_REACH - e, -AXLE_FLAT/2, axle_z - AXLE_D/2 - e]) cube([BRKT_T + 2*e, AXLE_FLAT, AXLE_D/2 + e]); // ── Bearing seat recess (inboard face, X=BRKT_T) ── translate([BRKT_REACH + BRKT_T - BEARING_H, 0, axle_z]) rotate([0, 90, 0]) cylinder(d=BEARING_D, h=BEARING_H + e); // ── Clamping plate bolt holes (×2, retain axle) ── for (dz=[-CLAMP_BOLT_SPC/2, CLAMP_BOLT_SPC/2]) translate([BRKT_REACH - e, 0, axle_z + dz]) rotate([0, 90, 0]) cylinder(d=CLAMP_BOLT_D, h=BRKT_T + 2*e); // ── Deck attachment holes through flange (M5 × 2) ── for (bz=[-MOT_BOLT_SPC/2, MOT_BOLT_SPC/2]) translate([-FLANGE_DEPTH - e, 0, bz]) rotate([0, 90, 0]) cylinder(d=M5_D, h=FLANGE_DEPTH + 2*e); // ── Lightening pocket on arm (inboard face) ── translate([BRKT_T, -BRKT_W/2 + 8, -BRKT_H_BELOW/2]) cube([BRKT_REACH - BRKT_T - 8, BRKT_W - 16, BRKT_H_BELOW/2 - 4]); } } // ───────────────────────────────────────────────────────── // axle_clamp_plate() // Bolts to bracket outboard face to close dropout slot. // Print flat face down. 1× per bracket. // ───────────────────────────────────────────────────────── module axle_clamp_plate() { axle_z = AXLE_ABOVE_DECK; difference() { translate([-CLAMP_W/2, 0, axle_z - CLAMP_H/2]) cube([CLAMP_W, CLAMP_T, CLAMP_H]); // Axle bore translate([0, -e, axle_z]) rotate([-90, 0, 0]) cylinder(d=AXLE_D + 0.5, h=CLAMP_T + 2*e); // Bearing seat relief translate([0, CLAMP_T - BEARING_H + e, axle_z]) rotate([-90, 0, 0]) cylinder(d=BEARING_D, h=BEARING_H + e); // M4 bolt holes (×2) for (dz=[-CLAMP_BOLT_SPC/2, CLAMP_BOLT_SPC/2]) translate([0, -e, axle_z + dz]) rotate([-90, 0, 0]) cylinder(d=CLAMP_BOLT_D, h=CLAMP_T + 2*e); } } // ───────────────────────────────────────────────────────── // Render selector // ───────────────────────────────────────────────────────── if (RENDER == "assembly") { color("DimGray", 0.90) motor_bracket(); color("SteelBlue", 0.85) translate([BRKT_REACH + BRKT_T, 0, 0]) axle_clamp_plate(); // Phantom axle stub color("Silver", 0.4) translate([BRKT_REACH, 0, AXLE_ABOVE_DECK]) rotate([0, 90, 0]) cylinder(d=AXLE_D, h=80); // Phantom tire (semi-transparent outline) color("Black", 0.12) translate([BRKT_REACH + 40, 0, AXLE_ABOVE_DECK]) rotate([0, 90, 0]) cylinder(d=TIRE_OD, h=54); // Reference deck edge color("Gold", 0.25) translate([-FLANGE_DEPTH - 20, -BRKT_W/2, -BRKT_H_BELOW]) cube([20, BRKT_W, BRKT_TOTAL_H]); } else if (RENDER == "bracket") { motor_bracket(); } else if (RENDER == "clamp_plate") { // Orient for printing: lay flat, rotate upright translate([0, CLAMP_T, -AXLE_ABOVE_DECK]) rotate([90, 0, 0]) axle_clamp_plate(); } else if (RENDER == "bracket_2d") { projection(cut=true) translate([0, 0, -BRKT_H_BELOW - BRKT_T/2]) motor_bracket(); }