Skip to content

Latest commit

 

History

History
218 lines (164 loc) · 8.59 KB

File metadata and controls

218 lines (164 loc) · 8.59 KB

ExitFlow — Post-Event Crowd Dispersal Copilot

Keeping crowds safe, one exit at a time.

ExitFlow is an AI-powered crowd dispersal system for large public events like concerts, stadium matches, and festivals. When 15,000 fans leave simultaneously, it prevents dangerous pile-ups by giving every attendee a personalized, staggered exit plan — and giving organizers a live control dashboard to manage bottlenecks in real time.


The Problem

When a major event ends, every attendee heads for the exits at the same moment. Gates hit 100% capacity within minutes. Transit nodes get overwhelmed. Crowd crushes happen. ExitFlow solves this by staggering departures across 45-minute windows, routing people by section, and using AI to adapt when things go wrong.


Chosen Vertical

Public Safety / Smart Events — preventing crowd crushes at post-event exits through AI-driven staggering, real-time density monitoring, and Gemini-generated interventions.


Live Demo

Surface URL
Landing page /
Attendee view (demo ticket) /attendee/TKT-00042
Organizer dashboard /dashboard

Tickets range from TKT-00001 to TKT-15000. Each maps to a different section, gate, wave, and transit option.


Features

For Attendees — /attendee/<ticket_id>

  • Personalized exit timeline — step-by-step: leave seat → walk to gate → board transit, each with a T+ offset from event end
  • Live crowd pressure gauge — real-time density at your assigned gate, colour-coded green/yellow/red, updates every 5 seconds
  • Gemini chat assistant — grounded in your specific plan (section, gate, transit, current crowd state). Handles questions like "Is there a quieter exit?", "Where's the nearest washroom?", "My child is lost"
  • Mobile-first design — large touch targets, calm soft-blue palette

For Organizers — /dashboard

  • Live Leaflet map of Wankhede Stadium and surroundings (real OpenStreetMap tiles, no API key needed)
  • Heatmap circles on all 8 gates — radius and colour scale with live density
  • Alert panel — fires when any gate exceeds 85% capacity for >10 seconds
  • Gemini intervention suggestions — each alert includes a specific, actionable instruction (e.g. "Redirect ~673 attendees from sections P, Q, R to Gate 8 via the east concourse")
  • AI Dispersal Strategy — Gemini 2.5 Pro rationale shown at the bottom of the panel
  • Aggregate stats bar: total attendees, walking, at-gate, % dispersed, avg wait, simulation clock

AI Integration (load-bearing, not decorative)

Gemini Call Model When
Dispersal strategy — wave assignments + rationale gemini-2.5-pro Once at startup
Attendee chat — context-aware personal guide gemini-2.5-flash Per chat message
Alert interventions — specific redirect instructions gemini-2.5-flash Per new bottleneck alert

All three have graceful fallbacks — the app runs fully without a Gemini API key.


Architecture

┌──────────────────────────────────────────────────────────┐
│                    FastAPI  (main.py)                     │
│                                                           │
│   GET /          GET /attendee/<id>    GET /dashboard     │
│   POST /api/chat  GET /api/crowd_state  GET /api/alerts   │
├──────────────────────────┬───────────────────────────────┤
│      simulator.py        │       gemini_client.py        │
│  • 15,000 attendees      │  • generate_dispersal_        │
│  • 20 sections, 8 gates  │    strategy()  [2.5-pro]      │
│  • 3 transit nodes       │  • chat_with_attendee()       │
│  • seated→walking→       │    [2.5-flash]                │
│    at_gate→dispersed     │  • generate_intervention()    │
│  • Background tick / 5s  │    [2.5-flash]                │
│  • Alert rule engine     │  • Result caching             │
└──────────────────────────┴───────────────────────────────┘

