PID Run Away Motor Control

2

Tengo un PID que controla un motor de CC. Estoy intentando controlar la velocidad del motor con mucha precisión. Mi controlador me permite cambiar la dirección del motor y darle un pwm para la velocidad. Por lo tanto, tengo un PID que tiene un máximo y un mínimo de más y menos. Con el fin de acelerar el dispositivo y ralentizar el dispositivo lo suficientemente rápido. La salida del PID es para el pwm y, por lo tanto, es un valor absoluto del PID, simplemente cambiando un pin de dirección cuando PID < 0. Estoy usando la dirección opuesta del motor solo como sistema de frenado. Por lo tanto, el motor siempre debe ir en una dirección, pero debe desacelerarse más rápido al aplicar un par de reversa.

Estoy escribiendo firmware C en MCUXpresso. Los gráficos provienen del envío de datos a través de UART a un Arduino para graficar datos fácilmente.

Mi problema es que, a veces, cuando la variable de proceso llega a 0 o cerca de ella, el PID se invierte y necesita ser negativo, por lo que hace girar el motor a toda velocidad en la dirección opuesta. Las dos imágenes a continuación muestran los casos concretos de cuando sucedió. La línea roja es el punto de ajuste y la línea azul es la variable de proceso.

El código que controla el dispositivo y el PID está debajo.

Me cuesta entender por qué el PID se escaparía de esta manera. Cualquier ayuda sería increíble. ¡Gracias!

Control principal

int dir = FORWARD; //Controls direction of motor

motorPID.setpoint = vehicleSpeed;

motorPID.input = SM_GetRPM();

motorPID.input = motorPID.input * speedConversion;

UART_SendPID((uint8_t)motorPID.input, (uint8_t)motorPID.setpoint);

PID_Compute(&motorPID);

if(motorPID.output < 0){
    dir = BACKWARD;
}

if(motorPID.setpoint == 0){
    motorPID.output = 0;
}

if(motorPID.input > 60){
    MC_SetMotorSpeed(0, dir);
    int test = 0;
}

MC_SetMotorSpeed(abs(motorPID.output),dir);

Código PID

//Find all error variables
self->lastError = self->error;
double input = self->input;                         //Only so input can't change during compute
self->error = self->setpoint - input;
self->integral += self->error;
double derivative = self->error - self->lastError;

//Anti-integral Windup
if(self->integral > self->Outmax)
    self->integral = self->Outmax;
else if(self->integral < self->Outmin)
    self->integral = self->Outmin;

//Calculate PID
self->output = (self->Kp*self->error) + (self->Ki * self->integral) + (self->Kd * derivative);

//Set limits
if(self->output > self->Outmax)
    self->output = self->Outmax;
else if(self->output < self->Outmin)
    self->output = self->Outmin;

EDITAR: Resulta que esto fue un error combinado del problema descrito y un problema de hardware.

    
pregunta Drew Fowler

2 respuestas

1

Intenta cambiar la línea que dice

self->integral += self->error;

a

self->integral += self-> Ki * self->error;

y coteja eso cambiando la línea que dice

self->output = (self->Kp*self->error) + (self->Ki * self->integral) + (self->Kd * derivative);

a

self->output = (self->Kp*self->error) + self->integral + (self->Kd * derivative);

Eso escalará el término integral correctamente para el paso de limitación de su integrador.

    
respondido por el TimWescott
0

a juzgar por sus gráficos, no creo que esté realizando una muestra a una velocidad lo suficientemente alta para lograr estabilidad ... Sin embargo, esta puede ser la limitación del arduino, ya que no estoy familiarizado con el MCUExpresso.

Idealmente, debería tener una descripción matemática de su sistema, de modo que tenga una función de transferencia, luego puede leer su ancho de banda de la función de transferencia. Este ancho de banda también es la frecuencia de Nyquist, que es la frecuencia mínima "aceptable" (usando esa palabra de manera holgada) para muestrear una señal. Normalmente, usted desea muestrear alrededor de 30-40 veces la frecuencia de Nyquist. Si esto no fuera posible, sugiero cambiar los sensores.

Encontré problemas similares el semestre pasado en la uni en mi proyecto, ¡espero que esto ayude!

    
respondido por el Thefoilist

Lea otras preguntas en las etiquetas