CCockrum commited on
Commit
6e2e787
·
verified ·
1 Parent(s): b59fc59

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +283 -0
app.py ADDED
@@ -0,0 +1,283 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 IsolationForest
6
+ from sklearn.preprocessing import StandardScaler
7
+ from sklearn.linear_model import LinearRegression
8
+ from sklearn.metrics import mean_squared_error, r2_score
9
+ import warnings
10
+ warnings.filterwarnings('ignore')
11
+
12
+ class F1TelemetryAnalyzer:
13
+ def __init__(self):
14
+ self.scaler = StandardScaler()
15
+ self.anomaly_detector = IsolationForest(contamination=0.1, random_state=42)
16
+ self.tire_model = LinearRegression()
17
+ self.fuel_model = LinearRegression()
18
+ self.is_trained = False
19
+
20
+ def generate_sample_data(self, num_samples=1000):
21
+ """Generate realistic F1 telemetry data"""
22
+ np.random.seed(42)
23
+
24
+ # Base parameters
25
+ lap_time = np.random.normal(90, 5, num_samples) # seconds
26
+ speed = np.random.normal(200, 30, num_samples) # km/h
27
+ throttle = np.random.uniform(0, 100, num_samples) # %
28
+ brake_pressure = np.random.uniform(0, 100, num_samples) # %
29
+ tire_temp = np.random.normal(80, 15, num_samples) # °C
30
+ engine_temp = np.random.normal(95, 10, num_samples) # °C
31
+
32
+ # Introduce some realistic correlations
33
+ speed = np.clip(speed + throttle * 0.5 - brake_pressure * 0.3, 50, 300)
34
+ tire_temp = np.clip(tire_temp + speed * 0.1 + throttle * 0.2, 40, 120)
35
+ engine_temp = np.clip(engine_temp + throttle * 0.15 + speed * 0.05, 70, 130)
36
+
37
+ # Lap number for degradation modeling
38
+ lap_number = np.random.randint(1, 60, num_samples)
39
+
40
+ # Tire degradation (performance decreases over laps)
41
+ tire_degradation = 100 - (lap_number * 0.8 + np.random.normal(0, 2, num_samples))
42
+ tire_degradation = np.clip(tire_degradation, 60, 100)
43
+
44
+ # Fuel consumption (decreases with laps)
45
+ fuel_remaining = 100 - (lap_number * 1.5 + np.random.normal(0, 3, num_samples))
46
+ fuel_remaining = np.clip(fuel_remaining, 0, 100)
47
+
48
+ # Add some anomalies
49
+ anomaly_indices = np.random.choice(num_samples, size=int(num_samples * 0.05), replace=False)
50
+ speed[anomaly_indices] = np.random.uniform(20, 50, len(anomaly_indices)) # Very slow speeds
51
+ tire_temp[anomaly_indices] = np.random.uniform(130, 150, len(anomaly_indices)) # Overheating
52
+
53
+ return pd.DataFrame({
54
+ 'lap_time': lap_time,
55
+ 'speed': speed,
56
+ 'throttle': throttle,
57
+ 'brake_pressure': brake_pressure,
58
+ 'tire_temp': tire_temp,
59
+ 'engine_temp': engine_temp,
60
+ 'lap_number': lap_number,
61
+ 'tire_degradation': tire_degradation,
62
+ 'fuel_remaining': fuel_remaining
63
+ })
64
+
65
+ def detect_anomalies(self, data):
66
+ """Detect anomalies in telemetry data"""
67
+ features = ['speed', 'throttle', 'brake_pressure', 'tire_temp', 'engine_temp']
68
+ X = data[features]
69
+
70
+ # Fit and predict anomalies
71
+ anomalies = self.anomaly_detector.fit_predict(X)
72
+ data['anomaly'] = anomalies
73
+
74
+ return data
75
+
76
+ def train_predictive_models(self, data):
77
+ """Train tire degradation and fuel consumption models"""
78
+ # Prepare features for prediction
79
+ features = ['lap_number', 'speed', 'throttle', 'tire_temp', 'engine_temp']
80
+ X = data[features]
81
+
82
+ # Train tire degradation model
83
+ y_tire = data['tire_degradation']
84
+ self.tire_model.fit(X, y_tire)
85
+
86
+ # Train fuel consumption model
87
+ y_fuel = data['fuel_remaining']
88
+ self.fuel_model.fit(X, y_fuel)
89
+
90
+ self.is_trained = True
91
+
92
+ # Calculate model performance
93
+ tire_pred = self.tire_model.predict(X)
94
+ fuel_pred = self.fuel_model.predict(X)
95
+
96
+ tire_r2 = r2_score(y_tire, tire_pred)
97
+ fuel_r2 = r2_score(y_fuel, fuel_pred)
98
+
99
+ return tire_r2, fuel_r2
100
+
101
+ def predict_performance(self, lap_number, speed, throttle, tire_temp, engine_temp):
102
+ """Predict tire degradation and fuel consumption"""
103
+ if not self.is_trained:
104
+ return "Model not trained yet!", ""
105
+
106
+ features = np.array([[lap_number, speed, throttle, tire_temp, engine_temp]])
107
+
108
+ tire_pred = self.tire_model.predict(features)[0]
109
+ fuel_pred = self.fuel_model.predict(features)[0]
110
+
111
+ return f"Predicted Tire Performance: {tire_pred:.1f}%", f"Predicted Fuel Remaining: {fuel_pred:.1f}%"
112
+
113
+ def create_visualizations(self, data):
114
+ """Create telemetry visualizations"""
115
+ fig, axes = plt.subplots(2, 2, figsize=(15, 12))
116
+
117
+ # Speed vs Lap Time
118
+ normal_data = data[data['anomaly'] == 1]
119
+ anomaly_data = data[data['anomaly'] == -1]
120
+
121
+ axes[0, 0].scatter(normal_data['speed'], normal_data['lap_time'],
122
+ alpha=0.6, label='Normal', color='blue')
123
+ axes[0, 0].scatter(anomaly_data['speed'], anomaly_data['lap_time'],
124
+ alpha=0.8, label='Anomaly', color='red')
125
+ axes[0, 0].set_xlabel('Speed (km/h)')
126
+ axes[0, 0].set_ylabel('Lap Time (s)')
127
+ axes[0, 0].set_title('Speed vs Lap Time (Anomaly Detection)')
128
+ axes[0, 0].legend()
129
+ axes[0, 0].grid(True, alpha=0.3)
130
+
131
+ # Tire Temperature Distribution
132
+ axes[0, 1].hist(normal_data['tire_temp'], bins=30, alpha=0.7, label='Normal', color='blue')
133
+ axes[0, 1].hist(anomaly_data['tire_temp'], bins=30, alpha=0.7, label='Anomaly', color='red')
134
+ axes[0, 1].set_xlabel('Tire Temperature (°C)')
135
+ axes[0, 1].set_ylabel('Frequency')
136
+ axes[0, 1].set_title('Tire Temperature Distribution')
137
+ axes[0, 1].legend()
138
+ axes[0, 1].grid(True, alpha=0.3)
139
+
140
+ # Tire Degradation over Laps
141
+ axes[1, 0].scatter(data['lap_number'], data['tire_degradation'], alpha=0.6, color='green')
142
+ axes[1, 0].set_xlabel('Lap Number')
143
+ axes[1, 0].set_ylabel('Tire Performance (%)')
144
+ axes[1, 0].set_title('Tire Degradation Over Race')
145
+ axes[1, 0].grid(True, alpha=0.3)
146
+
147
+ # Fuel Consumption
148
+ axes[1, 1].scatter(data['lap_number'], data['fuel_remaining'], alpha=0.6, color='orange')
149
+ axes[1, 1].set_xlabel('Lap Number')
150
+ axes[1, 1].set_ylabel('Fuel Remaining (%)')
151
+ axes[1, 1].set_title('Fuel Consumption Over Race')
152
+ axes[1, 1].grid(True, alpha=0.3)
153
+
154
+ plt.tight_layout()
155
+ return fig
156
+
157
+ # Initialize the analyzer
158
+ analyzer = F1TelemetryAnalyzer()
159
+
160
+ def analyze_telemetry():
161
+ """Main function to run telemetry analysis"""
162
+ # Generate sample data
163
+ data = analyzer.generate_sample_data(1000)
164
+
165
+ # Detect anomalies
166
+ data = analyzer.detect_anomalies(data)
167
+
168
+ # Train predictive models
169
+ tire_r2, fuel_r2 = analyzer.train_predictive_models(data)
170
+
171
+ # Create visualizations
172
+ fig = analyzer.create_visualizations(data)
173
+
174
+ # Generate summary report
175
+ total_samples = len(data)
176
+ anomalies_detected = len(data[data['anomaly'] == -1])
177
+ anomaly_percentage = (anomalies_detected / total_samples) * 100
178
+
179
+ report = f"""
180
+ ## F1 Telemetry Analysis Report
181
+
182
+ **Data Summary:**
183
+ - Total samples analyzed: {total_samples}
184
+ - Anomalies detected: {anomalies_detected} ({anomaly_percentage:.1f}%)
185
+
186
+ **Model Performance:**
187
+ - Tire Degradation Model R²: {tire_r2:.3f}
188
+ - Fuel Consumption Model R²: {fuel_r2:.3f}
189
+
190
+ **Key Insights:**
191
+ - Average lap time: {data['lap_time'].mean():.1f} seconds
192
+ - Average speed: {data['speed'].mean():.1f} km/h
193
+ - Maximum tire temperature: {data['tire_temp'].max():.1f}°C
194
+ - Minimum tire performance: {data['tire_degradation'].min():.1f}%
195
+
196
+ **Anomaly Analysis:**
197
+ - Anomalies primarily detected in: Low speed conditions and high tire temperatures
198
+ - Recommended action: Investigate cooling systems and potential mechanical issues
199
+ """
200
+
201
+ return fig, report
202
+
203
+ def predict_telemetry(lap_number, speed, throttle, tire_temp, engine_temp):
204
+ """Predict tire and fuel performance"""
205
+ tire_pred, fuel_pred = analyzer.predict_performance(lap_number, speed, throttle, tire_temp, engine_temp)
206
+ return tire_pred, fuel_pred
207
+
208
+ # Create Gradio interface
209
+ with gr.Blocks(title="F1 Telemetry Data Analyzer", theme=gr.themes.Soft()) as demo:
210
+ gr.Markdown("# 🏎️ F1 Telemetry Data Analyzer")
211
+ gr.Markdown("Advanced AI-powered analysis of Formula 1 telemetry data with anomaly detection and predictive modeling.")
212
+
213
+ with gr.Tab("📊 Data Analysis"):
214
+ gr.Markdown("### Generate and analyze telemetry data")
215
+ analyze_btn = gr.Button("🔍 Analyze Telemetry Data", variant="primary")
216
+
217
+ with gr.Row():
218
+ with gr.Column(scale=2):
219
+ plot_output = gr.Plot(label="Telemetry Visualizations")
220
+ with gr.Column(scale=1):
221
+ report_output = gr.Markdown(label="Analysis Report")
222
+
223
+ analyze_btn.click(
224
+ analyze_telemetry,
225
+ outputs=[plot_output, report_output]
226
+ )
227
+
228
+ with gr.Tab("🔮 Performance Prediction"):
229
+ gr.Markdown("### Predict tire performance and fuel consumption")
230
+ gr.Markdown("*Note: Run the analysis first to train the models*")
231
+
232
+ with gr.Row():
233
+ with gr.Column():
234
+ lap_input = gr.Slider(1, 60, value=10, label="Lap Number")
235
+ speed_input = gr.Slider(50, 300, value=200, label="Speed (km/h)")
236
+ throttle_input = gr.Slider(0, 100, value=75, label="Throttle (%)")
237
+ tire_temp_input = gr.Slider(40, 120, value=80, label="Tire Temperature (°C)")
238
+ engine_temp_input = gr.Slider(70, 130, value=95, label="Engine Temperature (°C)")
239
+
240
+ predict_btn = gr.Button("🎯 Predict Performance", variant="secondary")
241
+
242
+ with gr.Column():
243
+ tire_pred_output = gr.Textbox(label="Tire Performance Prediction")
244
+ fuel_pred_output = gr.Textbox(label="Fuel Consumption Prediction")
245
+
246
+ predict_btn.click(
247
+ predict_telemetry,
248
+ inputs=[lap_input, speed_input, throttle_input, tire_temp_input, engine_temp_input],
249
+ outputs=[tire_pred_output, fuel_pred_output]
250
+ )
251
+
252
+ with gr.Tab("ℹ️ About"):
253
+ gr.Markdown("""
254
+ ## About This Tool
255
+
256
+ This F1 Telemetry Data Analyzer demonstrates advanced AI techniques used in Formula 1 racing:
257
+
258
+ **🔍 Anomaly Detection:**
259
+ - Uses Isolation Forest algorithm to detect unusual patterns in telemetry data
260
+ - Identifies potential mechanical issues or performance anomalies
261
+ - Helps engineers spot problems before they become critical
262
+
263
+ **📈 Predictive Modeling:**
264
+ - Machine learning models predict tire degradation and fuel consumption
265
+ - Based on real-time telemetry inputs (speed, throttle, temperatures)
266
+ - Enables strategic decision-making during races
267
+
268
+ **🎯 Key Features:**
269
+ - Real-time telemetry processing simulation
270
+ - Advanced visualization of racing data
271
+ - Performance prediction for race strategy
272
+ - Anomaly detection for preventive maintenance
273
+
274
+ **🏗️ Technical Stack:**
275
+ - Python with scikit-learn for ML models
276
+ - Isolation Forest for anomaly detection
277
+ - Linear regression for performance prediction
278
+ - Matplotlib for advanced visualizations
279
+ - Gradio for interactive web interface
280
+ """)
281
+
282
+ if __name__ == "__main__":
283
+ demo.launch()