2024 - 2026 Simulation Software

2024 - 2026 Simulation Software

Code Architecture:

Backend:

Tech Stack:

  • Python 3.12.x

  • Numpy

    • For faster array manipulation

  • Pandas

    • csv handling

  • SciPy

    • Interpolate the points

Design Considerations:

Architecture and Modularity

  • Separation

    • core/ (physics + MPPT)

    • simulators/ (time loop)

    • ui/ (desktop GUI)

    • data/ (models, profiles)

  • Clear Interfaces

  • Config first

    • single config.yaml / toml for model params, profiles, algos, plotting cadence

    • immutable at runtime

    • runtime overrides via CLI flags

Real-Time Behavior

  • clocking

    • fixed timestep engine

      • option to use real-time mode (wall clock) vs fast-forward (sim time)

  • threading

    • UI thread separate from sim

    • threads need to be safe

      • no blocking disk I/O on UI thread

  • decouple sim tick from plot refresh

    • queue telemetry frames to the UI thread

  • while sliders drag, coarsen step_v (use larger v increments)

    • smoother refresh

    • once idle, auto refine and recompute MPP

 

UI/UX

  • controls

    • sliders for G/T, optional wind/shading toggles

    • the goals is to make it interactive

  • plot design

    • IV+PV with current Vref marker

    • time series of (G, T, V, I, P)

    • power vs true Pmax

    • Legends + units

    • Efficiency Panes

  • Presets

    • Preset scenarios?

    • make it easy to use common scenarios

    • keyboard shortcuts?

    • persist UI state between runs?

  • Data & Reproducibility

    • File formats: CSV/Parquet

      • per tick telemetry

        • run_id, t, Vref, V, I, P, G, Tc, Voc, Isc, Pmax_theory, algo, mode, explore_active

      • Source-grid

        • V, G, Tc, I + metadata: STC parameters, grid sizes, interpolation method, git SHA, created_at.

        • Source grid exists because solving the single-diode equation every sim tick is expensive

          • so precompute the IV relationship for a grid of points:

            • Voltage (V) : 0 → Voc, in small steps (e.g. 200 points)

            • Irradiance (G) : 0 → ~1200 W m⁻², several levels

            • Cell temperature (Tc) : –10 → 70 °C, several levels

          • store those currents I(V, G, Tc) in a 3D array (the source-grid)

          • at run time, when MPPT algo asks for current at conditions, sim uses a tri-linear interpolation inside that grid to return the current

            • its a quick look up

      • Profiles

        • {t, G, Tc[, load]} with opeartional per-module/per-substring irradiance maps

      • seed for stochastic algos

    • autosave summary metrics + plots per run into timestamped folder

      • option to export MPPT traces?

 

Engine and Messaging

  • fixed timestep: default 100 hz? (0.01s)

  • threading: sim loop runs in its own thread; UI refresh decoupled

  • 2 way messaging:

    • Engine → UI example:

      • {
        "t": 2.35,
        "V": 27.8, "I": 3.1, "P": 86.2,
        "Vref": 28.0,
        "G": 900, "Tc": 31.2,
        "Pmax_theory": 92.7,
        "algo": "pand_o",
        "mode": "exploit",
        "explore_active": false
        }

    • UI → Engine example:

      • { "cmd": "set", "path": "mppt.algo", "value": "hybrid_gs" }
        { "cmd": "pause", "value": true }
        { "cmd": "set", "path": "profile.G", "value": 750 }

  • msgs delivered through Qt signals/slots or a thread-safe queue

    • preference toward Qt

 

User Interface Scope

  • initial screens/widgets

    • IV/PV panel: live curves, Vref marker, optional explore samples

    • Time-series panel: V, I, P, G, Tc over time

    • Power vs P_max: MPPT output vs theoretical maximum

    • Efficiency Pane: instantaneous and rolling tracking efficiency

  • Controls:

    • irradiance and temp sliders

    • algo selector

    • start/stop buttons

 

Logging, Errors & Observability

  • structured logs with run_id, git_sha, seed, tick_ms, cache_hits

  • log levels: DEBUG, INFO, WARN, ERROR

  • On screen HUD: tick time, UI FPS, explore duty cycle

  • UI toasts for schema validation errors or out of bounds commands

 

Validation & Testing

  • Golden STC (Standard Test Conditions) tests: Vmpp, Impp, Voc, Isc within set tolerances.

    • simulated array should produce values close to known datasheet numbers

    • need to set a tolerance for this

  • Property tests: I(V=0)=Isc, V(I=0)=Voc, Pmax increases with G, Voc decreases with Tc.

    • make sure these relationships must always hold

  • Partial shading scenarios: multi-peak PV curve; Hybrid GS must outperform P&O.

    • make sure it can handle multiple peaks

  • Regression suite: locks expected metrics for each canned scenario.

 

