You are on page 1of 15

© 2010 Jorge Rodríguez Araújo

El regulador 20 de diciembre

PID 2010

Introducción al regulador PID, Estudio del


su implementación, sintonización y simulación.
PID

1.1 Introducción
Cuando se regula un proceso se busca generar una señal de control (CO, Controller Output)
que lleve, a la variable de medida del proceso (PV, Process Variable), a alcanzar un determinado valor
de referencia (SP, Set Point).

Para ello se implementa lo que se llama un lazo de control cerrado, donde la actuación sobre la
planta se realiza por medio de un controlador que actúa según el valor de referencia y la medida del
proceso.
En este caso, se trata de un controlador Proporcional-Integral-Derivativo (PID), donde la
actuación depende de la selección de sus parámetros (sintonización del controlador), siendo: P
proporcional al error instantáneo, I proporcional al error acumulado y D proporcional a la velocidad
del error.

1.1.1 El PID ideal


El PID es un tipo de controlador, de elevada implantación industrial, cuyo objetivo es generar
una señal de control ( u t ) que busca anular el error de control ( e t=r t – y t ), o de
seguimiento, según el valor de referencia ( r t ) establecido y la variable de proceso ( y t )
medida.
Para ello, el PID (Proportional Integral Derivative) combina tres acciones básicas de control: la
proporcional (P), que actúa según la magnitud del error, la integral (I), que anula el error de
seguimiento, y la derivativa (D), que reduce el tiempo de establecimiento del sistema. Siendo su

<grrodi@gmail.com> 1
© 2010 Jorge Rodríguez Araújo

expresión en el dominio de la frecuencia:


U  s=K c 1
1
T i⋅s 
T d⋅s ⋅E s 
Ecuación frecuencial del PID ideal

Ecuación en la que la salida y el comportamiento del controlador quedan establecidos por


medio del valor de los tres parámetros de control asociados a cada uno de los términos: ganancia del
controlador ( K c ), constante de tiempo integral ( T i ) y constante de tiempo derivativa ( T d ).

– La acción de control P depende del error en cada momento, actuando de forma inmediata y
proporcional ante su aparición. Con lo que consigue reducir el error de seguimiento, aunque
nunca anularlo, dado que según este disminuye, también lo hace su acción. Por tanto, es más
eficaz cuanto mayor es la ganancia ( K c ), aunque sin descuidar que valores excesivos
pueden producir respuestas sobreoscilatorias o incluso inestables.
u t= K c⋅e t 
– La acción de control I depende del histórico, o suma acumulada, del error, con lo que permite
obtener errores estacionarios nulos. Dado que por muy pequeño que este sea, su suma crece
con el tiempo, haciendo crecer la influencia del término integral, que actuará mientras exista
error de control. Sin embargo, al basarse en el histórico del error, su actuación conlleva un
cierto retraso que origina dinámicas lentas, más oscilatorias o incluso inestabilidad. Así,
mejora el amortiguamiento y reduce la sobreoscilación, pero empeora el transitorio,
aumentando el tiempo de establecimiento y disminuyendo el ancho de banda del sistema.

Kc t
u t= ∫ e t  dt
Ti 0

– La acción de control D depende de la velocidad de cambio del error en cada momento, con lo
que presenta un carácter anticipativo que acelera la reacción ante un cambio del error,
mejorando el amortiguamiento y disminuyendo el tiempo de establecimiento y la
sobreoscilación, en general, mejorando el comportamiento del sistema.
d e t
u t= K c⋅T d
dt
Finalmente, cada una de estas tres acciones contribuye a la generación de la salida de control,
de tal modo que la expresión temporal del PID, en su forma ideal, viene dada por:
t
d e t
ut =K p e t K i∫ e tdt K d
0 dt
Ecuación temporal del PID ideal

Así, para conseguir que la respuesta del sistema se ajuste a unos determinados requerimientos,
se debe proceder al ajuste de los parámetros del regulador.
Hay que tener presente que, en la mayoría de los casos, bastará con lograr la eliminación del

