# Software Architecture

The software stack is organized around a simple embedded control loop plus a cloud dashboard.

## Code Layers

| Layer | File | Responsibility |
| --- | --- | --- |
| Device control | [firmware/main.ino](../firmware/main.ino) | WiFi, Firebase REST calls, obstacle checks, command dispatch, GPS upload |
| GPS parsing | [firmware/gps_module.cpp](../firmware/gps_module.cpp) | UART NMEA parsing and decimal coordinate conversion |
| Motor control | [firmware/motor_control.cpp](../firmware/motor_control.cpp) | L298N movement primitives and PWM speed control |
| Dashboard UI | [dashboard/index.html](../dashboard/index.html) | Operator interface, route panel, and control surfaces |
| Dashboard logic | [dashboard/script.js](../dashboard/script.js) | Firebase sync, map rendering, OTP flow, animation, command writing |
| Firebase setup | [firebase/firebase-config.js](../firebase/firebase-config.js) | Project configuration and initialization |
| Database policy | [firebase/rules.json](../firebase/rules.json) | Access control for robot data and delivery data |

## Runtime Flow

```mermaid
sequenceDiagram
    participant Robot as ESP32 Firmware
    participant GPS as GPS Module
    participant US as Ultrasonic Sensor
    participant DB as Firebase RTDB
    participant UI as Web Dashboard

    Robot->>US: Read obstacle distance
    Robot->>GPS: Read NMEA sentence
    Robot->>DB: Push robotGPS and robotStatus
    UI->>DB: Read live telemetry
    UI->>DB: Write robotCommands
    DB-->>Robot: Deliver new motion command
    Robot->>DB: Update state after command execution
```

## Key Behaviors

- The firmware prioritizes safety over motion: obstacle detection runs before command execution.
- Firebase commands are polled on a short interval so manual control feels responsive.
- GPS and status updates are pushed as lightweight REST updates, which keeps the ESP32 logic simple and portable.
- The dashboard is intentionally decoupled from the firmware so the robot can keep running even if the UI is refreshed.
