Autor Tema: Control PID con anti-windup en PIC y CCSRTOS.  (Leído 38075 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Control PID con anti-windup en PIC y CCSRTOS.
« en: 10 de Julio de 2009, 02:34:22 »
Este ejemplo surgió de una práctica que realice para usar el CCS RTOS. El resultado fue un ejemplo, creo yo, bastante completo en la implementación de un control PID y el RTOS de CCS. Así que lo documenté y lo posteo, seguramente a alguien le va a servir la info expuesta.

Objetivo: Un sistema de control de temperatura configurable mediante un panel de control (Teclado mas display LCD), en donde se puede seleccionar entre control On/Off o PID, ingreso de Temperatura deseada (Set Point), cambio de alguno de los parámetros del PID (Kp, Ti, Td), Visualización de las variables (Temperatura actual del sistema, Temperatura deseada, Kp, Ti, Td) y un simple datalogger activable (Envía por RS232 temperatura cada ciertos ms)
El sistema a controlar será el horno Over que trae Proteus, excelente para esta práctica ya que trae un terminal donde nos indica la temperatura del horno necesaria para la realimentación. El Over lo configuramos de la siguiente manera para hacer más rápidas las simulaciones: 25, 0.7, 1, 1, 100.


Identificación del Sistema  (Apuntes de Identificación de sistemas)
En este caso para identificar el sistema simplemente aplique un escalón de 1 volts y determiné la salida. Capturé los datos cada 100ms, y con estos ingresé a la utilidad ident de Matlab.  Aquí blackgat explica paso a paso como determinar el sistema usando esta utilidad de Matlab. Este es solo un ejemplo así que no me preocupe por obtener un modelo bien determinado, en ese caso no solo hay que aplicar un escalón, sino aplicar una entrada de varios niveles, y así obtener un sistema estimado más aproximado al real.

En ident, seleccione oe221 logrando una identificación del 99.65%. El modelo del sistema resultante para Ts=0.1s:
GZ=\frac{0.6566z+0.6145}{z^2-1.809z+0.8178}
Aplicando D2C determinamos el modelo de sistema continuo:
GS=\frac{-0.0027s+140.4}{s^2+2.011s+0.9723}

Selección de muestro a lazo cerrado.
Este valor esta íntimamente relacionado con el ancho de banda del sistema y las velocidades razonables de muestro están entre 6 y 10 veces este valor.
En Matlab determinamos el bode del sistema, dando un ancho de banda de 4.4 Hz, con esto seleccionamos  0.02 segundos como periodo de muestro. (1/10•4.4Hz). Utilizando C2D  y Ts = 0.02 s determinamos el sistema muestreado :
GZ=\frac{0.0276z+0.0274}{z^2-1.96z+0.9606}

Control PID a aplicar
(Ver Apunte PID)
El control PID a utilizar es el siguiente:
Como se ve ya tiene implementado el control anti-windup. El efecto windup aparece al arrancar el sistema o en cualquier otra situación, donde aparece un error muy grande durante un tiempo prolongado. Esto hará que el término integral aumente para reducir el error. Pero si nuestro actuador es  limitado, con esto me refiero que la tensión que podemos aplicarle al horno solo (en este caso) esta entre 0 y 5V, se saturará pero el termino integral seguirá creciendo. Cuando el error se reduce, la parte integral también comenzará a reducirse pero desde un valor muy alto, llevando mucho tiempo hasta que logre la estabilidad, generando fluctuaciones exageradamente grandes.

Discretización:
Para la parte integral se aproxima a sumas sucesivas, y la parte derivativa por una diferencia:


Sintonización del Control PID Sintonización de PID
En este caso utilizo el método de Ziegler-Nichols basado en la respuesta en frecuencia. Se realimenta la planta con un regulador proporcional aumentando su ganancia hasta que el sistema presente una oscilación no amortiguada, determino la ganancia proporcional y el periodo de la oscilación:
Kc=1.4392, tc=0.44s
Kp=0.6Kc=0.8635, Ti=0.5tc=0.22, Td=0.125tc=0.055

Función de transferencia del PID discreto sin windup
\frac{U(z)}{E(z)}=\frac{q0z^2+q1z+q2}{z(z-1)}
Con el control PID sin windup utilizamos la herramienta sisotool para ver el resultado obtenido, y también si es posible mejorarlo.

Por ejemplo, un resultado mejor se obtiene modificando los ceros del control PID a 0.95; 0.95 y una ganancia de K=8.57. Con estos valores los nuevos parámetros del PID son:
Kp=0.8142, Ti=0.7609, Td=0.1899


En simulink podemos ver el efecto que tiene la saturación del actuador:
Resultado obtenido al aplicar antiwindup:


Control On/Off (todo o nada :?)

Es un sistema de control muy simple, y como su nombre lo indica, la señal de control en este caso será 0 Volts si Temperatura del horno es mayor a la deseada, y 5 Volts si es menor a la deseada. Mas info, Control Todo o nada
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #1 en: 10 de Julio de 2009, 02:36:07 »
El control PID ya esta calculado por lo menos en teoría  :mrgreen: Con esto pasamos a realizar el código que se ejecutará cada 20ms. Para ello creamos una tarea:

Código: C
  1. #task(rate=20ms,max=1ms)
  2. void ControlSistema(void){
  3.    Medida=read_adc();
  4.    TempReal=Medida;
  5.    TempReal=(TempReal*500)/1024;
  6.    
  7.    eT=TempRef-TempReal;                      //Cálculo error
  8.    
  9.    if(SistControl==1){
  10.       uT=q0*eT - q1*eT_1 + q2*eT_2 + uT_1;      //Cálculo de la salida PID (uT=[Volt])
  11.       rT=(uT*1000)/5;                           //duty cycle maximo 1000 -> 5V.-
  12.       /* <<<<< AntiWindup  >>>>>*/
  13.       if (rT>1000){                              //Salida PID si es mayor que el 1000.-
  14.          uT=(uT + 5*p0)*p00;      
  15.          rT=1000;
  16.       }
  17.       if (rT<0n){                              //Salida PID si es menor que el 0
  18.          uT=uT*p00;  
  19.          rT=0;
  20.       }
  21.       /* <<<<< Transferencia de salida PID a señal PWM >>>>>*/
  22.       ControlPWM=rT;                            
  23.       set_pwm1_duty(ControlPWM);
  24.       /*  <<<<< Guardar variables para proximo estado >>>>>*/
  25.       eT_2=eT_1;
  26.       eT_1=eT;
  27.       uT_1=uT;
  28.    }else{                               // Control On-Off
  29.       if(eT>0){output_high(PIN_C2);}
  30.       else{output_low(PIN_C2);}
  31.    }
  32. }

En RTOS CCS la “prioridad” de tareas, con esto me refiero si hay tareas que se ejecutan con el mismo periodo o con algún múltiplo del mismo se da en el orden en que se definen en el programa :? Así que como esta tarea es la mas importante se define primero a todas, excepto que exista alguna otra de inicialización del sistema.

Menú de control
Como objetivo se planteo armar un panel de control, éste tiene un menú que debe ser visualizado en display según las teclas presionadas de movimiento.
La impresión del menú en el display se hace por medio de una tarea, que se ejecuta cada 1ms cuando es habilitada. Esta tarea envía un carácter o comando a la vez, de esta manera hacemos la impresión de manera más dinámica  que al realizar un simple printf(lcd_putc,”Menu Principal \n     ---->”), línea que dependiendo de los datos que se envíe puede llegar a demorar unos 5ms. Puede que en este ejemplo no haya sido necesario, pero fue útil para aplicar algunos comandos de rtos :mrgreen:

Entonces para imprimir un mensaje en el LCD se usaron 2 buffer de 16 elementos para cada línea, dos variables que indican el largo de los string a escribir y una adicional para indicar si es necesario borrar el display al iniciar la escritura. La carga de un mensaje sería así:
Código: C
  1. strcpy(BufferLCD1,">Datos");
  2.          strcpy(BufferLCD2,"Configuracion");
  3.          LengthMsj1=strlen(BufferLCD1);
  4.          LengthMsj2=strlen(BufferLCD2);
  5.          Print=1; // 1 Requiere borrar LCD.

Al completar la cargar de los buffer se habilita la tarea que se encarga de imprimir el mensaje:
Código: C
  1. #task(rate=1ms,max=1ms)
  2. void ImprimirLCD(void){
  3. int j;
  4.  
  5.    if(Print==1){                 // Borramos display?
  6.       lcd_comand(1);    
  7.       Print=0;
  8.       rtos_yield();              // Se "duerme" hasta el proximo ciclo.-
  9.    }
  10.    for(j=0;j<LengthMsj1;j++){    // Si hay caracteres en Primer linea envia al LCD.-
  11.      lcd_putc(BufferLCD1[j]);
  12.      rtos_yield();              
  13.    }
  14.    if(LengthMsj2!=0){            // Si hay caracteres a imprimir en la segunda linea..
  15.       lcd_gotoxy(1,2);           // ..salta a la siguiente a la linea 2.
  16.       rtos_yield();
  17.    }
  18.    for(j=0;j<LengthMsj2;j++){    // Si hay caracteres en Segunda linea envia al LCD.-
  19.       lcd_putc(BufferLCD2[j]);
  20.       rtos_yield();
  21.    }
  22.    if(PosMod!=0){                // Utilizado para correr el cursor cuando se modifican
  23.                                  // los parametros.-
  24.       lcd_gotoxy(PosMod,1);      // Vuelve cursor para modificar valores.-
  25.       rtos_yield();
  26.    }
  27.    rtos_disable(ImprimirLCD);
  28. }

Control del menú mediante teclado.
Para detectar cuando se ha presionado una tecla se utiliza la interrupción por cambio de estado de RB4-RB7. Al activarse la interrupción se testea la tecla pulsada, este dato se coloca en cola de mensajes y se habilita la tarea que lo tratará.
Esta tarea recibe el dato, ejecuta una rutina que modifica las variables de control del menú, carga los buffer de visualización, habilita la tarea que realiza la impresión del menú en el display y se deshabilita así misma.

Código: C
  1. #int_RB
  2. void  RB_isr(void)
  3. {
  4.    Tecla=TestTeclado();                            //Testea la Tecla Pulsada.-
  5.    if(Tecla!=16){                                  //Tecla y no falsa alarma?.-
  6.          rtos_msg_send(VisualizacionLCD,Tecla);    
  7.          rtos_enable(VisualizacionLCD);
  8.    }
  9. }

Código: C
  1. void VisualizacionLCD(void){
  2.    if(rtos_msg_poll()>0){
  3.       SeleccionMenu(rtos_msg_read());  //Dependiendo la Tecla recibida se ubica
  4.                                        //dentro del Menu.-
  5.       if(Panel==1){                    //Si no se a pedido apagar...
  6.          if(Enter==0){                 //Y si no se ha presionado Enter...
  7.             ImpresionMenu();           //Cargamos los buffer segun la posicion
  8.                                        //en el menu para impresion en LCD.-
  9.          }
  10.          rtos_enable(ImprimirLCD);     //Habilitamos tarea para impresion en LCD.-
  11.       }
  12.    }
  13.    rtos_disable(VisualizacionLCD);
  14. }
« Última modificación: 10 de Julio de 2009, 02:46:31 por Suky »
No contesto mensajes privados, las consultas en el foro

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #2 en: 10 de Julio de 2009, 02:41:23 »
Un video de cómo sería el sistema simulado:
Señales obtenidas de la simulación:
Control PID:
Control On-Off:

Esta claro que para un sistema real hay muchas cosas adicionales a tener en cuenta :mrgreen:

Adjunto código.
No contesto mensajes privados, las consultas en el foro

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #3 en: 10 de Julio de 2009, 05:54:48 »
Espectacular, Suky. Muchas gracias por compartirlo

Desconectado NANO1985

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1698
    • Desarrollos Tecnologicos - Tucuman - Argentina
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #4 en: 10 de Julio de 2009, 12:54:45 »
t pasaste hermano!, muy buen documentoooo! sin palabras....
muchisimas gracias por compartirlo
Saludos  8)
"La inquebrantable voluntad de vencer"
"hay dos cosas infinitas... El universo y la Estupidez humana" Albert Einstein
 "El sabio actua sin anhelos, permanece sosegado,... así no es afectado por el resultado de sus acciones sean éstas el triunfo o el fracaso"
