// ============================================================ // realsense_mount.scad — RealSense D435i Bracket Rev A // Agent: sl-mechanical 2026-02-28 // ============================================================ // Single-piece bracket. Bolts to sensor_head platform front // face via 2× M4 bolts. Holds D435i at 10° nose-down tilt. // // RealSense D435i specs used: // Body: 90 × 25 × 25 mm (W × H × D) // Mount: 1/4-20 UNC female (bottom centre) // // Print orientation: flat base face on build plate — no supports. // // RENDER options: // "bracket" print-ready single piece (default) // "assembly" bracket + camera outline // ============================================================ RENDER = "bracket"; // ── Camera body ────────────────────────────────────────────── CAM_W = 90.0; // camera width CAM_H = 25.0; // camera height CAM_D = 25.0; // camera depth // ── Bracket geometry ───────────────────────────────────────── BASE_W = 40.0; // base plate width (Y direction) BASE_D = 20.0; // base plate depth (X direction) BASE_H = 8.0; // base plate thickness (Z direction) ARM_W = 24.0; // arm width ARM_H = 8.0; // arm thickness ARM_LEN = 75.0; // arm length (X direction from base edge) FACE_W = 30.0; // camera face plate width FACE_D = 8.0; // face plate thickness (holds camera) TILT = 10.0; // nose-down tilt (degrees) // ── Fasteners ──────────────────────────────────────────────── M4_D = 4.5; // M4 clearance hole M4_DY = 18.0; // half-spacing of base attachment holes // ← must match sensor_head ARM_DY_RS // 1/4-20 UNC: tap drill ≈ 5.5 mm. // We print a nut pocket for a 1/4-20 hex nut captured in the face. NUT1420_AF = 11.1; // 1/4-20 hex nut across-flats (7/16") NUT1420_H = 5.6; // 1/4-20 hex nut thickness (7/32") NUT1420_BORE= 6.5; // 1/4-20 bolt clearance through face NUT_POCKET_EXTRA = 0.4; // print clearance on nut pocket $fn = 64; e = 0.01; // ───────────────────────────────────────────────────────────── module realsense_bracket() { union() { // ── Base plate (attaches to platform top) ──────────── difference() { translate([-BASE_D, -BASE_W/2, 0]) cube([BASE_D, BASE_W, BASE_H]); // 2× M4 holes through base, ±ARM_DY_RS for (dy = [-M4_DY, M4_DY]) translate([-BASE_D/2, dy, -e]) cylinder(d = M4_D, h = BASE_H + 2*e); } // ── Arm extending in +X direction ──────────────────── difference() { hull() { translate([0, -ARM_W/2, 0]) cube([e, ARM_W, ARM_H]); translate([ARM_LEN,-ARM_W/2, 0]) cube([e, ARM_W, ARM_H]); } // No internal cuts here — arm is solid for rigidity } // ── Camera face plate at arm tip, tilted TILT° down ── translate([ARM_LEN, 0, ARM_H/2]) rotate([0, TILT, 0]) translate([0, 0, -ARM_H/2]) difference() { translate([0, -FACE_W/2, 0]) cube([FACE_D, FACE_W, CAM_H + 6]); // 1/4-20 hex nut pocket (captured, opens toward +X) translate([FACE_D - NUT1420_H, 0, (CAM_H + 6)/2]) rotate([0, 90, 0]) cylinder(d = (NUT1420_AF + NUT_POCKET_EXTRA) / cos(30), h = NUT1420_H + e, $fn = 6); // 1/4-20 bore through full face depth translate([-e, 0, (CAM_H + 6)/2]) rotate([0, 90, 0]) cylinder(d = NUT1420_BORE, h = FACE_D + 2*e); } } } // ───────────────────────────────────────────────────────────── // Render selector // ───────────────────────────────────────────────────────────── if (RENDER == "bracket") { realsense_bracket(); } else if (RENDER == "assembly") { color("LightGray", 0.9) realsense_bracket(); // Camera body outline translate([ARM_LEN, 0, ARM_H/2]) rotate([0, TILT, 0]) translate([FACE_D, -CAM_W/2, -(CAM_H/2 + 3)]) color("DimGray", 0.6) cube([CAM_D, CAM_W, CAM_H]); }