Control PID del fader del motor

15

Estoy tratando de controlar un fader motorizado (potenciómetro de deslizamiento lineal) usando un Arduino.
El control PID da buenos resultados para "saltar" a una posición de destino específica, pero el seguimiento de las rampas es un problema, no es nada suave. El movimiento es muy desigual, no importa lo que intente.

Aquí hay un gráfico de la posición de referencia, la posición medida y la salida del motor al rastrear una rampa: Seguimiento de una rampa

Y aquí hay un video de esa misma prueba.

En los sistemas comerciales, parece mucho más suave, mira esto .

Detalles :
El fader del motor es un Alps RSA0N11M9A0K . Para conducirlo, estoy usando un puente H ST L293D , alimentado por una fuente de alimentación regulada de 10 V CC ( XL6009 ).
En el Arduino UNO (ATmega328P), estoy usando los pines 9 y 10, con una frecuencia PWM de 31.372 kHz para que sea inaudible (Timer1 con un prescaler de 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001).
El potenciómetro está conectado entre tierra y 5V, con el limpiador yendo a ADC0, como de costumbre.

El controlador :
estoy usando un controlador PID simple con anti-windup, que se actualiza a una velocidad de 1 kHz (Ts = 1e-3 s):

float update(int16_t input) {
  int16_t error = setpoint - input;
  int16_t newIntegral = integral + error;
  float output = k_p * error 
               + k_i * newIntegral * Ts 
               + k_d * (input - previousInput) / Ts;

  if (output > maxOutput)
    output = maxOutput;
  else if (output < -maxOutput)
    output = -maxOutput;
  else
    integral = newIntegral;

  previousInput = input;
  return output;
}

La salida del controlador es un valor de -127 a 127. La salida PWM se genera de la siguiente manera:

const int8_t knee = 48;

uint8_t activation(int8_t val) {
  if (val == 0)
    return 0;
  else {
    return map(val, 0, 127, 2 * knee, 255);
  }
}

void writeMotor(int8_t val) {
  if (val >= 0) {
    analogWrite(forward, activation(val));
    digitalWrite(backward, 0);
  } else {
    analogWrite(backward, activation(-val));
    digitalWrite(forward, 0);
  }
}

Agregué 48 a la señal PWM de 7 bits, porque ahí es donde el motor comienza a moverse a 31 kHz, y luego lo escalo a un número de 8 bits (porque eso es lo que la analogWritefunción espera): Velocidad PWM

Lo que he intentado :
he intentado agregar un filtro EMA a la entrada, a la señal de control, al componente derivado del controlador PID, pero fue en vano. También intenté reducir la resolución de la entrada analógica, usando histéresis para evitar que cambie entre dos valores cuando está parado. Esto no parece afectar nada. Aumentar el paso de tiempo a 10 ms tampoco parece ayudar.

También intenté hacer una identificación del sistema en MATLAB, e intenté ajustarlo en Simulink (siguiendo esta serie de videos ). Obtuve un modelo con un ajuste del 91%, pero no sabía cómo lidiar con las no linealidades de entrada y salida del modelo MATLAB, cómo afectan el ajuste PID y cómo implementarlo en el Arduino.

Lo último que he intentado es hacer dos controladores diferentes: uno para grandes saltos en la posición de referencia y otro para pequeños errores al rastrear una rampa. Esto parece ayudar un poco, porque entonces puedo aumentar el coeficiente integral al rastrear, sin aumentar el sobreimpulso al saltar.
Sin embargo, al aumentar la ganancia integral (y proporcional), el motor ahora siempre está haciendo algo, incluso cuando debe estar parado y la referencia no cambia. (Realmente no se mueve, pero puedes sentirlo vibrar).
Prácticamente no tengo ganancia derivada, porque aumentarlo más alto que 1e-4 parece hacerlo aún más espasmódico, y realmente no noto ninguna diferencia entre 0 y 1e-4.

Supongo que necesita más potencia para superar la fricción estática, entonces la fricción dinámica es menor, por lo que se sobrepasa, por lo que impulsa el motor hacia atrás, haciendo que se detenga nuevamente, luego tiene que superar la fricción estática nuevamente, dispara hacia adelante nuevamente etc.

¿Cómo superan este problema los controladores comerciales?

Mi experiencia :
estoy en mi tercer año de licenciatura en Ingeniería Eléctrica, he seguido cursos sobre teoría de control, procesamiento de señal digital, control LQR, etc., así que tengo algunos antecedentes teóricos, pero tengo problemas para aplicar todas esas teorías a Este sistema del mundo real.


Editar :
he probado las mediciones del sensor de bucle abierto, como recomendó laptop2d, y estoy bastante sorprendido con los resultados: a altas frecuencias PWM, hay picos desagradables en las lecturas. A 490 Hz, no hay ninguno.
Y esto está en un ciclo de trabajo constante, por lo que no puedo imaginar qué tipo de ruido obtengo cuando el motor está invirtiendo la dirección muy rápidamente.

ingrese la descripción de la imagen aquí

Así que tendré que encontrar una manera de filtrar ese ruido antes de comenzar a trabajar en el controlador nuevamente.

Edición 2 : el
uso de un filtro de promedio móvil exponencial no fue suficiente para filtrar el ruido.

EMA

He intentado con polos en 0.25, 0.50 y 0.75. Los postes pequeños no tuvieron mucho efecto, y los postes más grandes agregaron demasiada latencia, por lo que tuve que reducir las ganancias para mantenerlo estable, lo que resultó en un peor rendimiento general.

He agregado un condensador de 0.1 µF a través del potenciómetro (entre el limpiador y la tierra), y eso parece limpiarlo.

