feat(mechanical): GoPro mount adapter for T-slot rail (Issue #195) #324

Closed
sl-mechanical wants to merge 3 commits from sl-mechanical/issue-195-gopro-mount into main
2 changed files with 508 additions and 0 deletions
Showing only changes of commit e22fd23f33 - Show all commits

256
chassis/gopro_mount.scad Normal file
View File

@ -0,0 +1,256 @@
// ============================================================
// gopro_mount.scad GoPro 3-Prong T-Slot Sensor Rail Mount
// Issue: #195 Agent: sl-mechanical Date: 2026-03-02
// ============================================================
//
// Universal GoPro camera mount for sensor_rail.scad (T-slot 2020).
//
// Top interface: Standard GoPro 3-prong (HERO 5+)
// Prongs slide into standard GoPro accessories.
// No additional clips or fasteners needed.
//
// Bottom clamp: T-slot 20×20 mm rail system (OpenBuilds compatible).
// M3 thumbscrew retention + M5 index holes for 15° detents.
//
// Tilt mechanism: Rotating hinge bracket allows camera tilt 0°90° from
// horizontal, locked at 15° increments via index holes.
// Rotation axis is perpendicular to rail (about Y-axis).
//
// Assembly:
// 1. Print gopro_mount_base (single part, flat-side-down, no supports)
// 2. Slide built-in T-nut into rail T-groove
// 3. Clamp with M3 thumbscrew from outside rail face
// 4. Rotate camera to desired tilt angle (0°, 15°, 30°, ... 90°)
// 5. Insert M5 alignment pin to lock tilt
//
// RENDER options:
// "mount" assembled mount view (default)
// "base_stl" base clamp for slicing (print flat)
// "camera_bracket" rotatable camera bracket for slicing
// ============================================================
RENDER = "mount";
// GoPro 3-prong interface (top)
// Standard GoPro HERO 5+ 3-prong attachment point.
// Overall footprint ~43×25 mm, 3 prongs slide into camera mounting slot.
GOPRO_WIDTH = 43.0; // front-to-back along camera face
GOPRO_DEPTH = 25.0; // left-to-right width
GOPRO_PRONG_H = 5.0; // height of prongs above base
GOPRO_PRONG_D = 4.0; // diameter/thickness of each prong
GOPRO_PRONG_SP = 14.0; // spacing between outer prongs (centre-to-centre)
// Centre prong is at Y=0; outer prongs at Y±GOPRO_PRONG_SP/2
// Prongs extend upward (+Z direction)
// T-slot clamp (bottom)
// Matches sensor_rail.scad T-slot 2020 dimensions.
RAIL_W = 20.0; // rail outer width/height
SLOT_INNER_W = 10.2; // T-groove inner width
SLOT_INNER_H = 5.8; // T-groove inner height (depth)
SLOT_NECK_H = 3.2; // distance from outer face to T-groove
TNUT_W = 9.8; // printable T-nut width (SLOT_INNER_W - 0.4)
TNUT_H = 5.5; // printable T-nut height (SLOT_INNER_H - 0.3)
TNUT_L = 12.0; // T-nut body length
TNUT_BOLT_D = 3.3; // M3 clearance bore through T-nut
THUMB_D = 16.0; // thumbwheel OD (visual only)
THUMB_H = 8.0; // thumbwheel height
// Index hole pitch for tilt detents
INDEX_PITCH = 25.0; // 25 mm spacing on rail
TILT_ANGLE_STEP = 15.0; // 15° tilt detents (0°, 15°, 30°, ... 90°)
M5_INDEX_D = 5.3; // M5 clearance hole diameter
// Rotation/tilt mechanism
// Camera bracket rotates about Y-axis relative to base.
// Rotation axis is at the rail clamp interface (Z=0, Y=0).
// Tilt range: 0° to 90°.
MAX_TILT_DEG = 90.0; // maximum tilt angle
// Hinge pin: M5 bolt passes through base and camera bracket
HINGE_PIN_D = 5.3; // M5 bolt clearance
HINGE_PIN_L = 25.0; // pin length (accommodates rail width + brackets)
// General
$fn = 64;
e = 0.01;
//
// gopro_mount_base()
// T-slot clamp bracket with integrated T-nut.
// Mounted at bottom, rail clamp at Z=0 face.
// Hinge pin axis at Y=0, rotates camera bracket ±X.
//
// Print: flat-side-down (rail face down), no supports needed.
//
module gopro_mount_base() {
clamp_h = RAIL_W + 8.0; // total clamp height
clamp_w = TNUT_L + 8.0; // clamp width (along rail)
clamp_d = 18.0; // clamp depth (front-to-back)
difference() {
union() {
// Main clamp body
translate([-clamp_w/2, -clamp_d/2, 0])
cube([clamp_w, clamp_d, clamp_h]);
// T-nut integration: slot to hold T-nut at rail interface
// T-nut sits in T-groove when rail is inserted from above
translate([-TNUT_L/2, -TNUT_W/2, SLOT_NECK_H])
cube([TNUT_L, TNUT_W, TNUT_H]);
// Hinge boss (supports rotation axis pin)
translate([-HINGE_PIN_L/2 - 2, -8, clamp_h - 4])
cube([HINGE_PIN_L + 4, 4, 4]);
}
// Rail bore (25.4 mm) matches stem adapter pattern
// When rail is vertical, this bore slides onto rail extrusion
translate([0, 0, -e])
cylinder(d=RAIL_W + 0.4, h=clamp_h + 2*e);
// T-nut through-bolt (M3 thumbscrew hole)
// Bolt comes from outside rail face, through T-nut, clamping it
translate([0, 0, SLOT_NECK_H + TNUT_H/2])
rotate([90, 0, 0])
cylinder(d=TNUT_BOLT_D, h=clamp_d + 2*e);
// Hinge pin (M5) passes through base to camera bracket
translate([-HINGE_PIN_L/2, 0, clamp_h - 2])
rotate([0, 90, 0])
cylinder(d=HINGE_PIN_D, h=HINGE_PIN_L + 2*e);
// Index hole pockets for tilt angle lock (M5)
// One index hole on each side to lock camera tilt
for (angle = [0 : TILT_ANGLE_STEP : MAX_TILT_DEG]) {
// Holes are radially spaced around the hinge axis
y_offset = (HINGE_PIN_L/2 - 2) * sin(angle);
z_offset = clamp_h - 2 - (HINGE_PIN_L/2 - 2) * (1 - cos(angle));
translate([0, y_offset, z_offset])
cylinder(d=M5_INDEX_D, h=4, center=false);
}
// Vent slots (optional, aesthetic + weight reduction)
for (dz = [4, 8, 12])
translate([-clamp_w/2 + 2, -clamp_d/2 - e, dz])
cube([clamp_w - 4, 2, 1.5]);
}
}
//
// gopro_camera_bracket()
// Rotatable bracket that holds GoPro camera via 3-prong mount.
// Rotates about Y-axis (hinge pin), tilt 0°90°.
//
// Hinge pin (M5 bolt) enters from base and locks bracket rotation.
// Index hole on bracket aligns with base index holes at each 15° step.
//
// Print: flat-side-down (prong face down), no supports.
//
module gopro_camera_bracket() {
bracket_h = GOPRO_WIDTH + 8.0; // height when vertical
bracket_w = GOPRO_DEPTH + 6.0; // width (left-right)
bracket_t = 4.0; // bracket thickness
difference() {
union() {
// Main bracket body
translate([-bracket_w/2, -bracket_t/2, 0])
cube([bracket_w, bracket_t, bracket_h]);
// Hinge pivot boss
translate([-HINGE_PIN_L/2 - 2, 0, bracket_h - 4])
cube([HINGE_PIN_L + 4, bracket_t, 4]);
// GoPro prong mounting boss
translate([-GOPRO_DEPTH/2, 0, bracket_h - GOPRO_WIDTH/2])
cube([GOPRO_DEPTH, bracket_t + 2, GOPRO_WIDTH]);
}
// Hinge pin bore (M5)
translate([-HINGE_PIN_L/2, 0, bracket_h - 2])
rotate([0, 90, 0])
cylinder(d=HINGE_PIN_D + 0.2, h=HINGE_PIN_L + 2*e);
// Index hole (M5) for angle lock
// Bracket has one index hole that aligns with base holes at tilt angles
translate([GOPRO_DEPTH/2 + 1, 0, bracket_h - 4])
cylinder(d=M5_INDEX_D, h=bracket_t + 2*e);
// GoPro prong socket (3 mounting prongs)
// Centre prong at Y=0, outer prongs at Y±GOPRO_PRONG_SP/2
for (dy = [0, GOPRO_PRONG_SP/2, -GOPRO_PRONG_SP/2]) {
translate([0, bracket_t + e, bracket_h - GOPRO_WIDTH/2 + 5 - dy])
rotate([90, 0, 0])
cylinder(d=GOPRO_PRONG_D + 0.4, h=4);
}
}
}
//
// gopro_prong_interface()
// Visual representation of the 3 prongs that camera mounts to.
// Not printed; shown during assembly view.
//
module gopro_prong_interface() {
bracket_h = GOPRO_WIDTH + 8.0;
bracket_w = GOPRO_DEPTH + 6.0;
// 3 cylindrical prongs
for (dy = [0, GOPRO_PRONG_SP/2, -GOPRO_PRONG_SP/2]) {
translate([0, bracket_w/2 + 0.5, bracket_h - GOPRO_WIDTH/2 + 5 - dy])
rotate([90, 0, 0])
cylinder(d=GOPRO_PRONG_D, h=GOPRO_PRONG_H, $fn=32);
}
}
//
// Assembly view: base + rotatable camera bracket
//
module gopro_mount_assembly() {
// Base clamp (fixed)
color("SteelBlue", 0.9)
gopro_mount_base();
// Camera bracket (rotatable, at 45° tilt for visualization)
color("CornflowerBlue", 0.85)
rotate([0, 45, 0])
translate([0, 0, RAIL_W + 8])
gopro_camera_bracket();
// Visual GoPro prongs
color("LightSteelBlue", 0.7)
rotate([0, 45, 0])
translate([0, 0, RAIL_W + 8])
gopro_prong_interface();
// Phantom M5 hinge pin (visual reference)
color("Silver", 0.5)
translate([-HINGE_PIN_L/2, 0, RAIL_W + 8 - 2])
rotate([0, 90, 0])
cylinder(d=5, h=HINGE_PIN_L);
}
//
// Render selector
//
if (RENDER == "mount") {
gopro_mount_assembly();
} else if (RENDER == "base_stl") {
// Flat print orientation: rail-facing side down
rotate([180, 0, 0])
translate([0, 0, -RAIL_W - 8])
gopro_mount_base();
} else if (RENDER == "camera_bracket") {
// Flat print orientation: prong-facing side down
rotate([0, 0, 0])
translate([0, 0, GOPRO_WIDTH + 14])
rotate([180, 0, 0])
gopro_camera_bracket();
}

252
chassis/gopro_mount_BOM.md Normal file
View File

@ -0,0 +1,252 @@
# GoPro 3-Prong T-Slot Sensor Rail Mount — BOM + Assembly
**Rev A — 2026-03-02 — sl-mechanical**
---
## System Overview
Universal GoPro HERO 5+ camera mount for sensor_rail.scad (T-slot 20×20 mm).
| Feature | Spec |
|---------|------|
| Camera interface | Standard GoPro 3-prong (HERO 5+) |
| Rail system | T-slot 2020 OpenBuilds / MISUMI compatible |
| Tilt range | 0° 90° from horizontal |
| Tilt detents | 15° increments (0°, 15°, 30°, 45°, 60°, 75°, 90°) |
| Retention | M3 thumbscrew clamp (T-nut to rail) + M5 index pin (angle lock) |
| Weight | ~85 g (printed) + ~45 g (fasteners) |
---
## Design Features
- **Top mount:** Standard GoPro 3-prong interface — no custom adapters, works with any GoPro HERO 5+ compatible accessory.
- **Bottom clamp:** Integrated T-nut slides into rail T-groove; single M3 thumbscrew locks clamp to rail (no tools required).
- **Tilt mechanism:** Rotating bracket + M5 hinge pin; camera tilts 0°90° and locks at 15° steps via M5 index holes.
- **Printability:** Both parts print flat-face-down, no support material required.
- **Compatibility:** Works with all SaltyLab / SaltyRover sensor_rail.scad mounts; positions camera anywhere along rail.
---
## Part A — Printed Components
### 1. Base Clamp (gopro_mount.scad, RENDER="base_stl")
**Purpose:** Holds T-nut in rail T-groove; provides rotation axis for camera bracket.
| Parameter | Value | Notes |
|-----------|-------|-------|
| Qty | 1 | Single part per mount |
| Material | PETG | 5 perimeters, 40% infill (gyroid) |
| Print size | ~45 × 35 × 28 mm | Flat-face-down (rail-side down) |
| Orientation | Rail bore facing DOWN | Supports natural bed adhesion |
| Support | None | Design allows direct print |
| Wall thickness | 45 mm minimum | Ensure M3 threads cut cleanly |
**Key features:**
- Integrated T-nut pocket (friction-fit to rail T-groove)
- M3 thumbscrew bore (perpendicular to T-nut, from outside rail face)
- M5 hinge-pin bore (passes through to camera bracket)
- 7 index holes (one for each tilt angle: 0°, 15°, 30°, 45°, 60°, 75°, 90°)
- Vent slots for weight reduction
---
### 2. Camera Bracket (gopro_mount.scad, RENDER="camera_bracket")
**Purpose:** Holds GoPro camera via 3-prong mount; rotates about M5 hinge pin.
| Parameter | Value | Notes |
|-----------|-------|-------|
| Qty | 1 | Single part per mount |
| Material | PETG | 4 perimeters, 30% infill |
| Print size | ~35 × 25 × 51 mm | Flat-face-down (prong-side down) |
| Orientation | GoPro prongs facing DOWN | Minimal post-processing |
| Support | None | Design supports printing without supports |
| Wall thickness | 34 mm | Adequate for M5 through-bore |
**Key features:**
- 3 cylindrical prong sockets (GoPro standard spacing)
- M5 hinge-pin bore (receives bolt from base)
- 1 index hole (aligns with base index holes at tilt angle)
- Lightweight design
---
## Part B — Fasteners & Hardware
All fasteners are stainless steel or zinc-plated for corrosion resistance.
| # | Spec | Qty | Use | Notes |
|---|------|-----|-----|-------|
| 1 | M3 × 12 SHCS | 1 | Thumbscrew — clamps T-nut to rail | or M3 cap screw with printed knob |
| 2 | M3 washer | 1 | Under thumbscrew head | standard flat washer |
| 3 | M5 × 25 SHCS | 1 | Hinge pin — camera bracket rotation axis | or M5 cap screw + lock washer |
| 4 | M5 washer | 2 | Hinge pin lock washers (each end) | prevents backlash |
| 5 | M5 lock nut | 1 | Hinge pin lock nut | nylon-insert preferred |
| 6 | M5 × 8 roll pin | 7 | Index pins — lock tilt angle | one for each 15° detent (0°90°) |
---
## Installation & Assembly
### Step 1: Prepare T-slot Rail
1. Verify rail is clean (no burrs, chips).
2. Slide base clamp assembly onto rail from above (rail face toward clamp bore).
3. Align T-nut pocket with T-slot T-groove (groove faces inward).
### Step 2: Clamp Base to Rail
1. Insert M3 thumbscrew through rail outer face, through the T-nut pocket.
2. Tighten **finger-tight** first (do not overtighten — rail will deform).
3. Verify clamp is centered on rail (equal gap on both sides).
4. Tighten to **hand-tight** (≈2 N·m for M3).
### Step 3: Assemble Hinge & Camera Bracket
1. Slide M5 × 25 bolt through base clamp hinge bore (horizontal, perpendicular to rail).
2. Mount camera bracket on bolt (prong-side facing camera direction).
3. Add M5 washers at both bolt ends.
4. Tighten M5 lock nut to **hand-tight** (≈5 N·m).
- Bolt should rotate smoothly but without play.
- If bracket binds, loosen slightly; if too loose, add second lock washer.
### Step 4: Mount GoPro Camera
1. Rotate camera bracket to desired tilt angle (0°, 15°, 30°, etc.).
2. Align index hole on bracket with corresponding hole on base clamp.
3. Insert M5 × 8 roll pin into aligned holes (pushes in snugly, no tools needed).
4. Verify pin locks camera position (should not rotate when pin is seated).
5. Slide GoPro onto 3 prongs until camera contacts mount.
### Step 5: Cable Management
- Route camera USB/HDMI cable down rail (behind robot).
- Use cable tie on thumbscrew pocket if additional restraint needed.
---
## Tilt Angle Detents
The 15° step gives 7 fixed positions within 0°90° range:
| Tilt Index | Angle | Use case |
|------------|-------|----------|
| 1 | 0° | Horizontal (level with horizon) |
| 2 | 15° | Slight upward tilt |
| 3 | 30° | Moderate upward tilt |
| 4 | 45° | Balanced forward-up tilt |
| 5 | 60° | Steep upward tilt |
| 6 | 75° | Nearly vertical forward |
| 7 | 90° | Straight vertical (zenith) |
To change tilt:
1. Push on camera bracket to rotate (index pin will pop out if at end of rotation).
2. Align new index hole.
3. Re-insert index pin.
---
## Fastener Torque Spec
| Fastener | Size | Torque | Note |
|----------|------|--------|------|
| M3 thumbscrew | M3 × 12 | 2 N·m | Hand-tight; over-tightening deforms rail |
| M5 hinge pin | M5 × 25 | 5 N·m | Smooth rotation, no play |
| M5 lock nut | M5 | 2.5 N·m | After initial tightening, verify free rotation |
---
## Post-Print Finishing
### Base Clamp
- **Support removal:** No supports needed.
- **Bore prep:** If M3 bore is rough, ream with M3 hand reamer (¼ turn only).
- **T-nut pocket:** Smooth with fine sandpaper if needed (must slide smoothly into groove).
### Camera Bracket
- **Support removal:** No supports needed.
- **Prong sockets:** Clean with compressed air; verify no strands block GoPro prongs.
- **Index hole:** Verify M5 bore is clear (small drill bit can clear if needed).
---
## Mass Estimate
| Component | Material | Est. Mass |
|-----------|----------|-----------|
| Base clamp | PETG | ~35 g |
| Camera bracket | PETG | ~28 g |
| M3 thumbscrew | Stainless | ~2 g |
| M5 hinge bolt + nut | Stainless | ~6 g |
| M5 index pins (×7) | Steel | ~4 g |
| **Total (without camera)** | | **~75 g** |
| **Total (with GoPro HERO)** | | **~250 g** |
---
## Mounting Position Recommendations
### On sensor_rail.scad vertical rail
| Position | Z height | Use |
|----------|----------|-----|
| Below sensor head | 700800 mm | Forward-facing wide-angle view |
| Mid-rail | 400500 mm | Side-looking perspective |
| Above base plate | 100200 mm | Ground-level or low-angle view |
Index holes on rail face every 25 mm; position bracket at any height (friction-fit with T-nut + thumbscrew).
### On payload_bay_rail.scad (horizontal rail)
Mount horizontally by:
1. Rotate entire assembly 90° (rail runs front-to-back).
2. Tilt camera bracket 0°90° to point downward or forward.
3. Good for payload bay documentation (downward view) or forward obstacle detection.
---
## Storage & Maintenance
- **Store bracket vertical** (prongs up) to avoid stress on sockets.
- **Clean prongs** after each field session (dust prevents secure seating).
- **Verify index pin seating** before each deployment (pin can loosen if rattled).
- **Check thumbscrew** monthly (re-tighten if rail has shifted).
---
## Design Notes for Future Revisions
- **Optional:** Add detent detents (spring-loaded ball bearing pockets) at index holes for positive clicks.
- **Optional:** Add strap attachment points on base clamp for secondary safety line.
- **Alternative bracket:** Straight vertical bracket (0° fixed) for weight-optimized variant.
- **Camera variants:** Compatibility with GoPro Session (action cam) and DJI Osmo Action (different prong patterns) would require bracket redesign.
---
## Files
| File | Purpose |
|------|---------|
| `gopro_mount.scad` | OpenSCAD parametric model (3 RENDER variants) |
| `gopro_mount_BOM.md` | This document |
| `sensor_rail.scad` | Parent T-slot rail system (dependency) |
| `sensor_rail_brackets.scad` | Additional rail bracket options |
---
## Assembly Checklist
- [ ] Print base clamp (PETG, 45 × 35 × 28 mm, flat-side-down)
- [ ] Print camera bracket (PETG, 35 × 25 × 51 mm, flat-side-down)
- [ ] Inspect prong sockets on bracket (no strands, smooth)
- [ ] Ream or smooth M3 thumbscrew bore in base clamp
- [ ] Test T-nut pocket (slides in/out of rail groove smoothly)
- [ ] Assemble: M3 thumbscrew + washer
- [ ] Assemble: M5 × 25 bolt + 2 washers + lock nut
- [ ] Mount bracket on hinge pin (hand-tight fit)
- [ ] Insert one M5 × 8 index pin at 0° (test fit)
- [ ] Mount GoPro camera (prongs snap in)
- [ ] Final check: camera level in 0° position
- [ ] Stow extra index pins in camera bag