<grrodi@gmail.com> 2
© 2010 Jorge Rodríguez Araújo

error mediante le ajuste del PI. Sin embargo, en aquellos donde los retardos son considerables, como
en la regulación de temperatura, se hace necesario el ajuste del PID para, por medio de la acción
derivativa, lograr una acción anticipativa que produzca una corrección significativa antes de que el
error se haga excesivo (extrapolación), añadiendo amortiguamiento y permitiendo una mayor ganancia
proporcional.
Aunque pudiera parecer resuelto el problema del diseño del PID, existen una serie de
limitaciones y problemas prácticos que dificultan su diseño y sintonización, y que llevan a que existan
diferentes formas, o variaciones, del algoritmo PID.

1.1.2 Problemas prácticos del PID ideal


Existen dos problemas fundamentales en la implementación práctica del PID ideal: la
saturación del término integral y el impulso derivativo.
El primero, conocido como “windup”, se debe al crecimiento del término integral fuera del
rango de control por causa de un error que perdura en el tiempo. Corriéndose el riesgo de que el
sumatorio del error provoque la saturación del término integral, provocando variaciones bruscas de la
salida de control y aumentando el tiempo de establecimiento.

El segundo, conocido como “derivative kick”, se debe a que cuando el error cambia de forma
brusca, debido a un nuevo establecimiento de consigna, su derivada se hace muy grande, tendiendo
teóricamente a infinito, lo que provoca que la acción derivativa genere un pulso instantáneo de valor
muy elevado, que resulta del todo indeseable.
Como se puede ver en la gráfica de la [Figura 3], cuando se utiliza la forma ideal del PID, un

<grrodi@gmail.com> 3
© 2010 Jorge Rodríguez Araújo

cambio de valor de consigna provoca que se produzca en ese instante un impulso derivativo. Y
aunque, como en este caso, el impulso derivativo sólo sea por un instante y no afecte al
comportamiento del sistema, no se debe asumir que esto siempre será así, dado que en algún
momento, de forma eventual, podrá llevar fuera de control a determinados elementos del sistema.

1.2 Algoritmos del PID


Para la implementación del regulador PID digital hay que proceder a la discretización de su
ecuación temporal por medio de su aproximación en diferencias. Debido a esto, existen diferentes
aproximaciones para el PID ideal, aunque aquí se considera una de las más típicas, donde:
e [k ]=r [k ]− y [k−1]
k
u [k ]=K p⋅e [k ]K i⋅∑ e [i ]K d⋅ e [k ]−e[ k−1] 
i=0

[Ecuación en diferencias del PID ideal]


Esta ecuación se define en términos de paso ( k ), dado que el tiempo queda definido a
través del establecimiento del período de muestreo ( T s ), cuya selección, basada en reglas
empíricas, resulta clave en la regulación del proceso. Siendo lo normal, escogerlo en función de la
constante de tiempo (  ), de tal modo que:

T s
10
Una vez establecido el período de muestreo, el ajuste o sintonización del PID consiste en la

<grrodi@gmail.com> 4
© 2010 Jorge Rodríguez Araújo

determinación de las constantes proporcional ( K p ), integral ( K i ) y derivativa ( K d ) que


controlan su comportamiento, de tal modo que permiten obtener una determinada respuesta temporal
de la planta.
Ts Td
K p= K ; K i=K ; K d =K
Ti Ts
Pero, como ya se ha comentado, existen dos problemas en la implementación directa del PID
ideal: la saturación del término integral y la generación del impulso derivativo.
Para solucionar el problema de la saturación del término integral se recurre a su limitación
dentro del rango de control del actuador, con lo que se evita que la respuesta esperada del sistema
degenere debido a la saturación del control.

