Use to navigate
LIVE IN PRODUCTION · JUNE 2026
B.Tech Final Project · Dept. of Information Technology · Gauhati University

RoadSense

Real-Time Road Hazard Detection, Geo-Mapping & Driver Alerting System

An end-to-end IoT pipeline that uses inertial measurement and GPS to detect road anomalies, encodes their locations using the Geohash spatial index, persists them on a globally distributed edge database, and delivers real-time audio proximity alerts to drivers — fully operational, not a proof-of-concept.

Ricky Kashyap
Roll No: 230103010
Kangkan Nath
Roll No: 230103018
IoT · Embedded Systems ESP32 · FreeRTOS Firmware Cloudflare Edge Computing Geohash Spatial Indexing Haversine Distance Algorithm LoRa Mesh Networking (v2) Mapbox GL JS · Web Speech API
01 — Problem Domain

Why India's roads need automated monitoring

🚗 India records ~3,500 deaths per year directly attributable to potholes (MoRTH, 2023). Vehicle damage costs the national economy an estimated ₹50,000 crore annually — a figure that grows with every delayed repair.

⏱️

Reactive Discovery Pipeline

Authorities are informed of road defects only after a citizen complaint is filed — often weeks after the hazard first forms. There is no continuous, automated monitoring pipeline in place for Indian urban roads.

👷

O(n) Manual Survey Scaling

Traditional inspection requires field workers to physically visit every road segment. The workforce requirement scales linearly with road length — completely impractical for a network of 63 lakh kilometres. Surveys are also subjective and inconsistent.

💸

Cost-Prohibitive Existing Tech

LiDAR-based survey vehicles cost ₹10 lakh+ per unit and require expert operators. Vision-based ML systems need GPU inference hardware and fail in rain or low-light. Neither approach is deployable at scale across Indian cities.

3,500
Annual pothole deaths (India)
63L km
Total road network
₹50K Cr
Annual vehicle damage cost
0
Public real-time hazard APIs

⚖️ Technology Comparison

ApproachUnit CostWeather-proofScalableCompute
LiDAR Survey₹10L+YesNoHigh
Vision / ML Camera₹50K+NoPartialHigh
RoadSense (IMU)₹1,800YesYesLow

💡 Research gap addressed: Vibration-based IoT detection paired with cloud-backed real-time geo-mapping fills the intersection of low cost, weather resilience, and scalability — previously unexplored in the Indian road monitoring context.

02 — System Architecture

Three-layer event-driven pipeline — sensor to screen

🚗
Hardware Layer
ESP32 + BMI160 IMU
+ NEO-M8N GPS
Custom PCB Enclosure
📡
Transport Layer
HTTPS · REST
JSON payload
Wi-Fi / 4G LTE
⚙️
Edge API Layer
Cloudflare Workers
V8 Isolate Runtime
CORS · Routing
🗄️
Data Layer
Cloudflare D1 SQLite
Geohash Spatial Index
Cloudflare R2 Blobs
🌐
Presentation Layer
Mapbox GL JS
Haversine Alerting
Web Speech API
🔩

Hardware Layer

The ESP32 runs two concurrent FreeRTOS tasks — one for continuous IMU sampling at 100 Hz and one for Wi-Fi network operations. This dual-core approach ensures sensor polling is never blocked by network I/O. The GPS produces NMEA 0183 sentence streams that are buffered and parsed in real time to extract latitude and longitude.

FreeRTOS Dual-Core100Hz IMU pollingNMEA Parsing
☁️

Edge Cloud Layer

Cloudflare Workers run in V8 JavaScript isolates — the same engine powering Chrome — at over 300 global Points of Presence. Unlike traditional serverless functions, V8 isolates have no cold-start delay and share memory across requests, making them ideal for latency-sensitive IoT ingestion workloads.

V8 Isolate · Zero Cold Start300+ Global PoPs
📐

Presentation Layer

The front-end uses the Haversine formula to compute great-circle distance between the user's live GPS coordinates and every stored hazard. When this distance falls below 50 metres, the Web Speech API synthesizes a real-time audio warning. Mapbox GL JS renders hazard markers on a dark vector tile map with severity-based colour coding.

