• Robótica

    Tutoriales de modelamiento y control de robots autónomos.
    Robots móviles,brazos robóticos, UAVs y más.

  • Inteligencia Artificial

    Tutoriales de diseño de algoritmos para resolver problemas prácticos.
    Deep Learning, Machine Learning, Algoritmos genéticos y más.

  • Electrónica

    Tutoriales de diseño y programación para resolver problemas prácticos.
    Arduino, PICs, Raspberry PI y más.

Métodos numéricos aplicados a la ingeniería

Introducción 

Este tutorial presenta los métodos numéricos más utilizados en el área de ingeniería. Por ejemplo, en el controlador PID se puede aproximar la acción integral y derivativa utilizando estos métodos. Además, estas técnicas se utilizarán en los siguientes blogs para el modelamiento y control de Robots Autónomos.

Las pruebas se realizaron en Matlab, más detalles en el siguiente video.


Diferenciación numérica 

La diferenciación numérica permite aproximar la derivada de una función. La derivada de una función representa la razón de cambio con respecto al tiempo.

En robótica se requiere medir la razón de cambio de las variables del robot. Por ejemplo la razón de cambio de la posición es la velocidad y la razón de cambio de la velocidad es la aceleración.

La derivada xp puede ser descrita por la pendiente de la recta formada entre las muestras (k-1)T y kT de la función, conocida como diferenciación con un paso atrás (backward difference), tal como muestra la figura 1.


Donde k={0, 1, 2, .....} y T es un intervalo de tiempo constante (tiempo de muestreo). 

Figura 1.  Aproximación de la derivada de una función.

También se puede aproximar la derivada entre las muestras kT y (k+1)T de la función, conocida como diferenciación hacia adelante (forward difference).



Implementación en Matlab

La figura 2 y 3 muestra la diferenciación numérica real, aproximada de una función senoidal.



Figura 2.  Diferenciación con un paso atrás (backward difference) con T=0.1s.

Figura 3.  Diferenciación hacia adelante (forward difference) con T=0.1s.


Integraciónumérica

Considerando que la integral de la aceleración es la velocidad, y la integral de la velocidad es la posición. Es decir, existe una relación entre la integral y la derivada. Por lo tanto se puede considerar que son operaciones inversas. 

Entonces si se considera la diferenciación hacia adelante (forward difference) la integral numérica esta dada por.


Implementación en Matlab

La figura 4 y 5 muestra la integración numérica real, aproximada de una función coseno. La diferenciación numérica permite aproximar la derivada de una función. En la figura 5 se ha disminuido el tiempo de muestreo T a 0.01 segundos resultando una mejor aproximación.



Figura 4.  Integración numérica considerando (forward difference) con T=0.1s.


Figura 5.  Integración numérica considerando (forward difference) con T=0.01s.



Compartir:

Sintonía de controlares PID basada en reglas.

Introducción 

En este tutorial se muestra cómo sintonizar un controlador PID digital en arduino basado en reglas.

Para mas información sobre el algoritmo de control y el código ingresa a mi anterior blog.

PID digital de luminosidad con arduino

La función de transferencia para el controlador PID ISA digital esta dada por


Tiempo de muestreo (T)

El control digital o discreto trabaja en instantes de tiempo predeterminados llamado tiempo de muestreo T. Fundamentalmente T es el tiempo de ejecución del algoritmo de control, normalmente el tiempo de ejecución suele ser mayor que el periodo de muestreo de los conversores A/D. En algunos casos, el periodo de muestreo se diseña para que sea mayor que el tiempo de tiempo de ejecución, cuando las constantes de tiempo del proceso son muy grandes (Planta de temperatura). Sin embargo, un periodo de muestreo alto conlleva una pérdida de la estabilidad relativa del sistema.



Un tiempo de muestreo optimo debe ser menor que el tiempo de establecimiento (te) o tiempo de retardo (tr) del sistema en lazo abierto. En el modelo Ziegler-Nichols se considera T<te/10 T<tr/4.

Acción proporcional (P)

La acción proporcional tiene una implementación directa, multiplica cada muestra de la señal de error actual por un valor de ganancia Kp. Es decir, genera una señal de control que es proporcional a la señal de error.


Figura 1. Respuesta del control P con Kp=0.055.
Figura 2. Respuesta del control P con Kp=0.1.

Figura 3. Respuesta del control P con Kp=0.5.

En base a los resultados el aumento de la ganancia Kp permite reducir el error en estado estacionario. Sin embargo, no permite eliminar el error. Ademas, aumentando la ganancia proporcional disminuye la estabilidad

Acción integral (I)

La función principal de la acción integral es asegurarse de que la salida del proceso Pv coincida con el punto de ajuste deseado Sp en estado estacionario.

Figura 4.  Respuesta del control PI con Kp=0.055 y Ti=0.1.

Figura 5.  Respuesta del control PI con Kp=0.055 y Ti=0.01.


Figura 6.  Respuesta del control PI con Kp=0.055 y Ti=0.001.

