Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import matplotlib.pyplot as plt
|
5 |
+
from sklearn.ensemble import RandomForestRegressor
|
6 |
+
from sklearn.preprocessing import StandardScaler
|
7 |
+
from sklearn.metrics import mean_squared_error, r2_score
|
8 |
+
from scipy.optimize import differential_evolution
|
9 |
+
import warnings
|
10 |
+
warnings.filterwarnings('ignore')
|
11 |
+
|
12 |
+
class F1AerodynamicPredictor:
|
13 |
+
def __init__(self):
|
14 |
+
self.model = RandomForestRegressor(n_estimators=100, random_state=42)
|
15 |
+
self.scaler = StandardScaler()
|
16 |
+
self.is_trained = False
|
17 |
+
self.feature_names = ['front_wing_angle', 'rear_wing_angle', 'ride_height',
|
18 |
+
'suspension_stiffness', 'downforce', 'drag_coefficient',
|
19 |
+
'track_temp', 'wind_speed', 'track_grip']
|
20 |
+
|
21 |
+
def generate_aero_data(self, num_samples=2000):
|
22 |
+
"""Generate realistic aerodynamic and setup data"""
|
23 |
+
np.random.seed(42)
|
24 |
+
|
25 |
+
# Car setup parameters
|
26 |
+
front_wing_angle = np.random.uniform(5, 25, num_samples) # degrees
|
27 |
+
rear_wing_angle = np.random.uniform(8, 35, num_samples) # degrees
|
28 |
+
ride_height = np.random.uniform(20, 80, num_samples) # mm
|
29 |
+
suspension_stiffness = np.random.uniform(50, 150, num_samples) # N/mm
|
30 |
+
|
31 |
+
# Aerodynamic parameters (derived from setup)
|
32 |
+
downforce = 800 + (front_wing_angle * 15) + (rear_wing_angle * 20) + np.random.normal(0, 50, num_samples)
|
33 |
+
drag_coefficient = 0.8 + (front_wing_angle * 0.02) + (rear_wing_angle * 0.025) + np.random.normal(0, 0.1, num_samples)
|
34 |
+
drag_coefficient = np.clip(drag_coefficient, 0.5, 2.0)
|
35 |
+
|
36 |
+
# Environmental conditions
|
37 |
+
track_temp = np.random.uniform(25, 45, num_samples) # °C
|
38 |
+
wind_speed = np.random.uniform(0, 15, num_samples) # m/s
|
39 |
+
track_grip = np.random.uniform(0.7, 1.0, num_samples) # coefficient
|
40 |
+
|
41 |
+
# Calculate lap time based on aerodynamic efficiency and setup
|
42 |
+
# Base lap time around 90 seconds, modified by aero efficiency
|
43 |
+
aero_efficiency = downforce / drag_coefficient
|
44 |
+
base_lap_time = 90
|
45 |
+
|
46 |
+
# Lap time calculation with realistic physics
|
47 |
+
lap_time = (base_lap_time -
|
48 |
+
(aero_efficiency - 800) * 0.01 + # Aero efficiency impact
|
49 |
+
(ride_height - 50) * 0.05 + # Ride height impact
|
50 |
+
(track_temp - 35) * 0.1 + # Temperature impact
|
51 |
+
wind_speed * 0.2 + # Wind resistance
|
52 |
+
(1 - track_grip) * 10 + # Grip impact
|
53 |
+
np.random.normal(0, 1, num_samples)) # Random variation
|
54 |
+
|
55 |
+
# Ensure realistic lap times
|
56 |
+
lap_time = np.clip(lap_time, 75, 110)
|
57 |
+
|
58 |
+
return pd.DataFrame({
|
59 |
+
'front_wing_angle': front_wing_angle,
|
60 |
+
'rear_wing_angle': rear_wing_angle,
|
61 |
+
'ride_height': ride_height,
|
62 |
+
'suspension_stiffness': suspension_stiffness,
|
63 |
+
'downforce': downforce,
|
64 |
+
'drag_coefficient': drag_coefficient,
|
65 |
+
'track_temp': track_temp,
|
66 |
+
'wind_speed': wind_speed,
|
67 |
+
'track_grip': track_grip,
|
68 |
+
'lap_time': lap_time
|
69 |
+
})
|
70 |
+
|
71 |
+
def train_model(self, data):
|
72 |
+
"""Train the aerodynamic performance model"""
|
73 |
+
X = data[self.feature_names]
|
74 |
+
y = data['lap_time']
|
75 |
+
|
76 |
+
# Scale features
|
77 |
+
X_scaled = self.scaler.fit_transform(X)
|
78 |
+
|
79 |
+
# Train model
|
80 |
+
self.model.fit(X_scaled, y)
|
81 |
+
self.is_trained = True
|
82 |
+
|
83 |
+
# Calculate performance metrics
|
84 |
+
y_pred = self.model.predict(X_scaled)
|
85 |
+
r2 = r2_score(y, y_pred)
|
86 |
+
rmse = np.sqrt(mean_squared_error(y, y_pred))
|
87 |
+
|
88 |
+
return r2, rmse
|
89 |
+
|
90 |
+
def predict_lap_time(self, setup_params):
|
91 |
+
"""Predict lap time for given setup parameters"""
|
92 |
+
if not self.is_trained:
|
93 |
+
return None
|
94 |
+
|
95 |
+
# Prepare input
|
96 |
+
X = np.array([setup_params]).reshape(1, -1)
|
97 |
+
X_scaled = self.scaler.transform(X)
|
98 |
+
|
99 |
+
# Predict
|
100 |
+
lap_time = self.model.predict(X_scaled)[0]
|
101 |
+
return lap_time
|
102 |
+
|
103 |
+
def optimize_setup(self, track_conditions):
|
104 |
+
"""Optimize car setup for given track conditions"""
|
105 |
+
if not self.is_trained:
|
106 |
+
return None
|
107 |
+
|
108 |
+
track_temp, wind_speed, track_grip = track_conditions
|
109 |
+
|
110 |
+
def objective(params):
|
111 |
+
"""Objective function to minimize lap time"""
|
112 |
+
setup_params = list(params) + [track_temp, wind_speed, track_grip]
|
113 |
+
return self.predict_lap_time(setup_params)
|
114 |
+
|
115 |
+
# Define bounds for optimization (setup parameters only)
|
116 |
+
bounds = [
|
117 |
+
(5, 25), # front_wing_angle
|
118 |
+
(8, 35), # rear_wing_angle
|
119 |
+
(20, 80), # ride_height
|
120 |
+
(50, 150), # suspension_stiffness
|
121 |
+
(600, 1200), # downforce
|
122 |
+
(0.5, 2.0) # drag_coefficient
|
123 |
+
]
|
124 |
+
|
125 |
+
# Optimize using differential evolution
|
126 |
+
result = differential_evolution(objective, bounds, maxiter=100, seed=42)
|
127 |
+
|
128 |
+
optimal_setup = result.x
|
129 |
+
optimal_lap_time = result.fun
|
130 |
+
|
131 |
+
return optimal_setup, optimal_lap_time
|
132 |
+
|
133 |
+
def analyze_sensitivity(self, base_setup, track_conditions):
|
134 |
+
"""Analyze sensitivity of lap time to setup changes"""
|
135 |
+
if not self.is_trained:
|
136 |
+
return None, None
|
137 |
+
|
138 |
+
# Base lap time
|
139 |
+
base_params = list(base_setup) + list(track_conditions)
|
140 |
+
base_lap_time = self.predict_lap_time(base_params)
|
141 |
+
|
142 |
+
# Analyze each parameter
|
143 |
+
sensitivity_data = []
|
144 |
+
param_names = ['Front Wing', 'Rear Wing', 'Ride Height', 'Suspension', 'Downforce', 'Drag Coeff']
|
145 |
+
|
146 |
+
for i, param_name in enumerate(param_names):
|
147 |
+
# Test parameter variations
|
148 |
+
variations = np.linspace(0.8, 1.2, 21) # ±20% variation
|
149 |
+
lap_times = []
|
150 |
+
|
151 |
+
for var in variations:
|
152 |
+
test_setup = base_setup.copy()
|
153 |
+
test_setup[i] *= var
|
154 |
+
test_params = list(test_setup) + list(track_conditions)
|
155 |
+
lap_time = self.predict_lap_time(test_params)
|
156 |
+
lap_times.append(lap_time)
|
157 |
+
|
158 |
+
sensitivity_data.append({
|
159 |
+
'parameter': param_name,
|
160 |
+
'variations': variations,
|
161 |
+
'lap_times': lap_times,
|
162 |
+
'sensitivity': np.std(lap_times)
|
163 |
+
})
|
164 |
+
|
165 |
+
return sensitivity_data, base_lap_time
|
166 |
+
|
167 |
+
def create_visualizations(self, data):
|
168 |
+
"""Create aerodynamic analysis visualizations"""
|
169 |
+
fig, axes = plt.subplots(2, 2, figsize=(15, 12))
|
170 |
+
|
171 |
+
# Downforce vs Drag trade-off
|
172 |
+
aero_efficiency = data['downforce'] / data['drag_coefficient']
|
173 |
+
scatter = axes[0, 0].scatter(data['drag_coefficient'], data['downforce'],
|
174 |
+
c=data['lap_time'], cmap='RdYlBu_r', alpha=0.6)
|
175 |
+
axes[0, 0].set_xlabel('Drag Coefficient')
|
176 |
+
axes[0, 0].set_ylabel('Downforce (N)')
|
177 |
+
axes[0, 0].set_title('Downforce vs Drag Trade-off')
|
178 |
+
plt.colorbar(scatter, ax=axes[0, 0], label='Lap Time (s)')
|
179 |
+
axes[0, 0].grid(True, alpha=0.3)
|
180 |
+
|
181 |
+
# Wing angle correlation
|
182 |
+
axes[0, 1].scatter(data['front_wing_angle'], data['rear_wing_angle'],
|
183 |
+
c=data['lap_time'], cmap='RdYlBu_r', alpha=0.6)
|
184 |
+
axes[0, 1].set_xlabel('Front Wing Angle (°)')
|
185 |
+
axes[0, 1].set_ylabel('Rear Wing Angle (°)')
|
186 |
+
axes[0, 1].set_title('Wing Angle Configuration')
|
187 |
+
axes[0, 1].grid(True, alpha=0.3)
|
188 |
+
|
189 |
+
# Aerodynamic efficiency distribution
|
190 |
+
axes[1, 0].hist(aero_efficiency, bins=30, alpha=0.7, color='skyblue', edgecolor='black')
|
191 |
+
axes[1, 0].set_xlabel('Aerodynamic Efficiency (Downforce/Drag)')
|
192 |
+
axes[1, 0].set_ylabel('Frequency')
|
193 |
+
axes[1, 0].set_title('Aerodynamic Efficiency Distribution')
|
194 |
+
axes[1, 0].grid(True, alpha=0.3)
|
195 |
+
|
196 |
+
# Lap time vs environmental conditions
|
197 |
+
axes[1, 1].scatter(data['track_temp'], data['lap_time'], alpha=0.6, label='Track Temp')
|
198 |
+
axes[1, 1].set_xlabel('Track Temperature (°C)')
|
199 |
+
axes[1, 1].set_ylabel('Lap Time (s)')
|
200 |
+
axes[1, 1].set_title('Environmental Impact on Performance')
|
201 |
+
axes[1, 1].grid(True, alpha=0.3)
|
202 |
+
|
203 |
+
plt.tight_layout()
|
204 |
+
return fig
|
205 |
+
|
206 |
+
# Initialize the predictor
|
207 |
+
predictor = F1AerodynamicPredictor()
|
208 |
+
|
209 |
+
def analyze_aerodynamics():
|
210 |
+
"""Main aerodynamic analysis function"""
|
211 |
+
# Generate data
|
212 |
+
data = predictor.generate_aero_data(2000)
|
213 |
+
|
214 |
+
# Train model
|
215 |
+
r2, rmse = predictor.train_model(data)
|
216 |
+
|
217 |
+
# Create visualizations
|
218 |
+
fig = predictor.create_visualizations(data)
|
219 |
+
|
220 |
+
# Generate report
|
221 |
+
report = f"""
|
222 |
+
## F1 Aerodynamic Performance Analysis
|
223 |
+
|
224 |
+
**Model Performance:**
|
225 |
+
- R² Score: {r2:.3f}
|
226 |
+
- RMSE: {rmse:.3f} seconds
|
227 |
+
|
228 |
+
**Dataset Statistics:**
|
229 |
+
- Total configurations analyzed: {len(data)}
|
230 |
+
- Fastest lap time: {data['lap_time'].min():.2f}s
|
231 |
+
- Slowest lap time: {data['lap_time'].max():.2f}s
|
232 |
+
- Average lap time: {data['lap_time'].mean():.2f}s
|
233 |
+
|
234 |
+
**Aerodynamic Insights:**
|
235 |
+
- Average downforce: {data['downforce'].mean():.0f}N
|
236 |
+
- Average drag coefficient: {data['drag_coefficient'].mean():.3f}
|
237 |
+
- Best aero efficiency: {(data['downforce'] / data['drag_coefficient']).max():.1f}
|
238 |
+
|
239 |
+
**Optimal Ranges:**
|
240 |
+
- Front wing: {data['front_wing_angle'].quantile(0.1):.1f}° - {data['front_wing_angle'].quantile(0.9):.1f}°
|
241 |
+
- Rear wing: {data['rear_wing_angle'].quantile(0.1):.1f}° - {data['rear_wing_angle'].quantile(0.9):.1f}°
|
242 |
+
- Ride height: {data['ride_height'].quantile(0.1):.1f}mm - {data['ride_height'].quantile(0.9):.1f}mm
|
243 |
+
"""
|
244 |
+
|
245 |
+
return fig, report
|
246 |
+
|
247 |
+
def predict_performance(front_wing, rear_wing, ride_height, suspension, downforce, drag_coeff, track_temp, wind_speed, track_grip):
|
248 |
+
"""Predict lap time for given setup"""
|
249 |
+
if not predictor.is_trained:
|
250 |
+
return "⚠️ Please run the analysis first to train the model!"
|
251 |
+
|
252 |
+
setup_params = [front_wing, rear_wing, ride_height, suspension, downforce, drag_coeff, track_temp, wind_speed, track_grip]
|
253 |
+
lap_time = predictor.predict_lap_time(setup_params)
|
254 |
+
|
255 |
+
return f"🏁 Predicted Lap Time: {lap_time:.3f} seconds"
|
256 |
+
|
257 |
+
def optimize_car_setup(track_temp, wind_speed, track_grip):
|
258 |
+
"""Optimize car setup for given conditions"""
|
259 |
+
if not predictor.is_trained:
|
260 |
+
return "⚠️ Please run the analysis first to train the model!"
|
261 |
+
|
262 |
+
track_conditions = [track_temp, wind_speed, track_grip]
|
263 |
+
result = predictor.optimize_setup(track_conditions)
|
264 |
+
|
265 |
+
if result is None:
|
266 |
+
return "❌ Optimization failed"
|
267 |
+
|
268 |
+
optimal_setup, optimal_lap_time = result
|
269 |
+
|
270 |
+
setup_report = f"""
|
271 |
+
## 🏆 Optimal Car Setup
|
272 |
+
|
273 |
+
**Predicted Lap Time: {optimal_lap_time:.3f} seconds**
|
274 |
+
|
275 |
+
**Optimal Configuration:**
|
276 |
+
- Front Wing Angle: {optimal_setup[0]:.1f}°
|
277 |
+
- Rear Wing Angle: {optimal_setup[1]:.1f}°
|
278 |
+
- Ride Height: {optimal_setup[2]:.1f}mm
|
279 |
+
- Suspension Stiffness: {optimal_setup[3]:.1f} N/mm
|
280 |
+
- Target Downforce: {optimal_setup[4]:.0f}N
|
281 |
+
- Target Drag Coefficient: {optimal_setup[5]:.3f}
|
282 |
+
|
283 |
+
**Track Conditions:**
|
284 |
+
- Track Temperature: {track_temp}°C
|
285 |
+
- Wind Speed: {wind_speed} m/s
|
286 |
+
- Track Grip: {track_grip}
|
287 |
+
"""
|
288 |
+
|
289 |
+
return setup_report
|
290 |
+
|
291 |
+
# Create Gradio interface
|
292 |
+
with gr.Blocks(title="F1 Aerodynamic Performance Predictor", theme=gr.themes.Soft()) as demo:
|
293 |
+
gr.Markdown("# 🏎️ F1 Aerodynamic Performance Predictor")
|
294 |
+
gr.Markdown("AI-powered aerodynamic analysis and setup optimization for Formula 1 racing.")
|
295 |
+
|
296 |
+
with gr.Tab("📊 Aerodynamic Analysis"):
|
297 |
+
gr.Markdown("### Analyze aerodynamic performance data")
|
298 |
+
analyze_btn = gr.Button("🔍 Analyze Aerodynamics", variant="primary")
|
299 |
+
|
300 |
+
with gr.Row():
|
301 |
+
with gr.Column(scale=2):
|
302 |
+
aero_plot = gr.Plot(label="Aerodynamic Analysis")
|
303 |
+
with gr.Column(scale=1):
|
304 |
+
aero_report = gr.Markdown(label="Analysis Report")
|
305 |
+
|
306 |
+
analyze_btn.click(
|
307 |
+
analyze_aerodynamics,
|
308 |
+
outputs=[aero_plot, aero_report]
|
309 |
+
)
|
310 |
+
|
311 |
+
with gr.Tab("🎯 Performance Prediction"):
|
312 |
+
gr.Markdown("### Predict lap time for specific setup")
|
313 |
+
gr.Markdown("*Note: Run the analysis first to train the model*")
|
314 |
+
|
315 |
+
with gr.Row():
|
316 |
+
with gr.Column():
|
317 |
+
gr.Markdown("**Car Setup Parameters:**")
|
318 |
+
front_wing_input = gr.Slider(5, 25, value=15, label="Front Wing Angle (°)")
|
319 |
+
rear_wing_input = gr.Slider(8, 35, value=20, label="Rear Wing Angle (°)")
|
320 |
+
ride_height_input = gr.Slider(20, 80, value=50, label="Ride Height (mm)")
|
321 |
+
suspension_input = gr.Slider(50, 150, value=100, label="Suspension Stiffness (N/mm)")
|
322 |
+
downforce_input = gr.Slider(600, 1200, value=900, label="Downforce (N)")
|
323 |
+
drag_input = gr.Slider(0.5, 2.0, value=1.0, label="Drag Coefficient")
|
324 |
+
|
325 |
+
with gr.Column():
|
326 |
+
gr.Markdown("**Track Conditions:**")
|
327 |
+
track_temp_input = gr.Slider(25, 45, value=35, label="Track Temperature (°C)")
|
328 |
+
wind_speed_input = gr.Slider(0, 15, value=5, label="Wind Speed (m/s)")
|
329 |
+
track_grip_input = gr.Slider(0.7, 1.0, value=0.85, label="Track Grip")
|
330 |
+
|
331 |
+
predict_btn = gr.Button("🎯 Predict Lap Time", variant="secondary")
|
332 |
+
|
333 |
+
lap_time_output = gr.Textbox(label="Lap Time Prediction", interactive=False)
|
334 |
+
|
335 |
+
predict_btn.click(
|
336 |
+
predict_performance,
|
337 |
+
inputs=[front_wing_input, rear_wing_input, ride_height_input, suspension_input,
|
338 |
+
downforce_input, drag_input, track_temp_input, wind_speed_input, track_grip_input],
|
339 |
+
outputs=[lap_time_output]
|
340 |
+
)
|
341 |
+
|
342 |
+
with gr.Tab("🏆 Setup Optimization"):
|
343 |
+
gr.Markdown("### Optimize car setup for track conditions")
|
344 |
+
gr.Markdown("*Uses genetic algorithm to find optimal aerodynamic configuration*")
|
345 |
+
|
346 |
+
with gr.Row():
|
347 |
+
with gr.Column():
|
348 |
+
gr.Markdown("**Track Conditions:**")
|
349 |
+
opt_track_temp = gr.Slider(25, 45, value=35, label="Track Temperature (°C)")
|
350 |
+
opt_wind_speed = gr.Slider(0, 15, value=5, label="Wind Speed (m/s)")
|
351 |
+
opt_track_grip = gr.Slider(0.7, 1.0, value=0.85, label="Track Grip")
|
352 |
+
|
353 |
+
optimize_btn = gr.Button("🔧 Optimize Setup", variant="primary")
|
354 |
+
|
355 |
+
with gr.Column():
|
356 |
+
optimization_output = gr.Markdown(label="Optimization Results")
|
357 |
+
|
358 |
+
optimize_btn.click(
|
359 |
+
optimize_car_setup,
|
360 |
+
inputs=[opt_track_temp, opt_wind_speed, opt_track_grip],
|
361 |
+
outputs=[optimization_output]
|
362 |
+
)
|
363 |
+
|
364 |
+
with gr.Tab("ℹ️ About"):
|
365 |
+
gr.Markdown("""
|
366 |
+
## About This Tool
|
367 |
+
|
368 |
+
This F1 Aerodynamic Performance Predictor uses advanced machine learning and optimization techniques:
|
369 |
+
|
370 |
+
**🎯 Performance Prediction:**
|
371 |
+
- Random Forest model predicts lap times based on car setup and track conditions
|
372 |
+
- Considers aerodynamic efficiency, wing configurations, and environmental factors
|
373 |
+
- Trained on realistic F1 aerodynamic data
|
374 |
+
|
375 |
+
**🔧 Setup Optimization:**
|
376 |
+
- Uses Differential Evolution algorithm to find optimal car configurations
|
377 |
+
- Balances downforce vs drag for maximum performance
|
378 |
+
- Considers track-specific conditions for tailored setups
|
379 |
+
|
380 |
+
**📊 Key Features:**
|
381 |
+
- Aerodynamic efficiency analysis (downforce/drag ratio)
|
382 |
+
- Wing angle optimization for different track types
|
383 |
+
- Environmental impact assessment (temperature, wind, grip)
|
384 |
+
- Sensitivity analysis for setup parameters
|
385 |
+
|
386 |
+
**🏗️ Technical Implementation:**
|
387 |
+
- Random Forest Regressor for non-linear relationships
|
388 |
+
- Differential Evolution for global optimization
|
389 |
+
- StandardScaler for feature normalization
|
390 |
+
- Advanced visualization of aerodynamic trade-offs
|
391 |
+
|
392 |
+
**🏁 Racing Applications:**
|
393 |
+
- Pre-race setup optimization
|
394 |
+
- Strategy planning for different track conditions
|
395 |
+
- Understanding aerodynamic trade-offs
|
396 |
+
- Performance prediction for qualifying and race scenarios
|
397 |
+
""")
|
398 |
+
|
399 |
+
if __name__ == "__main__":
|
400 |
+
demo.launch()
|