169 lines
5.4 KiB
Python
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()
|
|
|