Arduino. ¿Cómo limito el valor de salida de un controlador PID? [cerrado]

1

Tengo el siguiente algoritmo PID que arrebaté de un sitio web cuyo nombre olvidé y necesito limitar la salida para que su valor máximo sea, digamos, 90. ¿Cómo hago eso? Intenté usar la función de mapa de Arduino pero necesito saber el valor máximo de la salida para poder usar eso. Aquí está el código:

//working variables
unsigned long lastTime;
//double Input, Output, Setpoint;
double errSum, lastErr;
double kp, ki, kd;

void Compute()
{
   //How long since we last calculated
   unsigned long now = millis();
   double timeChange = (double)(now - lastTime);

   //Compute all the working error variables
   double error = Input;
   errSum += (error * timeChange);
   double dErr = (error - lastErr) / timeChange;

   //Compute PID Output
   Output = kp * error + ki * errSum + kd * dErr;
   Output = map(Output, 0, 1500,0,90);

   //Remember some variables for next time
   lastErr = error;
   lastTime = now;
}

void SetTunings(double Kp, double Ki, double Kd)
{
   kp = Kp;
   ki = Ki;
   kd = Kd;
}

La llamada de la función de mapa fue agregada por mí como una forma ineficiente de limitar la salida.

Si te ayuda de alguna manera, quiero usarlo para un robot de balanceo pero suceden cosas extrañas cuando el valor de la salida supera los 90 (la función write () de la biblioteca del servo solo acepta valores entre 0 y 180).

Gracias de antemano!

    
pregunta Calin

2 respuestas

3

Puede recortar la salida, como lo sugieren @jippie y @jrtrzeciak o, implementar un enfoque más avanzado como se explica a continuación.

Cuando simplemente se limita la salida, un problema proviene de la parte integral. Cuando alcanza uno de sus límites, el integrador continúa resumiendo las cosas. Y cuando la salida debe regresar dentro del rango permitido, se tarda años en recuperarse porque el valor del acumulador I se convirtió en ENORME. Esto se denomina un enrollamiento integral o un reinicio de reinicio.

Una forma inteligente de lidiar con esto es recompensar lo que habría sido el acumulador I si la salida estuviera en el valor de recorte. Y usted reemplaza su valor acumulador con este nuevo valor. Este enfoque es un tipo de técnica de anulación de reinicio.

Lo más importante aquí es la redacción. Ahora sabe cómo nombrar su problema (liquidación integral) y puede dedicar tiempo a encontrar en la web el sistema de mitigación adecuado que mejor se adapte a su aplicación.

Hay muchos ejemplos. Pero necesitas saber cómo buscarlos ...

Como recurso externo, se proporciona un buen ejemplo (con código) aquí: enlace

    
respondido por el Blup1980
1

Para establecer dinámicamente el máximo, puedes intentar:

//Compute PID Output
Output = kp * error + ki * errSum + kd * dErr;
if (Output > maxOutput)
    maxOutput = Output; 
Output = map(Output, 0, maxOutput, 0, 90);

Inicialice maxOutput a 1500 o cualquiera que sea su conjetura de la salida máxima del PID. Luego, si alguna vez supera eso, se ajustará automáticamente.

    
respondido por el Justin Trzeciak

Lea otras preguntas en las etiquetas