Haversine DistanceWeb Speech APIMapbox GL v2

📐 Design Pattern: Fully event-driven — each sensor event independently triggers the entire pipeline without polling between layers. Each layer exposes a clean REST interface, making any component swappable without affecting the others.

03 — Hardware Layer

IoT Sensor Node — Components, Protocols & Physics

🧠

ESP32-WROOM-32 — The Central Processing Unit

An Xtensa dual-core LX6 processor running at 240 MHz with 520 KB of SRAM. The device runs Espressif's port of FreeRTOS, allowing the sensor-reading task and the network-transmission task to execute concurrently on separate cores. Between events, the ESP32 enters light-sleep mode to reduce power draw, waking on an IMU interrupt pin. Built-in 802.11 b/g/n Wi-Fi handles cloud upload.

240 MHz · Xtensa LX6FreeRTOSWi-Fi 802.11 b/g/n
🛰️

u-blox NEO-M8N — Multi-Constellation GPS

Simultaneously tracks GPS, GLONASS, and Galileo satellite constellations, achieving a 2.5-metre Circular Error Probable (CEP) horizontal accuracy. It communicates over UART2 (TX→Pin 16, RX→Pin 17) at 9600 baud, streaming standard NMEA 0183 sentences. The GGA sentence — parsed by the firmware — contains latitude, longitude, fix quality, and satellite count. Cold-start acquisition takes ~26 seconds; hot-start (recent almanac cached) takes ~1 second.

UART2 · 9600 baudNMEA 0183 GGA2.5m CEP · Multi-GNSS
📐

Bosch BMI160 — 6-DoF Inertial Measurement Unit

Integrates a 3-axis accelerometer (±2g to ±16g selectable) and a 3-axis gyroscope (±125 to ±2000°/s) in a single package. Connected over I2C (SDA→GPIO 22, SCL→GPIO 23) at 400 kHz. The Z-axis (vertical) is the primary detection axis — a vehicle hitting a pothole produces a sharp, transient spike on Z, while a speed breaker produces a sustained, bilateral Z-axis deflection. Gyroscope data disambiguates the two patterns.

I2C 400 kHz6-DoF · ±16g rangeSDA→22 · SCL→23
3D Front Box
Fig 1 — 3D-printed top shell (Autodesk Fusion 360) · USB, GPS antenna & cable pass-through cutouts
3D Backplate
Fig 2 — Mounting backplate · M3 brass standoffs · vehicle adhesive mounting points

💰 Total Bill of Materials: ~₹1,800 — ESP32 module (₹400), NEO-M8N GPS (₹900), BMI160 IMU (₹200), PCB fabrication + passives (₹300). Designed for mass fleet deployment at minimal unit cost.

04 — Detection & Spatial Algorithms

How the system detects, classifies & locates hazards

1

Adaptive Baseline Calibration (2 minutes)

On power-on, the firmware samples the Z-axis accelerometer at 100 Hz for exactly 120 seconds — collecting 12,000 readings. The arithmetic mean of this window becomes the vehicle-specific baseline acceleration for normal driving on the current surface. This self-calibration absorbs variation in mounting angle, vehicle suspension stiffness, and road surface type — eliminating the need for manual tuning per vehicle.

2

Threshold Computation — 40% Rule

The trigger threshold is set at 1.40 × baseline. Any incoming Z-axis sample that exceeds this value is flagged as a potential hazard event. The 40% margin was chosen empirically to reject ordinary road unevenness while reliably capturing potholes and speed breakers. A 500ms lockout window follows each detection to prevent the same hazard from being logged multiple times.

3

Hazard Type Classification via Gyroscope

When a Z-axis spike is detected, the gyroscope's X-axis (pitch) rate is analysed over a 200ms window. A sharp transient spike (abrupt entry and exit) combined with a high gyro-X rate (>15°/s) indicates a pothole — the vehicle dips suddenly. A slower, symmetric Z-axis profile with minimal gyro-X change (<5°/s) indicates a speed breaker — the vehicle rises and falls gradually.

4

Severity Score Calculation

