Consolidating seb/saltylab into saltylab-firmware before deleting the seed repo. - 16 OpenSCAD CAD models → cad/ - Design docs (SALTYLAB.md, PLATFORM.md, AGENTS.md, board-viz.html) → docs/
455 lines
18 KiB
Markdown
455 lines
18 KiB
Markdown
# SaltyLab — Detailed Build Plan 🔬⚖️
|
||
|
||
Self-balancing two-wheeled indoor robot with AI brain.
|
||
|
||
---
|
||
|
||
## 1. Battery Analysis
|
||
|
||
### Pack Specs (Begode Master V1 packs)
|
||
- **Configuration per pack:** 10S (35V nominal, 42V full, 30V cutoff)
|
||
- **Chemistry:** Li-ion 18650 or 21700
|
||
- **Estimated capacity per pack:** ~450-500Wh (based on Master V1 total ~1800Wh ÷ 4 packs)
|
||
- If 10S4P with 21700 5000mAh cells: 36V × 20Ah = **720Wh**
|
||
- If 10S3P with 21700 5000mAh cells: 36V × 15Ah = **540Wh**
|
||
- If 10S4P with 18650 3500mAh cells: 36V × 14Ah = **504Wh**
|
||
- **Need to verify:** check cell count visible on pack, or weigh it
|
||
|
||
### SaltyLab Battery Config: Single Pack
|
||
- **Voltage:** 35V nominal (fits hoverboard ESC: designed for 36V/10S)
|
||
- **Capacity:** ~500Wh (conservative estimate)
|
||
- **Weight:** ~2-3kg per pack
|
||
|
||
### Why Single Pack is Enough
|
||
- SaltyLab is indoor-only, short missions
|
||
- One pack gives 2-4 hours runtime (see estimates below)
|
||
- Keep other 3 packs for SaltyRider and SaltyTank
|
||
|
||
---
|
||
|
||
## 2. Power Budget & Range Estimation
|
||
|
||
### Component Power Draw
|
||
|
||
| Component | Voltage | Current | Power (W) | Notes |
|
||
|-----------|---------|---------|-----------|-------|
|
||
| Jetson Nano | 5V | 2-4A | 10-20W | AI inference mode: ~15W avg |
|
||
| RealSense D435i | 5V (USB) | 0.7A | 3.5W | Depth + RGB streaming |
|
||
| RPLIDAR A1M8 | 5V | 0.5A | 2.5W | Spinning at 5.5Hz |
|
||
| BNO055 IMU | 3.3V | 0.01A | 0.04W | Negligible |
|
||
| ESC (idle/balance) | 36V | 0.3A | 10W | Maintaining balance, no movement |
|
||
| LEDs + misc | 12V | 0.5A | 6W | Status LEDs, speaker |
|
||
| DC-DC losses | — | — | ~5W | ~85% efficiency on converters |
|
||
| **Subtotal (idle/balancing)** | | | **~47W** | |
|
||
|
||
### Motor Power (Moving)
|
||
|
||
| Activity | Per Motor | Total (2 motors) | Notes |
|
||
|----------|-----------|-------------------|-------|
|
||
| Balancing in place | 5-15W | 10-30W | Continuous micro-corrections |
|
||
| Slow indoor movement (2 km/h) | 15-25W | 30-50W | Walking pace |
|
||
| Normal indoor (5 km/h) | 30-50W | 60-100W | Brisk walk |
|
||
| Fast / acceleration | 80-150W | 160-300W | Bursts, turning |
|
||
| Climbing threshold/ramp | 100-200W | 200-400W | Short duration |
|
||
|
||
### Total Power by Use Case
|
||
|
||
| Mode | Electronics | Motors | Total | Notes |
|
||
|------|-------------|--------|-------|-------|
|
||
| **Idle (balancing)** | 47W | 20W | **~67W** | Standing still |
|
||
| **Slow patrol** | 47W | 40W | **~87W** | Gentle movement |
|
||
| **Normal follow** | 47W | 80W | **~127W** | Following person around house |
|
||
| **Active (turning, accel)** | 47W | 200W | **~247W** | Bursts |
|
||
|
||
### Range Estimates (Single 500Wh Pack)
|
||
|
||
| Mode | Avg Power | Runtime | Distance |
|
||
|------|-----------|---------|----------|
|
||
| Idle (balancing) | 67W | **7.5 hours** | 0 km (stationary) |
|
||
| Slow patrol (2 km/h) | 87W | **5.7 hours** | ~11 km |
|
||
| Normal follow (5 km/h) | 127W | **3.9 hours** | ~20 km |
|
||
| Mixed indoor use | ~100W avg | **5 hours** | ~15 km |
|
||
| Aggressive (lots of turning) | 180W avg | **2.8 hours** | ~8 km |
|
||
|
||
**Bottom line: 3-5 hours of indoor use on a single pack.** More than enough.
|
||
|
||
### Weight Budget
|
||
|
||
| Component | Weight (g) | Notes |
|
||
|-----------|-----------|-------|
|
||
| Battery pack (1x) | 2500 | Estimated, weigh to verify |
|
||
| 2x 8" hub motors | 2400 | ~1200g each with tire |
|
||
| ESC board | 150 | Single board |
|
||
| Jetson Nano + heatsink | 280 | With Noctua fan |
|
||
| RealSense D435i | 72 | Very light |
|
||
| RPLIDAR A1M8 | 170 | With motor |
|
||
| BNO055 breakout | 5 | Tiny |
|
||
| DC-DC converters (2x) | 300 | 150g each |
|
||
| Frame + brackets | 1200 | Aluminum + 3D printed |
|
||
| Wiring + connectors | 200 | |
|
||
| Bumpers (TPU) | 150 | |
|
||
| **TOTAL** | **~7.4 kg** | Target: under 8 kg |
|
||
|
||
---
|
||
|
||
## 3. Detailed 2D Schematics
|
||
|
||
### 3.1 Base Plate — Top View
|
||
|
||
```
|
||
350mm
|
||
←─────────────────────────────────────→
|
||
|
||
┌─────────────────────────────────────┐ ─┬─
|
||
│ ○ ○ │ │
|
||
│ ┌───────────────────────────┐ │ │
|
||
│ │ MOTOR MOUNT PLATE │ │ │
|
||
│ │ │ │ │
|
||
│ │ ┌─────┐ ┌─────┐ │ │ │
|
||
│ │ │AXLE │ │AXLE │ │ │ │ 200mm
|
||
│ │ │ L │ │ R │ │ │ │
|
||
│ │ └─────┘ └─────┘ │ │ │
|
||
│ │ ↑ 250mm ↑ │ │ │
|
||
│ │ └─────────────┘ │ │ │
|
||
│ │ track width │ │ │
|
||
│ └───────────────────────────┘ │ │
|
||
│ ○ ○ │ │
|
||
└─────────────────────────────────────┘ ─┴─
|
||
|
||
○ = M5 mounting holes for vertical spine (4 corners)
|
||
|
||
Axle holes: Ø14mm (standard hoverboard axle)
|
||
Plate thickness: 6mm PETG
|
||
|
||
Motor mount detail:
|
||
┌──────────────┐
|
||
│ ┌────────┐ │
|
||
│ │ Ø14mm │ │ Two-piece clamp:
|
||
│ │ axle │ │ Bottom: part of base plate
|
||
│ │ hole │ │ Top: clamp plate with 2x M6 bolts
|
||
│ └────────┘ │
|
||
│ ○ ○ │ ○ = M6 clamp bolt holes
|
||
└──────────────┘
|
||
80mm
|
||
```
|
||
|
||
### 3.2 Side View — Full Assembly
|
||
|
||
```
|
||
FRONT →
|
||
|
||
550mm ┬ ┌─────────┐
|
||
│ │ RPLIDAR │ Ø80mm, 360° clear
|
||
│ │ A1M8 │
|
||
500mm │ ├─────────┤
|
||
│ │ │ ← LIDAR standoff tube (80mm tall)
|
||
│ │ │
|
||
420mm │ ├─────────┤
|
||
│ │RealSense│ ← Tilted down 10°, front-facing
|
||
│ │ D435i │ Adjustable bracket
|
||
380mm │ ├─────────┤
|
||
│ │ │
|
||
│ │ JETSON │ ← Noctua fan, ventilation slots
|
||
│ │ NANO │
|
||
300mm │ ├─────────┤
|
||
│ │ BNO055 │ ← IMU, vibration-isolated mount
|
||
280mm │ ├─────────┤
|
||
│ │ │
|
||
│ │ ESC + │ ← ESC board + DC-DC converters
|
||
│ │ DC-DCs │
|
||
200mm │ ├─────────┤
|
||
│ │ │
|
||
│ │ BATTERY │ ← Heaviest component, lowest position
|
||
│ │ PACK │ Strapped to spine with velcro
|
||
│ │ │
|
||
80mm │ ├─────────┤
|
||
│ │ BASE │ ← Motor mount plate (6mm)
|
||
│ │ PLATE │
|
||
40mm │ ├────┬────┤
|
||
│ │ │ │
|
||
┴ └────┘ └── 8" wheel (Ø203mm)
|
||
═════════════
|
||
GROUND (0mm)
|
||
|
||
Ground clearance: ~40mm (bottom of plate to ground)
|
||
Wheel contact to axle center: ~100mm (8" diameter / 2)
|
||
Axle height from ground: ~100mm
|
||
```
|
||
|
||
### 3.3 Front View
|
||
|
||
```
|
||
←── 350mm ──→
|
||
|
||
┌─────────┐ ─┬─ 550mm
|
||
│ RPLIDAR │ │
|
||
├─────────┤ │
|
||
│ ┃ │ ← spine │
|
||
│ ┃ │ (2020 │
|
||
│ ┃ │ extrusion│
|
||
│ ┃ │ or │
|
||
│ ┃ │ aluminum │
|
||
│ ┃ │ tube) │
|
||
│ ┃ │ │
|
||
├───┃─────┤ │
|
||
┌─────┐ │ ┃ │ ┌─────┐│
|
||
│ │ │ ┃ │ │ ││
|
||
│ 8" │ │ ┃ │ │ 8" ││ 100mm
|
||
│ L │───┤ ┃ ├───│ R ││ (axle)
|
||
│ │ │ ┃ │ │ ││
|
||
│ │ └───┃─────┘ │ │┴─ 0mm
|
||
└─────┘ ┃ └─────┘
|
||
═══════════════════════════════════
|
||
|
||
←65→←──── 250mm ────→←65→
|
||
mm (track width) mm
|
||
|
||
Total width with tires: ~380mm
|
||
Fits through standard doorway (760mm) ✓
|
||
```
|
||
|
||
### 3.4 Spine Detail — Side View
|
||
|
||
```
|
||
┌──┐ ← 20×20mm aluminum extrusion (2020 V-slot)
|
||
│ │ or 25×25mm square aluminum tube
|
||
│ │
|
||
│ │──── Shelf bracket (3D printed, bolts to T-slot)
|
||
│ │ Each shelf: 120mm wide × 100-150mm deep
|
||
│ │
|
||
│ │──── Shelf bracket
|
||
│ │
|
||
│ │──── Shelf bracket
|
||
│ │
|
||
│ │──── Shelf bracket
|
||
│ │
|
||
├──┤
|
||
│ │──── Base plate connection (L-brackets, 4x M5)
|
||
└──┘
|
||
|
||
Spine length: 470mm (from base plate to LIDAR mount)
|
||
|
||
Shelf positions (from base plate):
|
||
0mm — Base plate
|
||
30mm — Battery shelf (holds pack on its side)
|
||
150mm — ESC + DC-DC shelf
|
||
250mm — Jetson Nano shelf
|
||
300mm — BNO055 (attached to spine directly)
|
||
370mm — RealSense bracket (front-facing arm)
|
||
420mm — LIDAR standoff begins
|
||
500mm — LIDAR mount plate
|
||
```
|
||
|
||
### 3.5 Wiring Diagram
|
||
|
||
```
|
||
BATTERY PACK (35V nominal, 10S Li-ion)
|
||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||
│(+) (−)│
|
||
│ │
|
||
├──[E-STOP (NC)]───────────┤
|
||
│ │
|
||
XT60 ├────────┬────────┬────────┤ XT60
|
||
│ │ │ │
|
||
│ ┌───┴───┐ │ │
|
||
│ │DC-DC │ │ │
|
||
│ │36V→5V │ │ │
|
||
│ │ 4A │ │ │
|
||
│ └───┬───┘ │ │
|
||
│ 5V │ │ │
|
||
│ ┌───┴────┐ │ │
|
||
│ │USB Hub │ │ │
|
||
│ │Jetson │ │ │
|
||
│ │RealSns │ │ │
|
||
│ │RPLIDAR │ │ │
|
||
│ └────────┘ │ │
|
||
│ │ │
|
||
│ ┌────┴───┐ │ │
|
||
│ │DC-DC │ │ │
|
||
│ │36V→12V │ │ │
|
||
│ │ 2A │ │ │
|
||
│ └───┬────┘ │ │
|
||
│ 12V │ │ │
|
||
│ ┌───┴────┐ │ │
|
||
│ │LEDs │ │ │
|
||
│ │Speaker │ │ │
|
||
│ └────────┘ │ │
|
||
│ │ │
|
||
┌────┴─────────────────┴────────┴────┐
|
||
│ HOVERBOARD ESC │
|
||
│ (FOC firmware) │
|
||
│ │
|
||
│ I2C: SDA──BNO055──SCL │
|
||
│ UART: TX──Jetson──RX │
|
||
│ │
|
||
│ PHASE L: ─── 8" LEFT MOTOR │
|
||
│ HALL L: ─── (5 wire: hall A/B/C │
|
||
│ + 5V + GND) │
|
||
│ │
|
||
│ PHASE R: ─── 8" RIGHT MOTOR │
|
||
│ HALL R: ─── (5 wire) │
|
||
└────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Phased Build Plan
|
||
|
||
### Phase 1: Rolling Skeleton (Days 1-3)
|
||
**Goal:** Prove balance works.
|
||
|
||
**Tasks:**
|
||
- [ ] Measure 8" motor axle diameter with calipers
|
||
- [ ] Design motor mount plate in CAD (FreeCAD or TinkerCAD)
|
||
- [ ] Print motor mount plate on Bambu X1C (PETG, 80% infill, ~4h print)
|
||
- [ ] Print axle clamp tops (x2)
|
||
- [ ] Mount both 8" motors to plate
|
||
- [ ] Mount ESC to plate with standoffs
|
||
- [ ] Wire BNO055 to ESC I2C (4 wires: VCC, GND, SDA, SCL)
|
||
- [ ] Wire battery to ESC (XT60)
|
||
- [ ] Modify FOC firmware: add BNO055 I2C read, replace gyro board input
|
||
- [ ] Flash ESC with updated firmware
|
||
- [ ] **SAFETY:** Tie rope from ceiling to plate as fall catch
|
||
- [ ] Power on, tune PID (start with Kp=20, Ki=0, Kd=0, increase gradually)
|
||
- [ ] Achieve stable free-standing balance (no rope)
|
||
|
||
**Parts needed:** motor mount plate, 2x clamp tops, M6 bolts, M3 standoffs
|
||
**Risk:** PID tuning can take hours of iteration. Be patient.
|
||
|
||
### Phase 2: Spine + Brain (Days 4-7)
|
||
**Goal:** Add Jetson, achieve remote-controlled movement while balancing.
|
||
|
||
**Tasks:**
|
||
- [ ] Cut aluminum extrusion/tube to 470mm for spine
|
||
- [ ] Print shelf brackets (4x) and L-brackets for base connection
|
||
- [ ] Assemble spine onto base plate
|
||
- [ ] Mount battery to lowest shelf (velcro straps)
|
||
- [ ] Mount ESC + DC-DC converters
|
||
- [ ] Mount Jetson Nano on shelf, connect 5V power
|
||
- [ ] Wire Jetson UART → ESC UART
|
||
- [ ] Install JetPack 4.6 on Jetson (if not already)
|
||
- [ ] Write serial bridge: Jetson Python → ESC UART commands
|
||
- [ ] Test: keyboard control (WASD) → speed/steer commands → balanced movement
|
||
- [ ] Tune speed response (acceleration limits, max speed for indoor)
|
||
- [ ] Add E-stop button (inline with battery positive)
|
||
|
||
**Software deliverable:** `saltylab_teleop.py` — keyboard-controlled balancing bot
|
||
|
||
### Phase 3: Eyes + Ears (Days 8-12)
|
||
**Goal:** See the world. Map a room. Detect people.
|
||
|
||
**Tasks:**
|
||
- [ ] Print RealSense bracket (adjustable tilt)
|
||
- [ ] Print LIDAR standoff tube + mount plate
|
||
- [ ] Mount RealSense D435i (front-facing, ~10° down tilt)
|
||
- [ ] Mount RPLIDAR A1M8 (top of spine, 360° clear)
|
||
- [ ] Install ROS2 on Jetson
|
||
- [ ] Install and test `realsense-ros` (verify depth stream)
|
||
- [ ] Install and test `rplidar_ros` (verify laser scan)
|
||
- [ ] Run `slam_toolbox` — drive around room, build 2D map
|
||
- [ ] Test person detection with SSD-MobileNet-v2 (TensorRT)
|
||
- [ ] Implement follow mode:
|
||
- Detect person in RGB frame
|
||
- Get distance from depth frame
|
||
- PID to maintain 1.5m following distance
|
||
- LIDAR for obstacle avoidance
|
||
|
||
**Software deliverable:** `saltylab_follow.py` — person-following balanced bot
|
||
|
||
### Phase 4: Polish + Personality (Days 13-17)
|
||
**Goal:** Make it feel alive. Make it SaltyLab.
|
||
|
||
**Tasks:**
|
||
- [ ] Print proper enclosures for all electronics
|
||
- [ ] Print TPU bumpers (front + rear)
|
||
- [ ] Print carry handle
|
||
- [ ] Add NeoPixel LED ring around LIDAR mount (status indication)
|
||
- Blue breathing: idle/balancing
|
||
- Green: following
|
||
- Yellow: exploring/mapping
|
||
- Red: error/low battery
|
||
- [ ] Add small speaker (USB or I2S to amp)
|
||
- Boot sound
|
||
- Acknowledge commands with beeps/chirps
|
||
- Optional: TTS via Jetson ("I see you", "battery low")
|
||
- [ ] WiFi dashboard: live camera feed + map + battery status
|
||
- [ ] Battery voltage monitoring (ADC on ESC → Jetson via UART)
|
||
- [ ] Low battery return behavior (stop and beep)
|
||
- [ ] Integrate with Home Assistant (MQTT: location, battery, status)
|
||
|
||
### Phase 5: House Mapping + Autonomy (Days 18-24)
|
||
**Goal:** SaltyLab knows your house.
|
||
|
||
**Tasks:**
|
||
- [ ] Map every room (drive around manually, SLAM builds full floor plan)
|
||
- [ ] Save map, set up `nav2` for autonomous navigation
|
||
- [ ] Define waypoints: lab, living room, kitchen, hallway
|
||
- [ ] Patrol mode: visit waypoints on schedule
|
||
- [ ] Person detection + greeting ("hey Tee", "hi Inka")
|
||
- [ ] Integration with Bermuda BLE: know where people are, go to them
|
||
- [ ] Charging dock design (future: auto-dock when low)
|
||
|
||
---
|
||
|
||
## 5. Speed & Performance Specs
|
||
|
||
### Target Performance
|
||
|
||
| Parameter | Value | Notes |
|
||
|-----------|-------|-------|
|
||
| Max speed (indoor) | 5 km/h | Software limited for safety |
|
||
| Normal follow speed | 2-3 km/h | Walking pace |
|
||
| Turning radius | 0 (pivot) | Differential drive, spins in place |
|
||
| Ground clearance | 40mm | Clears door thresholds (~15mm) |
|
||
| Max incline | ~10° | Limited by motor torque + balance |
|
||
| Operating time | 3-5 hours | Single 500Wh pack |
|
||
| Charge time | ~2-3 hours | Using one of the existing chargers |
|
||
| Weight | ~7.5 kg | Easy to pick up with handle |
|
||
| Width | 380mm | Fits all doorways |
|
||
| Height | 550mm | Below table height |
|
||
|
||
### Motor Specs (8" hub motor, estimated)
|
||
| Parameter | Value |
|
||
|-----------|-------|
|
||
| Nominal voltage | 36V |
|
||
| Rated power | 250-350W per motor |
|
||
| No-load RPM | ~250 RPM |
|
||
| Wheel circumference | ~0.64m (Ø203mm) |
|
||
| Max wheel speed | 160 m/min = 9.6 km/h |
|
||
| Continuous torque | ~2-3 Nm |
|
||
| Stall torque | ~8-10 Nm |
|
||
|
||
---
|
||
|
||
## 6. Safety Considerations
|
||
|
||
| Hazard | Mitigation |
|
||
|--------|-----------|
|
||
| Falls over | TPU bumpers, max tilt cutoff (30°), low CoG |
|
||
| Runs away | Software speed limit (5 km/h), E-stop button |
|
||
| Pinches/crushes | No exposed gears, motor covers |
|
||
| Battery fire | BMS on pack, fused main power, no charging unattended |
|
||
| Hits furniture | LIDAR obstacle avoidance, bumper sensors (future) |
|
||
| Scares the cat | Slow acceleration, no sudden movements |
|
||
|
||
---
|
||
|
||
## 7. Shopping List (Items NOT in Inventory)
|
||
|
||
| Item | Price (CAD) | Source | Notes |
|
||
|------|------------|--------|-------|
|
||
| 2020 aluminum extrusion 500mm | ~$8 | Amazon/AliExpress | Spine |
|
||
| T-slot nuts + M5 bolts (pack) | ~$12 | Amazon | For shelf mounting |
|
||
| M6 bolts + nuts (axle clamps) | ~$5 | Hardware store | 4x sets |
|
||
| NeoPixel ring (24 LED) | ~$8 | Amazon | Status indication |
|
||
| Small speaker + amp (MAX98357A) | ~$10 | Amazon/Adafruit | I2S audio |
|
||
| E-stop mushroom button | ~$5 | Amazon | Safety |
|
||
| XT60 splitter/distribution | ~$8 | Amazon | Power wiring |
|
||
| Misc: heat shrink, zip ties, wire | ~$10 | — | Always need more |
|
||
| **TOTAL** | **~$66** | | Everything else: already owned |
|
||
|
||
---
|
||
|
||
*Last updated: 2026-02-27*
|
||
*Project: SaltyRover / SaltyLab*
|