Figura 7.  Respuesta del control PI con Kp=0.055 y Ti=0.0001.


En base a los resultados el error decae más rápidamente si se disminuye el tiempo de integración. Sin embargo, disminuyendo demasiado el tiempo de integración disminuye la estabilidad.

Acción de control derivativa (D)

Un controlador con acción derivativa se puede interpretar como si el control se hiciese proporcional a la salida predicha del proceso.


Figura 8.  Respuesta del control PID con Kp=0.064, Ti=0.01 y Td=0.
Figura 9.  Respuesta del control PID con Kp=0.064, Ti=0.01 y Td=0.0095.
Figura 10.  Respuesta del control PID con Kp=0.064, Ti=0.01 y Td=0.01.
Figura 11.  Respuesta del control PID con Kp=0.064, Ti=0.01 y Td=0.08.

En base a los resultados el aumento del tiempo derivativo mejora la estabilidad pero empeora otra vez cuando el tiempo derivativo se hace demasiado grande.

Un control PID correctamente sintonizado es rápido, estable y tiene un error en estado estable que tiende a cero. El objetivo se consigue con Kp=0.03, Ti=0.01 y Td=0.01.


Figura 12.  Respuesta del control PID con Kp=0.03, Ti=0.01 y Td=0.01.

Conclusión

Aumentando la ganancia proporcional disminuye la estabilidad.

El error decae más rápidamente si se disminuye el tiempo de integración. Sin embargo, disminuyendo demasiado el tiempo de integración disminuye la estabilidad.

Aumentando el tiempo derivativo mejora la estabilidad pero empeora otra vez cuando el tiempo derivativo se hace demasiado grande.
Compartir:

PID digital de luminosidad con arduino

Introducción 

Este tutorial muestra cómo implementar un controlador PID digital de luminosidad con arduino. Cabe señalar que más de la mitad de los controladores industriales que se usan hoy en día utilizan esquemas de control PID o PID modificado.
En la siguiente figura se muestra el diagrama de bloques del sistema en lazo cerrado.
Figura 1. Diagrama de bloques del sistema en lazo cerrado.

Donde Sp es el punto de ajuste deseado, Pv es la variable de proceso medida, e es el error (Sp-Pv) y Cv es variable de control.

El control PID implementado es de la forma estándar algunas veces llamado algoritmo ISA, o ideal. 

Figura 2. Diagrama de bloques del control PID ISA .

La función de transferencia en el dominio para el controlador PID ISA digital esta dada por

La señal de control Cv es la suma de tres términos: P (que es proporcional al error), I (que es proporcional a la integral del error), y el término (que es proporcional a la derivada del error). Los parámetros del controlador son la ganancia proporcional Kp, el tiempo integral Ti, el tiempo derivativo Td y el tiempo de muestreo T.

Para implementar el algoritmo de control en el arduino es necesario pasar la ecuación anterior a ecuaciones en diferencias, para esto se utiliza las siguientes propiedades de la transformada Z.


Aplicando las propiedades de la transformada Z se obtiene


Donde e(k) representa el error en el instante actual y e(k-1) el error en el instante anterior.

Hardware requerido

  • 1 Arduino 
  • 1 Led blanco de 5mm 
  • 2 Resistencias de 10k ohm
  • 1 Potenciómetro de 10k ohm
  • 1 Protoboard
  • Cable

Circuito

En la  figura 3 se muestra el esquema de conexión. Para la fuente de luminosidad se utiliza un led ultrabrillante de 5 mm, color blanco en serie con una resistencia de 10k ohm. El pin 6 se utiliza como salida de control (Cv) y para la lectura de la variable de proceso (Pv) se usa una LDR mediante un divisor de voltaje. 

Para variar el punto de ajuste (Sp) se utiliza un potenciómetro de 10k ohm. Para un mayor rango de control colocar el circuito en una caja cerrada como la figura 4.



Figura 3.  Esquema de conexión.

Código

