Lamaq commited on
Commit
aaa2f75
·
1 Parent(s): d1ff2bd

Changes in simulator frontend and backend

Browse files
Files changed (3) hide show
  1. README.md +1 -1
  2. src/api/simulator.py +28 -19
  3. track-config.yaml +179 -0
README.md CHANGED
@@ -1,6 +1,6 @@
1
  ---
2
  title: F1 Strategy Api
3
- emoji: 🐠
4
  colorFrom: indigo
5
  colorTo: pink
6
  sdk: docker
 
1
  ---
2
  title: F1 Strategy Api
3
+ emoji: 🏎️
4
  colorFrom: indigo
5
  colorTo: pink
6
  sdk: docker
src/api/simulator.py CHANGED
@@ -1,14 +1,14 @@
1
  import pandas as pd
 
 
2
  from model_loader import model_loader # We import the loader instance
3
 
4
- # A simple mapping for default temperatures if the user doesn't provide them.
5
- DEFAULT_TRACK_TEMPS = {
6
- "Silverstone": {"airtemp": 20.0, "tracktemp": 30.0},
7
- "Monza": {"airtemp": 25.0, "tracktemp": 40.0},
8
- "Bahrain": {"airtemp": 28.0, "tracktemp": 35.0},
9
- "Spa-Francorchamps": {"airtemp": 18.0, "tracktemp": 25.0},
10
- # Add other tracks as needed
11
- }
12
 
13
  class RaceSimulator:
14
  def __init__(self, model, preprocessor):
@@ -34,32 +34,39 @@ class RaceSimulator:
34
  """
35
  Runs a full race simulation based on a user-defined strategy.
36
  """
37
- # --- 1. Extract and validate inputs (using lowercase) ---
 
 
 
 
38
  base_params = {
39
- "track": strategy.get("track"),
40
  "driver": strategy.get("driver"),
41
  "year": 2025,
 
 
42
  }
43
 
44
- default_temps = DEFAULT_TRACK_TEMPS.get(base_params["track"], {"airtemp": 22.0, "tracktemp": 32.0})
45
- base_params["airtemp"] = strategy.get("air_temp", default_temps["airtemp"])
46
- base_params["tracktemp"] = strategy.get("track_temp", default_temps["tracktemp"])
47
-
48
  stints = strategy.get("stints", [])
49
  if not stints:
50
  raise ValueError("Strategy must include at least one stint.")
51
 
52
- # --- 2. Run the lap-by-lap simulation ---
53
  lap_records = []
54
  total_laps = sum(stint['laps'] for stint in stints)
55
  current_lap_number = 1
 
 
 
 
 
 
56
 
57
- for stint_info in stints:
58
  compound = stint_info['compound']
59
  num_laps_in_stint = stint_info['laps']
60
 
61
  for tyre_lap in range(1, num_laps_in_stint + 1):
62
- # Using lowercase keys to match the training data columns
63
  lap_data = {
64
  "tyrelife": float(tyre_lap),
65
  "lapnumber": float(current_lap_number),
@@ -68,6 +75,7 @@ class RaceSimulator:
68
  }
69
 
70
  predicted_time = self._predict_lap_time(lap_data)
 
71
 
72
  lap_records.append({
73
  "Lap Number": current_lap_number,
@@ -77,7 +85,7 @@ class RaceSimulator:
77
  })
78
  current_lap_number += 1
79
 
80
- # --- 3. Calculate summary statistics ---
81
  if not lap_records:
82
  return {"error": "Simulation produced no results."}
83
 
@@ -87,6 +95,7 @@ class RaceSimulator:
87
 
88
  summary = {
89
  "total_laps_simulated": total_laps,
 
90
  "average_lap_time": round(results_df['LapTimeInSeconds'].mean(), 3),
91
  "best_lap": {
92
  "lap_time": best_lap['LapTimeInSeconds'],
@@ -98,7 +107,7 @@ class RaceSimulator:
98
  "lap_number": int(worst_lap['Lap Number']),
99
  "compound": worst_lap['Compound'],
100
  },
101
- "pit_stop_disclaimer": "Total race time does not include time lost during pit stops (typically +2.0-5.0s per stop)."
102
  }
103
 
104
  return {
 
1
  import pandas as pd
2
+ import yaml
3
+ import os
4
  from model_loader import model_loader # We import the loader instance
5
 
6
+ # --- THE FIX ---
7
+ # Load the track configuration from our new YAML file.
8
+ # This is done once when the application starts.
9
+ CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'track_config.yaml')
10
+ with open(CONFIG_PATH, 'r') as f:
11
+ TRACK_CONFIG = yaml.safe_load(f)
 
 
12
 
