He estado construyendo un sistema para controlar la posición del motor con un microcontrolador. Pero tuve algunos problemas durante la implementación del controlador PID y lo descubrí gracias a este artículo: enlace Que el problema es la fricción. La siguiente imagen muestra la respuesta de mi sistema utilizando un controlador PI:
Donde la línea naranja es la variable de salida PID y la línea azul es el ángulo del eje del motor (lo que quiero controlar). Si compara esta imagen con la figura 12 en la página 12 del artículo publicado anteriormente, podemos concluir que la fricción es el problema. También en el mismo artículo, una de las soluciones proporcionadas es aplicar una banda muerta al controlador, pero tengo algunas dificultades para entender cómo implementarlo. Si el código de mi controlador PID es:
angulo = (encoder*360)/(4*102.0);
erro = setpoint - angulo;
d_term = kd*((erro - erro_ant)/0.00125);
i_term = i_term + ki*(0.00125*erro);
output = kp*erro + d_term + i_term;
erro_ant = erro;
if ( output >= 0 )
{
direcao(1);
setPWM(fabsf(output));
}
if ( output < 0 )
{
direcao(0);
setPWM(fabsf(output));
}
La función direcao () cambiará los pines del puente h para hacer que el motor gire en la dirección correcta. Y lo que luché para hacer fue:
...
erro_ant = erro;
if (error is within deadband)
{
setPWM(0);
}
else
{
if ( output >= 0 )
{
direcao(1);
setPWM(fabsf(output));
}
if ( output < 0 )
{
direcao(0);
setPWM(fabsf(output));
}
}
o
...
erro_ant = erro;
if (error is within deadband)
{
output = 0;
}
if ( output >= 0 )
{
direcao(1);
setPWM(fabsf(output));
}
if ( output < 0 )
{
direcao(0);
setPWM(fabsf(output));
}
También luché por establecer el término integral en cero, cuando está dentro de la banda muerta, pero eso actuará como una técnica anti-windup cuando se sobrepase el sistema.
Gracias de antemano a cualquiera que responda.