Télécharger le fichier « slci.py »
from numpy import pi
from numpy import vectorize, linspace
from numpy import arctan, arctan2, cos, exp, log10, sqrt # Indispensable pour vectoriser
import matplotlib.pyplot as plt
def module(re,im):
return sqrt((re)**2+(im)**2)
def argument(re,im):
return arctan2(im,re)
# integrateur
def fti(w,K,asymptote=0):
re, im = 0, w
mod = module(K,0)/module(re,im)
pha = argument(K,0)-argument(re,im)
return mod, 20*log10(mod) ,pha , (180/pi)*pha
fti = vectorize(fti)
# dérivateur
def ftd(w,K,asymptote=0):
re, im = 0, w
mod = module(K,0)*module(re,im)
pha = argument(K,0)+argument(re,im)
return mod, 20*log10(mod) ,pha , (180/pi)*pha
ftd = vectorize(ftd)
# premier ordre
def ftpo(w,K,t,asymptote=0):
if asymptote>0 :
if w<1/t:
mod, _, pha, _ = ftp(w,K)
else:
mod, _, pha, _ = fti(w,K/t)
if asymptote==2 and 0.1/t0:
if w<1/t:
mod, _, pha, _ = ftp(w,K)
else:
mod, _, pha, _ = ftd(w,K*t)
if asymptote==2 and 0.1/t=1
reN, imN = 1, a*T*w
reD, imD = 1, T*w
mod = module(K,0)*module(reN,imN)/module(reD,imD)
pha = argument(reN,imN)-argument(reD,imD)
return mod, 20*log10(mod) ,pha , (180/pi)*pha
# avance de phase
def ftadpD(w,K,b,T):
assert b<=1
return ftadpN(w,K,1/b,b*T)
from scipy.signal import TransferFunction, step
from numpy import delete, insert
# reponse indicelle deuxieme ordre aperiodique
def ripo(t, e0, K, tau, decalage=0, retard=0):
"""
Cette fonction vectorisée permet de donner la réponse indicielle
à l'instant : t
d'une consigne d'amplitude : e0
de décalage : decalage
d'une fonction de transfert du deuxième ordre
de retard : retard
de gain : K
de constante de temps : tau
"""
numerator = [K]
denominator = [tau, 1]
system = TransferFunction(numerator, denominator)
t, reponse = step(system, T=t)
reponse *= e0
i=0
while t[i] < decalage + retard:
reponse = delete(reponse, -1)
reponse = insert(reponse, 0, 0)
i += 1
return reponse
from scipy.signal import TransferFunction, step
from numpy import delete, insert
# reponse indicelle deuxieme ordre aperiodique
def rido(t, e0, K, z, w0, decalage=0, retard=0):
"""
Cette fonction vectorisée permet de donner la réponse indicielle
à l'instant : t
d'une consigne d'amplitude : e0
de décalage : decalage
d'une fonction de transfert du deuxième ordre
de retard : retard
de gain : K
d'amortissement : z
de pulsation propre : w0
"""
numerator = [K * w0**2]
denominator = [1, 2 * z * w0, w0**2]
system = TransferFunction(numerator, denominator)
t, reponse = step(system, T=t)
reponse *= e0
i=0
while t[i] < decalage + retard:
reponse = delete(reponse, -1)
reponse = insert(reponse, 0, 0)
i += 1
return reponse
# DepassementDeuxiemeOrdreAperiodique
def ddoa(e0,K,z,k):
return K*e0*(1-((-1)**k)*dpdoa(z,k))
# DepassementPourcentageDeuxiemeOrdreAperiodique
def dpdoa(z,k):
return exp(-(z*k*pi)/(sqrt(1-z**2)))
# TempsDepassementDeuxiemeOrdreAperiodique
def tddoa(z,w0,k):
return (k*pi)/(w0*sqrt(1-z**2))
def bande(x,K,e0,percent):
x /= K*e0
if x>1-(percent/100) and x<1+(percent/100):
return True
else:
return False
# TempsReponseDeuxiemeOrdre
def trdo(e0,K,z,w0,percent):
if z==1:
tMin = 2*z/w0
tMax = 3*2*z/w0
return trdoRec(e0,K,z,w0,tMin,tMax,percent), 0
elif z>1:
tMin = 2*z/w0
tMax = 3*2*z/w0
return trdoRec(e0,K,z,w0,tMin,tMax,percent), -1
elif z<1:
k = 1
while not bande(ddoa(e0,K,z,k),K,e0,percent): k += 1
tMin = tddoa(z,w0,k-1)
tMax = tddoa(z,w0,k-0)
return trdoRec(e0,K,z,w0,tMin,tMax,percent), k-1
trdoV = vectorize(trdo)
# TempsReponseDeuxiemeOrdreRecursif
def trdoRec(e0,K,z,w0,tMin,tMax,percent):
if tMax-tMin < 10**-4:
return tMax
else:
tMoy = (tMin+tMax)/2
sMoy = rido(tMoy,e0,K,z,w0)
if bande(sMoy,K,e0,percent):
tMax = tMoy
else:
tMin = tMoy
return trdoRec(e0,K,z,w0,tMin,tMax,percent)
def tracedose(e0,K,z,w0,percent,rap=3):
tr,k = trdo(e0,K,z,w0,percent)
abscisse = linspace(0,rap*tr,500)
ordonnee = rido(abscisse,e0,K,z,w0)
plt.figure()
plt.plot(abscisse,ordonnee,'g',label="Réponse")
plt.plot([0,rap*tr],[e0,e0],'r',label="Consigne")
plt.plot([0,rap*tr],[(1+percent/100)*K*e0,(1+percent/100)*K*e0],'-b')
plt.plot([0,rap*tr],[K*e0,K*e0],'--b')
plt.plot([0,rap*tr],[(1-percent/100)*K*e0,(1-percent/100)*K*e0],'-b')
plt.plot([tr,tr],[0,rido(tr,e0,K,z,w0)],'-ob',label="")
if k > 0:
i = 1
ti, di = tddoa(z,w0,i), ddoa(e0,K,z,i)
while ti < rap*tr:
plt.plot([ti,ti],[K*e0,di],'g-o')
i += 1
ti, di = tddoa(z,w0,i), ddoa(e0,K,z,i)
plt.title("Temps de réponse à "+str(percent)+"% : $t_{r"+str(percent)+"\\%} = "+'%.3f'%tr+" s$ \n Nombre de dépassement en régime transitoire : $"+str(k)+"$")
plt.xlabel("Temps en seconde")
plt.ylabel("Amplitude de la consigne et de la réponse")
plt.legend(loc="best")
Télécharger le fichier « slci.py »