13
  class RaceSimulator:
14
  def __init__(self, model, preprocessor):
 
34
  """
35
  Runs a full race simulation based on a user-defined strategy.
36
  """
37
+ # --- 1. Get track-specific defaults from our loaded config ---
38
+ track_name = strategy.get("track")
39
+ track_defaults = TRACK_CONFIG['tracks'].get(track_name, TRACK_CONFIG['default'])
40
+
41
+ # --- 2. Extract and validate inputs, using defaults as fallbacks ---
42
  base_params = {
43
+ "track": track_name,
44
  "driver": strategy.get("driver"),
45
  "year": 2025,
46
+ "airtemp": strategy.get("air_temp", track_defaults["air_temp"]),
47
+ "tracktemp": strategy.get("track_temp", track_defaults["track_temp"]),
48
  }
49
 
50
+ pit_stop_time = track_defaults["pit_stop_time"]
 
 
 
51
  stints = strategy.get("stints", [])
52
  if not stints:
53
  raise ValueError("Strategy must include at least one stint.")
54
 
55
+ # --- 3. Run the lap-by-lap simulation ---
56
  lap_records = []
57
  total_laps = sum(stint['laps'] for stint in stints)
58
  current_lap_number = 1
59
+ total_race_time = 0.0
60
+
61
+ for i, stint_info in enumerate(stints):
62
+ # Add pit stop time for every stop after the first stint
63
+ if i > 0:
64
+ total_race_time += pit_stop_time
65
 
 
66
  compound = stint_info['compound']
67
  num_laps_in_stint = stint_info['laps']
68
 
69
  for tyre_lap in range(1, num_laps_in_stint + 1):
 
70
  lap_data = {
71
  "tyrelife": float(tyre_lap),
72
  "lapnumber": float(current_lap_number),
 
75
  }
76
 
77
  predicted_time = self._predict_lap_time(lap_data)
78
+ total_race_time += predicted_time
79
 
80
  lap_records.append({
81
  "Lap Number": current_lap_number,
 
85
  })
86
  current_lap_number += 1
87
 
88
+ # --- 4. Calculate summary statistics ---
89
  if not lap_records:
90
  return {"error": "Simulation produced no results."}
91
 
 
95
 
96
  summary = {
97
  "total_laps_simulated": total_laps,
98
+ "total_race_time": round(total_race_time, 3),
99
  "average_lap_time": round(results_df['LapTimeInSeconds'].mean(), 3),
100
  "best_lap": {
101
  "lap_time": best_lap['LapTimeInSeconds'],
 
107
  "lap_number": int(worst_lap['Lap Number']),
108
  "compound": worst_lap['Compound'],
109
  },
110
+ "pit_stop_info": f"Simulation includes {len(stints) - 1} pit stop(s), adding {pit_stop_time:.1f}s each."
111
  }
112
 
