Upload
giuseppe-patti
View
220
Download
2
Embed Size (px)
DESCRIPTION
relazione materia univrsitaria
Citation preview
Università degli Studi di CataniaCorso di Laurea in Ingegneria dell’Automazione e Controllo dei Sistemi
Complessi
Controllo di Processi
Sintesi di controllori PID non interi
Anno 2009/210
Di Mauro Gianluca Patti Giuseppe
Saglimbene Silvana
Prof. Ing. A. Gallo
Ing. G. Dongola
Introduzione
Il nostro studio è stato incentrato sullo sviluppo di un algoritmo per la sintesi di
controllori PID di ordine non intero. Nella fattispecie, le nostre attenzioni si sono
dapprima concentrate sul confronto dei tempi di salita, scaturiti da diversi tipi di
controllori di ordine non intero. Si è successivamente sviluppato, in funzione di
parametri caratteristici quali tempo di salita ed errore al regime, un tool software in
Matlab per la sintesi di tali controllori operanti sia su un plant del 1° ordine che su
plant rispecchianti sistemi realmente esistenti.
Calcolo Frazionario
Accanto all’ormai famoso calcolo differenziale, usato per descrivere attraverso delle
equazioni differenziali i più svariati fenomeni naturali, si è sentita l’ esigenza,
scaturita, peraltro, dalla sempre più approfondita conoscenza dei fenomeni fisici, di
introdurre il cosiddetto calcolo frazionario. Tale calcolo nasce, come accennato
poc’anzi, dal fatto che ad un’analisi più approfondita di molti sistemi, come per
esempio quelli riguardanti la trasmissione di calore o linee di trasmissione, vengono
modellati al meglio da modelli di ordine non più intero ma frazionario.
A tale scopo si è quindi sviluppata un’opportuna teoria matematica, che permette di
usare così operatori come la derivata e l’integrale (di ordine frazionario ) ,
indispensabili per l’analisi di tali sistemi.
Cenni teorici . La definizione più comune di un integrale d’ordine non intero positivo q è quella
introdotta da Riemann-Liouville :
dftqdt
tfd qt
q
q
)()(
1)( 1
0
(1.1)
ove Г(.) indica la funzione Gamma di Eulero definita per valori reali positivi della
quantità n-α:
dxexn xn
0
1 (1.2)
Discretizzando:
1
1 )1()()1(
)( k
oj
qqji
q
q
q
jkjkffq
T
t
kfd
(1.1.1)
Sfruttando la proprietà che la derivata è la funzione inversa dell’integrale si può
ricavare, dalla (1.1), la derivata di ordine non intero q considerando un grado
derivativo n (intero) e un grado integrativo α (non intero) tale che n- α sia uguale a q
ottenendo così la (1.3):
dftdt
d
dt
tfd
dt
d
dt
tfd
dt
tfd t
n
n
n
n
n
n
q
q
)()()(
1)()()( 1
0
Si deduce dalla (1.3) che la derivata di ordine non intero q è uguale alla derivata di
ordine intero n dell’integrale di ordine frazionale α definito dalla (1.1).
La relazione (1.3) comunque risulta molto laboriosa da un punto di vista sia analitico
che numerico e quindi poco si addice ad uno sviluppo di tipo digitale. Pertanto risulta
più utile riportare la definizione di derivata di ordine non intero α nota come
relazione di Grunwald-Letnikov:
)(0
1)( jK
K
j
jKT f
jtfD
(1.4)
Dove possiamo indicare
1
11)1(
j
jj C
jjC
(1.5)
Per lo studio dei sistemi di ordine non intero si impiegano modelli matematici
dinamici e, finché l’approssimazione è accettabile, lineari come nel caso classico dei
sistemi di ordine intero seguendo degli algoritmi di approssimazione. I più utilizzati
sono:
approssimazione nel dominio della frequenza;
approssimazione nel dominio del tempo;
metodo inverso;
algoritmo genetico.
Approssimazione nel dominio della frequenza
Il metodo più utilizzato è quello di approssimazione nel dominio della
frequenza. Per approssimare un sistema di ordine non intero viene utilizzata la
somma di tanti sistemi di ordine intero:
1
0
0
11
1 1
( )
Nsz i
im N
s sp p iT
i
H s
(1.6)
Un modo per scegliere la coppia di poli e zeri è basato su una sorta di
algoritmo “riverse best fit” , giungendo al calcolo del primo polo e del primo
zero della funzione H(s) secondo le seguenti relazioni:
)]1(10/[00
20/0
10*
10*my
myT
pz
pp
(1.7)
ove y si ricorda essere il grado di accuratezza dell’errore (o anche detto gap
massimo accettabile in db). Ora non rimane altro che trovare i rimanenti N-1
poli espressi dalle seguenti uguaglianze:
)]1(10/[
10/1
10*
10*my
ii
myii
pz
zp
.
my
NN zp 10/1 10*
(1.8)
giungendo a calcolare quanto vale N . Se si imponesse lo scarto tra poli e zeri
successivi sempre costante e le quantità numeriche 10[y/10(1-m)] = a e 10[y/10m] = b
si otterrebbe:
b
a
n
n
n
n
zp
zp
zp
pz
pz
pz
11
2
0
1
1
1
1
1
0
0
.........
.........
(1.9)
Così facendo, i poli e zeri delle espressioni (1.8), insieme a p0 e z0, possono
essere riscritti secondo la (1.9):
0
0
)(
)(
apabz
pabp
ii
ii
(1.10)
Considerando infine la banda massima segue che:
1
)1(
)log()log()log()1(
)()(
)()(
)log(
)log(
)log(
)log(
1
0max01
0
max
0
max
0
max
0
max
ab
ab
p
Np
N
NN
p
p
INTN
NN
abNabN
abab
pabpab
(1.11)
dove INT sta ad indicare la parte intera del blocco dentro la parentesi quadra.
Figura 1.1 Risposta in frequenza di F(s) = 1/ (s+1)0.3 comparata con la sua approssimazione per tre differenti valori di y
Si può notare infine in Figura 1.1 che, mantenendo costante ωmax = 106, il numero di
poli e il numero di zeri si incrementa al decrescere di y.
2 – PID di ordine non intero
I regolatori PIλDµ di ordine non intero rappresentano un caso più generale dei
regolatori PID interi, essi garantiscono la funzionalità data dai classici
controllori/regolatori di ordine intero, tuttavia aggiungono importanti vantaggi sia per
quanto riguarda la sintonizzazione che il raggiungimento dei requisiti di controllo.
Nei PIλDµ, esattamente come nei controllori di ordine intero, la variabile di controllo
u(t) viene generata dalla somma di tre contributi: azione proporzionale, azione
integrale e azione derivativa.
I coefficienti reali λ e µ stanno ad indicare rispettivamente il grado dell’azione
integrale e il
grado dell’azione derivativa.
Figura 2: Schema a blocchi di un regolatore PIλDµ con λ=µ=1
L’equazione d’uscita di un controllore PIλ Dµ nel dominio del tempo è:
)]()(1
)([)( teDTteDT
teKtu DI
p 2.1
in cui TI è detto tempo integrale mentre TD è detto tempo derivativo.
Considerando i rapporti e , la (2.1) può essere riscritta nella
forma:
)()()()( teDKteDKteKtu DIp
(2.2)
Scegliendo λ=1 e µ=1 si ottiene il classico controllore PID ; con λ=1 e µ=0 si ottiene
un controllore PI ; con λ=0 e µ=1 si ottiene un controllore PD mentre con λ=0 e µ=0
si ottiene semplicemente un guadagno.
Il PSO
La tecnica del Particle Swarm Optimization (PSO) è stata originariamente sviluppata
nel 1995 da uno psico - sociologo di nome James Kennedy e da un ingegnere elettrico
Russel Eberart.
Tale algoritmo rientra nella categoria degli algoritmi evoluzionistici basati su
popolazioni di individui, ma diversamente degli algoritmi genetici, la popolazione
viene aggiornata senza l’utilizzo degli operatori genetici quali il crossover e la
mutazione. Ciò accade perché il PSO nasce dall’ analisi dei meccanismi di
interazione tra gli individui che fanno parte di un branco e che devono raggiungere un
obbiettivo comune come la ricerca del cibo o la semplice convivenza.
Un esempio in tal senso può essere ricercato nello studio delle regole del volo di uno
stormo, da cui si evince come un individuo leghi il suo comportamento a quello
degli altri membri del gruppo. Infatti ,un individuo che nel suo movimento scorge una
fonte di cibo si trova di fronte a due alternative: o allontanarsi dal gruppo per
raggiungerlo (individualismo) o rimanere nel gruppo (socialità). Nel caso in cui più
individui si dirigono verso il cibo, anche altri membri possono cambiare la loro
direzione per sfruttare la stessa fonte di nutrimento e il gruppo, così, cambia
gradualmente direzione verso le zone più promettenti, ovvero l’informazione
gradualmente si propaga a tutti.
Da qui l’analogia con il problema di ottimizzazione , che può essere definito come:
individui: configurazioni di tentativo che si spostano e campionano la funzione
obiettivo in uno spazio reale a N dimensioni (applicazione floating point);
interazione sociale: un individuo trae vantaggio dalle ricerche degli altri dirigendosi
verso la regione del punto migliore globalmente trovato.
Mentre la strategia di ricerca può essere espressa come bilanciamento tra exploration
ed exploitation:
exploration: legato all’individualità del singolo che ricerca la soluzione;
exploitation: legato alla socialità ,ovvero allo sfruttamento dei successi di altri
individui.
Una caratteristica che risulta essere importante nella ricerca e’ legata al concetto di
vicinanza.
Gli individui sono influenzati dalle azioni degli individui ad essi più vicini (sotto-
gruppi) e quindi la circolazione dell’informazione e’ globalmente garantita.
I sotto-gruppi non sono legati alla vicinanza fisica delle configurazioni nello spazio
dei parametri, ma sono definiti a priori e possono tenere in conto di spostamenti
anche notevoli tra gli individui.
Pensando ora ad un’applicazione si intuisce, da quanto detto poc’anzi, che il PSO è
adatto a risolvere con relativa facilità implementativa ed efficienza, problemi
multidimensionali non lineari e non differenziabili come appunto quelli riguardanti la
sintesi di controllori FOPID; in quanto da come si può evincere dalla figura
sottostante
Tale algoritmo, prendendo in ingresso l’errore, riesce a decretare i parametri
necessari per il funzionamento del suddetto controllore.
PSO IN DETTAGLIO Il PSO consiste in uno sciame di particelle che si muovono in uno spazio a D
dimensioni in cui deve essere ottimizzata la funzione di interesse. Ogni particella ha
sia una posizione che una velocità e queste ultime vengono rispettivamente
rappresentate dal vettore posizione Xi=(xi1,xi2,…,xiD) e da quello della velocità
Vi=(vi1,vi2,…,viD), (limitato da un vettore di velocità massima )
Vmax=(vmax1,vmax2,…,vmaxD)). Ogni particella ricorda la propria posizione
migliore grazie all’utilizzo di un vettore Pi=(pi1,pi2,…,piD) (dove i indica l’indice
della particella), mentre il vettore dove vengono conservate le migliori posizioni tra
tutte quelle vicine è rappresentato da Pg=(pg1,pg2,…,pgD).
(9)
(10)
Dove w rappresenta un’inerzia il cui valore decresce linearmente durante una
simulazione da un wmax (0.9) a un wmin (0.4) ; per settare tale parametro
generalmente si usa la seguente equazione:
(11)
Dove itermax rappresenta il max num di iterazioni e iter quello corrente (o
generazione).
Un elevato valore di w facilita l’esplorazione globale (cercando in nuove aree),
mentre un valore più basso facilita l’esplorazione locale, permettendo una ricerca
migliore nell’area locale.
Per quanto riguarda i parametri c1 e c2, chiamati apprendimento cognitivo, sono le
costanti di accelerazione che influenzano la velocità di convergenza di ogni particella
(e spesso sono settati a 2 in accordo con esperimenti già condotti).?
Per finire r1 e r2 sono ,invece ,dei numeri casuali generati nell’intervallo [0,1].
OSS
Nel caso di problemi D-dimensionali, poiché lo spazio delle soluzioni avrà D
dimensioni, ogni particella dovrà avere un vettore di posizione e velocità di D
dimensioni.
Se Vmax è troppo piccolo le particelle potrebbero non esplorare lo spazio ,quindi si
suggerisce di settare Vmax con lo stesso range delle variabili per ogni
dimensione ,cioè vdmax=xdmax
IMPLEMENTAZIONE
Per l’implementazione del PSO
Sia la fitness multidimensionale che vogliamo ottimizzare. Sia n il
numero di particelle , ad ognuna delle quali vengono associati i vettori posizione
, e velocità , . Sia inoltre la migliore posizione
corrente di ogni particella e la migliore posizione globale.
Si inizializzano e per tutte le particelle (i). Una scelta comune è quella
di prendere e per tutte le i e , dove aj,bj
sono i limiti del dominio di ricerca in ogni dimensione, e U rappresenta una
distribuzione uniforme.
e .
Prima della convergenza:
o Per ogni particella :
Creiamo un vettore random , : e f per tutti i
j,considerando per
si aggiornano le velocità delle particelle:
.
Si aggiornano le posizioni delle particelle : .
Si aggiornano le migliori posizioni locali : se ,
.
Si aggiorna la migliore posizione globale: se ,
.
è la soluzione ottima con fitness .
Riassumendo quindi passi principali sono: 1) inizializzare una popolazione di particelle (posizione e velocità) 2) aggiornare le velocità 3) aggiornare le posizioni.
Tutto ciò in pseudo codice diventa
# Initialize the particle positions and their velocities X = lower_limit + (upper_limit - lower_limit) * rand(n_particles, n_dimensions) assert X.shape == (n_particles, n_dimensions) V = zeros(X.shape) # Initialize the global and local fitness to the worst possible fitness_gbest = inf fitness_lbest = fitness_gbest * ones(n_particles) # Loop until convergence, in this example a finite number of iterations chosen for k in range(0, n_iterations):
# evaluate the fitness of each particle fitness_X = evaluate_fitness(X) # Update the local bests and their fitness for I in range(0, n_particles):
if fitness_X[I] < fitness_lbest[I]: fitness_lbest[I] = fitness_X[I]
for J in range(0, n_dimensions): X_lbest[I][J] = X[I][J] # Update the global best and its fitness min_fitness_index = argmin(fitness_X) min_fitness = fitness_X[min_fitness_index]
if min_fitness < fitness_gbest: fitness_gbest = min_fitness X_gbest = X[min_fitness_index,:] # Update the particle velocity and position
for I in range(0, n_particles): for J in range(0, n_dimensions):
R1 = uniform_random_number() R2 = uniform_random_number() V[I][J] = (w*V[I][J] + C1*R1*(X_lbest[I][J] - X[I][J]) + C2*R2*(X_gbest[J] - X[I][J])) X[I][J] = X[I][J] + V[I][J]
Tools Software
I tools software da noi sviluppati, come accennato pocanzi, consentono la sintesi di
controllori PID di ordine frazionario. Il primo, permette un confronto sul tempo di
salita sia a livello grafico che numerico, tra un PID classico, cioè di ordine intero, e
una serie di FOPID (fractional order PID). Il secondo, invece, sfruttando l’algoritmo
evoluzionistico introdotto precedentemente, calcola a partire da un plant del primo
ordine e dal tempo di salita desiderato i parametri caratteristici del nostro FOPID,
come le costanti KP,KI e KD e i coefficienti di integrazione e derivazione. Mentre il
terzo, che non è altro che una rielaborazione del secondo, si occupa della sintesi di
un PID su un plant modellanti un sistema reale.
Confronto tempi di salita dei PID
Come si può notare dalla figura sottostante al fine di determinare il confronto tra i
suddetti PID bisogna impostare diversi parametri quali: il plant, che in questo
studio è del primo ordine, il range di variazione dei PID non interi e i parametri
caratteristici come Kp tempo di campionamento, di assestamento e di salita.
I risultati, come mostrato in fig. ,sono sia in forma numerica ,e in questo caso
mostrano i diversi tempi di salita per ogni variazione dell’ordine del controllore, che
in forma grafica, dove le diverse risposte sono sovrapposte per mettere in risalto la
differenza tra il PID intero (verde) e quello non intero (blu).
Analisi del codice
Analizzando il codice, è possibile rintracciare il fulcro di tutto nel modello simulink ,
che permette di calcolare entrambe le tipologie di PID.
Infatti da quest’ultimo si estrae di volta in volta ,sia il tempo di salita, che la risposta
al gradino del FOPID, che verrà poi rappresentata graficamente.
dim=size(PIDout); dim=dim(1); for i=1:dim valore=PIDout(i,1); if(valore>0.9) break end end %------------------------ %Calcolo del valore a 0.1 (PI_ni) valoreni_min=valore for psi=1:dim valore_min=PIDout(psi,1); if(valore>0.1) break end end
Sintesi del FOPID
Osservando l’interfaccia relativa a questo secondo tool, si nota la presenza di due
aree ben distinte. Nella prima, racchiusa all’interno della sezione “Parametri del PSO”
è possibile settare i parametri dell’algoritmo di ottimizzazione quali: numero di
particelle, iterazioni massime consentite, C1 e C2 . Mentre nella seconda “Parametri
FOPID” ,si setta il tempo di salita desiderato.
Alla convergenza del software i risultati ottenuti sono i guadagni Kp, Ki e Kd ordine
di integrazione e di derivazione.
Analisi del codice
Prima di analizzare in dettaglio i risultati ottenuti è bene introdurre il modo di
operare del codice, presente in questa sezione e le scelte da noi prese per effettuare
questo studio. Infatti ,poiché per il tuning di un PID di ordine frazionario si è scelto
di ricorrere all’algoritmo di ottimizzazione chiamato PSO, è stato necessario
implementare sia una funzione obbiettivo da ottimizzare , sia un criterio di stop che
ci permettesse di ottenere i risultati voluti.
Funzione obbiettivo
La funzione obbiettivo, chiamata FOPI, si occupa di ricalcolare, ogni qualvolta
l’algoritmo PSO lo richieda, dapprima i parametri del FOPID attraverso il blocco
simulink mostrato in fig.
e successivamente il funzionale da minimizzare per ottenere la fitness, attraverso il
codice
TT=(ts_PI_ni-Tsdes)^2; alpha=10;beta=10; out=e*beta+TT*alpha;
Il pso
Per quanto riguarda l’algoritmo, le nostre modifiche rispetto alla versione originale,
sono state incentrate in primis sull’incremento del numero di dimensioni del
problema da trattare
dim = 5; % Dimension of the problem … … R1 = rand(dim, n); % valori random di inizializzazione R2 = rand(dim, n); …
…
current_position = 10*(rand(dim, n)-.5); %posizione inz random velocity = .3*randn(dim, n); %velocità iniz random …
velocity = w *velocity + c1*(R1.*(local_best_position-current_position)) + c2*(R2.*(globl_best_position-current_position));% velo per ogni particella … e successivamente sulla definizione di un criterio che ci permettesse di fermare il
tutto a convergenza avvenuta.
while ( (oout>= 0.2 )&&(iter<bird_setp)) …
….
x=fitness(:,1); [Y,I] = min(xx); CC=current_position(:,I) ; tss = FOPI_test2(abs(CC(1)),abs(CC(2)),abs(CC((3))),coeff1,coeff2,b,k) % controllo del tempo di salita attuale Kp, ki, kd, deriv_ni , interg_ni ,b,k oout=abs(Tsdes-tss) end
Sintesi DEL FOPID su un sistema reale
Quest’ultimo tool che si occupa di effettuare la sintesi di un FOPID per un sistema
realmente esistente non è altro che una rivisitazione del precedente e pertanto gli
unici cambiamenti che si hanno sono concentrati nel codice.
Prima di descriverne il funzionamento è opportuno però introdurre il sistema che si
intende controllare.
Modello
Il plant che verrà controllato è rappresentato da un attuatore creato tramite un
cantilever IPMC (Ionic Polymer Metal Composities).
Tale sistema può essere modellato da due diversi tipi di plant:
uno frazionario
o uno del 6° ordine:
Saranno quindi questi i due plant che verranno usati per la sintesi.
Analisi del codice
Le modifiche principali sono state effettuate sullo schema Simulink ottenendo
per il plant di ordine frazionario:
E per il plant del 6° ordine
Successivamente, si è agito sul funzionale che ora implementa l’ITAE
e =alpha* sum(T*abs(e1)*time);%ITAE %calcolo del funzionale da ottimizzare
Risultati
Confronto PID /FOPID
Le immagini sottostanti si riferiscono al confronto del tempo di salita tra un PI
intero e uno non intero, con il coefficiente di integrazione che varia tra 0.2 e 2.5 e
plant 1/1+2s
Per quanto riguarda i valori numerici e l’andamento che questi ultimi assumono
1/(2s+1)
Kp=10
Lamba Ts PI ni TS PI
0,3 0,29 0.41
0,4 0,31 0,41
0,5 0,33 0,41
0,6 0,34 0,41
0,7 0,36 0,41
0,8 0,38 0,41
0,9 0,39 0,41
1 0,41 0,41
1,1 0,43 0,41
1,2 0,44 0,41
1,3 0,46 0,41
1,4 0,48 0,41
1,5 0,49 0,41
1,6 0,51 0,41
1,7 0,53 0,41
1,8 0,55 0,41
1,9 0,56 0,41
2 0,58 0,41
2,1 0,59 0,41
2,2 0,61 0,41
2,3 0,63 0,41
0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
1 3 5 7 9 11 13 15 17 19 21 23
Serie1
2,4 0,64 0,41
2,5 0,66 0,41
Considerando ora altri casi si ottengono i seguenti risultati:
1/(s+5)
Kp=10
Lamba Ts PI ni TS PI
0,3 0,24 0.46
0,4 0,26 0,46
0,5 0,28 0,46
0,6 0,3 0,46
0,7 0,33 0,46
0,8 0,36 0,46
0,9 0,4 0,46
1 0,45 0,46
1,1 0,49 0,46
1,2 0,53 0,46
1,3 0,58 0,46
1,4 0,62 0,46
1,5 0,66 0,46
1,6 0,71 0,46
1,7 0,75 0,46
1,8 0,79 0,46
1,9 0,84 0,46
2 0,88 0,46
2,1 0,92 0,46
2,2 0,96 0,46
2,3 1,01 0,46
2,4 1,05 0,46
2,5 1,09 0,46
1/(s+3)
Kp=10
Lamba Ts PI ni TS PI
0,3 0,23 0.36
0,4 0,24 0,36
0,5 0,26 0,36
0,6 0,27 0,36
0,7 0,29 0,36
0,8 0,31 0,36
0,9 0,33 0,36
1 0,35 0,36
1,1 0,38 0,36
1,2 0,41 0,36
1,3 0,44 0,36
0
0,1
0,2
0,3
0,4
0,5
0,6
0,7
0,8
0,9
1
1 3 5 7 9 11 13 15 17 19 21 23
Serie1
0
0,2
0,4
0,6
0,8
1
1,2
1 3 5 7 9 11 13 15 17 19 21 23
Serie1
1,4 0,47 0,36
1,5 0,51 0,36
1,6 0,55 0,36
1,7 0,59 0,36
1,8 0,63 0,36
1,9 0,68 0,36
2 0,72 0,36
2,1 0,76 0,36
2,2 0,81 0,36
2,3 0,85 0,36
2,4 0,89 0,36
2,5 0,93 0,36
Valori ottenuti con il FOPID su un plant del 1° ordine
I risultati ottenuti da questa sezione, considerando 100 particelle C1 = C2 =1.2 sono
presentati dalla seguente tabella
1/(s+2) 1/(s+2) 1/(s+2) 1/(s+2) 1/(s+5)
Coeff1(Derivatore) 0,5 0,7 0,5 0,7 0,5
Coeff2(Integratore) 0,5 0,5 0,7 0,7 0,5
Ts Desiderato 1,50 1,5 1,5 1,5 1,5
Ts Ottenuto 1,3 1,4 1,3 1,4 1,5
Kp 2,3755 5,26 6,53 3,67 14,97
Ki 12,32 12,69 12,65 5,35 31,85
Kd 3,27 2,7 2,85 0,48 6,87
1/(s+5) 1/(s+5) 1/(s+5) 1/(s+5) 1/(s+5)
Coeff1(Derivatore) 0,5 0,7 0,7 0,7 0,7
Coeff2(Integratore) 0,7 0,5 0,7 1,1 1,2
Ts Desiderato 1,5 1,5 1,5 1,5 1,5
Ts Ottenuto 1,3 1,4 1,3 1,5 1,4
Kp 21,99 11,34 25,08 6,03 1,32
Ki 30,85 30,98 23,02 13,63 10,39
Kd 4,24 2,82 1,31 0,425 0,44
Risutati ottenuti applicando il FOPID all’attuatore IPMC
Prima di analizzare i risultati ottenuti è bene fare alcune precisazioni. Infatti analizzando il
plant del 6° ordine si è visto che presenta dei poli instabili
Ciò significa che per poter provare a controllarlo bisogna portare quei poli nel
semipiano sinistro.
Si è pensato allora, avendo effettuato delle analisi perlopiù qualitative, che un PID
con un’azione derivativa al cubo possa migliorare la situazione
Ragion per cui le nostre analisi, nel caso del plant di 6° ordine si sono limitate ad
impostare il valore dell’integratore uguale ad uno e far variare quello del derivatore
tra uno e tre
Da come si evince osservando i risultati ottenuti non è stato possibile controllare
questo sistema
Plant frazionario
Mentre per il plant di ordine frazionario osservando il luogo delle radici
Si è scelto come range di variazione quello tradizionale ottenendo:
Da come si può notare solo per i valori di integrazione e derivazione di 0.5 si è avuta
la convergenza
Appendice
Prima sezione File PI_ni.m
function pushbutton1_Callback(hObject, eventdata, handles) global Tr Ts x0 global coeff1 coeff2 T cc y1 H Kp Kd Ki ts_PI_ni_strr=zeros(2,1); ts_PI_strr=zeros(2,1); tt=1; k=str2num(get(handles.edit1,'string')); b=str2num(get(handles.edit2,'string')); T=str2num(get(handles.edit3,'string')); coeff2=str2num(get(handles.edit4,'string')); % coefficiente di integrazione iniziale Kp=str2num(get(handles.edit5,'string')); Ts=str2num(get(handles.edit6,'string')); Tr=str2num(get(handles.edit7,'string')); time=str2num(get(handles.edit8,'string')); coeff2_final=str2num(get(handles.edit9,'string')); % coefficiente di integrazione finale ax= axes('position',[.45 .3 .5 .4]) s=('C:\PID_NI\val.txt'); filem=fopen(s,'w'); nuovo_indice=1; for ind=coeff2:0.1:coeff2_final set(handles.text12,'string',ind) coeff2=ind x0=[1,1]; optionss=optimset('Display','iter'); % Option to display output [x,fval] = fsolve(@myfun,x0,optionss) % Call optimizer zet=real(x(2)) omega=real(x(1)) if((zet>0) && (zet<=1)) Kd=(Kp+k-2*b*zet*omega)/(2*zet*omega); Ki=(Kd+b)*omega^2; options = simset('SrcWorkspace','current');
sim('feedback_mar',time,options) % manda in simulazione il blocco simulik cosi prima inizializziamo e poi simuliamo else disp (st) end if ((PIDout((Ts/T)+50)<1.1) && (PIDout((Ts/T)+50)>0.9) && (PIDout((tout(1000))*1/T)>0.9) && (PIDout((tout(1000))*1/T)<1.1)) set(handles.text11,'string','SODDISFA LE SPECIFICHE'); else set(handles.text11,'string','NON SODDISFA LE SPECIFICHE'); end dim=size(PIDout); dim=dim(1); for i=1:dim valore=PIDout(i,1); if(valore>0.9) break end end valoreni_min=valore for psi=1:dim valore_min=PIDout(psi,1); if(valore>0.1) break end end indice_min=psi; valoreni=valore; ts_PI_ni=(i-psi)*T ts_PI_ni_vett(nuovo_indice)=ts_PI_ni; nuovo_indice=1+nuovo_indice; valore_ni=0; for i=1:dim valore=PIDout(i,3); if(valore>0.9) break end end %------ valoreni_min=valore for eta=1:dim valore_min=PIDout(eta,3); if(valore>0.1) break end end indice_minpi=eta;
%------- valore_i=valore; ts_PI=(i-indice_minpi)*T indice=num2str(ind); fprintf(filem,indice); fprintf(filem,' ts_PI_ni=') ts_PI_ni_str=num2str(ts_PI_ni); ts_PI_ni_strr(tt)=ts_PI_ni; indd(tt)=ind; fprintf(filem,ts_PI_ni_str) fprintf(filem,' ts_PI='); ts_PI_str=num2str(ts_PI); ts_PI_strr(tt)=ts_PI; fprintf(filem,ts_PI_str); fprintf(filem,'\n'); hold off x=1:1:4004; %newFig=figure plot(x,PIDout(:,1),'b') hold on plot(x,PIDout(:,2),'r') plot(x,PIDout(:,3),'g') carat=num2str(ind); c=('immagine'); d=('.jpg'); nomeim=strcat(c,carat,d); newFig =figure; axesObject2 = copyobj(ax,newFig); set(axesObject2,'Position',[.1 .1 .8 .8]); set(newFig,'Position',[15 10 30 10]); saveas(gcf,nomeim); close(newFig) tt=tt+1; end hold off coeff3=coeff2:0.1:1.2; nomeim1=('andamento.jpg');
set(handles.text16,'string',ts_PI_ni_strr); set(handles.text17,'string',ts_PI_strr); set(handles.text18,'string',indd); plot(indd,ts_PI_ni_strr,'r') %procedura di salvataggio del grafico che compare nella GUI newFig =figure; axesObject2 = copyobj(ax,newFig); set(axesObject2,'Position',[.1 .1 .8 .8]); set(newFig,'Position',[15 10 30 10]); saveas(gcf,nomeim1); close(newFig)
simulink
Seconda parte
File PI_niott.m function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) %clear clc global k b coeff2 Tsdes coeff1 T coeff2=str2num(get(handles.edit2,'string')); % coefficiente di integrazione Tsdes=str2num(get(handles.edit1,'string')); % tempo si salita desiderato k=str2num(get(handles.edit4,'string')); b=str2num(get(handles.edit5,'string')); n=str2num(get(handles.edit3,'string')); %numero di particelle bird_setp=str2num(get(handles.edit6,'string')); % massimo numero di iterazioni c1=str2num(get(handles.edit8,'string')); % parametri del PSO c2=str2num(get(handles.edit7,'string')); coeff1=str2num(get(handles.edit10,'string')); % coefficiente di derivazione %% inizializzazione dell'algoritmo T=0.1; oout=0.3; dim = 3; % Dimensione del problema da ottimizzare w =0.9; % inerzia fitness=0*ones(n,bird_setp); % inizializzazione dei parametri R1 = rand(dim, n); %creo dei vettori di numeri random dimesione uguale a quella del problema R2 = rand(dim, n); current_fitness =0*ones(n,1); %ogni particella assegno una fitness che inizialmente sara uguale a zero %Inizializzazione di posizione e velocità delle particelle
current_position = 10*(rand(dim, n)-.5); %per ogni particella inizializzo in manienra random le posizioni velocity = .3*randn(dim, n); % stessa cosa per la velocità local_best_position = current_position; % rinomino la posizione iniziale come la posizione locale mgliore for i = 1:n % per ogni particella calcolo la fitness trovando la current fitness e inserendola nel vettore current_fitness(i) = FOPI(current_position(:,i)) ; current_position(:,i); end local_best_fitness = current_fitness; % copio tutto nel vettore local best... [global_best_fitness,g] = min(local_best_fitness); % trovo il minimo e la sua posizione global_best_fitness; for i=1:n globl_best_position(:,i) = local_best_position(:,g); %trovo la posizione della particella che mi ha fornito il min e la inserisco in glob.. end velocity = w *velocity + c1*(R1.*(local_best_position-current_position)) + c2*(R2.*(globl_best_position-current_position));% do una vel per ogni part %aggiornamento della posizione con la velocità current_position = current_position + velocity ; %% Main Loop iter = 0 ; % contatore per le iterazioni while ( (oout>= 0.2 )&&(iter<bird_setp))% il ciclo si ferma o se la differenza con il tempo di salita desiderato è di %0.2 oppure dopo 50 iterazioni iter = iter + 1 iiter=num2str(iter); for i = 1:n current_fitness(i) = FOPI(current_position(:,i)) ; % ricalcolo della fitness per ogni particella dalla funz da ottim end for i = 1 : n %controllo se la local_best_fitness é > della current fitness, in tal caso ne prende il posto
if current_fitness(i) < local_best_fitness(i) local_best_fitness(i) = current_fitness(i); local_best_position(:,i) = current_position(:,i) ; end end [current_global_best_fitness,g] = min(local_best_fitness); if current_global_best_fitness < global_best_fitness global_best_fitness = current_global_best_fitness; for i=1:n globl_best_position(:,i) = local_best_position(:,g); end end % calcolo della velocità e posizione velocity = w *velocity + c1*(R1.*(local_best_position-current_position)) + c2*(R2.*(globl_best_position-current_position)); current_position = current_position + velocity; %calolo del criterio xx=fitness(:,1); [Y,I] = min(xx); CC=current_position(:,I) ; % calcolo del tempo di salita attuale tss = FOPI_test2(abs(CC(1)),abs(CC(2)),abs(CC((3))),coeff1,coeff2,b,k) %kp,ki,kd,deriv_ni,interg_ni,b,k oout=abs(Tsdes-tss) end kkp=num2str(abs(CC(1))) kki=num2str(abs(CC(2))) kkd=num2str(abs(CC(3))) beep ts=num2str(tss); set(handles.text8,'string',iiter); set(handles.text13,'string',ts); set(handles.text5,'string',kkp); set(handles.text6,'string',kki); set(handles.text20,'string',kkd);
File FOPI.m function [out] = FOPI(pid) Kp = pid(1); Ki = pid(2); Kd=pid(3); global T coeff2 k b Tsdes coeff1 b; k; Tsdes; T=0.1; coeff1; coeff2; % richiamo del modello simulink dove è implementato il FOPID time=40; options = simset('SrcWorkspace','current'); %options = simset('solver','ode5','SrcWorkspace','Current','DstWorkspace','Current','AbsTol',1e-100); sim('feedback_martest',time,options); % manda in simulazione il blocco simulik cosi prima inizializziamo e poi simuliamo % calcolo del Tempo di salita dim=size(PIDout); dim1=size(PIDout); dim=dim(1); for i=1:dim valore=PIDout(i,1); if(valore>0.9) break end end for psi=1:dim valore_min=PIDout(psi,1); if(valore>0.1) break end end %tempo di salita ts_PI_ni=(i-psi)*T; %calcolo del funzionale da ottimizzare TT=(ts_PI_ni-Tsdes)^2; alpha=10;beta=10; out=e*beta+TT*alpha;
modello simulink feedback_martest
File FOPI_test2.m function [ts_PI_ni] = FOPI_test2(Kp,Ki,Kd,coeff1,coeff2,b,k) T=0.1; coeff2; coeff1; Kd; Kp; Ki; %calcolo del tempo di salita attraverso il simulink time=40; options = simset('SrcWorkspace','current'); sim('feedback_martest2',time,options) % manda in simulazione il blocco simulik cosi prima inizializziamo e poi simuliamo
nuovo_indice=1; dim=size(PIDout); dim=dim(1); for i=1:dim valore=PIDout(i,1); if(valore>0.9) break end end %------------------------ %Calcolo del valore a 0.1 (PI_ni) valoreni_min=valore; for psi=1:dim valore_min=PIDout(psi,1); if(valore>0.1) break end end indice_min=psi; %------------------------ %Calcolo del valore a 0.9 valoreni=valore; ts_PI_ni=(i-psi)*T; ts_PI_ni_vett(nuovo_indice)=ts_PI_ni; nuovo_indice=1+nuovo_indice; valore_ni=0; for i=1:dim valore=PIDout(i,2); if(valore>0.9) break end end %plotting della risposta x=1:1:dim; plot(x,PIDout(:,1),'g')
modello simulink feedback_martest2
File myfun.m function F = myfun(x) global Ts Tr F = [x(1)*(sqrt(1-x(2)^2))*Tr-pi+atan((sqrt(1-x(2)^2)/x(2))); (Ts*x(2)*x(1)-4)]; end
File Calc_I_G.m
function Int = Calc_I(f) global coeff2 T H; coeff2; T; H; sigma = coeff2; h =round(f(1)/T); %il fix permette di prendere la parte intera del singolo campione f %visto che un ingresso è la rampa avrò k=1, k=2 ...... k=n. In questo modo %capisco quale campione è entrato: si ricordi che questa funzione è richiamata %ogni qual volta si riceve una coppia di valori. H(h+1)=h; global x % questa definizione permette di salvare il contenuto di y in % memoria perchè ad ogni chiamata della funzione sono necessari i valori % precedentemente salvati. %adesso salvo la prima coppia di valori x(1) = 0; x(h+1) = f(2); % il campione relativo al segnale c = 0; for j=0:h-1;
a = x(j+1)+x(j+2); b = (h-j)^sigma - (h-j-1)^sigma; c = c + 0.5*a*b; end Int = (((T)^sigma)/gamma(sigma+1))*c;
File Calc_D_Petras_G.m
function Der = Calc_D_Petras_G(h) % la funzione richiede in ingresso il vettore h % h rappresenta il segnale di ingresso da derivare % % definizione parametri globali : % % - coeff = ordine della derivata (non intero) % - T = intervallo di campionamento % - cc = vettore degli ingressi % - y1 = vettore delle uscite global coeff1 T cc y1; T; cc; y1; coeff1; lambda = coeff1; % k= arrotondamento di h(1)/T , dove h(1) è il primo valore del vettore di % ingresso che passiamo alla funzione (rampa) % k numero di campioni k = round(h(1)/T); % s = minimo tra k e 1/T s=min(k,(T^-1)); % il primo valore dell'uscita è posto pari a zero y1(1) =0; % il valore k+1 dell'uscita è posto pari ad h(2) % è uguale ad h(2) y1(k+1) = h(2); % inizializzazione di c a zero c = 0; % primo valore degli ingressi è posto pari a 1 cc(1)=1; % il valore k+1 degli ingressi è pari a cc(j+1)=cc(j)*( cc(k+1)=cc(k)*(1-(1+lambda)/(k));
for j=0:k; c=c+cc(j+1)*y1(k-j+1); end % for j=1:k; % % cc(j+1)=cc(j)*(1-(1+lambda)/(j)); % c=c+cc(j+1)*y1(k-j+1); % end Der=(T^(-lambda))*c;