- UNIVERSIDAD TECNOLOGICA NACIONAL - FACULTAD REGIONAL TUCUMAN -

Desconectado Gonzalo_BlackHawk

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 519
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #5 en: 10 de Julio de 2009, 18:38:01 »
Grande Suky! Una muy buena clase de control para todos nosotros...

Te pasaste!  :-/ :-/ :-/ :-/

Saludos.
"Siempre piensa si el jugo vale la exprimida..."

"La muerte esta tan segura de vencer que nos da toda una vida de ventaja."

Desconectado kcire

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 84
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #6 en: 10 de Julio de 2009, 19:39:51 »
Muy buen trabajo Ale, felicidades y gracias por compartirlo.

Un saludo,  :lol:
Erick
"La imaginación es más rica que el lenguaje... sugiere con palabras, la imaginación podrá hacer el resto."

Desconectado barral

  • PIC10
  • *
  • Mensajes: 37
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #7 en: 15 de Julio de 2009, 04:04:13 »
Estupendo. Muy bien explicado y documentado.

Cada vez más tengo ganas de tener suficiente tiempo para meterme en RTOS....

Saludos

Desconectado Nichita

  • Colaborador
  • PIC12
  • *****
  • Mensajes: 86
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #8 en: 15 de Julio de 2009, 17:30:51 »
Muy bueno!!!, gracias por compartirlo. :mrgreen:

Desconectado fidodido18

  • PIC18
  • ****
  • Mensajes: 312
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #9 en: 09 de Agosto de 2009, 21:29:33 »
Si no viniera de Suky diria algo como "Te sobraste hermano!" pero el ya nos tiene acostumbrado a semejantes post!

sobre todo la humildad que le pone, diciendo que para un sistema real faltan muchas cosas mas a considerar, la verdad no creo que falte mucho mas, y te lo digo yo que he implementado mas de 3 sistemas reales (a pequeña escala).

lo unico que le falta al documento es la explicacion para pasar la respuesta del sistema analogico a digital, pero se asume que eso lo debe saber cualquiera que se atreva a ver un PID digital..

En hora buena Suky, felicitaciones!

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #10 en: 09 de Agosto de 2009, 21:39:56 »
Si no viniera de Suky diria algo como "Te sobraste hermano!" pero el ya nos tiene acostumbrado a semejantes post!

sobre todo la humildad que le pone, diciendo que para un sistema real faltan muchas cosas mas a considerar, la verdad no creo que falte mucho mas, y te lo digo yo que he implementado mas de 3 sistemas reales (a pequeña escala).

lo unico que le falta al documento es la explicacion para pasar la respuesta del sistema analogico a digital, pero se asume que eso lo debe saber cualquiera que se atreva a ver un PID digital..

