summaryrefslogtreecommitdiff
path: root/MIL_testing
diff options
context:
space:
mode:
authorTanner Robison <[email protected]>2026-07-07 20:48:28 -0700
committerYour Name <[email protected]>2026-07-10 19:51:37 +0000
commit4f36a1654ff6560c915a39e1f9999e0efc4a9680 (patch)
tree984b234215ee1972a396d1491e5dc3fd07da5d4c /MIL_testing
parente2b30976cdaccf9d2b9820fefa22ced03c82711f (diff)
SPICE model in the loop testing
Diffstat (limited to 'MIL_testing')
-rw-r--r--MIL_testing/integration_test.py14
-rw-r--r--MIL_testing/ng_test1.cir25
-rw-r--r--MIL_testing/spice_backend.py70
3 files changed, 109 insertions, 0 deletions
diff --git a/MIL_testing/integration_test.py b/MIL_testing/integration_test.py
new file mode 100644
index 0000000..7c8e2fa
--- /dev/null
+++ b/MIL_testing/integration_test.py
@@ -0,0 +1,14 @@
+import subprocess
+
+result = subprocess.run(
+ ["ngspice", "-b", "ng_test1.cir"],
+ capture_output=True,
+ text=True
+)
+
+print("Return code:", result.returncode)
+print(result.stdout)
+
+if result.stderr:
+ print("Errors:")
+ print(result.stderr)
diff --git a/MIL_testing/ng_test1.cir b/MIL_testing/ng_test1.cir
new file mode 100644
index 0000000..892a284
--- /dev/null
+++ b/MIL_testing/ng_test1.cir
@@ -0,0 +1,25 @@
+* RC Charging Circuit
+
+V1 in 0 PULSE(0 5 1u 1u 1u 100m 200m)
+
+R1 in out 1k
+
+C1 out 0 1u
+
+.tran 10u 50m
+
+.control
+run
+
+set finalindex = $&{length(v(in)) - 1}
+
+let final_vin = v(in)[$finalindex]
+let final_vout = v(out)[$finalindex]
+let final_current = v1#branch[$finalindex]
+
+echo "----- final time analysis -----"
+print final_vin final_vout
+print final_current
+
+.endc
+.end
diff --git a/MIL_testing/spice_backend.py b/MIL_testing/spice_backend.py
new file mode 100644
index 0000000..674ae30
--- /dev/null
+++ b/MIL_testing/spice_backend.py
@@ -0,0 +1,70 @@
+import subprocess
+import re
+
+class SpiceBackend:
+ """This is what actually does all of the spice stuff"""
+ def __init__(self, device_file: str):
+ self.conductance = 0
+ self.voltage = 0
+ self.current = 0
+ self.time = 0
+
+ def simulate(self, voltage_signal: float, return_current: bool = False) -> float:
+ """runs the simulation for one time step"""
+ len_voltage_signal = 1
+ try:
+ len_voltage_signal = len(voltage_signal)
+ except:
+ voltage_signal = [voltage_signal]
+
+ if return_current:
+ current = np.zeros(len_voltage_signal)
+
+ for t in enumerate(len_voltage_signal):
+ result = self.run_spice(voltage_signal)
+
+ single_current = result.current
+ self.conductance = result.conductance
+
+ if return_current:
+ current[t] = single_current
+
+ if return_current:
+ return current
+
+
+ def set_conductance(self, conductance: float):
+ """Handled by spice now"""
+ """Could probably still add some safety checks just to be sure later"""
+ self.conductance = conductance
+
+ def run_spice(self, voltage: float) -> float:
+ """returns the current after given a voltage signal"""
+ #need to find a way to pass voltage signal to ngspice here
+ #also maybe a time series resolution??
+ result = subprocess.run(
+ ["ngspice" "-b" "spicefile.cir"],
+ capture_output=True,
+ text=True
+ )
+ if result.returncode != 0:
+ raise RuntimeError(result.stderr)
+
+ # parse current into float variable
+ output = result.stdout
+ #is there a better (less rigid) way of grabbing the output
+ current_match = re.search("final_current = ([-\deE.+]+)", output)
+ if current_match is None:
+ raise RuntimeError("Could not find current in ngspice output")
+
+ current = float(current_match.group(1))
+
+ if abs(voltage) > 1e-12:
+ conductance = current / voltage
+ else:
+ conductance = self.conductance
+
+ return {
+ "current": current,
+ "conductance": conductance,
+ }