Added consideration of race position and gap to ahead cars

This commit is contained in:
Aditya Pulipaka
2025-10-19 04:28:49 -05:00
parent 098d881d15
commit 47f592c88b
15 changed files with 413 additions and 17537 deletions

View File

@@ -1,52 +1,52 @@
lap_number,total_laps,lap_time,average_speed,max_speed,tire_compound,tire_life_laps,track_temperature,rainfall
1,51,0 days 00:01:33.340000,210.17,326.0,MEDIUM,1,42.5,False
2,51,0 days 00:01:28.012000,236.87,330.0,MEDIUM,2,42.5,False
3,51,0 days 00:01:27.546000,236.4,331.0,MEDIUM,3,43.2,False
4,51,0 days 00:01:27.221000,240.13,341.0,MEDIUM,4,43.2,False
5,51,0 days 00:01:27.033000,236.09,345.0,MEDIUM,5,43.1,False
6,51,0 days 00:01:27.175000,236.74,343.0,MEDIUM,6,43.3,False
7,51,0 days 00:01:26.929000,239.72,340.0,MEDIUM,7,43.6,False
8,51,0 days 00:01:26.943000,238.45,351.0,MEDIUM,8,43.6,False
9,51,0 days 00:01:27.383000,236.81,330.0,MEDIUM,9,43.6,False
10,51,0 days 00:01:27.368000,232.42,331.0,MEDIUM,10,43.9,False
11,51,0 days 00:01:27.343000,237.18,331.0,MEDIUM,11,43.9,False
12,51,0 days 00:01:27.339000,236.76,332.0,MEDIUM,12,43.3,False
13,51,0 days 00:01:27.158000,235.47,330.0,MEDIUM,13,43.1,False
14,51,0 days 00:01:27.607000,235.97,332.0,MEDIUM,14,43.7,False
15,51,0 days 00:01:26.929000,237.04,332.0,MEDIUM,15,43.7,False
16,51,0 days 00:01:27.164000,238.88,333.0,MEDIUM,16,43.9,False
17,51,0 days 00:01:27.156000,235.35,333.0,MEDIUM,17,43.7,False
18,51,0 days 00:01:27.275000,238.66,333.0,MEDIUM,18,43.5,False
19,51,0 days 00:01:27.318000,234.62,333.0,MEDIUM,19,43.6,False
20,51,0 days 00:01:28.284000,235.31,333.0,MEDIUM,20,44.3,False
21,51,0 days 00:01:32.377000,224.11,332.0,MEDIUM,21,44.3,False
22,51,0 days 00:01:47.272000,191.14,322.0,HARD,4,43.7,False
23,51,0 days 00:01:26.849000,236.5,329.0,HARD,5,43.7,False
24,51,0 days 00:01:26.949000,238.49,331.0,HARD,6,43.5,False
25,51,0 days 00:01:26.899000,237.13,331.0,HARD,7,43.5,False
26,51,0 days 00:01:26.792000,238.18,331.0,HARD,8,43.4,False
27,51,0 days 00:01:26.666000,238.7,331.0,HARD,9,43.4,False
28,51,0 days 00:01:26.723000,234.46,331.0,HARD,10,43.3,False
29,51,0 days 00:01:26.997000,236.12,332.0,HARD,11,42.9,False
30,51,0 days 00:01:26.915000,238.87,333.0,HARD,12,42.5,False
31,51,0 days 00:01:26.848000,240.21,335.0,HARD,13,42.8,False
32,51,0 days 00:01:26.747000,235.57,332.0,HARD,14,42.6,False
33,51,0 days 00:01:26.769000,238.33,332.0,HARD,15,42.4,False
34,51,0 days 00:01:26.563000,236.92,332.0,HARD,16,42.5,False
35,51,0 days 00:01:26.517000,239.63,333.0,HARD,17,42.6,False
36,51,0 days 00:01:26.457000,237.1,332.0,HARD,18,42.5,False
37,51,0 days 00:01:26.380000,238.39,333.0,HARD,19,42.5,False
38,51,0 days 00:01:26.574000,237.75,333.0,HARD,20,42.8,False
39,51,0 days 00:01:26.707000,238.65,332.0,HARD,21,42.8,False
40,51,0 days 00:01:26.610000,235.8,333.0,HARD,22,42.8,False
41,51,0 days 00:01:26.815000,236.82,334.0,HARD,23,42.9,False
42,51,0 days 00:01:26.403000,239.47,332.0,HARD,24,42.5,False
43,51,0 days 00:01:26.105000,240.15,334.0,HARD,25,42.5,False
44,51,0 days 00:01:26.155000,241.7,332.0,HARD,26,41.7,False
45,51,0 days 00:01:26.277000,241.25,333.0,HARD,27,41.7,False
46,51,0 days 00:01:26.453000,238.02,335.0,HARD,28,41.8,False
47,51,0 days 00:01:26.912000,236.31,336.0,HARD,29,41.2,False
48,51,0 days 00:01:27.183000,237.42,340.0,HARD,30,41.2,False
49,51,0 days 00:01:27.245000,238.99,335.0,HARD,31,41.0,False
50,51,0 days 00:01:27.360000,237.3,342.0,HARD,32,40.8,False
51,51,0 days 00:01:27.395000,237.13,345.0,HARD,33,40.8,False
lap_number,total_laps,position,gap_to_leader,gap_to_ahead,lap_time,average_speed,max_speed,tire_compound,tire_life_laps,track_temperature,rainfall
1,51,11,6.223,0.62,0 days 00:01:33.340000,210.17,326.0,MEDIUM,1,42.5,False
2,51,11,8.229,0.712,0 days 00:01:28.012000,236.87,330.0,MEDIUM,2,42.5,False
3,51,11,9.799,0.898,0 days 00:01:27.546000,236.4,331.0,MEDIUM,3,43.2,False
4,51,11,10.953,0.919,0 days 00:01:27.221000,240.13,341.0,MEDIUM,4,43.2,False
5,51,11,11.563,0.917,0 days 00:01:27.033000,236.09,345.0,MEDIUM,5,43.1,False
6,51,11,12.123,0.923,0 days 00:01:27.175000,236.74,343.0,MEDIUM,6,43.3,False
7,51,11,12.694,0.387,0 days 00:01:26.929000,239.72,340.0,MEDIUM,7,43.6,False
8,51,10,13.413,2.76,0 days 00:01:26.943000,238.45,351.0,MEDIUM,8,43.6,False
9,51,10,14.32,3.387,0 days 00:01:27.383000,236.81,330.0,MEDIUM,9,43.6,False
10,51,10,15.177,3.76,0 days 00:01:27.368000,232.42,331.0,MEDIUM,10,43.9,False
11,51,10,15.829,3.984,0 days 00:01:27.343000,237.18,331.0,MEDIUM,11,43.9,False
12,51,10,16.76,4.129,0 days 00:01:27.339000,236.76,332.0,MEDIUM,12,43.3,False
13,51,10,17.031,3.995,0 days 00:01:27.158000,235.47,330.0,MEDIUM,13,43.1,False
14,51,10,17.666,4.076,0 days 00:01:27.607000,235.97,332.0,MEDIUM,14,43.7,False
15,51,10,17.366,0.469,0 days 00:01:26.929000,237.04,332.0,MEDIUM,15,43.7,False
16,51,9,17.812,2.844,0 days 00:01:27.164000,238.88,333.0,MEDIUM,16,43.9,False
17,51,9,18.235,2.415,0 days 00:01:27.156000,235.35,333.0,MEDIUM,17,43.7,False
18,51,9,19.237,2.411,0 days 00:01:27.275000,238.66,333.0,MEDIUM,18,43.5,False
19,51,9,20.117,2.28,0 days 00:01:27.318000,234.62,333.0,MEDIUM,19,43.6,False
20,51,7,17.552,2.734,0 days 00:01:28.284000,235.31,333.0,MEDIUM,20,44.3,False
21,51,6,16.826,4.269,0 days 00:01:32.377000,224.11,332.0,MEDIUM,21,44.3,False
22,51,12,29.113,8.135,0 days 00:01:47.272000,191.14,322.0,HARD,4,43.7,False
23,51,12,27.412,4.623,0 days 00:01:26.849000,236.5,329.0,HARD,5,43.7,False
24,51,11,27.05,4.191,0 days 00:01:26.949000,238.49,331.0,HARD,6,43.5,False
25,51,11,27.953,4.679,0 days 00:01:26.899000,237.13,331.0,HARD,7,43.5,False
26,51,10,28.959,5.184,0 days 00:01:26.792000,238.18,331.0,HARD,8,43.4,False
27,51,10,30.124,5.602,0 days 00:01:26.666000,238.7,331.0,HARD,9,43.4,False
28,51,9,31.413,5.714,0 days 00:01:26.723000,234.46,331.0,HARD,10,43.3,False
29,51,10,32.939,1.141,0 days 00:01:26.997000,236.12,332.0,HARD,11,42.9,False
30,51,10,34.456,1.716,0 days 00:01:26.915000,238.87,333.0,HARD,12,42.5,False
31,51,10,35.802,2.16,0 days 00:01:26.848000,240.21,335.0,HARD,13,42.8,False
32,51,10,37.139,2.287,0 days 00:01:26.747000,235.57,332.0,HARD,14,42.6,False
33,51,10,38.668,2.472,0 days 00:01:26.769000,238.33,332.0,HARD,15,42.4,False
34,51,10,39.548,2.799,0 days 00:01:26.563000,236.92,332.0,HARD,16,42.5,False
35,51,10,40.25,3.3,0 days 00:01:26.517000,239.63,333.0,HARD,17,42.6,False
36,51,10,41.109,3.552,0 days 00:01:26.457000,237.1,332.0,HARD,18,42.5,False
37,51,10,41.806,3.933,0 days 00:01:26.380000,238.39,333.0,HARD,19,42.5,False
38,51,10,42.795,4.233,0 days 00:01:26.574000,237.75,333.0,HARD,20,42.8,False
39,51,10,44.016,4.691,0 days 00:01:26.707000,238.65,332.0,HARD,21,42.8,False
40,51,10,44.725,4.643,0 days 00:01:26.610000,235.8,333.0,HARD,22,42.8,False
41,51,9,45.761,3.957,0 days 00:01:26.815000,236.82,334.0,HARD,23,42.9,False
42,51,9,46.252,4.144,0 days 00:01:26.403000,239.47,332.0,HARD,24,42.5,False
43,51,9,46.363,4.156,0 days 00:01:26.105000,240.15,334.0,HARD,25,42.5,False
44,51,9,46.767,3.159,0 days 00:01:26.155000,241.7,332.0,HARD,26,41.7,False
45,51,9,47.128,2.193,0 days 00:01:26.277000,241.25,333.0,HARD,27,41.7,False
46,51,9,47.396,1.629,0 days 00:01:26.453000,238.02,335.0,HARD,28,41.8,False
47,51,9,48.171,0.655,0 days 00:01:26.912000,236.31,336.0,HARD,29,41.2,False
48,51,9,48.119,1.105,0 days 00:01:27.183000,237.42,340.0,HARD,30,41.2,False
49,51,9,47.457,0.689,0 days 00:01:27.245000,238.99,335.0,HARD,31,41.0,False
50,51,9,46.424,0.875,0 days 00:01:27.360000,237.3,342.0,HARD,32,40.8,False
51,51,9,46.294,0.845,0 days 00:01:27.395000,237.13,345.0,HARD,33,40.8,False
1 lap_number total_laps position gap_to_leader gap_to_ahead lap_time average_speed max_speed tire_compound tire_life_laps track_temperature rainfall
2 1 51 11 6.223 0.62 0 days 00:01:33.340000 210.17 326.0 MEDIUM 1 42.5 False
3 2 51 11 8.229 0.712 0 days 00:01:28.012000 236.87 330.0 MEDIUM 2 42.5 False
4 3 51 11 9.799 0.898 0 days 00:01:27.546000 236.4 331.0 MEDIUM 3 43.2 False
5 4 51 11 10.953 0.919 0 days 00:01:27.221000 240.13 341.0 MEDIUM 4 43.2 False
6 5 51 11 11.563 0.917 0 days 00:01:27.033000 236.09 345.0 MEDIUM 5 43.1 False
7 6 51 11 12.123 0.923 0 days 00:01:27.175000 236.74 343.0 MEDIUM 6 43.3 False
8 7 51 11 12.694 0.387 0 days 00:01:26.929000 239.72 340.0 MEDIUM 7 43.6 False
9 8 51 10 13.413 2.76 0 days 00:01:26.943000 238.45 351.0 MEDIUM 8 43.6 False
10 9 51 10 14.32 3.387 0 days 00:01:27.383000 236.81 330.0 MEDIUM 9 43.6 False
11 10 51 10 15.177 3.76 0 days 00:01:27.368000 232.42 331.0 MEDIUM 10 43.9 False
12 11 51 10 15.829 3.984 0 days 00:01:27.343000 237.18 331.0 MEDIUM 11 43.9 False
13 12 51 10 16.76 4.129 0 days 00:01:27.339000 236.76 332.0 MEDIUM 12 43.3 False
14 13 51 10 17.031 3.995 0 days 00:01:27.158000 235.47 330.0 MEDIUM 13 43.1 False
15 14 51 10 17.666 4.076 0 days 00:01:27.607000 235.97 332.0 MEDIUM 14 43.7 False
16 15 51 10 17.366 0.469 0 days 00:01:26.929000 237.04 332.0 MEDIUM 15 43.7 False
17 16 51 9 17.812 2.844 0 days 00:01:27.164000 238.88 333.0 MEDIUM 16 43.9 False
18 17 51 9 18.235 2.415 0 days 00:01:27.156000 235.35 333.0 MEDIUM 17 43.7 False
19 18 51 9 19.237 2.411 0 days 00:01:27.275000 238.66 333.0 MEDIUM 18 43.5 False
20 19 51 9 20.117 2.28 0 days 00:01:27.318000 234.62 333.0 MEDIUM 19 43.6 False
21 20 51 7 17.552 2.734 0 days 00:01:28.284000 235.31 333.0 MEDIUM 20 44.3 False
22 21 51 6 16.826 4.269 0 days 00:01:32.377000 224.11 332.0 MEDIUM 21 44.3 False
23 22 51 12 29.113 8.135 0 days 00:01:47.272000 191.14 322.0 HARD 4 43.7 False
24 23 51 12 27.412 4.623 0 days 00:01:26.849000 236.5 329.0 HARD 5 43.7 False
25 24 51 11 27.05 4.191 0 days 00:01:26.949000 238.49 331.0 HARD 6 43.5 False
26 25 51 11 27.953 4.679 0 days 00:01:26.899000 237.13 331.0 HARD 7 43.5 False
27 26 51 10 28.959 5.184 0 days 00:01:26.792000 238.18 331.0 HARD 8 43.4 False
28 27 51 10 30.124 5.602 0 days 00:01:26.666000 238.7 331.0 HARD 9 43.4 False
29 28 51 9 31.413 5.714 0 days 00:01:26.723000 234.46 331.0 HARD 10 43.3 False
30 29 51 10 32.939 1.141 0 days 00:01:26.997000 236.12 332.0 HARD 11 42.9 False
31 30 51 10 34.456 1.716 0 days 00:01:26.915000 238.87 333.0 HARD 12 42.5 False
32 31 51 10 35.802 2.16 0 days 00:01:26.848000 240.21 335.0 HARD 13 42.8 False
33 32 51 10 37.139 2.287 0 days 00:01:26.747000 235.57 332.0 HARD 14 42.6 False
34 33 51 10 38.668 2.472 0 days 00:01:26.769000 238.33 332.0 HARD 15 42.4 False
35 34 51 10 39.548 2.799 0 days 00:01:26.563000 236.92 332.0 HARD 16 42.5 False
36 35 51 10 40.25 3.3 0 days 00:01:26.517000 239.63 333.0 HARD 17 42.6 False
37 36 51 10 41.109 3.552 0 days 00:01:26.457000 237.1 332.0 HARD 18 42.5 False
38 37 51 10 41.806 3.933 0 days 00:01:26.380000 238.39 333.0 HARD 19 42.5 False
39 38 51 10 42.795 4.233 0 days 00:01:26.574000 237.75 333.0 HARD 20 42.8 False
40 39 51 10 44.016 4.691 0 days 00:01:26.707000 238.65 332.0 HARD 21 42.8 False
41 40 51 10 44.725 4.643 0 days 00:01:26.610000 235.8 333.0 HARD 22 42.8 False
42 41 51 9 45.761 3.957 0 days 00:01:26.815000 236.82 334.0 HARD 23 42.9 False
43 42 51 9 46.252 4.144 0 days 00:01:26.403000 239.47 332.0 HARD 24 42.5 False
44 43 51 9 46.363 4.156 0 days 00:01:26.105000 240.15 334.0 HARD 25 42.5 False
45 44 51 9 46.767 3.159 0 days 00:01:26.155000 241.7 332.0 HARD 26 41.7 False
46 45 51 9 47.128 2.193 0 days 00:01:26.277000 241.25 333.0 HARD 27 41.7 False
47 46 51 9 47.396 1.629 0 days 00:01:26.453000 238.02 335.0 HARD 28 41.8 False
48 47 51 9 48.171 0.655 0 days 00:01:26.912000 236.31 336.0 HARD 29 41.2 False
49 48 51 9 48.119 1.105 0 days 00:01:27.183000 237.42 340.0 HARD 30 41.2 False
50 49 51 9 47.457 0.689 0 days 00:01:27.245000 238.99 335.0 HARD 31 41.0 False
51 50 51 9 46.424 0.875 0 days 00:01:27.360000 237.3 342.0 HARD 32 40.8 False
52 51 51 9 46.294 0.845 0 days 00:01:27.395000 237.13 345.0 HARD 33 40.8 False

