• Non ci sono risultati.

Codice del software sviluppato.

N/A
N/A
Protected

Academic year: 2021

Condividi "Codice del software sviluppato. "

Copied!
15
0
0

Testo completo

(1)

APPENDICE A

Codice del software sviluppato.

Funzione step1.

function [Dphi,Dy,THETA] = step1 (y,m,n)

% function [Dphi,Dy,THETA] = step1 (y,m,n)

%

% Identificazione della non linearità di uscita

% per un sistema Hammerstein-Wiener.

% y contiene le uscite campionate con periodo h/2,

% m e il grado dell'approssimazione polinomiale

% dell'inversa della non linearità di uscita,

% n è l'ordine della G(z).

% Vengono restituiti la matrice ed il vettore

% dei termini noti del sistema lineare (Dphi,Dy)

% e la sua soluzione (THETA)

% conto per quanti periodi di campionamento T ho misurato la y steps = ceil(length(y)/(2*(n+1)));

Dy=[];

% costruisco il vettore DELTAy for i=1:(steps-1)

% y[l*T] - y[l*T - h] cioè

% y[l*(n+1)*h] - y[l*(n+1)*h - h]

Dy=[Dy;y(2*(n+1)*i+1)-y(2*(n+1)*i-1)];

end Dphi=[];

for i=1:(steps-1)

% se voglio calcolare phi1[k*h], tmpy conterrà % la y da k*h-n*h a k*h; in questo modo

% fornisco a buildphi tutte e sole le misure % dell'uscita che le servono.

(2)

tmpy=[];

% calcolo phi1[l*T]

for j=1:(n+1)

tmpy = [tmpy;y(2*(n+1)*i+1-2*(j-1))];

end

phi1 = buildphi(tmpy,m,n);

tmpy=[];

% calcolo phi1[l*T-h]

for j=1:(n+1)

tmpy = [tmpy;y(2*(n+1)*i-1-2*(j-1))];

end

phi2 = buildphi(tmpy,m,n);

% calcolo DELTAphi1[l]

Dphi = [Dphi;phi1-phi2];

end

% calcolo theta1 risolvendo il sistema lineare THETA = Dphi\Dy

(3)

Funzione buildphi.

function [phi] = buildphi (y,m,n)

% function [phi] = buildphi (y,m,n)

%

% Costruisce il vettore riga phi1[k*h].

% y contiene le misure dell'uscite a partire

% dall'istante k*h (primo elemento) a k*h-n*h

% (ultimo elemento).

% m e il grado dell'approssimazione polinomiale

% dell'inversa della non linearità di uscita,

% n è l'ordine della G(z).

% Viene restituito il vettore phi1 completo.

phi=[];

% costruisco i primi m-1 elementi del vettore:

% [-y^2[kh],...,-y^m[kh]]

for i=2:m

phi = [phi,-y(1)^i];

end

% costruisco i successivi m*n elementi del vettore:

% [y[(k-1)h],...,y[(k-n)h],...,y^m[(k-1)h],...,y^m[(k-n)h]]

for i=1:m for j=1:n

phi = [phi,y(j+1)^i];

end end

(4)

Funzione find_r_alpha.

function [r,alpha] = find_r_alpha (theta,m,n)

% function [r,alpha] = find_r_alpha (theta,m,n)

%

% Calcola i gli r_i e gli alpha_i a partire da theta1.

% theta è il vettore theta1 calcolato dalla funzione "bai",

% m e il grado dell'approssimazione polinomiale

% dell'inversa della non linearità di uscita,

% n è l'ordine della G(z).

% Viene restituito un vettore contenente i coefficienti

% dell'inversa della non linearità sull'uscita,

% da quello di primo grado a quello di grado m (quello di

% grado zero è 0); alpha contiene i coefficienti del

% denominatore della G~(z) in ordine crescente.

A =[];

% costruisco la matrice OMEGA1, contenente le

% componenti di theta per colonna for i=1:m

for j=1:n

A(j,i) = theta(n*(i-1)+j+m-1);

end end

[u,s,v] = svd(A);

% calcolo r e alpha a partire dalla SVD di OMEGA1 r = v(:,1) / v(1,1);

alpha = s(1,1) * u(:,1) * v(1,1);

(5)

Funzione step2.

function [THETA2] = step2 (y2,n,p)

% function [THETA2] = step2 (y2,n,p)

%

% Identificazione della parte lineare

% per un sistema Hammerstein-Wiener.