Frontend: Plain HTML · Tailwind CSS (CDN) · Vanilla JS
Maps:     Leaflet.js + OpenStreetMap (free, no key)
Deploy:   Single Docker container · Google Cloud Run

Venue

Hardcoded to Wankhede Stadium, Mumbai (IPL Final 2025 scenario):

  • 8 gates placed around the stadium perimeter
  • 3 transit nodes: Churchgate Metro Station, Marine Lines Bus Depot, Wankhede Taxi Stand
  • 20 seating sections (A–T), each with ~750 attendees

Simulation

Attendees move through states: seated → walking → at_gate → dispersed.
The sim runs at 20× real time — the full 45-minute dispersal window completes in ~135 real seconds. Gaussian noise on density figures makes the heatmap feel organic.


Running Locally

# 1. Clone the repo
git clone <repo-url>
cd ExitFlow-Claude

# 2. Create a virtual environment
python -m venv venv
venv\Scripts\activate        # Windows
# source venv/bin/activate   # macOS / Linux

# 3. Install dependencies
pip install -r requirements.txt

# 4. Add your Gemini API key (optional — app works without it)
cp .env.example .env
# Edit .env and set GEMINI_API_KEY=your_key_here

# 5. Run
uvicorn main:app --host 0.0.0.0 --port 8080 --reload

Then open:


Running with Docker

docker build -t exitflow .
docker run -p 8080:8080 -e GEMINI_API_KEY=your_key_here exitflow

Deploying to Google Cloud Run

# Authenticate and set project
gcloud auth login
gcloud config set project YOUR_PROJECT_ID

# Enable required APIs
gcloud services enable run.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com

# Build image remotely (no local Docker push needed)
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/exitflow .

# Deploy
gcloud run deploy exitflow \
  --image gcr.io/YOUR_PROJECT_ID/exitflow \
  --platform managed \
  --region asia-south1 \
  --port 8080 \
  --set-env-vars GEMINI_API_KEY=your_key_here \
  --allow-unauthenticated \
  --memory 512Mi

asia-south1 (Mumbai) is the closest region to the venue — lowest latency for the demo.


Project Structure

ExitFlow-Claude/
├── main.py              # FastAPI app — routes, lifespan, background tick
├── gemini_client.py     # All Gemini API calls with caching and fallbacks
├── simulator.py         # Venue data, 15k attendees, state machine, alerts
├── requirements.txt     # Pinned dependencies
├── Dockerfile           # python:3.11-slim, port 8080
├── .env.example         # GEMINI_API_KEY template
├── templates/
│   ├── index.html       # Landing page
│   ├── attendee.html    # Mobile attendee view
│   └── dashboard.html   # Organizer desktop dashboard
└── static/
    ├── css/custom.css   # Leaflet overrides, typing animation
    └── js/
        ├── attendee.js  # Crowd pressure polling, Gemini chat drawer
        └── dashboard.js # Leaflet map, heatmap circles, alert panel

API Reference

Method Endpoint Description
GET / Landing page
GET /attendee/{ticket_id} Attendee exit plan page
GET /dashboard Organizer live dashboard
POST /api/chat {ticket_id, message}{reply}
GET /api/crowd_state Gate densities, transit load, sim stats
GET /api/alerts Active bottleneck alerts with AI suggestions
GET /api/strategy Cached Gemini dispersal strategy text

Assumptions

  • All crowd density is simulated — no real sensor data
  • No authentication on any route (demo/prototype scope)
  • In-memory state only — restarting the server resets the simulation
  • Gemini calls are best-effort; fallback heuristics ensure the app is always usable

Google Services Used

Service Role
Gemini 2.5 Pro One-time dispersal strategy at event start
Gemini 2.5 Flash Real-time attendee chat assistant
Gemini 2.5 Flash Per-alert organizer intervention suggestions
Cloud Run Serverless container hosting (port 8080)
Cloud Build Remote Docker image build and push
Container Registry Docker image storage (gcr.io)