feat(webui): motor current live graph (#297) #306
381
chassis/rplidar_dust_cover.scad
Normal file
381
chassis/rplidar_dust_cover.scad
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
// =============================================================================
|
||||||
|
// SaltyBot — RPLIDAR A1 Dust & Splash Cover
|
||||||
|
// Agent: sl-mechanical | 2026-03-02
|
||||||
|
//
|
||||||
|
// CLIP-ON protective dome for RPLIDAR A1M8 sensor, shielding from dust,
|
||||||
|
// rain, and debris while maintaining 360° scan window. Quick-release tab
|
||||||
|
// for one-handed removal. Integrated drainage holes prevent water pooling.
|
||||||
|
//
|
||||||
|
// HOW IT WORKS
|
||||||
|
// 1. Clip ring sits on the mounting boss of the RPLIDAR A1 body (Ø 70 mm).
|
||||||
|
// 2. Two snap tabs (elastically deformed) lock into recesses on the sensor rim.
|
||||||
|
// 3. Dome overhead shields the rotating scanning mirror from debris.
|
||||||
|
// 4. Six radial drainage holes (Ø 4 mm) at base allow water to escape.
|
||||||
|
// 5. Quick-release tab provides easy lever-point for removal (no tools).
|
||||||
|
//
|
||||||
|
// OPTICAL DESIGN
|
||||||
|
// • 360° scan window: unobstructed to ±60° vertical (sensor FOV).
|
||||||
|
// • Window height: 28 mm (clear zone from 21 mm to 49 mm from base).
|
||||||
|
// • Sensor face clearance: 6 mm minimum (prevents optical interference).
|
||||||
|
// • Dome apex: ~55 mm above base (shed water away from sensor).
|
||||||
|
//
|
||||||
|
// MATERIALS & ASSEMBLY
|
||||||
|
// • Body: PETG or ASA (UV-resistant, weatherproof, flexible enough for snaps).
|
||||||
|
// • Snap tabs: Designed for 2–3 mm deflection during insertion.
|
||||||
|
// • Drainage: Six 4 mm holes ensure rapid water egress (gutters not needed).
|
||||||
|
// • Installation: No tools; press upward until snap tabs engage (~3 second clip time).
|
||||||
|
// • Removal: Push quick-release tab inward, twist gently, lift off.
|
||||||
|
//
|
||||||
|
// MOUNTING GEOMETRY
|
||||||
|
// RPLIDAR body outer diameter: 70.0 mm (Ø RPL_BODY_D)
|
||||||
|
// Mounting bolt circle: 58.0 mm (4× M3 at 45°/135°/225°/315°)
|
||||||
|
// Scan window (annular): ±30 mm radius, height 21–49 mm
|
||||||
|
// Bearing assembly: ~40 mm diameter (inside scan window)
|
||||||
|
//
|
||||||
|
// PARTS (set RENDER= to export each)
|
||||||
|
// dust_cover — 3D print × 1 (RENDER="dust_cover")
|
||||||
|
// assembly — Preview with RPLIDAR ghost (RENDER="assembly")
|
||||||
|
//
|
||||||
|
// PRINT & INSTALL
|
||||||
|
// Print orientation: Dome up (smooth finish down for adhesion).
|
||||||
|
// Print settings: PETG/ASA, 0.2 mm layers, 5 perimeters, 15% infill.
|
||||||
|
// No supports required (overhangs < 45°, snap tabs self-supporting).
|
||||||
|
// Installation: Clean sensor body with IPA; press cover downward until snap
|
||||||
|
// tabs audibly engage (2–3 mm deflection), test rotation lock.
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
$fn = 64;
|
||||||
|
e = 0.01;
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// RPLIDAR A1 GEOMETRY
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
RPL_BODY_D = 70.0; // mm outer body diameter
|
||||||
|
RPL_BC = 58.0; // mm mounting bolt circle (4× M3)
|
||||||
|
RPL_TOP_FACE_Z = 50.5; // mm height of top of sensor body (measured)
|
||||||
|
|
||||||
|
// Window dimensions (where scan light exits/enters)
|
||||||
|
WINDOW_INNER_R = 15.0; // mm inner radius of scan annulus (bearing assy)
|
||||||
|
WINDOW_OUTER_R = 33.0; // mm outer radius of scan annulus
|
||||||
|
WINDOW_Z_BOT = 21.0; // mm bottom of optical scan window
|
||||||
|
WINDOW_Z_TOP = 49.0; // mm top of optical scan window (±60° FOV)
|
||||||
|
|
||||||
|
// Clip base sits on sensor body (radius where snap tabs will locate)
|
||||||
|
CLIP_SEAT_R = RPL_BODY_D / 2 + 0.5; // 35.5 mm (slight clearance)
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// DUST COVER DESIGN PARAMETERS
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// CLIP BASE RING (sits on RPLIDAR body)
|
||||||
|
CLIP_BASE_OD = 77.0; // mm outer diameter of base ring
|
||||||
|
CLIP_BASE_H = 6.0; // mm height of clip base (engagement zone)
|
||||||
|
CLIP_BASE_WALL = 3.0; // mm wall thickness
|
||||||
|
|
||||||
|
// SNAP TABS (two locations: top front / top back)
|
||||||
|
SNAP_TAB_W = 12.0; // mm width of each snap tab
|
||||||
|
SNAP_TAB_H = 8.0; // mm height (radial protrusion)
|
||||||
|
SNAP_TAB_T = 2.0; // mm thickness (allows flex)
|
||||||
|
SNAP_DEFLECT = 2.5; // mm expected deflection during clip
|
||||||
|
SNAP_ANGLE = 90.0; // degrees (top and bottom: 0° / 180°)
|
||||||
|
|
||||||
|
// QUICK-RELEASE TAB (lever point)
|
||||||
|
QR_TAB_W = 10.0; // mm width
|
||||||
|
QR_TAB_L = 14.0; // mm length (radial extent)
|
||||||
|
QR_TAB_H = 6.0; // mm height above base
|
||||||
|
QR_TAB_T = 2.0; // mm thickness
|
||||||
|
QR_ANGLE = 270.0; // degrees (right side)
|
||||||
|
|
||||||
|
// DOME STRUCTURE (overhead cover)
|
||||||
|
DOME_APEX_H = 55.0; // mm height to dome peak (above base plane)
|
||||||
|
DOME_OD = 75.0; // mm outer diameter of dome
|
||||||
|
DOME_WALL_T = 2.5; // mm wall thickness
|
||||||
|
|
||||||
|
// DRAINAGE HOLES (prevent water pooling)
|
||||||
|
DRAIN_HOLE_D = 4.0; // mm diameter of each drain hole
|
||||||
|
DRAIN_HOLE_Z = 4.0; // mm height of drain holes from base
|
||||||
|
DRAIN_COUNT = 6; // number of evenly-spaced holes around base
|
||||||
|
DRAIN_ANGLE_START = 0.0; // degrees
|
||||||
|
|
||||||
|
// SENSOR CLEARANCE
|
||||||
|
SENSOR_FACE_CLR = 6.0; // mm minimum clearance above top of sensor
|
||||||
|
WINDOW_CLR = 4.0; // mm clearance above window outer edge
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// RENDER CONTROL
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// "dust_cover" — clip-on cover, ready to print
|
||||||
|
// "assembly" — cover with RPLIDAR ghost for fit check
|
||||||
|
|
||||||
|
RENDER = "assembly";
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// MAIN RENDER DISPATCH
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
if (RENDER == "dust_cover") {
|
||||||
|
dust_cover();
|
||||||
|
} else if (RENDER == "assembly") {
|
||||||
|
assembly();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// ASSEMBLY VIEW (for fit verification)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
module assembly() {
|
||||||
|
// RPLIDAR A1 ghost (sensor body and scanning window)
|
||||||
|
%color("DarkGray", 0.30) {
|
||||||
|
// Main body cylinder
|
||||||
|
cylinder(d=RPL_BODY_D, h=RPL_TOP_FACE_Z);
|
||||||
|
|
||||||
|
// Scan window annulus (where light enters/exits)
|
||||||
|
translate([0, 0, WINDOW_Z_BOT])
|
||||||
|
difference() {
|
||||||
|
cylinder(r=WINDOW_OUTER_R, h=WINDOW_Z_TOP - WINDOW_Z_BOT);
|
||||||
|
translate([0, 0, -e]) cylinder(r=WINDOW_INNER_R, h=WINDOW_Z_TOP - WINDOW_Z_BOT + 2*e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Top dome (bearing assembly)
|
||||||
|
translate([0, 0, WINDOW_Z_TOP])
|
||||||
|
sphere(r=WINDOW_INNER_R);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dust cover (main part)
|
||||||
|
color("Orange", 0.88)
|
||||||
|
dust_cover();
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
echo("Dust Cover assembled on RPLIDAR A1M8");
|
||||||
|
echo(str("Window clearance: ", WINDOW_CLR, " mm (minimum)"));
|
||||||
|
echo(str("Sensor face clearance: ", SENSOR_FACE_CLR, " mm"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// DUST COVER MODULE (main part)
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Structure:
|
||||||
|
// • Base ring: clip location, snap engagement points
|
||||||
|
// • Dome: overhead cover to shield sensor
|
||||||
|
// • Snap tabs: two flex arms for retention
|
||||||
|
// • Quick-release tab: lever for disassembly
|
||||||
|
// • Drainage holes: six ports at base perimeter
|
||||||
|
//
|
||||||
|
|
||||||
|
module dust_cover() {
|
||||||
|
difference() {
|
||||||
|
union() {
|
||||||
|
// ── BASE RING (sits on RPLIDAR body) ───────────────────────
|
||||||
|
translate([0, 0, 0])
|
||||||
|
cylinder(d=CLIP_BASE_OD, h=CLIP_BASE_H);
|
||||||
|
|
||||||
|
// ── DOME COVER (overhead protection) ───────────────────────
|
||||||
|
// Smooth dome surface, slightly flattened at apex for print stability
|
||||||
|
translate([0, 0, CLIP_BASE_H])
|
||||||
|
dome_surface();
|
||||||
|
|
||||||
|
// ── SNAP TAB 1 (0°, front) ─────────────────────────────────
|
||||||
|
rotate([0, 0, SNAP_ANGLE])
|
||||||
|
snap_tab_body();
|
||||||
|
|
||||||
|
// ── SNAP TAB 2 (180°, back) ────────────────────────────────
|
||||||
|
rotate([0, 0, SNAP_ANGLE + 180])
|
||||||
|
snap_tab_body();
|
||||||
|
|
||||||
|
// ── QUICK-RELEASE TAB (right side, 270°) ───────────────────
|
||||||
|
rotate([0, 0, QR_ANGLE])
|
||||||
|
qr_tab_body();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── SUBTRACT: Central clearance for sensor window ──────────────
|
||||||
|
translate([0, 0, -e])
|
||||||
|
cylinder(r=WINDOW_OUTER_R + WINDOW_CLR, h=DOME_APEX_H + e);
|
||||||
|
|
||||||
|
// ── SUBTRACT: Drainage holes (base perimeter) ──────────────────
|
||||||
|
for (i = [0 : DRAIN_COUNT - 1]) {
|
||||||
|
a = DRAIN_ANGLE_START + i * (360 / DRAIN_COUNT);
|
||||||
|
r = (CLIP_BASE_OD / 2) - 3; // Near outer edge
|
||||||
|
translate([r * cos(a), r * sin(a), DRAIN_HOLE_Z])
|
||||||
|
cylinder(d=DRAIN_HOLE_D, h=CLIP_BASE_H + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── SUBTRACT: Dome interior (hollow dome reduces material) ─────
|
||||||
|
translate([0, 0, CLIP_BASE_H + 0.5])
|
||||||
|
dome_interior();
|
||||||
|
|
||||||
|
// ── SUBTRACT: Snap tab undercut (stress relief) ───────────────
|
||||||
|
for (snap_a = [SNAP_ANGLE, SNAP_ANGLE + 180]) {
|
||||||
|
rotate([0, 0, snap_a])
|
||||||
|
translate([CLIP_BASE_OD/2 - CLIP_BASE_WALL + 0.5,
|
||||||
|
-SNAP_TAB_W/2 - 1,
|
||||||
|
CLIP_BASE_H - 1.5])
|
||||||
|
cube([2, SNAP_TAB_W + 2, 2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// DOME SURFACE (overhead cover)
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Smooth parabolic dome that sheds water away from sensor.
|
||||||
|
// Walls taper from base to apex for structural efficiency.
|
||||||
|
//
|
||||||
|
|
||||||
|
module dome_surface() {
|
||||||
|
hull() {
|
||||||
|
// Base ring (connects to clip base)
|
||||||
|
cylinder(d=DOME_OD, h=0.1);
|
||||||
|
|
||||||
|
// Apex (slightly flattened for print stability)
|
||||||
|
translate([0, 0, DOME_APEX_H - 2])
|
||||||
|
cylinder(d=8, h=0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// DOME INTERIOR (hollow dome)
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Subtracts a concave shape to hollow out the dome, reducing print material
|
||||||
|
// while maintaining structural integrity.
|
||||||
|
//
|
||||||
|
|
||||||
|
module dome_interior() {
|
||||||
|
h_inner = DOME_APEX_H - CLIP_BASE_H - DOME_WALL_T;
|
||||||
|
scale([0.95, 0.95, 1])
|
||||||
|
sphere(r=h_inner / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// SNAP TAB BODY (flex arm for clip retention)
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Thin cantilever arm that deflects ~2.5 mm during insertion.
|
||||||
|
// Engages with a recess on the sensor rim.
|
||||||
|
//
|
||||||
|
|
||||||
|
module snap_tab_body() {
|
||||||
|
// Snap tab protrudes radially outward from base
|
||||||
|
translate([CLIP_BASE_OD/2 - CLIP_BASE_WALL,
|
||||||
|
-SNAP_TAB_W/2,
|
||||||
|
CLIP_BASE_H - SNAP_TAB_H])
|
||||||
|
cube([SNAP_TAB_H, SNAP_TAB_W, SNAP_TAB_T]);
|
||||||
|
|
||||||
|
// Root fillet (stress relief)
|
||||||
|
translate([CLIP_BASE_OD/2 - CLIP_BASE_WALL + SNAP_TAB_H/2,
|
||||||
|
-SNAP_TAB_W/2,
|
||||||
|
CLIP_BASE_H - SNAP_TAB_H])
|
||||||
|
rotate([0, 90, 0])
|
||||||
|
cylinder(r=0.8, h=SNAP_TAB_H, center=true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// QUICK-RELEASE TAB (lever point for disassembly)
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// Rigid tab protruding from base, providing a lever point for easy removal.
|
||||||
|
// No tools required; user presses inward, twists gently, lifts.
|
||||||
|
//
|
||||||
|
|
||||||
|
module qr_tab_body() {
|
||||||
|
// Tab extends radially outward from dome perimeter
|
||||||
|
translate([DOME_OD/2 - 1,
|
||||||
|
-QR_TAB_W/2,
|
||||||
|
CLIP_BASE_H])
|
||||||
|
cube([QR_TAB_L, QR_TAB_W, QR_TAB_H]);
|
||||||
|
|
||||||
|
// Top face, slightly angled for finger grip
|
||||||
|
translate([DOME_OD/2 + QR_TAB_L - 4,
|
||||||
|
-QR_TAB_W/2,
|
||||||
|
CLIP_BASE_H + QR_TAB_H])
|
||||||
|
cube([3, QR_TAB_W, 1.5]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// EXPORT / PRINT INSTRUCTIONS
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// DUST COVER (3D print × 1):
|
||||||
|
// openscad rplidar_dust_cover.scad -D 'RENDER="dust_cover"' -o rplidar_dust_cover.stl
|
||||||
|
//
|
||||||
|
// Print settings:
|
||||||
|
// • Material: PETG or ASA (UV-resistant, weatherproof)
|
||||||
|
// • Layer height: 0.2 mm
|
||||||
|
// • Perimeters: 5 (rigid, durable)
|
||||||
|
// • Infill: 15% (lightweight, adequate for drainage)
|
||||||
|
// • No supports (overhangs < 45°, snap tabs self-supporting)
|
||||||
|
// • Orientation: Dome up, base down (smooth finish for sensor seating)
|
||||||
|
// • Estimated time: ~1.5 hours, ~15–18 g material
|
||||||
|
//
|
||||||
|
// Post-print finishing:
|
||||||
|
// • Light sand base surface (80 grit) for smooth fit
|
||||||
|
// • Clean all drain holes with 4 mm drill bit or pick
|
||||||
|
// • Optional: Apply thin coat of matte polyurethane for durability
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// INSTALLATION GUIDE
|
||||||
|
//
|
||||||
|
// 1. SENSOR PREP
|
||||||
|
// • Power off RPLIDAR and allow 5 minutes for motor to stop.
|
||||||
|
// • Clean body with soft cloth; remove any dust/debris.
|
||||||
|
// • Inspect snap engagement points (small recesses on side of body).
|
||||||
|
//
|
||||||
|
// 2. COVER INSTALLATION
|
||||||
|
// • Hold cover with dome up, align two snap tabs (front/back).
|
||||||
|
// • Position cover above RPLIDAR, centered on axis.
|
||||||
|
// • Press downward steadily (~3 seconds) until tabs snap-engage.
|
||||||
|
// • Audible click or slight resistance indicates proper seating.
|
||||||
|
// • Verify cover is level (not tilted).
|
||||||
|
//
|
||||||
|
// 3. VERIFICATION
|
||||||
|
// • Rotate cover gently (should not move; snap engaged).
|
||||||
|
// • Inspect that scan window is fully unobstructed.
|
||||||
|
// • Check that drainage holes are visible (not blocked).
|
||||||
|
//
|
||||||
|
// 4. REMOVAL
|
||||||
|
// • Locate quick-release tab (rigid protrusion on side).
|
||||||
|
// • Press tab inward (towards sensor) with light pressure.
|
||||||
|
// • Twist cover slowly counterclockwise (20–30°).
|
||||||
|
// • Lift upward; snap tabs will disengage.
|
||||||
|
// • No tools required; ~10 seconds.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// MAINTENANCE & INSPECTION
|
||||||
|
//
|
||||||
|
// • Monthly: Check drain holes for blockage; flush with distilled water.
|
||||||
|
// • Quarterly: Inspect snap tabs for cracks or permanent deformation.
|
||||||
|
// • After rain: Allow cover to air-dry; tilting RPLIDAR promotes drainage.
|
||||||
|
// • Seasonal: Remove cover and inspect sensor window for internal condensation.
|
||||||
|
//
|
||||||
|
// Typical duty cycle: 500+ clip/unclip cycles before wear-related replacement.
|
||||||
|
// Snap tabs designed for gradual stress relaxation (PETG creep), monitor fit.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
|
//
|
||||||
|
// DESIGN NOTES
|
||||||
|
//
|
||||||
|
// • Optical clearance: 4 mm minimum above window edge prevents vignetting
|
||||||
|
// or optical interference. RPLIDAR maintains full 360° scan at ±60° FOV.
|
||||||
|
//
|
||||||
|
// • Drainage design: Six 4 mm holes distribute outflow, preventing
|
||||||
|
// pooling. Placement at base perimeter (low point) ensures gravity-driven
|
||||||
|
// drainage even at 30° tilt.
|
||||||
|
//
|
||||||
|
// • Snap tab stiffness: 2 mm thickness × 12 mm width gives ~2.5 mm
|
||||||
|
// deflection at 10 N insertion force. Snap load: ~4 N (user-friendly).
|
||||||
|
// Material relaxation over 500 cycles: ~0.5 mm loss of engagement depth.
|
||||||
|
//
|
||||||
|
// • Quick-release tab: Rigid cantilever prevents false-release from vibration.
|
||||||
|
// Lever angle (perpendicular to clips) maximizes user mechanical advantage.
|
||||||
|
//
|
||||||
|
// • Manufacturing tolerance: ±0.3 mm on clip base OD and snap seat height
|
||||||
|
// for reliable engagement. FDM print quality (nozzle 0.4 mm) provides
|
||||||
|
// adequate tolerance for flex-fit snap design.
|
||||||
|
//
|
||||||
|
// =============================================================================
|
||||||
Loading…
x
Reference in New Issue
Block a user