113
  return {
track-config.yaml ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # src/api/track_config.yaml
2
+ # This file stores default simulation parameters for each F1 track for the 2025 season.
3
+
4
+ # Default values used if a specific track is not found in the list below.
5
+ default:
6
+ air_temp: 22.0
7
+ track_temp: 32.0
8
+ pit_stop_time: 23.0 # Average time lost in a standard pit stop
9
+ total_laps: 55
10
+
11
+ # Track-specific overrides for the 2025 F1 Season
12
+ tracks:
13
+ # 1. Australian Grand Prix
14
+ Melbourne:
15
+ air_temp: 20.0
16
+ track_temp: 35.0
17
+ pit_stop_time: 21.5
18
+ total_laps: 58
19
+
20
+ # 2. Chinese Grand Prix
21
+ Shanghai:
22
+ air_temp: 22.0
23
+ track_temp: 38.0
24
+ pit_stop_time: 23.5
25
+ total_laps: 56
26
+
27
+ # 3. Japanese Grand Prix
28
+ Suzuka:
29
+ air_temp: 18.0
30
+ track_temp: 28.0
31
+ pit_stop_time: 23.0
32
+ total_laps: 53
33
+
34
+ # 4. Bahrain Grand Prix
35
+ Bahrain:
36
+ air_temp: 28.0
37
+ track_temp: 35.0
38
+ pit_stop_time: 22.5
39
+ total_laps: 57
40
+
41
+ # 5. Saudi Arabian Grand Prix
42
+ Jeddah:
43
+ air_temp: 26.0
44
+ track_temp: 32.0
45
+ pit_stop_time: 21.0
46
+ total_laps: 50
47
+
48
+ # 6. Miami Grand Prix
49
+ Miami:
50
+ air_temp: 29.0
51
+ track_temp: 45.0
52
+ pit_stop_time: 22.0
53
+ total_laps: 57
54
+
55
+ # 7. Emilia Romagna Grand Prix
56
+ Imola:
57
+ air_temp: 20.0
58
+ track_temp: 40.0
59
+ pit_stop_time: 28.0 # Very long pit lane
60
+ total_laps: 63
61
+
62
+ # 8. Monaco Grand Prix
63
+ Monaco:
64
+ air_temp: 24.0
65
+ track_temp: 45.0
66
+ pit_stop_time: 20.5 # Very short pit lane
67
+ total_laps: 78
68
+
69
+ # 9. Spanish Grand Prix
70
+ "Circuit de Barcelona-Catalunya":
71
+ air_temp: 26.0
72
+ track_temp: 44.0
73
+ pit_stop_time: 22.2
74
+ total_laps: 66
75
+
76
+ # 10. Canadian Grand Prix
77
+ Montreal:
78
+ air_temp: 19.0
79
+ track_temp: 33.0
80
+ pit_stop_time: 18.5 # Short pit lane
81
+ total_laps: 70
82
+
83
+ # 11. Austrian Grand Prix
84
+ Spielberg:
85
+ air_temp: 22.0
86
+ track_temp: 42.0
87
+ pit_stop_time: 19.5 # Short pit lane
88
+ total_laps: 71
89
+
90
+ # 12. British Grand Prix
91
+ Silverstone:
92
+ air_temp: 20.0
93
+ track_temp: 30.0
94
+ pit_stop_time: 24.5 # Long pit lane
95
+ total_laps: 52
96
+
97
+ # 13. Belgian Grand Prix
98
+ "Spa-Francorchamps":
99
+ air_temp: 18.0
100
+ track_temp: 25.0
101
+ pit_stop_time: 21.5
102
+ total_laps: 44
103
+
104
+ # 14. Hungarian Grand Prix
105
+ Budapest:
106
+ air_temp: 28.0
107
+ track_temp: 50.0
108
+ pit_stop_time: 20.0
109
+ total_laps: 70
110
+
111
+ # 15. Dutch Grand Prix
112
+ Zandvoort:
113
+ air_temp: 20.0
114
+ track_temp: 35.0
115
+ pit_stop_time: 21.0
116
+ total_laps: 72
117
+
118
+ # 16. Italian Grand Prix
119
+ Monza:
120
+ air_temp: 25.0
121
+ track_temp: 40.0
122
+ pit_stop_time: 24.0
123
+ total_laps: 53
124
+
125
+ # 17. Azerbaijan Grand Prix
126
+ Baku:
127
+ air_temp: 24.0
128
+ track_temp: 48.0
129
+ pit_stop_time: 22.0
130
+ total_laps: 51
131
+
132
+ # 18. Singapore Grand Prix
133
+ Singapore:
134
+ air_temp: 29.0
135
+ track_temp: 36.0
136
+ pit_stop_time: 25.0 # Long pit lane
137
+ total_laps: 62
138
+
139
+ # 19. United States Grand Prix
140
+ Austin:
141
+ air_temp: 27.0
142
+ track_temp: 38.0
143
+ pit_stop_time: 21.8
144
+ total_laps: 56
145
+
146
+ # 20. Mexican Grand Prix
147
+ "Mexico City":
148
+ air_temp: 22.0
149
+ track_temp: 46.0
150
+ pit_stop_time: 20.0
151
+ total_laps: 71
152
+
153
+ # 21. Brazilian Grand Prix
154
+ "Sao Paulo":
155
+ air_temp: 21.0
156
+ track_temp: 40.0
157
+ pit_stop_time: 21.2
158
+ total_laps: 71
159
+
160
+ # 22. Las Vegas Grand Prix
161
+ "Las Vegas":
162
+ air_temp: 15.0
163
+ track_temp: 18.0
164
+ pit_stop_time: 22.5
165
+ total_laps: 50
166
+
167
+ # 23. Qatar Grand Prix
168
+ Lusail:
169
+ air_temp: 30.0
170
+ track_temp: 36.0
171
+ pit_stop_time: 20.5
172
+ total_laps: 57
173
+
174
+ # 24. Abu Dhabi Grand Prix
175
+ "Yas Marina":
176
+ air_temp: 28.0
177
+ track_temp: 34.0
178
+ pit_stop_time: 22.8
179
+ total_laps: 58