Por ahora, funciona lo suficientemente bien. Mientras tanto, estoy leyendo el periódico publicado por Tim Wescott .
Gracias por toda tu ayuda.

tttapa
fuente
¿Puedes controlar 31KHz pwm con precisión?
Hasan alattar
@ Hasanalattar: No, las frecuencias que puedo usar están en el segundo gráfico (preescalador de 1, 8, 64, 256, 1024). Son audibles 4 kHz y 500 Hz, por lo que producen un sonido molesto, que me gustaría evitar. Eso deja 31 kHz, 120 Hz y 30 Hz. Y los dos últimos son demasiado lentos, creo. La resolución PWM es de 8 bits, pero estoy usando menos, porque mi señal de control es de solo 7 bits, y uso solo valores PWM superiores a 96.
tttapa
1
El puente H que vinculó tiene en la página principal de la hoja de datos: This device is suitable for use in switching applications at frequencies up to 5 kHz. Pero las características eléctricas en la página 3 sugieren un máximo absoluto de 690 kHz si suma todos los retrasos. (4 líneas inferiores) Personalmente, iría mucho más lento que eso, pero creo que 31kHz debería ser adecuado ... si no fuera por la nota en la página 1.
AaronD
Sin embargo, eso supone un ciclo de trabajo fijo. (o un "no me importa" ciclo de trabajo para la frecuencia máxima absoluta a "sólo moverla" - se dará cuenta de que es asimétrica) de alta y ciclos de trabajo bajos pueden producir algunos pulsos muy estrechos, por lo que el ancho se los compara con el parte inferior de la página 3?
AaronD
1
No estoy seguro de si es su problema, pero si la marca de tiempo puede variar, entonces creo que debería agregar el error * Ts a la integral, no solo el error, y no multiplicar la integral por Ts. (Si Ts es siempre una constante, entonces no importa)
user253751

Respuestas:

9

Un sistema de control es tan bueno como su sensor, ejecute el circuito abierto del sensor y retire la entrada de control. Cree su propia entrada al sensor y deslícela lentamente (o encuentre una manera de deslizarla lentamente de manera confiable) mientras toma datos de posición para asegurarse de que no sea el sensor. Si el sensor hace ruido, entonces mejore el rendimiento del sensor obteniendo un sensor nuevo o en paralelo, o filtrando la salida del sensor . Es posible que necesite un sensor con mayor resolución.

Si el sensor no es ruidoso, deberá obtener un bucle de control diferente. Los PID son sistemas de primer orden y no son realmente buenos para el control de velocidad.

Pico de voltaje
fuente
Gracias, de hecho, hay mucho ruido con frecuencias PWM más altas, así que tendré que encontrar una manera de mejorar eso. ¿Tienes algún indicador sobre cómo hacer eso?
tttapa
Use un filtro, mecánico o digital. Si no puede hacer eso, tal vez los sensores en paralelo serían buenos. meta.stackexchange.com/questions/126180/…
Pico de voltaje
6

Tiene razón en que el problema es de fricción, o posiblemente una combinación de fricción y reacción. Su diagrama de velocidad promedio vs. ciclo de trabajo para varios anchos de pulso es característico de un sistema con fricción. Este documento explica lo que está viendo y tiene un compendio de soluciones que se han utilizado desde siempre para tratar los problemas. No los habrá visto en su plan de estudios de ingeniería porque son difíciles de analizar; básicamente tienes que jugar con ellos caso por caso para que funcionen.

No sé qué hacen los controladores comerciales, aunque sospecho que hay una variedad de soluciones disponibles. Lo que he hecho en el pasado con cosas como esta es cuando la señal del motor que sale de mi controlador PID cae por debajo de algún umbral (probablemente de 60 a 70 en su caso) Empiezo a pulsar el motor en el umbral, con un deber ciclo que hace que la unidad promedio sea igual a la salida PID. Por lo general, utilizo un modulador sigma-delta-ish para esto porque se puede implementar en muy pocas líneas, pero puede elegir lo que funcione para usted.

TimWescott
fuente
4

Parece que la mayor parte del ruido proviene de la señal de la unidad PWM.

¿Has intentado sincronizar la captura ADC con el ciclo PWM? La mayoría de los microcontroladores tienen una forma de activar la captura de ADC en el temporizador, por lo que siempre puede activar en el mismo punto del ciclo.

Para obtener el ruido más bajo, la posición de muestreo óptima sería justo antes de encender el motor, porque entonces los picos han tenido el mayor tiempo para asentarse. Pero no importa cuál sea la posición, sincronizar la captura reducirá los picos porque la cantidad de desplazamiento permanecerá aproximadamente igual en el mismo punto del ciclo PWM.

jpa
fuente
3

Así que tendré que encontrar una manera de filtrar ese ruido antes de comenzar a trabajar en el controlador nuevamente.

Puede filtrar el ruido del sensor (o cualquier otra medición / variable ruidosa) en código con algo como esto (filtrado de paso bajo):

Sfiltrado[k]=αSfiltrado[k-1]+(1-α)Scrudo[k]

0 0<<α1

Big6
fuente
He intentado eso, pero no es suficiente para deshacerme de los picos, y agrega demasiado retraso.
tttapa
@tttapa ya veo. ¿Qué valor de alfa intentaste? (0.8,0.9) Va a tomar un poco de ajuste, lo que quizás ya hayas hecho, solo preguntándote.
Big6
Actualicé mi publicación original para agregar una gráfica de los filtros EMA que he probado. También probé 0.9, y fue aún peor que el 0.75, las ganancias tienen que ser mucho más bajas debido al retraso. Creo que voy a usar un EMA limitado para limpiar el ruido ADC, pero por ahora el condensador es suficiente.
tttapa