Implementando una banda muerta en un controlador PID para un motor de CC

0

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.

    
pregunta M_Luis

2 respuestas

1

Es un hecho común que un sistema de transmisión tiene una frecuencia de resonancia debido al momento de inercia y la elasticidad de la transmisión. Si tiene una ganancia alta de bucle cerrado, el sistema siempre está "nervioso" en espera de una acción dinámica. Para superar este pequeño problema de oscilaciones en un equipo profesional, configure los filtros de muesca para eliminar esta frecuencia de resonancia. Esto se hace inyectando señales y dibujando el diagrama de Bode. Puede agregar un filtro de paso bajo, pero perderá la dinámica o podría disminuir la ganancia.

Introducir la banda muerta significa introducir la no linealidad en el sistema. Quizás haya mejores soluciones en lugar de una banda muerta para el control de la unidad.

Los controladores de unidad profesionales que he usado tienen una adaptación de Kp y Ti con respecto al valor de entrada. En error bajo, el Kp es bajo y Ti es ligeramente más alto. Esto podría ser también un camino a seguir.

Porejemplo,haceselabs()enlaentradayluegohacesunafunciónlinealconunKpmínimoenelerrordeentradabajoyKpnominalenelerrordeentradaalto.

Detodosmodos,sideseaunabandamuerta,yatieneunafórmulaenelartículo(29)y(30)queproporcionalanuevaentradatransformadacomosemuestraenlafigura16.    

Continuará ...

    
respondido por el Marko Buršič
0

siguiendo ese artículo y su código, parece que la respuesta de Marko es la dirección correcta, y está cerca de su código.

Si observa el diagrama de bloques en el artículo y lo aplica a su fórmula en su código, es relativamente sencillo.

puedeverquelosvaloresIyDsiempreseaplican,laúnicapartequeseajustaescuandoseaplicaelvalorP.

Entonces,tubandamuertaessolounrangodondeerrosemantendráencero.

deadband = <deadband value>; //choose your deadband size if (abs(erro) <= deadband) { erro = 0; }

y eso debería ser.

Eso sí, me gradué recientemente, pero mi clase de controles está fresca en la memoria, así que espero que esté viendo esto correctamente.

    
respondido por el Ticktok

Lea otras preguntas en las etiquetas