controlador PID implementado digitalmente

1

He estado leyendo artículos sobre la implementación de PID digital. Entonces, en el dominio discreto, podemos escribir la ley de PID de forma paralela, como:

$$ U (z) = E (z) * \ left [K_p + \ frac {K_iT_s} {1 - z ^ {- 1}} + K_d \ frac {1 - z ^ {- 1}} { T_s} \ right] $$

Donde \ $ T_s \ $ es el tiempo de muestreo. También se dice que \ $ K_p \ $, \ $ K_i \ $ y \ $ K_d \ $ están relacionados como:

$$ K_i = \ frac {K_p} {T_i} \\ K_d = K_p \ cdot T_d $$

donde \ $ T_i \ $ es el tiempo integral y \ $ T_d \ $ es el tiempo derivado.

Entonces, en la ecuación anterior obtendría $$ K_i = K_p \ frac {T_s} {T_i} \\ K_d = K_p \ frac {T_d} {T_s} $$

Digamos que implemento mi ley de control, en tiempo discreto (k), como:

$$ u [k] = K_p \ cdot e [k] + K_i \ big (e [k] + e [k-1] \ big) + K_d \ big (e [k] - e [k- 1] \ big) $$

Mis preguntas:

  • es el tiempo integral y el tiempo derivado (\ $ T_s \ $ y \ $ T_d \ $) definidos por el período de reloj del circuito que realiza estos cálculos?

  • si mi señal de error es muestreada por el mismo reloj que calcula las partes integrales y derivadas de mi ley, \ $ T_i = T_d = T_s \ $?

  • Si \ $ T_i = T_d = T_s \ $, \ $ K_p = K_i = K_d \ $? Suena realmente extraño.

pregunta user3845287

2 respuestas

1
  

es el tiempo integral y el tiempo derivado (Ts y Td) definido por el   ¿Período de reloj del circuito que realiza estos cálculos?

El tiempo integral y el tiempo derivado se relacionan con cualquier luz estroboscópica asociada utilizada alrededor de esos bloques.

La electrónica digital toma un tiempo finito para realizar las operaciones requeridas. Tome un integrador discreto de trapecio cuya ecuación de diferencia se vea así:

\ $ y_n = y_ {n-1} + K_i * T_s * \ frac {x_n + x_ {n-1}} {2} \ $

Hay dos adiciones, dos multiplicaciones y una división (aunque se trata de una división a la derecha con cambio barato) para un paso de integración. Esto debe completarse antes de que llegue la siguiente muestra \ $ x_n \ $. Ahora, para ahorrar en una multiplicación, \ $ K_i * T_s \ $ se podría combinar en un escalar, que es una práctica estándar & esto resulta en la variable de ganancia relacionada con el tiempo de muestra \ $ T_s \ $

¿Qué establece tu \ $ T_s \ $? . Esas multiplicaciones y adiciones toman un tiempo finito & DEBEN completarse para cuando la siguiente muestra esté disponible \ $ x_n \ $

  

si mi señal de error es muestreada por el mismo reloj que calcula el   partes integrales y derivadas de mi ley, Ti = Td = Ts?

Sí, lo sería, si Ts es la tasa de adquisición de datos o de interpolación, de una se utiliza)

  

Si Ti = Td = Ts, Kp = Ki = Kd? Suena realmente extraño.

No, porque Ts es solo una parte de la ecuación integral discreta ya que existe el factor de ganancia. Como se mencionó anteriormente, el factor de ganancia Y el período de muestra se pueden calcular previamente para ahorrar en un paso de multiplicación

--edit--

