s1Eva2009TII_T2 LTI DT bloques, respuesta impulso y paso

Ejercicio: 1Eva2009TII_T2 LTI DT bloques, respuesta impulso y paso

literal a. Respuesta al impulso, o H(s) del diagrama de bloques

a.1 H[z] Función de transferencia

Referencia: LTI DT – H[z] Diagrama de bloques con «1/z»

Dado que hay dos bloques (1/z) o de retraso , se identifica que los polinomios son de segundo orden (N=2). Los coeficientes de retraso se leen de arriba hacia abajo como a0,-a1,-a2 ordenados en la siguiente tabla:

coeficientes
retraso adelanto
a0 = 1 b0 = 1
a1 = -(3/4) = -3/4 b1 = 0
a2 = -(-1/8) = 1/8 b2 = 0

Se aplica lo mismo para los coeficientes de adelanto y se completa el modelo para los polinomios del numerador y denominador:

H[z] = \frac{b_0 z^N +b_1 z^{N-1} + \text{ ... } + b_{N-1} z + b_N}{z^N + a_1 z^{N-1} +\text{ ... } + a_{N-1}z +a_N} H[z] = \frac{z^2}{z^2 - \frac{3}{4} z+\frac{1}{8}}

a.2 H[z] en fracciones parciales

fracciones parciales modificadas,

\frac{H[z]}{z} = \Big( \frac{1}{z} \Big) \frac{z^2}{z^2 - \frac{3}{4} z+\frac{1}{8}} = \frac{z}{z^2 - \frac{3}{4} z+\frac{1}{8}}

El polinomio del denominador es:

Q[z] = z^2 - \frac{3}{4} z+\frac{1}{8}

con raíces en 1/4 y 1/2

con lo que se obtiene la expresión para usar el método de «cubrir» de Heaviside

\frac{H[z]}{z} = \frac{z}{(z-1/4)(z-1/2)}= \frac{k_1}{z-1/4}+ \frac{k_2}{z-1/2} k_1 = \frac{z}{\cancel{(z-1/4)}(z-1/2)}\Big|_{z=1/4} = \frac{1/4}{(1/4-1/2)} = -1 k_2 = \frac{z}{(z-1/4)\cancel{(z-1/2)}}\Big|_{z=1/2} = \frac{1/2}{(1/2-1/4)} = 2 \frac{H[z]}{z} = \frac{-1}{z-1/4}+ \frac{2}{z-1/2}

fracciones parciales

H[z] = \frac{-z}{z-1/4}+ \frac{2z}{z-1/2}

Revisando el resultado con el algoritmo en Python:

 Hz:
          2        
         z         
-------------------
 2                 
z  - 0.75*z + 0.125

 Hz/z:
           z           
-----------------------
     2                 
1.0*z  - 0.75*z + 0.125

 Hz/z.apart:
       1             2.0    
- ------------ + -----------
  1.0*z - 0.25   1.0*z - 0.5

 Hz = (Hz/z)*z
       z            2.0*z   
- ------------ + -----------
  1.0*z - 0.25   1.0*z - 0.5

 polos:     {0.250000000000000: 1, 0.500000000000000: 1}

 polos Re:  [1/4, 1/2]

Se obtiene h[n] usando la tabla de transformadas z

 Hz = (Hz/z)*z
       z            2.0*z   
- ------------ + -----------
  1.0*z - 0.25   1.0*z - 0.5
h[n] = - \Big(\frac{1}{4}\Big)^n \mu[n]+2\Big( \frac{1}{2} \Big)^n \mu[n]

a.3. Estabilidad del sistema

Los polos son menores que un radio de 1.
La ROC para el primer polo |z|>1/4 y para el segundo polo es |z|>1/2

Observaciones:

Las raíces características o frecuencias naturales del sistema se encuentran dentro del círculo de radio unitario. El sistema es asintóticamente estable, que implica que es BIBO estable.

h[n] no es de la forma k δ[n], por lo que el sistema global es con memoria.

a.4 Instrucciones con Python

Usando los algoritmo de la sección LTID Transformada z – X[z] Fracciones parciales modificadas con Python se adapta para el ejercicio

# Transformada z- Fracciones parciales
# Polos únicos, repetidos y complejos
# Lathi Ejercicio 5.3c pd495
# blog.espol.edu.ec/telg1001
import sympy as sym
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
z = sym.Symbol('z')

Pz = z**2
Qz = z**2-(3/4)*z+1/8

# PROCEDIMIENTO
P = Pz.as_poly(z)
Q = Qz.as_poly(z)
Xz = Pz/Qz