The severity score is defined as the ratio of the detected acceleration to the baseline: severity = acc_z ÷ baseline. This produces a normalised, vehicle-agnostic severity index. A severity score above 7.0 is classified as critical — rendered as a pulsing red marker on the map — while scores below 7.0 are moderate, shown in amber.

5

Offline Queue — SPIFFS Flash Buffer

If the Wi-Fi connection is unavailable at the time of detection, the event payload is serialised and written to the ESP32's SPIFFS (SPI Flash File System) — an on-chip flat-file storage area. A background task continuously monitors connectivity and drains the FIFO queue to the cloud once a connection is restored, ensuring zero data loss even in areas with intermittent coverage.

🔲

Geohash — Spatial Encoding Algorithm

Every detected hazard's latitude-longitude pair is encoded into a Geohash string before being stored. Geohash is a hierarchical, base-32 geocoding system that maps the Earth's surface into a grid of rectangular cells. Each additional character added to the hash narrows the cell by roughly a factor of 32.

RoadSense uses 5-character Geohash precision, which corresponds to a cell size of approximately 4.9 km × 4.9 km. Two hazards that share the same 5-character geohash prefix are guaranteed to be within the same geographic cell.

This enables extremely fast bounding-box spatial queries on the database: instead of computing the distance between a user's location and every stored hazard — an O(n) scan — the server calculates the Geohash of the user's region and retrieves only hazards whose geohash matches that prefix. The B-tree index on the geohash column reduces this to O(log n).

Base-32 Encoding5-char · ~4.9km cellO(log n) spatial query
📏

Haversine Formula — Real-Time Proximity Alerting

On the client side, the Haversine formula computes the great-circle distance — the shortest path over the Earth's curved surface — between the driver's live GPS coordinate and each hazard point. Unlike Euclidean distance (which assumes a flat surface), Haversine accounts for the Earth's spherical geometry, yielding accurate results at the metre level over city-scale distances.

The formula uses the angular differences in latitude (Δφ) and longitude (Δλ), converts them to radians, and applies the arc-tangent of the square-root-of-sum-of-squares to produce a central angle. Multiplied by Earth's radius (~6,371 km), this yields distance in metres. The computation is O(1) per hazard point and runs continuously as the GPS updates.

Great-Circle Distance50m trigger radiusO(1) per point
05 — Backend Infrastructure

Edge-native serverless architecture on Cloudflare

⚙️

Cloudflare Workers — V8 Isolate Runtime

Each incoming HTTP request is handled by a Worker running inside a V8 JavaScript isolate — the same engine used in Chrome. Unlike traditional Lambda functions that spin up a container, V8 isolates are pre-warmed and share a single process. This eliminates cold-start latency entirely. Workers are deployed to all 300+ Cloudflare PoPs simultaneously, so the device always hits the geographically nearest server, minimising round-trip time.

🗄️

Cloudflare D1 — Distributed Edge SQLite

D1 is Cloudflare's globally distributed relational database built on SQLite. It replicates data across PoPs using a primary-replica model, ensuring read queries are served from the nearest edge replica. The hazards table carries two performance-critical B-tree indexes: one on the geohash column for spatial prefix queries and one on the severity column for filtering critical hazards — both reducing query time from O(n) full-scan to O(log n).

📦

Cloudflare R2 — Zero-Egress Object Storage

An S3-compatible object store with no egress fees. Currently used as a staging area for bulk telemetry exports and future binary data (e.g. IMU waveform recordings). R2 integrates directly with Workers, meaning data can be written to the object store inside the same request handler that writes to D1, with no additional network hop.

🏠

Self-Hosted Home Lab + Cloudflare Tunnel

A local Linux server is used for development, staging, and redundant testing. It is exposed to the internet via Cloudflare Tunnel — an outbound-only encrypted connection — so no ports need to be opened on the home network. This allows it to receive production traffic through Cloudflare's proxy without any public IP exposure.

🗃️ Database Schema Design

The hazards table is the central data store. Each row represents one sensor event and stores geographic position (lat/lng), hazard classification, severity ratio, a 5-character geohash for spatial indexing, the originating device ID, vehicle speed at time of detection, and an automatic timestamp. A separate users table supports future authenticated reporting.