Other Notes

  • Other teams should be able to use our functions

    • TrackSim needs to be able to input irradiance to model shading

    • deprioritize integration with other teams for now

  • Maintainability

    • When we add the aeroshell angle simulator, we should be able to reuse our functions without needing to change much

  • Array should be easy to build

    • We separate objects to Cell, Module, String

  • Dynamic environments with changing irradiance and temperature should be modeled

    • Read array value from user input so real-time changes could be reflected

      • array > queue for history

        • no point of queue if we will not exceed memory

    • User should be able to input a .txt file of cycles and then parse to simulate dynamic environments

    • User should be able to step through or auto-run dynamic environments

  • Environment should be a little noisy with bumps to replicate real curves

Power Curve Simulation:

Overview:

Cell → Substring → String → Array

  • Cell: basic photovoltaic unit, modeled with a single-diode equation.

  • Substring: series of cells, optionally grouped with bypass diodes.

  • String: series of modules, raising voltage for inverter input.

  • Array: parallel of strings, raising current for total output power.

Notes:

  • All objects should have the option of Ideal or Non-Ideal

    • Calculations will be different depending on state

  • keep Substring as first-class with bypass diode logic; precompute per-substring IV, then compose at Module/String. This keeps multi-peak P-V natural.

1. Cell (single-diode model)

Constants and Helpers:

Parameters (at STC, 1000 W/m², 25 °C):

These should either be imported from measuring the individual cell and input those parameters or just make them all the same. Some could be found from the sheet for ideal factors.

  • Isc_ref [A]: short-circuit current

  • Voc_ref [V]: open-circuit voltage

  • n [–]: diode ideality factor (≈ 1–2)

  • Rs [Ω]: series resistance

  • Rsh [Ω]: shunt (parallel) resistance

Temperature coefficients:

  • alpha_Isc [A/°C]: temperature coefficient of Isc

  • beta_Voc [V/°C]: temperature coefficient of Voc

Environment (runtime inputs):

  • G [W/m²]: irradiance on the cell

  • T_c [°C]: cell temperature

Numerical controls:

  • tol: solver tolerance

  • max_iter: max iterations for Newton/bisection

Functions:

  • set_conditions(G, T_c): update irradiance, temperature, and other values → None

    • We can consider calculating true irradiance from the angle that the sun hits the solar cell later.

  • i_of_v(V): current at a given voltage (single-diode model) → float

    • Here we are trying to solve the I (current) at a specific voltage according to the equation. We use the newton equation in order to get better estimates on what the correct I should be.

    • Later we can upgrade to a two diode equation which uses I1 and I2 and is more accurate but takes longer computation time.

  • v_at_i(I): module voltage at current I (sum of cell voltages at I) → float

    •  

    • This is the same equation as the one to solve for i_at_v but for solving voltage given current

  • voc(): open-circuit voltage (where I = 0) → float

  • iv_curve(points): sweep voltages, compute currents → List

    • solve i_of_v(V) for alot of points and return (V,I,P = VI)

  • mpp(): return Vmpp, Impp, Pmpp, Voc, Isc

2. Substring (cells in series, optional bypass)

Composition:

  • Contains a list of Cell objects.

  • Each module 6-8 cells has 1 bypass diode

  • Bypass Diode is a separate class

Rules:

  • Series wiring → current is common, voltages add.

  • Bypass diodes allow shaded substrings to drop out when reverse biased.

Functions:

  • set_conditions(G, T_c): broadcast to all cells → None

  • isc(): module short-circuit current (≈ min cell Isc) → float

    •  

    • we can upgrade to this equation later, but for now we can stick with min cell

  • voc(): module open-circuit voltage (sum of cell Voc) → float

  • v_at_i(I):

    • Call each cell’s v_at_i(I) to get the sum of all voltages

    • We then also take BypassDiode’s equation for finding Vbypass and take the max of both

  • iv_curve(points): sweep current 0 → Isc, compute V(I) → float

  • mpp(): return Vmpp, Impp, Pmpp, Voc, Isc

2.1 BypassDiode (helper class for substring)

Composition:

  • Contains a helper class for calculating bypass diode values

Rules:

  • none

Functions:

  • set_temperature(T_c)

    •  

  • v_at_i(I)

    • diode terminal voltage at current I

  • dv_dI(I)

    • slope of diode voltage curve, useful for newton solvers

  • activation_condition(Vcells, I)

    • check if the diode turns on if cells would go more negative than the bypass clamp

  • Clamp(Vcells, I)

    • take whatever voltage is greater

    •  