File diff suppressed because it is too large Load Diff

View File

@@ -1,182 +0,0 @@
"""
Raspberry Pi Telemetry Stream Simulator - Lap-Level Data
Reads the ALONSO_2023_MONZA_LAPS.csv file lap by lap and simulates
live telemetry streaming from a Raspberry Pi sensor.
Sends data to the HPC simulation layer via HTTP POST at fixed
1-minute intervals between laps.
Usage:
python simulate_pi_stream.py
python simulate_pi_stream.py --interval 30 # 30 seconds between laps
"""
import argparse
import time
import sys
from pathlib import Path
from typing import Dict, Any
import pandas as pd
import requests
def load_lap_csv(filepath: Path) -> pd.DataFrame:
"""Load lap-level telemetry data from CSV file."""
df = pd.read_csv(filepath)
# Convert lap_time to timedelta if it's not already
if 'lap_time' in df.columns and df['lap_time'].dtype == 'object':
df['lap_time'] = pd.to_timedelta(df['lap_time'])
print(f"✓ Loaded {len(df)} laps from {filepath}")
print(f" Laps: {df['lap_number'].min():.0f}{df['lap_number'].max():.0f}")
return df
def lap_to_json(row: pd.Series) -> Dict[str, Any]:
"""Convert a lap DataFrame row to a JSON-compatible dictionary."""
data = {
'lap_number': int(row['lap_number']) if pd.notna(row['lap_number']) else None,
'total_laps': int(row['total_laps']) if pd.notna(row['total_laps']) else None,
'lap_time': str(row['lap_time']) if pd.notna(row['lap_time']) else None,
'average_speed': float(row['average_speed']) if pd.notna(row['average_speed']) else 0.0,
'max_speed': float(row['max_speed']) if pd.notna(row['max_speed']) else 0.0,
'tire_compound': str(row['tire_compound']) if pd.notna(row['tire_compound']) else 'UNKNOWN',
'tire_life_laps': int(row['tire_life_laps']) if pd.notna(row['tire_life_laps']) else 0,
'track_temperature': float(row['track_temperature']) if pd.notna(row['track_temperature']) else 0.0,
'rainfall': bool(row['rainfall'])
}
return data
def simulate_stream(
df: pd.DataFrame,
endpoint: str,
interval: int = 60,
start_lap: int = 1,
end_lap: int = None
):
"""
Simulate live telemetry streaming with fixed interval between laps.
Args:
df: DataFrame with lap-level telemetry data
endpoint: HPC API endpoint URL
interval: Fixed interval in seconds between laps (default: 60 seconds)
start_lap: Starting lap number
end_lap: Ending lap number (None = all laps)
"""
# Filter by lap range
filtered_df = df[df['lap_number'] >= start_lap].copy()
if end_lap:
filtered_df = filtered_df[filtered_df['lap_number'] <= end_lap].copy()
if len(filtered_df) == 0:
print("❌ No laps in specified lap range")
return
# Reset index for easier iteration
filtered_df = filtered_df.reset_index(drop=True)
print(f"\n🏁 Starting lap-level telemetry stream simulation")
print(f" Endpoint: {endpoint}")
print(f" Laps: {start_lap}{end_lap or 'end'}")
print(f" Interval: {interval} seconds between laps")
print(f" Total laps: {len(filtered_df)}")
print(f" Est. duration: {len(filtered_df) * interval / 60:.1f} minutes\n")
sent_count = 0
error_count = 0
try:
for i in range(len(filtered_df)):
row = filtered_df.iloc[i]
lap_num = int(row['lap_number'])
# Convert lap to JSON
lap_data = lap_to_json(row)
# Send lap data
try:
response = requests.post(
endpoint,
json=lap_data,
timeout=5.0
)
if response.status_code == 200:
sent_count += 1
progress = (i + 1) / len(filtered_df) * 100
# Print lap info
print(f" 📡 Lap {lap_num}/{int(row['total_laps'])}: "
f"Avg Speed: {row['average_speed']:.1f} km/h, "
f"Tire: {row['tire_compound']} (age: {int(row['tire_life_laps'])} laps) "
f"[{progress:.0f}%]")
# Show response if it contains strategies
try:
response_data = response.json()
if 'strategies_generated' in response_data:
print(f" ✓ Generated {response_data['strategies_generated']} strategies")
except:
pass
else:
error_count += 1
print(f" ⚠ Lap {lap_num}: HTTP {response.status_code}: {response.text[:100]}")
except requests.RequestException as e:
error_count += 1
print(f" ⚠ Lap {lap_num}: Connection error: {str(e)[:100]}")
# Sleep for fixed interval before next lap (except for last lap)
if i < len(filtered_df) - 1:
time.sleep(interval)
print(f"\n✅ Stream complete!")
print(f" Sent: {sent_count} laps")
print(f" Errors: {error_count}")
except KeyboardInterrupt:
print(f"\n⏸ Stream interrupted by user")
print(f" Sent: {sent_count}/{len(filtered_df)} laps")
def main():
parser = argparse.ArgumentParser(
description="Simulate Raspberry Pi lap-level telemetry streaming"
)
parser.add_argument("--endpoint", type=str, default="http://localhost:8000/ingest/telemetry",
help="HPC API endpoint (default: http://localhost:8000/ingest/telemetry)")
parser.add_argument("--interval", type=int, default=60,
help="Fixed interval in seconds between laps (default: 60)")
parser.add_argument("--start-lap", type=int, default=1, help="Starting lap number")
parser.add_argument("--end-lap", type=int, default=None, help="Ending lap number")
args = parser.parse_args()
try:
# Hardcoded CSV file location in the same folder as this script
script_dir = Path(__file__).parent
data_path = script_dir / "ALONSO_2023_MONZA_LAPS.csv"
df = load_lap_csv(data_path)
simulate_stream(
df,
args.endpoint,
args.interval,
args.start_lap,
args.end_lap
)
except FileNotFoundError:
print(f"❌ File not found: {data_path}")
print(f" Make sure ALONSO_2023_MONZA_LAPS.csv is in the scripts/ folder")
sys.exit(1)
except Exception as e:
print(f"❌ Error: {e}")
raise
if __name__ == "__main__":
main()

View File

@@ -66,6 +66,9 @@ class PiSimulator:
return {
"lap_number": int(row["lap_number"]),
"total_laps": int(row["total_laps"]),
"position": int(row["position"]) if pd.notna(row["position"]) else 10,
"gap_to_leader": float(row["gap_to_leader"]) if pd.notna(row["gap_to_leader"]) else 0.0,
"gap_to_ahead": float(row["gap_to_ahead"]) if pd.notna(row["gap_to_ahead"]) else 0.0,
"lap_time": str(row["lap_time"]),
"average_speed": float(row["average_speed"]),
"max_speed": float(row["max_speed"]),