% y2 contiene le uscite campionate con periodo h/2

% (in modo tale da avere a disposizione i campioni

% corrispondenti agli istanti kT+T/2 indipendemente

% dal fatto che n sia pari o dispari),

% n è l'ordine della G(z),

% p è un vettore contenente i coefficienti polinomiali

% dell'inversa della non linearità di uscita in formato MATLAB.

% Viene restituito il vettore (THETA2) soluzione

% del sistema lineare x^[kT+T/2]=phi2[k]*theta2.

% conto per quanti periodi di campionamento T ho misurato la y steps = ceil(length(y2)/(2*(n+1)));

% trova le x^[kT], stima delle x[kT], a partire da y[kT]

xcap = polyval(p,y2);

phi2 = [];

xcap2 = [];

for k=(n-1):(steps-2) % uso questi estremi per evitare di uscire da xcap

% costruisco una riga della matrice phi2 (phi2[kT]) % e calcolo un elemento del vettore dei termini noti % (x^[kT+T/2])

[tmpphi2,tmpxcap2] = buildphi2(xcap,k,n);

phi2 = [phi2;tmpphi2];

xcap2 = [xcap2;tmpxcap2];

end

% risolvo il sistema lineare THETA2 = phi2\xcap2;

(6)

Funzione buildphi2.

function [phi,xc] = buildphi2 (xcap,k,n)

% function [phi,xc] = buildphi2 (xcap,k,n)

%

% Costruisce il vettore riga phi2[k]

% ed estrae x^[kT+T/2].

% xcap contiene le stime di x campionate

% con periodo h/2, k è il numero della

% riga di phi2 che voglio generare,

% n è l'ordine della G(z).

% Viene restituito il vettore phi2[k] e x^[kT+T/2].

phi=[];

% x^[kT+T/2]

xc = xcap(2*(n+1)*k + 1 + (n+1));

for i=2:n

% -x^[kT+T/2-(i-1)T]

phi = [phi, -xcap(2*(n+1)*k + 1 - (i-1)*(n+1)*2 + (n+1))];

end

for i=1:n+1

% x^[kT+T-(i-1)T]

phi = [phi, xcap(2*(n+1)*k + 1 - (i-2)*(n+1)*2)];

end

(7)

Funzione step3.

function [w2,ucap] = step3 (y2,w,n,p,alpha,beta,betasegnato)

% function [w2,ucap] = step3 (y2,w,n,p,alpha,beta,betasegnato)

%

% Identificazione della non linearità di ingresso

% per un sistema Hammerstein-Wiener.

% y2 contiene le uscite campionate con periodo h/2

% (in modo tale da avere a disposizione i campioni

% corrispondenti agli istanti kT+T/2 indipendemente

% dal fatto che n sia pari o dispari),

% w contiene gli ingressi del sistema campionati con periodo h/2,

% n è l'ordine della G(z),

% p è un vettore contenente i coefficienti polinomiali

% dell'inversa della non linearità di uscita,

% alpha e beta sono due vettori contenenti risp.

% i coefficienti del denominatore e del numeratore

% della G(z) (secondo lo standard usato dalla funzione filt),

% betasegnato contiene i coefficienti del numeratore della

% f.d.t. T.D. considerando i campioni negli istanti

% KT+T/2 anzichè KT (stesso formato di beta).

% Vengono restituiti due vettori, w2 e ucap, contenenti

% coppie di punti (w,u) che caratterizzano la g(w):

% la i-esima coppia è costituita dall'i-esima componente

% di w2 e dall'i-esima componente di ucap

% conto per quanti periodi di campionamento T ho misurato la y steps = ceil(length(y2)/(2*(n+1)));

% trova le x^[kT], stima delle x[kT], a partire da y[kT]

xcap = polyval(p,y2);

% min_ph indica se una delle due tra G(z) e G(z) segnato

% è a fase minima e se si quale (se lo sono entrambe indica G(z)) min_ph = 0;

% calcolo gli zeri di G(z)

zeri = roots(inverti(beta)).^(-1);

ok = 0;

% Verifico se G(z) è a fase minima, se sì pongo min_ph=1 for i=1:length(zeri)

% si noti che G(z) è strettamente propria

% perciò nel vettore "zeri", calcolato come sopra, % ho sempre almeno una componente infinita

if ((abs(zeri(i)) < 1) | isinf(zeri(i))) ok = ok + 1;

end end

if (ok == length(zeri)) min_ph = 1;

end

