Controllo PID del fader del motore


15

Sto cercando di controllare un fader motorizzato (potenziometro lineare a scorrimento) usando un Arduino.
Il controllo PID fornisce buoni risultati per "saltare" verso una posizione target specifica, ma il monitoraggio delle rampe è un problema, non è affatto regolare. Il movimento è molto a scatti, qualunque cosa io provi.

Ecco un grafico della posizione di riferimento, della posizione misurata e dell'uscita del motore quando si traccia una rampa: Tracciare una rampa

Ed ecco un video di quello stesso test.

Sui sistemi commerciali, sembra molto più fluido, vedi questo .

Dettagli :
il fader del motore è un Alps RSA0N11M9A0K . Per guidarlo, sto usando un H-bridge ST L293D , alimentato da un alimentatore a 10 V CC regolato ( XL6009 ).
Su Arduino UNO (ATmega328P), sto usando i pin 9 e 10, con una frequenza PWM di 31.372 kHz per renderlo impercettibile (Timer1 con un prescaler di 1, TCCR1B = (TCCR1B & 0b11111000) | 0b001).
Il potenziometro è cablato tra terra e 5 V, con il tergicristallo diretto su ADC0, come al solito.

Il controller :
sto usando un semplice controller PID con anti-windup, che si aggiorna ad una frequenza di 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;
}

L'uscita del controller ha un valore compreso tra -127 e 127. L'uscita PWM viene generata come segue:

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);
  }
}

Ho aggiunto 48 al segnale PWM a 7 bit, perché è lì che il motore inizia a muoversi a 31 kHz, quindi lo ridimensiono fino a un numero di 8 bit (perché è quello che la analogWritefunzione si aspetta): PWM velocità

Cosa ho provato :
ho provato ad aggiungere un filtro EMA all'ingresso, al segnale di controllo, al componente derivato del controller PID, ma senza risultati. Ho anche provato ad abbassare la risoluzione dell'ingresso analogico, usando l' isteresi per impedirgli di passare tra due valori quando è fermo. Questo non sembra influenzare nulla. Anche aumentare il tempo a 10 ms non sembra aiutare.

Ho anche provato a fare un'identificazione di sistema in MATLAB e ho provato a sintonizzarla in Simulink (seguendo questa serie di video ). Ho ottenuto un modello con un adattamento del 91%, ma non sapevo come gestire le non linearità di input e output del modello MATLAB, in che modo influiscono sulla regolazione PID e come implementarlo su Arduino.

L'ultima cosa che ho provato è realizzare due controller diversi: uno per i salti di grandi dimensioni nella posizione di riferimento e uno per i piccoli errori durante il tracciamento di una rampa. Questo sembra aiutare un po ', perché poi posso aumentare il coefficiente integrale durante il tracking, senza aumentare il superamento durante il salto.
Tuttavia, aumentando il guadagno integrale (e proporzionale), il motore ora fa sempre qualcosa, anche quando dovrebbe essere fermo e il riferimento non cambia. (Non si muove davvero, ma puoi sentirlo vibrare.)
Non ho praticamente alcun guadagno derivato, perché aumentarlo più in alto di 1e-4 sembra renderlo ancora più nervoso, e non noto davvero alcuna differenza tra 0 e 1e-4.

La mia ipotesi è che abbia bisogno di più potenza per superare l'attrito statico, quindi l'attrito dinamico è minore, quindi si supera, quindi spinge il motore all'indietro, facendolo arrestare di nuovo, quindi deve superare di nuovo l'attrito statico, spara di nuovo in avanti , eccetera.

In che modo i controller commerciali superano questo problema?

Il mio background :
Sono al mio terzo anno di laurea in ingegneria elettrica, ho seguito corsi di teoria del controllo, elaborazione del segnale digitale, controllo LQR ecc. Quindi ho un background teorico, ma ho problemi ad applicare tutte quelle teorie a questo sistema del mondo reale.


Modifica :
ho testato le misurazioni del sensore ad anello aperto, come raccomandato da laptop2d, e sono abbastanza sorpreso dai risultati: ad alte frequenze PWM, ci sono picchi cattivi nelle letture. A 490 Hz, non ce ne sono.
E questo è a un ciclo di lavoro costante, quindi non riesco a immaginare che tipo di rumore ricevo quando il motore inverte la direzione molto rapidamente.

inserisci qui la descrizione dell'immagine

Quindi dovrò trovare un modo per filtrare quel rumore prima di ricominciare a lavorare sul controller.

Modifica 2 : L'
uso di un filtro esponenziale a media mobile non era sufficiente per filtrare il rumore.

EMA

Ho provato con i poli in 0,25, 0,50 e 0,75. I poli piccoli non hanno avuto molto effetto e i poli più grandi hanno aggiunto troppa latenza, quindi ho dovuto ridurre i guadagni per mantenerlo stabile, con conseguente peggioramento delle prestazioni complessive.

Ho aggiunto un condensatore da 0,1 µF attraverso il potenziometro (tra tergicristallo e terra) e questo sembra pulirlo.

Per ora funziona abbastanza bene. Nel frattempo, sto leggendo l' articolo pubblicato da Tim Wescott .
Grazie a tutti per il vostro aiuto.


puoi controllare con precisione 31kHz pwm?
Hasan alattar

@Hasanalattar: No, le frequenze che posso usare sono sul secondo grafico (prescaler di 1, 8, 64, 256, 1024). 4 kHz e 500 Hz sono udibili, quindi producono un fastidioso bip, che vorrei evitare. Ciò lascia 31 kHz, 120 Hz e 30 Hz. E gli ultimi due sono troppo lenti, penso. La risoluzione PWM è di 8 bit, ma sto usando meno, perché il mio segnale di controllo è solo 7 bit e utilizzo solo valori PWM superiori a 96.
tttapa