# Raices Denominador
Q_raiz = sym.roots(Q)
Q_raizRe = sym.real_roots(Q)
rcompleja = len(Q_raiz)-len(Q_raizRe)

# Raices reales, únicas y repetidas
if (rcompleja<=0 and len(Q_raizRe)>0):
    # fracciones parciales modificadas
    Xzz = (P/Q)/z
    Xzm = Xzz.apart()
    # fracciones parciales restaurada
    terminos = Xzm.args
    Xzp = 0*z
    for untermino in terminos:
        Xzp = Xzp + untermino*z

def parametro_cuadratico(untermino):
    unparametro ={}
    # revisa denominador cuadratico
    [numerador,denominador] = (untermino).as_numer_denom()
    gradoD = 0
    coeficientesD = denominador
    gradoN = 0
    coeficientesN = numerador
    if not(denominador.is_constant()):
        denominador = denominador.as_poly()
        gradoD = denominador.degree()
        coeficientesD = denominador.coeffs()
    if not(numerador.is_constant()):
        numerador = numerador.as_poly()
        gradoN = numerador.degree()
        coeficientesN = numerador.coeffs()
    if gradoD == 2 and gradoN==2:
        a = float(coeficientesD[1])/2
        gamma2 = float(coeficientesD[2])
        gamma = np.sqrt(gamma2)
        A = float(coeficientesN[0])
        B = float(coeficientesN[1])
        rN = (A**2)*gamma2 + B**2 - 2*A*a*B
        rD = gamma2 - a**2
        r = np.sqrt(rN/rD)
        beta = np.arccos(-a/gamma)
        thetaN = A*a-B
        thetaD = A*np.sqrt(gamma2-a**2)
        theta = np.arctan(thetaN/thetaD)
        unparametro = {'r':r,
                       'gamma':gamma,
                       'beta':beta,
                       'theta':theta}
    return (unparametro)

# Terminos cuadraticos
parametros = [] # denominador cuadratico
if (rcompleja>0 and len(Q_raizRe)>0):
    # fracciones parciales modificadas
    Xzz = (P/Q)/z
    Xzm = Xzz.apart()
    # fracciones parciales restaurada
    terminos = Xzm.args
    Xzp = 0*z
    for untermino in terminos:
        Xzp = Xzp + untermino*z
        unparam = parametro_cuadratico(untermino*z)
        if len(unparam)>0:
            parametros.append(unparam)
if (rcompleja>0 and len(Q_raizRe)==0):
    Xzp = P/Q
    parametros.append(parametro_cuadratico(P/Q))

# SALIDA
print('\n Hz:')
sym.pprint(Xz)
if (len(Q_raizRe)>0):
    print('\n Hz/z:')
    sym.pprint(Xzz)
    print('\n Hz/z.apart:')
    sym.pprint(Xzm)
    print('\n Hz = (Hz/z)*z')
    sym.pprint(Xzp)
    print('\n polos:    ', Q_raiz)
print('\n polos Re: ', Q_raizRe)
if len(parametros)>0:
    for unparam in parametros:
        print('parametros cuadraticos: ')
        for cadauno in unparam.keys():
            print(cadauno,'\t',unparam[cadauno])


# grafica plano z imaginario
figura, grafROC = plt.subplots()
# limite
radio1 = plt.Circle((0,0),1,color='lightgreen',
                    fill=True)
radio2 = plt.Circle((0,0),1,linestyle='dashed',
                    color='lightgreen',fill=False)
grafROC.add_patch(radio1)
for raiz in Q_raiz.keys():
    [r_real,r_imag] = raiz.as_real_imag()
    radio_raiz = np.abs(raiz)
    nROC = plt.Circle((0,0),radio_raiz,
                      color='red',fill=True)
    grafROC.add_patch(nROC)
grafROC.add_patch(radio2) # borde r=1
grafROC.axis('equal')
# marcas de r=1 y valor a
for raiz in Q_raiz.keys():
    [r_real,r_imag] = raiz.as_real_imag()
    grafROC.plot(r_real,r_imag,'o',color='orange',
             label ='polo:'+str(float(raiz))+';'+str(Q_raiz[raiz]))
grafROC.plot(1,0,'o',color='green',
         label ='radio:'+str(1))

plt.axhline(0,color='grey')
plt.axvline(0,color='grey')
plt.grid()
plt.legend()
plt.xlabel('Re[z]')
plt.ylabel('Imag[z]')
untitulo = 'ROC H[z]='+str(Xz)
plt.title(untitulo)

# h[n] usando tabla de transformadas
m = 10
n = sym.Symbol('n')
hn = 0.5833*((0.7)**n)*sym.Heaviside(n)+0.4166*((-0.5)**n)*sym.Heaviside(n)
fn = sym.lambdify(n,hn)
ki = np.arange(0,m,1)
xnk = fn(ki)