Para solucionar el problema del impulso derivativo, como se puede ver en la [Figura 4], se
sustituye la derivada del error por la derivada de la medida, pues después de establecido el valor de
referencia, la derivada será igual a menos la derivada de la variable de proceso, por ser la referencia
constante y su derivada igual a cero. Dado que mientras que cuando se establece un nuevo valor de
consigna, el error experimenta un cambio instantáneo que provoca que se produzca un impulso
derivativo, la medida no experimenta estas variaciones instantáneas debidas a un cambio de consigna,
eliminándose por tanto el impulso derivativo.
t
de t  d r – y t  −dy t  d y t 
= = => ut =K p e t K i∫ e tdt −K d
dt dt dt 0 dt

<grrodi@gmail.com> 5
© 2010 Jorge Rodríguez Araújo

Así, se define la ecuación en diferencias del PID sin impulso derivativo, como:
k
u [k ]=K p⋅e [k ]K i⋅∑ e [i]−K d⋅ y [k −1]− y [k −2] 
i=0

Dado que el signo del término derivativo es negativo, significa que el impacto sobre la salida
de control será oponiéndose a la variación de la variable de proceso y, por tanto, inhibiendo
movimientos rápidos de la variable de proceso.
Así, al calcular el término derivativo en función de la variable de proceso, desaparece el
impulso derivativo, y su influencia aumenta con la rapidez con que cambia la variable de proceso,
contrarrestándola, mientras se conservan iguales los valores de sintonización.
Además, para garantizar que el valor de salida es el correcto, dado que se pueden producir
errores por desbordamiento, hay que añadir una última etapa en la que se limita la actuación al rango
establecido por los límites del actuador.

1.3 Sintonización del PID


Para la sintonización del PID se recurre al método de Ziegler-Nichols en lazo abierto que,
gracias a su sencillez y a proporcionar respuestas aceptables en multitud de problemas, es uno de los
métodos empíricos clásicos más utilizados en control industrial.
Este método, en lazo abierto, se basa en la respuesta experimental de la planta ante una entrada
tipo escalón. A partir de la cual, se modela un sistema de primer orden con retardo, siempre y cuando
la respuesta de la planta presente forma de “S”.

K⋅e −T⋅s
G s =
1⋅s
[Función de transferencia de una planta de primer orden con retardo]
Para determinar los parámetros que caracterizan el modelo de la planta de primer orden con
retardo: ganancia estática ( K ), constante de tiempo (  )1 y retardo temporal ( T ), se traza la
recta tangente en el punto de inflexión de la curva de respuesta temporal a entrada escalón en lazo
abierto (curva de reacción), de tal modo que:
1. Con la planta en lazo abierto, se lleva al proceso a que alcance el estado estacionario, en un
punto de operación normal con una salida estabilizada ( y 0 ) y una entrada constante ( u 0
).

2. En el instante inicial ( t 0 ), con la planta en lazo abierto, se excita el proceso por medio de
una entrada tipo escalón, cuyo valor ( u 1 ) debería estar en torno a un 30% del rango
completo.
3. A partir de ahí, se registran los datos de respuesta hasta que se estabilice el nuevo punto de
operación ( y 1 ), alcanzándose nuevamente la estabilización del proceso.

1 La constante de tiempo es igual al tiempo necesario para que la señal de salida alcance el 63,2% de su valor final.

<grrodi@gmail.com> 6
© 2010 Jorge Rodríguez Araújo

4. Finalmente, sobre la curva de reacción construida a partir de los datos adquiridos, se traza la
recta tangente de máxima pendiente, obteniéndose los instantes de tiempo ( t 1 y t 2 ),
donde la recta de máxima pendiente corta a los valores de salida inicial y final ( y0 , y1
).
Así:
y1 – y 0
K= ; T =t 1 – t 0 ; =t 2 −t 1
u1−u0

Finalmente, modelada la planta, los parámetros del controlador PID por el método de Ziegler-
Nichols, con un objetivo de diseño para alcanzar un amortiguamiento tal que exista una relación de 4:1
para el primer y segundo pico de la respuesta a una referencia escalón (criterio de amortiguamiento
1/4)2, se obtienen a partir de las expresiones de la siguiente tabla:

2 La amplitud de las oscilaciones se reduce a la cuarta parte en un período.

<grrodi@gmail.com> 7
© 2010 Jorge Rodríguez Araújo