Para ayudar a aclarar. A continuación se muestra un fragmento de código de Python que implementa un integrador discreto (opción de 3, pero la trampa más a menudo que no es la que desea). El tiempo de muestra, \ $ T_s \ $ aquí es 1us (así como 100us para demostrar un punto). En este caso \ $ T_i = T_s = 1us (o 100us) \ $. Del mismo modo, el "reloj" del procesador, la velocidad del reloj de la máquina virtual de Python, por simplicidad, puede considerarse como 2.9 GHz. Este es un ejemplo razonable para un FPGA / uP que se ejecuta a una velocidad mayor y los ADC están muestreando a una velocidad más lenta, PERO una velocidad que es lo suficientemente lenta para que el procesador principal complete sus pasos computacionales.

#!/usr/bin/env python
import numpy as np
from matplotlib import pyplot as plt


def fwdEuler(X=0, dt=0):
    '''y(n) = y(n-1) + [t(n)-t(n-1)]*x(n-1)'''
    x[0] = X*Ki # apply gain prior to integration 
    y[0] = self.y[-1] + dt*x[-1]
    x[-1] = float(x[0])
    y[-1] = float(y[0])
    return y[0]

def revEuler(X=0, dt=0):
    '''y(n) = y(n-1) + [t(n)-t(n-1)]*x(n)'''
    x[0] = X*Ki # apply gain prior to integration 
    y[0] = y[-1] + dt*x[0]
    x[-1] = float(x[0])
    y[-1] = float(y[0])
    return y[0]

def Trap(X=0, dt=0):
    '''y(n) = y(n-1) + K*[t(n)-t(n-1)]*[x(n)+x(n-1)]/2'''
    x[0] = X*Ki # apply gain prior to integration 
    y[0] = y[-1] + dt*(x[0]+x[-1])/2
    x[-1] = float(x[0])
    y[-1] = float(y[0])
    return y[0]


plt.hold(True)
plt.grid(True)
f,p = plt.subplots(4)
x = [0,0]
y = [0,0]
Ki = 1

t = np.arange(0,1,1e-6)  # 1million samples at 1us step
data = np.ones(t.size)*1 # 
p[0].plot(t,data)
p[0].set_title('Simple straight line to integrate')

int_1 = np.zeros(t.size)
for i in range(t.size):
    int_1[i] = Trap(data[i],t[1]-t[0])
p[1].set_title('Trap integration with Ki=1 and Ti=1u')
p[1].plot(t,int_1)

x = [0,0]
y = [0,0]
Ki = 1
t = np.arange(0,1,100e-6)  # 1million samples at 1us step
data = np.ones(t.size)*1 # 
int_2 = np.zeros(t.size)
for i in range(t.size):
    int_2[i] = Trap(data[i],t[1]-t[0])
p[2].set_title('Trap integration with Ki=1 and Ti=100u')
p[2].plot(t,int_2)


x = [0,0]
y = [0,0]
Ki = 2
t = np.arange(0,1,1e-6)  # 1million samples at 1us step
data = np.ones(t.size)*1 # 
int_3 = np.zeros(t.size)
for i in range(t.size):
    int_3[i] = Trap(data[i],t[1]-t[0])
p[3].set_title('Trap integration with Ki=2 and Ti=1u')
p[3].plot(t,int_3)

plt.show()

Como puede ver, para un algoritmo de diferencia integral válido, la ganancia integral real es la unidad y, por lo tanto, puede ser ... sintonizada, a través de una ganancia adicional, \ $ K_i \ $. Esto es igualmente cierto para los términos diferenciales.

    
respondido por el JonRB
0