% Se G(z) non è a fase minima, verifico se G(z) segnato

% è a fase minima, e in questo caso pongo min_ph=2

(8)

if (min_ph == 0)

% calcolo gli zeri di G(z) segnato

zeri = roots(inverti(betasegnato)).^(-1);

ok = 0;

for i=1:length(zeri) if (abs(zeri(i)) < 1) ok = ok + 1;

end end

if (ok == length(zeri)) min_ph = 2;

end end

% Se min_ph è rimasto a zero, vuol dire che nè G(z)

% nè G(z) segnato sono a fase minima, perciò termino

% la funzione riportando un messaggio di errore if (min_ph == 0)

errordlg('G e Gsegnato non sono a fase minima!','Errore') return;

end

% w2 conterrà i valori di w(t) misurati negli istanti kT, k>=0 w2 = [];

% ucap(i) conterrà una stima della u relativa a w2(i) ucap = [];

% Per ora i primi n elementi di ucap conterranno

% i valori di u associati alla w misurata negli istanti

% che vanno da -nT a -T, mentre quello relativo a t=0

% è contenuto in ucap(n+1); supponendo che u=0 per t<0,

% inizializzo queste prime n componenti a zero for i=1:n

ucap(i,1) = 0;

end

% Analogamente a quanto fatto sopra, aggiungo n componenti

% nulle in testa al vettore xcap, in modo tale che la componente

% che contiene x[0] sia la n+1-esima. Faccio questo perchè

% nel calcolare la u[kT] mi servono i campioni della x anche per

% gli n periodi di campionamento che precedono kT e per k<n mi servono

% dei campioni per t<0, che non conosco for i=1:2*n*(n+1)

xcap = [0;xcap];

end

% Se G(z) è a fase minima la usa per calcolare le coppie (w,u) if (min_ph == 1)

% calcolo i vari u[kT] usando la formula che % li ricavadalla G(z) e dalle stime di x for i=1:steps-2

% uso tmpu come variabile temporanea per memorizzare

% ucap(i) man mano che sommo i termini che la costituiscono tmpu = 0;

(9)

% w[(i-1)T]

w2 = [w2; w(2*(n+1)*(i-1) + 1)];

for j=2:n

% beta contiene [0,beta_1,beta_2,...]

b = beta(j+1);

% ... - beta_(j+1)*u[(i-1)T-jT]

tmpu = tmpu - b * ucap(i - (j-1) + n);

end

for j=0:n

a = alpha(j+1);

% ... - alpha_(j+1)*x[(i-1)T+T/2-j*T]

% si ricordi che alpha contiene [1,-alpha_1,- alpha_2,...]

tmpu = tmpu + a * xcap(2*(n+1)*(i-1) + 1 - (j-1)*2*(n+1) + 2*n*(n+1));

end

ucap = [ucap; tmpu];

end

% Se G(z) segnato è fase minima e G(z) no, uso G(z) segnato

% per calcolare le coppie (w,u) else

% il seguito è del tutto analogo al ramo principale dell'if, ma % stavolta applico la formula che ricava u[kT] usando G(z) segnato

for i=1:steps-2 tmpu = 0;

w2 = [w2; w(2*(n+1)*(i-1) + 1)];

for j=1:n

b = betasegnato(j+1);

tmpu = tmpu - b * ucap(i - j + n);

end

for j=0:n

a = alpha(j+1);

tmpu = tmpu + a * xcap(2*(n+1)*(i-1) + 1 + (n+1) - j*2*(n+1) + 2*n*(n+1));

end

tmpu = tmpu / betasegnato(1);

ucap = [ucap; tmpu];

end

end

% elimino le prime n componenti di ucap, aggiunte

% artificiosamente (vedi sopra) ucap = ucap(n+1:length(ucap));

(10)

Funzione inverti.

function res = inverti (v)

% function res = inverti (v)

%

% Prende come argomento un vettore (v)

% e restituisce un vettore (res) con le

% stesse componenenti, ma in ordine inverso L = length(v);

for i=1:L

res(i) = v(L-i+1);

end

(11)

Procedura di identificazione.

% PROCEDURA AUTOMATICA PER L'IDENTIFICAZIONE DI SISTEMI HAMMERSTEIN- WIENER

% Nello workspace devono essere presenti le seguenti variabili:

% n: ordine della G(z)

% m: grado dell'inversa della n.l. di uscita

% q: grado della n.l. di uscita

% FASE 1:

