Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VoltPilot logo VoltPilot — EV Road Trip Planner for India

Plan a confident EV road trip across India — real charging-stop simulation against your vehicle's actual battery profile, India-focused charger discovery from three merged data sources, live traffic-aware routing, and an AI Copilot that curates places to stop along the way.

Built as a full-stack portfolio project on free tiers and open data only — no paid APIs, anywhere.

React Node.js MapLibre GL JS Gemini Free tier only


🔗 Live Demo

Table of Contents


Product Showcase

Landing Page — Hero

Landing hero

Landing Page — Full Walkthrough

Landing page scroll walkthrough

Trip Planner Dashboard

Empty trip planner workspace, India-wide map

Vehicle Picker — 12 Brands, 37 Models

EV brand picker grid

Model & Variant Picker — Real Battery & Range Specs

EV model and variant picker with battery and range specs

Route Generation — Charging Stops Mapped End-to-End

Generated route with charging stops on the map

Full Trip Analytics — Distance, Time, Stops & Battery

Trip analytics: stat cards, battery-over-route chart, trip time breakdown

AI Trip Copilot — Curated Stops Along the Way

AI Copilot suggesting food and rest stops near charging stops

Full Planner Walkthrough

Full planner walkthrough


Features

Trip Planning & Routing

  • Turn-by-turn routing via OpenRouteService, rendered as a live polyline on a MapLibre GL JS map
  • Real battery/range simulation — real-world efficiency derived from claimed range, adjusted per-segment for elevation gain, a seasonal heat heuristic, and highway-vs-city road type
  • Automatic charging-stop planning — inserts charging stops along the route based on the selected vehicle's actual battery profile and the driver's start-charge / minimum-arrival-charge preferences
  • Alternative routes — requests a genuinely distinct second route where one exists, so the driver isn't silently stuck with whichever route the API picks first
  • Manual waypoints — add intermediate stops to route through, same way Google/Apple Maps let you add a stop
  • Live traffic overlay via TomTom, degrades gracefully if unavailable

Charger Discovery (India-focused)

  • Three merged data sources — e-AMRIT (Government of India / NITI Aayog public dataset), Open Charge Map, and OpenStreetMap Overpass — deduplicated by proximity + name similarity, since no single free source has adequate India coverage alone
  • Nearby-search and along-route charger queries

AI Trip Copilot

  • Gemini-powered curation of attractions, food, lodging, and amenities anchored to the actual route and charging stops, not arbitrary route-position windows
  • Wikipedia-enriched descriptions and images for points of interest
  • Preference-aware scoring (interests, dietary needs) with a tiered "curated, not chaotic" display cap
  • A no-LLM degraded fallback path so the feature never hard-fails if the AI call is unavailable

Vehicle Catalog

  • ~38 India-market EV models/trims with a verified flag per entry — premium/import figures are explicitly flagged pending manual OEM-spec cross-check rather than silently presented as certain

Design & Experience

  • GSAP-driven landing page: scroll-triggered hero scenes (intro → vehicle → trip → charging → destination) built around a cockpit/instrument-cluster visual motif
  • Interactive 3D charger-coverage globe (react-globe.gl + Three.js)
  • Product-preview sections reuse real dashboard components with real data — no hand-drawn mockups
  • Fully responsive: dedicated mobile drawer/bottom-sheet patterns for map controls, not just a squeezed desktop layout
  • Session-scoped trip persistence — a refresh restores your in-progress trip, but closing the tab clears it (no stale trips resurfacing days later, no cross-tab overwrite conflicts)
  • App-wide error boundary + custom 404 page

Backend Hardening

  • Per-endpoint rate limiting tuned to each free-tier API's actual quota (protects the shared Gemini/ORS quota from being burned by one script)
  • Helmet security headers, strict CORS allowlist, graceful SIGTERM/SIGINT shutdown for clean redeploys

Tech Stack & Data Sources

Frontend

Framework React 18 (Create React App) + React Router 6
Mapping MapLibre GL JS
Animation GSAP + @gsap/react
3D react-globe.gl + Three.js
Styling Tailwind CSS
Icons Phosphor Icons

Backend

Runtime Node.js + Express 5
AI @google/genai (Gemini)
Security Helmet, express-rate-limit, CORS

External APIs & Data — all free tier, verified zero-cost

Service Used for
OpenRouteService Turn-by-turn routing & directions
Open Charge Map EV charger data
e-AMRIT (NITI Aayog) Government of India public charging station dataset
OpenStreetMap Overpass Charger data + points of interest
Mappls (MapmyIndia) India-focused geocoding/autosuggest
TomTom Live traffic
Google Gemini AI Trip Copilot
Wikipedia Point-of-interest enrichment (descriptions/images)

Architecture

The frontend never talks to OpenRouteService, Open Charge Map, TomTom, Mappls, or Gemini directly — every external call is proxied through the backend, which is the only place any API key ever lives.