# grafica h[n]
figura, grafxn = plt.subplots()
plt.stem(ki,xnk)
plt.xlabel('ki')
plt.ylabel('h[n]')
plt.title('h[n]= '+str(hn))
plt.show()

literal b. La respuesta de paso s[n]

La señal de entrada será x[n] = μ[n], con transformada z de:

X[z] = \frac{z}{z-1}

b.1 Y[z] ante entrada X[z] y con función de transferencia H[z]

Usando el resultado de la respuesta al impulso,

H[z] = \frac{-z}{z-1/4}+ \frac{2z}{z-1/2}

La salida Y[n] del sistema será:

Y[z] = X[z] H[z] = \frac{z}{z-1} \Bigg[ \frac{-z}{z-1/4} + \frac{2z}{z-1/2} \Bigg]

b.2 Y[z] en fracciones parciales

Fracciones parciales modificadas

\frac{Y[z]}{z} = \frac{1}{z-1} \Bigg[ \frac{-z}{z-1/4} + \frac{2z}{z-1/2} \Bigg] \frac{Y[z]}{z} = \frac{1}{(z-1)} \frac{-z}{z-1/4} + \frac{1}{(z-1)}\frac{2z}{z-1/2}

La expresión se puede operar por partes:

\frac{-z}{(z-1)(z-1/4)} = \frac{k_1}{z-1} + \frac{k_2}{z-1/4} k_1 = \frac{-z}{\cancel{(z-1)}(z-1/4)} \Big|_{z=1} = \frac{-1}{(1-1/4)}=-\frac{4}{3} k_2 = \frac{-z}{(z-1)\cancel{(z-1/4)}} \Big|_{z=1/4} = \frac{-1/4}{(1/4-1)} = \frac{1}{3}

y la segunda parte,

\frac{2z}{(z-1)(z-1/2)} = \frac{k_3}{z-1} + \frac{k_4}{z-1/2} k_3 = \frac{2z}{\cancel{(z-1)}(z-1/2)} \Big|_{z=1} = \frac{2(1)}{1-1/2} = 4 k_4 = \frac{2z}{(z-1)\cancel{(z-1/2)}} \Big|_{z=1/2} = \frac{2(1/2)}{1/2-1} = -2

Uniendo las partes de fracciones parciales modificadas se tiene:

\frac{Y[z]}{z} = \frac{-4/3}{z-1} + \frac{1/3}{z-1/4} + \frac{4}{z-1}+\frac{-2}{z-1/2}

restaurando las fraciones parciales

Y[z] = \frac{8}{3}\frac{z}{z-1} + \frac{1}{3}\frac{z}{z-1/4} -2\frac{z}{z-1/2}

Usando la tabla de transformadas z

y[n] = \frac{8}{3}\mu [n] + \frac{1}{3}\Big( \frac{1}{4}\Big)^n \mu [n] -2 \Big(\frac{1}{2}\Big) ^n \mu[n]

Usando el algoritmo en Python, se tiene:

 Yz:
              3             
             z              
----------------------------
(z - 1)*(z - 0.5)*(z - 0.25)

 Yz/z:
                 2                
                z                 
----------------------------------
     3         2                  
1.0*z  - 1.75*z  + 0.875*z - 0.125

 Yz/z.apart:
0.333333333333333       2.0       2.66666666666667
----------------- - ----------- + ----------------
   1.0*z - 0.25     1.0*z - 0.5        z - 1      

 Yz = (Yz/z)*z
0.333333333333333*z      2.0*z      2.66666666666667*z
------------------- - ----------- + ------------------
    1.0*z - 0.25      1.0*z - 0.5         z - 1       

 polos:  {0.2500: 1, 0.5000: 1, 1.0000: 1}

gráfica de salida y[n]

s1Eva2009TII_T1 LTI CT diagrama canónico y respuesta a impulso

Ejercicio1Eva2009TII_T1 LTI CT diagrama canónico y respuesta a impulso

a. A partir del diagrama canónico se puede reordenar, identificando las partes del numerador P(s) y denominador Q(s) para escribir la función de transferencia;

reordenando diagrama:

escribiendo la ecuación como:

H(s) = \Big[ \frac{1}{s^2+3s+2}\Big]\Big[ 3s+2\Big] e^{-3s} H(s) = \Big[ \frac{3s+2}{s^2+3s+2}\Big] e^{-3s}

Se usan los polos de la expresión para el denominador Q, para realizar las fracciones parciales:

 {polos,veces}:  {-1: 1, -2: 1}