Kp Ti Td

Controlador P - -
K⋅T

Controlador PI 0,9 3⋅T -
K⋅T

Controlador PID 1,2 2⋅T 0,5⋅T
K⋅T
Tabla 1: Parámetros de ajuste del controlador por el método de la curva de reacción

Donde los parámetros del PID vienen dados por: la ganancia proporcional ( K p ), el tiempo
integral ( T i ) y el tiempo derivativo ( T d ).

1.4 Simulación del PID


Aunque lo normal en estos casos es recurrir a Matlab, una licencia de este programa presenta
un coste prohibitivo, que en este caso resultaría totalmente injustificado, aún más cuando es
completamente viable realizarlo con herramientas libres: Python como lenguaje de “script”, Numpy
como librería de cálculo algebraico y Matplotlib como librería de representación gráfica 2D.
Así, se programa en Python un “script” que permite simular la respuesta de la planta a través
de su aproximación discreta al modelo de primer orden con retardo, cuya identificación se lleva a cabo
por medio del método de Ziegler-Nichols.
Con ello, y gracias a la simulación de la planta, se puede observar el comportamiento del
sistema bajo los parámetros de ajuste del PID según el método de Ziegler-Nichols, y permite analizar
el comportamiento de los diferentes algoritmos de implementación del PID, y generar los datos
necesarios para la verificación de su correcta implementación.

1.4.1 Aproximación discreta de la planta


Para la simulación de la planta, se recurre al modelo discreto de primer orden con retardo puro.
Que se encuentra precedido por un retenedor de orden cero (ZOH, Zero Order Hold), dado que la
respuesta de la planta depende de una entrada aplicada en forma de escalones, o pulsos, producidos
por una unidad PWM.
Así, dado que la acción de control se encuentra retardada un paso dado por el tiempo muerto y
el período de muestreo, se tiene que:

T
G z =
z –1 1
z {
s z
}
⋅ ⋅G  s ⋅z −d ; d=
Ts
(entero positivo)

Resolviendo la transformación se puede obtener la ecuación en diferencias del modelo, siendo:


y [k ]=a⋅y [k −1]b⋅u [k −d ]c

a=e−T /  ;
s
b=K⋅1−a ; c=1−a ⋅y0 ; d =T /T s

<grrodi@gmail.com> 8
© 2010 Jorge Rodríguez Araújo

1.4.2 Implementación
El siguiente listado recoge el “script” implementado para la simulación y ajuste del PID.

from pylab import *

class ZieglerNichols:
""" Método de Ziegler-Nichols en lazo abierto """

def __init__(self, t, u, y, Ts):


""" Establece los valores experimentales de la curva de respuesta """

# Constantes
self.SHIFT = 256 # desplazamiento (coma fija)
self.UMAX = 255 # límite de actuación superior (8 bits)
self.UMIN = 0 # límite de actuación inferior
self.MAX = (2**(16))-1 # límite de precisión superior (16 bits)
self.MIN = -(2**(16))-1 # límite de precisión inferir (16 bits)

# Vectores del sistema en lazo abierto


self.t = t # vector de tiempo
self.u = u # vector de acciones de control
self.y = y # vector de salidas de proceso

# Valores iniciales
self.y0 = 0
self.u0 = 0

# Parámetros de muestreo
self.Ts = Ts # período de muestreo
self.samples = len(t) # número de muestras

# Vectores del sistema en lazo cerrado


self.r = zeros(self.samples) # vector de valores de referencia
self.e = zeros(self.samples) # vector de errores de seguimiento

# Parámetros del modelo de la planta


self.K = 0 # ganancia estática
self.T = 0 # retardo temporal
self.tau = 0 # constante de tiempo

# Parámetros del PID


self.Kp = 0 # ganancia proporcional
self.Ki = 0 # ganancia integral
self.Kd = 0 # ganancia derivativa

# Vectores de las acciones del PID


self.P = zeros(self.samples) # proporcional
self.I = zeros(self.samples) # integral
self.D = zeros(self.samples) # derivativa

