source/src/funcionesSimELectrica.py
Oscar Suescun Elizalde 04076e9292 as
2025-05-27 10:19:17 +02:00

169 lines
5.4 KiB
Python

from PyLTSpice import SimRunner, SpiceEditor, RawRead
import numpy as np
import matplotlib.pyplot as plt
'''
Este codigo funciona sobre modelo.net
Para conseguir este archivo hay que ir al .asc con
el mismo nombre y ir View > SPICE Netlist. Esto
mostrara el codigo que se quiere. Se copia el codigo
y se pega en un file con extenion .net
'''
__author__ = 'Oscar Suescun'
def solver_manual(tensionCap, Rtotal, Lbobina, Ctotal, t):
'''
Solver analitico de la descarga LCR, resuelto manualmente.
Se esta resuelto con el metodo para ecuaciones diferenciales
homogeneas de segundo orden con coeficientes constantes.
Para evitar que el sistema tenga un periodo oscilatorio se necesita
cumplir que R^2 >= 4 * L/C. Si esto no se cumple tendra un perido
de oscilacion antes de apagarse lo que puede generar fuerzas negativas
en el vastago.
Entradas:
- tensionCap -> Tension del capacitor
- Rtotal -> Resistencia total en el circuito (Rextra + Rbobina)
- Lbobina -> Inductancia de la bobina
- Ctotal -> capacidad del banco de capacitores
Salida:
- Corriente en la bobina
'''
if Rtotal**2 - 4*Lbobina/Ctotal >= 0:
tau1 = (-Rtotal + np.sqrt(Rtotal**2 - 4*Lbobina/Ctotal)) / (2 * Lbobina)
tau2 = (-Rtotal - np.sqrt(Rtotal**2 - 4*Lbobina/Ctotal)) / (2 * Lbobina)
iCap = tensionCap/(Lbobina*(tau1 - tau2)) * (np.exp(tau1 * t) - np.exp(tau2 * t))
else:
a = -Rtotal / (2*Lbobina)
b = np.sqrt(4*Lbobina/Ctotal - Rtotal**2) / (2*Lbobina)
iCap = np.exp(a*t) * tensionCap / (b * Lbobina) * np.sin(b*t)
return iCap
def simular_LTS(tensionCap, Rtotal, Lbobina, Ctotal, lts_path, tSim = 100e-3, toff_sw = 1e-3, ton_mos = 1.5e-3):
'''
Funcion principal de simulacion. Es legado por si se quisiera simular
con LTSpice. No se usa porque hay problemas con el tamaño del step
en los resultados.
Entradas Obligatorias:
- tensionCap -> Tension del capacitor
- Rtotal -> Resistencia total en el circuito (Rextra + Rbobina)
- Lbobina -> Inductancia de la bobina
- Ctotal -> capacidad del banco de capacitores
- lts_path -> directorio donde tienes el .exe de LTSpice
Entradas Opcionales:
- tSim -> tiempo total de simulacion (de normal 100ms)
- toff_sw -> tiempo que tarda la fuente en
desconectarse del capacitor (de normal 1ms)
- ton_mos -> tiempo que tarda el mosfet en abrir el gate
del mosfet de disparo (de normal 1.5ms)
Salida
resultados = {
'tiempo' : vector con el tiempo de simulacion
'vCap' : Vector con la tension entre Capacitor -> GND
'vBob' : Vector de tension atraves de la bobina
'iBob' : Vector con la corriente atraves de Bobina
}
'''
modeloSim = "src/simulador/modelo_transitorio.asc"
outDir = 'src/simulador'
## Hago la simulacion
simulador = SimRunner(output_folder=outDir, simulator=lts_path)
simulador.create_netlist(modeloSim)
netlist = SpiceEditor(modeloSim.replace('.asc', '.net'))
netlist.set_parameters(V = tensionCap,
R = Rtotal,
L = Lbobina,
C = Ctotal,
tSim = tSim,
toff_sw = toff_sw,
ton_mos = ton_mos)
simulador.run(netlist)
raw_path, log_path = next(iter(simulador)) # Obtener el único resultado
raw = RawRead(raw_path)
tiempo = np.array(raw.get_trace('time'))
vCap = np.array(raw.get_trace(('V(condensador)')))
vBob = np.array(raw.get_trace('V(v1)')) - np.array(raw.get_trace('V(v2)'))
iBob = np.array(raw.get_trace('I(L1)'))
iMos = np.array(raw.get_trace('Id(M1)'))
idx = np.where(tiempo >= ton_mos)
try:
return {
'tiempo': tiempo[idx],
'vCap': vCap[idx],
'vBob': vBob[idx],
'iBob': iBob[idx],
'iMos' : iMos[idx]
}
except KeyError as e:
print(f'Error al leer señal del archivo .raw: {e}')
return None
def dibujar(resultado):
plt.figure()
plt.plot(resultado['tiempo']*1e3, resultado['vCap'], label='Tension Cap [V]')
plt.plot(resultado['tiempo']*1e3, resultado['vBob'], label='Tension Bobina [V]')
plt.plot(resultado['tiempo']*1e3, resultado['iBob'], label='Corriente Bobina [A]')
plt.xlabel("Tiempo [ms]")
plt.grid()
plt.legend()
plt.show()
if __name__ == '__main__':
lts_path = "C:/Users/osuescuneli/AppData/Local/Programs/ADI/LTspice/LTspice.exe"
Tension = 30
Resistencia = 10
Inductancia = 1
Capacitancia = 0.02
tiempoSimulacion = 10
tiempoSwitch = 25e-6
tiempoMos = 50e-6
resultado1 = simular_LTS(Tension,
Resistencia,
Inductancia,
Capacitancia,
lts_path,
tSim = tiempoSimulacion,
toff_sw = tiempoSwitch,
ton_mos = tiempoMos)
t = np.arange(0,tiempoSimulacion, 10e-6)
resultado2 = solver_manual(Tension, Resistencia, Inductancia, Capacitancia, t )
plt.figure()
plt.plot(resultado1['tiempo']*1e3, resultado1['iBob'], label = 'LTS')
plt.plot(t*1e3, resultado2, label='Manual')
plt.legend()
plt.show()