H(s) = \Big[ \frac{3s+2}{(s+2)(s+1)} \Big] e^{-3s}

Al enfocarse en H(s) sin usar el retraso e-3s se tiene H1(s)

H_1(s) = \frac{3s+2}{(s+2)(s+1)}

y se usa el método de «cubrir» de Heaviside para encontrar las constantes,

k_1 = \frac{3s+2}{\cancel{(s+2)}(s+1)} \Big|_{s=-2} = \frac{3(-2)+2}{(-2+1)}=4 k_2 = \frac{3s+2}{(s+2)\cancel{(s+1)}} \Big|_{s=-1} = \frac{3(-1)+2}{(-1+2)} = -1

reemplazando las constantes en H1(s) o mejor en H(s) se obtiene expresiones mas simples en fracciones parciales.

H(s) = \Big[ \frac{4}{s+2}- \frac{1}{s+1}\Big] e^{-3s} H(s) = e^{-3s} \frac{4}{s+2} - e^{-3s}\frac{1}{s+1}

b. Usar la tabla de transformadas de Laplace, y la propiedad de desplazamiento en t

h(t) = 4e^{-2(t-3)}\mu(t-3)- e^{-(t-3)}\mu(t-3)

Tarea: usar la forma analítica para encontrar la respuesta.

la gráfica de respuesta del sistema ht(t) y la salida y(t) del sistema ante una entrada impulso, serán iguales:

s1Eva2009TII_T1 xh_y

c. ¿Qué puede decir acerca de la estabilidad interna y externa?

Los polos se encuentran en el lado izquierdo del plano, sus componentes son exponenciales decrecientes. Por lo que se considera asintóticamente estable, tambien es acotado o BIBO estable.

Estabilidad de H(s):
 n_polos_real : 2
 n_polos_imag : 0
 enRHP : 0
 unicos : 0
 repetidos : 0
 asintota : estable

s1Eva2009TII_T1_polosrevisando el resultado de los polos en conjunto con H(s)

s1Eva2009TII_T1_polos_ht

Resultados con el algoritmo:

 H(s) = P(s)/Q(s):
/  4       1  \  -3*s
|----- - -----|*e    
\s + 2   s + 1/      
 H(s) en factores:
           -3*s
(3*s + 2)*e    
---------------
(s + 1)*(s + 2)

 h(t) :