def measure(self, t, u, y):


""" Realiza una estimación de los valores de los parámetros de medida:
u0, u1, y0, y1, t0, t1, t2 """

self.u0 = u[0]
u1 = u[-1]
self.y0 = int(mean(y[0:100]))

<grrodi@gmail.com> 9
© 2010 Jorge Rodríguez Araújo

y1 = int(mean(y[-100:-1]))
for k in range(len(t)):
if u[k] > u[k-1]:
t0 = t[k]
break
t1 = t0 + 1
t2 = t0 + 15

return (self.u0, u1, self.y0, y1, t0, t1, t2)

def estimate(self, u0, u1, y0, y1, t0, t1, t2):


""" Realiza la estimación de los parámetros de la planta a partir
de los valores medidos sobre la curva de respuesta temporal """

self.K = float(y1 - y0) / float(u1 - u0)


self.T = float(t1 - t0)
self.tau = float(t2 - t1)

# Genera el vector de referencia según la respuesta en lazo abierto


self.r = ones(self.samples) * y1
for k in range(int(t0 / self.Ts)): self.r[k] = y0

print ">> Estimando los parametros de la planta"


print "K =", self.K, "; T =", self.T, "; tau =", self.tau

def tunning(self, K, T, tau):


""" Realiza la estimación de los parámetros de ajuste del PID por
el método y criterio de Ziegler-Nichols en lazo abierto """

# Constantes de definición del PID


self.Kp = int(round((1.2 * (tau / (K * T))) * self.SHIFT, 0))
self.Ki = int(round((K * self.Ts / (2 * T)) * self.SHIFT, 0))
self.Kd = int(round((K * (0.5 * T) / self.Ts) * self.SHIFT, 0))

print ">> Sintonizando el PID por Ziegler-Nichols"


print "Kp =", self.Kp, "; Ki =", self.Ki, "; Kd =", self.Kd

def plant_discrete(self, k, u, y):


""" Implementa el modelo discreto de una planta de primer orden
con retardo puro """

# Parámetros del modelo discreto


a = exp(-self.Ts / self.tau)
b = self.K * (1 - a)
c = (1 - a) * self.y0 - b * self.u0
d = int(ceil(self.T/ self.Ts)) # dead time (en pasos)

# Algoritmo del modelo discreto


if k > d: y[k] = a * y[k-1] + b * u[k-d] + c
elif k > 0: y[k] = a * y[k-1] + b * self.u0 + c
else: y[k] = self.y0

return y[k]

def pid_discrete(self, k, r, y, u):


""" Implementa el modelo discreto del PID con limitación del
término integral y eliminacion del impulso derivativo """

<grrodi@gmail.com> 10
© 2010 Jorge Rodríguez Araújo

# Cálculo del error de seguimiento


if k > 0: self.e[k] = int(r[k] - int(y[k-1]))
else: self.e[k] = int(r[k])

# Cálculo del término de acción proporcional


self.P[k] = self.Kp * self.e[k]

# Cáculo del término de acción integral


if k > 0: self.I[k] = self.I[k-1] + self.Ki * self.e[k]
else: self.I[k] = self.Ki * self.e[k]

# Cáculo del término de acción derivativa "ideal"


if k > 0: self.D[k] = self.Kd * (self.e[k] - self.e[k-1])
else: self.D[k] = self.Kd * self.e[k]

# Eliminación del impulso derivativo "no kick"


"""if k > 1: self.D[k] = - self.Kd * (y[k-1] - y[k-2])
elif k > 0: self.D[k] = - self.Kd * y[k-1]
else: self.D[k] = - 0"""

# Limitación del término integral "anti-windup" (límite de 16 bits)


"""if self.I[k] > self.MAX: self.I[k] = self.MAX # límite superior
if self.I[k] < self.MIN: self.I[k] = self.MIN # límite inferior"""

# Acción de control PID


u[k] = self.P[k] + self.I[k] + self.D[k]

# Ajuste de la acción de control


