saltylab-firmware/chassis/realsense_mount.scad
sl-mechanical 23f2daa3cd feat: sensor head mounts — stem collar, RPLIDAR, RealSense, 4× IMX219
Part of Phase 2 sensor mount designs for SaltyBot 25 mm mast.

Files added:
  chassis/sensor_head.scad        — split collar (25 mm OD stem) + octagonal platform
  chassis/rplidar_mount.scad      — anti-vibration ring for RPLIDAR A1M8 (Ø58 mm BC)
  chassis/realsense_mount.scad    — RealSense D435i arm bracket, 10° tilt, 1/4-20 nut
  chassis/imx219_mount.scad       — 4× IMX219 radial arms, 10° tilt, CSI ribbon slot
  chassis/sensor_head_assembly.md — assembly diagram + fastener BOM + print settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-28 22:53:18 -05:00

115 lines
5.2 KiB
OpenSCAD
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================
// 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]);
}