import gradio as gr import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor from sklearn.preprocessing import StandardScaler from sklearn.metrics import classification_report, accuracy_score, mean_squared_error import warnings warnings.filterwarnings('ignore') class F1PredictiveMaintenance: def __init__(self): self.failure_classifier = RandomForestClassifier(n_estimators=100, random_state=42) self.wear_predictor = RandomForestRegressor(n_estimators=100, random_state=42) self.scaler = StandardScaler() self.is_trained = False # Component definitions self.components = { 'Engine': {'max_cycles': 7, 'critical_temp': 120, 'normal_temp': 95}, 'Gearbox': {'max_cycles': 6, 'critical_temp': 100, 'normal_temp': 80}, 'Turbocharger': {'max_cycles': 4, 'critical_temp': 140, 'normal_temp': 110}, 'MGU-K': {'max_cycles': 5, 'critical_temp': 90, 'normal_temp': 70}, 'MGU-H': {'max_cycles': 4, 'critical_temp': 130, 'normal_temp': 105}, 'Suspension': {'max_cycles': 8, 'critical_temp': 60, 'normal_temp': 45}, 'Brakes': {'max_cycles': 3, 'critical_temp': 200, 'normal_temp': 150}, 'Tires': {'max_cycles': 1, 'critical_temp': 120, 'normal_temp': 80} } def generate_maintenance_data(self, num_samples=3000): """Generate realistic F1 component maintenance data""" np.random.seed(42) data = [] for _ in range(num_samples): # Select random component component = np.random.choice(list(self.components.keys())) comp_info = self.components[component] # Usage parameters race_weekend = np.random.randint(1, 25) # Race weekend number session_type = np.random.choice(['Practice', 'Qualifying', 'Race']) laps_completed = np.random.randint(10, 70) # Session intensity (Race > Qualifying > Practice) intensity_multiplier = {'Practice': 0.7, 'Qualifying': 1.0, 'Race': 1.2}[session_type] # Environmental conditions ambient_temp = np.random.uniform(15, 35) # °C humidity = np.random.uniform(40, 90) # % track_temp = ambient_temp + np.random.uniform(5, 25) # Operating conditions max_temp = comp_info['normal_temp'] + np.random.normal(0, 10) * intensity_multiplier max_temp = np.clip(max_temp, comp_info['normal_temp'] * 0.8, comp_info['critical_temp'] * 1.2) avg_temp = max_temp * 0.8 + np.random.normal(0, 5) vibration = np.random.exponential(2) * intensity_multiplier load_factor = np.random.uniform(0.6, 1.2) * intensity_multiplier # Component age and usage cycles_used = np.random.uniform(0, comp_info['max_cycles'] * 1.5) total_laps = cycles_used * np.random.uniform(300, 800) # Laps per cycle # Wear calculation temp_stress = max(0, (max_temp - comp_info['normal_temp']) / comp_info['normal_temp']) usage_stress = cycles_used / comp_info['max_cycles'] environmental_stress = (track_temp - 30) / 50 + humidity / 200 wear_level = (usage_stress * 0.4 + temp_stress * 0.3 + vibration * 0.1 + load_factor * 0.1 + environmental_stress * 0.1) wear_level = np.clip(wear_level, 0, 1) # Failure prediction failure_probability = wear_level ** 2 if component in ['Engine', 'Gearbox']: failure_probability *= 0.8 # More reliable components elif component in ['Turbocharger', 'MGU-H']: failure_probability *= 1.3 # Less reliable components # Add random failures failure_risk = failure_probability > 0.7 or np.random.random() < 0.05 # Maintenance recommendations if wear_level > 0.8: maintenance_action = 'Replace' elif wear_level > 0.6: maintenance_action = 'Inspect' elif wear_level > 0.4: maintenance_action = 'Monitor' else: maintenance_action = 'Normal' data.append({ 'component': component, 'race_weekend': race_weekend, 'session_type': session_type, 'laps_completed': laps_completed, 'ambient_temp': ambient_temp, 'track_temp': track_temp, 'humidity': humidity, 'max_temp': max_temp, 'avg_temp': avg_temp, 'vibration': vibration, 'load_factor': load_factor, 'cycles_used': cycles_used, 'total_laps': total_laps, 'wear_level': wear_level, 'failure_risk': failure_risk, 'maintenance_action': maintenance_action }) return pd.DataFrame(data) def train_models(self, data): """Train predictive maintenance models""" # Prepare features feature_columns = ['race_weekend', 'laps_completed', 'ambient_temp', 'track_temp', 'humidity', 'max_temp', 'avg_temp', 'vibration', 'load_factor', 'cycles_used', 'total_laps'] # Encode categorical variables data_encoded = data.copy() data_encoded['component_encoded'] = pd.Categorical(data['component']).codes data_encoded['session_encoded'] = pd.Categorical(data['session_type']).codes feature_columns.extend(['component_encoded', 'session_encoded']) X = data_encoded[feature_columns] X_scaled = self.scaler.fit_transform(X) # Train failure classifier y_failure = data['failure_risk'] self.failure_classifier.fit(X_scaled, y_failure) # Train wear predictor y_wear = data['wear_level'] self.wear_predictor.fit(X_scaled, y_wear) self.is_trained = True # Calculate performance metrics failure_pred = self.failure_classifier.predict(X_scaled) wear_pred = self.wear_predictor.predict(X_scaled) failure_accuracy = accuracy_score(y_failure, failure_pred) wear_rmse = np.sqrt(mean_squared_error(y_wear, wear_pred)) return failure_accuracy, wear_rmse, data_encoded def predict_maintenance(self, component, race_weekend, session_type, laps_completed, ambient_temp, track_temp, humidity, max_temp, avg_temp, vibration, load_factor, cycles_used, total_laps): """Predict maintenance requirements for a component""" if not self.is_trained: return "Model not trained", "Model not trained", "Model not trained" # Encode inputs component_encoded = list(self.components.keys()).index(component) session_encoded = ['Practice', 'Qualifying', 'Race'].index(session_type) # Prepare feature vector features = np.array([[race_weekend, laps_completed, ambient_temp, track_temp, humidity, max_temp, avg_temp, vibration, load_factor, cycles_used, total_laps, component_encoded, session_encoded]]) features_scaled = self.scaler.transform(features) # Make predictions failure_prob = self.failure_classifier.predict_proba(features_scaled)[0][1] wear_level = self.wear_predictor.predict(features_scaled)[0] # Determine maintenance action if wear_level > 0.8 or failure_prob > 0.7: maintenance_action = "REPLACE - Critical wear detected" elif wear_level > 0.6 or failure_prob > 0.5: maintenance_action = "INSPECT - High wear detected" elif wear_level > 0.4 or failure_prob > 0.3: maintenance_action = "MONITOR - Moderate wear" else: maintenance_action = "NORMAL - Good condition" return f"Failure Risk: {failure_prob:.1%}", f"Wear Level: {wear_level:.1%}", maintenance_action def create_maintenance_dashboard(self, data): """Create comprehensive maintenance visualization""" fig, axes = plt.subplots(2, 2, figsize=(15, 12)) # Component reliability analysis component_failure_rate = data.groupby('component')['failure_risk'].mean().sort_values(ascending=False) bars = axes[0, 0].bar(component_failure_rate.index, component_failure_rate.values, color='lightcoral', alpha=0.7) axes[0, 0].set_title('Component Failure Risk Analysis') axes[0, 0].set_ylabel('Failure Risk') axes[0, 0].tick_params(axis='x', rotation=45) axes[0, 0].grid(True, alpha=0.3) # Add value labels on bars for bar in bars: height = bar.get_height() axes[0, 0].text(bar.get_x() + bar.get_width()/2., height, f'{height:.1%}', ha='center', va='bottom') # Wear level distribution axes[0, 1].hist(data['wear_level'], bins=20, alpha=0.7, color='skyblue', edgecolor='black') axes[0, 1].axvline(data['wear_level'].mean(), color='red', linestyle='--', label=f'Mean: {data["wear_level"].mean():.2f}') axes[0, 1].set_title('Component Wear Distribution') axes[0, 1].set_xlabel('Wear Level') axes[0, 1].set_ylabel('Frequency') axes[0, 1].legend() axes[0, 1].grid(True, alpha=0.3) # Temperature vs Wear correlation scatter = axes[1, 0].scatter(data['max_temp'], data['wear_level'], c=data['failure_risk'], cmap='RdYlBu_r', alpha=0.6) axes[1, 0].set_xlabel('Maximum Temperature (°C)') axes[1, 0].set_ylabel('Wear Level') axes[1, 0].set_title('Temperature Impact on Component Wear') plt.colorbar(scatter, ax=axes[1, 0], label='Failure Risk') axes[1, 0].grid(True, alpha=0.3) # Maintenance action recommendations maintenance_counts = data['maintenance_action'].value_counts() wedges, texts, autotexts = axes[1, 1].pie(maintenance_counts.values, labels=maintenance_counts.index, autopct='%1.1f%%', startangle=90) axes[1, 1].set_title('Maintenance Action Distribution') plt.tight_layout() return fig def generate_maintenance_schedule(self, data): """Generate maintenance schedule recommendations""" schedule = [] for component in self.components.keys(): comp_data = data[data['component'] == component] if len(comp_data) == 0: continue avg_wear = comp_data['wear_level'].mean() failure_rate = comp_data['failure_risk'].mean() # Calculate recommended maintenance interval if failure_rate > 0.3: interval = "Every race weekend" elif failure_rate > 0.15: interval = "Every 2 race weekends" elif failure_rate > 0.05: interval = "Every 3 race weekends" else: interval = "Every 4 race weekends" # Priority based on criticality if component in ['Engine', 'Gearbox']: priority = "High" elif component in ['Turbocharger', 'MGU-K', 'MGU-H']: priority = "Critical" else: priority = "Medium" schedule.append({ 'Component': component, 'Average Wear': f"{avg_wear:.1%}", 'Failure Rate': f"{failure_rate:.1%}", 'Recommended Interval': interval, 'Priority': priority }) return pd.DataFrame(schedule) # Initialize the maintenance system maintenance_system = F1PredictiveMaintenance() def analyze_maintenance_data(): """Analyze maintenance data and train models""" # Generate data data = maintenance_system.generate_maintenance_data(3000) # Train models failure_acc, wear_rmse, data_encoded = maintenance_system.train_models(data) # Create visualizations fig = maintenance_system.create_maintenance_dashboard(data) # Generate maintenance schedule schedule = maintenance_system.generate_maintenance_schedule(data) # Create summary report report = f""" ## F1 Predictive Maintenance Analysis **Model Performance:** - Failure Prediction Accuracy: {failure_acc:.1%} - Wear Level RMSE: {wear_rmse:.3f} **Fleet Analysis:** - Total components analyzed: {len(data)} - Average wear level: {data['wear_level'].mean():.1%} - Components at risk: {(data['wear_level'] > 0.6).sum()} - High-priority maintenance: {(data['maintenance_action'] == 'Replace').sum()} **Risk Assessment:** - Highest risk component: {data.groupby('component')['failure_risk'].mean().idxmax()} - Most reliable component: {data.groupby('component')['failure_risk'].mean().idxmin()} - Critical temperature events: {(data['max_temp'] > 120).sum()} **Maintenance Recommendations:** - Immediate attention needed: {(data['wear_level'] > 0.8).sum()} components - Scheduled inspection: {(data['wear_level'] > 0.6).sum()} components - Monitoring required: {(data['wear_level'] > 0.4).sum()} components """ return fig, report, schedule def predict_component_maintenance(component, race_weekend, session_type, laps_completed, ambient_temp, track_temp, humidity, max_temp, avg_temp, vibration, load_factor, cycles_used, total_laps): """Predict maintenance for specific component""" if not maintenance_system.is_trained: return "Please run the analysis first!", "", "" failure_risk, wear_level, maintenance_action = maintenance_system.predict_maintenance( component, race_weekend, session_type, laps_completed, ambient_temp, track_temp, humidity, max_temp, avg_temp, vibration, load_factor, cycles_used, total_laps ) return failure_risk, wear_level, maintenance_action # Create Gradio interface with gr.Blocks(title="F1 Predictive Maintenance System", theme=gr.themes.Soft()) as demo: gr.Markdown("# F1 Predictive Maintenance System") gr.Markdown("AI-powered predictive maintenance for Formula 1 components with failure prediction and wear analysis.") with gr.Tab("Maintenance Analysis"): gr.Markdown("### Analyze component reliability and maintenance requirements") analyze_btn = gr.Button("Analyze Fleet Data", variant="primary") with gr.Row(): with gr.Column(scale=2): maintenance_plot = gr.Plot(label="Maintenance Dashboard") with gr.Column(scale=1): maintenance_report = gr.Markdown(label="Analysis Report") with gr.Row(): maintenance_schedule = gr.DataFrame(label="Maintenance Schedule", interactive=False) analyze_btn.click( analyze_maintenance_data, outputs=[maintenance_plot, maintenance_report, maintenance_schedule] ) with gr.Tab("Component Prediction"): gr.Markdown("### Predict maintenance requirements for specific components") gr.Markdown("*Note: Run the analysis first to train the models*") with gr.Row(): with gr.Column(): gr.Markdown("**Component Information:**") component_select = gr.Dropdown( choices=list(maintenance_system.components.keys()), value="Engine", label="Component" ) race_weekend_input = gr.Slider(1, 25, value=10, label="Race Weekend") session_type_select = gr.Dropdown( choices=["Practice", "Qualifying", "Race"], value="Race", label="Session Type" ) laps_input = gr.Slider(10, 70, value=50, label="Laps Completed") gr.Markdown("**Operating Conditions:**") ambient_temp_input = gr.Slider(15, 35, value=25, label="Ambient Temperature (°C)") track_temp_input = gr.Slider(20, 60, value=40, label="Track Temperature (°C)") humidity_input = gr.Slider(40, 90, value=65, label="Humidity (%)") max_temp_input = gr.Slider(60, 200, value=100, label="Max Component Temperature (°C)") avg_temp_input = gr.Slider(50, 150, value=85, label="Average Temperature (°C)") with gr.Column(): gr.Markdown("**Component Usage:**") vibration_input = gr.Slider(0, 10, value=2, label="Vibration Level") load_factor_input = gr.Slider(0.5, 1.5, value=1.0, label="Load Factor") cycles_input = gr.Slider(0, 10, value=3, label="Cycles Used") total_laps_input = gr.Slider(0, 5000, value=1500, label="Total Laps") predict_btn = gr.Button("Predict Maintenance", variant="secondary") gr.Markdown("**Predictions:**") failure_risk_output = gr.Textbox(label="Failure Risk", interactive=False) wear_level_output = gr.Textbox(label="Wear Level", interactive=False) maintenance_action_output = gr.Textbox(label="Maintenance Action", interactive=False) predict_btn.click( predict_component_maintenance, inputs=[component_select, race_weekend_input, session_type_select, laps_input, ambient_temp_input, track_temp_input, humidity_input, max_temp_input, avg_temp_input, vibration_input, load_factor_input, cycles_input, total_laps_input], outputs=[failure_risk_output, wear_level_output, maintenance_action_output] ) with gr.Tab("About"): gr.Markdown(""" ## About This System This F1 Predictive Maintenance System uses advanced AI to predict component failures and optimize maintenance schedules: **Failure Prediction:** - Random Forest Classifier predicts component failure risk - Considers operating conditions, usage patterns, and environmental factors - Provides early warning for potential failures **Wear Analysis:** - Machine learning model predicts component wear levels - Accounts for temperature stress, vibration, and load factors - Enables proactive maintenance scheduling **Key Features:** - Real-time component health monitoring - Predictive maintenance recommendations - Temperature and environmental impact analysis - Maintenance schedule optimization - Component reliability assessment **Component Coverage:** - Engine and power unit components - Transmission and drivetrain - Hybrid energy systems (MGU-K, MGU-H) - Suspension and braking systems - Tires and consumables **Technical Implementation:** - Random Forest algorithms for robust predictions - Feature engineering for component-specific factors - Time-series analysis for wear progression - Risk assessment and priority classification **Racing Applications:** - Prevent costly race retirements - Optimize component allocation across seasons - Reduce unexpected failures during critical sessions - Enhance reliability through data-driven maintenance """) if __name__ == "__main__": demo.launch()