• Non ci sono risultati.

ƒ Matlab function per la stima dell’SNR sul tracciato EMG.

N/A
N/A
Protected

Academic year: 2021

Condividi "ƒ Matlab function per la stima dell’SNR sul tracciato EMG. "

Copied!
33
0
0

Testo completo

(1)

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

(2)

% 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

(3)

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;

(4)

ƒ 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

(5)

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

(6)

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

(7)

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

(8)

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.

(9)

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

(10)

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

(11)

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;

(12)

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;

%%==========================%%

(13)

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

(14)

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

(15)

% --- 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

(16)

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

(17)

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

(18)

%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

(19)

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

(20)

ƒ 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)

(21)

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;

(22)

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];

} } }

(23)

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;

}

(24)

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),:);

(25)

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.

(26)

ƒ 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;

(27)

%%%%%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.

(28)

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;

(29)

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)

%

(30)

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

(31)

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

(32)

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

(33)

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"

Riferimenti

Documenti correlati

Si osserva che, pur essendo tutti gli autovalori di B inclusi nell’intervallo [10 −6 , 10 −2 ], ed essendo massimo il rango della matrice (pari alla dimensione della matrice),

Il contenuto della parentesi che seguono l'istruzione writeln può essere sia un'espressione (stringa o numerica), sia una variabile sia una combinazione. La parte testuale è

• Regola 3: Anche se le stringhe di formato della scanf() assomigliano molto a quelle della printf(), hanno una semantica leggermente differente (leggete il manuale!). • Regola

By default, each function and data file will use a different line type and point type, up to the maximum number of available types. All terminal drivers support at least six

Indeed, by default I-DLV output is produced in a numeric format compliant with the mentioned solvers.. In order to interoperate with a

whose name is distinct from all other existing files, and opens the file for binary writing and reading (as if the mode string &#34;wb+&#34; were used in an fopen() call). If

© 2000 Pier Luca Montessoro (si veda la nota di copyright alla slide n. 2) 2 Questo insieme di trasparenze (detto nel seguito slide) è protetto dalle leggi sul copyright e

Per aprire uno stream di output occorre dichiarare che appartiene alla classe ofstream: ofstream out;.. Uno stream che eseguirà operazioni di input ed output deve appartenere