1
L'H-bridge che hai collegato ha sulla prima pagina del foglio dati: This device is suitable for use in switching applications at frequencies up to 5 kHz. Ma le caratteristiche elettriche a pagina 3 suggeriscono un massimo assoluto di 690kHz se sommi tutti i ritardi. (righe 4 in basso) Personalmente, andrei molto più lentamente di così, ma penso che 31kHz dovrebbe essere adeguato ... se non fosse per la nota a pagina 1.
AaronD

Tuttavia, ciò presuppone un ciclo di lavoro fisso. (o un "non mi interessa" duty cycle per la frequenza massima assoluta a "basta dimenare" - si noterà che è asimmetrica) Alta e cicli di lavoro a basso grado di produrre alcuni impulsi molto stretti, così come a livello sono quelli rispetto al in fondo alla pagina 3?
AaronD

1
Non sono sicuro che sia il tuo problema, ma se il timestamp può variare, penso che dovresti aggiungere l'errore * Ts all'integrale, non solo l'errore, e non moltiplicare l'integrale per Ts. (Se Ts è sempre una costante, non importa)
user253751

Risposte:


9

Un sistema di controllo è valido solo quanto il suo sensore, esegue l'anello aperto del sensore e rimuove l'ingresso di controllo. Crea il tuo input per il sensore e fallo scorrere lentamente (o trova un modo per farlo scorrere lentamente in modo affidabile) mentre acquisisci i dati di posizione per assicurarti che non sia il sensore. Se il sensore è rumoroso, quindi migliorare le prestazioni del sensore ottenendo un nuovo sensore o in parallelo, o filtrando l'uscita del sensore . Potrebbe essere necessario un sensore con una risoluzione più elevata.

Se il sensore non è rumoroso, dovrai ottenere un circuito di controllo diverso. I PID sono sistemi di primo ordine e non sono davvero eccezionali per il controllo dei tassi.


Grazie, c'è davvero molto rumore con frequenze PWM più elevate, quindi dovrò trovare un modo per migliorarlo. Ti capita di avere qualche suggerimento su come farlo?
tttapa,

Utilizzare un filtro, meccanico o digitale. Se non puoi farlo, forse i sensori in parallelo sarebbero buoni. meta.stackexchange.com/questions/126180/…
Voltage Spike

6

Hai ragione nel dire che il problema è dovuto all'attrito, o forse a una combinazione di attrito e contraccolpo. Il diagramma della velocità media rispetto al ciclo di lavoro per varie larghezze di impulso è caratteristico di un sistema con attrito. Questo documento spiega ciò che stai vedendo e ha un compendio di soluzioni che sono state utilizzate da sempre per affrontare i problemi. Non li avrai visti nel tuo curriculum di ingegneria perché sono difficili da analizzare; fondamentalmente devi giocherellare con loro caso per caso per farli funzionare.

Non so cosa facciano i controller commerciali, anche se sospetto che ci siano una varietà di soluzioni là fuori. Quello che ho fatto in passato con cose del genere è quando il segnale di azionamento del motore dal mio controller PID scende al di sotto di una soglia (probabilmente 60 a 70 conteggi nel tuo caso) Comincio a pulsare l'azionamento del motore alla soglia, con un dovere ciclo che rende l'azionamento medio uguale all'uscita PID. In genere uso un modulatore sigma-delta-ish per questo perché può essere implementato in pochissime righe, ma puoi andare con qualsiasi cosa funzioni per te.


4

Sembra che la maggior parte del rumore provenga dal segnale dell'unità PWM.

Hai provato a sincronizzare l'acquisizione ADC con il ciclo PWM? La maggior parte dei microcontrollori ha un modo per innescare l'acquisizione ADC sul timer, quindi puoi sempre innescare nello stesso punto del ciclo.

Per il rumore più basso, la posizione di campionamento ottimale sarebbe quella giusta prima di accendere il motore, perché in questo modo tutti i picchi hanno avuto il tempo più lungo per stabilizzarsi. Indipendentemente dalla posizione, la sincronizzazione dell'acquisizione ridurrà i picchi poiché la quantità di offset rimarrà approssimativamente la stessa nello stesso punto del ciclo PWM.


3

Quindi dovrò trovare un modo per filtrare quel rumore prima di ricominciare a lavorare sul controller.

È possibile filtrare il rumore del sensore (o qualsiasi altra misurazione / variabile rumorosa) nel codice con qualcosa del genere (filtro passa basso):

Sfiltrato[K]=αSfiltrato[K-1]+(1-α)Scrudo[K]

Dove 0<<α1. Più si avvicina a 1, più liscio sarà, ma aggiungerà anche più ritardo, iniziare con un valore di 0,9, ad esempio e vedere come si comporta.


Ci ho provato, ma non è abbastanza per sbarazzarsi delle vette e aggiunge troppo ritardo.
tttapa,

@tttapa vedo. Quale valore per alfa hai provato? (0.8.0.9) Ci vorrà un po 'di accordatura, cosa che potresti aver già fatto, solo chiedendoti.
Big6

Ho aggiornato il mio post originale per aggiungere una trama dei filtri EMA che ho provato. Ho provato anche 0.9, ed è stato anche peggio dello 0,75, i guadagni devono essere molto più bassi a causa del ritardo. Penso che userò un EMA limitato per ripulire il rumore ADC, ma per ora il condensatore è sufficiente.
tttapa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.