Real-time F1 race strategy system combining telemetry enrichment with AI-powered strategy generation. The system receives lap-by-lap telemetry from vehicle controller simulation, enriches it with performance analytics, and generates dynamic race strategies using Google Gemini AI before sending control updates back to the vehicle controller simulation.
The system consists of two main services:
-
Enrichment Service (
hpcsim/) - Port 8000- Receives raw telemetry from Raspberry Pi simulator
- Enriches data with tire degradation, pace trends, pit window predictions
- Forwards to AI Layer via webhook
-
AI Intelligence Layer (
ai_intelligence_layer/) - Port 9000- WebSocket server for real-time Pi communication
- Generates race strategies using Google Gemini AI
- Sends control commands (brake bias, differential slip) back to Pi
- Web dashboard for monitoring (visit port 9000 after starting the server to view the dashboard)
- Python 3.9+
- Google Gemini API key
# Install enrichment service dependencies
pip install -r requirements.txt
# Install AI layer dependencies
pip install -r ai_intelligence_layer/requirements.txtCreate ai_intelligence_layer/.env:
GEMINI_API_KEY=your_gemini_api_key_here
ENVIRONMENT=development
FAST_MODE=true
STRATEGY_COUNT=3Option A: Run both services together (recommended)
python3 scripts/serve.pyOptional downstream forwarding:
export NEXT_STAGE_CALLBACK_URL="http://localhost:9000/next-stage"
python3 scripts/serve.pyWhen set, every enriched record is also POSTed to the callback URL (best-effort, async). Ingestion still returns 200 even if forwarding fails.
Accepts raw Raspberry Pi or FastF1-style telemetry, normalizes field names, enriches it, stores a recent copy, and returns the enriched record.
- Content-Type: application/json
- Request body (flexible/aliases allowed):
- lap (int) — aliases: Lap, LapNumber
- speed (float, km/h) — alias: Speed
- throttle (0..1) — alias: Throttle
- brake (0..1) — aliases: Brake, Brakes
- tire_compound (string: soft|medium|hard|inter|wet) — aliases: Compound, TyreCompound, Tire
- fuel_level (0..1) — aliases: Fuel, FuelRel, FuelLevel
- ers (0..1) — aliases: ERS, ERSCharge (optional)
- track_temp (Celsius) — alias: TrackTemp (optional)
- rain_probability (0..1) — aliases: RainProb, PrecipProb (optional)
Example request:
Response 200 (application/json):
{
"lap": 27,
"aero_efficiency": 0.83,
"tire_degradation_index": 0.65,
"ers_charge": 0.72,
"fuel_optimization_score": 0.91,
"driver_consistency": 0.89,
"weather_impact": "medium"
}Errors:
- 400 if the body cannot be normalized/enriched
Accepts an already-enriched record (useful if enrichment runs elsewhere). Stores and echoes it back.
- Content-Type: application/json
- Request body:
- lap: int
- aero_efficiency: float (0..1)
- tire_degradation_index: float (0..1)
- ers_charge: float (0..1)
- fuel_optimization_score: float (0..1)
- driver_consistency: float (0..1)
- weather_impact: string (low|medium|high)
Example:
curl -s -X POST http://localhost:8000/enriched \
-H "Content-Type: application/json" \
-d '{
"lap": 99,
"aero_efficiency": 0.8,
"tire_degradation_index": 0.5,
"ers_charge": 0.6,
"fuel_optimization_score": 0.9,
"driver_consistency": 0.95,
"weather_impact": "low"
}'Returns an array of the most recent enriched records.
- Query params:
- limit: int (1..200, default 50)
Example:
curl -s "http://localhost:8000/enriched?limit=10"Response 200 example:
[
{ "lap": 27, "aero_efficiency": 0.83, "tire_degradation_index": 0.65, "ers_charge": 0.72, "fuel_optimization_score": 0.91, "driver_consistency": 0.89, "weather_impact": "medium" }
]Health check.
curl -s http://localhost:8000/healthzResponse 200 example:
{ "status": "ok", "stored": 5 }- Authentication/authorization is not enabled yet; add API keys or headers if deploying externally.
- Storage is in-memory (most recent ~200 records). For persistence, we can add Redis/SQLite.
- Forwarding to downstream (e.g., strategy LLM stage) is opt-in via
NEXT_STAGE_CALLBACK_URL.