APPENDICE B
PROGRAMMI MATLAB SVILUPPATI
Matlab function per l’applicazione del filtro di Kalman all’elaborazione offline.
function [Xres] = mio_kalman(sign) L=length(sign);
% Definizioni dei valori interni alle matrici del filtro
% varianza errore valore iniziale e1 = 0;
% varianza errore stato iniziale d=diff(sign);
q1=cov(d);
% varianza rumore sulla misura r1 = 0.1.*[1 0 0; 0 1 0; 0 0 1];
% Inizializzazione dello stato del filtro Xn = [0; 0; 0];
P = zeros(3);
% Definizioni delle matrici del filtro PHI = eye(3);
Q = q1;
R = r1;
C = eye(3);
a = [0; 0; 0];
b = zeros(3);
% Inizializzazione del vettore dei risultati Xres = []; Pres = [];
% Loop per 't' step sign = sign';
for t = 1:L
Xr = sign(:,t);
Z = Xr;
% Lettura delle misure affette da rumore Xp=a;
Pp=b;
% Calcolo della matrice di guadagno del filtro di Kalman K = Pp * C' * inv(C * Pp * C' + R);
% Aggiornamento della stima dello stato Xn = Xp + K * (Z - C * Xp);
% Aggiornamento della varianza dei disturbi sullo stato e aggiornamento del ciclo
Pn = (eye(3) - K * C)* Pp;
% Aggiornamento dello stato
a = PHI * Xn; %%stima dello stato futuro a k+1
% Aggiornamento della stima della varianza dell'errore sullo stato k+1 b = PHI * Pn * PHI' + Q;
% Memorizzazione dei risultati XRres(:,t) = Xr;
Xres(:,t) = Xn;
end
Xres=Xres';
XRres=XRres';
%Visualizzazione
subplot(3,1,1), plot(tempo(1:length(Xres(:,1))),Xres(:,1)+1);
hold;
plot(tempo(1:length(Xres)),XRres(:,1)-1,'g');
xlabel('time (s)');
ylabel('V(Volt)');
legend('C1 filtrato','C1 non filtrato');
subplot(3,1,2), plot(tempo(1:length(Xres)),Xres(:,2)+1);
hold;
plot(tempo(1:length(Xres)),XRres(:,2)-1,'g');
xlabel('time (s)');
ylabel('V(Volt)');
legend('C2 filtrato','C2 non filtrato');
subplot(3,1,3), plot(tempo(1:length(Xres)),Xres(:,3)+3);
hold;
plot(tempo(1:length(Xres)),XRres(:,3)-3,'g');
xlabel('time (s)');
ylabel('V(Volt)');
legend('C3 filtrato','C3 non filtrato');
Matlab function per la stima dell’SNR sul tracciato EMG.
function [SNR N] = signaltonoise(C)
%==============%
%%%%%RUMORE%%%%%
%==============%
for i = 1:3
noise (:,i) = C(2000:2999,i); %Creazione della matrice di rumore
P_noise(:,i)= sqrt(sum(noise(:,i).*conj(noise(:,i)))/1000); %Calcolo della potenza di rumore
%===============%
%%%%%SEGNALE%%%%%
%===============%
L = length(C);
rect_elettrodo = abs(C(2000:L,i)); %rettifico il canale
M = max(rect_elettrodo); %individuo l'ampiezza massima del segnale originario
for n = 1:L-2000
b = rect_elettrodo(n);
if b == M
max_sample = n; %individuo il campione corrispondente all'ampiezza massima
end;
end;
inf = max_sample - 500;
sup = max_sample + 499;
signal(:,i) = C(inf:sup,i);
P_signal (:,i) = sqrt(sum(signal(:,i).*conj(signal(:,i)))/1000); %Calcolo della potenza di segnale
%====Calcolo dell' SNR
SNR(:,i) = P_signal/P_noise;
N(:,i)= 10*log10(SNR(:,i));
end;
end
Matlab function per l’estrazione dell’inviluppo lineare dai segnali EMG.
function[env]=Inviluppo(sign)
[a,b]=butter(5,10/2000,'low'); %crea il passa-basso per lo smoothing (Fcutoff= 10Hz, Fc=2000Hz, ordine 5)
env = filter(a,b,abs(sign));
end
Matlab function per il calcolo dell’onset su segnali EMG.
function [sampleno reston] = solonset(y,a,b,c,d)
%y: segnale su cui calcolare l'onset
%[a,b]: segmento di segnale su cui calcolare la soglia
%[c,d]: inizio e fine dell'intero tracciato EMG da analizzare
reston = mean(y(a:b)) + 3*std(y(a:b));
x = 0;
for n = c:d
if y(n) >= reston x = x+1;
else
x = 0;
end
if x == 50
sampleno = n - 49;
break end
end;
Codice Matlab per l’elaborazione di segnali EMG con calcolo dei parametri teta e rappresentazione degli onset sugli inviluppi.
n = input('Inserisci il numero di acquisizioni per il movimento: ');
w = input('inserisci la lunghezza del segnale da analizzare: ');
c = 1;
d = w;
a = input('inserisci il sample inf di riposo pre-burnst [a]: ');
b = input('inserisci il sample sup di riposo pre-burnst [b]: ');
for z = 1:n
%---%
%Separazione e rettifica dei canali dal file di acquisizione originario da
%Grass
sign = input('inserisci il file della misura ');
[C1 C2 C3 L] = Sep_Rett (sign);
C=[C1 C2 C3];
%---%
%Estrazione degli inviluppi nella finestra di osservazione L=[3000:i]
%campioni.
for i = 1:3
S(:,i) = Inviluppo(C(:,i));
Env(:,i) = S(3000:(w+999),i);
end;
%---%
%Calcolo dell' onset (function 'solonset') sull' inviluppo dei segnali.
for i = 1:3
[sampon soglia]= solonset(Env(:,i),a,b,c,d);
on(:,i) = sampon;
soglia_on(:,i) = soglia;
end;
%---%
Rappresentazioe degli onset sugli inviluppi.
plot(Env(:,1), 'b');
xlabel('sample number');
ylabel('EMG signal');
hold on
point1=[on(1,1) on(1,1)];
point2=[0 max(Env(:,1))];
plot(point1, point2,'LineWidth',2,'Color','b');
s1=['onset1 = ', num2str(on(1,1))];
text(on(1,1)+1, max(Env(:,1)), s1, 'Color','b');
hold on
plot(Env(:,2),'r');
hold on
point3=[on(1,2) on(1,2)];
point4=[0 max(Env(:,2))];
plot(point3, point4,'LineWidth',2,'Color','r');
t1=['onset2 = ', num2str(on(1,2))];
text(on(1,2)+1, max(Env(:,2)), t1, 'Color','r');
hold on
plot(Env(:,3), 'g');
hold on
point5=[on(1,3) on(1,3)];
point6=[0 max(Env(:,3))];
plot(point5, point6,'LineWidth',2,'Color','g');
u1=['onset3 = ', num2str(on(1,3))];
text(on(1,3)+1, max(Env(:,3)), u1, 'Color','g');
hold off;
%---%
%Calcolo degli sfasamenti tra onset (parametri teta).
if on(1,1) == 0 || on(1,2) == 0 tetaon12 = 0;
else tetaon12 = abs(on(1,1) - on(1,2));
end;
if on(1,1) == 0 || on(1,3) == 0 tetaon13 = 0;
else tetaon13 = abs(on(1,1) - on(1,3));
end;
if on(1,2) == 0 || on(1,3) == 0 tetaon23 = 0;
else tetaon23 = abs(on(1,2) - on(1,3));
end;
%---%
%Creazione della matrice degli sfasamenti.
tetaon = [tetaon12 tetaon13 tetaon23];
teta(z,:) = tetaon;
clear C C1 C2 C3 Env L S i sampon sign soglia t1 u1;
%---%
end;
clear a b c d n on soglia_on tetaon tetaon12 tetaon13 tetaon23 w z;
Matlab function per la separazione dei canali dal file di acquisizione da GRASS.
function [C1 C2 C3 L] = Sep_Rett (sign)
L = length(sign);
C1 = abs(sign(1:L,2));
C2 = abs(sign(1:L,3) - 0.5);
C3 = abs(sign(1:L,4) - 0.8);
end
Matlab functions per il calcolo dei parametri dell’EMG e dell’indice SEM di ripetibilità.
%============================Calcolo dell'ARV==============================
%==========================================================================
%Il valore medio del segnale rettificato (ARV) è un descrittore di ampiezza
%del segnale EMG.
%==========================================================================
function ARV = ARV(elettrodo)
L = length(elettrodo); %intervallo di osservazione dell'EMGs
rec_ch = abs(elettrodo); %rettifica del segnale ARV = (sum(rec_ch))/L; % calcolo dell' ARV end
%==========================================================================
%============================Calcolo dell'RMS==============================
%==========================================================================
%Il Valore Efficace (RMS) è un descrittore di ampiezza del segnale EMG.
%Coincide, tra l'altro, con la potenza elettrica del segnale.
%==========================================================================
function RMS = RMS(elettrodo)
L = length(elettrodo); %intervallo di osservazione dell'EMGs square_ch = elettrodo.^2; %quadrato del segnale originario RMS = sqrt((sum(square_ch))/L); %calcolo dell'RMS
end
%==========================================================================
%=========================Calcolo della MNF================================
%==========================================================================
%La Frequenza Media (MNF) è un descrittore di frequenza del segnale EMG.
%E' definita come l’ascissa del baricentro dello spettro.
%==========================================================================
function MNF = MNF (input)
%Costruzione dello spettro di potenza FFTch = fft(input, 512);
Pch = (FFTch.*conj(FFTch))/512;
f = 2000*(0:256)/512;
m = Pch(1:257);
m=1000*m;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
M1 = sum(f.*m');
M0 = sum(m);
MNF = M1/M0
%plot(f,m);
end
%===========================Calcolo del SEM================================
%L'Errore Standard della Media (SEM) stima l'errore sul valore medio delle
%misure di una variabile. Da esso può ricavarsi un giudizio sulla bontà
%delle misure ed è uno stimatore semplice di ripetibilità intra-soggetto.
%Dividendo il SEM per il valore medio si ottiene il SEM Normalizzato, che
%stabilisce la % di errore commessa nella misura.
function [SEM SEMN VMEDIO]= SEM(input, nr_mis)
%global par;
%global nr_mis;
sigma = std(input); %deviazione standard
VMEDIO = mean(input);
SEM = (sigma)/sqrt(nr_mis);
SEMN = 100*abs((SEM/mean(input)));
end
Codice Matlab che gestisce il test di ripetibilità del SEM.
for i = 1:3
canale = input('inserisci il canale ');
[arv rms mnf mdf variance cda cdc] = parametri(canale, nr_mis);
%matrici nr_mis x 3(C1 C2 C3) Arv(:,i) = arv';
Rms(:,i) = rms';
Mnf(:,i) = mnf';
teta(:,i) = teta';
%calcolo dei valori medi e delle deviazioni dei parametri per i 3 %Canali per un movimento.
med_arv(:,i)=mean(Arv(:,i));
dev_arv(:,i)=std(Arv(:,i));
end;
%par=Arv(:,1);
%Calcolo del sem e del semn
for j = 1:7 %tanti quanti i parametri
parametro = input('Inserisci il parametro ');
for i = 1:3
par = parametro(:,i);
[sem(j,i) semn(j,i) vmedio(j,i)] = SEM(par, nr_mis);
end;
end;
%Conformazione della matrice del SEM (analog. per SEMN):
%
%
% | sem(C1,1) sem(C2,1) sem(C3,1)|
% sem = | sem(C1,2) sem(C2,2) sem(C3,3)|
% | .... ... .. |
% | sem(C1,4) sem(C2,4) sem(C3,4)|
%=======================================================
%Matrice dei Valori Medi (sulle righe: val.medi del parametro su 3 canali;
%sulle colonne: canali) per un movimento!!!
mov = mean(vmedio,2);
Matlab function per il calcolo simultaneo dei parametri EMG.
%==Ogni uscita è un vettore dei valori del parametro corrispondente nelle=%
%======='nr_mis' acquisizioni per un canale per un dato movimento=========%
function [arv rms mnf mdf variance cda cdc] = Parametri (canale, nr_mis)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%
for i = 1:nr_mis
arv(:,i) = ARV(canale(:,i)); %Valore Medio Rettificato
rms(:,i) = RMS(canale(:,i)); %Valore Quadratico Medio mnf(:,i) = MNF(canale(:,i)); %Frequenza Media
teta(:,i) = TETA(canale(:,i)); %Sfasamenti fra onset end;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
Matlab GUI per la gestione della calibrazione e dell’inizializzazione del classificatore.
function varargout = EMGui(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @EMGui_OpeningFcn, ...
'gui_OutputFcn', @EMGui_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before EMGui is made visible.
function EMGui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to EMGui (see VARARGIN)
% Choose default command line output for EMGui handles.output = hObject;
% Update handles structure guidata(hObject, handles);
% UIWAIT makes EMGui wait for user response (see UIRESUME)
% uiwait(handles.figure1);
%
Elettromiografia; %apre il modello Simulink rtwbuild('Elettromiografia');% esegue il "build"
pause(1);
global conta_ext conta_flex conta_pro conta_ad conta_ab;%parametro;
conta_ext = 0;
conta_flex = 0;
conta_pro = 0;
conta_ad = 0;
conta_ab = 0;
set(handles.text3,'String','');
% --- Outputs from this function are returned to the command line.
function varargout = EMGui_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes on button press in pushbutton.
function pushbutton_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set_param('Elettromiografia','SimulationCommand','Connect'); %connette il modulo simulink
pause(1); %aspetta
set_param('Elettromiografia','SimulationCommand','Start');%comincia l' acquisizione
pause(2.5);
set(handles.text8,'foregroundcolor', 'b');
set(handles.text8, 'string', 'ESEGUI!');
pause(1);
set(handles.text8, 'string', '');
pause(2.5);
set_param('Elettromiografia','SimulationCommand','Stop');%termina l'acquisizione pause(1);%aspetta
set_param('Elettromiografia','SimulationCommand','Disconnect');%disconnette il modulo simulink
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% set_param('Elettromiografia','SimulationCommand','Stop');%termina l'acquisizione
% pause(1);%aspetta
% set_param('Elettromiografia','SimulationCommand','Disconnect');%disconnette il modulo simulink
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global conta_ext conta_flex conta_pro mov conta_ad conta_ab ARV_AD RMS_AD TETA_AD ARV_AB RMS_AB TETA_AB SOGLIE_FLEX SOGLIE_PRO;
global SNR_ref nr_mis ARV_EXT ARV_FLEX ARV_PRO RMS_EXT RMS_FLEX RMS_PRO TETA_EXT TETA_FLEX TETA_PRO SOGLIE_EXT SOGLIE_AD SOGLIE_AB;
set(handles.text3,'String','');
signal = evalin('base','nokalman');%prelevo dal workspace il segnale acquisito come inviluppo
C = Sep_Rett(signal);%nella matrice C ho i 3 canali utili senza il tempo
[SNR N] = signaltonoise(C); %calcolo il SNR (N in dB) dell'acquisizione sui tre canali
if SNR(1) >= SNR_ref(1) && SNR(2) >= SNR_ref(2) && SNR(3)>= SNR_ref(3) pause(0.5);
set(handles.text3,'foregroundcolor', 'g');
set(handles.text3,'String','MISURA BUONA!');
if mov == 1
conta_ext = conta_ext+1;
[arv_ext rms_ext teta_ext threshold_ext] = win_par(C);%calcolo i parametri per i 3 canali
ARV_EXT(conta_ext,:) = arv_ext;%matrice degli arv su tutte le misure(nr_mis x canali)
RMS_EXT(conta_ext,:) = rms_ext;%matrice degli rms su tutte le misure(nr_mis x canali)
TETA_EXT(conta_ext,:) = teta_ext;%matrice dei teta su tutte le misure(nr_mis x canali)
SOGLIE_EXT(conta_ext,:) = threshold_ext;%matrice delle soglie su tutte le misure(nr_mis x canali)
if conta_ext == nr_mis
set(handles.text3,'foregroundcolor', 'b');
set(handles.text3,'string', 'STOP EXTENSION!');
%salvataggio delle variabili save arv_ext ARV_EXT
save rms_ext RMS_EXT;
save teta_ext TETA_EXT;
save soglie_ext SOGLIE_EXT;
%%===PER IL CLASSIFICATORE===%%
%calcolo i valori medi dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVM_EXT = mean(ARV_EXT,1);
RMSM_EXT = mean(RMS_EXT,1);
TETAM_EXT = mean(TETA_EXT,1);
SOGLIEM_EXT = mean(SOGLIE_EXT,1);
%salvataggio delle variabili save arvm_ext ARVM_EXT;
save rmsm_ext RMSM_EXT;
save tetam_ext TETAM_EXT;
save sogliem_ext SOGLIEM_EXT;
%calcolo le dev. st. dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVDS_EXT = std(ARV_EXT,1);
RMSDS_EXT = std(RMS_EXT,1);
TETADS_EXT = std(TETA_EXT,1);
SOGLIEDS_EXT = std(SOGLIE_EXT,1);
%salvataggio delle variabili save arvds_ext ARVDS_EXT;
save rmsds_ext RMSDS_EXT;
save tetads_ext TETADS_EXT;
save soglieds_ext SOGLIEDS_EXT;
conta_ext = 0;
%%===========================%%
end
elseif mov == 2
conta_flex = conta_flex+1;
[arv_flex rms_flex teta_flex threshold_flex] = win_par(C);
ARV_FLEX(conta_flex,:) = arv_flex;%matrice degli arv su tutte le misure(nr_mis x canali)
RMS_FLEX(conta_flex,:) = rms_flex;%matrice degli rms su tutte le misure(nr_mis x canali)
TETA_FLEX(conta_flex,:) = teta_flex;%matrice dei teta su tutte le misure(nr_mis x canali)
SOGLIE_FLEX(conta_flex,:) = threshold_flex;%matrice delle soglie su tutte le misure(nr_mis x canali)
if conta_flex ==nr_mis
set(handles.text3,'foregroundcolor', 'b');
set(handles.text3,'string', 'STOP FLEXION!');
%salvataggio delle variabili save arv_flex ARV_FLEX;
save rms_flex RMS_FLEX;
save teta_flex TETA_FLEX;
save soglie_flex SOGLIE_FLEX;
%%===PER IL CLASSIFICATORE===%%
%calcolo i valori medi dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVM_FLEX = mean(ARV_FLEX,1);
RMSM_FLEX = mean(RMS_FLEX,1);
TETAM_FLEX = mean(TETA_FLEX,1);
SOGLIEM_FLEX = mean(SOGLIE_FLEX,1);
%salvataggio delle variabili save arvm_flex ARVM_FLEX;
save rmsm_flex RMSM_FLEX;
save tetam_flex TETAM_FLEX;
save sogliem_flex SOGLIEM_FLEX;
%calcolo le dev. st. dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVDS_FLEX = std(ARV_FLEX,1);
RMSDS_FLEX = std(RMS_FLEX,1);
TETADS_FLEX = std(TETA_FLEX,1);
SOGLIEDS_FLEX = std(SOGLIE_FLEX,1);
%salvataggio delle variabili save arvds_flex ARVDS_FLEX;
save rmsds_flex RMSDS_FLEX;
save tetads_flex TETADS_FLEX;
save soglieds_flex SOGLIEDS_FLEX;
conta_flex=0;
%%===========================%%
end
elseif mov == 3
conta_pro = conta_pro+1;
[arv_pro rms_pro teta_pro threshold_pro] = win_par(C);
ARV_PRO(conta_pro,:) = arv_pro;%matrice degli arv su tutte le misure(nr_mis x canali)
RMS_PRO(conta_pro,:) = rms_pro;%matrice degli rms su tutte le misure(nr_mis x canali)
TETA_PRO(conta_pro,:) = teta_pro;%matrice dei teta su tutte le misure(nr_mis x canali)
SOGLIE_PRO(conta_pro,:) = threshold_pro;%matrice delle soglie su tutte le misure(nr_mis x canali)
if conta_pro == nr_mis
set(handles.text3,'foregroundcolor', 'b');
set(handles.text3,'string','STOP PRONOSUP.!');
%salvataggio delle variabili save arv_pro ARV_PRO;
save rms_pro RMS_PRO;
save teta_pro TETA_PRO;
save soglie_pro SOGLIE_PRO;
%%===PER IL CLASSIFICATORE===%%
%calcolo i valori medi dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVM_PRO = mean(ARV_PRO,1);
RMSM_PRO = mean(RMS_PRO,1);
TETAM_PRO = mean(TETA_PRO,1);
SOGLIEM_PRO = mean(SOGLIE_PRO,1);
%salvataggio delle variabili save arvm_pro ARVM_PRO;
save rmsm_pro RMSM_PRO;
save tetam_pro TETAM_PRO;
save sogliem_pro SOGLIEM_PRO;
%calcolo le dev. st. dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVDS_PRO = std(ARV_PRO,1);
RMSDS_PRO = std(RMS_PRO,1);
TETADS_PRO = std(TETA_PRO,1);
SOGLIEDS_PRO = std(SOGLIE_PRO,1);
%salvataggio delle variabili save arvds_pro ARVDS_PRO;
save rmsds_pro RMSDS_PRO;
save tetads_pro TETADS_PRO;
save soglieds_pro SOGLIEDS_PRO;
conta_pro=0;
%%===========================%%
end
elseif mov == 4
conta_ad = conta_ad+1;
[arv_ad rms_ad teta_ad threshold_ad] = win_par(C);
ARV_AD(conta_ad,:) = arv_ad;%matrice degli arv su tutte le misure(nr_mis x canali)
RMS_AD(conta_ad,:) = rms_ad;%matrice degli rms su tutte le misure(nr_mis x canali)
TETA_AD(conta_ad,:) = teta_ad;%matrice dei teta su tutte le misure(nr_mis x canali)
SOGLIE_AD(conta_ad,:) = threshold_ad;%matrice delle soglie su tutte le misure(nr_mis x canali)
if conta_ad == nr_mis
set(handles.text3,'foregroundcolor', 'b');
set(handles.text3,'string','STOP ADDUCTION!');
%salvataggio delle variabili save arv_ad ARV_AD;
save rms_ad RMS_AD;
save teta_ad TETA_AD;
save soglie_ad SOGLIE_AD;
%===PER IL CLASSIFICATORE===%%
%calcolo i valori medi dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVM_AD = mean(ARV_AD,1);
RMSM_AD = mean(RMS_AD,1);
TETAM_AD = mean(TETA_AD,1);
SOGLIEM_AD = mean(SOGLIE_AD,1);
%salvataggio delle variabili save arvm_ad ARVM_AD;
save rmsm_ad RMSM_AD;
save tetam_ad TETAM_AD;
save sogliem_ad SOGLIEM_AD;
%calcolo le dev. st. dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVDS_AD = std(ARV_AD,1);
RMSDS_AD = std(RMS_AD,1);
TETADS_AD = std(TETA_AD,1);
SOGLIEDS_AD = std(SOGLIE_AD,1);
%salvataggio delle variabili save arvds_ad ARVDS_AD;
save rmsds_ad RMSDS_AD;
save tetads_ad TETADS_AD;
save soglieds_ad SOGLIEDS_AD;
conta_ad=0;
%%==========================%%
end
elseif mov == 5
conta_ab = conta_ab+1;
[arv_ab rms_ab teta_ab threshold_ab] = win_par(C);
ARV_AB(conta_ab,:) = arv_ab;%matrice degli arv su tutte le misure(nr_mis x canali)
RMS_AB(conta_ab,:) = rms_ab;%matrice degli rms su tutte le misure(nr_mis x canali)
TETA_AB(conta_ab,:) = teta_ab;%matrice dei teta su tutte le misure(nr_mis x canali)
SOGLIE_AB(conta_ab,:) = threshold_ab;%matrice delle soglie su tutte le misure(nr_mis x canali)
if conta_ab == nr_mis
set(handles.text3,'foregroundcolor', 'b');
set(handles.text3,'string','STOP ABDUCTION!');
%salvataggio delle variabili save arv_ab ARV_AB;
save rms_ab RMS_AB;
save teta_ab TETA_AB;
save soglie_ab SOGLIE_AB;
%%===PER IL CLASSIFICATORE===%%
%calcolo i valori medi dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVM_AB = mean(ARV_AB,1);
RMSM_AB = mean(RMS_AB,1);
TETAM_AB = mean(TETA_AB,1);
SOGLIEM_AB = mean(SOGLIE_AB,1);
%salvataggio delle variabili save arvm_ab ARVM_AB;
save rmsm_ab RMSM_AB;
save tetam_ab TETAM_AB;
save sogliem_ab SOGLIEM_AB;
%calcolo le dev. st. dei parametri e delle soglie %si tratta di vettori (1 x canali)
ARVDS_AB = std(ARV_AB,1);
RMSDS_AB = std(RMS_AB,1);
TETADS_AB = std(TETA_AB,1);
SOGLIEDS_AB = std(SOGLIE_AB,1);
%salvataggio delle variabili save arvds_ab ARVDS_AB;
save rmsds_ab RMSDS_AB;
save tetads_ab TETADS_AB;
save soglieds_ab SOGLIEDS_AB;
conta_ab=0;
%%===========================%%
end end
else pause(0.5);
set(handles.text3,'foregroundcolor', 'r');
set(handles.text3,'String','RIPETERE LA MISURA!');
end
% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
% hObject handle to listbox1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = get(hObject,'String') returns listbox1 contents as cell array
% contents{get(hObject,'Value')} returns selected item from listbox1
global SNR_ref mov;
list_movements = get(handles.listbox1,'String');
index_selected = get(handles.listbox1,'Value');
if strcmp(list_movements(index_selected),'Estensione') SNR_ref = [3 3 3];
mov=1;
elseif strcmp(list_movements(index_selected),'Flessione') SNR_ref = [3 3 3];
mov=2;
elseif strcmp(list_movements(index_selected),'Pronosupinazione') SNR_ref = [2 2 2];
mov=3;
elseif strcmp(list_movements(index_selected),'Adduzione') SNR_ref = [2 2 2];
mov=4;
elseif strcmp(list_movements(index_selected),'Abduzione') SNR_ref = [1.5 1.5 1.5];
mov=5;
end
set(handles.text4, 'string', SNR_ref)
% --- Executes during object creation, after setting all properties.
function listbox1_CreateFcn(hObject, eventdata, handles)
% hObject handle to listbox1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: listbox controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function edit4_Callback(hObject, eventdata, handles)
% hObject handle to edit4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit4 as text
% str2double(get(hObject,'String')) returns contents of edit4 as a double global nr_mis;
nr_mis = get(handles.edit4,'string');
nr_mis = str2double(nr_mis);
% --- Executes during object creation, after setting all properties.
function edit4_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global ARV_EXT ARV_FLEX ARV_PRO RMS_EXT RMS_FLEX RMS_PRO TETA_EXT TETA_FLEX TETA_PRO;
global ARV_AD RMS_AD TETA_AD ARV_AB RMS_AB TETA_AB nr_mis parametro;
axes(handles.axes4);
if strcmp(parametro,'arv') for i=1:nr_mis
plot3(ARV_EXT(i,1), ARV_EXT(i,2), ARV_EXT(i,3),'rs');
hold on
plot3(ARV_FLEX(i,1), ARV_FLEX(i,2), ARV_FLEX(i,3),'ko');
plot3(ARV_PRO(i,1), ARV_PRO(i,2), ARV_PRO(i,3),'*');
plot3(ARV_AD(i,1), ARV_AD(i,2), ARV_AD(i,3),'gd');
plot3(ARV_AB(i,1), ARV_AB(i,2), ARV_AB(i,3),'c+');
hold on
set(handles.axes4,'XMinorTick','on') grid on
saveas(axes4,'grafici.fig');
end hold off
elseif strcmp(parametro,'rms') for i=1:nr_mis
plot3(RMS_EXT(i,1), RMS_EXT(i,2), RMS_EXT(i,3),'rs');
hold on
plot3(RMS_FLEX(i,1), RMS_FLEX(i,2), RMS_FLEX(i,3),'ko');
plot3(RMS_PRO(i,1), RMS_PRO(i,2), RMS_PRO(i,3),'*');
plot3(RMS_AD(i,1), RMS_AD(i,2), RMS_AD(i,3),'gd');
plot3(RMS_AB(i,1), RMS_AB(i,2), RMS_AB(i,3),'c+');
hold on
set(handles.axes4,'XMinorTick','on') grid on
saveas(axes4,'grafici.fig');
end hold off
elseif strcmp(parametro,'teta') for i=1:nr_mis
plot3(TETA_EXT(i,1), TETA_EXT(i,2), TETA_EXT(i,3),'rs');
hold on
plot3(TETA_FLEX(i,1), TETA_FLEX(i,2), TETA_FLEX(i,3),'ko');
plot3(TETA_PRO(i,1), TETA_PRO(i,2), TETA_PRO(i,3),'*');
plot3(TETA_AD(i,1), TETA_AD(i,2), TETA_AD(i,3),'gd');
plot3(TETA_AB(i,1), TETA_AB(i,2), TETA_AB(i,3),'c+');
hold on
set(handles.axes4,'XMinorTick','on') grid on
saveas(axes4,'grafici.fig');
end hold off
else errordlg('Invalid input!!!','ERROR DIALOG BOX','modal');
end
function edit5_Callback(hObject, eventdata, handles)
% hObject handle to edit5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit5 as text
% str2double(get(hObject,'String')) returns contents of edit5 as a double
global parametro
parametro = (get(handles.edit5, 'String'));
% --- Executes during object creation, after setting all properties.
function edit5_CreateFcn(hObject, eventdata, handles)
% hObject handle to edit5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton5 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Close the GUI and any plot window that is open close(EMGui)
Matlab function che calcola gli istanti di attivazione, esegue il finestraggio dei segnali calcolando i parametri arv, rms e teta.
% 'C' è l'acquisizione ritenuta buona in fase di calibrazione function [arv rms teta threshold] = win_par(C)
%envC = Inviluppo(C);%calcolo gli inviluppi dei canali
%Calcolo dell' onset.
for j = 1:3
sign = C(:,j);
[sampon soglia] = solonset(sign,1,length(sign));
on(j) = sampon;%creo un vettore degli onset dei tre canali threshold(j) = soglia;%creo un vettore delle soglie
end;
%Calcolo dei teta
if on(1) == 0 || on(2) == 0 tetaon12 = 0;
else tetaon12 = abs(on(1) - on(2));
end;
if on(1) == 0 || on(3) == 0 tetaon13 = 0;
else tetaon13 = abs(on(1) - on(3));
end;
if on(2) == 0 || on(3) == 0 tetaon23 = 0;
else tetaon23 = abs(on(2) - on(3));
end;
%Eseguo il finestraggio.
for n = 1:3
new_C(:,n) = C(on(n):on(n)+1999,n);
end;
%Creazione delle matrici dei parametri arv, rms e teta %[arv rms] = parametri(new_C);
for i = 1:3
par1(:,i) = ARV(new_C(:,i)); %Valore Medio Rettificato par2(:,i) = RMS(new_C(:,i)); %Valore Efficace
end;
arv = par1;
rms = par2;
teta = [tetaon12 tetaon13 tetaon23];
end
%=========================================================================%
%Questa funzione restituisce, per ogni movimento, le matrici dei 3
%parametri per i tre movimenti, sulle nr_mis misure,(9 matrici):
%
% parametro = [nr_mis x 3 canali]
%
%=========================================================================%
Matlab function che calcola la matrice dei valori medi e delle deviazioni standard dei paramentri misurati su 20 acquisizioni per ognuno dei 4 movimenti studiati.
function [arvm arvds rmsm rmsds] = calcolapar(par1, par2)
L = length(par1);
%costruisco una matrice [4*nr_mis x 3] con tutti gli arv dei 4 movimenti
%sui 3 canali for i = 1:3 volte = 0;
indice_row = 1;
for j = 1:L
if par1(j,i) ~= 0 volte = 1;
elseif volte == 1
arv(indice_row,i) = par1(j-1,i);
indice_row = indice_row + 1;
volte = 0;
end
end end;
%calcolo la matrice dei valori medi e delle dev.st. x il classificatore
%Simulink di dimensioni [movimenti x canali] (4x3)
for i = 1:3
arvm(1,i) = mean(arv(1:5,i));
arvm(2,i) = mean(arv(6:10,i));
arvm(3,i) = mean(arv(11:15,i));
arvm(4,i) = mean(arv(16:20,i));
arvds(1,i) = std(arv(1:5,i));
arvds(2,i) = std(arv(6:10,i));
arvds(3,i) = std(arv(11:15,i));
arvds(4,i) = std(arv(16:20,i));
end;
M = length(par2);
%costruisco una matrice [4*nr_mis x 3] con tutti gli rms2 dei 4 movimenti %sui 3 canali
for i = 1:3 volte = 0;
indice_row = 1;
for j = 1:L
if par2(j,i) ~= 0 volte = 1;
elseif volte == 1
rms(indice_row,i) = sqrt(par2(j-1,i));
indice_row = indice_row + 1;
volte = 0;
end
end end;
%calcolo la matrice dei valori medi e delle dev.st. x il classificatore %Simulink di dimensioni [movimenti x canali] (4x3)
for i = 1:3
rmsm(1,i) = mean(rms(1:5,i));
rmsm(2,i) = mean(rms(6:10,i));
rmsm(3,i) = mean(rms(11:15,i));
rmsm(4,i) = mean(rms(16:20,i));
rmsds(1,i) = std(rms(1:5,i));
rmsds(2,i) = std(rms(6:10,i));
rmsds(3,i) = std(rms(11:15,i));
rmsds(4,i) = std(rms(16:20,i));
end;
end
Matlab function per la costruzione e visualizzazione delle classi CUBE nello spazio dei canali.
function [] = calcolaclassi(vmedi,devst,k)
%plottaggio delle classi figure;
grid on hold on
%costruzione della matrice dei vertici ext1m_min = vmedi(1,1) - k*devst(1,1);
ext1m_max = vmedi(1,1) + k*devst(1,1);
ext2m_min = vmedi(1,2) - k*devst(1,2);
ext2m_max = vmedi(1,2) + k*devst(1,2);
ext3m_min = vmedi(1,3) - k*devst(1,3);
ext3m_max = vmedi(1,3) + k*devst(1,3);
vertici_ext = [ext1m_max ext2m_max ext3m_min;ext1m_min ext2m_max
ext3m_min;ext1m_min ext2m_min ext3m_min;ext1m_max ext2m_min ext3m_min;ext1m_max
ext2m_max ext3m_max;ext1m_min ext2m_max ext3m_max ;ext1m_min ext2m_min ext3m_max;ext1m_max ext2m_min ext3m_max];
connessioni_ext = [1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
patch('Vertices',vertici_ext,'Faces',connessioni_ext);
flex1m_min = vmedi(2,1) - k*devst(2,1);
flex1m_max = vmedi(2,1) + k*devst(2,1);
flex2m_min = vmedi(2,2) - k*devst(2,2);
flex2m_max = vmedi(2,2) + k*devst(2,2);
flex3m_min = vmedi(2,3) - k*devst(2,3);
flex3m_max = vmedi(2,3) + k*devst(2,3);
vertici_flex = [flex1m_max flex2m_max flex3m_min;flex1m_min flex2m_max flex3m_min;flex1m_min flex2m_min flex3m_min;flex1m_max flex2m_min
flex3m_min;flex1m_max flex2m_max flex3m_max;flex1m_min flex2m_max
flex3m_max;flex1m_min flex2m_min flex3m_max;flex1m_max flex2m_min flex3m_max];
connessioni_flex = [1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
patch('Vertices',vertici_flex,'Faces',connessioni_flex);
add1m_min = vmedi(3,1) - k*devst(3,1);
add1m_max = vmedi(3,1) + k*devst(3,1);
add2m_min = vmedi(3,2) - k*devst(3,2);
add2m_max = vmedi(3,2) + k*devst(3,2);
add3m_min = vmedi(3,3) - k*devst(3,3);
add3m_max = vmedi(3,3) + k*devst(3,3);
vertici_add = [add1m_max add2m_max add3m_min;add1m_min add2m_max
add3m_min;add1m_min add2m_min add3m_min;add1m_max add2m_min add3m_min;add1m_max add2m_max add3m_max;add1m_min add2m_max add3m_max;add1m_min add2m_min
add3m_max;add1m_max add2m_min add3m_max];
connessioni_add = [1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
patch('Vertices',vertici_add,'Faces',connessioni_add);
abd1m_min = vmedi(4,1) - k*devst(4,1);
abd1m_max = vmedi(4,1) + k*devst(4,1);
abd2m_min = vmedi(4,2) - k*devst(4,2);
abd2m_max = vmedi(4,2) + k*devst(4,2);
abd3m_min = vmedi(4,3) - k*devst(4,3);
abd3m_max = vmedi(4,3) + k*devst(4,3);
vertici_abd = [abd1m_max abd2m_max abd3m_min;abd1m_min abd2m_max
abd3m_min;abd1m_min abd2m_min abd3m_min;abd1m_max abd2m_min abd3m_min;abd1m_max abd2m_max abd3m_max;abd1m_min abd2m_max abd3m_max;abd1m_min abd2m_min
abd3m_max;abd1m_max abd2m_min abd3m_max];
connessioni_abd = [1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
patch('Vertices',vertici_abd,'Faces',connessioni_abd);
%hold off end
Embedded Matlab function che implementa il filtro di Kalman per il modello Simulink di
“Calibrazione” e “Real-Time Classification”.
function [stima, reale, varianzaposteriori,varianzapriori, stimafutura] = fcn(in, i1,i2)
PHI = [1 0 0; 0 1 0; 0 0 1];
Q = 0.0001 * [0.3299 -0.1645 -0.0188; -0.1645 0.3392 0.0186; -0.0188 0.0186 0.2193];%matrice di covarianza di processo, scelta considerando il caso peggiore
R = 0.1.*[1 0 0; 0 1 0; 0 0 1];
C = [1 0 0; 0 1 0; 0 0 1];
Xr =in; %ingresso
X = i1; %stima a priori Pp=i2; % varianza a priori
% Calcolo della matrice di guadagno del filtro di Kalman K = Pp * C' * inv(C * Pp * C' + R); % costante kalman [Z, Xr] = Processo(Xr);
% Aggiornamento della stima dello stato
Xn = X + K * (Z - C * X); % stima a posteriori
% Aggiornamento della varianza dei disturbi sullo stato e aggiornamento del ciclo
P = (eye(3) - K * C)* Pp; % stima a posteriori
% Aggiornamento dello stato
Xp = PHI * Xn; %stima dello stato futuro a k+1 stima a priori
% Aggiornamento della stima della varianza dell'errore sullo stato k+1 Pk = PHI * P * PHI' + Q; %stima a priori
stima=Xn;
reale =Xr;
varianzapriori=Pk; % varianza a priori
varianzaposteriori=P; % varianza a posteriori stimafutura=Xp;
function [Z, Xr] = Processo(Xr)
x1 = Xr;
%x1= x1;%+0.1*randn;
Z = x1 ; % misura dell stato x1
S-Function Matlab che implementa l’elaborazione per l’inizializzazione del clasificatore nel modello Simulink “Calibrazione”.
Spazio delle variabili di stato:
xD[0] = xD[0] + 1;
//
if (xD[0] >= 3000) {
if (xD[5] == 2000 && xD[10] == 2000 && xD[15] == 2000) {
xD[5] = 51; //riinizializzo le finestre xD[10] = 51;
xD[15] = 51;
xD[1] = 0; //azzero i contatori dei varchi xD[6] = 0;
xD[11] = 0;
xD[2] = 0; //azzero il blocco della ricerca degli onset xD[7] = 0;
xD[12] = 0;
xD[3] = 0; //azzero gli arv xD[8] = 0;
xD[13] = 0;
xD[4] = 0; //azzero gli rms2 xD[9] = 0;
xD[14] = 0;
} else {
if (xD[2] == 0) {
if (canale[0] >= soglia[0]) {
xD[1] = xD[1] + 1;
xD[3] = canale[0] + xD[3];
xD[4] = (canale[0]*canale[0]) + xD[4];
if (xD[1] == 50) {
xD[16]=xD[0] - 49;
xD[2] = 1;
} }
else {
xD[1] = 0;
xD[3] = 0;
xD[4] = 0;
} }
if (xD[1] == 50 && xD[0] < xD[16] + 1998) {
xD[5] = xD[5] + 1;
xD[3] = canale[0] + xD[3];
xD[4] = (canale[0]*canale[0]) + xD[4];
}
//
if (xD[7] == 0) {
if (canale[1] >= soglia[1]) {
xD[6] = xD[6] + 1;
xD[8] = canale[1] + xD[8];
xD[9] = (canale[1]*canale[1]) + xD[9];
if (xD[6] == 50) {
xD[17]=xD[0] - 49;
xD[7] = 1;
} }
else {
xD[6] = 0;
xD[8] = 0;
xD[9] = 0;
} }
if (xD[6] == 50 && xD[0] < xD[17] + 1998) {
xD[10] = xD[10] + 1;
xD[8] = canale[1] + xD[8];
xD[9] = (canale[1]*canale[1]) + xD[9];
} //
if (xD[12] == 0) {
if (canale[2] >= soglia[2]) {
xD[11] = xD[11] + 1;
xD[13] = canale[2] + xD[13];
xD[14] = (canale[2]*canale[2]) + xD[14];
if (xD[11] == 50) {
xD[18]=xD[0] - 49;
xD[12] = 1;
} }
else {
xD[11] = 0;
xD[13] = 0;
xD[14] = 0;
} }
if (xD[11] == 50 && xD[0] < xD[18] + 1998) {
xD[15] = xD[15] + 1;
xD[13] = canale[2] + xD[13];
xD[14] = (canale[2]*canale[2]) + xD[14];
} } }
Spazio degli outputs:
//
onset[0] = xD[16];
arv[0]=xD[3]/2000;
rms2[0]=xD[4]/2000;
finestra[0] = xD[5];
//
onset[1] = xD[17];
arv[1]=xD[8]/2000;
rms2[1]=xD[9]/2000;
finestra[1] = xD[10];
//
onset[2] = xD[18];
arv[2]=xD[13]/2000;
rms2[2]=xD[14]/2000;
finestra[2] = xD[15];
S-Funcion Matlab per la classificazione in tempo reale e il controllo del cursore su schermo del modello Simulink “Real-Time Application”.
NOTA: lo spazio delle variabili di stato è identico al listato precedente.
Spazio degli outputs:
onset[0] = xD[16];
arv[0]=xD[3]/2000;
rms2[0]=xD[4]/2000;
finestra[0] = xD[5];
onset[1] = xD[17];
arv[1]=xD[8]/2000;
rms2[1]=xD[9]/2000;
finestra[1] = xD[10];
onset[2] = xD[18];
arv[2]=xD[13]/2000;
rms2[2]=xD[14]/2000;
finestra[2] = xD[15];
if (xD[5]==2000 && xD[10]==2000 && xD[15]==2000) {
if (((fabs(arv[0]-arvm[0])<=3*arvst[0]) && (fabs(arv[1]- arvm[4])<=3*arvst[4]) && (fabs(arv[2]-arvm[8])<=3*arvst[8])) ||
((fabs(sqrt(rms2[0])-rmsm[0])<= 3*rmsst[0]) && (fabs(sqrt(rms2[1])-rmsm[4])<=
3*rmsst[4]) && (fabs(sqrt(rms2[2])-rmsm[8])<= 3*rmsst[8]))) {
y[0]= y[0]+1;
}
if (((fabs(arv[0]-arvm[3])<=5*arvst[3]) && (fabs(arv[1]- arvm[7])<=5*arvst[7]) && (fabs(arv[2]-arvm[11])<=5*arvst[11])) ||
((fabs(sqrt(rms2[0])-rmsm[3])<= 5*rmsst[3]) && (fabs(sqrt(rms2[3])-rmsm[7])<=
5*rmsst[7]) && (fabs(sqrt(rms2[2])-rmsm[11])<= 5*rmsst[11]))) {
x[0] = x[0]+1;
}
if (((fabs(arv[0]-arvm[1])<=4*arvst[1]) && (fabs(arv[1]- arvm[5])<=4*arvst[5]) && (fabs(arv[2]-arvm[9])<=4*arvst[9])) ||
((fabs(sqrt(rms2[0])-rmsm[1])<= 4*rmsst[1]) && (fabs(sqrt(rms2[1])-rmsm[5])<=
4*rmsst[5]) && (fabs(sqrt(rms2[2])-rmsm[9])<= 4*rmsst[9]))) {
y[0] = y[0]-1;
}
if (((fabs(arv[0]-arvm[2])<=3*arvst[2]) && (fabs(arv[1]- arvm[6])<=3*arvst[6]) && (fabs(arv[2]-arvm[10])<=3*arvst[10])) ||
((fabs(sqrt(rms2[0])-rmsm[2])<= 3*rmsst[2]) && (fabs(sqrt(rms2[1])-rmsm[6])<=
3*rmsst[6]) && (fabs(sqrt(rms2[2])-rmsm[10])<= 3*rmsst[10]))) {
x[0] = x[0]-1;
} }
Matlab function per il test di cross validation del classificatoreCUBE.
%miomatdati = matrice dei dati [80x7], dove 7 sono le features ( i 3 ARV e i
%tre RMS), l'ultima colonna sono le classi, e 80 sono gli 'esempi', ovvero le 20 acquisizioni per ogni classe
%(movimento).
%==========================================================================
%scelta del numero di esempi da usare come training e di quelli da usare
%come test.
numesempitrain = input('Inserisci quanti esempi vuoi per il training: da 1 a 19 '); %esempi per il training.
numesempitest = 20 - numesempitrain; %esempi per il test.
%%%%
box = confusMatrixStatInit(4); %inizializzazione della struttura confusMatrixStat.
%%%%
%CICLO DI CROSS VALIDATION for n = 1:20
%Estrazione dal miomatdati dei numesempitrain in maniera casuale.
index1 = randperm(20); %vettore riga di 20 numeri da 1 a 20 in ordine casuale.
for i = 1:20
dataset1(i,:) = miomatdati(index1(i),:);
end
index2 = randperm(20)+20;
for i = 1:20
dataset2(i,:) = miomatdati(index2(i),:);
end
index3 = randperm(20)+40;
for i = 1:20
dataset3(i,:) = miomatdati(index3(i),:);
end
index4 = randperm(20)+60;
for i = 1:20
dataset4(i,:) = miomatdati(index4(i),:);
end;
%Creazione della matrice dati per il training del classificatore 'cube':
[numesempitrain x 7].
datatrain = [dataset1(1:numesempitrain,:); dataset2(1:numesempitrain,:);
dataset3(1:numesempitrain,:); dataset4(1:numesempitrain,:)];
%Creazione della matrice dati per il test del classificatore 'cube':
[numesempitest x 7].
datatest = [dataset1(numesempitrain+1:end,:); dataset2(numesempitrain+1:end,:);
dataset3(numesempitrain+1:end,:); dataset4(numesempitrain+1:end,:)];
%Calcolo dei parametri per il classificatore dal datatrain: [4 x 6].
vmedi = [mean(datatrain(1:numesempitrain,1:end-1));
mean(datatrain(numesempitrain+1:2*numesempitrain,1:end-1));
mean(datatrain(2*numesempitrain+1:3*numesempitrain,1:end-1));
mean(datatrain(3*numesempitrain+1:4*numesempitrain,1:end-1))];
devst = [std(datatrain(1:numesempitrain,1:end-1));
std(datatrain(numesempitrain+1:2*numesempitrain,1:end-1));
std(datatrain(2*numesempitrain+1:3*numesempitrain,1:end-1));
std(datatrain(3*numesempitrain+1:4*numesempitrain,1:end-1))];
%%%%%%%%%%%%%
confusione = cubeclass(datatest, numesempitest, vmedi,devst, 2,2,2,2); %calcolo della matrice di confusione
box = confusMatrixStatAdd(box, confusione(:,1:4)); %calcolo delle statistiche di CROSS VALIDATION
end;
%%%%%%%%%%%%%
[boxMean, boxStd] = confusMatrixStatGet(box); %estraggo dalla struttura le matrici MEAN e STD sulle 10 mat di conf.
Matlab function per il test di classificazione e per la costruzione della matrice di confusione del test.
function [confusmat] = cubeclass(datatest, numesempitest, vmedi, devst, k1, k2, k3, k4)
%La funzione svolge le seguenti operazioni:
%
% 1) Test di classificazione col datatest fornito.
%
% 2) Construzione della matrice di confusione per il
% test.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% %%%%
%%%% PROCEDURA DI CLASSIFICAZIONE %%%%
%%%% %%%%
confusmat = zeros(4,5); %inizializzo la matrice di confusione: sulla colonna 5 i NON CLASSIFICATI in alcuna delle 4 classi.
for i = 1:4*numesempitest
confusprec = confusmat;
%%%%%BLOCCO ESTENSIONE
if ((abs(datatest(i,1) - vmedi(1,1))<= k1*devst(1,1)) && (abs(datatest(i,2) - vmedi(1,2))<= k1*devst(1,2)) && (abs(datatest(i,3) - vmedi(1,3))<=
k1*devst(1,3))) || ((abs(datatest(i,4) - vmedi(1,4))<= k1*devst(1,4)) &&
(abs(datatest(i,5) - vmedi(1,5))<= k1*devst(1,5)) && (abs(datatest(i,6) - vmedi(1,6))<= k1*devst(1,6)))
if datatest(i,end) == 1; % riconoscimento esatto dell'EXT.
confusmat(1,1) = confusmat(1,1) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 2; % scambio con la FLEX.
confusmat(1,2) = confusmat(1,2) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 3; % scambio con la ADD.
confusmat(1,3) = confusmat(1,3) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 4; % scambio con la ABD.
confusmat(1,4) = confusmat(1,4) + 1; %aggiornamento della matrice di confusione.
end;
end;
%%%%%BLOCCO FLESSIONE
if ((abs(datatest(i,1) - vmedi(2,1))<= k2*devst(2,1)) && (abs(datatest(i,2) - vmedi(2,2))<= k2*devst(2,2)) && (abs(datatest(i,3) - vmedi(2,3))<=
k2*devst(2,3))) || ((abs(datatest(i,4) - vmedi(2,4))<= k2*devst(2,4)) &&
(abs(datatest(i,5) - vmedi(2,5))<= k2*devst(2,5)) && (abs(datatest(i,6) - vmedi(2,6))<= k2*devst(2,6)))
if datatest(i,end) == 1; % scambio con l'EXT.
confusmat(2,1) = confusmat(2,1) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 2; % riconoscimento esatto della FLEX.
confusmat(2,2) = confusmat(2,2) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 3; % scambio con la ADD.
confusmat(2,3) = confusmat(2,3) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 4; % scambio con la ABD.
confusmat(2,4) = confusmat(2,4) + 1; %aggiornamento della matrice di confusione.
end;
end;
%%%%%BLOCCO ADDUZIONE
if ((abs(datatest(i,1) - vmedi(3,1))<= k3*devst(3,1)) && (abs(datatest(i,2) - vmedi(3,2))<= k3*devst(3,2)) && (abs(datatest(i,3) - vmedi(3,3))<=
k3*devst(3,3))) || ((abs(datatest(i,4) - vmedi(3,4))<= k3*devst(3,4)) &&
(abs(datatest(i,5) - vmedi(3,5))<= k3*devst(3,5)) && (abs(datatest(i,6) - vmedi(3,6))<= k3*devst(3,6)))
if datatest(i,end) == 1; % scambio con l'EXT.
confusmat(3,1) = confusmat(3,1) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 2; % scambio con la FLEX.
confusmat(3,2) = confusmat(3,2) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 3; % riconoscimento esatto della ADD.
confusmat(3,3) = confusmat(3,3) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 4; % scambio con la ABD.
confusmat(3,4) = confusmat(3,4) + 1; %aggiornamento della matrice di confusione.
end;
end;
%%%%%BLOCCO ABDUZIONE
if ((abs(datatest(i,1) - vmedi(4,1))<= k4*devst(4,1)) && (abs(datatest(i,2) - vmedi(4,2))<= k4*devst(4,2)) && (abs(datatest(i,3) - vmedi(4,3))<=
k4*devst(4,3))) || ((abs(datatest(i,4) - vmedi(4,4))<= k4*devst(4,4)) &&
(abs(datatest(i,5) - vmedi(4,5))<= k4*devst(4,5)) && (abs(datatest(i,6) - vmedi(4,6))<= k4*devst(4,6)))
if datatest(i,end) == 1; % scambio con l'EXT.
confusmat(4,1) = confusmat(4,1) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 2; % scambio con la FLEX.
confusmat(4,2) = confusmat(4,2) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 3; % scambio con la ADD.
confusmat(4,3) = confusmat(4,3) + 1; %aggiornamento della matrice di confusione.
elseif datatest(i,end) == 4; % riconoscimento esatto della ABD.
confusmat(4,4) = confusmat(4,4) + 1; %aggiornamento della matrice di confusione.
end;
end;
%%%%BLOCCO DI NON CLASSIFICAZIONE
if confusmat(:,1:4) == confusprec (:,1:4)
if datatest(i,end) == 1; %EXT.
confusmat(1,5) = confusmat(1,5) + 1;
elseif datatest(i,end) == 2; %FLEX.
confusmat(2,5) = confusmat(2,5) + 1;
elseif datatest(i,end) == 3; %ADD.
confusmat(3,5) = confusmat(3,5) + 1;
elseif datatest(i,end) == 4; %ABD.
confusmat(4,5) = confusmat(4,5) + 1;
end end;
end; %finito il ciclo ho completato la matrice di confusione.
confusmat = [confusmat/numesempitest]; %normalizzazione dellla matrice di confusione.
end
Strutture Matlab per la gestione del test di cross validation.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% [ confusStat ] = confusMatrixStatInit(numClasses)
%
function [ confusStat ] = confusMatrixStatInit(numClasses)
confusStat.data = [];
confusStat.classes = numClasses;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% [ confusStat ] = confusMatrixStatAdd(confusStat, confus)
%
function [ confusStat ] = confusMatrixStatAdd(confusStat, confus) r = confusStat.classes;
row = [];
for i=1:r
row = [ row, confus(i,:) ];
end
confusStat.data = [ confusStat.data; row ];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% [ confusMean, confusStd ] = confusMatrixStatGet(confusStat)
%
function [ confusMean confusStd ] = confusMatrixStatGet(confusStat) r = confusStat.classes;
cMean = mean(confusStat.data);
cStd = std(confusStat.data);
confusMean = [];
confusStd = [];
for i=1:r
confusMean = [ confusMean; cMean( ((i-1)*r+1):((i-1)*r+r) ) ];
confusStd = [ confusStd; cStd( ((i-1)*r+1):((i-1)*r+r) ) ];
end
Matlab GUI per la gestione della precalibrazione, della calibrazione e dell’applicazione real- time di classificazione e controllo cursore.
function varargout = EMGui1(varargin)
% EMGUI1 M-file for EMGui1.fig
% EMGUI1, by itself, creates a new EMGUI1 or raises the existing
% singleton*.
%
% H = EMGUI1 returns the handle to a new EMGUI1 or the handle to
% the existing singleton*.
%
% EMGUI1('CALLBACK',hObject,eventData,handles,...) calls the local
% function named CALLBACK in EMGUI1.M with the given input arguments.
%
% EMGUI1('Property','Value',...) creates a new EMGUI1 or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before EMGui1_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to EMGui1_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one
% instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help EMGui1
% Last Modified by GUIDE v2.5 28-May-2008 18:50:57
% Begin initialization code - DO NOT EDIT gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @EMGui1_OpeningFcn, ...
'gui_OutputFcn', @EMGui1_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before EMGui1 is made visible.
function EMGui1_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin command line arguments to EMGui1 (see VARARGIN)
% Choose default command line output for EMGui1 handles.output = hObject;
% Update handles structure guidata(hObject, handles);
% UIWAIT makes EMGui1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
Calibrazione2; %apre il modello Simulink per la calibrazione pause(1);
set_param('Calibrazione2/soglie','Value','[0 0 0]');%inizializzo le soglie rtwbuild('Calibrazione2');% esegue il "build"
pause(1);
global arvm arvds rmsm rmsds;global threshold;
arvm=[]; arvds=[]; rmsm=[]; rmsds=[];threshold =[];
% --- Outputs from this function are returned to the command line.
function varargout = EMGui1_OutputFcn(hObject, eventdata, handles)
% varargout cell array for returning output args (see VARARGOUT);
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure varargout{1} = handles.output;
% --- Executes on button press in pushbutton1.
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)
set_param('Calibrazione2','SimulationCommand','Connect');
pause(2.5);
set_param('Calibrazione2','SimulationCommand','Start');
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA) global arvm arvds rmsm rmsds;
set_param('Calibrazione2','SimulationCommand','Stop');%termina l'acquisizione
pause(1);%aspetta
set_param('Calibrazione2','SimulationCommand','Disconnect'); %disconnette il modulo simulink dal target
%fase di elaborazione
ARV = evalin('base','arv');%prelevo dal workspace le variabili salvate dalla fase di acquisizione
RMS2 = evalin('base','rms2');
[arvm arvds rmsm rmsds] = calcolapar(ARV,RMS2);%funzione che calcola le matrici di calibrazione per il classificatore
%per verifica salvo le matrici [4x3]
save ARVM arvm;
save ARVDS arvds;
save RMSM rmsm;
save RMSDS rmsds;
save pararv ARV;
save parrms2 RMS2;
SEGNALI = evalin('base','ScopeData');
save ScopeData SEGNALI;
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global arvm arvds rmsm rmsds;global threshold;
Realtime7; %apro il modello Simulink x la classificazione pause(1);
%inizializzo le matrici di calibrazione per il classificatore e le soglie
set_param('Realtime7/arvm','Value',['[',num2str(arvm(1,:)),';',num2str(arvm(2,:) ),';',num2str(arvm(3,:)),';',num2str(arvm(4,:)),']']);
set_param('Realtime7/arvst','Value',['[',num2str(arvds(1,:)),';',num2str(arvds(2 ,:)),';',num2str(arvds(3,:)),';',num2str(arvds(4,:)),']']);
set_param('Realtime7/rmsm','Value',['[',num2str(rmsm(1,:)),';',num2str(rmsm(2,:) ),';',num2str(rmsm(3,:)),';',num2str(rmsm(4,:)),']']);
set_param('Realtime7/rmsst','Value',['[',num2str(rmsds(1,:)),';',num2str(rmsds(2 ,:)),';',num2str(rmsds(3,:)),';',num2str(rmsds(4,:)),']']);
set_param('Realtime7/soglie','Value',['[',num2str(threshold),']']);
%set_param('Realtime7/soglie','Value','[0.015 0.015 0.02]');
rtwbuild('Realtime7');% esegue il "build"
pause(1);
%inizio l'acquisizione
set_param('Realtime7','SimulationCommand','Connect');
pause(2.5);
set_param('Realtime7','SimulationCommand','Start');
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA) global threshold;
%Precalibrazione
%acquisisco rumore per circa 8s
set_param('Calibrazione2','SimulationCommand','Connect');%avvia l'acquisizione pause(1);
set_param('Calibrazione2','SimulationCommand','Start');
pause(8)
set_param('Calibrazione2','SimulationCommand','Stop');%termina l'acquisizione pause(1);
set_param('Calibrazione2','SimulationCommand','Disconnect');%disconnette il modulo simulink
signal = evalin('base','ScopeData');%prelevo dal workspace il segnale acquisito come inviluppo
C = Sep_Rett(signal);%nella matrice C ho i 3 canali utili senza il tempo
%calcolo delle soglie dei canali su 2000smps for i = 1:3
sign = C(:,i);
threshold(i) = mean(sign(3000:6000)) + 5*std(sign(3000:6000));
end;
set_param('Calibrazione2/soglie','Value',['[',num2str(threshold),']']);
rtwbuild('Calibrazione2');% esegue il "build"