ColumnTypePurpose
lat, lngREALGeographic coordinates
typeTEXTpothole | speed_breaker
severityREALG-force ratio (acc ÷ baseline)
geohashTEXT5-char spatial index key
device_idTEXTSource IoT unit identifier
speed_kmhREALVehicle speed at detection
created_atDATETIMEAuto UTC timestamp

🌐 REST API Contract

The Worker exposes four endpoints. Every response includes CORS headers to permit browser and mobile app access. The POST endpoint computes and stores the geohash server-side, so the device only needs to send raw lat/lng.

MethodEndpointAction
GET/api/hazardsAll hazards as JSON array
GET/api/search?q=Filter by location_name prefix
POST/api/reportIngest new device event
GET/api/bboxGeohash bounding-box query

📡 Seed Data Strategy: Initial hazard data for Guwahati (Ganeshguri, Dispur) and Delhi (Connaught Place) was manually inserted via SQL to populate the map before live device deployment — enabling front-end testing with realistic geographic distribution.

06 — Results, Testing & Complexity Analysis

System performance & what we measured

<100ms
End-to-end latency (IoT→DB)
50m
Haversine alert radius
40%
IMU trigger threshold above baseline
₹1,800
Full hardware BOM

⚡ Latency Analysis — Why Edge Wins

The end-to-end latency from ESP32 POST to D1 write acknowledgement averages under 100ms. This is achieved because Cloudflare Workers run inside the same data centre that terminates the TCP connection — the request never leaves the PoP to reach a central server. In traditional cloud architectures (e.g. AWS Lambda in a single region), a device in Guwahati would incur 180–250ms of additional RTT to reach a Mumbai or Singapore region.

📐 Algorithm Complexity Summary

OperationComplexityNotes
Baseline calibrationO(n) time, O(1) spaceSingle-pass running mean
Per-sample IMU detectionO(1)Single comparison per sample
Geohash encodingO(p)p = precision (5 chars)
DB spatial query (geohash)O(log n)B-tree index prefix scan
Haversine per hazardO(1)Runs across all m hazards = O(m)
Full-table scan (no index)O(n)Avoided by geohash index

🧪 Testing — Node.js ESP32 Simulator

Because physical road testing at scale is impractical, a Node.js simulator was built to mimic the ESP32 hardware. It generates random hazard events at coordinates sampled uniformly within the Guwahati geographic bounding box (lat 26.08–26.20, lng 91.68–91.82), POSTing them to the live API at a configurable rate. This enabled load testing, UI validation, and geohash query verification without a physical device.

📊 Scalability Model

The serverless model has near-zero idle cost and scales horizontally with zero configuration. Cloudflare automatically routes each incoming request to any available Worker instance across the global PoP network. The D1 database handles read replicas automatically. To support a hypothetical deployment of 10,000 devices simultaneously reporting once per second, no architectural changes are needed — only the D1 write throughput tier needs upgrading.

Auto-scale · 0 ops overhead0 idle compute cost

⚠️ Limitations & Root Causes

Fixed Vehicle Threshold

The 1.40× multiplier is vehicle-agnostic. A 15-tonne bus produces 3× the impact G-force of a motorcycle for the identical pothole. This causes under-detection on heavy vehicles and over-detection on lightweight ones. Addressed in future work via TinyML vehicle classification.

GPS NLOS Multipath Error

In dense urban areas like Paltan Bazar, satellite signals reflect off buildings before reaching the antenna (Non-Line-Of-Sight), degrading positional accuracy to 8–15m. Mitigated by the Geohash cell granularity — at 5-char precision, a 15m error stays within the same cell.

GPS Cold-Start Window

The NEO-M8N requires ~26 seconds to acquire a satellite fix from a cold state. Events detected during this window are buffered in SPIFFS with a null coordinate and flushed once a fix is obtained.

07 — Future Roadmap & Research Extensions

What's next for RoadSense

📶

LoRa Mesh Crash Detection & Emergency Alerting

Priority v2 Feature

