Controller PID Quadcopter per la distanza
Sto cercando di utilizzare un controller PID per fermare un quadricottero in una posizione specifica mentre viaggio orizzontalmente, tuttavia attualmente supera / non supera la velocità massima. Ho provato a regolare manualmente i guadagni P, I e D con successo limitato. Essenzialmente la velocità deve andare da maxSpeed a 0 alla fine del percorso di volo.
Utilizza l'SDK DJI quindi gli ingressi al quadricottero sono molto semplicistici, l'ingresso del passo al quadricottero è in m / se ricalcolo la distanza (m) dal bersaglio ad ogni iterazione.
Eseguo un ciclo che viene eseguito ogni 0,1 di secondo. Alcuni pseudo codice:
kP = 0.25
kI = 0.50
kD = 90
timeStep = 0.1
maxSpeed = 10
currentError = initialDistanceToLocation - currentDistanceToLocation
derivativeError = (currentError - previousError) / timeStep
previousError = currentError
output = kP * currentError + kI * integralError + kD * derivativeError
integralError = integralError + currentError * timeStep
if >= maxSpeed {
output = maxSpeed
} else if output <= 0 {
output = 0
}
return output
C'è un modo per sintonizzare in modo affidabile questo controller PID su questo sistema che funzionerà per velocità massime diverse, o è troppo semplicistico e ci sono altri fattori che devo considerare?
Risposte
Se si desidera lavorare con velocità più elevate, è necessario esaminare anche il controller di velocità. Puoi anche provare a incorporare il controllo della velocità nel tuo sistema di controllo. Consente un arresto regolare del punto che può alleviare il problema. Ma un controller PID generico con solo controllo della posizione non dovrebbe superare troppo il limite se regolato correttamente e le velocità massime non sono troppo alte.
Non so fino a che punto il tuo pseudo-codice possa essere considerato rappresentativo del tuo codice reale, ma posso vedere le seguenti preoccupazioni con esso.
Termine derivato
Nelle applicazioni pratiche, il termine derivato calcolato come differenza finita a un passo come di seguito è completamente inutile:
derivativeError = (currentError - previousError) / timeStep
Le ragioni sono numerose, principalmente legate al fatto che segnali fisici come la distanza misurata dal target sono pesantemente influenzati dal rumore, che a sua volta ha componenti ad alta frequenza che vengono amplificati da questa operazione degradando inevitabilmente il Prestazioni PID e causa di instabilità.
Quindi, dovresti invece ricorrere a tecniche più sofisticate come osservatori di velocità (ad es. Lo stimatore di stato di Kalman) o filtri robusti (ad es. dispositivi costosi però).
Non fatevi prendere dal panico / preoccupatevi, lasciate semplicemente cadere il termine derivato con leggerezza. Ricorda che il 90% dei controllori PID mondiali sono semplicemente PI 😉
Termine integrale
Questa è la parte più problematica. Non è possibile impostare la soglia dell'uscita del controller entro [0, maxSpeed] senza indicare al PID cosa sta succedendo. Non funzionerà semplicemente. In questo modo, infatti, susciterai oscillazioni indesiderate che sono proprio ciò che hai osservato.
Affinché il controller sia a conoscenza dei limiti di attivazione, è necessario fare affidamento su un diagramma anti-windup standard .
Questa è una procedura ben nota in letteratura. Puoi scoprirlo nella Bibbia dei controller PID (par. 3.5), inoltre potresti leggere questa interessante risorsa MATLAB .
In sostanza, è necessario integrare anche la differenza tra l'uscita con soglia e l'uscita pura (vedere l'illustrazione sotto).
integralError += (currentError + thresOutput - sheerOutput) * timeStep
Osservazioni finali
Una volta che avrai giocherellato con tutti i punti sopra, avrai sicuramente più possibilità di ridurre gli over / underhoots. Detto questo, un controller di velocità puro si rivela una sorta di approccio semplicistico. Pertanto, per essere ancora più efficaci e precisi, dovresti eventualmente giocare con il modello dinamico del quadricottero.
Spero che aiuti.