From f37553fffd805558eec3f9ca5ad5bf56b046b8fe Mon Sep 17 00:00:00 2001 From: Kai Chappell Date: Mon, 24 Mar 2025 15:02:51 +0000 Subject: [PATCH] Add interactive physics controls --- src/py_dvt_ate/app/dashboard/app.py | 78 +++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/src/py_dvt_ate/app/dashboard/app.py b/src/py_dvt_ate/app/dashboard/app.py index 5a12b76..df6a06e 100644 --- a/src/py_dvt_ate/app/dashboard/app.py +++ b/src/py_dvt_ate/app/dashboard/app.py @@ -118,6 +118,81 @@ def display_current_state() -> None: st.metric("Sim Time", f"{engine.simulation_time:.2f} s") +def display_controls() -> None: + """Display simulation control panel in sidebar.""" + engine: PhysicsEngine = st.session_state.engine + + st.sidebar.header("Simulation Controls") + + # Start/Stop button + if st.session_state.running: + if st.sidebar.button("Stop Simulation", type="primary", use_container_width=True): + st.session_state.running = False + st.rerun() + else: + if st.sidebar.button( + "Start Simulation", type="primary", use_container_width=True + ): + st.session_state.running = True + st.rerun() + + # Reset button + if st.sidebar.button("Reset", use_container_width=True): + st.session_state.engine = PhysicsEngine(update_rate_hz=100.0) + st.session_state.history = SimulationHistory() + st.session_state.running = False + st.rerun() + + st.sidebar.divider() + + # Temperature setpoint + st.sidebar.subheader("Thermal Chamber") + temp_setpoint = st.sidebar.slider( + "Temperature Setpoint (°C)", + min_value=-40.0, + max_value=125.0, + value=25.0, + step=5.0, + key="temp_setpoint", + ) + engine.set_chamber_setpoint(temp_setpoint) + + st.sidebar.divider() + + # Power supply controls + st.sidebar.subheader("Power Supply") + input_voltage = st.sidebar.slider( + "Input Voltage (V)", + min_value=0.0, + max_value=12.0, + value=5.0, + step=0.1, + key="input_voltage", + ) + engine.set_input_voltage(input_voltage) + + output_enabled = st.sidebar.toggle( + "Output Enabled", + value=engine.is_output_enabled, + key="output_enabled", + ) + engine.set_output_enabled(output_enabled) + + st.sidebar.divider() + + # Load controls + st.sidebar.subheader("Electronic Load") + load_current_ma = st.sidebar.slider( + "Load Current (mA)", + min_value=0.0, + max_value=500.0, + value=100.0, + step=10.0, + key="load_current", + ) + engine.set_load_current(load_current_ma / 1000.0) + + def main() -> None: """Main entry point for the Streamlit dashboard.""" st.set_page_config( @@ -136,6 +211,9 @@ def main() -> None: init_session_state() + # Sidebar controls + display_controls() + # Current state display st.subheader("Current State") display_current_state()