Each RoadSense device will gain a LoRa SX1278 radio module (915 MHz ISM band, ~5km range per hop). When an extreme crash event is detected — defined as a G-force spike exceeding 20g with simultaneous multi-axis gyroscope saturation — the device cannot wait for a Wi-Fi connection. It instead broadcasts a compact crash packet (<250 bytes, AES-128 encrypted) over LoRa.

MESH PROPAGATION — FLOOD-FILL WITH TTL DECREMENT
💥
Device A
CRASH
TTL=6
📡
Device B
relay
TTL=5
📡
Device C
relay
TTL=4
🌐
Device D
Wi-Fi
gateway
🚨
Auth.
Server
alert!
🔁 Flood-fill routing with TTL: Every device that receives a crash packet re-broadcasts it once, decrementing a Time-To-Live counter. When TTL reaches zero, propagation stops. A unique packet ID prevents any device from forwarding the same packet twice, preventing broadcast storms.
🌐 Wi-Fi gateway: The first mesh node that has an active Wi-Fi connection uploads the crash event to the cloud API. The packet carries the original GPS coordinates of the crash site — not the relay's position.
🚒 Dual-channel alert: The server simultaneously notifies (1) central emergency authorities via HTTP webhook and (2) all RoadSense devices within a 2km radius via a reverse LoRa broadcast, warning nearby drivers of the crash ahead.
🤖
TinyML On-Device Hazard Classification Deploy a quantized 8-bit integer CNN (~50 KB) trained on labelled IMU waveform datasets directly on the ESP32's 4MB flash. The model classifies hazard type from the full 200ms vibration signature — far more robust than heuristic gyroscope thresholding. Eliminates the fixed-threshold vehicle bias limitation entirely.
📊
Dynamic Vehicle-Aware Thresholding At journey start, the system analyses the low-frequency vibration signature during the first 30 seconds of motion to classify vehicle type (heavy/medium/light). The threshold multiplier is then selected from a lookup table calibrated per vehicle class, reducing false positives by an estimated 35% based on simulation.
🚌
City Bus Fleet Crowd-Sourcing Deploy RoadSense nodes passively across all ~200 Guwahati city buses. Each bus continuously maps its fixed route. Because buses repeat the same routes multiple times per day, every hazard accumulates multiple severity readings — enabling confidence-weighted averaging that suppresses one-off sensor noise.
🗺️
Weighted Graph Route Optimisation Model the road network as a weighted directed graph where each edge weight is the rolling average severity score of that road segment. Expose a shortest-safe-path API — built on a modified Dijkstra's algorithm — that emergency vehicles and fragile cargo logistics fleets can query for the smoothest available route between two points.
🏛️
Municipal SLA Dashboard A role-restricted admin portal for PWD / NHAI officials. Each unresolved hazard above a severity threshold automatically generates a repair ticket with a priority score derived from severity × reported frequency × road classification (national highway vs. local road). SLA timers track time-to-repair. Hazards auto-expire once subsequent sensor readings confirm severity has dropped below threshold.
🌐
Open Public API + Community Reporting Publish a rate-limited, API-key-authenticated REST API for third-party consumption (navigation apps, civic dashboards). Allow citizens to manually report hazards via the mobile app with an optional photo attachment stored in R2. Cross-reference manual reports with IoT data to compute a combined confidence score per hazard.
LIVE IN PRODUCTION · GUWAHATI & DELHI

Thank You.

RoadSense demonstrates that a ₹1,800 IoT node, a few kilobytes of firmware, and a globally distributed edge database can outperform traditional infrastructure monitoring at a fraction of the cost — and scale infinitely.

Built by Ricky Kashyap & Kangkan Nath

3
Architecture Layers
2
Cities Live
5+
Core Algorithms
Fleet Scale Potential
ESP32 · FreeRTOS · C++ BMI160 IMU · Z-axis detection Geohash · Haversine · Dijkstra (v2) Cloudflare Workers · D1 SQLite Mapbox GL JS · Web Speech API LoRa Mesh · Flood-fill TTL routing (v2)

Dept. of Information Technology · Gauhati University · June 2026