reduce number of predictions

This commit is contained in:
rishubm
2025-10-18 23:56:53 -05:00
parent 49b982ec97
commit de97719e52
18 changed files with 1083 additions and 22 deletions

View File

@@ -0,0 +1,294 @@
# Race Context Guide
## Why Race Context is Separate from Telemetry
**Enrichment Service** (port 8000):
- Provides: **Enriched telemetry** (changes every lap)
- Example: tire degradation, aero efficiency, ERS charge
**Client/Frontend**:
- Provides: **Race context** (changes less frequently)
- Example: driver name, current position, track info, competitors
This separation is intentional:
- Telemetry changes **every lap** (real-time HPC data)
- Race context changes **occasionally** (position changes, pit stops)
- Keeps enrichment service simple and focused
## How to Call Brainstorm with Both
### Option 1: Client Provides Both (Recommended)
```bash
curl -X POST http://localhost:9000/api/strategy/brainstorm \
-H "Content-Type: application/json" \
-d '{
"enriched_telemetry": [
{
"lap": 27,
"aero_efficiency": 0.85,
"tire_degradation_index": 0.72,
"ers_charge": 0.78,
"fuel_optimization_score": 0.82,
"driver_consistency": 0.88,
"weather_impact": "low"
}
],
"race_context": {
"race_info": {
"track_name": "Monaco",
"current_lap": 27,
"total_laps": 58,
"weather_condition": "Dry",
"track_temp_celsius": 42
},
"driver_state": {
"driver_name": "Hamilton",
"current_position": 4,
"current_tire_compound": "medium",
"tire_age_laps": 14,
"fuel_remaining_percent": 47
},
"competitors": []
}
}'
```
### Option 2: AI Layer Fetches Telemetry, Client Provides Context
```bash
# Enrichment service POSTs telemetry to webhook
# Then client calls:
curl -X POST http://localhost:9000/api/strategy/brainstorm \
-H "Content-Type: application/json" \
-d '{
"race_context": {
"race_info": {...},
"driver_state": {...},
"competitors": []
}
}'
```
AI layer will use telemetry from:
1. **Buffer** (if webhook has pushed data) ← CURRENT SETUP
2. **GET /enriched** from enrichment service (fallback)
## Creating a Race Context Template
Here's a reusable template:
```json
{
"race_context": {
"race_info": {
"track_name": "Monaco",
"current_lap": 27,
"total_laps": 58,
"weather_condition": "Dry",
"track_temp_celsius": 42
},
"driver_state": {
"driver_name": "Hamilton",
"current_position": 4,
"current_tire_compound": "medium",
"tire_age_laps": 14,
"fuel_remaining_percent": 47
},
"competitors": [
{
"position": 1,
"driver": "Verstappen",
"tire_compound": "hard",
"tire_age_laps": 18,
"gap_seconds": -12.5
},
{
"position": 2,
"driver": "Leclerc",
"tire_compound": "medium",
"tire_age_laps": 10,
"gap_seconds": -5.2
},
{
"position": 3,
"driver": "Norris",
"tire_compound": "medium",
"tire_age_laps": 12,
"gap_seconds": -2.1
},
{
"position": 5,
"driver": "Sainz",
"tire_compound": "soft",
"tire_age_laps": 5,
"gap_seconds": 3.8
}
]
}
}
```
## Where Does Race Context Come From?
In a real system, race context typically comes from:
1. **Timing System** - Official F1 timing data
- Current positions
- Gap times
- Lap numbers
2. **Team Database** - Historical race data
- Track information
- Total laps for this race
- Weather forecasts
3. **Pit Wall** - Live observations
- Competitor tire strategies
- Weather conditions
- Track temperature
4. **Telemetry Feed** - Some data overlaps
- Driver's current tires
- Tire age
- Fuel remaining
## Recommended Architecture
```
┌─────────────────────┐
│ Timing System │
│ (Race Control) │
└──────────┬──────────┘
┌─────────────────────┐ ┌─────────────────────┐
│ Frontend/Client │ │ Enrichment Service │
│ │ │ (Port 8000) │
│ Manages: │ │ │
│ - Race context │ │ Manages: │
│ - UI state │ │ - Telemetry │
│ - User inputs │ │ - HPC enrichment │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
│ │ POST /ingest/enriched
│ │ (telemetry only)
│ ▼
│ ┌─────────────────────┐
│ │ AI Layer Buffer │
│ │ (telemetry only) │
│ └─────────────────────┘
│ │
│ POST /api/strategy/brainstorm │
│ (race_context + telemetry) │
└───────────────────────────────┤
┌─────────────────────┐
│ AI Strategy Layer │
│ (Port 9000) │
│ │
│ Generates 3 │
│ strategies │
└─────────────────────┘
```
## Python Example: Calling with Race Context
```python
import httpx
async def get_race_strategies(race_context: dict):
"""
Get strategies from AI layer.
Args:
race_context: Current race state
Returns:
3 strategies with pit plans and risk assessments
"""
url = "http://localhost:9000/api/strategy/brainstorm"
payload = {
"race_context": race_context
# enriched_telemetry is optional - AI will use buffer or fetch
}
async with httpx.AsyncClient(timeout=60.0) as client:
response = await client.post(url, json=payload)
response.raise_for_status()
return response.json()
# Usage:
race_context = {
"race_info": {
"track_name": "Monaco",
"current_lap": 27,
"total_laps": 58,
"weather_condition": "Dry",
"track_temp_celsius": 42
},
"driver_state": {
"driver_name": "Hamilton",
"current_position": 4,
"current_tire_compound": "medium",
"tire_age_laps": 14,
"fuel_remaining_percent": 47
},
"competitors": []
}
strategies = await get_race_strategies(race_context)
print(f"Generated {len(strategies['strategies'])} strategies")
```
## Alternative: Enrichment Service Sends Full Payload
If you really want enrichment service to send race context too, you'd need to:
### 1. Store race context in enrichment service
```python
# In hpcsim/api.py
_race_context = {
"race_info": {...},
"driver_state": {...},
"competitors": []
}
@app.post("/set_race_context")
async def set_race_context(context: Dict[str, Any]):
"""Update race context (call this when race state changes)."""
global _race_context
_race_context = context
return {"status": "ok"}
```
### 2. Send both in webhook
```python
# In ingest_telemetry endpoint
if _CALLBACK_URL:
payload = {
"enriched_telemetry": [enriched],
"race_context": _race_context
}
await client.post(_CALLBACK_URL, json=payload)
```
### 3. Update AI webhook to handle full payload
But this adds complexity. **I recommend keeping it simple**: client provides race_context when calling brainstorm.
---
## Current Working Setup
**Enrichment service** → POSTs telemetry to `/api/ingest/enriched`
**AI layer** → Stores telemetry in buffer
**Client** → Calls `/api/strategy/brainstorm` with race_context
**AI layer** → Uses buffer telemetry + provided race_context → Generates strategies
This is clean, simple, and follows single responsibility principle!