% IDENTIFICAZIONE DELLA NON LINEARITA' DI USCITA

% eseguo l'algoritmo per trovare la non linearità di uscita

% e il denominatore della G(z) relativa ad h [dphi,dy,theta] = step1 (y2,m,n);

[r,alpha_h] = find_r_alpha(theta,m,n)

% p contiene i coefficienti dell'inversa della f(x) p = [inverti(r),0]

clear r;

% Stima della non linearità di uscita a partire dalla sua inversa ymin = min(y);

ymax = max(y);

% suddivido il range delle y ottenute dalla simulazione in 1000 intervalli

y1 = ymin:((ymax-ymin)/1000):ymax;

y1 = y1.';

% ricostruisco le x1 relative alle y1 sfruttando l'inversa di f(x) x1 = polyval(p,y1);

A = [];

% A = [x1^q,x1^(q-1),...,x^2,x]

% (matrice di Vandermonde senza la colonna relativa al termine noto) for i=1:q

A = [A,x1.^(q+1-i)];

end

% trovo i coefficienti (vettore est) risolvendo A*est=y1:

% coefficienti che meglio approssimano le coppie (x1,y1)

% nel senso dei minimi quadrati est = A\y1;

clear A;

clear x1;

clear y1;

% termine noto = 0 (non linearità passante per l'origine) est = [est;0]

% confronto tra la non linerità di uscita identificata

% e quella reale.

% N.B.: viene effettuato solo se nello workspace

% di base è presente una variabile di nome "xx"

% contenente il range della x ed un'altra di nome "yy"

% contenente i relativi valori della y reale.

if (evalin('base','exist(''xx'')') & evalin('base','exist(''yy'')')) xx = evalin('base','xx');

(12)

yy= evalin('base','yy');

plot(xx,polyval(est,xx),'ro',xx,yy,'b') legend('stima di f(x)','f(x)')

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% FASE 2:

% IDENTIFICAZIONE DELLA PARTE LINEARE [theta2] = step2(y2,n,p);

betasegnato = theta2(n:length(theta2)) beta = theta2(1:n-1);

beta = [0;1;beta].'

% calcolo di alpha

aa = roots([inverti(-alpha_h),1]);

aa = aa.^(-n-1); % calcolo i poli della G(z) pol = [];

for i=1:length(aa)

pol = [pol,[-aa(i);1]];

end

alpha = 1;

for i=1:length(aa)

alpha = conv(alpha,pol(:,i));

end

clear aa;

clear alpha_h;

alpha = real(alpha);

alpha = inverti(alpha)

if (evalin('base','exist(''T'')')) Gz = filt(beta,alpha,T)

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% FASE 3:

% IDENTIFICAZIONE DELLA NON LINEARITA' DI INGRESSO [w2,ucap] = step3(y2,w,n,p,alpha,beta,betasegnato);

wu = [w2,ucap];

wu = sortrows(wu);

clear w2;

clear ucap;

% suddivido l'intervallo di valori tra cui varia la w

% in 50 sottointervalli e per ciascuno calcolo la media

% delle relative u

intervallo = (wu(size(wu,1),1) - wu(1,1)) / 50;

scorri = 1;

wu_media = [];

for i=1:50 temp = [];

j = 1;

(13)

while (wu(scorri,1) <= i * intervallo + wu(1,1)) temp(j,1) = wu(scorri,2);

scorri = scorri + 1;

if (scorri >= size(wu,1)) break;

end

j = j + 1;

end

wu_media(i,1) = i * intervallo - (intervallo/2) + wu(1,1);

wu_media(i,2) = mean(temp);

end figure;

plot(wu(:,1),wu(:,2),'ro',wu_media(:,1),wu_media(:,2),'gx')

(14)

Funzione hw_fun_mod.

function [p,est,num,den,nlc] = hw_fun_mod (np,nz,go,gi,m,y,t,w,y_fm,T)

% function [p,est,num,den,nlc] = hw_fun_mod (np,nz,go,gi,m,y,t,w,y_fm,T)

%

% Identificazione di sistemi Hammerstein-Wienere, con uso della

% tecnica delle funzioni modulanti per la parte Hammerstein.

% np: numero di poli della G(s),

% nz: numero di zeri della G(s),

% go: grado della n.l. di uscita,

% gi: grado della n.l. di ingresso,

% m: grado dell'inversa della n.l. di uscita,

% y: vettore contenente le misure dell'uscita campionate con periodo h/2,

% t: istanti di campionamento dei segnali per l'identificazione

% con la tecnica delle funzioni modulanti,

% w: segnale di ingresso per l'identificazione

% con la tecnica delle funzioni modulanti,

% y_fm: segnale di uscita per l'identificazione

% con la tecnica delle funzioni modulanti,

% T: finestra di integrazione per l'identificazione

% con la tecnica delle funzioni modulanti.

% p: coefficienti polinomiali dell'inversa della n.l. di uscita,

% est: coefficienti polinomiali della n.l. di uscita,

% num: coefficienti del numeratore della G(s),

% den: coefficienti del denominatore della G(s),

% nlc:coefficienti polinomiali della n.l. di ingresso.

% FASE 1:

% IDENTIFICAZIONE DELLA NON LINEARITA' DI USCITA

% ordine della G(z) = numero di poli della G(s) n = np;

q = go;

% eseguo l'algoritmo per trovare la non linearità di uscita [dphi,dy,theta] = step1 (y,m,n);

[r,alpha_h] = find_r_alpha(theta,m,n)

% p contiene i coefficienti dell'inversa della f(x) p = [inverti(r),0]

% Stima della non linearità di uscita a partire dalla sua inversa ymin = min(y);

ymax = max(y);

% suddivido il range delle y ottenute dalla simulazione in 1000 intervalli

y1 = ymin:((ymax-ymin)/1000):ymax;

y1 = y1.';

% ricostruisco le x1 relative alle y1 sfruttando l'inversa di f(x) x1 = polyval(p,y1);

A = [];

(15)

% A = [x1^q,x1^(q-1),...,x^2,x]

% (matrice di Vandermonde senza la colonna relativa al termine noto) for i=1:q

A = [A,x1.^(q+1-i)];

end

% trovo i coefficienti (vettore est) risolvendo A*est=y1

% coefficienti che meglio approssimano le coppie (x1,y1)

% nel senso dei minimi quadrati est = A\y1;

% termine noto = 0 (non linearità passante per l'origine) est = [est;0]

% confronto tra la non linerità di uscita identificata

% e quella reale.

% N.B.: viene effettuato solo se nello workspace

% di base è presente una variabile di nome "xx"

% contenente il range della x ed un'altra di nome "yy"

% contenente i relativi valori della y reale.

if (evalin('base','exist(''xx'')') & evalin('base','exist(''yy'')')) xx = evalin('base','xx');

yy= evalin('base','yy');

plot(xx,polyval(est,xx),'ro',xx,yy,'b') legend('stima di f(x)','f(x)')

end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% FASE 2:

% APPLICAZIONE DEL METODO DELLE FUNZIONI MODULANTI

% ALLA PARTE HAMMERSTEIN DEL SISTEMA

y = polyval(p,y_fm); % ricostruisco le uscite della parte lineare save 'ywt.mat' y w t;

%chiamo la funzione per identificare un sistema Hammerstein con le f.m.

[num,den,nlc] = fun_mod_ham(T,np,nz,gi,'yut.mat');

% si riportano i coefficienti della n.l. di ingresso stimati

% nel formato polinomiale standard di MATLAB nlc = inverti(nlc);

nlc(length(nlc)+1) = 0;

% confronto tra le risposte al gradino

% N.B.: viene effettuato solo se nello workspace

% di base è presente una variabile di nome "G"

% contenente la G(s) NORMALIZZATA: il confronto

% ha senso solo se G HA GUADAGNO STATICO UNITARIO.

if (evalin('base','exist(''G'')')) G = evalin('base','G');

G_stimata = tf(num,den);

step(G,G_stimata);

legend('G(s)','G(s) stimata');

end

Riferimenti

Documenti correlati

Corso di studi:... Corso

[r]

[r]

Nel piano, due vettori non nulli fra loro ortogonali sono sempre linearmente indipendenti; nello spazio, due vettori non nulli fra loro ortogonali sono sempre linearmente

Ora, un punto che partendo da O si sposta prima nel punto di coordinate v1 , v2 , 0 e poi si sposta di v3 unita’ nella direzione dell’asse z, descrive i due cateti di un

Fissi- amo nello spazio un sistema di riferimento cartesiano ortogonale monometrico con origine nel punto O, ed identifichiamo i vettori di R 3 con vettori applicati

Piu’ in generale, si definiscono un’operazione di addizione fra matrici dello stesso tipo, un’operazione di moltiplicazione di una matrice per uno scalare, e si prova che il prodotto

[r]