Research-grade multi-agent reinforcement learning for smart city traffic optimisation.
TrafficFlowRL simulates a city grid of intersections where independent RL agents control traffic lights to minimise congestion, reduce vehicle wait times, and prioritise emergency vehicles โ all trained end-to-end with Proximal Policy Optimization (PPO).
Urban traffic congestion costs billions of hours and dollars annually. Traditional fixed-cycle traffic lights ignore real-time demand. TrafficFlowRL demonstrates how decentralised RL agents โ one per intersection โ can learn cooperative signal policies that:
- Minimise city-wide average wait time
- Maximise vehicle throughput
- Prioritise emergency vehicles (ambulances, fire trucks)
- Adapt to rush-hour patterns and weather conditions
trafficflowrl/
โโโ env/ # Gymnasium environment
โ โโโ city_env.py # Main CityTrafficEnv (Gymnasium API)
โ โโโ intersection.py # Traffic light phases & queues
โ โโโ vehicle.py # Vehicle entity with pathfinding
โ โโโ road_network.py # Grid graph (NetworkX)
โ โโโ traffic_generator.py # Vehicle spawning & rush hour
โ โโโ reward_system.py # Multi-component reward function
โ โโโ state_encoder.py # Observation normalisation
โโโ agents/
โ โโโ ppo_agent.py # Custom PPO with GAE
โ โโโ policy_network.py # Actor-Critic neural network
โโโ training/
โ โโโ train.py # Training loop with checkpointing
โ โโโ evaluate.py # Evaluation & statistics
โ โโโ config.py # Centralised hyper-parameters
โโโ visualization/
โ โโโ city_visualizer.py # Real-time Pygame renderer
โ โโโ training_dashboard.py # Matplotlib metrics dashboard
โโโ utils/
โ โโโ logger.py # CSV + JSON logging
โ โโโ seed.py # Reproducible seeding
โโโ requirements.txt
โโโ README.md
The environment simulates a configurable NรN grid of intersections (default 3ร3 = 9 intersections) connected by bidirectional roads. Vehicles spawn at city edges and follow the shortest path (BFS on the grid graph) to a random destination edge.
Each intersection produces a 7-dimensional observation vector:
| Index | Feature | Range | Description |
|---|---|---|---|
| 0 | North Queue | [0, 1] | Normalised queue length |
| 1 | South Queue | [0, 1] | Normalised queue length |
| 2 | East Queue | [0, 1] | Normalised queue length |
| 3 | West Queue | [0, 1] | Normalised queue length |
| 4 | Light Phase | {0, 1} | 0 = NS green, 1 = EW green |
| 5 | Phase Timer | [0, 1] | Normalised time since last switch |
| 6 | Emergency Flag | {0, 1} | 1 if emergency vehicle in queue |
Global observation = concatenation of all intersection vectors โ shape (N*N*7,) = (63,) for a 3ร3 grid.
MultiDiscrete โ one action per intersection:
| Action | Meaning |
|---|---|
| 0 | Set North-South green |
| 1 | Set East-West green |
| 2 | Keep current phase |
Actions have a minimum phase time constraint (default 3 steps) to prevent unrealistic rapid switching.
The reward is a weighted sum of five components, averaged across all intersections:
| Component | Value | Condition |
|---|---|---|
| Throughput | +1.0 | Per vehicle passing through intersection |
| Waiting penalty | โ0.5 | Per vehicle still waiting in queue |
| Emergency bonus | +5.0 | Emergency vehicle cleared quickly (โค5 steps) |
| Emergency penalty | โ5.0 | Emergency vehicle waited too long |
| Switch penalty | โ0.2 | Phase change occurred this step |
Input (7) โ Dense(256, ReLU) โ Dense(256, ReLU) โ Action Logits (3)
Input (7) โ Dense(256, ReLU) โ Dense(256, ReLU) โ Value (1)
A shared architecture is used for all intersections โ the same network weights process every intersection's local observation, enabling parameter-efficient scaling to larger grids.
| Parameter | Value |
|---|---|
| Episodes | 1,000 |
| Max steps/episode | 300 |
| Discount (ฮณ) | 0.99 |
| GAE ฮป | 0.95 |
| Learning rate | 3ร10โปโด |
| Batch size | 64 |
| Clip range (ฮต) | 0.2 |
| Entropy coeff | 0.01 |
| Value coeff | 0.5 |
| PPO epochs/update | 4 |
- ๐ Rush Hour Patterns โ sinusoidal traffic demand increases
- ๐ง๏ธ Weather Effects โ reduce vehicle speed dynamically
- ๐ Multiple Emergency Vehicles โ configurable probability
- ๐ Adaptive Traffic Demand โ spawn rate changes over time
pip install -r requirements.txtcd trafficflowrl
python training/train.pyWith bonus features:
python training/train.py --episodes 500 --rush-hour --weather --grid 3python training/evaluate.py --checkpoint checkpoints/ppo_traffic_best.pt --episodes 20python visualization/city_visualizer.py --checkpoint checkpoints/ppo_traffic_best.ptControls: [R] Reset episode ยท [ESC] Quit
python visualization/training_dashboard.py --log-dir logsFor Windows users a helper batch file is provided to run the common commands without typing long Python calls. From the project root, you can:
run.bat train # starts training using training/train.py with default args
run.bat evaluate # runs evaluation using training/evaluate.py
run.bat visualize # launches the Pygame visualizer with the best checkpointReplace the subcommand with train, evaluate, or visualize. You can also pass additional CLI flags which will be forwarded to the underlying Python script (for example run.bat train --episodes 500).
The real-time visualizer renders:
- ๐ข๐ด Traffic lights at each intersection with phase indicators
- ๐ Moving vehicles as coloured dots on the road network
- ๐ Emergency vehicles with red pulsing glow effects
- ๐ Stats panel showing step count, reward, queue lengths, and per-intersection details
The dashboard displays five smoothed metric plots:
- Episode reward curve (with moving average)
- Average wait time per episode
- Vehicles cleared per episode
- Policy loss convergence
- Value loss convergence
- Summary statistics panel
All hyper-parameters are centralised in training/config.py as a TrainingConfig dataclass. Modify defaults or pass CLI arguments:
from training.config import TrainingConfig
cfg = TrainingConfig(
grid_rows=4,
grid_cols=4,
total_episodes=2000,
enable_rush_hour=True,
enable_weather=True,
device="cuda",
)Vehicles use BFS shortest path on the NetworkX grid graph. Each vehicle stores its planned path and advances one intersection per green-light timestep.
Emergency vehicles bypass the traffic light phase โ they are always released from queues regardless of the current signal phase, simulating real-world signal pre-emption.
While agents are decentralised (each intersection acts independently), coordination emerges through:
- Shared parameters โ the same neural network processes all intersections
- Global reward signal โ averaged across intersections, encouraging cooperative behaviour
- Information flow โ queue build-ups from neighbouring intersections implicitly encode coordination signals
MIT License โ free for academic and commercial use.
Built for AI hackathon demonstrations and RL research. Contributions welcome!