3. String (substrings in series)

Composition:

  • Contains a list of Module objects.

Rules:

  • Series wiring → same current, voltages add.

Functions:

  • set_conditions(G, T_c): broadcast to all modules → None

  • isc(): string short-circuit current (≈ min module Isc) → Float

  • voc(): string open-circuit voltage (sum of module Voc) → Float

  • v_at_i(I): sum of module voltages at current I → Float

    • We can just sum all of the voltages since we calculated it earlier

  • iv_curve(points): sweep current, compute V(I) → List

  • mpp(): return Vmpp, Impp, Pmpp, Voc, Isc

4. Array (strings in parallel)

Composition:

  • Contains a list of String objects.

Rules:

  • Parallel wiring → same voltage across strings, currents add.

  • Optional: account for bus/combiner resistance R_bus.

Functions:

  • set_conditions(G, T_c): broadcast to all strings

  • voc(): array open-circuit voltage (≈ max of string Voc)

  • isc(): array short-circuit current (sum of string Isc)

  • i_at_v(V): sum of string currents at a common voltage V

    • We can just sum all of the currents at V for the strings

    •  

  • iv_curve(points): sweep voltage, sum currents

  • mpp(): Vmpp, Impp, Pmpp, Voc, Isc

5. Caching for Performance

  • Each object (Cell, Module, String, Array) can cache its IV curve for the current conditions.

  • Cache should be invalidated when set_conditions() is called.

  • Higher-level objects reuse cached IVs from lower levels, speeding up array simulations.

6. Threading/Parallel Programming for Performance

  • Not exactly sure how fast the IV curve is calculated using newton method, but the more data points we get or times we need to recalculate points we might benefit from parallel computing.

 

MPPT Algorithms:

Should be used after curve is generated

Algorithms:

  • Perturb and Observe

    • condition: stable sunlight, simple

    • idea: nudge v_ref +/- change in V

      • if P went up, keep direction, else flip

  • Incremental Conductance

    • condition: better slope math, simple

    • idea: uses dI/dV about = -I/V at MPP

      • moves voltage based on sign of dP/dV without dithering

  • Hybrid Global Sampling

    • condition: partial shading/multi peaks

    • idea: short bursts of samples across V subset {V_min, V_max} using Sobol/Halton or stratified randomization

      • pick highest P, then hand it off to P&O/IC

  • each algo defines param defaults, update equations, filters/EMA, power-drop triggers, and bounds

Saftey considerations:

  • slew-rate on Vref, min/max Vref bounds, dwell/averaging per sample

Continuous Update Design:

  • small periodic probes, recency-weighted PV map triggers

Evaluation:

  • standardized metrics

    • instant and mean efficiency

      • P/P_max * 100%

    • %time within X% of GMPP

    • settiling time

    • overshoot

    • energy yield

Algorithm Tuner:

  • Should be able to run simulations using the algorithm and tune hyperparameters

  • small gird/random search over stride, dwell, and explore cadence

  • persist results in a timestamped runs/ dir with metrics CSV + plots

 

Hardware Simulator (DC-DC Converter):

  • ideal DC-DC converter that instantly presents commanded V_ref

  • hooks for future non-ideal features

    • efficiency map η(V,I)

    • first order dynamic response (time constant)

    • switching ripple for ripple-correlation control

Frontend:

Tech Stack:

  • ReactJS or TSX

    • Best features for frontend UI

    • Ideal for maintaining

  • PyQt6 + Qt WebEngine + Plotly

    • interactive GUI

    • Qt WebEngine is needed to embed Plotly into a desktop app

      • Plotly Dash for web based version

Design Considerations:

  • Users should be able to create cells, modules, strings, and arrays easily through an interactive UI

  • Users should be able to set cell irradiance and temperature

  • Future aeroshell simulation integration with putting cells on the curvature of the solar car

Flowchart:

High Level:

Frontend setup (irradiance, temperature, array setup, …) → calculate cells → calculate modules → calculate strings → calculate array → return List or object containing all points from graph → plot on graph → export data somewhere to reuse?

Repository Structure:

Power-Generation-Eclipse-SW/

├── README.md # High-level overview, quickstart instructions
├── pyproject.toml / setup.cfg
│ # (optional) for packaging if you want pip install -e .
├── requirements.txt # Python dependencies
├── LICENSE

├── eclipse/ # Python package (all importable modules live here)
│ ├── init.py
│ ││ ├── core/ # Shared simulation logic│ │ ├── cell.py # Single-diode PV cell model