Overview
I designed and built a Raspberry Pi–powered rover that detects obstacles and makes simple navigation decisions.
The Pi hosts a Flask server exposing controls and telemetry to a clean HTML/CSS interface with a bit of JavaScript.
Drivers (motors, ultrasonic sensor, and steering via PCA9685) are abstracted behind Python modules so the web layer stays minimal and testable.
Goals
- Reliable browser controls for forward/back/left/right/stop.
- Autonomous mode that stops for obstacles and selects a safer direction.
- Modular hardware layer so components (motors/sensors) can be swapped without UI changes.
My Role
- Backend: Flask routes & REST endpoints for drive commands and status polling.
- Hardware: PWM motor control, ultrasonic distance reads, servo sweep logic.
- Frontend: HTML/CSS layout + JS
fetch calls for controls and live updates.
Architecture
- Backend: Flask app exposes
/drive, /mode, /status; a background loop runs autonomy.
- Hardware Modules:
motor.py (PCA9685 PWM), sensor.py (HC-SR04 reads), servo.py (steering sweep).
- Autonomy Logic: If obstacle < threshold, stop → sweep angles (L/C/R) → compare distances → rotate toward max clearance → proceed.
- Frontend: Jinja templates for pages; JS sends commands and refreshes status without full reload.
- Deployment: Runs on the Pi; systemd service starts Flask at boot; .env stores pins/thresholds.
Highlights
Separation of Concerns
Hardware drivers are isolated from views; swapping sensors or motors won’t break the dashboard.
Deterministic Control
Calibrated PWM ranges and steering offsets yield smooth, repeatable movement.
Extendable to Vision/ML
Pipeline is ready for camera input and simple policies (e.g., Q-learning or rule weighting).
Challenges & Solutions
- Sensor Interference: Multiple ultrasonic reads conflicted → Added timing gaps and median filtering.
- Power Instability: Motor draw browned out the Pi → Isolated power rails and added caps.
- Steering Drift: Servo center varied across boots → Stored calibration (μs pulse) and applied offset.
What I Learned
- GPIO/I2C/PWM on Raspberry Pi and clean driver abstractions in Python.
- Designing Flask endpoints for low-latency control loops and status polling.
- How to structure embedded projects so the web UI and hardware evolve independently.
Next Steps
- Live MJPEG camera stream in the dashboard with recording toggle.
- CSV run logs + analytics page (distance vs. time, stop events, route decisions).
- Pluggable “policy” module: rule-based now; option for Q-learning or heuristic weighting later.