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 »