Sí, los coeficientes de integración y derivación están sujetos al tiempo de muestreo, pero no de la forma que sugiere. Ti, Td siguen siendo siempre los mismos que se definen en el tiempo de espera, como un regulador PID opamp funciona de la misma manera en comparación con el regulador PID discreto con el mismo Kp, Ti, Td. Lo que realmente corresponde a los pesos de una ecuación que cambia con respecto al tiempo de muestreo.
Un regualtor PID parece muy sencillo de implementar, pero también tiene trampas, una conocida es la saturación del integrador, por lo que se llaman algoritmos especiales como anti-windup. El integrador se puede hacer con la fórmula Simpson, mientras que el diferenciador también es complicado, ya que tiene que ser amortiguado, por lo tanto, se utiliza un diferenciador aproximado. Los reguladores con parámetro Kp, Ti, Td son de tipo europeo, mientras que los EE. UU. Usan Kp, ki, kd. Son diferentes porque en el tipo de UE, Kp se multiplica por el integrador y el diferenciador, como anotó ki = Kp / Ti, kd = Kp * Td y Ti, constantes de tiempo [t] de Td, y se pueden calcular con métodos como Ziegler-Nichols, mientras que ki, kd no tiene unidades.

Aquí también puede encontrar el código fuente de los controladores implementados en el libro .

//TO...sample time
// at initial time all: ek1, ek2, ek3, e4, uk1 are zero  

q0 := Kp*(1 + T0/Ti + Td/(6*T0));
q1 := Kp*(-1 + Td/(3*T0));
q2 := Kp*(-Td/T0);
q3 := Kp*(Td/(3*T0));
q4 := Kp*(Td/(6*T0));

ek4 := ek3
ek3 := ek2;
ek2 := ek1;
ek1 := ek;
ek := setpoint - actual;

u := q0*ek + q1*ek1 + q2*ek2 + q3*ek3 + q4*ek4 + uk1;

if u > u_max then
    u := u_max;
elsif u < u_min then
    u := u_min;
end_if;

uk1 := u;

Este es el regulador Ziegler-Nichols (Zn3fpd.m). El controlador se basa en un método rectangular de discretización hacia adelante que reemplaza la derivación por una diferencia de cuatro puntos de enlace, reajustado por mí en un idioma diferente. No doy ninguna garantía.

Este es un código de zn2fr.m, de manera similar con su enlace, pero teniendo en cuenta el tiempo de muestreo, mientras que el algoritmo en el enlace que publicó no proporciona el mismo comportamiento con diferentes tiempos de muestreo. El tiempo de muestreo adecuado referido por el autor es de 5 a 20 veces el tiempo de subida del sistema.

q0 = Kp*(1+Td/T0);
q1 = -Kp*(1-T0/Ti+2*Td/T0);
q2 = Kp*(Td/T0);

ek2 := ek1;
ek1 := ek;
ek := setpoint - actual;

u = q0*ek + q1*ek1 + q2*ek2 + uk1;

if u > u_max then
        u := u_max;
elsif u < u_min then
        u := u_min;
end_if;

uk1 := u;

% zn3fd Controlador% para procesos de 3er orden con filtración de componente D usando Aproximación% Tustin. Constante de tiempo del filtro Tf = Td / alfa.

Este controlador es ampliamente utilizado en la industria, tiene un componente D aproximado (como una fuga de opamp real), alfa está entre 3 ... 30, a los 30 se comportará casi sin D filtrado, a los 3 D El componente es casi inútil (demasiado filtrado)

Tf = Td/alfa;
cf = Tf/T0;
ci = T0/Ti;
cd = Td/T0;
p1 = -4*cf/(1+2*cf);
p2 = (2*cf-1)/(1+2*cf);
q0 = Kp * (1 + 2*(cf+cd) + (ci/2)*(1+2*cf))/(1+2*cf);
q1 = Kp * (ci/2-4*(cf+cd))/(1+2*cf);
q2 = Kp * (cf*(2-ci) + 2*cd + ci/2 - 1)/(1+2*cf);

ek4 := ek3
ek3 := ek2;
ek2 := ek1;
ek1 := ek;
ek := setpoint - actual;

u = q0*ek + q1*ek1 + q2*ek2 - p1*uk1 - p2*uk2;

if u > u_max then
   u := u_max;
elsif u < u_min then
   u := u_min;
end_if;

uk2 := uk1;    
uk1 := u;
    
respondido por el Marko Buršič

Lea otras preguntas en las etiquetas