Primero definimos nuestro rango de control aplicando el mínimo Cv (0 ciclo de trabajo PWM al 0%) y máximo Cv (255 ciclo de trabajo 100%y leyendo el valor digital del sensor (0-1023) mediante el siguiente programa.

Rango_de_Control.ino

float sensorValue = 0; 
int PWM=0;  

char cadena[30]; 
byte posicion = 0; 

void setup() 
{
  Serial.begin(9600);   
}
void loop() 
{

  if (Serial.available())
    {
      memset(cadena, 0, sizeof(cadena)); 
      while (Serial.available() > 0) 
      {
        cadena[posicion] = Serial.read(); 
        posicion++;
        delay(10);
      }
      posicion = 0;
      PWM = atoi(cadena); 
    }
  
    sensorValue=analogRead(A0);

    
    analogWrite(6,PWM);


    Serial.print("sensorValue : ");
    Serial.print(sensorValue);
    Serial.print(" PWM : ");
    Serial.println(PWM);
    delay(1000);
}

Ingresar el Cv mediante el monitor serial de Arduino.



Figura 4. Rango de control mínimo (0 PWM ~ 40 valor digital).


Figura 5.  Rango de control máximo (255 PWM ~ 755 valor digital).


A continuación se implementa el algoritmo PID. Para mas detalles del código mira el vídeo.



Control_PID.ino


float Pv = 0; // variable de proceso medida (porcentaje luminosidad)
float Sp= 0; // punto de ajuste deseado (porcentaje luminosidad)
int Cv=0;  // variable manipulada (MV) o variable de control (PWM)
 
float error=0;  //error actual 
float error_1=0; // error anterior 

float Kp=0.05; // ganancia proporcional 
float P=0.0; // término P

float Ti=0.03; // tiempo integral
float I=0.0; // término I

float Td=0.0001; // tiempo derivativo
float D=0.0; // término D

int T=100;    // tiempo de muestreo milisegundos  

// Variables para asegurar tiempo muestreo                      
unsigned long pasado=0;
unsigned long actual;



void setup() 
{
  Serial.begin(9600);   
}
void loop() 
{

 actual=millis(); // milisegundos desde que se inició el programa
  
 unsigned long dt=actual-pasado; 

  if(dt>=T)
  {
    pasado=actual;
    
    Pv=promedio(100,0); // Escalamiento de Pv
    Pv=abs(map(Pv,5,880,0,100));

    Sp=promedio(100,1); // Escalamiento de Pv
    Sp=map(Sp,0,1023,0,100);// Escalamiento de Sp
    
    error = Sp - Pv;  // Cálculo de error                  
        
    P=Kp*error; // término P

    I=I+(Kp/Ti)*error*(T/1000.0); // término I


    D=D=(Kp*Td)*((error-error_1)/(T/1000.0));   // término D

    error_1=error; // error anterior

    Cv=P+I+D; // Control PID
    Cv=constrain(Cv,0,255);// Restricción de acción de control  
    
    analogWrite(6,Cv); 

    Serial.print("Sp : ");
    Serial.print(Sp);
    Serial.print(" Pv : ");
    Serial.print(Pv);
    Serial.print(" Cv : ");
    Serial.println(Cv);

  }
}

float promedio(int numeroLecturas,int sensorPin) 
{
  float aux=0.0;
  for (int conta = 1; conta <=numeroLecturas ; conta++) 
  {
    aux=aux+analogRead(sensorPin); // Escalamiento de Pv
    delayMicroseconds(10);    
  }
  return (aux/numeroLecturas);
}


Resultados

La siguiente figura muestra la respuesta del controlador a varios escalones.


Figura 6.  Respuesta del sistema en lazo cerrado.
Compartir:

Filtro Promedio

Introducción 

Este tutorial muestra cómo implementar un filtro promedio en arduino. El objetivo es suavizar los valores de sensores ruidosos o inestables de una manera fácil.




El filtro promedio está dado por la siguiente fórmula


El resultado es la suma de una cantidad de mediciones, y el total se divide por la cantidad de  mediciones N. Cuantas más mediciones incluyas en el promedio, más ruido se eliminará. Sin embargo, se produce un retardo en la lectura de la señal.

Hardware requerido

  • 1 Arduino 
  • 1 Potenciómetro de 10k ohm
  • 1 Protoboard
  • Cable

Circuito

En la  figura 1 se muestra el esquema de conexión. Conecte un pin de un potenciómetro a 5V, el pin central al pin analógico A0, y el último pin a GND.
Figura 1. Esquema de conexión.

Código

El siguiente código permite calcular  el valor promedio de N muestras mediante la función promedio()

Sintaxis
promedio(N, AnalogInput)

Parámetros

AnalogInput: Entrada analógica

float sensorValue = 0;

void setup() 
{
  Serial.begin(9600);   
}
void loop() 
{
    sensorValue=promedio(100,0);
    Serial.println(sensorValue);
    delay(50);
}

float promedio(int numeroLecturas,int sensorPin) 
{
  float aux=0.0;
  for (int conta = 1; conta <= numeroLecturas ; conta++) 
  {
    aux=aux+analogRead(sensorPin); // Escalamiento de Pv
   delayMicroseconds(10);    
 }
 return (aux/numeroLecturas);
}

Resultados

La figura 2 muestra la medición original y la filtrada para un N=10, debido al pequeño número de mediciones aún existe un ruido considerable.
Figura 2. Resultado del filtro con N=10.
La figura 3 muestra la medición original y la filtrada para un N=100, debido al mayor número de mediciones, el resultado es una señal mas suavizada. Sin embargo, a medida que se incrementa N también lo hace el tiempo de muestreo.
El tiempo de ejecución del filtro es de aproximadamente (N*0.13) milisegundos. Es decir, para un N=100 el tiempo de ejecución 13 milisegundos.
Figura 3. Resultado del filtro con N=100.


Compartir:

Donaciones

Suscribete

SÍGUENOS EN FACEBOOK

Posts Populares

Categorías

Post Recientes