u[k] = u[k] / self.SHIFT # Desplazamiento (coma fija)
if u[k] > self.UMAX: u[k] = self.UMAX # Ajuste del límite superior
if u[k] < self.UMIN: u[k] = self.UMIN # Ajuste del límite inferior

return int(u[k])

def simulate_plant(self):
""" Simula la respuesta de la planta en lazo abierto """

# Respuesta de la planta a entrada escalón


y = zeros(self.samples)
for k in range(self.samples):
y[k] = self.plant_discrete(k, self.u, y)

self.plot_plant(self.t, self.u, y)

return y

def simulate_pid(self, r):


""" Simula la respuesta de la planta en lazo de control cerrado """

# Respuesta de la planta regulada


u = zeros(self.samples)
y = zeros(self.samples)
for k in range(self.samples):
u[k] = self.pid_discrete(k, r, y, u)
y[k] = self.plant_discrete(k, u, y)

self.plot_pid(self.t, self.r, u, y)

<grrodi@gmail.com> 11
© 2010 Jorge Rodríguez Araújo

return (y, u)

def plot_plant(self, t, u, y):


""" Representa la respuesta temporal de la planta """

subplot(211)
plot(self.t, self.y, 'b.')
plot(t, u, 'g--', t, y, 'r-', lw=1.2)
xlabel("Tiempo [s]")
ylabel("Variable de proceso (PV)")

title("Respuesta temporal en lazo abierto (Modelo)")

subplot(212)
plot(self.t, self.u, 'r-')
xlabel("Tiempo [s]")
ylabel("Salida de control (CO)")

subplot(211)
grid(True)
axis([self.t[0], self.t[-1], 0, 255])

subplot(212)
grid(True)
axis([self.t[0], self.t[-1], 0, 255])

def plot_pid(self, t, r, u, y):


""" Representa la respuesta temporal del sistema en lazo cerrado
y las acciones de control que la provocan """

# Señal de control discreta con mantenedor de orden 0


t0 = zeros(2 * self.samples)
t0[-1] = self.samples * self.Ts # Último valor
r0 = zeros(2 * self.samples)
y0 = zeros(2 * self.samples)
u0 = zeros(2 * self.samples)
for k in range(self.samples):
# Señal de control discreta
j = 2 * k
if k > 0: t0[j] = t0[j-1] = t[k]
r0[j+1] = r0[j] = r[k]
y0[j+1] = y0[j] = y[k]
u0[j+1] = u0[j] = u[k]

subplot(211)
plot(t0, r0, 'g--', t0, y0, 'b-')
xlabel("Tiempo [s]")
ylabel("Variable de proceso (PV)")

title("Respuesta temporal en lazo cerrado (PID)")

subplot(212)
plot(t0, r0, 'g--', t0, u0, 'r-')
xlabel("Tiempo [s]")
ylabel("Salida de control (CO)")

#subplot(212)
#plot(self.t, self.P, self.t, self.I, self.t, self.D)

<grrodi@gmail.com> 12
© 2010 Jorge Rodríguez Araújo

#ylabel("Accion de control")
#legend(("P", "I", "D"), 'best')

subplot(211)
grid(True)
axis([t0[0], t0[-1], 0, 255])

subplot(212)
grid(True)
axis([t0[0], t0[-1], 0, 255])

def plot_measures(self, u0, u1, y0, y1, t0, t1, t2):


""" Representa los valores de los parámetros de medida """

subplot(211)
plot([self.t[0], self.t[-1]], [y0, y0], 'k--',
[self.t[0], self.t[-1]], [y1, y1], 'k--',
[t1, t1], [0, 255], 'k--',
[t2, t2], [0, 255], 'k--',
[t1, t2], [y0, y1], '--')
if y0 != 0: text(-1, y0, "y0", va='center', ha='right',
fontsize=9, color='blue')
if y1 != 0: text(-1, y1, "y1", va='center', ha='right',
fontsize=9, color='blue')
if t1 != 0: text(t1, -1, "\nt1", ha='center', va='top',
fontsize=9, color='green')
if t2 != 0: text(t2, -1, "\nt2", ha='center', va='top',
fontsize=9, color='green')

