| """ |
| Vehicle Input Component |
| ======================= |
| Handles vehicle data input forms. |
| """ |
|
|
| import streamlit as st |
| from config import VEHICLE_TYPES, SPEED_RANGE |
|
|
|
|
| def render_vehicle_input(vehicle_id: int): |
| """ |
| Render the vehicle input form. |
| |
| Args: |
| vehicle_id: 1 or 2 to determine which vehicle |
| """ |
| vehicle_key = f'vehicle_{vehicle_id}' |
| color = "#FF4B4B" if vehicle_id == 1 else "#4B7BFF" |
| |
| st.markdown(f""" |
| <div style=" |
| background: rgba(255, 255, 255, 0.08); |
| border: 2px solid {color}; |
| border-radius: 12px; |
| padding: 1.2rem; |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); |
| "> |
| <h3 style="color: {color}; margin: 0; font-weight: 700;">🚗 Vehicle {vehicle_id} Details</h3> |
| </div> |
| """, unsafe_allow_html=True) |
| |
| st.markdown("") |
| |
| |
| vehicle_type = st.selectbox( |
| "Vehicle Type", |
| options=list(VEHICLE_TYPES.keys()), |
| format_func=lambda x: VEHICLE_TYPES[x]['name'], |
| index=list(VEHICLE_TYPES.keys()).index(st.session_state[vehicle_key]['type']), |
| key=f"type_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['type'] = vehicle_type |
| |
| |
| specs = VEHICLE_TYPES[vehicle_type] |
| with st.expander("📋 Vehicle Specifications"): |
| col1, col2 = st.columns(2) |
| with col1: |
| st.write(f"**Length:** {specs['length']} m") |
| st.write(f"**Width:** {specs['width']} m") |
| with col2: |
| st.write(f"**Max Speed:** {specs['max_speed']} km/h") |
| st.write(f"**Accel:** {specs['acceleration']} m/s²") |
| |
| |
| speed = st.slider( |
| "Approximate Speed (km/h)", |
| min_value=SPEED_RANGE['min'], |
| max_value=min(SPEED_RANGE['max'], specs['max_speed']), |
| value=st.session_state[vehicle_key]['speed'], |
| step=5, |
| key=f"speed_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['speed'] = speed |
| |
| |
| if speed < 30: |
| st.success("🐢 Low speed") |
| elif speed < 60: |
| st.info("🚗 Normal speed") |
| elif speed < 100: |
| st.warning("🏎️ High speed") |
| else: |
| st.error("⚠️ Very high speed") |
| |
| |
| direction = st.selectbox( |
| "Direction of Travel", |
| options=['north', 'south', 'east', 'west', 'northeast', 'northwest', 'southeast', 'southwest'], |
| index=['north', 'south', 'east', 'west', 'northeast', 'northwest', 'southeast', 'southwest'].index( |
| st.session_state[vehicle_key]['direction'] |
| ), |
| key=f"direction_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['direction'] = direction |
| |
| |
| direction_arrows = { |
| 'north': '⬆️', 'south': '⬇️', 'east': '➡️', 'west': '⬅️', |
| 'northeast': '↗️', 'northwest': '↖️', 'southeast': '↘️', 'southwest': '↙️' |
| } |
| st.write(f"Direction: {direction_arrows.get(direction, '➡️')} {direction.title()}") |
| |
| |
| action = st.selectbox( |
| "Action Before Accident", |
| options=[ |
| 'going_straight', |
| 'turning_left', |
| 'turning_right', |
| 'changing_lane_left', |
| 'changing_lane_right', |
| 'entering_roundabout', |
| 'exiting_roundabout', |
| 'slowing_down', |
| 'accelerating', |
| 'stopped' |
| ], |
| format_func=lambda x: x.replace('_', ' ').title(), |
| key=f"action_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['action'] = action |
| |
| |
| description = st.text_area( |
| "Driver's Description of Events", |
| value=st.session_state[vehicle_key].get('description', ''), |
| placeholder=f"What did Vehicle {vehicle_id}'s driver say happened?", |
| height=100, |
| key=f"description_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['description'] = description |
| |
| |
| st.markdown("**Additional Factors**") |
| |
| col1, col2 = st.columns(2) |
| |
| with col1: |
| braking = st.checkbox( |
| "Was braking", |
| key=f"braking_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['braking'] = braking |
| |
| signaling = st.checkbox( |
| "Was signaling", |
| key=f"signaling_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['signaling'] = signaling |
| |
| with col2: |
| lights_on = st.checkbox( |
| "Lights on", |
| value=True, |
| key=f"lights_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['lights_on'] = lights_on |
| |
| horn_used = st.checkbox( |
| "Horn used", |
| key=f"horn_{vehicle_id}" |
| ) |
| st.session_state[vehicle_key]['horn_used'] = horn_used |
| |
| |
| st.markdown("---") |
| st.markdown("**Path Status**") |
| |
| path = st.session_state[vehicle_key].get('path', []) |
| if path and len(path) >= 2: |
| st.success(f"✅ Path defined with {len(path)} points") |
| else: |
| st.warning("⚠️ Please draw the vehicle's path on the map") |
|
|
|
|
| def render_vehicle_summary(vehicle_id: int): |
| """ |
| Render a summary of vehicle data. |
| |
| Args: |
| vehicle_id: 1 or 2 |
| """ |
| vehicle_key = f'vehicle_{vehicle_id}' |
| vehicle = st.session_state[vehicle_key] |
| color = "#FF4B4B" if vehicle_id == 1 else "#4B7BFF" |
| |
| st.markdown(f""" |
| <div style=" |
| background: rgba(255, 255, 255, 0.08); |
| backdrop-filter: blur(10px); |
| border: 2px solid {color}; |
| border-radius: 12px; |
| padding: 1.2rem; |
| margin: 0.5rem 0; |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); |
| "> |
| <h4 style="color: {color}; margin: 0 0 0.8rem 0; font-weight: 700;">🚗 Vehicle {vehicle_id}</h4> |
| <p style="margin: 0.25rem 0; color: white;"><b>Type:</b> {VEHICLE_TYPES[vehicle['type']]['name']}</p> |
| <p style="margin: 0.25rem 0; color: white;"><b>Speed:</b> {vehicle['speed']} km/h</p> |
| <p style="margin: 0.25rem 0; color: white;"><b>Direction:</b> {vehicle['direction'].title()}</p> |
| <p style="margin: 0.25rem 0; color: white;"><b>Action:</b> {vehicle.get('action', 'N/A').replace('_', ' ').title()}</p> |
| <p style="margin: 0.25rem 0; color: white;"><b>Path Points:</b> {len(vehicle.get('path', []))}</p> |
| </div> |
| """, unsafe_allow_html=True) |
|
|