/   3  -t      6  -2*t\                 
\- e *e   + 4*e *e    /*Heaviside(t - 3)

polosceros:
exp(-3*s) : {'Q_polos': {-1: 1, -2: 1}, 
             'P_ceros': {-2/3: 1}}
Q_polos : {-1: 1, -2: 1}
P_ceros : {-2/3: 1}

Estabilidad de H(s):
 n_polos_real : 2
 n_polos_imag : 0
 enRHP : 0
 unicos : 0
 repetidos : 0
 asintota : estable

 X(s): 
1

Respuesta entrada cero ZIR H(s) y condiciones iniciales
term_cero : 0
ZIR :
0
yt_ZIR :
0

 ZSR respuesta estado cero:
ZSR :
/  4       1  \  -3*s
|----- - -----|*e    
\s + 2   s + 1/      
yt_ZSR :
/   3  -t      6  -2*t\                 
\- e *e   + 4*e *e    /*Heaviside(t - 3)

 Y(s)_total = ZIR + ZSR:
/  4       1  \  -3*s
|----- - -----|*e    
\s + 2   s + 1/      

 y(t)_total = ZIR + ZSR:
/   3  -t      6  -2*t\                 
\- e *e   + 4*e *e    /*Heaviside(t - 3)

Instrucciones en Python

Para resolver el ejercicio, se define la funcion H(s) por los polinomios P y Q, la entrada se define como un impulso δ(t).

Usando los bloques desarrollados en la Unidad 4 Sistemas LTI – Laplace  y las funciones resumidas como telg1001.py que pueden ser usados en cada pregunta.

# Y(s) Respuesta total con entada cero y estado cero
# Qs Y(s) = Ps X(s) ; H(s)=Ps/Qs
# https://blog.espol.edu.ec/telg1001/
import sympy as sym
import matplotlib.pyplot as plt
import telg1001 as fcnm

# INGRESO
s = sym.Symbol('s')
t = sym.Symbol('t', real=True)
d = sym.DiracDelta(t)
u = sym.Heaviside(t)

# H(s) y estabilidad
Hs = (3*s+2)/(s**2+3*s+2) * sym.exp(-3*s)
#Hs = 2*(s+5)/((s+4)*(s+3)) * sym.exp(-3*s)

# X(s) Señal de entrada
xt = d #+ d.subs(t,t-2)

# condiciones iniciales, [y'(0),y(0)] orden descendente
t0 = 0
cond_inicio = [0, 0] # estado cero no se usan

# Grafica, intervalo tiempo [t_a,t_b]
t_a = 0 ; t_b = 10
muestras = 101  # 51 resolucion grafica

# PROCEDIMIENTO
Hs = fcnm.apart_s(Hs) # fracciones parciales
Hs_fc = fcnm.factor_exp(Hs) # en factores
Hs_Qs2 = fcnm.Q_cuad_s_parametros(Hs_fc)

polosceros = fcnm.busca_polosceros(Hs)
Q_polos = polosceros['Q_polos']
P_ceros = polosceros['P_ceros']

estable = fcnm.estabilidad_asintotica_s(Q_polos)

# H(t) respuesta al impulso
ht = 0*s
term_suma = sym.Add.make_args(Hs)
for term_k in term_suma:
    ht_k = sym.inverse_laplace_transform(term_k,s,t)
    # simplifica log(exp()) ej: e**(-2s)/(s**2)
    if ht_k.has(sym.log):
        ht_k = sym.simplify(ht_k,inverse=True)
    ht  = ht + ht_k
lista_escalon = ht.atoms(sym.Heaviside)
ht = sym.expand(ht,t) # terminos suma
ht = sym.collect(ht,lista_escalon)

# PROCEDIMIENTO Respuesta ZIR, ZSR
Xs = fcnm.laplace_transform_suma(xt)

# ZIR_s respuesta entrada cero de s
sol_ZIR = fcnm.respuesta_ZIR_s(Hs,cond_inicio)
ZIR = sol_ZIR['ZIR']
yt_ZIR = sol_ZIR['yt_ZIR']

# ZSR respuesta estado cero, Y(s) a entrada X(s)
sol_ZSR = fcnm.respuesta_ZSR_s(Hs,Xs)
ZSR = sol_ZSR['ZSR']
yt_ZSR = sol_ZSR['yt_ZSR']

# Respuesta total Y(s) y y(t)
Ys = ZIR + ZSR
Ys = fcnm.apart_s(Ys)
yt = yt_ZIR + yt_ZSR
lista_escalon = yt.atoms(sym.Heaviside)
yt = sym.collect(yt,lista_escalon)

# SALIDA
print(' H(s) = P(s)/Q(s):')
sym.pprint(Hs)
print(' H(s) en factores:')
sym.pprint(Hs_fc)
if len(Hs_Qs2)>0:
    print('\nH(s) parámetros cuadraticos:')
    fcnm.print_resultado_dict(Hs_Qs2)

print('\n h(t) :')
sym.pprint(ht)

print('\npolosceros:')
fcnm.print_resultado_dict(polosceros)

print('\nEstabilidad de H(s):')
for k in estable:
    print('',k,':',estable[k])

print('\n X(s): ')
sym.pprint(Xs)
print('\nRespuesta entrada cero ZIR H(s) y condiciones iniciales')

if not(sol_ZIR == sym.nan): # existe resultado
    fcnm.print_resultado_dict(sol_ZIR)
else:
    print(' insuficientes condiciones iniciales')
    print(' revisar los valores de cond_inicio[]')

print('\n ZSR respuesta estado cero:')
fcnm.print_resultado_dict(sol_ZSR)

print('\n Y(s)_total = ZIR + ZSR:')
sym.pprint(Ys)
print('\n y(t)_total = ZIR + ZSR:')
sym.pprint(yt)

# Graficas polos, H(s), con polos h(t) --------
muestras_H = 101
figura_s  = fcnm.graficar_Fs(Hs_fc,Q_polos,P_ceros,f_nombre='H',solopolos=True)
figura_Hs = fcnm.graficar_Fs(Hs_fc,Q_polos,P_ceros,muestras=muestras_H,f_nombre='H')
figura_ht = fcnm.graficar_ft(ht,t_a,t_b,muestras,f_nombre='h')
# GRAFICAS y(t),x(t),h(t) ---------------------
figura_ft = fcnm.graficar_xh_y(xt,ht,yt,t_a,t_b,muestras)
plt.show()

Referencia: LTI CT Laplace – H(s) Estabilidad del sistema con Python
Ejemplo 3, LTI CT Laplace – H(s) Diagramas de bloques y ecuaciones diferenciales

Ejemplos – soluciones propuestas

Ejercicios resueltos mostrando el desarrollo analítico y validados con los algoritmos en Python realizados en clase. Contienen tareas por desarrollar, observaciones a otras formas de algoritmos.