En hora buena Suky, felicitaciones!
Gracias fidodido18!

Con respecto a la obtención del sistema digital indique el post de Blackgat, y como dices, el que tiene conocimiento lo entiende  :mrgreen:

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Renatox_

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 541
    • máquinas cnc
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #11 en: 12 de Agosto de 2009, 02:12:08 »
Muchas gracias Suky por la informacion, nos va a servir a todos lo que vemos control, y yo pensaba que el control PID digital C(z)=(qoz^2+q1z+q2)/(z(z-1)) ya tenía incluido el antiwinup pero estaba en un error, la diferencia de resultados que da uno y otro control son asombrosas, con antiwindup se protege más al actuador, voy a probarlo con mi PID.

Una pregunta primero hallastes unos parametros kp, ti, td en base a ziger nichols,, luego lo cambiastes por otrs valores para que te salga la respuesta mas amortiguada,,en base a que criterio lo escojistes.
Por cierto a los sistemas que responden siempre en forma sobreamortiguada, es decir sin sobreimpulso es recomendable aproximarlos a un sistema de primer orden.

Para fidodido sobre cambiar de sistemas continuos a discretos hay que usar la transformada z con un periodo de muestreo, el mismo que del control y anteponerle un ZOH a la planta, eso se hace a mano cuando uno lleva control digital pero luego solo debemos poner en matlab c2d(Gz,T,'zoh').

saludos.
« Última modificación: 12 de Agosto de 2009, 02:15:54 por Renatox_ »
control de movimiento

Desconectado msegredo

  • PIC10
  • *
  • Mensajes: 7
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #12 en: 30 de Agosto de 2009, 00:38:25 »
Muy bueno! Podrias subir el codigo completo? Muchas gracias.

Desconectado Suky

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #13 en: 30 de Agosto de 2009, 10:18:48 »
Una pregunta primero hallastes unos parametros kp, ti, td en base a ziger nichols,, luego lo cambiastes por otrs valores para que te salga la respuesta mas amortiguada,,en base a que criterio lo escojistes.
Perdón, no había leído esta respuesta. Observando el lugar de
\xi
y
\omega
T. Realizando un pequeño ajuste sin alejarnos mucho de los ptos ya establecidos. Aprovechando la utilidad de sisotool, porque esto analíticamente no lo sacamos nunca  :mrgreen:

Muy bueno! Podrias subir el codigo completo? Muchas gracias.
Bienvenido msegredo! Revisa en el 3º post esta lo que buscas  :mrgreen:


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Re: Control PID con anti-windup en PIC y CCSRTOS.
« Respuesta #14 en: 30 de Agosto de 2009, 12:39:37 »
Muy bueno Suky, que nivel he, la verdad que te pasaste!
Tenes un 10!  :-/
@fabianjsm is on twitter


 

anything