Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import joblib | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| # Set the title of the app | |
| st.title("π€ Robotic Grasp Robustness Predictor") | |
| st.markdown(""" | |
| Welcome! This application predicts the **stability/robustness** of a robotic grasp based on sensor data. | |
| You can either upload a CSV file with sensor features or input values manually. π | |
| """) | |
| # Display robotics images at the top (ensure the URLs are accessible) | |
| st.image("industrial_robotic_arm_for_automated.png", | |
| caption="Robotic Arm π¦Ύ", use_container_width=True) | |
| # Load the saved model (make sure the model file 'model.pkl' is in the same directory) | |
| def load_model(): | |
| model = joblib.load("model.pkl") | |
| return model | |
| model = load_model() | |
| # Sidebar for input selection | |
| st.sidebar.header("Input Options") | |
| input_method = st.sidebar.radio("Choose input method:", ("Custom / API Input","CSV Upload")) | |
| # Define the list of features expected by the model. | |
| FEATURES = [ | |
| "H1_F1J2_pos", "H1_F1J2_vel", "H1_F1J2_eff", | |
| "H1_F1J3_pos", "H1_F1J3_vel", "H1_F1J3_eff", | |
| "H1_F1J1_pos", "H1_F1J1_vel", "H1_F1J1_eff", | |
| "H1_F3J1_pos", "H1_F3J1_vel", "H1_F3J1_eff", | |
| "H1_F3J2_pos", "H1_F3J2_vel", "H1_F3J2_eff", | |
| "H1_F3J3_pos", "H1_F3J3_vel", "H1_F3J3_eff", | |
| "H1_F2J1_pos", "H1_F2J1_vel", "H1_F2J1_eff", | |
| "H1_F2J3_pos", "H1_F2J3_vel", "H1_F2J3_eff", | |
| "H1_F2J2_pos", "H1_F2J2_vel", "H1_F2J2_eff" | |
| ] | |
| # CSV Upload Option | |
| if input_method == "CSV Upload": | |
| st.header("Upload CSV File π") | |
| uploaded_file = st.file_uploader("Upload your CSV file", type=["csv"]) | |
| if uploaded_file is not None: | |
| try: | |
| input_df = pd.read_csv(uploaded_file) | |
| st.success("CSV file successfully loaded! β ") | |
| # Clean column names | |
| input_df.columns = input_df.columns.str.strip() | |
| missing_features = [col for col in FEATURES if col not in input_df.columns] | |
| if missing_features: | |
| st.error(f"Missing required feature(s): {', '.join(missing_features)} π") | |
| else: | |
| # Make predictions | |
| predictions = model.predict(input_df[FEATURES]) | |
| input_df["Predicted Robustness"] = predictions | |
| # Interactive histogram of predictions | |
| fig_hist = px.histogram(input_df, x="Predicted Robustness", nbins=30, | |
| title="Distribution of Predicted Robustness") | |
| st.plotly_chart(fig_hist, use_container_width=True) | |
| st.subheader("Predictions") | |
| st.dataframe(input_df) | |
| except Exception as e: | |
| st.error(f"Error processing file: {e}") | |
| # Manual Input Option | |
| else: | |
| st.header("Manual Input βοΈ") | |
| st.markdown("Enter the sensor values for prediction below:") | |
| # Add a radio button for selecting the input mode within manual input | |
| input_mode = st.radio("Select input mode:", ("Custom Input", "API Default Values")) | |
| # Default API values (you can adjust these as appropriate) | |
| default_values = { | |
| "H1_F1J2_pos": 0.5, "H1_F1J2_vel": 0.0, "H1_F1J2_eff": 0.1, | |
| "H1_F1J3_pos": 0.5, "H1_F1J3_vel": 0.0, "H1_F1J3_eff": 0.1, | |
| "H1_F1J1_pos": 0.5, "H1_F1J1_vel": 0.0, "H1_F1J1_eff": 0.1, | |
| "H1_F3J1_pos": 1.0, "H1_F3J1_vel": 0.0, "H1_F3J1_eff": 0.2, | |
| "H1_F3J2_pos": 1.0, "H1_F3J2_vel": 0.0, "H1_F3J2_eff": 0.2, | |
| "H1_F3J3_pos": 1.0, "H1_F3J3_vel": 0.0, "H1_F3J3_eff": 0.2, | |
| "H1_F2J1_pos": 0.7, "H1_F2J1_vel": 0.0, "H1_F2J1_eff": 0.15, | |
| "H1_F2J3_pos": 0.7, "H1_F2J3_vel": 0.0, "H1_F2J3_eff": 0.15, | |
| "H1_F2J2_pos": 0.7, "H1_F2J2_vel": 0.0, "H1_F2J2_eff": 0.15, | |
| } | |
| # Container dictionary for all input values. | |
| input_data = {} | |
| # Create expandable sections for sensor groups. | |
| with st.expander("F1 Joint Sensors"): | |
| st.write("Sensors for Finger 1:") | |
| input_data["H1_F1J2_pos"] = st.number_input("H1_F1J2_pos", | |
| value=default_values["H1_F1J2_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J2_vel"] = st.number_input("H1_F1J2_vel", | |
| value=default_values["H1_F1J2_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J2_eff"] = st.number_input("H1_F1J2_eff", | |
| value=default_values["H1_F1J2_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| st.write("Sensors for Finger 3:") | |
| input_data["H1_F1J3_pos"] = st.number_input("H1_F1J3_pos", | |
| value=default_values["H1_F1J3_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J3_vel"] = st.number_input("H1_F1J3_vel", | |
| value=default_values["H1_F1J3_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J3_eff"] = st.number_input("H1_F1J3_eff", | |
| value=default_values["H1_F1J3_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| st.write("Sensors for Finger 1 (alternate):") | |
| input_data["H1_F1J1_pos"] = st.number_input("H1_F1J1_pos", | |
| value=default_values["H1_F1J1_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J1_vel"] = st.number_input("H1_F1J1_vel", | |
| value=default_values["H1_F1J1_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F1J1_eff"] = st.number_input("H1_F1J1_eff", | |
| value=default_values["H1_F1J1_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| with st.expander("F3 Joint Sensors"): | |
| input_data["H1_F3J1_pos"] = st.number_input("H1_F3J1_pos", | |
| value=default_values["H1_F3J1_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J1_vel"] = st.number_input("H1_F3J1_vel", | |
| value=default_values["H1_F3J1_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J1_eff"] = st.number_input("H1_F3J1_eff", | |
| value=default_values["H1_F3J1_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J2_pos"] = st.number_input("H1_F3J2_pos", | |
| value=default_values["H1_F3J2_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J2_vel"] = st.number_input("H1_F3J2_vel", | |
| value=default_values["H1_F3J2_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J2_eff"] = st.number_input("H1_F3J2_eff", | |
| value=default_values["H1_F3J2_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J3_pos"] = st.number_input("H1_F3J3_pos", | |
| value=default_values["H1_F3J3_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J3_vel"] = st.number_input("H1_F3J3_vel", | |
| value=default_values["H1_F3J3_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F3J3_eff"] = st.number_input("H1_F3J3_eff", | |
| value=default_values["H1_F3J3_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| with st.expander("F2 Joint Sensors"): | |
| input_data["H1_F2J1_pos"] = st.number_input("H1_F2J1_pos", | |
| value=default_values["H1_F2J1_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J1_vel"] = st.number_input("H1_F2J1_vel", | |
| value=default_values["H1_F2J1_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J1_eff"] = st.number_input("H1_F2J1_eff", | |
| value=default_values["H1_F2J1_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J3_pos"] = st.number_input("H1_F2J3_pos", | |
| value=default_values["H1_F2J3_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J3_vel"] = st.number_input("H1_F2J3_vel", | |
| value=default_values["H1_F2J3_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J3_eff"] = st.number_input("H1_F2J3_eff", | |
| value=default_values["H1_F2J3_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J2_pos"] = st.number_input("H1_F2J2_pos", | |
| value=default_values["H1_F2J2_pos"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J2_vel"] = st.number_input("H1_F2J2_vel", | |
| value=default_values["H1_F2J2_vel"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| input_data["H1_F2J2_eff"] = st.number_input("H1_F2J2_eff", | |
| value=default_values["H1_F2J2_eff"] if input_mode=="API Default Values" else 0.0, | |
| format="%.5f") | |
| # Predict button for manual input | |
| if st.button("Predict π"): | |
| input_df = pd.DataFrame([input_data]) | |
| prediction = model.predict(input_df) | |
| st.success(f"The predicted grasp robustness is: {prediction[0]:.3f}") | |
| # Create a gauge chart using Plotly for visualization. | |
| fig_gauge = go.Figure(go.Indicator( | |
| mode="gauge+number", | |
| value=prediction[0], | |
| title={'text': "Grasp Robustness"}, | |
| gauge={ | |
| 'axis': {'range': [0, 100]}, | |
| 'bar': {'color': "darkblue"}, | |
| 'steps': [ | |
| {'range': [0, 30], 'color': "red"}, | |
| {'range': [30, 70], 'color': "yellow"}, | |
| {'range': [70, 100], 'color': "green"} | |
| ], | |
| } | |
| )) | |
| st.plotly_chart(fig_gauge, use_container_width=True) | |
| # Display feature importances if available | |
| try: | |
| feature_importances = model.named_steps['model'].feature_importances_ | |
| imp_df = pd.DataFrame({ | |
| 'Feature': FEATURES, | |
| 'Importance': feature_importances | |
| }).sort_values(by='Importance', ascending=False) | |
| st.subheader("Feature Importances π") | |
| fig_imp = px.bar(imp_df, x='Feature', y='Importance', title="Feature Importances") | |
| st.plotly_chart(fig_imp, use_container_width=True) | |
| except Exception as ex: | |
| st.info("Feature importance is not available for this model.") | |