saltylab-firmware/chassis/saltytank_skid_plate.scad
sl-mechanical d93919e26f feat: SaltyTank tracked chassis — drive sprockets, tensioners, skid plate (#121)
Three new chassis design files for the SaltyTank continuous-track variant:

• saltytank_chassis.scad — Deck plate (500×360×8mm Al, DXF export), 2×
  side track frames (6mm Al, CNC/laser), idler tensioner sliding block,
  4× CSI corner camera mounts (45°/20°), D435i front bracket (8° tilt),
  stem collar (Ø25mm shared).  Drive sprocket mounts accept hoverboard hub
  motors with caliper-verified D-cut bore (16.11mm/13mm flat) + 52mm BC
  hub flange bolt pattern.  M6 tensioner bolt adjusts idler ±15mm for
  track tension. Shared FC 30.5×30.5mm + Jetson 58×49mm M3 patterns.
  Electronics bay footprint matches rover_electronics_bay.scad exactly.

• saltytank_skid_plate.scad — Sacrificial underside skid panel (360×500mm).
  4mm HDPE (DXF) or PETG print; countersunk M4 FHCS bolt-on.  4× drain/
  inspection slots; optional printed ribs (RIB_PRINT=true).  Ground
  clearance of hull between tracks: 90mm (exceeds 50mm requirement).

• saltytank_BOM.md — Full BOM: deck plate, side frames, drive sprockets,
  idler wheels + tensioners, road wheels (2/side), track belts (1109mm
  circumference calc), skid plate, sensor brackets, electronics bay
  (rover_electronics_bay.scad reused unchanged). Frame mass ≈ 2.98 kg
  (just under 3 kg target). Assembly sequence and track tensioning
  procedure included.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-02 09:20:41 -05:00

215 lines
9.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.

// ============================================================
// saltytank_skid_plate.scad — SaltyTank Underside Skid Plate
// Issue: #121 Agent: sl-mechanical Date: 2026-03-01
// ============================================================
//
// Bolt-on underside protection panel for rough terrain.
// Mounts to the underside of the deck plate, covering the hull
// floor between the two track frames.
//
// Purpose:
// • Protects electronics bay wiring + deck underside from rock strikes
// • Sacrificial layer — replace without reworking deck plate
// • Provides a smooth low-drag hull bottom for terrain sliding
// • Four drain / inspection slots (water / mud egress)
//
// Material options:
// Primary : 4 mm HDPE (high-density polyethylene)
// — lightweight, impact resistant, low friction surface
// Alternative: 2 mm 304 stainless steel
// — heavier (+0.5 kg), extremely wear resistant
// Prototype : 6 mm plywood (quick, cheap; not weatherproof)
//
// Dimensions: BODY_W × BODY_L × SKID_T
// = 360 × 500 × 4 mm (fits between track inner faces)
//
// Mounting:
// 8× M4 SHCS from below; nuts captured in deck plate M4 rivet-nuts
// (see saltytank_chassis.scad skid plate attachment holes)
// Countersunk (FHCS) variant available — set COUNTERSINK = true
//
// Coordinate: Z=0 at skid top face (= deck plate underside)
// Ground contact surface at Z = -(FRAME_H) = -90 mm (in deck coords)
// Skid sits immediately below deck: deck_bottom → skid_top
//
// RENDER options:
// "skid_stl" STL for 3D printing (4 mm PETG, prototype)
// "skid_2d" DXF for waterjet / CNC (HDPE or steel plate)
// "assembly" preview with deck ghost
//
// Export commands:
// DXF (HDPE / steel — recommended):
// openscad saltytank_skid_plate.scad -D 'RENDER="skid_2d"' -o saltytank_skid.dxf
// STL (3D print prototype):
// openscad saltytank_skid_plate.scad -D 'RENDER="skid_stl"' -o saltytank_skid.stl
// ============================================================
$fn = 64;
e = 0.01;
// ── Skid plate dimensions ────────────────────────────────────────────────────
// Must match saltytank_chassis.scad BODY_W and BODY_L exactly.
BODY_L = 500.0; // fore-aft — copy from saltytank_chassis.scad
BODY_W = 360.0; // left-right
SKID_T = 4.0; // skid plate thickness (4 mm HDPE)
SKID_R = 12.0; // corner radius (matches deck corners, ease of cleaning)
FRAME_H = 90.0; // side frame height (from saltytank_chassis.scad)
// ── Skid reinforcement ribs (under-surface, printed variant only) ─────────────
// Ribs add stiffness to the printed skid without adding flat-surface area.
// Ribs are omitted on the CNC/laser version (material stiffness is sufficient).
RIB_H = 8.0; // rib height below skid top face
RIB_T = 3.0; // rib wall thickness
RIB_PRINT = false; // set true to add ribs (print only; skip for DXF)
// ── Attachment bolt holes (M4) ───────────────────────────────────────────────
// Pattern must match saltytank_chassis.scad skid plate holes exactly.
// 2 rows × 3 columns = 6 holes + 2 corners = 8 total
BOLT_D = 4.3; // M4 clearance
BOLT_INSET_X = 20.0; // CL inset from left/right edge
BOLT_INSET_Y = 25.0; // CL inset from front/rear edge
// Countersinking (flat-head bolts flush with skid surface — preferred for terrain)
COUNTERSINK = true;
CSINK_ANGLE = 82; // M4 FHCS countersink angle (82° for DIN 7991)
CSINK_OD = 8.0; // M4 FHCS head diameter
// ── Drain / inspection slots ─────────────────────────────────────────────────
DRAIN_W = 20.0; // slot width
DRAIN_L = 60.0; // slot length
DRAIN_R = 10.0; // slot corner radius
// ── Road-wheel axle pass-through slots ───────────────────────────────────────
// The road wheel axles sit OUTSIDE the skid plate (they're in the side frames),
// so no axle holes are needed in the skid plate.
// The skid plate is a solid panel between the track frames.
// ── Fasteners ─────────────────────────────────────────────────────────────────
M4_D = 4.3;
// ============================================================
// RENDER DISPATCH
// ============================================================
RENDER = "assembly";
if (RENDER == "skid_stl") {
skid_plate();
} else if (RENDER == "skid_2d") {
projection(cut = true)
translate([0, 0, -SKID_T / 2])
skid_plate_flat_only();
} else if (RENDER == "assembly") {
assembly();
}
// ============================================================
// ASSEMBLY PREVIEW
// ============================================================
module assembly() {
color("Sienna", 0.85) skid_plate();
// Ghost deck plate above
%color("Silver", 0.25)
translate([0, 0, SKID_T])
linear_extrude(8)
minkowski() {
square([BODY_L - 24, BODY_W - 24], center = true);
circle(r = 12);
}
// Ghost side frames (simplified)
for (sx = [-1, 1])
%color("SteelBlue", 0.20)
translate([sx * (BODY_W/2 + 3), 0, SKID_T])
cube([6, BODY_L, FRAME_H + 8], center = true);
}
// ============================================================
// SKID PLATE (3D print — includes optional ribs)
// ============================================================
module skid_plate() {
difference() {
union() {
// ── Base plate ─────────────────────────────────────────────
linear_extrude(SKID_T)
skid_profile_2d();
// ── Reinforcement ribs (printed version only) ──────────────
if (RIB_PRINT) {
// Longitudinal centre rib
translate([0, 0, SKID_T])
cube([RIB_T, BODY_L - 40, RIB_H], center = true);
// Lateral ribs (3× fore-aft)
for (ry = [-BODY_L/4, 0, BODY_L/4])
translate([0, ry, SKID_T])
cube([BODY_W - 40, RIB_T, RIB_H], center = true);
}
}
// ── Attachment bolt holes ──────────────────────────────────────
for (bpos = bolt_positions())
translate([bpos[0], bpos[1], -e]) {
cylinder(d = BOLT_D, h = SKID_T + 2*e);
if (COUNTERSINK)
// Countersink cone from top face
translate([0, 0, SKID_T + e])
cylinder(d1 = CSINK_OD, d2 = BOLT_D,
h = (CSINK_OD - BOLT_D) / (2 * tan(CSINK_ANGLE/2)));
}
// ── Drain / inspection slots (4×, one per quadrant) ───────────
for (sx = [-1, 1])
for (sy = [-1, 1]) {
dx = sx * (BODY_W/4 + 15);
dy = sy * (BODY_L/4 + 20);
translate([dx - DRAIN_W/2 + DRAIN_R, dy - DRAIN_L/2 + DRAIN_R, -e])
linear_extrude(SKID_T + 2*e)
minkowski() {
square([DRAIN_W - 2*DRAIN_R, DRAIN_L - 2*DRAIN_R]);
circle(r = DRAIN_R);
}
}
}
}
// 2D profile of skid plate (shared by skid_plate and DXF export)
module skid_profile_2d() {
minkowski() {
square([BODY_L - 2*SKID_R, BODY_W - 2*SKID_R], center = true);
circle(r = SKID_R);
}
}
// Flat-only version for DXF projection (no ribs)
module skid_plate_flat_only() {
difference() {
linear_extrude(SKID_T) skid_profile_2d();
for (bpos = bolt_positions())
translate([bpos[0], bpos[1], -e])
cylinder(d = BOLT_D, h = SKID_T + 2*e);
for (sx = [-1, 1])
for (sy = [-1, 1]) {
dx = sx * (BODY_W/4 + 15);
dy = sy * (BODY_L/4 + 20);
translate([dx - DRAIN_W/2 + DRAIN_R, dy - DRAIN_L/2 + DRAIN_R, -e])
linear_extrude(SKID_T + 2*e)
minkowski() {
square([DRAIN_W - 2*DRAIN_R, DRAIN_L - 2*DRAIN_R]);
circle(r = DRAIN_R);
}
}
}
}
// ── Bolt position list (8 positions matching saltytank_chassis.scad) ──────────
function bolt_positions() = [
// From saltytank_chassis.scad skid plate holes (sx × (BODY_W/2 - 20), sy × BODY_L/3)
[-BODY_W/2 + BOLT_INSET_X, -BODY_L/3],
[-BODY_W/2 + BOLT_INSET_X, 0],
[-BODY_W/2 + BOLT_INSET_X, +BODY_L/3],
[+BODY_W/2 - BOLT_INSET_X, -BODY_L/3],
[+BODY_W/2 - BOLT_INSET_X, 0],
[+BODY_W/2 - BOLT_INSET_X, +BODY_L/3]
];