subplot(212)
plot([self.t[0], self.t[-1]], [u0, u0], 'k--',
[self.t[0], self.t[-1]], [u1, u1], 'k--',
[t0, t0], [0, 255], 'k--')
if u0 != 0: text(-1, u0, "u0", va='center', ha='right',
fontsize=9, color='red')
if u1 != 0: text(-1, u1, "u1", va='center', ha='right',
fontsize=9, color='red')
if t0 != 0: text(t0, -1, "\nt0", ha='center', va='top',
fontsize=9, color='green')

def plot(self, u0, u1, y0, y1, t0, t1, t2):


""" Representa la respuesta del sistema en lazo abierto """

self.plot_measures(u0, u1, y0, y1, t0, t1, t2)

self.simulate_plant()

def load(filename):
""" Devuelve los datos (t, u, y, Ts) a partir del archivo de datos de
respuesta del sistema """

print ">> Leyendo los datos de respuesta temporal del sistema "
try:
# Leer archivo de datos (U Y)
file = open(filename, 'r')
# Leer valor de Ts en us expresado en hexadecimal en la primera línea
Ts = int(file.readline(), 16) / 1000000.
# Ignorar la segunda línea que identifica las columnas U Y

<grrodi@gmail.com> 13
© 2010 Jorge Rodríguez Araújo

line = file.readline()
# Leer la información que se encuentra en el resto de líneas del
archivo
lines = file.readlines()
file.close()

# Procesar datos (U Y) hex


u = []
y = []
for line in lines:
[uk, yk] = line.split() # Datos hex
u.append(int(uk, 16))
y.append(int(yk, 16))

# Crear el vector de tiempo


t = arange(len(u)) * Ts

print "Archivo cargado"

return (t, u, y, Ts)


except:
print "¡No se ha podido abrir el archivo!"

def save(filename, y, u):


""" Guarda los datos de simulación temporal del sistema con PID (y, u) """

print ">> Guardando los datos de simulacion del sistema "


try:
contents = "Y U\n"
for k in range(len(y)):
if k> 0: contents += "%d %d\n" %(y[k-1], u[k])
else: contents += "%d %d\n" %(0, u[k])
# Guadar archivo de datos (Y U)
file = open(filename, 'w')
file.write(contents)
file.close()
print "Archivo guardado"
except:
print "¡No se ha podido guardar el archivo!"

if __name__ == "__main__":

# Cargar los datos de la respuesta del sistema


(t, u, y, Ts) = load("ADC.dat")

# Definición de los datos para la aplicación del método de Ziegler-Nichols


zn = ZieglerNichols(t, u, y, Ts)

# Estimación de la planta por el método de Ziegler-Nichols


(u0, u1, y0, y1, t0, t1, t2) = zn.measure(t, u, y) # parámetros de medida
zn.estimate(u0, u1, y0, y1, t0, t1, t2)
# Sintonización del PID por el método de Ziegler-Nichols
zn.tunning(zn.K, zn.T, zn.tau)

# Simulación y representación de la respuesta en lazo abierto


f = figure()
zn.simulate_plant()
zn.plot(u0, u1, y0, y1, t0, t1, t2)

<grrodi@gmail.com> 14
© 2010 Jorge Rodríguez Araújo

f.show()

# Simulación y representación de la respuesta en lazo cerrado


f = figure()
(y, u) = zn.simulate_pid(zn.r)
f.show()

# Guardar los datos de la simulación del sistema


save("PID.dat", y, u)

>> Leyendo los datos de respuesta temporal del sistema


Archivo cargado
>> Estimando los parametros de la planta
K = 0.549222797927 ; T = 1.0 ; tau = 14.0
>> Sintonizando el PID por Ziegler-Nichols
Kp = 7831 ; Ki = 7 ; Kd = 687
>> Guardando los datos de simulacion del sistema
Archivo guardado

<grrodi@gmail.com> 15

You might also like