goatifi / README.md
KonoDioDaa's picture
Initial FlowTwin deployment
e7a9f02
|
Raw
History Blame Contribute Delete
15.3 kB
---
title: FlowTwin Crowd Race Control
emoji: 🏎️
colorFrom: red
colorTo: gray
sdk: gradio
sdk_version: 4.26.0
app_file: app.py
pinned: false
---
# FlowTwin — Crowd Race Control
**Predict. Simulate. Reroute.**
An AI-powered crowd digital twin for Formula 1 venues. FlowTwin observes how
spectators move, predicts where flow will break down, simulates candidate
interventions against an identical copy of the current crowd state, and
recommends the one that measurably performs best.
> Formula 1 has spent decades turning telemetry into strategy. The cars are not
> the only thing moving on race day. FlowTwin applies the same decision loop to
> the hundreds of thousands of people moving through finite gates, corridors and
> transport links.
```
SEE ──► PREDICT ──► SIMULATE ──► ACT ──► SEE again
```
---
## The problem
Crowd-flow failures at large venues are not a headcount problem. A venue can sell
out successfully while individual parts of its network fail. UK HSE event-safety
guidance is explicit that operators should monitor **spatial distribution**
entrances, exits, queues, concessions and pinch points — and anticipate problems
rather than react to them.
The 2022 Spanish Grand Prix is the case study this project is built around:
a reported 277,836 weekend attendance, documented severe road and public-transport
congestion, long concession queues, and Formula 1 publicly telling the promoter the
situation was not acceptable.
So the question FlowTwin answers is not *where is the crowd?* It is:
**Where will crowd flow fail, why, and which intervention should an operator
deploy before it does?**
---
## What it actually does
| Layer | What it is |
|---|---|
| **Venue digital twin** | Directed weighted graph: gates, grandstands, concourses, concessions, exits, transport interfaces. Edges carry length, width, capacity and live state. |
| **Crowd simulation** | Up to 40,000+ individual agents with their own walking speed, destination, route and compliance. Speed falls with local density; gates have per-minute throughput; corridors have finite storage, so congestion spills back upstream. |
| **Crowd State Engine** | Per corridor and zone: occupancy, density, inflow, outflow, velocity, capacity utilisation, density growth, queue growth, opposing flow, and a composite risk score. |
| **Prediction** | Gradient-boosted model trained on simulator ground truth, projecting density at +30 / +60 / +90 / +120 s and converting it into time-to-critical. |
| **Dynamic routing** | Edge costs from distance, live travel time, congestion and risk; next-hop tables recomputed from live state with hysteresis and route commitment to stop oscillation. |
| **Strategy Engine** | Candidate interventions generated from the venue topology around the detected bottleneck. |
| **Counterfactual simulator** | Every candidate is applied to a byte-identical clone of the live state and rolled forward. Same seed, same starting state, one variable. |
| **Optimizer** | Multi-objective score `J` over peak density, critical duration, travel time, risk, queue, throughput and reroute cost — normalised against the no-action outcome. |
| **Race Control UI** | Animated venue map, live alerts with cause and lead time, strategy comparison table, and a "why this strategy" panel built from the same numbers that produced the score. |
| **Perception** | A Hugging Face crowd model turns a real camera frame into the same observation schema the simulator produces, so everything downstream is identical in either mode. |
**The recommendation is a measurement, not a rule.** No language model is
anywhere in the decision path.
---
## Quick start
Requires Python 3.10+. No Node build step — the dashboard is served by the
backend.
```bash
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r backend/requirements-core.txt
./run.sh # Windows: run.bat
```
Open **http://127.0.0.1:8000**.
Optional extras:
```bash
pip install -r backend/requirements.txt # adds torch/transformers for perception
python scripts/fetch_hf_model.py # download + verify the HF crowd model
python scripts/train_predictor.py # retrain and re-validate the predictor
python scripts/run_benchmarks.py --seeds 8 # regenerate the benchmark table
python scripts/record_fallback.py # record demo-fallback runs
cd backend && python -m pytest # test suite
```
---
## The two demonstrations
### Simulation 1 — F1 Circuit Stress Test
A fictional but realistically proportioned Grand Prix venue: four perimeter
exits, six spectator zones, a full concourse ring, three concession clusters, two
transport interfaces. 40,000 spectators leave at once over an 18-minute departure
curve. At T+240 s, **Exit B loses half its throughput** — a scripted
infrastructure failure that is a real change to the simulated network, not an
annotation.
What you see: normal flow → the East Concourse approach begins to compress →
FlowTwin projects it going critical → eight candidate strategies are simulated →
a recommendation with its reasoning → apply it → the crowd redistributes and the
queue falls.
This is the technical proof.
### Simulation 2 — Barcelona 2022 Counterfactual
A simplified spectator and transport network for the Circuit de
Barcelona-Catalunya, run at race-day scale under the documented 2022 conditions.
**This is a counterfactual reconstruction using publicly documented event
conditions and a synthetic crowd model. It is not a replay of original spectator
telemetry, which is not public.** The dashboard separates the two explicitly:
every documented fact carries its source, and every modelling assumption is
labelled as one. Both lists are on screen throughout.
| Documented | Modelled |
|---|---|
| 277,836 reported weekend attendance | Spectator distribution across stands |
| 120,000+ reported on race day | Departure-mode split (rail / coach / car parks) |
| Severe road and public-transport congestion reported | Corridor widths and capacities |
| Long concession queues reported | Rail approach throughput |
| F1 publicly called the situation not acceptable | Departure curve shape |
| Circuit length 4.675 km, 2022 configuration | Schematic venue geometry |
The question it answers is *"given the documented conditions, what would FlowTwin
have recommended?"* — never *"this is what happened."*
---
## Measured results
Generated by `scripts/run_benchmarks.py` across independent random seeds of the
full simulation. Mean ± standard deviation. **No value here is entered by hand**;
the numbers below are reproduced from `benchmarks/BENCHMARKS.md`, which the
script rewrites on every run.
Three arms on identical scenarios and seeds:
- **Shortest path** — Baseline A: everyone walks the shortest route, no operator action.
- **Static routing** — Baseline B: a capacity-aware plan computed before the event and never revised.
- **FlowTwin** — the full loop: predict, evaluate candidates against clones of its own state, apply the measured optimum, repeat on a review cycle.
See `benchmarks/BENCHMARKS.md` for the current table and
`benchmarks/benchmark_results.json` for every individual run, including which
intervention was chosen at each review point.
### What the results say
**Simulation 1 — the safety gain is close to free.** Peak density at the
degraded exit falls by roughly half, time spent in critical conditions goes to
zero, and the largest queue falls by about 60% — while average journey time gets
slightly *shorter*, not longer, and the venue still clears.
**Barcelona — the safety gain costs something, and the numbers say so.** Peak
density and maximum queue fall by 40–50% and critical exposure again goes to
zero, but average journey time rises by a few per cent and the 95th percentile
by more. That is the honest trade: relieving a saturated rail interface means
walking some people further. The optimizer weights travel time explicitly, so
this is a trade it made deliberately and reports, not one it hid.
**The two scenarios get different answers.** On the circuit, the winning lever is
usually a redirect or a staggered release — there is spare capacity at another
exit. At Barcelona the winner is often a *destination split*, because you cannot
reroute around a saturated rail terminus; you have to move demand to another
mode. A system that returned "redirect 30%" to everything would not be doing the
work.
**Static routing is not always different from shortest path.** In the
reconstructed Barcelona topology the two baselines produce identical results,
because most origin–destination pairs have effectively one sensible route. A
pre-event plan cannot help when the network offers no alternative — which is part
of why the real event's transport interface was the thing that failed.
Prediction accuracy is validated on **disjoint seeds** from training and reported
in the dashboard under *Model accuracy* — including the analytic mass-balance
baseline it must beat. If the trained model does not beat that baseline on
held-out data, FlowTwin refuses to load it and falls back to the baseline rather
than presenting an unvalidated prediction.
---
## Hugging Face integration
Perception is a genuine input to the engine, not a decorative dependency:
```
camera frame ──► HF crowd model ──┐
├──► crowd observation ──► Crowd State Engine
synthetic agents ───────────────────┘ (density, risk,
prediction, strategy)
```
Both observation modes converge on one schema, so nothing downstream can tell —
or needs to tell — which one is feeding it.
The model is resolved through a candidate chain, first one that loads wins:
1. `AbdurRahman011/csrnet-indian-metro-crowd-density` — density-map regression (specification candidate A). CSRNet's architecture is defined locally in `perception/csrnet.py` so a bare checkpoint can be loaded.
2. `AmineSam/irail-crowd-counting-yolov8n` — head detection on the RPEE-Heads dataset (specification candidate B), via `ultralytics`.
3. `hustvl/yolos-tiny`, then `facebook/detr-resnet-50` — widely mirrored COCO detectors, counting the `person` class.
Override with `FLOWTWIN_HF_MODEL`. Run `scripts/fetch_hf_model.py` to download,
select and verify with a real inference; it writes `models/perception_manifest.json`
recording which model was chosen.
**If no model loads, the endpoint reports the actual error and returns nothing.
It never invents a count.** The dashboard's Perception panel shows the chain, the
active model, and every load failure verbatim.
---
## Reproducibility
Every run is fully determined by `(venue, scenario, seed, overrides)`. The random
generator state travels with the simulation snapshot, so a counterfactual branch
is exactly reproducible and two strategies are always compared from an identical
starting state. The seed is displayed on the dashboard and returned by the API.
```bash
POST /api/simulation/start
{ "venue_id": "circuit_alpha", "scenario_id": "circuit_alpha_post_race", "seed": 42193 }
```
The test suite asserts this directly: same seed reproduces identical output,
different seeds diverge, snapshot/restore is exact, and two branches of one state
produce identical metrics.
---
## Project layout
```
flowtwin/
├── backend/flowtwin/
│ ├── venue/ graph + scenario schema and loaders
│ ├── simulation/ agents, movement physics, the simulator
│ ├── crowd/ density, flow, state engine, bottleneck detection
│ ├── prediction/ features, trained model, inference
│ ├── routing/ dynamic edge costs, next-hop tables
│ ├── strategy/ interventions, counterfactuals, optimizer
│ ├── perception/ Hugging Face crowd model + CSRNet architecture
│ ├── runtime/ sessions, WebSocket broadcast, replay
│ ├── benchmarks/ evaluation harness
│ └── api/ REST + WebSocket
├── frontend/ Race Control dashboard (no build step)
├── data/ venues, scenarios, fallback recordings
├── scripts/ venue builder, training, benchmarks, HF fetch, UI check
├── docs/ ARCHITECTURE.md, DEMO.md
└── benchmarks/ generated results
```
## API
| Endpoint | Purpose |
|---|---|
| `GET /api/meta` | Version, prediction accuracy, perception status, config |
| `GET /api/venues` · `/api/venues/{id}` | Venue graph and provenance |
| `GET /api/scenarios` | Scenario catalogue |
| `POST /api/simulation/start` | Start a run |
| `GET /api/simulation/{id}/state` | Current crowd state |
| `POST /api/simulation/{id}/control` | play / pause / speed / step / run_to / trigger_event |
| `POST /api/simulation/{id}/strategy/simulate` | Run the counterfactual sweep |
| `POST /api/simulation/{id}/strategy/apply` | Apply a strategy to the live run |
| `GET /api/simulation/{id}/alerts` · `/prediction` | Alerts, projections |
| `POST /api/perception/analyze` | Hugging Face crowd observation |
| `GET /api/benchmarks` | Measured benchmark results |
| `WS /api/ws/simulation/{id}` | Live state stream |
Interactive docs at `/docs`.
---
## Limitations
Stated plainly, because they are the difference between a prototype and a claim:
- Synthetic agents are not people. The movement model reproduces the *phenomena* that matter for this decision — speed collapse under density, throughput limits, spillback, partial compliance — not human behaviour in general.
- Public historical information cannot reproduce original venue telemetry. Barcelona is a documented-condition counterfactual with labelled assumptions.
- Density thresholds are context-dependent. The warning/critical values are venue configuration, presented as an operational scale, not a safety standard.
- Camera-based counting undercounts dense or occluded crowds. The perception result says so alongside every count.
- Real deployment would require venue-specific calibration, sensor integration and operational validation.
- **FlowTwin is decision support.** It shows a recommendation, its cause, its lead time and its expected outcome. A trained human operator makes the call. It does not control gates or emergency systems and cannot guarantee that any incident is prevented.
## Licence and data
Venue geometry is fictional (Circuit Alpha) or schematic (Barcelona). No personal
data is collected, required or stored: the system needs position, density and
flow, never identity.
## Documentation
| File | What it is |
|---|---|
| `README.md` | This file — overview, setup, results |
| `docs/ARCHITECTURE.md` | How it is built and why each decision was made |
| `docs/DEMO.md` | Timed demo script, fallbacks, judge questions |
| `docs/SPEC_AUDIT.md` | Every spec requirement checked, plus the ten engine defects found and fixed |
| `docs/ROADMAP.md` | Known gaps and what to fix next |
| `benchmarks/BENCHMARKS.md` | Generated results table |