flowchart LR
    A[React Frontend] -->|REST| B[Express Backend]
    B --> C[OpenRouteService<br/>routing]
    B --> D[Open Charge Map]
    B --> E[e-AMRIT<br/>Govt. of India]
    B --> F[OSM Overpass]
    B --> G[Mappls<br/>geocoding]
    B --> H[TomTom<br/>traffic]
    B --> I[Google Gemini<br/>AI Copilot]
    B --> J[Wikipedia]
Loading

See docs/BACKEND_IMPROVEMENT_PLAN.md for the full backend design rationale.


Project Structure

Voltpilot/
├── frontend/                  React app (Create React App)
│   ├── src/
│   │   ├── components/        Shared UI primitives + landing-page sections
│   │   ├── features/
│   │   │   ├── dashboard/     AI Copilot panel, analytics, battery chart
│   │   │   ├── map/           MapLibre canvas, route layer, map controls
│   │   │   ├── planner/       Trip planner state + location fields
│   │   │   └── vehicles/      Vehicle showroom, brand grid, specs
│   │   ├── pages/              DashboardPage, LandingPage, NotFoundPage
│   │   ├── data/                Vehicle database (vehicles.json)
│   │   ├── utils/               Battery simulation, trip persistence
│   │   └── assets/              Optimized images, fonts, icons
│   └── public/
│
├── backend/                    Express API
│   ├── routes/                 route, chargers, geocode, copilot, traffic
│   ├── services/                Charger aggregation, AI trip planning,
│   │                            Wikipedia enrichment, POI clustering
│   └── middleware/              Rate limiters
│
├── docs/                        Project documentation
└── render.yaml                  Backend deployment config (Render)

Getting Started

1. Backend

cd backend
npm install
cp .env.example .env   # then fill in real values, see below
npm start               # http://localhost:5000

2. Frontend

cd frontend
npm install
npm start   # http://localhost:3000

Environment Variables

backend/.env

Variable Required? Notes
ORS_API_KEY Yes Free key from openrouteservice.org
GEMINI_API_KEY Recommended Free key from Google AI Studio. Powers /api/copilot/*; Copilot falls back to a degraded result if unset, rather than failing
MAPPLS_KEY Yes Free key from Mappls, used for India-focused geocoding
OCM_KEY Optional Free key from openchargemap.org. Charger coverage degrades gracefully to e-AMRIT + Overpass if unset
TOMTOM_API_KEY Optional Free key from TomTom Developer Portal. Traffic-aware routing degrades gracefully if unset
ALLOWED_ORIGIN Yes CORS allowlist, e.g. http://localhost:3000
PORT No Defaults to 5000

frontend/.env.local

Variable Notes
REACT_APP_API_BASE_URL Where the backend is running — http://localhost:5000 locally, or the deployed backend URL in production

The frontend never reads REACT_APP_ORS_KEY or REACT_APP_OCM_KEY — those API keys live server-side only.


Deployment (free tier)

  • Backend → Render free tier. Root directory backend/, set the env vars above in the dashboard. Free tier sleeps after inactivity — first request after idle takes ~30–60s to wake up.
  • Frontend → Vercel or Netlify free tier, static CRA build. Set the project's root/base directory to frontend/ in the platform dashboard, and REACT_APP_API_BASE_URL to the deployed Render URL.

Notable Engineering Decisions

  • Charger aggregation (backend/services/chargerAggregator.js) — merges and deduplicates e-AMRIT, Open Charge Map, and OSM Overpass by proximity + name similarity, since no single free source has adequate India coverage alone.
  • Range modeling (frontend/src/utils/batterySimulation.js) — real-world efficiency is derived from claimed range at a fixed real-world/claimed ratio, then adjusted per-segment for elevation gain, a static hot-season heuristic (no live weather API, by design), and highway-vs-city road type.
  • AI Copilot anchoring (backend/services/tripClusterer.js) — curated places are anchored to the trip's start/charging-stops/destination by real proximity radius, not naive route-position windows, so suggestions are actually reachable from where the driver will be stopped.
  • Rate limiting (backend/middleware/rateLimiters.js) — scoped per-endpoint to each external API's actual free-tier quota (Gemini's ~20 req/day shared quota is by far the tightest constraint), not a single blanket limit.
  • Session-scoped trip persistence (frontend/src/utils/tripPersistence.js) — deliberately sessionStorage, not localStorage: matches the actual need ("survive a refresh") without the staleness and cross-tab conflicts that permanent storage introduced.

License

Personal portfolio/student project. All rights reserved unless a LICENSE file is added.

About

Plan confident EV road trips across India. Real battery/range simulation per vehicle, charger discovery merged from 3 India-focused sources, live-traffic-aware routing, and a Gemini-powered AI Copilot for stops along the way built entirely on free-tier APIs, no paid services.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages