diff --git a/BioPatRec.m b/BioPatRec.m index a212506..b393c9c 100644 --- a/BioPatRec.m +++ b/BioPatRec.m @@ -1,32 +1,32 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% BioPatRec is a research platform for testing and development of -% algorithms for prosthetic control. This function call the main GUI. -% For more information and documention visit: -% http://code.google.com/p/biopatrec/ -% -% ------------------------- Updates & Contributors ------------------------ -% 2009-04-02 / Max Ortiz / Creation of EMG_AQ -% 2011-22-06 / Max Ortiz / Software name changed from EMG_AQ to BioPatRec - -close all; -clear all; - -%EMG_AQ -GUI_BioPatRec; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% BioPatRec is a research platform for testing and development of +% algorithms for prosthetic control. This function call the main GUI. +% For more information and documention visit: +% http://code.google.com/p/biopatrec/ +% +% ------------------------- Updates & Contributors ------------------------ +% 2009-04-02 / Max Ortiz / Creation of EMG_AQ +% 2011-22-06 / Max Ortiz / Software name changed from EMG_AQ to BioPatRec + +close all; +clear all; + +%EMG_AQ +GUI_BioPatRec; diff --git a/Comm/AFE/Acquire_tWs.m b/Comm/AFE/Acquire_tWs.m new file mode 100644 index 0000000..f706ea5 --- /dev/null +++ b/Comm/AFE/Acquire_tWs.m @@ -0,0 +1,68 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-1-12 / Enzo Mastinu / Divided the RecordingSession function into + % several functions: ConnectDevice(), + % SetDeviceStartAcquisition(), + % Acquire_tWs(), StopAcquisition(). This functions + % has been moved to COMM/AFE folder, into this new script. + +% 20xx-xx-xx / Author / Comment + + + +% It acquire tWs samples from the selected device +function cData = Acquire_tWs(deviceName, obj, nCh, tWs) + + cData = zeros(tWs,nCh); % this is the data structure that the function must return + ampPP = 0.0005; + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + + + %%%%% ADS1299 %%%%% + if strcmp(deviceName, 'ADS1299') + LSBweight = double(4.5/(24*8388607)); % ADS1299: if gain is set on 24 V/V + for sampleNr = 1:tWs + % 27bytes package mode + byteData = fread(obj,27,'char'); % Acquire 27 bytes packet from Tiva (and from ADS1299), 3 status bytes + 3 byte (24bit) for each channel + value = [65536 256 1]*reshape(byteData(4:end), 3, 8); % all channels data are now available on value vector, byteData(4:end) means throw away status bytes + for k = 1:nCh + if value(k) > 8388607 % the data must be converted from 2's complement + value(k) = value(k) - 2^24; + end + cData(sampleNr,k) = value(k) * LSBweight; + end + end + end + + %%%%% INTAN RHA2216 %%%%% + if strcmp(deviceName, 'RHA2216') + LSBweight = double(2.5/(200*65535)); % Intan differential gain is 200 V/V + for sampleNr = 1:tWs + value16 = fread(obj,nCh,'uint16'); + for k = 1:nCh +% cData(sampleNr,k) = value16(k) - 16384; % Centers data and scales it to fit the graphs + cData(sampleNr,k) = value16(k)*LSBweight; % Convert data into volt + end + end + end + +end diff --git a/Comm/AFE/ConnectDevice.m b/Comm/AFE/ConnectDevice.m new file mode 100644 index 0000000..a5fddc1 --- /dev/null +++ b/Comm/AFE/ConnectDevice.m @@ -0,0 +1,88 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-1-12 / Enzo Mastinu / Divided the RecordingSession function into + % several functions: ConnectDevice(), + % SetDeviceStartAcquisition(), + % Acquire_tWs(), StopAcquisition(). This functions + % has been moved to COMM/AFE folder, into this new script. + + +% 20xx-xx-xx / Author / Comment + + + +% it creates IP object and sets the buffersize depending on the device that has been chose +function obj = ConnectDevice(handles) + + deviceName = handles.deviceName; + ComPortType = handles.ComPortType; + if strcmp(ComPortType, 'COM') + ComPortName = handles.ComPortName; + end + sF = handles.sF; + sT = handles.sT; + nCh = handles.nCh; + sTall = handles.sTall; + + % Delete previous connection objects + if exist('obj') + fclose(obj); + delete(obj); + end + + %%%%% WiFi %%%%% + if strcmp(ComPortType, 'WiFi') + %%%%% TI ADS1299 %%%%% + if strcmp(deviceName, 'ADS1299') + obj = tcpip('192.168.100.10',65100,'NetworkRole','client'); % WIICOM + obj.InputBufferSize = sTall*sF*27; % 27bytes data package + end + %%%%% INTAN RHA2216 %%%%% + if strcmp(deviceName, 'RHA2216') + obj = tcpip('192.168.100.10',65100,'NetworkRole','client'); % WIICOM + obj.InputBufferSize = sT*sF*nCh*2; + end + end + + %%%%% COM %%%%% + if strcmp(ComPortType, 'COM') + %%%%% TI ADS1299 %%%%% + if strcmp(deviceName, 'ADS1299') + obj = serial (ComPortName, 'baudrate', 2500000, 'databits', 8, 'byteorder', 'bigEndian'); + obj.InputBufferSize = sTall*sF*27; % 27bytes data package + end + %%%%% INTAN RHA2216 %%%%% + if strcmp(deviceName, 'RHA2216') + obj = serial (ComPortName, 'baudrate', 1250000, 'databits', 8, 'byteorder', 'bigEndian'); + obj.InputBufferSize = sT*sF*nCh*2; + end + end + + % Open the connection + fopen(obj); + + % Read available data and discard it + if obj.BytesAvailable > 1 + fread(obj,obj.BytesAvailable,'uint8'); + end +% disp(obj); + +end diff --git a/Comm/AFE/NI_USB6009/InitNI.m b/Comm/AFE/NI_USB6009/InitNI.m index 5ae28d6..857a0cb 100644 --- a/Comm/AFE/NI_USB6009/InitNI.m +++ b/Comm/AFE/NI_USB6009/InitNI.m @@ -1,108 +1,108 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to Initialize the NI-6009 -% ch Channels, binary string -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-27 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - - -function [ai, ao, dio] = InitNI(sF, sT, chAI) - -% Close possible daq objects running -if (~isempty(daqfind)) - stop(daqfind) -end - -% Use this command to determine Board IDs in system, if needed -hw = daqhwinfo('nidaq'); -hw.InstalledBoardIds; -hw.BoardNames - -%% Analog Inputs -% Create an analog input object using Board ID. -ai = analoginput('nidaq','Dev1'); - -% Set the sample rate and samples per trigger -ai.SampleRate = sF; -ai.SamplesPerTrigger = sF*sT; - -% Set Inputy Type and Ranges -%set(ai,'InputType','Differential'); -set(ai,'InputType','SingleEnde'); - -% Add chanels -if chAI(1) - addchannel(ai, 0,'ch0'); - set(ai.ch0,'InputRange',[-10 10]); -end -if chAI(2) - addchannel(ai, 1,'ch1'); - set(ai.ch1,'InputRange',[-10 10]); -end -if chAI(3) - addchannel(ai, 2,'ch2'); - set(ai.ch2,'InputRange',[-10 10]); -end -if chAI(4) - addchannel(ai, 3,'ch3'); - set(ai.ch3,'InputRange',[-10 10]); -end -if chAI(5) - addchannel(ai, 4,'ch4'); - set(ai.ch4,'InputRange',[-10 10]); -end -if chAI(6) - addchannel(ai, 5,'ch5'); - set(ai.ch5,'InputRange',[-10 10]); -end -if chAI(7) - addchannel(ai, 6,'ch6'); - set(ai.ch6,'InputRange',[-10 10]); -end -if chAI(8) - addchannel(ai, 7,'ch7'); - set(ai.ch7,'InputRange',[-10 10]); -end - -disp(ai); -% %% Analog Outputs -% % Create an analog input object using Board ID "Dev1". -% ao = analogoutput('nidaq','Dev1'); -% -% % Add channels -% addchannel(ao, 0, 'ch0'); -% -% % Security -% putsample(ao,0); % Zero exit -% -% %% Digital Input Outputs -% %Create an analog input object using Board ID "Dev1". -% dio = digitalio('nidaq', 'Dev1'); -% -% % Add channels -% addline(dio, 0:3, 1, 'Out'); % Port 1 as Output -% addline(dio, 0:7, 0, 'In'); % Port 0 as Inputs -% -% % Security -% putvalue(dio.Line([1 2]), [1 1]); % Stop motor - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to Initialize the NI-6009 +% ch Channels, binary string +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-27 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function [ai, ao, dio] = InitNI(sF, sT, chAI) + +% Close possible daq objects running +if (~isempty(daqfind)) + stop(daqfind) +end + +% Use this command to determine Board IDs in system, if needed +hw = daqhwinfo('nidaq'); +hw.InstalledBoardIds; +hw.BoardNames + +%% Analog Inputs +% Create an analog input object using Board ID. +ai = analoginput('nidaq','Dev1'); + +% Set the sample rate and samples per trigger +ai.SampleRate = sF; +ai.SamplesPerTrigger = sF*sT; + +% Set Inputy Type and Ranges +%set(ai,'InputType','Differential'); +set(ai,'InputType','SingleEnde'); + +% Add chanels +if chAI(1) + addchannel(ai, 0,'ch0'); + set(ai.ch0,'InputRange',[-10 10]); +end +if chAI(2) + addchannel(ai, 1,'ch1'); + set(ai.ch1,'InputRange',[-10 10]); +end +if chAI(3) + addchannel(ai, 2,'ch2'); + set(ai.ch2,'InputRange',[-10 10]); +end +if chAI(4) + addchannel(ai, 3,'ch3'); + set(ai.ch3,'InputRange',[-10 10]); +end +if chAI(5) + addchannel(ai, 4,'ch4'); + set(ai.ch4,'InputRange',[-10 10]); +end +if chAI(6) + addchannel(ai, 5,'ch5'); + set(ai.ch5,'InputRange',[-10 10]); +end +if chAI(7) + addchannel(ai, 6,'ch6'); + set(ai.ch6,'InputRange',[-10 10]); +end +if chAI(8) + addchannel(ai, 7,'ch7'); + set(ai.ch7,'InputRange',[-10 10]); +end + +disp(ai); +% %% Analog Outputs +% % Create an analog input object using Board ID "Dev1". +% ao = analogoutput('nidaq','Dev1'); +% +% % Add channels +% addchannel(ao, 0, 'ch0'); +% +% % Security +% putsample(ao,0); % Zero exit +% +% %% Digital Input Outputs +% %Create an analog input object using Board ID "Dev1". +% dio = digitalio('nidaq', 'Dev1'); +% +% % Add channels +% addline(dio, 0:3, 1, 'Out'); % Port 1 as Output +% addline(dio, 0:7, 0, 'In'); % Port 0 as Inputs +% +% % Security +% putvalue(dio.Line([1 2]), [1 1]); % Stop motor + + diff --git a/Comm/AFE/NI_USB6009/Init_NI_AI.m b/Comm/AFE/NI_USB6009/Init_NI_AI.m index d9da6ee..07e4678 100644 --- a/Comm/AFE/NI_USB6009/Init_NI_AI.m +++ b/Comm/AFE/NI_USB6009/Init_NI_AI.m @@ -1,104 +1,104 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to Initialize the NI-6009 Analog Inputs -% Input = Handles -% Output = ai object -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-03-31 / Max Ortiz / Creation -% 2011-06-19 / Max Ortiz /Modified for general numer of channels -% 20xx-xx-xx / Author / Comment on update - - -function [ai,chp] = Init_NI_AI(handles,sF,sT,nCh) - -% Close possible daq objects running -if (~isempty(daqfind)) - stop(daqfind) -end - -% Use this command to determine Board IDs in system, if needed -hw = daqhwinfo('nidaq'); -hw.InstalledBoardIds; -hw.BoardNames - -% Create an analog input object using Board ID "Dev6". -ai = analoginput('nidaq','Dev1'); - -% Set the sample rate and samples per trigger -ai.SampleRate = sF; -ai.SamplesPerTrigger = sF*sT; - -% Set Inputy Type and Ranges -%set(ai,'InputType','Differential'); -set(ai,'InputType','SingleEnde'); - -% Add all chanels -if get(handles.cb_ch0,'Value') == 1 && nCh > 0 - addchannel(ai, 0,'ch0'); - set(ai.ch0,'InputRange',[-10 10]); - chp(1)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch1,'Value') == 1 && nCh > 0 - addchannel(ai, 1,'ch1'); - set(ai.ch1,'InputRange',[-10 10]); - chp(2)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch2,'Value') == 1 && nCh > 0 - addchannel(ai, 2,'ch2'); - set(ai.ch2,'InputRange',[-10 10]); - chp(3)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch3,'Value') == 1 && nCh > 0 - addchannel(ai, 3,'ch3'); - set(ai.ch3,'InputRange',[-10 10]); - chp(4)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch4,'Value') == 1 && nCh > 0 - addchannel(ai, 4,'ch4'); - set(ai.ch4,'InputRange',[-10 10]); - chp(5)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch5,'Value') == 1 && nCh > 0 - addchannel(ai, 5,'ch5'); - set(ai.ch5,'InputRange',[-10 10]); - chp(6)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch6,'Value') == 1 && nCh > 0 - addchannel(ai, 6,'ch6'); - set(ai.ch6,'InputRange',[-10 10]); - chp(7)=1; - nCh = nCh - 1; -end -if get(handles.cb_ch7,'Value') == 1 && nCh > 0 - addchannel(ai, 7,'ch7'); - set(ai.ch7,'InputRange',[-10 10]); - chp(8)=1; -end - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to Initialize the NI-6009 Analog Inputs +% Input = Handles +% Output = ai object +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-03-31 / Max Ortiz / Creation +% 2011-06-19 / Max Ortiz /Modified for general numer of channels +% 20xx-xx-xx / Author / Comment on update + + +function [ai,chp] = Init_NI_AI(handles,sF,sT,nCh) + +% Close possible daq objects running +if (~isempty(daqfind)) + stop(daqfind) +end + +% Use this command to determine Board IDs in system, if needed +hw = daqhwinfo('nidaq'); +hw.InstalledBoardIds; +hw.BoardNames + +% Create an analog input object using Board ID "Dev6". +ai = analoginput('nidaq','Dev1'); + +% Set the sample rate and samples per trigger +ai.SampleRate = sF; +ai.SamplesPerTrigger = sF*sT; + +% Set Inputy Type and Ranges +%set(ai,'InputType','Differential'); +set(ai,'InputType','SingleEnde'); + +% Add all chanels +if get(handles.cb_ch0,'Value') == 1 && nCh > 0 + addchannel(ai, 0,'ch0'); + set(ai.ch0,'InputRange',[-10 10]); + chp(1)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch1,'Value') == 1 && nCh > 0 + addchannel(ai, 1,'ch1'); + set(ai.ch1,'InputRange',[-10 10]); + chp(2)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch2,'Value') == 1 && nCh > 0 + addchannel(ai, 2,'ch2'); + set(ai.ch2,'InputRange',[-10 10]); + chp(3)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch3,'Value') == 1 && nCh > 0 + addchannel(ai, 3,'ch3'); + set(ai.ch3,'InputRange',[-10 10]); + chp(4)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch4,'Value') == 1 && nCh > 0 + addchannel(ai, 4,'ch4'); + set(ai.ch4,'InputRange',[-10 10]); + chp(5)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch5,'Value') == 1 && nCh > 0 + addchannel(ai, 5,'ch5'); + set(ai.ch5,'InputRange',[-10 10]); + chp(6)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch6,'Value') == 1 && nCh > 0 + addchannel(ai, 6,'ch6'); + set(ai.ch6,'InputRange',[-10 10]); + chp(7)=1; + nCh = nCh - 1; +end +if get(handles.cb_ch7,'Value') == 1 && nCh > 0 + addchannel(ai, 7,'ch7'); + set(ai.ch7,'InputRange',[-10 10]); + chp(8)=1; +end + + + + diff --git a/Comm/AFE/NI_USB6009/NI_DataShow.m b/Comm/AFE/NI_USB6009/NI_DataShow.m index 35c1d2e..226d815 100644 --- a/Comm/AFE/NI_USB6009/NI_DataShow.m +++ b/Comm/AFE/NI_USB6009/NI_DataShow.m @@ -1,237 +1,237 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to Show data on the GUI -% Input = ai object, sCh channels pressences -% Output = data and time -% Max J. Ortiz C. -% 09-04-15 -% hGUI_Rec = handles from the GUI_Recordings -% ai = analog input "object" -% sCh = Selected channels, binary string to indicate which channels have been selected -% sF = Sample frequency -% sT = Samople time -% pT = peek time -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - - -function cdata = NI_DataShow(handles, ai, sCh, sF, sT, pT) - -% Setting for data peeking -tt = 0:1/sF:pT-1/sF; % Create vector of time -data = zeros(length(tt),8); % Current data - -% Create handles for the plots -% this is faster than creating the plot everytime -if sCh(1) - axes(handles.a_t0); - p_t0 = plot(tt,data(:,1)); - axes(handles.a_f0); - p_f0 = plot(1,1); -end -if sCh(2) - axes(handles.a_t1); - p_t1 = plot(tt,data(:,2)); - axes(handles.a_f1); - p_f1 = plot(1,1); -end -if sCh(3) - axes(handles.a_t2); - p_t2 = plot(tt,data(:,3)); - axes(handles.a_f2); - p_f2 = plot(1,1); -end - -if sCh(4) - axes(handles.a_t3); - p_t3 = plot(tt,data(:,4)); - axes(handles.a_f3); - p_f3 = plot(1,1); -end - -if length(sCh) > 4 % Conditional added to keep compatibility with previous versions - if sCh(5) - axes(handles.a_t4); - p_t4 = plot(tt,data(:,5)); - %axes(handles.a_f4); - %p_f4 = plot(1,1); - end - - if sCh(6) - axes(handles.a_t5); - p_t5 = plot(tt,data(:,6)); - %axes(handles.a_f5); - %p_f5 = plot(1,1); - end - - if sCh(7) - axes(handles.a_t6); - p_t6 = plot(tt,data(:,7)); - %axes(handles.a_f6); - %p_f6 = plot(1,1); - end - - if sCh(8) - axes(handles.a_t7); - p_t7 = plot(tt,data(:,8)); - %axes(handles.a_f7); - %p_f7 = plot(1,1); - end -end - -%% Start DAQ -start(ai); -%ao = init_ao(); test of ao, hardware connections must be done - -% Wait until the first samples are aquired -while ai.SamplesAcquired < sF*pT -end -% Peek Data -while ai.SamplesAcquired < sT*sF - - %putsample(ao,5); test of ao - - % Peek data - set(handles.t_msg,'String',['Peek at: ' num2str(ai.SamplesAcquired)]) % Show message about acquisition - data = peekdata(ai,pT*sF); - data = FilterData(data, handles, sF); %Filter the data - % Fast Fourier Transform - aNs = length(data(:,1)); - NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(data(1:aNs,:),NFFT)/aNs; - m = 2*abs(dataf((1:NFFT/2),:)); - - chi = 1; %Channel Index for map data - if sCh(1) - set(p_t0,'YData',data(:,chi)); - set(p_f0,'XData',f); - set(p_f0,'YData',m(:,chi)); - chi=chi+1; - end - if sCh(2) - set(p_t1,'YData',data(:,chi)); - set(p_f1,'XData',f); - set(p_f1,'YData',m(:,chi)); - chi=chi+1; - end - if sCh(3) - set(p_t2,'YData',data(:,chi)); - set(p_f2,'XData',f); - set(p_f2,'YData',m(:,chi)); - chi=chi+1; - end - if sCh(4) - set(p_t3,'YData',data(:,chi)); - set(p_f3,'XData',f); - set(p_f3,'YData',m(:,chi)); - chi=chi+1; - end - if length(sCh) > 4 - if sCh(5) - set(p_t4,'YData',data(:,chi)); - chi=chi+1; - %set(p_f4,'XData',f); - %set(p_f4,'YData',m(:,chi)); - end - if sCh(6) - set(p_t5,'YData',data(:,chi)); - chi=chi+1; - %set(p_f5,'XData',f); - %set(p_f5,'YData',m(:,chi)); - end - if sCh(7) - set(p_t6,'YData',data(:,chi)); - chi=chi+1; - %set(p_f6,'XData',f); - %set(p_f6,'YData',m(:,chi)); - end - if sCh(8) - set(p_t7,'YData',data(:,chi)); - %set(p_f7,'XData',f); - %set(p_f7,'YData',m(:,chi)); - end - end - - drawnow -end - -wait(ai,sT+1); %Wait until the daq is over or until sT+1 is reached -[data,time,abstime] = getdata(ai); -abstime = fix(abstime); -set(handles.t_msg,'String',['DAQ Done ' num2str(abstime(4)) ':' num2str(abstime(5))]) % Show message about acquisition - - -% Save acquired data into cdata -% Settings for total data -tt = time; % Create vector of time -chi=1; -if sCh(1) == 1 - cdata(:,1) = data(:,chi); - set(p_t0,'XData',tt); - set(p_t0,'YData',cdata(:,1)); - chi=chi+1; -end -if sCh(2) == 1 - cdata(:,2) = data(:,chi); - set(p_t1,'XData',tt); - set(p_t1,'YData',cdata(:,2)); - chi=chi+1; -end -if sCh(3) == 1 - cdata(:,3) = data(:,chi); - set(p_t2,'XData',tt); - set(p_t2,'YData',cdata(:,3)); - chi=chi+1; -end -if sCh(4) == 1 - cdata(:,4) = data(:,chi); - set(p_t3,'XData',tt); - set(p_t3,'YData',cdata(:,4)); - chi=chi+1; -end -if length(sCh) > 4 - if sCh(5) == 1 - cdata(:,5) = data(:,chi); - set(p_t4,'XData',tt); - set(p_t4,'YData',cdata(:,5)); - chi=chi+1; - end - if sCh(6) == 1 - cdata(:,6) = data(:,chi); - set(p_t5,'XData',tt); - set(p_t5,'YData',cdata(:,6)); - chi=chi+1; - end - if sCh(7) == 1 - cdata(:,7) = data(:,chi); - set(p_t6,'XData',tt); - set(p_t6,'YData',cdata(:,7)); - chi=chi+1; - end - if sCh(8) == 1 - cdata(:,8) = data(:,chi); - set(p_t7,'XData',tt); - set(p_t7,'YData',cdata(:,8)); - end -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to Show data on the GUI +% Input = ai object, sCh channels pressences +% Output = data and time +% Max J. Ortiz C. +% 09-04-15 +% hGUI_Rec = handles from the GUI_Recordings +% ai = analog input "object" +% sCh = Selected channels, binary string to indicate which channels have been selected +% sF = Sample frequency +% sT = Samople time +% pT = peek time +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function cdata = NI_DataShow(handles, ai, sCh, sF, sT, pT) + +% Setting for data peeking +tt = 0:1/sF:pT-1/sF; % Create vector of time +data = zeros(length(tt),8); % Current data + +% Create handles for the plots +% this is faster than creating the plot everytime +if sCh(1) + axes(handles.a_t0); + p_t0 = plot(tt,data(:,1)); + axes(handles.a_f0); + p_f0 = plot(1,1); +end +if sCh(2) + axes(handles.a_t1); + p_t1 = plot(tt,data(:,2)); + axes(handles.a_f1); + p_f1 = plot(1,1); +end +if sCh(3) + axes(handles.a_t2); + p_t2 = plot(tt,data(:,3)); + axes(handles.a_f2); + p_f2 = plot(1,1); +end + +if sCh(4) + axes(handles.a_t3); + p_t3 = plot(tt,data(:,4)); + axes(handles.a_f3); + p_f3 = plot(1,1); +end + +if length(sCh) > 4 % Conditional added to keep compatibility with previous versions + if sCh(5) + axes(handles.a_t4); + p_t4 = plot(tt,data(:,5)); + %axes(handles.a_f4); + %p_f4 = plot(1,1); + end + + if sCh(6) + axes(handles.a_t5); + p_t5 = plot(tt,data(:,6)); + %axes(handles.a_f5); + %p_f5 = plot(1,1); + end + + if sCh(7) + axes(handles.a_t6); + p_t6 = plot(tt,data(:,7)); + %axes(handles.a_f6); + %p_f6 = plot(1,1); + end + + if sCh(8) + axes(handles.a_t7); + p_t7 = plot(tt,data(:,8)); + %axes(handles.a_f7); + %p_f7 = plot(1,1); + end +end + +%% Start DAQ +start(ai); +%ao = init_ao(); test of ao, hardware connections must be done + +% Wait until the first samples are aquired +while ai.SamplesAcquired < sF*pT +end +% Peek Data +while ai.SamplesAcquired < sT*sF + + %putsample(ao,5); test of ao + + % Peek data + set(handles.t_msg,'String',['Peek at: ' num2str(ai.SamplesAcquired)]) % Show message about acquisition + data = peekdata(ai,pT*sF); + data = FilterData(data, handles, sF); %Filter the data + % Fast Fourier Transform + aNs = length(data(:,1)); + NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(data(1:aNs,:),NFFT)/aNs; + m = 2*abs(dataf((1:NFFT/2),:)); + + chi = 1; %Channel Index for map data + if sCh(1) + set(p_t0,'YData',data(:,chi)); + set(p_f0,'XData',f); + set(p_f0,'YData',m(:,chi)); + chi=chi+1; + end + if sCh(2) + set(p_t1,'YData',data(:,chi)); + set(p_f1,'XData',f); + set(p_f1,'YData',m(:,chi)); + chi=chi+1; + end + if sCh(3) + set(p_t2,'YData',data(:,chi)); + set(p_f2,'XData',f); + set(p_f2,'YData',m(:,chi)); + chi=chi+1; + end + if sCh(4) + set(p_t3,'YData',data(:,chi)); + set(p_f3,'XData',f); + set(p_f3,'YData',m(:,chi)); + chi=chi+1; + end + if length(sCh) > 4 + if sCh(5) + set(p_t4,'YData',data(:,chi)); + chi=chi+1; + %set(p_f4,'XData',f); + %set(p_f4,'YData',m(:,chi)); + end + if sCh(6) + set(p_t5,'YData',data(:,chi)); + chi=chi+1; + %set(p_f5,'XData',f); + %set(p_f5,'YData',m(:,chi)); + end + if sCh(7) + set(p_t6,'YData',data(:,chi)); + chi=chi+1; + %set(p_f6,'XData',f); + %set(p_f6,'YData',m(:,chi)); + end + if sCh(8) + set(p_t7,'YData',data(:,chi)); + %set(p_f7,'XData',f); + %set(p_f7,'YData',m(:,chi)); + end + end + + drawnow +end + +wait(ai,sT+1); %Wait until the daq is over or until sT+1 is reached +[data,time,abstime] = getdata(ai); +abstime = fix(abstime); +set(handles.t_msg,'String',['DAQ Done ' num2str(abstime(4)) ':' num2str(abstime(5))]) % Show message about acquisition + + +% Save acquired data into cdata +% Settings for total data +tt = time; % Create vector of time +chi=1; +if sCh(1) == 1 + cdata(:,1) = data(:,chi); + set(p_t0,'XData',tt); + set(p_t0,'YData',cdata(:,1)); + chi=chi+1; +end +if sCh(2) == 1 + cdata(:,2) = data(:,chi); + set(p_t1,'XData',tt); + set(p_t1,'YData',cdata(:,2)); + chi=chi+1; +end +if sCh(3) == 1 + cdata(:,3) = data(:,chi); + set(p_t2,'XData',tt); + set(p_t2,'YData',cdata(:,3)); + chi=chi+1; +end +if sCh(4) == 1 + cdata(:,4) = data(:,chi); + set(p_t3,'XData',tt); + set(p_t3,'YData',cdata(:,4)); + chi=chi+1; +end +if length(sCh) > 4 + if sCh(5) == 1 + cdata(:,5) = data(:,chi); + set(p_t4,'XData',tt); + set(p_t4,'YData',cdata(:,5)); + chi=chi+1; + end + if sCh(6) == 1 + cdata(:,6) = data(:,chi); + set(p_t5,'XData',tt); + set(p_t5,'YData',cdata(:,6)); + chi=chi+1; + end + if sCh(7) == 1 + cdata(:,7) = data(:,chi); + set(p_t6,'XData',tt); + set(p_t6,'YData',cdata(:,7)); + chi=chi+1; + end + if sCh(8) == 1 + cdata(:,8) = data(:,chi); + set(p_t7,'XData',tt); + set(p_t7,'YData',cdata(:,8)); + end +end + diff --git a/Comm/AFE/SBI/DAQShow_SBI.m b/Comm/AFE/SBI/DAQShow_SBI.m index 0db911f..6491647 100644 --- a/Comm/AFE/SBI/DAQShow_SBI.m +++ b/Comm/AFE/SBI/DAQShow_SBI.m @@ -1,306 +1,306 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Funtion to show the aquired data in the GUI (based in NI_DataShow) -% -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-02-09 / Max Ortiz / Creation, moved from Legacy to SBI -% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels -% 20xx-xx-xx / Author / Comment on update - -function cdata = DAQShow_SBI(handlesX, sCh, sF, sT, pT) - - global handles; - global allData; - global timeStamps; - - % Variable to be sent globally - allData = []; - timeStamps = []; - handles = handlesX; - handles.sCh = sCh; - handles.sF = sF; - - - % Setting for data peeking - tt = 0:1/sF:pT-1/sF; % Create vector of time - data = zeros(length(tt),8); % Current data - - % Create handles for the plots - % this is faster than creating the plot everytime - if sCh(1) - axes(handles.a_t0); - p_t0 = plot(tt,data(:,1)); - handles.p_t0 = p_t0; - axes(handles.a_f0); - p_f0 = plot(1,1); - handles.p_f0 = p_f0; - end - if sCh(2) - axes(handles.a_t1); - p_t1 = plot(tt,data(:,2)); - handles.p_t1 = p_t1; - axes(handles.a_f1); - p_f1 = plot(1,1); - handles.p_f1 = p_f1; - end - if sCh(3) - axes(handles.a_t2); - p_t2 = plot(tt,data(:,3)); - handles.p_t2 = p_t2; - axes(handles.a_f2); - p_f2 = plot(1,1); - handles.p_f2 = p_f2; - end - - if sCh(4) - axes(handles.a_t3); - p_t3 = plot(tt,data(:,4)); - handles.p_t3 = p_t3; - axes(handles.a_f3); - p_f3 = plot(1,1); - handles.p_f3 = p_f3; - - end - - if length(sCh) > 4 % Conditional added to keep compatibility with previous versions - if sCh(5) - axes(handles.a_t4); - p_t4 = plot(tt,data(:,5)); - handles.p_t4 = p_t4; - %axes(handles.a_f4); - %p_f4 = plot(1,1); - end - - if sCh(6) - axes(handles.a_t5); - p_t5 = plot(tt,data(:,6)); - handles.p_t5 = p_t5; - %axes(handles.a_f5); - %p_f5 = plot(1,1); - end - - if sCh(7) - axes(handles.a_t6); - p_t6 = plot(tt,data(:,7)); - handles.p_t6 = p_t6; - %axes(handles.a_f6); - %p_f6 = plot(1,1); - end - - if sCh(8) - axes(handles.a_t7); - p_t7 = plot(tt,data(:,8)); - handles.p_t7 = p_t7; - %axes(handles.a_f7); - %p_f7 = plot(1,1); - end - end - - % Send variables; - %handles.p_f4 = handles.p_f4; - %handles.p_f5 = handles.p_f5; - %handles.p_f6 = handles.p_f6; - %handles.p_f7 = handles.p_f7; - - - - %% Init DAQ - s = InitSBI_NI(sF,sT,sCh); - % Change the interruption time - s.NotifyWhenDataAvailableExceeds = sF*pT; - lh = s.addlistener('DataAvailable', @DataShow_SBI_OneShot); - - %% Run in the backgroud - s.startBackground(); - - % Wait until it has finished done - %s.IsDone % will report 0 - s.wait(); % rather than while - %s.IsDone % will report 1 - - %% Finish session - set(handles.t_msg,'String','Done') % Show message about acquisition - data = allData; - - % Fast Fourier Transform - aNs = length(data(:,1)); - NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(data(1:aNs,:),NFFT)/aNs; - m = 2*abs(dataf((1:NFFT/2),:)); - - - % Save acquired data into cdata - % Settings for all data - tt = timeStamps; % Create vector of time - chIdx=1; % Channel Index in the Data matrix - if sCh(1) == 1 - cdata(:,1) = data(:,chIdx); - set(p_t0,'XData',tt); - set(p_t0,'YData',cdata(:,1)); - set(p_f0,'XData',f); - set(p_f0,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(2) == 1 - cdata(:,2) = data(:,chIdx); - set(p_t1,'XData',tt); - set(p_t1,'YData',cdata(:,2)); - set(p_f1,'XData',f); - set(p_f1,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(3) == 1 - cdata(:,3) = data(:,chIdx); - set(p_t2,'XData',tt); - set(p_t2,'YData',cdata(:,3)); - set(p_f2,'XData',f); - set(p_f2,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(4) == 1 - cdata(:,4) = data(:,chIdx); - set(p_t3,'XData',tt); - set(p_t3,'YData',cdata(:,4)); - set(p_f3,'XData',f); - set(p_f3,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if length(sCh) > 4 - if sCh(5) == 1 - cdata(:,5) = data(:,chIdx); - set(p_t4,'XData',tt); - set(p_t4,'YData',cdata(:,5)); - chIdx=chIdx+1; - end - if sCh(6) == 1 - cdata(:,6) = data(:,chIdx); - set(p_t5,'XData',tt); - set(p_t5,'YData',cdata(:,6)); - chIdx=chIdx+1; - end - if sCh(7) == 1 - cdata(:,7) = data(:,chIdx); - set(p_t6,'XData',tt); - set(p_t6,'YData',cdata(:,7)); - chIdx=chIdx+1; - end - if sCh(8) == 1 - cdata(:,8) = data(:,chIdx); - set(p_t7,'XData',tt); - set(p_t7,'YData',cdata(:,8)); - end - end - -%Delete listener SBI -delete (lh) - -end - -function DataShow_SBI_OneShot(src,event) - - global handles; - global allData; - global timeStamps; - - % Get info from hendles - sF = handles.sF; - sCh = handles.sCh; - - % Get data - tempData = event.Data; - allData = [allData; tempData]; - timeStamps = [timeStamps; event.TimeStamps]; - - % filter the data - tempData = FilterData(tempData, handles, sF); %Filter the data - % Fast Fourier Transform - aNs = length(tempData(:,1)); - NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(tempData(1:aNs,:),NFFT)/aNs; - m = 2*abs(dataf((1:NFFT/2),:)); - - chIdx = 1; %Channel Index for map data - if sCh(1) - p_t0 = handles.p_t0; - p_f0 = handles.p_f0; - set(p_t0,'YData',tempData(:,chIdx)); - set(p_f0,'XData',f); - set(p_f0,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(2) - p_t1 = handles.p_t1; - p_f1 = handles.p_f1; - set(p_t1,'YData',tempData(:,chIdx)); - set(p_f1,'XData',f); - set(p_f1,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(3) - p_t2 = handles.p_t2; - p_f2 = handles.p_f2; - set(p_t2,'YData',tempData(:,chIdx)); - set(p_f2,'XData',f); - set(p_f2,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if sCh(4) - p_t3 = handles.p_t3; - p_f3 = handles.p_f3; - set(p_t3,'YData',tempData(:,chIdx)); - set(p_f3,'XData',f); - set(p_f3,'YData',m(:,chIdx)); - chIdx=chIdx+1; - end - if length(sCh) > 4 - if sCh(5) - p_t4 = handles.p_t4; - set(p_t4,'YData',tempData(:,chIdx)); - chIdx=chIdx+1; - %set(p_f4,'XData',f); - %set(p_f4,'YData',m(:,chIdx)); - end - if sCh(6) - p_t5 = handles.p_t5; - set(p_t5,'YData',tempData(:,chIdx)); - chIdx=chIdx+1; - %set(p_f5,'XData',f); - %set(p_f5,'YData',m(:,chIdx)); - end - if sCh(7) - p_t6 = handles.p_t6; - set(p_t6,'YData',tempData(:,chIdx)); - chIdx=chIdx+1; - %set(p_f6,'XData',f); - %set(p_f6,'YData',m(:,chIdx)); - end - if sCh(8) - p_t7 = handles.p_t7; - set(p_t7,'YData',tempData(:,chIdx)); - %set(p_f7,'XData',f); - %set(p_f7,'YData',m(:,chIdx)); - end - end - - drawnow; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Funtion to show the aquired data in the GUI (based in NI_DataShow) +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-02-09 / Max Ortiz / Creation, moved from Legacy to SBI +% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels +% 20xx-xx-xx / Author / Comment on update + +function cdata = DAQShow_SBI(handlesX, sCh, sF, sT, pT) + + global handles; + global allData; + global timeStamps; + + % Variable to be sent globally + allData = []; + timeStamps = []; + handles = handlesX; + handles.sCh = sCh; + handles.sF = sF; + + + % Setting for data peeking + tt = 0:1/sF:pT-1/sF; % Create vector of time + data = zeros(length(tt),8); % Current data + + % Create handles for the plots + % this is faster than creating the plot everytime + if sCh(1) + axes(handles.a_t0); + p_t0 = plot(tt,data(:,1)); + handles.p_t0 = p_t0; + axes(handles.a_f0); + p_f0 = plot(1,1); + handles.p_f0 = p_f0; + end + if sCh(2) + axes(handles.a_t1); + p_t1 = plot(tt,data(:,2)); + handles.p_t1 = p_t1; + axes(handles.a_f1); + p_f1 = plot(1,1); + handles.p_f1 = p_f1; + end + if sCh(3) + axes(handles.a_t2); + p_t2 = plot(tt,data(:,3)); + handles.p_t2 = p_t2; + axes(handles.a_f2); + p_f2 = plot(1,1); + handles.p_f2 = p_f2; + end + + if sCh(4) + axes(handles.a_t3); + p_t3 = plot(tt,data(:,4)); + handles.p_t3 = p_t3; + axes(handles.a_f3); + p_f3 = plot(1,1); + handles.p_f3 = p_f3; + + end + + if length(sCh) > 4 % Conditional added to keep compatibility with previous versions + if sCh(5) + axes(handles.a_t4); + p_t4 = plot(tt,data(:,5)); + handles.p_t4 = p_t4; + %axes(handles.a_f4); + %p_f4 = plot(1,1); + end + + if sCh(6) + axes(handles.a_t5); + p_t5 = plot(tt,data(:,6)); + handles.p_t5 = p_t5; + %axes(handles.a_f5); + %p_f5 = plot(1,1); + end + + if sCh(7) + axes(handles.a_t6); + p_t6 = plot(tt,data(:,7)); + handles.p_t6 = p_t6; + %axes(handles.a_f6); + %p_f6 = plot(1,1); + end + + if sCh(8) + axes(handles.a_t7); + p_t7 = plot(tt,data(:,8)); + handles.p_t7 = p_t7; + %axes(handles.a_f7); + %p_f7 = plot(1,1); + end + end + + % Send variables; + %handles.p_f4 = handles.p_f4; + %handles.p_f5 = handles.p_f5; + %handles.p_f6 = handles.p_f6; + %handles.p_f7 = handles.p_f7; + + + + %% Init DAQ + s = InitSBI_NI(sF,sT,sCh); + % Change the interruption time + s.NotifyWhenDataAvailableExceeds = sF*pT; + lh = s.addlistener('DataAvailable', @DataShow_SBI_OneShot); + + %% Run in the backgroud + s.startBackground(); + + % Wait until it has finished done + %s.IsDone % will report 0 + s.wait(); % rather than while + %s.IsDone % will report 1 + + %% Finish session + set(handles.t_msg,'String','Done') % Show message about acquisition + data = allData; + + % Fast Fourier Transform + aNs = length(data(:,1)); + NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(data(1:aNs,:),NFFT)/aNs; + m = 2*abs(dataf((1:NFFT/2),:)); + + + % Save acquired data into cdata + % Settings for all data + tt = timeStamps; % Create vector of time + chIdx=1; % Channel Index in the Data matrix + if sCh(1) == 1 + cdata(:,1) = data(:,chIdx); + set(p_t0,'XData',tt); + set(p_t0,'YData',cdata(:,1)); + set(p_f0,'XData',f); + set(p_f0,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(2) == 1 + cdata(:,2) = data(:,chIdx); + set(p_t1,'XData',tt); + set(p_t1,'YData',cdata(:,2)); + set(p_f1,'XData',f); + set(p_f1,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(3) == 1 + cdata(:,3) = data(:,chIdx); + set(p_t2,'XData',tt); + set(p_t2,'YData',cdata(:,3)); + set(p_f2,'XData',f); + set(p_f2,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(4) == 1 + cdata(:,4) = data(:,chIdx); + set(p_t3,'XData',tt); + set(p_t3,'YData',cdata(:,4)); + set(p_f3,'XData',f); + set(p_f3,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if length(sCh) > 4 + if sCh(5) == 1 + cdata(:,5) = data(:,chIdx); + set(p_t4,'XData',tt); + set(p_t4,'YData',cdata(:,5)); + chIdx=chIdx+1; + end + if sCh(6) == 1 + cdata(:,6) = data(:,chIdx); + set(p_t5,'XData',tt); + set(p_t5,'YData',cdata(:,6)); + chIdx=chIdx+1; + end + if sCh(7) == 1 + cdata(:,7) = data(:,chIdx); + set(p_t6,'XData',tt); + set(p_t6,'YData',cdata(:,7)); + chIdx=chIdx+1; + end + if sCh(8) == 1 + cdata(:,8) = data(:,chIdx); + set(p_t7,'XData',tt); + set(p_t7,'YData',cdata(:,8)); + end + end + +%Delete listener SBI +delete (lh) + +end + +function DataShow_SBI_OneShot(src,event) + + global handles; + global allData; + global timeStamps; + + % Get info from hendles + sF = handles.sF; + sCh = handles.sCh; + + % Get data + tempData = event.Data; + allData = [allData; tempData]; + timeStamps = [timeStamps; event.TimeStamps]; + + % filter the data + tempData = FilterData(tempData, handles, sF); %Filter the data + % Fast Fourier Transform + aNs = length(tempData(:,1)); + NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(tempData(1:aNs,:),NFFT)/aNs; + m = 2*abs(dataf((1:NFFT/2),:)); + + chIdx = 1; %Channel Index for map data + if sCh(1) + p_t0 = handles.p_t0; + p_f0 = handles.p_f0; + set(p_t0,'YData',tempData(:,chIdx)); + set(p_f0,'XData',f); + set(p_f0,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(2) + p_t1 = handles.p_t1; + p_f1 = handles.p_f1; + set(p_t1,'YData',tempData(:,chIdx)); + set(p_f1,'XData',f); + set(p_f1,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(3) + p_t2 = handles.p_t2; + p_f2 = handles.p_f2; + set(p_t2,'YData',tempData(:,chIdx)); + set(p_f2,'XData',f); + set(p_f2,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if sCh(4) + p_t3 = handles.p_t3; + p_f3 = handles.p_f3; + set(p_t3,'YData',tempData(:,chIdx)); + set(p_f3,'XData',f); + set(p_f3,'YData',m(:,chIdx)); + chIdx=chIdx+1; + end + if length(sCh) > 4 + if sCh(5) + p_t4 = handles.p_t4; + set(p_t4,'YData',tempData(:,chIdx)); + chIdx=chIdx+1; + %set(p_f4,'XData',f); + %set(p_f4,'YData',m(:,chIdx)); + end + if sCh(6) + p_t5 = handles.p_t5; + set(p_t5,'YData',tempData(:,chIdx)); + chIdx=chIdx+1; + %set(p_f5,'XData',f); + %set(p_f5,'YData',m(:,chIdx)); + end + if sCh(7) + p_t6 = handles.p_t6; + set(p_t6,'YData',tempData(:,chIdx)); + chIdx=chIdx+1; + %set(p_f6,'XData',f); + %set(p_f6,'YData',m(:,chIdx)); + end + if sCh(8) + p_t7 = handles.p_t7; + set(p_t7,'YData',tempData(:,chIdx)); + %set(p_f7,'XData',f); + %set(p_f7,'YData',m(:,chIdx)); + end + end + + drawnow; + end \ No newline at end of file diff --git a/Comm/AFE/SBI/InitSBI_NI.m b/Comm/AFE/SBI/InitSBI_NI.m index efa23b7..aa68605 100644 --- a/Comm/AFE/SBI/InitSBI_NI.m +++ b/Comm/AFE/SBI/InitSBI_NI.m @@ -1,123 +1,123 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% ------------------- Function Description ------------------ -% Initialization of the Session-Based Inferface -% This routine was created from the Init_NIx routines used in previous -% versions of Matlab 2011. The daq toolbox in the 64 releases required a -% completly different initialization (the session-based interface). -% -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-01-24 / Max Ortiz / Creation -% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels -% not the most elegant solution but it does the -% job -% 2012-05-29 / Max Ortiz / Removed the routine for sequentially adding -% channels to a loop. -% 20xx-xx-xx / Author / Comment on update - -function [s] = InitSBI_NI(sF, sT, chAI, chAO) - -% Auxiliar variables -nChAI = size(chAI,2); -chAIidx = find(chAI); - -% Close possible daq objects running -if (~isempty(daqfind)) - stop(daqfind) -end - -% Find devices -dev = daq.getDevices; - -% Create a session -s = daq.createSession('ni'); - - -% Add channels in a loop - -for i = 1 : size(chAIidx,2) - chID = ['ai' num2str(chAIidx(i)-1)]; - s.addAnalogInputChannel(dev.ID,chID,'Voltage'); - s.Channels(i).InputType ='SingleEnded'; - s.Channels(i).Range = [-5 5]; -end - -% Add channels -% if nChAI >= 1; -% if chAI(1) -% s.addAnalogInputChannel(dev.ID,'ai0','Voltage'); -% s.Channels(1).InputType ='SingleEnded'; -% s.Channels(1).Range = [-5 5]; -% end -% end -% if nChAI >= 2; -% if chAI(2) -% s.addAnalogInputChannel(dev.ID,'ai1','Voltage'); -% s.Channels(2).InputType ='SingleEnded'; -% s.Channels(2).Range = [-5 5]; -% end -% end -% if nChAI >= 3; -% if chAI(3) -% s.addAnalogInputChannel(dev.ID,'ai2','Voltage'); -% s.Channels(3).InputType ='SingleEnded'; -% s.Channels(3).Range = [-5 5]; -% end -% end -% if nChAI >= 4; -% if chAI(4) -% s.addAnalogInputChannel(dev.ID,'ai3','Voltage'); -% s.Channels(4).InputType ='SingleEnded'; -% s.Channels(4).Range = [-5 5]; -% end -% end -% if nChAI >= 5; -% if chAI(5) -% s.addAnalogInputChannel(dev.ID,'ai4','Voltage'); -% s.Channels(5).InputType ='SingleEnded'; -% s.Channels(5).Range = [-5 5]; -% end -% end -% if nChAI >= 6; -% if chAI(6) -% s.addAnalogInputChannel(dev.ID,'ai5','Voltage'); -% s.Channels(6).InputType ='SingleEnded'; -% s.Channels(6).Range = [-5 5]; -% end -% end -% if nChAI >= 7; -% if chAI(7) -% s.addAnalogInputChannel(dev.ID,'ai6','Voltage'); -% s.Channels(7).InputType ='SingleEnded'; -% s.Channels(7).Range = [-5 5]; -% end -% end -% -% if nChAI >= 8; -% if chAI(8) -% s.addAnalogInputChannel(dev.ID,'ai7','Voltage'); -% s.Channels(8).InputType ='SingleEnded'; -% s.Channels(8).Range = [-5 5]; -% end -% end -% Modify duration and frequency - -s.DurationInSeconds = sT; -s.Rate = sF; - -disp(s); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Initialization of the Session-Based Inferface +% This routine was created from the Init_NIx routines used in previous +% versions of Matlab 2011. The daq toolbox in the 64 releases required a +% completly different initialization (the session-based interface). +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-01-24 / Max Ortiz / Creation +% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels +% not the most elegant solution but it does the +% job +% 2012-05-29 / Max Ortiz / Removed the routine for sequentially adding +% channels to a loop. +% 20xx-xx-xx / Author / Comment on update + +function [s] = InitSBI_NI(sF, sT, chAI, chAO) + +% Auxiliar variables +nChAI = size(chAI,2); +chAIidx = find(chAI); + +% Close possible daq objects running +if (~isempty(daqfind)) + stop(daqfind) +end + +% Find devices +dev = daq.getDevices; + +% Create a session +s = daq.createSession('ni'); + + +% Add channels in a loop + +for i = 1 : size(chAIidx,2) + chID = ['ai' num2str(chAIidx(i)-1)]; + s.addAnalogInputChannel(dev.ID,chID,'Voltage'); + s.Channels(i).InputType ='SingleEnded'; + s.Channels(i).Range = [-5 5]; +end + +% Add channels +% if nChAI >= 1; +% if chAI(1) +% s.addAnalogInputChannel(dev.ID,'ai0','Voltage'); +% s.Channels(1).InputType ='SingleEnded'; +% s.Channels(1).Range = [-5 5]; +% end +% end +% if nChAI >= 2; +% if chAI(2) +% s.addAnalogInputChannel(dev.ID,'ai1','Voltage'); +% s.Channels(2).InputType ='SingleEnded'; +% s.Channels(2).Range = [-5 5]; +% end +% end +% if nChAI >= 3; +% if chAI(3) +% s.addAnalogInputChannel(dev.ID,'ai2','Voltage'); +% s.Channels(3).InputType ='SingleEnded'; +% s.Channels(3).Range = [-5 5]; +% end +% end +% if nChAI >= 4; +% if chAI(4) +% s.addAnalogInputChannel(dev.ID,'ai3','Voltage'); +% s.Channels(4).InputType ='SingleEnded'; +% s.Channels(4).Range = [-5 5]; +% end +% end +% if nChAI >= 5; +% if chAI(5) +% s.addAnalogInputChannel(dev.ID,'ai4','Voltage'); +% s.Channels(5).InputType ='SingleEnded'; +% s.Channels(5).Range = [-5 5]; +% end +% end +% if nChAI >= 6; +% if chAI(6) +% s.addAnalogInputChannel(dev.ID,'ai5','Voltage'); +% s.Channels(6).InputType ='SingleEnded'; +% s.Channels(6).Range = [-5 5]; +% end +% end +% if nChAI >= 7; +% if chAI(7) +% s.addAnalogInputChannel(dev.ID,'ai6','Voltage'); +% s.Channels(7).InputType ='SingleEnded'; +% s.Channels(7).Range = [-5 5]; +% end +% end +% +% if nChAI >= 8; +% if chAI(8) +% s.addAnalogInputChannel(dev.ID,'ai7','Voltage'); +% s.Channels(8).InputType ='SingleEnded'; +% s.Channels(8).Range = [-5 5]; +% end +% end +% Modify duration and frequency + +s.DurationInSeconds = sT; +s.Rate = sF; + +disp(s); diff --git a/Comm/AFE/SBI/TestSBI_NI_USB6009.m b/Comm/AFE/SBI/TestSBI_NI_USB6009.m index 00d93bf..bc595fe 100644 --- a/Comm/AFE/SBI/TestSBI_NI_USB6009.m +++ b/Comm/AFE/SBI/TestSBI_NI_USB6009.m @@ -1,100 +1,100 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Test funtions for data aquisition using Session-base Interfaces -% -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-01-31 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - -function TestSBI_NI_USB6009 - - %TestSimpleAIForeground(); - %TestSimpleAIBackground(); - TestGlobalAIBackground(); - -end - -function TestSimpleAIForeground - - s = daq.createSession('ni') - s.addAnalogInputChannel('dev1','ai0','Voltage') - data = s.startForeground() - plot (data) - -end - -function TestSimpleAIBackground - - s = daq.createSession('ni') - s.addAnalogInputChannel('dev1','ai0','Voltage') - lh = s.addlistener('DataAvailable', @plotData); - s.startBackground(); - s.wait; - delete (lh) - -end - -function TestGlobalAIBackground - %clear global data; - clear all; - %clear functions - - global data - - s = daq.createSession('ni'); - s.addAnalogInputChannel('dev1',0,'voltage'); - s.Rate = 1000; - s.DurationInSeconds = 1; - %Verify that the notification is done automatically - %s.IsNotifyWhenDataAvailableExceedsAuto = 1; - % Change the peek time - s.NotifyWhenDataAvailableExceeds = 100; - lh = s.addlistener('DataAvailable',@plotGloalData); - - s.startBackground(); - % Wait - s.wait; - %close(gcf); - figure(); - plot(data); % plot global data - delete (lh) -end - - -function plotGloalData(src,event) - persistent tempData; - persistent i; - global data - if(isempty(tempData)) - tempData = []; - i = 1; - end - disp(i); - %plot(event.TimeStamps, event.Data); - plot(event.Data); - tempData = [tempData;event.Data]; - data = tempData; - i=i+1; -end - - -function plotData(src,event) - plot(event.TimeStamps, event.Data) - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Test funtions for data aquisition using Session-base Interfaces +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-01-31 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + +function TestSBI_NI_USB6009 + + %TestSimpleAIForeground(); + %TestSimpleAIBackground(); + TestGlobalAIBackground(); + +end + +function TestSimpleAIForeground + + s = daq.createSession('ni') + s.addAnalogInputChannel('dev1','ai0','Voltage') + data = s.startForeground() + plot (data) + +end + +function TestSimpleAIBackground + + s = daq.createSession('ni') + s.addAnalogInputChannel('dev1','ai0','Voltage') + lh = s.addlistener('DataAvailable', @plotData); + s.startBackground(); + s.wait; + delete (lh) + +end + +function TestGlobalAIBackground + %clear global data; + clear all; + %clear functions + + global data + + s = daq.createSession('ni'); + s.addAnalogInputChannel('dev1',0,'voltage'); + s.Rate = 1000; + s.DurationInSeconds = 1; + %Verify that the notification is done automatically + %s.IsNotifyWhenDataAvailableExceedsAuto = 1; + % Change the peek time + s.NotifyWhenDataAvailableExceeds = 100; + lh = s.addlistener('DataAvailable',@plotGloalData); + + s.startBackground(); + % Wait + s.wait; + %close(gcf); + figure(); + plot(data); % plot global data + delete (lh) +end + + +function plotGloalData(src,event) + persistent tempData; + persistent i; + global data + if(isempty(tempData)) + tempData = []; + i = 1; + end + disp(i); + %plot(event.TimeStamps, event.Data); + plot(event.Data); + tempData = [tempData;event.Data]; + data = tempData; + i=i+1; +end + + +function plotData(src,event) + plot(event.TimeStamps, event.Data) + end diff --git a/Comm/AFE/SetDeviceStartAcquisition.m b/Comm/AFE/SetDeviceStartAcquisition.m new file mode 100644 index 0000000..3d550b4 --- /dev/null +++ b/Comm/AFE/SetDeviceStartAcquisition.m @@ -0,0 +1,101 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-1-12 / Enzo Mastinu / Divided the RecordingSession function into + % several functions: ConnectDevice(), + % SetDeviceStartAcquisition(), + % Acquire_tWs(), StopAcquisition(). This functions + % has been moved to COMM/AFE folder, into this new script. + +% 20xx-xx-xx / Author / Comment + + + +% it sets the chosen device and sends start acquisition command +function SetDeviceStartAcquisition(handles, obj) + + deviceName = handles.deviceName; + nCh = handles.nCh; + sTall = handles.sTall; + sF = handles.sF; + + + %%%%% INTAN RHA2216 %%%%% + if strcmp(deviceName, 'RHA2216') + + % Setup the selected channels + vCh = 0:nCh'-1; % Vector of channels + fwrite(obj,'C','char'); + fwrite(obj,nCh,'uint8'); + for i = 1 : nCh + fwrite(obj,vCh(i),'uint8'); + end + replay = char(fread(obj,1,'char')); + if ~strcmp(replay,'O') + set(handles.t_msg,'String','Error setting the vector of channels'); + fclose(obj); + return + else + set(handles.t_msg,'String','Channel vector set'); + end + + % Set up frequency in the microcontroller + fwrite(obj,'F','char'); + fwrite(obj,sF,'uint16'); + replay = char(fread(obj,1,'char')); + if ~strcmp(replay,'O') + set(handles.t_msg,'String','Error setting the frequency'); + fclose(obj); + return + else + set(handles.t_msg,'String','Frequency set'); + end + + % Set sampling time + fwrite(obj,sTall,'uint8'); + replay = char(fread(obj,1,'char')); + if ~strcmp(replay,'O') + set(handles.t_msg,'String','Error setting sampling time'); + fclose(obj); + return + else + set(handles.t_msg,'String','Sampling time set'); + end + + % Start the aquisition + fwrite(obj,'S','char'); + set(handles.t_msg,'String','Start'); + end + + %%%%% TI ADS1299 %%%%% + if strcmp(deviceName, 'ADS1299') + % Start the acquisition + fwrite(obj,'G','char'); + replay = char(fread(obj,1,'char')); + if strcmp(replay,'G') + set(handles.t_msg,'String','Start'); + else + set(handles.t_msg,'String','Error Start'); + fclose(obj); + return + end + end + +end diff --git a/Comm/AFE/StopAcquisition.m b/Comm/AFE/StopAcquisition.m new file mode 100644 index 0000000..62f46be --- /dev/null +++ b/Comm/AFE/StopAcquisition.m @@ -0,0 +1,46 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-1-12 / Enzo Mastinu / Divided the RecordingSession function into + % several functions: ConnectDevice(), + % SetDeviceStartAcquisition(), + % Acquire_tWs(), StopAcquisition(). This functions + % has been moved to COMM/AFE folder, into this new script. + +% 20xx-xx-xx / Author / Comment + + + +% it sends the stop acquisition command to the chosen device +function StopAcquisition(deviceName, obj) + + %%%%% INTAN RHA2216 %%%%% + if strcmp(deviceName, 'RHA2216') + fwrite(obj,'Q','char'); % Stop the aquisition ´ + fclose(obj); % Close connection + end + + %%%%% ADS1299 %%%%% + if strcmp(deviceName, 'ADS1299') + fwrite(obj,'G','char'); % Stop the aquisition ´ + fclose(obj); % Close connection + end + +end \ No newline at end of file diff --git a/Comm/ALC/VCP_Piccolo/Connect_ALC.m b/Comm/ALC/VCP_Piccolo/Connect_ALC.m index 7b2478e..211fcd4 100644 --- a/Comm/ALC/VCP_Piccolo/Connect_ALC.m +++ b/Comm/ALC/VCP_Piccolo/Connect_ALC.m @@ -1,39 +1,39 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% ------------------- Function Description ------------------ -% Function to create the communicatio object - -% --------------------------Updates-------------------------- -% 2011-11-09 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - - - -function obj = Connect_ALC(conn) - %conn, Connection String - %Find serial port objects with specified property values - obj.io=instrfind('Status','open'); - if isempty(obj.io) - obj.io=serial(conn, 'BaudRate', 14400); - pause(1) - % Open io for read and write access - set(obj.io,'InputBuffer',1024*64) - fopen(obj.io) - pause(1) - end - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to create the communicatio object + +% --------------------------Updates-------------------------- +% 2011-11-09 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + + + +function obj = Connect_ALC(conn) + %conn, Connection String + %Find serial port objects with specified property values + obj.io=instrfind('Status','open'); + if isempty(obj.io) + obj.io=serial(conn, 'BaudRate', 14400); + pause(1) + % Open io for read and write access + set(obj.io,'InputBuffer',1024*64) + fopen(obj.io) + pause(1) + end + +end diff --git a/Comm/ALC/VCP_Piccolo/TestConnectionALC.m b/Comm/ALC/VCP_Piccolo/TestConnectionALC.m index 55cb402..d1f0d0f 100644 --- a/Comm/ALC/VCP_Piccolo/TestConnectionALC.m +++ b/Comm/ALC/VCP_Piccolo/TestConnectionALC.m @@ -1,38 +1,38 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to test the communicatio object -% --------------------------Updates-------------------------- -% 2011-11-09 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - -%% Test Connection -function result = TestConnectionALC(obj) - %If buffer not empty, - if obj.io.BytesAvailable>0 - fread(obj.io,obj.io.BytesAvailable); - end - %Send connection test - fwrite(obj.io,'C'); - pause(0.5); - if fread(obj.io,1)==1 - result=1; - else - result=0; - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to test the communicatio object +% --------------------------Updates-------------------------- +% 2011-11-09 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + +%% Test Connection +function result = TestConnectionALC(obj) + %If buffer not empty, + if obj.io.BytesAvailable>0 + fread(obj.io,obj.io.BytesAvailable); + end + %Send connection test + fwrite(obj.io,'C'); + pause(0.5); + if fread(obj.io,1)==1 + result=1; + else + result=0; + end end \ No newline at end of file diff --git a/Comm/ALC/VCP_Piccolo/TestPWMusingSCIbyCycling.m b/Comm/ALC/VCP_Piccolo/TestPWMusingSCIbyCycling.m index 0ad6fa7..7c9fa9d 100644 --- a/Comm/ALC/VCP_Piccolo/TestPWMusingSCIbyCycling.m +++ b/Comm/ALC/VCP_Piccolo/TestPWMusingSCIbyCycling.m @@ -1,128 +1,128 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to test the i-limb motors. This function will increase and -% decrease the speed as well as to change the motor direction. -% -% The corresponding function in the ACL has the same name. -% -% This fuction is a VERY slow implementation of SCI communication. It waits -% until the ALC acknowledges the comunication, otherwise it exits with a -% failure (result = 0). -% -% The driver are controlled to work in fast decay (see data-sheet DVR8833) -% in order to achieve this, one PWM sets the speed while the other is held -% low -% -% pwmDC = PWM duty cycle is inverse, so 10 = 90% of duty cycle -% -% comObj is the communication objectt required for data transmission -% -% --------------------------Updates-------------------------- -% 2011-11-07 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - - -function result = TestPWMusingSCIbyCycling(comObj) - - % Send the Test routine in the ALC - fwrite(comObj.io,'T') - pause(0.1) - % Send the Test ID - fwrite(comObj.io,'B'); - pause(0.1) - reps = 2; - - % Repeat the cycle "reps" times - for i = 1 : reps; - - % Cycle the PWM until 100 percent to go FORWARD - for pwmDC = 0 : 20 : 100 - - % Update the all PWM - for j = 1 : 2 : 10 - - % First PWM to set the speed - fwrite(comObj.io,pwmDC,'uint8','async') - %pause(0.1) - % Read answer - if fread(comObj.io,1) ~= j - result=0; - return; - end - - % Second PWM held low - fwrite(comObj.io,100,'uint8','async') - %pause(0.1) - % Read answer - if fread(comObj.io,1) ~= j+1 - result=0; - return; - end - - end - - % Continue the transmission - fwrite(comObj.io,'C'); - end - - % Cycle the PWM until 100 percent to go Backwards - for pwmDC = 0 : 20 : 100 - - % Update the all PWM - for j = 1 : 2 : 10 - - % First PWM to set the speed - fwrite(comObj.io,100,'uint8','async') - %pause(0.1) - % Read answer - if fread(comObj.io,1) ~= j - result=0; - return; - end - - % Second PWM held low - fwrite(comObj.io,pwmDC,'uint8','async') - %pause(0.1) - % Read answer - if fread(comObj.io,1) ~= j+1 - result=0; - return; - end - - end - - % Break or continue the repetitions - if i >= reps && pwmDC >= 100 % Break the cycle - fwrite(comObj.io,'B') - %pause(0.1) - else % Continue the cycle - fwrite(comObj.io,'C') - %pause(0.1) - end - end - - end - - % Read confirmation - if fread(comObj.io,1)==1 - result=1; - else - result=0; - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to test the i-limb motors. This function will increase and +% decrease the speed as well as to change the motor direction. +% +% The corresponding function in the ACL has the same name. +% +% This fuction is a VERY slow implementation of SCI communication. It waits +% until the ALC acknowledges the comunication, otherwise it exits with a +% failure (result = 0). +% +% The driver are controlled to work in fast decay (see data-sheet DVR8833) +% in order to achieve this, one PWM sets the speed while the other is held +% low +% +% pwmDC = PWM duty cycle is inverse, so 10 = 90% of duty cycle +% +% comObj is the communication objectt required for data transmission +% +% --------------------------Updates-------------------------- +% 2011-11-07 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + + +function result = TestPWMusingSCIbyCycling(comObj) + + % Send the Test routine in the ALC + fwrite(comObj.io,'T') + pause(0.1) + % Send the Test ID + fwrite(comObj.io,'B'); + pause(0.1) + reps = 2; + + % Repeat the cycle "reps" times + for i = 1 : reps; + + % Cycle the PWM until 100 percent to go FORWARD + for pwmDC = 0 : 20 : 100 + + % Update the all PWM + for j = 1 : 2 : 10 + + % First PWM to set the speed + fwrite(comObj.io,pwmDC,'uint8','async') + %pause(0.1) + % Read answer + if fread(comObj.io,1) ~= j + result=0; + return; + end + + % Second PWM held low + fwrite(comObj.io,100,'uint8','async') + %pause(0.1) + % Read answer + if fread(comObj.io,1) ~= j+1 + result=0; + return; + end + + end + + % Continue the transmission + fwrite(comObj.io,'C'); + end + + % Cycle the PWM until 100 percent to go Backwards + for pwmDC = 0 : 20 : 100 + + % Update the all PWM + for j = 1 : 2 : 10 + + % First PWM to set the speed + fwrite(comObj.io,100,'uint8','async') + %pause(0.1) + % Read answer + if fread(comObj.io,1) ~= j + result=0; + return; + end + + % Second PWM held low + fwrite(comObj.io,pwmDC,'uint8','async') + %pause(0.1) + % Read answer + if fread(comObj.io,1) ~= j+1 + result=0; + return; + end + + end + + % Break or continue the repetitions + if i >= reps && pwmDC >= 100 % Break the cycle + fwrite(comObj.io,'B') + %pause(0.1) + else % Continue the cycle + fwrite(comObj.io,'C') + %pause(0.1) + end + end + + end + + % Read confirmation + if fread(comObj.io,1)==1 + result=1; + else + result=0; + end end \ No newline at end of file diff --git a/Comm/ALC/VCP_Piccolo/Update2PWMusingSCI.m b/Comm/ALC/VCP_Piccolo/Update2PWMusingSCI.m index b4c3ded..22a0975 100644 --- a/Comm/ALC/VCP_Piccolo/Update2PWMusingSCI.m +++ b/Comm/ALC/VCP_Piccolo/Update2PWMusingSCI.m @@ -1,54 +1,54 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to test the i-limb motors per DoF. -% -% The corresponding function in the ACL has the same name. -% -% This fuction is a slow implementation of SCI communication. It waits -% until the ALC acknowledges the comunication, otherwise it exits with a -% failure (result = 0). -% -% --------------------------Updates-------------------------- -% 2011-11-10 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - - -function result = Update2PWMusingSCI(obj, pwmID, pwm1, pwm2) - - % Send the Test routine in the ALC - fwrite(obj.io,'D'); - %pause(0.01); % Delay seems to not be neccesary - % Send PWM ID - fwrite(obj.io,pwmID); - %pause(0.01) % Delay seems to not be neccesary - % Send duty cycle - fwrite(obj.io,100-pwm1,'uint8','sync') - %pause(0.01) % Delay seems to not be neccesary - fwrite(obj.io,100-pwm2,'uint8','sync') - %pause(0.01) % Delay seems to not be neccesary - - % If no problems where encountered, the ALC must return 1 - if fread(obj.io,1)==1 - result=1; - else - result=0; - return; - end - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to test the i-limb motors per DoF. +% +% The corresponding function in the ACL has the same name. +% +% This fuction is a slow implementation of SCI communication. It waits +% until the ALC acknowledges the comunication, otherwise it exits with a +% failure (result = 0). +% +% --------------------------Updates-------------------------- +% 2011-11-10 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + + +function result = Update2PWMusingSCI(obj, pwmID, pwm1, pwm2) + + % Send the Test routine in the ALC + fwrite(obj.io,'D'); + %pause(0.01); % Delay seems to not be neccesary + % Send PWM ID + fwrite(obj.io,pwmID); + %pause(0.01) % Delay seems to not be neccesary + % Send duty cycle + fwrite(obj.io,100-pwm1,'uint8','sync') + %pause(0.01) % Delay seems to not be neccesary + fwrite(obj.io,100-pwm2,'uint8','sync') + %pause(0.01) % Delay seems to not be neccesary + + % If no problems where encountered, the ALC must return 1 + if fread(obj.io,1)==1 + result=1; + else + result=0; + return; + end + +end diff --git a/Comm/ALC/VCP_Piccolo/UpdateAllPWMusingSCI.m b/Comm/ALC/VCP_Piccolo/UpdateAllPWMusingSCI.m index f74ce27..04b5cc4 100644 --- a/Comm/ALC/VCP_Piccolo/UpdateAllPWMusingSCI.m +++ b/Comm/ALC/VCP_Piccolo/UpdateAllPWMusingSCI.m @@ -1,61 +1,61 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to test the i-limb motors. This function will update the values -% of the PWM using a PWM ID and then sending the percentage of duty cycle. -% -% The corresponding function in the ACL has the same name. -% -% This fuction is a slow implementation of SCI communication. It waits -% until the ALC acknowledges the comunication, otherwise it exits with a -% failure (result = 0). -% -% --------------------------Updates-------------------------- -% 2011-11-08 / Max Ortiz / Creation -% 2012-05-03 / Pratham D / Added K and L -% 2012-07-08 / Max Ortiz / Update the communication protocol - -function result = UpdateAllPWMusingSCI(obj, pwms) - - % Setup IDs - pwmID = ['A' ; 'B' ; 'C' ; 'D' ; 'E'; 'F' ; 'G' ; 'H' ; 'I' ; 'J'; 'K' ; 'L']; - - for i = 1 : size(pwms,2) - % Send the Test routine in the ALC -% fwrite(obj.io,'T'); -% %pause(0.01); % Delay seems to not be neccesary -% % Send the Test ID -% fwrite(obj.io,'X'); - % Send Single PWM update - fwrite(obj.io,'S'); - %Send ID - fwrite(obj.io,pwmID(i)); - %pause(0.01) % Delay seems to not be neccesary - % Send duty cycle - fwrite(obj.io,pwms(i),'uint8','async') - %pause(0.01) % Delay seems to not be neccesary - - % If no problems where encountered, the ALC must return 1 - if fread(obj.io,1)==1 - result=1; - else - result=0; - return; - end - end -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to test the i-limb motors. This function will update the values +% of the PWM using a PWM ID and then sending the percentage of duty cycle. +% +% The corresponding function in the ACL has the same name. +% +% This fuction is a slow implementation of SCI communication. It waits +% until the ALC acknowledges the comunication, otherwise it exits with a +% failure (result = 0). +% +% --------------------------Updates-------------------------- +% 2011-11-08 / Max Ortiz / Creation +% 2012-05-03 / Pratham D / Added K and L +% 2012-07-08 / Max Ortiz / Update the communication protocol + +function result = UpdateAllPWMusingSCI(obj, pwms) + + % Setup IDs + pwmID = ['A' ; 'B' ; 'C' ; 'D' ; 'E'; 'F' ; 'G' ; 'H' ; 'I' ; 'J'; 'K' ; 'L']; + + for i = 1 : size(pwms,2) + % Send the Test routine in the ALC +% fwrite(obj.io,'T'); +% %pause(0.01); % Delay seems to not be neccesary +% % Send the Test ID +% fwrite(obj.io,'X'); + % Send Single PWM update + fwrite(obj.io,'S'); + %Send ID + fwrite(obj.io,pwmID(i)); + %pause(0.01) % Delay seems to not be neccesary + % Send duty cycle + fwrite(obj.io,pwms(i),'uint8','async') + %pause(0.01) % Delay seems to not be neccesary + + % If no problems where encountered, the ALC must return 1 + if fread(obj.io,1)==1 + result=1; + else + result=0; + return; + end + end +end diff --git a/Comm/ALC/VCP_Piccolo/UpdatePWMusingSCI_PanTilt.m b/Comm/ALC/VCP_Piccolo/UpdatePWMusingSCI_PanTilt.m index d3ad12e..e1fb5af 100644 --- a/Comm/ALC/VCP_Piccolo/UpdatePWMusingSCI_PanTilt.m +++ b/Comm/ALC/VCP_Piccolo/UpdatePWMusingSCI_PanTilt.m @@ -1,79 +1,79 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to send the PWM for control of the servo motors for the Pan & -% Tilt unit. -% -% --------------------------Updates-------------------------- -% 2012-05-04 / Max Ortiz / Creation -% 2012-06-29 / Max Ortiz / Modified the protocolo for communication with -% the microcontroller, now it will only send a "S" -% before the servo ID, and duty cycle. -% 20xx-xx-xx / Author / - - -function [result pwmPer] = UpdatePWMusingSCI_PanTilt(obj, pwmID, pwmPer) - - %% Safety routine (specifically for the servocity pantilt) - %Tilt - if strcmp(pwmID,'L') - maxP = 85; - minP = 7; - if minP > pwmPer - pwmPer = minP; - end - if maxP < pwmPer - pwmPer = maxP; - end - end - %Pan - if strcmp(pwmID,'K') - maxP = 100; - minP = 1; - if minP > pwmPer - pwmPer = minP; - end - if maxP < pwmPer - pwmPer = maxP; - end - end - - %% Send values to controller - % Send the Test routine in the ALC - % fwrite(obj.io,'T'); - % pause(0.01); % Delay seems to not be neccesary - % Send the Test ID - % fwrite(obj.io,'X'); - - % Send servo indentifier - fwrite(obj.io,'S'); - %Send ID - fwrite(obj.io,pwmID); - %pause(0.01) % Delay seems to not be neccesary - % Send duty cycle - fwrite(obj.io,pwmPer,'uint8','async') - %pause(0.01) % Delay seems to not be neccesary - - if fread(obj.io,1)==1 - result=1; - else - result=0; - return; - end - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to send the PWM for control of the servo motors for the Pan & +% Tilt unit. +% +% --------------------------Updates-------------------------- +% 2012-05-04 / Max Ortiz / Creation +% 2012-06-29 / Max Ortiz / Modified the protocolo for communication with +% the microcontroller, now it will only send a "S" +% before the servo ID, and duty cycle. +% 20xx-xx-xx / Author / + + +function [result pwmPer] = UpdatePWMusingSCI_PanTilt(obj, pwmID, pwmPer) + + %% Safety routine (specifically for the servocity pantilt) + %Tilt + if strcmp(pwmID,'L') + maxP = 85; + minP = 7; + if minP > pwmPer + pwmPer = minP; + end + if maxP < pwmPer + pwmPer = maxP; + end + end + %Pan + if strcmp(pwmID,'K') + maxP = 100; + minP = 1; + if minP > pwmPer + pwmPer = minP; + end + if maxP < pwmPer + pwmPer = maxP; + end + end + + %% Send values to controller + % Send the Test routine in the ALC + % fwrite(obj.io,'T'); + % pause(0.01); % Delay seems to not be neccesary + % Send the Test ID + % fwrite(obj.io,'X'); + + % Send servo indentifier + fwrite(obj.io,'S'); + %Send ID + fwrite(obj.io,pwmID); + %pause(0.01) % Delay seems to not be neccesary + % Send duty cycle + fwrite(obj.io,pwmPer,'uint8','async') + %pause(0.01) % Delay seems to not be neccesary + + if fread(obj.io,1)==1 + result=1; + else + result=0; + return; + end + +end diff --git a/Control/ConnectVRE.m b/Comm/ConnectVRE.m similarity index 95% rename from Control/ConnectVRE.m rename to Comm/ConnectVRE.m index f62db15..2a02cea 100644 --- a/Control/ConnectVRE.m +++ b/Comm/ConnectVRE.m @@ -1,49 +1,50 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Used to Connect a VRE session to a struct. -% Can be used for Realtime, Training, Motion Test etc. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2013-01-29 / Nichlas Sander / Creation - -function handles = ConnectVRE(handles, program) - if ~isfield(handles,'vre_Com') - open(program); - handles.vre_Com = tcpip('127.0.0.1',23068,'NetworkRole','server'); - fopen(handles.vre_Com); - end - handles = DisableIfExists(handles,'pb_socketConnect'); - handles = DisableIfExists(handles,'pb_socketConnect2'); - handles = EnableIfExists(handles,'pb_socketDisconnect'); - handles = EnableIfExists(handles,'pb_Camera'); - handles = EnableIfExists(handles,'pb_ActivateArm'); -end - -function handles = EnableIfExists(handles,field) - if isfield(handles,field) - set(handles.(field),'Enable','on'); - end -end - -function handles = DisableIfExists(handles,field) - if isfield(handles,field) - set(handles.(field),'Enable','off'); - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Used to Connect a VRE session to a struct. +% Can be used for Realtime, Training, Motion Test etc. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2013-01-29 / Nichlas Sander / Creation + +function handles = ConnectVRE(handles, program) + if ~isfield(handles,'vre_Com') + open(program); + handles.vre_Com = tcpip('127.0.0.1',23068,'NetworkRole','server'); + fopen(handles.vre_Com); + end + handles = DisableIfExists(handles,'pb_socketConnect'); + handles = DisableIfExists(handles,'pb_socketConnect2'); + handles = DisableIfExists(handles,'pb_ARarm'); + handles = EnableIfExists(handles,'pb_socketDisconnect'); + handles = EnableIfExists(handles,'pb_Camera'); + handles = EnableIfExists(handles,'pb_ActivateArm'); +end + +function handles = EnableIfExists(handles,field) + if isfield(handles,field) + set(handles.(field),'Enable','on'); + end +end + +function handles = DisableIfExists(handles,field) + if isfield(handles,field) + set(handles.(field),'Enable','off'); + end end \ No newline at end of file diff --git a/Control/DisconnectVRE.m b/Comm/DisconnectVRE.m similarity index 95% rename from Control/DisconnectVRE.m rename to Comm/DisconnectVRE.m index 829e0a2..96eb48f 100644 --- a/Control/DisconnectVRE.m +++ b/Comm/DisconnectVRE.m @@ -1,48 +1,49 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Used to Disconnect any existing VRE on a struct. -% Can be used for Realtime, Training, Motion Test etc. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2013-01-29 / Nichlas Sander / Creation - -function handles = DisconnectVRE(handles) - if isfield(handles,'vre_Com') - fclose(handles.vre_Com); - handles = rmfield(handles,'vre_Com'); - end - handles = EnableIfExists(handles,'pb_socketConnect'); - handles = EnableIfExists(handles,'pb_socketConnect2'); - handles = DisableIfExists(handles,'pb_socketDisconnect'); - handles = DisableIfExists(handles,'pb_Camera'); - handles = DisableIfExists(handles,'pb_ActivateArm'); -end - -function handles = DisableIfExists(handles,field) - if isfield(handles,field) - set(handles.(field),'Enable','off'); - end -end - -function handles = EnableIfExists(handles,field) - if isfield(handles,field) - set(handles.(field),'Enable','on'); - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Used to Disconnect any existing VRE on a struct. +% Can be used for Realtime, Training, Motion Test etc. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2013-01-29 / Nichlas Sander / Creation + +function handles = DisconnectVRE(handles) + if isfield(handles,'vre_Com') + fclose(handles.vre_Com); + handles = rmfield(handles,'vre_Com'); + end + handles = EnableIfExists(handles,'pb_socketConnect'); + handles = EnableIfExists(handles,'pb_socketConnect2'); + handles = EnableIfExists(handles,'pb_ARarm'); + handles = DisableIfExists(handles,'pb_socketDisconnect'); + handles = DisableIfExists(handles,'pb_Camera'); + handles = DisableIfExists(handles,'pb_ActivateArm'); +end + +function handles = DisableIfExists(handles,field) + if isfield(handles,field) + set(handles.(field),'Enable','off'); + end +end + +function handles = EnableIfExists(handles,field) + if isfield(handles,field) + set(handles.(field),'Enable','on'); + end end \ No newline at end of file diff --git a/Comm/GetMovementCombination.m b/Comm/GetMovementCombination.m index aec8c3a..321d16f 100644 --- a/Comm/GetMovementCombination.m +++ b/Comm/GetMovementCombination.m @@ -1,98 +1,98 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Input: None. Hard-coded, should be dynamic. -% -% Output: combinations - The possible combinations of the inputting -% movements, with respect to the limitations in the limitMovements.def -% file. -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-07-30 / Nichlas Sander / Creation of GetMovementCombination - -function combinations = GetMovementCombination(num,numMovements) - -if num == 1 - combinations = randperm(numMovements)'; - return; -elseif num == 2 - if numMovements < 3 - return; - end - combos = [1,3;1,4;2,3;2,4;]; - if numMovements > 4 - combos = [combos; - 1,5; - 1,6; - 2,5; - 2,6; - 3,5; - 3,6; - 4,5; - 4,6; ]; - end -elseif num == 3 - if numMovements < 6 - return; - end - combos = [ 1,3,5; - 1,3,6; - 1,4,5; - 1,4,6; - 2,3,5; - 2,3,6; - 2,4,5; - 2,4,6; ]; -else - - return; -end - - -combinations = combos(randperm(length(combos)),:); - -% fid = fopen('limitMovements.def'); -% tline = fgetl(fid); -% while ischar(tline) -% %Puts the data of tline into t -% t = textscan(tline,'%s','delimiter',';'); -% t = t{1}; -% %These are for movements that are not to be combined with any other -% %movements, such as rest. -% if strcmp(t(2),'*') -% tline = fgetl(fid); -% continue; -% end -% temp = t(2); -% temp = textscan(temp{1},'%s','delimiter',','); -% limitMovements(t(1),2:length(temp{1})+1) = temp{1}; -% tline = fgetl(fid); -% end -% %Loop through the movements, and generate a random array. -% for j = 1:size(movOutIdx,1) -% movement = movements(movOutIdx{j}); -% notAllowed = limitMovements(movement.idVRE,:); -% movs = movOutIdx; -% movs(j) = []; -% movs(find(movs == notAllowed)) = []; -% end -% -% combinations = zeros(length(movements),1); -% -% fclose(fid); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Input: None. Hard-coded, should be dynamic. +% +% Output: combinations - The possible combinations of the inputting +% movements, with respect to the limitations in the limitMovements.def +% file. +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-07-30 / Nichlas Sander / Creation of GetMovementCombination + +function combinations = GetMovementCombination(num,numMovements) + +if num == 1 + combinations = randperm(numMovements)'; + return; +elseif num == 2 + if numMovements < 3 + return; + end + combos = [1,3;1,4;2,3;2,4;]; + if numMovements > 4 + combos = [combos; + 1,5; + 1,6; + 2,5; + 2,6; + 3,5; + 3,6; + 4,5; + 4,6; ]; + end +elseif num == 3 + if numMovements < 6 + return; + end + combos = [ 1,3,5; + 1,3,6; + 1,4,5; + 1,4,6; + 2,3,5; + 2,3,6; + 2,4,5; + 2,4,6; ]; +else + + return; +end + + +combinations = combos(randperm(length(combos)),:); + +% fid = fopen('limitMovements.def'); +% tline = fgetl(fid); +% while ischar(tline) +% %Puts the data of tline into t +% t = textscan(tline,'%s','delimiter',';'); +% t = t{1}; +% %These are for movements that are not to be combined with any other +% %movements, such as rest. +% if strcmp(t(2),'*') +% tline = fgetl(fid); +% continue; +% end +% temp = t(2); +% temp = textscan(temp{1},'%s','delimiter',','); +% limitMovements(t(1),2:length(temp{1})+1) = temp{1}; +% tline = fgetl(fid); +% end +% %Loop through the movements, and generate a random array. +% for j = 1:size(movOutIdx,1) +% movement = movements(movOutIdx{j}); +% notAllowed = limitMovements(movement.idVRE,:); +% movs = movOutIdx; +% movs(j) = []; +% movs(find(movs == notAllowed)) = []; +% end +% +% combinations = zeros(length(movements),1); +% +% fclose(fid); end \ No newline at end of file diff --git a/Comm/Keys/GUI_SendKeys.fig b/Comm/Keys/GUI_SendKeys.fig index c02c382..05afa55 100644 Binary files a/Comm/Keys/GUI_SendKeys.fig and b/Comm/Keys/GUI_SendKeys.fig differ diff --git a/Comm/Keys/GUI_SendKeys.m b/Comm/Keys/GUI_SendKeys.m index 363878a..a2ce5bf 100644 --- a/Comm/Keys/GUI_SendKeys.m +++ b/Comm/Keys/GUI_SendKeys.m @@ -22,7 +22,7 @@ % Edit the above text to modify the response to help GUI_SendKeys -% Last Modified by GUIDE v2.5 22-Nov-2012 09:30:26 +% Last Modified by GUIDE v2.5 07-Aug-2013 14:54:20 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -65,14 +65,13 @@ function GUI_SendKeys_OpeningFcn(hObject, eventdata, handles, varargin) movements = mainHandles.patRec.mov; handles.mov = movements; - - numberOfMovements = mainHandles.patRec.nOuts; - - for i = 1:numberOfMovements + for i = 1:length(movements) obj = sprintf('txt_%i',i); - set(handles.(obj),'String',movements{i}); + if(isfield(handles,obj)) + set(handles.(obj),'String',movements{i}); + end end - for i = numberOfMovements:7 + for i = length(movements):7 obj = sprintf('txt_%i',i); set(handles.(obj),'Visible','off'); obj = sprintf('popupmenu%i',i); @@ -276,14 +275,185 @@ function pb_close_Callback(hObject, eventdata, handles) inObj = handles.main; savedKeys = zeros(length(handles.mov),1); +savedControls = zeros(length(handles.mov),1); for i = 1:length(handles.mov)-1 obj = sprintf('popupmenu%i',i); - savedKeys(i) = get(handles.(obj),'Value') - 1; + if(isfield(handles,obj)) + savedKeys(i) = get(handles.(obj),'Value') - 1; + end +end +for i = 1:length(handles.mov)-1 + obj = sprintf('popupmenu%i',i+7); + if(isfield(handles,obj)) + savedControls(i) = get(handles.(obj),'Value') - 1; + end end mainHandles = guidata(inObj); mainHandles.savedKeys = savedKeys; +mainHandles.savedControls = savedControls; guidata(inObj,mainHandles); close(clf); + + +% --- Executes on selection change in popupmenu8. +function popupmenu8_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu8 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu8 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu8 + + +% --- Executes during object creation, after setting all properties. +function popupmenu8_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu8 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu9. +function popupmenu9_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu9 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu9 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu9 + + +% --- Executes during object creation, after setting all properties. +function popupmenu9_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu9 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu10. +function popupmenu10_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu10 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu10 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu10 + + +% --- Executes during object creation, after setting all properties. +function popupmenu10_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu10 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu11. +function popupmenu11_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu11 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu11 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu11 + + +% --- Executes during object creation, after setting all properties. +function popupmenu11_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu11 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu12. +function popupmenu12_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu12 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu12 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu12 + + +% --- Executes during object creation, after setting all properties. +function popupmenu12_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu12 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu13. +function popupmenu13_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu13 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu13 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu13 + + +% --- Executes during object creation, after setting all properties. +function popupmenu13_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu13 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in popupmenu14. +function popupmenu14_Callback(hObject, eventdata, handles) +% hObject handle to popupmenu14 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu14 contents as cell array +% contents{get(hObject,'Value')} returns selected item from popupmenu14 + + +% --- Executes during object creation, after setting all properties. +function popupmenu14_CreateFcn(hObject, eventdata, handles) +% hObject handle to popupmenu14 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 diff --git a/Control/ResetVRE.m b/Comm/ResetVRE.m similarity index 97% rename from Control/ResetVRE.m rename to Comm/ResetVRE.m index ce29d7f..b206233 100644 --- a/Control/ResetVRE.m +++ b/Comm/ResetVRE.m @@ -1,34 +1,34 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This is used to reset the position of a specified hand within a -% VRE-session. -% The 'returningValue' specifies whether the VR-system is expected to -% return a value. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2013-01-29 / Nichlas Sander / Creation - -function ResetVRE(obj,handToReset, returningValue) - fwrite(obj,sprintf('%c%c%c%c%c','r',char(handToReset),char(0),char(0),char(0))); - if returningValue - fread(obj,1); - end -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This is used to reset the position of a specified hand within a +% VRE-session. +% The 'returningValue' specifies whether the VR-system is expected to +% return a value. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2013-01-29 / Nichlas Sander / Creation + +function ResetVRE(obj,handToReset, returningValue) + fwrite(obj,sprintf('%c%c%c%c%c','r',char(handToReset),char(0),char(0),char(0))); + if returningValue + fread(obj,1); + end +end + diff --git a/Comm/SendKeys.m b/Comm/SendKeys.m index d3b1e63..2a54c1c 100644 --- a/Comm/SendKeys.m +++ b/Comm/SendKeys.m @@ -1,66 +1,66 @@ -function SendKeys(keys,savedKeys) - import java.awt.*; - import java.awt.event.*; - rob=Robot; - - %AvailableKeys = {KeyEvent.VK_A,KeyEvent.VK_B,KeyEvent.VK_C,KeyEvent.VK_D,KeyEvent.VK_E,KeyEvent.VK_F,KeyEvent.VK_G,KeyEvent.VK_H,KeyEvent.VK_I,KeyEvent.VK_J,KeyEvent.VK_K,KeyEvent.VK_L,KeyEvent.VK_M,KeyEvent.VK_N,KeyEvent.VK_O,KeyEvent.VK_P,KeyEvent.VK_Q,KeyEvent.VK_R,KeyEvent.VK_S,KeyEvent.VK_T,KeyEvent.VK_U,KeyEvent.VK_V,KeyEvent.VK_W,KeyEvent.VK_X,KeyEvent.VK_Y,KeyEvent.VK_Z}; - - if(numel(savedKeys) > 0) - for i = 1:length(savedKeys) - KeyFunction(savedKeys(i),keys(i),rob); - end - else - if keys(1) - rob.keyPress(KeyEvent.VK_W); - else - rob.keyRelease(KeyEvent.VK_W); - end - if keys(2) - rob.keyPress(KeyEvent.VK_S); - else - rob.keyRelease(KeyEvent.VK_S); - end - if keys(3) - rob.keyPress(KeyEvent.VK_A); - else - rob.keyRelease(KeyEvent.VK_A); - end - if keys(4) - rob.keyPress(KeyEvent.VK_D); - else - rob.keyRelease(KeyEvent.VK_D); - end - end -end - -function KeyFunction(key,event,rob) - import java.awt.*; - import java.awt.event.*; - - switch(key) - case 1 - if event - rob.keyPress(KeyEvent.VK_W); - else - rob.keyRelease(KeyEvent.VK_W); - end - case 2 - if event - rob.keyPress(KeyEvent.VK_A); - else - rob.keyRelease(KeyEvent.VK_A); - end - case 3 - if event - rob.keyPress(KeyEvent.VK_S); - else - rob.keyRelease(KeyEvent.VK_S); - end - case 4 - if event - rob.keyPress(KeyEvent.VK_D); - else - rob.keyRelease(KeyEvent.VK_D); - end - end +function SendKeys(keys,savedKeys) + import java.awt.*; + import java.awt.event.*; + rob=Robot; + + %AvailableKeys = {KeyEvent.VK_A,KeyEvent.VK_B,KeyEvent.VK_C,KeyEvent.VK_D,KeyEvent.VK_E,KeyEvent.VK_F,KeyEvent.VK_G,KeyEvent.VK_H,KeyEvent.VK_I,KeyEvent.VK_J,KeyEvent.VK_K,KeyEvent.VK_L,KeyEvent.VK_M,KeyEvent.VK_N,KeyEvent.VK_O,KeyEvent.VK_P,KeyEvent.VK_Q,KeyEvent.VK_R,KeyEvent.VK_S,KeyEvent.VK_T,KeyEvent.VK_U,KeyEvent.VK_V,KeyEvent.VK_W,KeyEvent.VK_X,KeyEvent.VK_Y,KeyEvent.VK_Z}; + + if(numel(savedKeys) > 0) + for i = 1:length(savedKeys) + KeyFunction(savedKeys(i),keys(i),rob); + end + else + if keys(1) + rob.keyPress(KeyEvent.VK_W); + else + rob.keyRelease(KeyEvent.VK_W); + end + if keys(2) + rob.keyPress(KeyEvent.VK_S); + else + rob.keyRelease(KeyEvent.VK_S); + end + if keys(3) + rob.keyPress(KeyEvent.VK_A); + else + rob.keyRelease(KeyEvent.VK_A); + end + if keys(4) + rob.keyPress(KeyEvent.VK_D); + else + rob.keyRelease(KeyEvent.VK_D); + end + end +end + +function KeyFunction(key,event,rob) + import java.awt.*; + import java.awt.event.*; + + switch(key) + case 1 + if event + rob.keyPress(KeyEvent.VK_W); + else + rob.keyRelease(KeyEvent.VK_W); + end + case 2 + if event + rob.keyPress(KeyEvent.VK_A); + else + rob.keyRelease(KeyEvent.VK_A); + end + case 3 + if event + rob.keyPress(KeyEvent.VK_S); + else + rob.keyRelease(KeyEvent.VK_S); + end + case 4 + if event + rob.keyPress(KeyEvent.VK_D); + else + rob.keyRelease(KeyEvent.VK_D); + end + end end \ No newline at end of file diff --git a/Comm/VRE/GUI_Test_VRE.fig b/Comm/VRE/GUI_Test_VRE.fig index ade2e37..a271ace 100644 Binary files a/Comm/VRE/GUI_Test_VRE.fig and b/Comm/VRE/GUI_Test_VRE.fig differ diff --git a/Comm/VRE/GUI_Test_VRE.m b/Comm/VRE/GUI_Test_VRE.m index f82d8e2..8245356 100644 --- a/Comm/VRE/GUI_Test_VRE.m +++ b/Comm/VRE/GUI_Test_VRE.m @@ -22,7 +22,7 @@ % Edit the above text to modify the response to help GUI_Test_VRE -% Last Modified by GUIDE v2.5 07-Dec-2012 13:46:35 +% Last Modified by GUIDE v2.5 22-Oct-2013 11:25:20 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -73,24 +73,25 @@ function GUI_Test_VRE_OpeningFcn(hObject, eventdata, handles, varargin) varargout{1} = handles.output; -% --- Executes on button press in pb_connect. -function pb_connect_Callback(hObject, eventdata, handles) -% hObject handle to pb_connect (see GCBO) +% --- Executes on button press in pb_startVRE. +function pb_startVRE_Callback(hObject, eventdata, handles) +% hObject handle to pb_startVRE (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -if(strcmp(get(handles.pb_connect,'String'),'Connect')) - port = str2double(get(handles.et_connection,'String')); - set(handles.t_msg,'String','Waiting for client connection.'); - obj = tcpip('127.0.0.1',port,'NetworkRole','server'); - fopen(obj); - set(handles.t_msg,'String','Server established on port'); - set(handles.pb_connect,'String','Disconnect'); - handles.com = obj; -else - fclose(handles.com); - set(handles.t_msg,'String','Disconnected'); - set(handles.pb_connect,'String','Connect'); -end +% % if(strcmp(get(handles.pb_startVRE,'String'),'Connect')) +% % port = str2double(get(handles.et_connection,'String')); +% % set(handles.t_msg,'String','Waiting for client connection.'); +% % obj = tcpip('127.0.0.1',port,'NetworkRole','server'); +% % fopen(obj); +% % set(handles.t_msg,'String','Server established on port'); +% % set(handles.pb_startVRE,'String','Disconnect'); +% % handles.com = obj; +% % else +% % fclose(handles.com); +% % set(handles.t_msg,'String','Disconnected'); +% % set(handles.pb_startVRE,'String','Connect'); +% % end +handles = ConnectVRE(handles,'Virtual Reality.exe'); guidata(hObject,handles); % --- Executes during object creation, after setting all properties. @@ -105,19 +106,20 @@ function et_connection_CreateFcn(hObject, eventdata, handles) set(hObject,'BackgroundColor','white'); end -% --- Executes on button press in pb_start. -function pb_start_Callback(hObject, eventdata, handles) -% hObject handle to pb_start (see GCBO) +% --- Executes on button press in pb_startARE. +function pb_startARE_Callback(hObject, eventdata, handles) +% hObject handle to pb_startARE (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -open('Virtual Reality.exe'); +handles = ConnectVRE(handles,'Augmented Reality.exe'); +guidata(hObject,handles); % --- Executes on button press in pb_sendValues. function pb_sendValues_Callback(hObject, eventdata, handles) % hObject handle to pb_sendValues (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -obj = handles.com; +obj = handles.vre_Com; one = get(handles.tb_value1,'String'); two = get(handles.tb_value2,'String'); three = get(handles.tb_value3,'String'); @@ -250,3 +252,60 @@ function tb_value5_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end + + +% --- Executes on button press in pb_send100. +function pb_send100_Callback(hObject, eventdata, handles) +% hObject handle to pb_send100 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +obj = handles.vre_Com; +one = get(handles.tb_value1,'String'); +two = get(handles.tb_value2,'String'); +three = get(handles.tb_value3,'String'); +four = get(handles.tb_value4,'String'); +five = get(handles.tb_value5,'String'); +pause on; +% VREActivation(obj,four,[],two, three, 0); +tic; +for i = 1:100 + fwrite(obj,sprintf('%c%c%c%c%c',checkValues(one),checkValues(two),checkValues(three),checkValues(four), checkValues(five))); + if handles.returnValues + fread(obj,1); + end +end +set(handles.txt_Time,'String',toc); + + +% --- Executes on button press in pb_return. +function pb_return_Callback(hObject, eventdata, handles) +% hObject handle to pb_return (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% % if handles.returnValues +% % fwrite(handles.com,sprintf('%c%c%c%c%c','c',char(7),char(0),char(0),char(0))); +% % handles.returnValues = 0; +% % else +% % fwrite(handles.com,sprintf('%c%c%c%c%c','c',char(7),char(1),char(0),char(0))); +% % handles.returnValues = 1; +% % end +handles = DisconnectVRE(handles); +guidata(hObject, handles); + + +% --- If Enable == 'on', executes on mouse press in 5 pixel border. +% --- Otherwise, executes on mouse press in 5 pixel border or over pb_startARE. +function pb_startARE_ButtonDownFcn(hObject, eventdata, handles) +% hObject handle to pb_startARE (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +handles = ConnectVRE(handles,'Augmented Reality.exe'); +guidata(hObject,handles); + +% --- Executes on button press in pb_startAREARM. +function pb_startAREARM_Callback(hObject, eventdata, handles) +% hObject handle to pb_startAREARM (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +handles = ConnectVRE(handles,'Augmented Reality ARM.exe'); +guidata(hObject,handles); diff --git a/Comm/VRE/Ogre.log b/Comm/VRE/Ogre.log index c554b32..aa0c11b 100644 --- a/Comm/VRE/Ogre.log +++ b/Comm/VRE/Ogre.log @@ -1,31 +1,31 @@ -16:33:58: Creating resource group General -16:33:58: Creating resource group Internal -16:33:58: Creating resource group Autodetect -16:33:58: SceneManagerFactory for type 'DefaultSceneManager' registered. -16:33:58: Registering ResourceManager for type Material -16:33:58: Registering ResourceManager for type Mesh -16:33:58: Registering ResourceManager for type Skeleton -16:33:58: MovableObjectFactory for type 'ParticleSystem' registered. -16:33:58: OverlayElementFactory for type Panel registered. -16:33:58: OverlayElementFactory for type BorderPanel registered. -16:33:58: OverlayElementFactory for type TextArea registered. -16:33:58: Registering ResourceManager for type Font -16:33:58: ArchiveFactory for archive type FileSystem registered. -16:33:58: ArchiveFactory for archive type Zip registered. -16:33:58: DDS codec registering -16:33:58: FreeImage version: 3.13.1 -16:33:58: This program uses FreeImage, a free, open source image library supporting all common bitmap formats. See http://freeimage.sourceforge.net for details -16:33:58: Supported formats: bmp,ico,jpg,jif,jpeg,jpe,jng,koa,iff,lbm,mng,pbm,pbm,pcd,pcx,pgm,pgm,png,ppm,ppm,ras,tga,targa,tif,tiff,wap,wbmp,wbm,psd,cut,xbm,xpm,gif,hdr,g3,sgi,exr,j2k,j2c,jp2,pfm,pct,pict,pic,bay,bmq,cr2,crw,cs1,dc2,dcr,dng,erf,fff,hdr,k25,kdc,mdc,mos,mrw,nef,orf,pef,pxn,raf,raw,rdc,sr2,srf,arw,3fr,cine,ia,kc2,mef,nrw,qtk,rw2,sti,drf,dsc,ptx,cap,iiq,rwz -16:33:58: Registering ResourceManager for type HighLevelGpuProgram -16:33:58: Registering ResourceManager for type Compositor -16:33:58: MovableObjectFactory for type 'Entity' registered. -16:33:58: MovableObjectFactory for type 'Light' registered. -16:33:58: MovableObjectFactory for type 'BillboardSet' registered. -16:33:58: MovableObjectFactory for type 'ManualObject' registered. -16:33:58: MovableObjectFactory for type 'BillboardChain' registered. -16:33:58: MovableObjectFactory for type 'RibbonTrail' registered. -16:33:58: OGRE EXCEPTION(6:FileNotFoundException): 'plugins_d.cfg' file not found! in ConfigFile::load at ..\..\..\..\OgreMain\src\OgreConfigFile.cpp (line 83) -16:33:58: plugins_d.cfg not found, automatic plugin loading disabled. -16:33:58: *-*-* OGRE Initialising -16:33:58: *-*-* Version 1.7.2 (Cthugha) -16:33:58: OGRE EXCEPTION(6:FileNotFoundException): 'ogre.cfg' file not found! in ConfigFile::load at ..\..\..\..\OgreMain\src\OgreConfigFile.cpp (line 83) +16:33:58: Creating resource group General +16:33:58: Creating resource group Internal +16:33:58: Creating resource group Autodetect +16:33:58: SceneManagerFactory for type 'DefaultSceneManager' registered. +16:33:58: Registering ResourceManager for type Material +16:33:58: Registering ResourceManager for type Mesh +16:33:58: Registering ResourceManager for type Skeleton +16:33:58: MovableObjectFactory for type 'ParticleSystem' registered. +16:33:58: OverlayElementFactory for type Panel registered. +16:33:58: OverlayElementFactory for type BorderPanel registered. +16:33:58: OverlayElementFactory for type TextArea registered. +16:33:58: Registering ResourceManager for type Font +16:33:58: ArchiveFactory for archive type FileSystem registered. +16:33:58: ArchiveFactory for archive type Zip registered. +16:33:58: DDS codec registering +16:33:58: FreeImage version: 3.13.1 +16:33:58: This program uses FreeImage, a free, open source image library supporting all common bitmap formats. See http://freeimage.sourceforge.net for details +16:33:58: Supported formats: bmp,ico,jpg,jif,jpeg,jpe,jng,koa,iff,lbm,mng,pbm,pbm,pcd,pcx,pgm,pgm,png,ppm,ppm,ras,tga,targa,tif,tiff,wap,wbmp,wbm,psd,cut,xbm,xpm,gif,hdr,g3,sgi,exr,j2k,j2c,jp2,pfm,pct,pict,pic,bay,bmq,cr2,crw,cs1,dc2,dcr,dng,erf,fff,hdr,k25,kdc,mdc,mos,mrw,nef,orf,pef,pxn,raf,raw,rdc,sr2,srf,arw,3fr,cine,ia,kc2,mef,nrw,qtk,rw2,sti,drf,dsc,ptx,cap,iiq,rwz +16:33:58: Registering ResourceManager for type HighLevelGpuProgram +16:33:58: Registering ResourceManager for type Compositor +16:33:58: MovableObjectFactory for type 'Entity' registered. +16:33:58: MovableObjectFactory for type 'Light' registered. +16:33:58: MovableObjectFactory for type 'BillboardSet' registered. +16:33:58: MovableObjectFactory for type 'ManualObject' registered. +16:33:58: MovableObjectFactory for type 'BillboardChain' registered. +16:33:58: MovableObjectFactory for type 'RibbonTrail' registered. +16:33:58: OGRE EXCEPTION(6:FileNotFoundException): 'plugins_d.cfg' file not found! in ConfigFile::load at ..\..\..\..\OgreMain\src\OgreConfigFile.cpp (line 83) +16:33:58: plugins_d.cfg not found, automatic plugin loading disabled. +16:33:58: *-*-* OGRE Initialising +16:33:58: *-*-* Version 1.7.2 (Cthugha) +16:33:58: OGRE EXCEPTION(6:FileNotFoundException): 'ogre.cfg' file not found! in ConfigFile::load at ..\..\..\..\OgreMain\src\OgreConfigFile.cpp (line 83) diff --git a/Comm/limitMovements.def b/Comm/limitMovements.def index 52ad925..2228807 100644 --- a/Comm/limitMovements.def +++ b/Comm/limitMovements.def @@ -1,7 +1,7 @@ -0;* -1;2,7,8,9,10,11,12,13,14,15,16,17,18,19 -2;1,7,8,9,10,11,12,13,14,15,16,17,18,19 -3;4 -4;3 -5;6 +0;* +1;2,7,8,9,10,11,12,13,14,15,16,17,18,19 +2;1,7,8,9,10,11,12,13,14,15,16,17,18,19 +3;4 +4;3 +5;6 6;5 \ No newline at end of file diff --git a/Comm/motors.def b/Comm/motors.def deleted file mode 100644 index 3a62b14..0000000 --- a/Comm/motors.def +++ /dev/null @@ -1,8 +0,0 @@ -0,0,0 -A,0,60 -B,0,60 -C,0,60 -D,0,100 -E,0,100 -K,1,72 -L,1,54 \ No newline at end of file diff --git a/Comm/movements.def b/Comm/movements.def deleted file mode 100644 index cb12416..0000000 --- a/Comm/movements.def +++ /dev/null @@ -1,25 +0,0 @@ -0,Rest,0,0,1 -1,Open Hand,9,1,2 -2,Close Hand,9,0,2 -3,Flex Hand,7,0,1 -4,Ext Hand,7,1,1 -5,Pronation,8,0,3 -6,Supination,8,1,3 -24,Side Grip,13,1,1 -23,Fine Grip,12,1,1 -22,Agree,11,1,1 -17,Point,10,1,1 -7,Thumb Ext,5,1,1 -8,Thumb Flex,5,0,1 -19,Thumb Yaw Ext,6,1,1 -18,Thumb Yaw Flex,6,0,1 -20,Flex Elbow,15,1,4 -21,Ext Elbow,15,0,4 -9,Index Ext,4,1,1 -10,Index Flex,4,0,1 -11,Middle Ext,3,1,1 -12,Middle Flex,3,0,1 -13,Ring Ext,2,1,1 -14,Ring Flex,2,0,1 -15,Little Ext,1,1,1 -16,Little Flex,1,0,1 diff --git a/Control/ActivateMotors.m b/Control/ActivateMotors.m index d70fc1c..a975190 100644 --- a/Control/ActivateMotors.m +++ b/Control/ActivateMotors.m @@ -1,74 +1,74 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to update the motors. A motor is paired to 2 movements which make -% the different directions for the motor. If both movements are selected at -% the same time, they are both discarted. -% -% It runs over the lenght of pwmIDs/2 and assigns the corresponding pwm -% value saved in pwmAs and pwmBs. The selected motors to activate are taken -% from outMov. -% -% --------------------------Updates-------------------------- -% 2011-11-17 / Max Ortiz / Creation -% 2012-03-19 / Max Ortiz / Review if the recieved outMov is different from -% the last one, otherwise don't update the motors PWM - - -function ActivateMotors(com, pwmIDs, pwmAs, pwmBs, outMov) - -persistent outMovLast; - -if isempty(outMovLast) - outMovLast = zeros(1,size(pwmIDs,1)); -end - -toutMov = zeros(1,10); - if outMov ~= 0 - toutMov(outMov) = 1; - end -outMov = toutMov; - -if ~strcmp(outMov,outMovLast) - % Go through all PWMS - for i = 1 : 2 : size(pwmIDs) - % Only send the PWMs that have change - if outMov(i) ~= outMovLast(i) || outMov(i+1) ~= outMovLast(i+1) - % Only considered one movement per motor (or nothing) - if xor(outMov(i), outMov(i+1)) - if outMov(i) - pwmA = pwmAs(i); - pwmB = pwmBs(i); - else - pwmA = pwmAs(i+1); - pwmB = pwmBs(i+1); - end - else - pwmA = 0; - pwmB = 0; - end - - % Send motor values - if ~Update2PWMusingSCI(com, pwmIDs(i), pwmA, pwmB) - set(handles.t_msg,'String',['Failed in motor ' pwmID(round(i/2))]); - end - end - end -end - -outMovLast = outMov; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to update the motors. A motor is paired to 2 movements which make +% the different directions for the motor. If both movements are selected at +% the same time, they are both discarted. +% +% It runs over the lenght of pwmIDs/2 and assigns the corresponding pwm +% value saved in pwmAs and pwmBs. The selected motors to activate are taken +% from outMov. +% +% --------------------------Updates-------------------------- +% 2011-11-17 / Max Ortiz / Creation +% 2012-03-19 / Max Ortiz / Review if the recieved outMov is different from +% the last one, otherwise don't update the motors PWM + + +function ActivateMotors(com, pwmIDs, pwmAs, pwmBs, outMov) + +persistent outMovLast; + +if isempty(outMovLast) + outMovLast = zeros(1,size(pwmIDs,1)); +end + +toutMov = zeros(1,10); + if outMov ~= 0 + toutMov(outMov) = 1; + end +outMov = toutMov; + +if ~strcmp(outMov,outMovLast) + % Go through all PWMS + for i = 1 : 2 : size(pwmIDs) + % Only send the PWMs that have change + if outMov(i) ~= outMovLast(i) || outMov(i+1) ~= outMovLast(i+1) + % Only considered one movement per motor (or nothing) + if xor(outMov(i), outMov(i+1)) + if outMov(i) + pwmA = pwmAs(i); + pwmB = pwmBs(i); + else + pwmA = pwmAs(i+1); + pwmB = pwmBs(i+1); + end + else + pwmA = 0; + pwmB = 0; + end + + % Send motor values + if ~Update2PWMusingSCI(com, pwmIDs(i), pwmA, pwmB) + set(handles.t_msg,'String',['Failed in motor ' pwmID(round(i/2))]); + end + end + end +end + +outMovLast = outMov; diff --git a/Control/ApplyControl.m b/Control/ApplyControl.m index 7ee50f9..35f906a 100644 --- a/Control/ApplyControl.m +++ b/Control/ApplyControl.m @@ -1,78 +1,78 @@ -%% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% [patRec, outMov] = ApplyControl(patRec, outMov, outVec) -% -% Applies the control algorithm stored inside patRec.control, if no -% controlAlg structure is created, the outMov is passed through to -% the output. -% -% INPUTS: -% -% outMov - is the outMov predicted by the classifier -% -% outVec - is the probabilities of each movement predicted by the -% classifier -% -% OUTPUTS: -% -% patRec - is the updated patRec structure, the control algorithms can -% change e.g. their own properties and the output buffer. Inorder for -% the control algorithms to work as intended, these changes has to be -% stored between trials. -% -% outMov - is the movement outputted from the control algorithm, may -% not be the same as the outMov predicted by the classifier. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-07-18 / Max Ortiz / Creation (moved out from RealtimePatRec) -% -% 2012-10-05 / Joel Falk-Dahlin / Changing from string checking to storing -% a function handle within the controlAlg -% structrue. Allows a single function call -% to execute all controlAlg and no extra -% hard coding is needed to implement new. -% -% Added outVec and handles as extra inputs -% to allow for even more complex control -% algorithms. -% -% 2012-10-19 / Joel Falk-Dahlin / Added outMov = 0 control. -% 2012-11-23 / Joel Falk-Dahlin / Removed handles since speeds now are in -% patRec -% -% 20xx-xx-xx / Author / Comment on update - -function [patRec, outMov] = ApplyControl(patRec, outMov, outVec) - - if isfield(patRec.control,'controlAlg') - [patRec, outMov] = patRec.control.controlAlg.fnc(patRec, outMov, outVec); - end - -%% OLD CODE -% if strcmp(patRec.controlAlg,'Majority vote') -% [patRec outMov] = MajorityVote(patRec,outMov); -% elseif strcmp(patRec.controlAlg,'Buffer output') -% [patRec outMov] = BufferOutput(patRec,outMov); -% elseif strcmp(patRec.controlAlg,'Ramp') -% -% end -end +%% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% [patRec, outMov] = ApplyControl(patRec, outMov, outVec) +% +% Applies the control algorithm stored inside patRec.control, if no +% controlAlg structure is created, the outMov is passed through to +% the output. +% +% INPUTS: +% +% outMov - is the outMov predicted by the classifier +% +% outVec - is the probabilities of each movement predicted by the +% classifier +% +% OUTPUTS: +% +% patRec - is the updated patRec structure, the control algorithms can +% change e.g. their own properties and the output buffer. Inorder for +% the control algorithms to work as intended, these changes has to be +% stored between trials. +% +% outMov - is the movement outputted from the control algorithm, may +% not be the same as the outMov predicted by the classifier. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-07-18 / Max Ortiz / Creation (moved out from RealtimePatRec) +% +% 2012-10-05 / Joel Falk-Dahlin / Changing from string checking to storing +% a function handle within the controlAlg +% structrue. Allows a single function call +% to execute all controlAlg and no extra +% hard coding is needed to implement new. +% +% Added outVec and handles as extra inputs +% to allow for even more complex control +% algorithms. +% +% 2012-10-19 / Joel Falk-Dahlin / Added outMov = 0 control. +% 2012-11-23 / Joel Falk-Dahlin / Removed handles since speeds now are in +% patRec +% +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = ApplyControl(patRec, outMov, outVec) + + if isfield(patRec.control,'controlAlg') + [patRec, outMov] = patRec.control.controlAlg.fnc(patRec, outMov, outVec); + end + +%% OLD CODE +% if strcmp(patRec.controlAlg,'Majority vote') +% [patRec outMov] = MajorityVote(patRec,outMov); +% elseif strcmp(patRec.controlAlg,'Buffer output') +% [patRec outMov] = BufferOutput(patRec,outMov); +% elseif strcmp(patRec.controlAlg,'Ramp') +% +% end +end \ No newline at end of file diff --git a/Control/ApplyProportionalControl.m b/Control/ApplyProportionalControl.m index 5b25ec3..d894086 100644 --- a/Control/ApplyProportionalControl.m +++ b/Control/ApplyProportionalControl.m @@ -1,79 +1,79 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% patRec = ApplyProportionalControl(tSet,patRec) -% -% Calculates degrees to move based upon the variables stored inside -% patRec.control.propControl. If propControl does not exist, the -% movements are performed at maximum degrees per movement, which is -% stored within patRec.control.maxDegPerMov -% -% INPUTS: -% -% tSet - feature set calculated from one time window, can be -% calculated by SignalProcessing_RealtimePatRec(). -% -% patRec - the pattern recognition structure -% -% OUTPUTS: -% -% patRec - updated pattern recognition structure containing -% patRec.control.currentDegPerMov, which are the degrees to move -% the device with for this particular prediction. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-26 / Joel Falk-Dahlin / Creation -% -% 2012-11-06 / Joel Falk-Dahlin / Changed so that features are not -% recalculated, uses tSet vector instead. -% -% 2012-11-23 / Joel Falk-Dahlin / Removed handles since speeds now are in -% patRec -% -% 20xx-xx-xx / Author / Comment on update - -function patRec = ApplyProportionalControl(tSet,patRec) - -% If proportional control is being used, calculate desired speed -if isfield(patRec.control,'propControl') - - % Extract proportional Control variables - propMinThresh = patRec.control.propControl.propMinThresh; - propMaxThresh = patRec.control.propControl.propMaxThresh; - propSpeedMap = patRec.control.propControl.propSpeedMap; - - % Extract tSet indicies - nCh = length(patRec.nCh); - selFeature = patRec.control.propControl.propFeature; - idx = nCh*(selFeature-1)+1:nCh*(selFeature-1)+nCh; - - % Calculate Feature value - featureVal = abs( mean( tSet(idx) ) ); - - % Map Feature value to speed percent - speedPercent = CalculateDesiredSpeedPercent(featureVal, propMinThresh, ... - propMaxThresh, propSpeedMap); - - % Output Speeds - patRec.control.currentDegPerMov = patRec.control.maxDegPerMov.*speedPercent.*0.01; - -% If not proportional control is used, set speed to maximum speed -else - patRec.control.currentDegPerMov = patRec.control.maxDegPerMov; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% patRec = ApplyProportionalControl(tSet,patRec) +% +% Calculates degrees to move based upon the variables stored inside +% patRec.control.propControl. If propControl does not exist, the +% movements are performed at maximum degrees per movement, which is +% stored within patRec.control.maxDegPerMov +% +% INPUTS: +% +% tSet - feature set calculated from one time window, can be +% calculated by SignalProcessing_RealtimePatRec(). +% +% patRec - the pattern recognition structure +% +% OUTPUTS: +% +% patRec - updated pattern recognition structure containing +% patRec.control.currentDegPerMov, which are the degrees to move +% the device with for this particular prediction. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-26 / Joel Falk-Dahlin / Creation +% +% 2012-11-06 / Joel Falk-Dahlin / Changed so that features are not +% recalculated, uses tSet vector instead. +% +% 2012-11-23 / Joel Falk-Dahlin / Removed handles since speeds now are in +% patRec +% +% 20xx-xx-xx / Author / Comment on update + +function patRec = ApplyProportionalControl(tSet,patRec) + +% If proportional control is being used, calculate desired speed +if isfield(patRec.control,'propControl') + + % Extract proportional Control variables + propMinThresh = patRec.control.propControl.propMinThresh; + propMaxThresh = patRec.control.propControl.propMaxThresh; + propSpeedMap = patRec.control.propControl.propSpeedMap; + + % Extract tSet indicies + nCh = length(patRec.nCh); + selFeature = patRec.control.propControl.propFeature; + idx = nCh*(selFeature-1)+1:nCh*(selFeature-1)+nCh; + + % Calculate Feature value + featureVal = abs( mean( tSet(idx) ) ); + + % Map Feature value to speed percent + speedPercent = CalculateDesiredSpeedPercent(featureVal, propMinThresh, ... + propMaxThresh, propSpeedMap); + + % Output Speeds + patRec.control.currentDegPerMov = patRec.control.maxDegPerMov.*speedPercent.*0.01; + +% If not proportional control is used, set speed to maximum speed +else + patRec.control.currentDegPerMov = patRec.control.maxDegPerMov; end \ No newline at end of file diff --git a/Control/BayesianFusion.m b/Control/BayesianFusion.m new file mode 100644 index 0000000..5c5ad14 --- /dev/null +++ b/Control/BayesianFusion.m @@ -0,0 +1,62 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% BayesianFusion control algorithm. This algorithm uses the predicted +% probabilities in outVec in the buffer instead of the predicted outmoves. +% The idea is that EMG signals recorded from windows disjoint in time are +% weakly correlated and the conditional propabilites of each move can be +% described as a product of the probabilities each time. +% +% Not suitable for simulataneous control because it only output one +% movement, the one with highest probability. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-09 / Joel Falk-Dahlin / Creation +% 2013-01-25 / Joel Falk-Dahlin / Changed algorithm to not make +% predictions if classifier did not find +% any movement (pass 'rest' through). +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = BayesianFusion(patRec, outMov, outVec) + +% Update buffer +patRec.control.outBuffer(1:end-1,:) = patRec.control.outBuffer(2:end,:); +patRec.control.outBuffer(end,:) = outVec; + +% Check if movement is Rest, if not make new prediction (Movement is rest +% if classifier did not find any motion, and no new prediction should be +% made) +if ismember(patRec.nOuts,outMov) && strcmp(patRec.mov{end},'Rest') + outMov = patRec.nOuts; + patRec.control.outBuffer(:) = 0; +else + % Read parameters + k = patRec.control.controlAlg.prop.k; + + % Calculate Joint probabilities + prob = prod(patRec.control.outBuffer + k); + %prob = prob/sum(prob,1); + + % Set outMov to movement with highest joint probability + if max(prob) > 0 + outMov = find( prob == max(prob) )'; + else + outMov = patRec.nOuts; + end +end \ No newline at end of file diff --git a/Control/BufferOutput.m b/Control/BufferOutput.m new file mode 100644 index 0000000..f328f47 --- /dev/null +++ b/Control/BufferOutput.m @@ -0,0 +1,38 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to compute the Majority voting control strategy. It looks at the +% latest prediction and extracts the most common +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-07-03 / Max Ortiz / Creation +% 2012-10-05 / Joel Falk-Dahlin / Changed input/ouputs to match controlAlg standard +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = BufferOutput(patRec,outMov, outVec) + +% Remove the oldest prediction +patRec.control.outBuffer = patRec.control.outBuffer(2:end,:); +% Add the new prediction +patRec.control.outBuffer(end+1,outMov) = 1; + +%% Compute output +% Not suitable for simltaneous control +outMov = find(0.5 <= sum(patRec.control.outBuffer)./size(patRec.control.outBuffer,1)); + diff --git a/Control/CalculateDesiredSpeedPercent.m b/Control/CalculateDesiredSpeedPercent.m index af54d74..d855037 100644 --- a/Control/CalculateDesiredSpeedPercent.m +++ b/Control/CalculateDesiredSpeedPercent.m @@ -1,89 +1,89 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% -% desiredSpeedPercent = CalculateDesiredSpeedPercent(featureCurrent, featureMin,featureMax, map) -% -% Function to convert a feature value to a desired speed percentage. -% The conversion is done using the threshold values featuresMin, -% featuresMax and the mapping function map. -% -% The value of featureCurrent is mapped to the interval of [0,1] -% where values <= featureMin are mapped to zero and values >= -% featureMax are mapped to 1. The value that is retrieved is -% recalculated using the map function, remapping it to the interval -% [0,1]. -% -% This function is used in proportional control -% -% INPUTS: -% -% featureCurrent - A number, currently the mean value of the selected -% feature to use with proportional control across all channels. -% -% featureMin - The threshold when movement should begin, all values -% below featureMin will be mapped to the value 0. -% -% featureMax - Feature value where maximum speed should be outputted, -% all values above featureMax will be mapped to the value 1. -% -% featureMap - string determining which function to use when mapping -% the value in [0,1] back onto the interval [0,1]. Available options -% are currently; 'linear', 'quad', 'sqrt'. -% -% OUTPUTS: -% -% desiredSpeedPercent - a number from 0 - 100 that gives how many -% percent of the maximum degrees per movement that are to be -% outputted. -% -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-10-26 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function desiredSpeedPercent = CalculateDesiredSpeedPercent(featureCurrent, featureMin,featureMax, map) - - if featureCurrent > featureMax - featureCurrent = featureMax; - elseif featureCurrent < featureMin - featureCurrent = featureMin; - end - - % Map into [0,1] interval - xVal = featureCurrent ./ (featureMax - featureMin) - featureMin./(featureMax - featureMin); - - % Now we can use any mapping we want (f(0) should be minimum - % activation percentage (0.0 for threshold), f(1) should be 100 percent (1.0) - - % Linear mapping - if strcmp(map, 'linear') - desiredSpeedPercent = xVal; - % Quadratic mapping - elseif strcmp(map,'quad') - desiredSpeedPercent = xVal.^2; - % Square-root mapping - elseif strcmp(map,'sqrt') - desiredSpeedPercent = sqrt(xVal); - else - desiredSpeedPercent = xVal; - end - - desiredSpeedPercent = desiredSpeedPercent*100; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% +% desiredSpeedPercent = CalculateDesiredSpeedPercent(featureCurrent, featureMin,featureMax, map) +% +% Function to convert a feature value to a desired speed percentage. +% The conversion is done using the threshold values featuresMin, +% featuresMax and the mapping function map. +% +% The value of featureCurrent is mapped to the interval of [0,1] +% where values <= featureMin are mapped to zero and values >= +% featureMax are mapped to 1. The value that is retrieved is +% recalculated using the map function, remapping it to the interval +% [0,1]. +% +% This function is used in proportional control +% +% INPUTS: +% +% featureCurrent - A number, currently the mean value of the selected +% feature to use with proportional control across all channels. +% +% featureMin - The threshold when movement should begin, all values +% below featureMin will be mapped to the value 0. +% +% featureMax - Feature value where maximum speed should be outputted, +% all values above featureMax will be mapped to the value 1. +% +% featureMap - string determining which function to use when mapping +% the value in [0,1] back onto the interval [0,1]. Available options +% are currently; 'linear', 'quad', 'sqrt'. +% +% OUTPUTS: +% +% desiredSpeedPercent - a number from 0 - 100 that gives how many +% percent of the maximum degrees per movement that are to be +% outputted. +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-10-26 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function desiredSpeedPercent = CalculateDesiredSpeedPercent(featureCurrent, featureMin,featureMax, map) + + if featureCurrent > featureMax + featureCurrent = featureMax; + elseif featureCurrent < featureMin + featureCurrent = featureMin; + end + + % Map into [0,1] interval + xVal = featureCurrent ./ (featureMax - featureMin) - featureMin./(featureMax - featureMin); + + % Now we can use any mapping we want (f(0) should be minimum + % activation percentage (0.0 for threshold), f(1) should be 100 percent (1.0) + + % Linear mapping + if strcmp(map, 'linear') + desiredSpeedPercent = xVal; + % Quadratic mapping + elseif strcmp(map,'quad') + desiredSpeedPercent = xVal.^2; + % Square-root mapping + elseif strcmp(map,'sqrt') + desiredSpeedPercent = sqrt(xVal); + else + desiredSpeedPercent = xVal; + end + + desiredSpeedPercent = desiredSpeedPercent*100; + end \ No newline at end of file diff --git a/Control/CombinedControl.m b/Control/CombinedControl.m new file mode 100644 index 0000000..e27cd46 --- /dev/null +++ b/Control/CombinedControl.m @@ -0,0 +1,13 @@ +function [patRec, outMov, handles] = CombinedControl(patRec, outMov, outVec, handles) + + % Apply first controller + p = patRec.control.controlAlg.prop.patRecOne; + [patRecOut, outMov] = ApplyControl(p, outMov, outVec); + patRec.controlAlg.prop.patRecOne = patRecOut; + + % Apply second controller + p = patRec.control.controlAlg.prop.patRecTwo; + [patRecOut, outMov] = ApplyControl(p, outMov, outVec); + patRec.control.controlAlg.prop.patRecTwo = patRecOut; + +end \ No newline at end of file diff --git a/Control/GUI_ControlParameters.m b/Control/GUI_ControlParameters.m index 7c0217b..bca6bb9 100644 --- a/Control/GUI_ControlParameters.m +++ b/Control/GUI_ControlParameters.m @@ -1,178 +1,178 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% GUI to get quick access to control algorithm parameters. Called from -% GUI_TestPatRec_Mov2Mov when options-button is clicked. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-05 / Joel Falk-Dahlin / Creation -% 2012-10-08 / Joel Falk-Dahlin / Added correct buffer setting from - % internal property (.prop.bufferSize) and - % not only from parameter - % (.parameter.bufferSize) allowing for - % different types of controlAlgs. -% 2012-10-10 / Joel Falk-Dahlin / Added check of previously init outBuffer - % This allows for external setting of - % outBuffer from InitFile. This way the - % outBuffer can be set to have any ammount - % of elements, not only patRec.nOuts -% 20xx-xx-xx / Author / Comment on update - -function figureH = GUI_ControlParameters(inObj) - -% Read data from MainGUI -handles = guidata(inObj); - -if isfield(handles,'patRec') - if isfield(handles.patRec.control,'controlAlg') - - % Create GUI-window - figureH = figure; - - % Set up Vars used by GUI-code - patRec = handles.patRec; - parameterNames = fieldnames(patRec.control.controlAlg.parameters); - nParameters = size(parameterNames,1); - - paramValBoxes = zeros(1,nParameters); - - % Set up position and sizes for the different GUI-fields - xPosNameBox = 20; - yPosNameBox = 70; - xSizeNameBox = 150; - ySizeNameBox = 20; - - xPosValBox = xPosNameBox + xSizeNameBox + 10; - yPosValBox = yPosNameBox; - xSizeValBox = 150; - ySizeValBox = ySizeNameBox; - - % Create UI objects for the parameters - for i = 1:nParameters - - % Create UI-name boxes from the parameters - uicontrol('Style', 'text', 'String', parameterNames{i},... - 'Position', [xPosNameBox yPosNameBox+(i-1)*ySizeNameBox, ... - xSizeNameBox ySizeNameBox]); - - % Save value of the parameters - parameterValue = patRec.control.controlAlg.parameters.(parameterNames{i}); - - % Create UI-value boxes from the parameters - paramValBoxes(i) = uicontrol('Style', 'edit', 'String', parameterValue,... - 'Position', [xPosValBox yPosValBox+(i-1)*ySizeValBox, ... - xSizeValBox ySizeValBox],... - 'Callback', {@SetParam,inObj}, ... - 'Tag',parameterNames{i}); - end - - % Create a UI-title - title = uicontrol('Style', 'text', 'String', ['Parameters for ', patRec.control.controlAlg.name{1}],... - 'Position', [(xPosNameBox+xPosValBox)/2 yPosNameBox+(i+1)*ySizeNameBox, ... - 250 80], ... - 'Tag', 'Title'); - - % Set title fontsize - set(title,'FontSize',15); - - % Create OK-button - uicontrol('Style', 'pushbutton', 'String', 'OK',... - 'Position', [xPosValBox+xSizeValBox+20 yPosValBox 50 40], ... - 'Callback', {@ExitGUI,inObj,paramValBoxes}); - - % Create Default-button - uicontrol('Style', 'pushbutton', 'String', 'Default',... - 'Position', [xPosValBox+xSizeValBox+20 yPosValBox+50 50 40], ... - 'Callback', {@SetDefault,inObj}); - - % Resize the GUI-window - figurePos = get(figureH,'Position'); - figurePos(3:4) = [xSizeNameBox+xSizeValBox+50+2*xPosNameBox+20,... - yPosNameBox+50+yPosNameBox+(i+1)*ySizeNameBox]; - set(figureH,'Position',figurePos,'MenuBar','none'); - - else - % If patRec does not contain any control algorithm print message - set(handles.t_msg,'String','No Control Algorithm set'); - return - end -else - % If the MainGUI-data does not contain any patRec print message - set(handles.t_msg,'String','No PatRec Loaded'); - return -end - -end - -% -------------- GUI CALLBACK FUNCTIONS ------------------ - -function SetParam(hObj, event, inObj) -% -------------- Function Description -------------------- -% Activated when enter press in any of the value fields, saves the value -% in the field to the patRec and saves patrec to mainGUI data. -%--------------------------------------------------------- - handles = guidata(inObj); - if ~isnan( str2double(get(hObj,'String') ) ) - handles.patRec.control.controlAlg.parameters.(get(hObj,'Tag')) = str2double(get(hObj,'String')); - else - handles.patRec.control.controlAlg.parameters.(get(hObj,'Tag')) = get(hObj,'String'); - end - guidata(inObj,handles); -end - -function ExitGUI(hObj, event, inObj,paramValBoxes) -% -------------- FUNCTION DESCRIPTION ---------------- -% Activated when OK-button is pressed. Sets values of valuefield and -% exits GUI window. -% ---------------------------------------------------- - - - % Set Parameters to current value of valueboxes, precaution if - % someone forgets to press ENTER when changing a value - for i = 1:size(paramValBoxes,2) - SetParam(paramValBoxes(i),[],inObj); - end - - % Update the handles so they exists with current instance - handles = guidata(inObj); - - % Update buffers using current parameters - handles.patRec = ReInitControl(handles.patRec); - - % Save PatRec with updated buffer size - guidata(inObj, handles); - - % Close the Parameter GUI - close(clf); -end - -function SetDefault(hObj,event,inObj) -% ---------------- Function Description -------------------------- -% Activates when Default-button is pressed, reinitilizes the controlAlg -% from the definition file, saves to MainGUI and closes and reopen -% parameter GUIwindow. -% ----------------------------------------------------------------- - handles = guidata(inObj); - patRec = handles.patRec; - handles.patRec = InitControl_new(patRec,patRec.control.controlAlg.name{1}); - guidata(inObj,handles); - close(clf); - GUI_ControlParameters(inObj); -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% GUI to get quick access to control algorithm parameters. Called from +% GUI_TestPatRec_Mov2Mov when options-button is clicked. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-05 / Joel Falk-Dahlin / Creation +% 2012-10-08 / Joel Falk-Dahlin / Added correct buffer setting from + % internal property (.prop.bufferSize) and + % not only from parameter + % (.parameter.bufferSize) allowing for + % different types of controlAlgs. +% 2012-10-10 / Joel Falk-Dahlin / Added check of previously init outBuffer + % This allows for external setting of + % outBuffer from InitFile. This way the + % outBuffer can be set to have any ammount + % of elements, not only patRec.nOuts +% 20xx-xx-xx / Author / Comment on update + +function figureH = GUI_ControlParameters(inObj) + +% Read data from MainGUI +handles = guidata(inObj); + +if isfield(handles,'patRec') + if isfield(handles.patRec.control,'controlAlg') + + % Create GUI-window + figureH = figure; + + % Set up Vars used by GUI-code + patRec = handles.patRec; + parameterNames = fieldnames(patRec.control.controlAlg.parameters); + nParameters = size(parameterNames,1); + + paramValBoxes = zeros(1,nParameters); + + % Set up position and sizes for the different GUI-fields + xPosNameBox = 20; + yPosNameBox = 70; + xSizeNameBox = 150; + ySizeNameBox = 20; + + xPosValBox = xPosNameBox + xSizeNameBox + 10; + yPosValBox = yPosNameBox; + xSizeValBox = 150; + ySizeValBox = ySizeNameBox; + + % Create UI objects for the parameters + for i = 1:nParameters + + % Create UI-name boxes from the parameters + uicontrol('Style', 'text', 'String', parameterNames{i},... + 'Position', [xPosNameBox yPosNameBox+(i-1)*ySizeNameBox, ... + xSizeNameBox ySizeNameBox]); + + % Save value of the parameters + parameterValue = patRec.control.controlAlg.parameters.(parameterNames{i}); + + % Create UI-value boxes from the parameters + paramValBoxes(i) = uicontrol('Style', 'edit', 'String', parameterValue,... + 'Position', [xPosValBox yPosValBox+(i-1)*ySizeValBox, ... + xSizeValBox ySizeValBox],... + 'Callback', {@SetParam,inObj}, ... + 'Tag',parameterNames{i}); + end + + % Create a UI-title + title = uicontrol('Style', 'text', 'String', ['Parameters for ', patRec.control.controlAlg.name{1}],... + 'Position', [(xPosNameBox+xPosValBox)/2 yPosNameBox+(i+1)*ySizeNameBox, ... + 250 80], ... + 'Tag', 'Title'); + + % Set title fontsize + set(title,'FontSize',15); + + % Create OK-button + uicontrol('Style', 'pushbutton', 'String', 'OK',... + 'Position', [xPosValBox+xSizeValBox+20 yPosValBox 50 40], ... + 'Callback', {@ExitGUI,inObj,paramValBoxes}); + + % Create Default-button + uicontrol('Style', 'pushbutton', 'String', 'Default',... + 'Position', [xPosValBox+xSizeValBox+20 yPosValBox+50 50 40], ... + 'Callback', {@SetDefault,inObj}); + + % Resize the GUI-window + figurePos = get(figureH,'Position'); + figurePos(3:4) = [xSizeNameBox+xSizeValBox+50+2*xPosNameBox+20,... + yPosNameBox+50+yPosNameBox+(i+1)*ySizeNameBox]; + set(figureH,'Position',figurePos,'MenuBar','none'); + + else + % If patRec does not contain any control algorithm print message + set(handles.t_msg,'String','No Control Algorithm set'); + return + end +else + % If the MainGUI-data does not contain any patRec print message + set(handles.t_msg,'String','No PatRec Loaded'); + return +end + +end + +% -------------- GUI CALLBACK FUNCTIONS ------------------ + +function SetParam(hObj, event, inObj) +% -------------- Function Description -------------------- +% Activated when enter press in any of the value fields, saves the value +% in the field to the patRec and saves patrec to mainGUI data. +%--------------------------------------------------------- + handles = guidata(inObj); + if ~isnan( str2double(get(hObj,'String') ) ) + handles.patRec.control.controlAlg.parameters.(get(hObj,'Tag')) = str2double(get(hObj,'String')); + else + handles.patRec.control.controlAlg.parameters.(get(hObj,'Tag')) = get(hObj,'String'); + end + guidata(inObj,handles); +end + +function ExitGUI(hObj, event, inObj,paramValBoxes) +% -------------- FUNCTION DESCRIPTION ---------------- +% Activated when OK-button is pressed. Sets values of valuefield and +% exits GUI window. +% ---------------------------------------------------- + + + % Set Parameters to current value of valueboxes, precaution if + % someone forgets to press ENTER when changing a value + for i = 1:size(paramValBoxes,2) + SetParam(paramValBoxes(i),[],inObj); + end + + % Update the handles so they exists with current instance + handles = guidata(inObj); + + % Update buffers using current parameters + handles.patRec = ReInitControl(handles.patRec); + + % Save PatRec with updated buffer size + guidata(inObj, handles); + + % Close the Parameter GUI + close(clf); +end + +function SetDefault(hObj,event,inObj) +% ---------------- Function Description -------------------------- +% Activates when Default-button is pressed, reinitilizes the controlAlg +% from the definition file, saves to MainGUI and closes and reopen +% parameter GUIwindow. +% ----------------------------------------------------------------- + handles = guidata(inObj); + patRec = handles.patRec; + handles.patRec = InitControl_new(patRec,patRec.control.controlAlg.name{1}); + guidata(inObj,handles); + close(clf); + GUI_ControlParameters(inObj); +end diff --git a/Control/GUI_ProportionalControl.fig b/Control/GUI_ProportionalControl.fig new file mode 100644 index 0000000..5ff6ef7 Binary files /dev/null and b/Control/GUI_ProportionalControl.fig differ diff --git a/Control/GUI_ProportionalControl.m b/Control/GUI_ProportionalControl.m new file mode 100644 index 0000000..760b2bc --- /dev/null +++ b/Control/GUI_ProportionalControl.m @@ -0,0 +1,496 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% GUI to choose feature, thresholds and mapping for proportional control +% It is launched from GUI_PatRec_Mov2Mov +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-10-26 / Joel Falk-Dahlin / Creation +% +% 2012-11-06 / Joel Falk-Dahlin / Moved all proportionalControl variables +% to the patRec structure. Added text box to +% change the testing time. +% +% 20xx-xx-xx / Author / Comment on update + +function varargout = GUI_ProportionalControl(varargin) +%GUI_PROPORTIONALCONTROL M-file for GUI_ProportionalControl.fig +% GUI_PROPORTIONALCONTROL, by itself, creates a new GUI_PROPORTIONALCONTROL or raises the existing +% singleton*. +% +% H = GUI_PROPORTIONALCONTROL returns the handle to a new GUI_PROPORTIONALCONTROL or the handle to +% the existing singleton*. +% +% GUI_PROPORTIONALCONTROL('Property','Value',...) creates a new GUI_PROPORTIONALCONTROL using the +% given property value pairs. Unrecognized properties are passed via +% varargin to GUI_ProportionalControl_OpeningFcn. This calling syntax produces a +% warning when there is an existing singleton*. +% +% GUI_PROPORTIONALCONTROL('CALLBACK') and GUI_PROPORTIONALCONTROL('CALLBACK',hObject,...) call the +% local function named CALLBACK in GUI_PROPORTIONALCONTROL.M with the given input +% arguments. +% +% *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 GUI_ProportionalControl + +% Last Modified by GUIDE v2.5 06-Nov-2012 15:46:30 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @GUI_ProportionalControl_OpeningFcn, ... + 'gui_OutputFcn', @GUI_ProportionalControl_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 GUI_ProportionalControl is made visible. +function GUI_ProportionalControl_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 unrecognized PropertyName/PropertyValue pairs from the +% command line (see VARARGIN) + +% Choose default command line output for GUI_ProportionalControl +handles.output = hObject; + +% Find if another GUI is passed +for i = 1:length(varargin) + if isfield(varargin{i},'mainGUI') + handles.mainGUI = varargin{i}.mainGUI; + end + if isfield(varargin{i},'patRec'); + handles.patRec = varargin{i}.patRec; + end +end + +% Save mainGUI to handles and update mainGUIHandles with proportional vars +if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + + % Check if GUI handles has proportional control vars + if isfield(handlesMainGUI.patRec.control.propControl,'propMaxThresh') + set(handles.et_thresholdValue,'String',num2str(handlesMainGUI.patRec.control.propControl.propMaxThresh)); + end + if isfield(handlesMainGUI.patRec.control.propControl,'propMinThresh') + set(handles.et_minValue,'String',num2str(handlesMainGUI.patRec.control.propControl.propMinThresh)); + end + if isfield(handlesMainGUI.patRec.control.propControl,'propFeature') + set(handles.pm_featureSelection,'Value',handlesMainGUI.patRec.control.propControl.propFeature); + end + if isfield(handlesMainGUI.patRec.control.propControl,'propSpeedMap') + speedMapList = get( handles.pm_speedMap, 'String' ); + for i = 1:length( speedMapList ) + if strcmp(speedMapList{i}, handlesMainGUI.patRec.control.propControl.propSpeedMap ) + set(handles.pm_speedMap,'Value',i); + break; + end + end + end + + % Update mainGUIHandles to contain maxSpeedThresh and propFeature + handlesMainGUI.patRec.control.propControl.propMaxThresh = str2double(get(handles.et_thresholdValue,'String')); + handlesMainGUI.patRec.control.propControl.propFeature = get(handles.pm_featureSelection,'Value'); + mapStr = get(handles.pm_speedMap,'String'); + selectedMap = mapStr( get(handles.pm_speedMap,'Value') ); + selectedMap = strtrim( selectedMap ); + handlesMainGUI.patRec.control.propControl.propSpeedMap = selectedMap; + + guidata(handles.mainGUI, handlesMainGUI); + + % Save patRec + if isfield(handlesMainGUI,'patRec') + handles.patRec = handlesMainGUI.patRec; + end +end + +% Save selected values to PropGUI handles +handles.patRec.control.propControl.propMaxThresh = str2double(get(handles.et_thresholdValue,'String')); +handles.patRec.control.propControl.propFeature = get(handles.pm_featureSelection,'Value'); + +mapStr = get(handles.pm_speedMap,'String'); +selectedMap = mapStr( get(handles.pm_speedMap,'Value') ); +selectedMap = strtrim( selectedMap ); +handles.patRec.control.propControl.propSpeedMap = selectedMap; + +% Setup plot +ax = handles.speedAxes; +axes(ax); +set(ax,'XLim',[0 1], 'YLim',[0 100],'YTick',[0 25 50 75 100],'YTickMode','manual'); +handles.speedPatch = patch([0 1 1 0],[0 0 0 0],'b'); + +ax = handles.featureAxes; +axes(ax); +set(ax,'XLim',[0 1]); +handles.featurePatch = patch([0 1 1 0],[0 0 0 0],'b'); + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes GUI_ProportionalControl wait for user response (see UIRESUME) +% uiwait(handles.figure1); + + +% --- Outputs from this function are returned to the command line. +function varargout = GUI_ProportionalControl_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; + + + +function et_thresholdValue_Callback(hObject, eventdata, handles) +% hObject handle to et_thresholdValue (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 et_thresholdValue as text +% str2double(get(hObject,'String')) returns contents of et_thresholdValue as a double + +% Save selected values to PropGUI handles +set(handles.t_msg,'String',''); +handles.patRec.control.propControl.propMaxThresh = str2double(get(handles.et_thresholdValue,'String')); +guidata(hObject,handles); + +if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + handlesMainGUI.patRec.control.propControl.propMaxThresh = str2double(get(handles.et_thresholdValue,'String')); + guidata(handles.mainGUI, handlesMainGUI); +end + + +% --- Executes during object creation, after setting all properties. +function et_thresholdValue_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_thresholdValue (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 selection change in pm_featureSelection. +function pm_featureSelection_Callback(hObject, eventdata, handles) +% hObject handle to pm_featureSelection (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_featureSelection contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_featureSelection + +set(handles.t_msg,'String',''); +set(handles.featureAxes,'YLim',[0,1]); +set(handles.featurePatch,'YData',[0 0 0 0]); +set(handles.speedPatch,'YData',[0 0 0 0]); + +% Save selected values to PropGUI handles +handles.patRec.control.propControl.propFeature = get(handles.pm_featureSelection,'Value'); +guidata(hObject,handles); + +if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + handlesMainGUI.patRec.control.propControl.propFeature = get(handles.pm_featureSelection,'Value'); + guidata(handles.mainGUI, handlesMainGUI); +end + +% --- Executes during object creation, after setting all properties. +function pm_featureSelection_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_featureSelection (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 + +if isappdata(0,'selFeatures'); + selFeatures = getappdata(0,'selFeatures'); + set(hObject,'String',selFeatures); + rmappdata(0,'selFeatures'); +else + set(hObject,'String','No Features Loaded'); +end +guidata(hObject,handles); + + +% --- Executes on button press in pb_testThreshold. +function pb_testThreshold_Callback(hObject, eventdata, handles) +% hObject handle to pb_testThreshold (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Initialize DAQ if patRec is loaded +if isfield(handles,'patRec') + set(handles.pb_testThreshold,'String','Running') + set(handles.pb_testThreshold,'Enable','off'); + set(handles.t_msg,'String','Initialize DAQ','ForegroundColor','g'); + drawnow; + patRec = handles.patRec; + testingTime = str2double( get(handles.et_testingTime,'String') ); + chAI = zeros(1,8); % 8 ch is the limit for the USB6009 + chAI(patRec.nCh) = 1; + %Init the SBI + handles.s = InitSBI_NI(patRec.sF,testingTime,chAI); + handles.s.NotifyWhenDataAvailableExceeds = (patRec.sF*0.05); +end + +% If DAQ in initialized +if isfield(handles,'s') + + % Set messages + set(handles.t_msg,'String','Running Test','ForegroundColor','g'); + drawnow; + set(handles.featureAxes,'YLim',[0 1e-10]); + + % Remove any listener existing listeners + if isfield(handles,'lh') + delete(handles.lh); + handles = rmfield(handles,'lh'); + end + + % Setup container to store sampled data from DAQ-card + tempData = []; + setappdata(hObject,'tempData',tempData); + + % get mainGUI handles, to be able to update predictions + if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + else + handlesMainGUI = []; + end + + % create new listener + handles.lh = handles.s.addlistener('DataAvailable', @(src,event) Test_ProportionalControl(src, event, hObject, handles, handlesMainGUI) ); + + % Start test + handles.s.startBackground(); + handles.s.wait(); + + % Update Messages + set(handles.pb_testThreshold,'String','Test'); + set(handles.pb_testThreshold,'Enable','on'); + set(handles.t_msg,'String','Test Done','ForegroundColor','g') + + % Delete listener and clear session + delete(handles.lh); + handles.s.stop(); + clear handles.s; + handles = rmfield(handles,'s'); + +% If DAQ in not initialized +else + set(handles.t_msg,'String','No PatRec Loaded','ForegroundColor','r'); +end + +% Save data +guidata(hObject,handles); + +function Test_ProportionalControl(src,event, hObject, handles, handlesMainGUI) + +% Read previously sampled data from testing session +tempData = getappdata(hObject,'tempData'); + +% Read patRec from handles +patRec = handles.patRec; + +% Keep saving all recorded data +tempData = [tempData; event.Data]; + +% Only considered the data once it has at least the size of a time window +if size(tempData,1) >= (patRec.sF*patRec.tW) + + % Use only data size equal to the trained time window + tData = tempData(end-patRec.sF*patRec.tW+1:end,:); + + % Signal processing, to calculate signal feature vector + tSet = SignalProcessing_RealtimePatRec(tData, patRec); + + % Extract proportional Control variables from GUI textboxes + propMinThresh = str2double( get(handles.et_minValue,'String') ); + propMaxThresh = str2double( get(handles.et_thresholdValue,'String') ); + propSpeedMap = patRec.control.propControl.propSpeedMap; + + % Extract tSet indicies + nCh = length(patRec.nCh); + selFeature = get(handles.pm_featureSelection,'Value'); + idx = nCh*(selFeature-1)+1:nCh*(selFeature-1)+nCh; + + % Calculate Feature value + featureVal = abs( mean( tSet(idx) ) ); + + % Map Feature value to speed percent + speedPercent = CalculateDesiredSpeedPercent(featureVal, propMinThresh, ... + propMaxThresh, propSpeedMap); + + % Plot speed and feature bars + yLimVal = get(handles.featureAxes,'YLim'); + yLimVal = yLimVal(2); + if featureVal > yLimVal + set(handles.featureAxes,'YLim',[0 featureVal]) + end + set(handles.featurePatch,'YData',[0 0 featureVal featureVal]); + set(handles.speedPatch,'YData',[0 0 speedPercent speedPercent]); + + % If the main gui is open, predicted movement and update mainGUI + if ~isempty(handlesMainGUI) + + % Signal processing + tSet = SignalProcessing_RealtimePatRec(tData, handles.patRec); + % One shoot PatRec + outMov = OneShotPatRecClassifier(handles.patRec, tSet); + + % If no movement is predicted, predict rest + if outMov == 0 + outMov = handles.patRec.nOuts; + end + + % Draw predicted movement + set(handlesMainGUI.lb_movements,'Value',outMov); + drawnow; + end + +end + +% Save the tempData back to the GUI so it can be used next time DAQ fires +% DataAvailable event +setappdata(hObject,'tempData',tempData); + +% --- Executes during object creation, after setting all properties. +function t_speed_CreateFcn(hObject, eventdata, handles) +% hObject handle to t_speed (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + + +% --- Executes on selection change in pm_speedMap. +function pm_speedMap_Callback(hObject, eventdata, handles) +% hObject handle to pm_speedMap (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_speedMap contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_speedMap +speedMapList = get(hObject,'String'); +val = get(hObject,'Value'); +map = speedMapList{val}; +map = strtrim( map ); + +handles.patRec.control.propControl.propSpeedMap = map; +guidata(hObject,handles); + +% If MainGUI exists, save selected map to handlesMainGUI +if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + handlesMainGUI.patRec.control.propControl.propSpeedMap = map; + guidata(handles.mainGUI, handlesMainGUI); +end + +% --- Executes during object creation, after setting all properties. +function pm_speedMap_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_speedMap (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 et_minValue_Callback(hObject, eventdata, handles) +% hObject handle to et_minValue (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 et_minValue as text +% str2double(get(hObject,'String')) returns contents of et_minValue as a double + +% Save selected values to PropGUI handles +set(handles.t_msg,'String',''); +handles.patRec.control.propControl.propMinThresh = str2double(get(handles.et_minValue,'String')); +guidata(hObject,handles); + +if isfield(handles,'mainGUI') + handlesMainGUI = guidata(handles.mainGUI); + handlesMainGUI.patRec.control.propControl.propMinThresh = str2double(get(handles.et_minValue,'String')); + guidata(handles.mainGUI, handlesMainGUI); +end + +% --- Executes during object creation, after setting all properties. +function et_minValue_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_minValue (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 + + + +function et_testingTime_Callback(hObject, eventdata, handles) +% hObject handle to et_testingTime (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 et_testingTime as text +% str2double(get(hObject,'String')) returns contents of et_testingTime as a double + + +% --- Executes during object creation, after setting all properties. +function et_testingTime_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_testingTime (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 \ No newline at end of file diff --git a/Control/GUI_Sensors.fig b/Control/GUI_Sensors.fig new file mode 100644 index 0000000..2b62b78 Binary files /dev/null and b/Control/GUI_Sensors.fig differ diff --git a/Control/GUI_Sensors.m b/Control/GUI_Sensors.m new file mode 100644 index 0000000..e50d835 --- /dev/null +++ b/Control/GUI_Sensors.m @@ -0,0 +1,242 @@ +function varargout = GUI_Sensors(varargin) +% GUI_SENSORS MATLAB code for GUI_Sensors.fig +% GUI_SENSORS, by itself, creates a new GUI_SENSORS or raises the existing +% singleton*. +% +% H = GUI_SENSORS returns the handle to a new GUI_SENSORS or the handle to +% the existing singleton*. +% +% GUI_SENSORS('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in GUI_SENSORS.M with the given input arguments. +% +% GUI_SENSORS('Property','Value',...) creates a new GUI_SENSORS or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before GUI_Sensors_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to GUI_Sensors_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 GUI_Sensors + +% Last Modified by GUIDE v2.5 12-Jun-2015 11:08:36 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @GUI_Sensors_OpeningFcn, ... + 'gui_OutputFcn', @GUI_Sensors_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 GUI_Sensors is made visible. +function GUI_Sensors_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 GUI_Sensors (see VARARGIN) + +%handles = varargin{1}; + +% Choose default command line output for GUI_Sensors +handles.output = hObject; + +% get the handle of Gui1 +h = findobj('Tag','Gui1'); +% if exists (not empty) +if ~isempty(h) + % get handles and other user-defined data associated to Gui1 + g1data = guidata(h); + + % handles.sensors = g1data.sensors + handles.sensors = InitSensors(); + handles.com = g1data.Control_obj; +end + +% if InitSensors found the "sensors.def" file +if isobject(handles.sensors) + % Fetch the number of sensors + nrSensors = size(handles.sensors,2); + handles.nrSensors = nrSensors; + + % list them in GUI_Sensors + for k = 1 : nrSensors + listboxItems(nrSensors-k+1) = handles.sensors(k).name; + end + set(handles.listbox,'string',listboxItems); + + % Set up the timer for sensors readings + handles.guifig = gcf; + handles.timerS = timer('TimerFcn', {@SensorRequest,handles.guifig},'ExecutionMode','fixedRate','Period', 0.05); + guidata(handles.guifig,handles); + guidata(hObject, handles); + + % Set up the plot + handles.t = 1; + handles.plotGain = 10000000; + handles.data = zeros(200,nrSensors); + h = plot(handles.axes1, handles.data); + axis([0 200 0 5*nrSensors]) + % Shift the different plots to fit into the main figure + global offVector; + global ampPP; + ampPP = 5; + offVector = 0:handles.nrSensors-1; + offVector = offVector .* ampPP; + set(handles.axes1,'YTick',offVector); + set(handles.axes1,'YTickLabel',fliplr(listboxItems)); + handles.p_t0 = h; + +else % no "sensors.def" file was found + % Disable start and stop buttons + set(handles.pb_start,'Enable','off'); + set(handles.pb_stop,'Enable','off'); + + % Empty the sensors list + set(handles.listbox,'string',''); + + % Set up the (empty) plot + handles.data = zeros(200,1); + h = plot(handles.axes1, handles.data); + axis([0 200 0 5]) + handles.p_t0 = h; +end + +% Update handles structure +guidata(hObject, handles); + +% --- Outputs from this function are returned to the command line. +function varargout = GUI_Sensors_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 pb_stop. +function pb_stop_Callback(hObject, eventdata, handles) +% hObject handle to pb_stop (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +stop(handles.timerS); + + +function et_frequency_Callback(hObject, eventdata, handles) +% hObject handle to et_frequency (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 et_frequency as text +% str2double(get(hObject,'String')) returns contents of et_frequency as a double + + +% --- Executes during object creation, after setting all properties. +function et_frequency_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_frequency (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 pb_start. +function pb_start_Callback(hObject, eventdata, handles) +% hObject handle to pb_start (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +handles.t = 1; +guidata(hObject,handles); + +start(handles.timerS); + +function SensorRequest(src, event, handles) + + global offVector; + global ampPP; + handles = guidata(handles); + obj = handles.com; + t = handles.t; + + data = handles.data; + p_t0 = handles.p_t0; + + data(t,:) = ReadSensors(obj, handles.sensors, handles.nrSensors); + data(t+1,:) = NaN; + data(t+2,:) = NaN; + + if(t+2 >= 200) + handles.t = 1; + else + handles.t = t + 1; + end + + handles.data = data; + +% plot(handles.axes1, data(:,1)); +% plot(handles.axes1, data(:,2)); +% plot(handles.axes1, data(:,3)); +% plot(handles.axes1, data(:,4)); + + plotGain = handles.plotGain; + + K = ampPP/(2*(max(max(abs(data))))); + if K < plotGain + % if the signals in the different windows is getting bigger the gain + % must be reduced consequently, the channels plots must always fit + % the main plot + plotGain = K; + end + % plot a new tWs sized window + for j = 1 : handles.nrSensors + set(p_t0(j),'YData',data(:,j)*plotGain + offVector(j)); % add offsets to plot channels in same graph + end + drawnow + + handles.plotGain = plotGain; + guidata(handles.guifig, handles); + + +% --- Executes on selection change in listbox. +function listbox_Callback(hObject, eventdata, handles) +% hObject handle to listbox (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns listbox contents as cell array +% contents{get(hObject,'Value')} returns selected item from listbox + + +% --- Executes during object creation, after setting all properties. +function listbox_CreateFcn(hObject, eventdata, handles) +% hObject handle to listbox (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 diff --git a/Control/GUI_SingleMotorTest.fig b/Control/GUI_SingleMotorTest.fig new file mode 100644 index 0000000..c114f9f Binary files /dev/null and b/Control/GUI_SingleMotorTest.fig differ diff --git a/Control/GUI_SingleMotorTest.m b/Control/GUI_SingleMotorTest.m new file mode 100644 index 0000000..2959496 --- /dev/null +++ b/Control/GUI_SingleMotorTest.m @@ -0,0 +1,1016 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% [Give a short summary about the principle of your function here.] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function varargout = GUI_SingleMotorTest(varargin) +% GUI_SINGLEMOTORTEST M-file for GUI_SingleMotorTest.fig +% GUI_SINGLEMOTORTEST, by itself, creates a new GUI_SINGLEMOTORTEST or raises the existing +% singleton*. +% +% H = GUI_SINGLEMOTORTEST returns the handle to a new GUI_SINGLEMOTORTEST or the handle to +% the existing singleton*. +% +% GUI_SINGLEMOTORTEST('CALLBACK',hObject,eventData,handles,...) calls the local +% function named CALLBACK in GUI_SINGLEMOTORTEST.M with the given input arguments. +% +% GUI_SINGLEMOTORTEST('Property','Value',...) creates a new GUI_SINGLEMOTORTEST or raises the +% existing singleton*. Starting from the left, property value pairs are +% applied to the GUI before GUI_SingleMotorTest_OpeningFcn gets called. An +% unrecognized property name or invalid value makes property application +% stop. All inputs are passed to GUI_SingleMotorTest_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 GUI_SingleMotorTest + +% Last Modified by GUIDE v2.5 15-Sep-2011 12:10:36 + +% Begin initialization code - DO NOT EDIT +gui_Singleton = 1; +gui_State = struct('gui_Name', mfilename, ... + 'gui_Singleton', gui_Singleton, ... + 'gui_OpeningFcn', @GUI_SingleMotorTest_OpeningFcn, ... + 'gui_OutputFcn', @GUI_SingleMotorTest_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 GUI_SingleMotorTest is made visible. +function GUI_SingleMotorTest_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 GUI_SingleMotorTest (see VARARGIN) + +% Choose default command line output for GUI_SingleMotorTest +handles.output = hObject; + +% Button Group +set(handles.motordir,'SelectionChangeFcn',@motordir_SelectionChangeFcn); + +% Update handles structure +guidata(hObject, handles); + +% UIWAIT makes GUI_SingleMotorTest wait for user response (see UIRESUME) +% uiwait(handles.fig_one_motor_test_panel); + + +% --- Outputs from this function are returned to the command line. +function varargout = GUI_SingleMotorTest_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 pb_initDAQ. +function pb_initDAQ_Callback(hObject, eventdata, handles) +% hObject handle to pb_initDAQ (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + sF = str2double(get(handles.et_Fs,'String')); + sT = str2double(get(handles.et_Ts,'String')); + [ai ao dio] = init_DAQ(sF,sT,1:8); + + set(handles.t_ai,'UserData',ai); + set(handles.t_ao,'UserData',ao); + set(handles.t_dio,'UserData',dio); + + % Enable Buttons + set(handles.pb_recordAI,'Enable','on') + set(handles.pb_stopDAQ,'Enable','on') + + +function et_Fs_Callback(hObject, eventdata, handles) + set(handles.pb_recordAI,'Enable','off') + set(handles.pb_stopDAQ,'Enable','off') + + +% --- Executes during object creation, after setting all properties. +function et_Fs_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_Fs (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 + + + +function et_Ts_Callback(hObject, eventdata, handles) + set(handles.pb_recordAI,'Enable','off') + set(handles.pb_stopDAQ,'Enable','off') + + +% --- Executes during object creation, after setting all properties. +function et_Ts_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_Ts (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 + + + +function et_Tp_Callback(hObject, eventdata, handles) +% hObject handle to et_Tp (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 et_Tp as text +% str2double(get(hObject,'String')) returns contents of et_Tp as a double + + +% --- Executes during object creation, after setting all properties. +function et_Tp_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_Tp (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 pb_recordAI. +function pb_recordAI_Callback(hObject, eventdata, handles) + + Fs = str2double(get(handles.et_Fs,'String')); + Ts = str2double(get(handles.et_Ts,'String')); + Tp = str2double(get(handles.et_Tp,'String')); + + cIdx = zeros(1,21); + gcIdx = zeros(1,21); + + % Get ANN + if get(handles.cb_ann,'Value') + ANN = get(handles.cb_ann,'UserData'); + if isempty(ANN) + [file, path] = uigetfile('*.mat'); + load([path,file]); + if exist('psoANN','var') + ANN = psoANN; + elseif exist('eaANN','var') + ANN = eaANN; + elseif exist('bpANN','var') + ANN = bpANN; + else + errordlg('File without ANNs','Error'); + return; + end + set(handles.cb_ann,'UserData',ANN) + end + if Tp ~= ANN.tw + errordlg(['Peek time does not match ANN.tw:' num2str(ANN.tw)],'Error'); + return; + elseif Fs ~= ANN.Fs + errordlg(['Fs does not match ANN.Fs:' num2str(ANN.Fs)],'Error'); + return; + end + cIdx(ANN.cIdx) = 1; + treated_data.vdata = []; + treated_data.tdata = []; + treated_data.etrN = 1; + end + ncIdx = get(handles.pm_chrs,'Value'); + gcIdx(ncIdx) = 1; + + % Index + mIIdx = 5; % Index for motor I + PWMIdx = 6; % Index for PWM + + % Init Graphs + nxt = round(Ts/Tp) * 5; % Total samples to peek + nx = Fs*Tp; % samples to peek + axes(handles.a_motorRI); + mRIy = zeros(1,nxt); % Motor RI y (or vector) + p_motorRI = plot(1:nxt,mRIy); + axes(handles.a_motorI); + y = zeros(1,nx); % Motor I and PWM vector + p_motorI = plot(1:nx,y); + axes(handles.a_PWM); + p_PWM = plot(1:nx,y); % PWM plot + axes(handles.a_schr); + pv = [zeros(1,nxt) ; zeros(1,nxt) ; zeros(1,nxt) ; zeros(1,nxt)]; % Plot vector for signal chrs + p_schr = plot(1:nxt,pv); + axes(handles.a_controls); + cv = zeros(1,nxt); % Control Vector + cvA = cv; % Analog Control Vector + p_controls = plot(1:nxt,cv); + axes(handles.a_error); + ev = zeros(1,nxt); % Error Vector + p_error = plot(1:nxt,ev); + + %Scaling + chmin(1) = str2double(get(handles.et_ch0min,'String')); + chmax(1) = str2double(get(handles.et_ch0max,'String')); + chmin(2) = str2double(get(handles.et_ch1min,'String')); + chmax(2) = str2double(get(handles.et_ch1max,'String')); + chmin(3) = str2double(get(handles.et_ch2min,'String')); + chmax(3) = str2double(get(handles.et_ch2max,'String')); + chmin(4) = str2double(get(handles.et_ch3min,'String')); + chmax(4) = str2double(get(handles.et_ch3max,'String')); + Aoutmin = str2double(get(handles.et_Aoutmin,'String')); + Aoutmax = str2double(get(handles.et_Aoutmax,'String')); + errmRImin = str2double(get(handles.et_errmRImin,'String')); + errmRImax = str2double(get(handles.et_errmRImax,'String')); + + % Chanel for control + if get(handles.cb_ch0,'value') + csch = 1; + elseif get(handles.cb_ch1,'value') + csch = 2; + elseif get(handles.cb_ch2,'value') + csch = 3; + elseif get(handles.cb_ch3,'value') + csch = 4; + end + Amin = chmin(csch); + Amax = chmax(csch); + + % DAQ + ai = get(handles.t_ai,'UserData'); + start(ai); + dio = get(handles.t_dio,'UserData'); + ao = get(handles.t_ao,'UserData'); + StopMotor(dio,ao); + + % wait for the first samples to be aquired + while ai.SamplesAcquired < Fs*Tp + end + i=1; + while ai.SamplesAcquired < Fs*Ts + + data = peekdata(ai,Fs*Tp); + datam = data(:,mIIdx); + datapwm = data(:,PWMIdx); + data = data(:,1:4); + + % MOTOR +% data(:,mIIdx) = data(:,mIIdx)./ str2double(get(handles.et_senseR,'String')); % Change from Voltage to Current +% motorRI(i) = trapz(data(:,mIIdx)) / 1000; % Integral of the current per mS + datam = datam ./ str2double(get(handles.et_senseR,'String')); % Change from Voltage to Current + motorRI(i) = trapz(datam) / 1000; % Integral of the current per mS + %motorRI(i) = sum(data(:,mIIdx).^2)/Fs*Tp; + if motorRI(i) >= 0.9 % Safety routing + StopMotor(dio,ao); + end + mRIy(i) = motorRI(i); + set(handles.et_motorRI,'String',num2str(motorRI(i))); + set(p_motorRI,'YData',mRIy); + set(p_motorI,'YData',datam); + set(p_PWM,'YData',datapwm); + drawnow; + + + % Signal Characteristics for Amplitud + treated_data.trdata = analyze_signal(data(:,1:4),Fs,gcIdx); % Only Breakdown the Biosignals + allChrs = fieldnames(treated_data.trdata); + Chr = allChrs(ncIdx); + pv(:,i) = treated_data.trdata.(Chr{1}); + % Graphics + set(p_schr(1),'YData',pv(1,:)); + set(p_schr(2),'YData',pv(2,:)); + set(p_schr(3),'YData',pv(3,:)); + set(p_schr(4),'YData',pv(4,:)); + + if get(handles.cb_ann,'Value') + % filtering + if ANN.filters.PLH + data = BSbutterPLHarmonics(Fs, data); + elseif ANN.filters.BP + data = FilterBP_EMG(Fs, data); + end + treated_data.trdata = analyze_signal(data,Fs,cIdx); + trset = get_Sets(treated_data,ANN.Chrs); + + % Normalize + if ANN.normalize == 1 + allsets = get(handles.t_allsets,'UserData'); + allsets(length(allsets(:,1))+1 : length(allsets(:,1))+length(trset(:,1)),:) = trset; + mn = mean(allsets,1); + vr = var(allsets); + trset = (trset - mn(ones(size(trset,1), 1), :)) ./ vr(ones(size(trset,1), 1), :); + end + + ANN = evaluate_ann(trset, ANN); + + if round(ANN.o(1)) == 1 && round(ANN.o(2)) == 0 + dir = [0 1]; % 1 Open + csch = 2; + set(handles.t_msgdir,'String','Open'); + elseif round(ANN.o(1)) == 0 && round(ANN.o(2)) == 1 + dir = [1 0]; % 2 Close + csch = 1; + set(handles.t_msgdir,'String','Close'); + else + dir = [1 1]; % 2 Close + set(handles.t_msgdir,'String','Do nothing'); + end + + else + % Automatic direction + if get(handles.cb_ch1and2,'Value') % CH 1 and CH 2 Natural + if pv(2,i) > pv(1,i) + dir = [0 1]; % 1 Open + csch = 2; + set(handles.t_msgdir,'String','Open'); + else + dir = [1 0]; % 2 Close + csch = 1; + set(handles.t_msgdir,'String','Close'); + end + elseif get(handles.cb_ch2and3,'Value') % CH 2 and CH 3 Usual + if pv(2,i) > pv(3,i) + dir = [0 1]; % 1 Open + csch = 2; + set(handles.t_msgdir,'String','Open'); + else + dir = [1 0]; % 2 Close + csch = 3; + set(handles.t_msgdir,'String','Close'); + end + end + end + + % Scaling: First range is how you want the output, seconde range is where the raw-data comes + Amin = chmin(csch); + Amax = chmax(csch); + cv(i) = scale(pv(csch,i),0,100,Amin,Amax); + if cv(i) > 0 % Set direction only if there is control planned + putvalue(dio.Line([1 2]), dir); + else + putvalue(dio.Line([1 2]), [1 1]); + end + set(p_controls,'YData',cv); + + % Error + smotorRI = scale(motorRI(i),0,100,errmRImin,errmRImax); + ev(i) = cv(i) - smotorRI; % 1 Amp = 100% + set(p_error,'YData',ev); + + + % Scaling output 1 - 4 V and control signal from 0 - 100; + cvA(i) = scale(cv(i),Aoutmin,Aoutmax,0,100); + if get(handles.cb_linkcontrols,'Value') + putsample(ao,cvA(i)); % Exit according to slider + end + + i=i+1; + end + + [data t] = getdata(ai); + data(:,mIIdx) = data(:,mIIdx)./ str2double(get(handles.et_senseR,'String')); % change from V to I + set(handles.t_t,'UserData',t); + + set(handles.pb_pmotorRI,'UserData',motorRI); + + motorI = data(:,mIIdx); + set(p_motorI,'XData',t); + set(p_motorI,'YData',motorI); + set(handles.pb_pmotorI,'UserData',motorI); + + PWM = data(:,PWMIdx); + set(p_PWM,'XData',t); + set(p_PWM,'YData',PWM); + set(handles.pb_pPWM,'UserData',PWM); + + set(handles.pb_pschr,'UserData',pv); + set(handles.pb_pcontrols,'UserData',cv); + set(handles.pb_pcontrolsA,'UserData',cvA); + set(handles.pb_perror,'UserData',ev); + + StopMotor(dio,ao); % End by stoping the motor + + +% --- Executes on button press in pb_stopDAQ. +function pb_stopDAQ_Callback(hObject, eventdata, handles) +% hObject handle to pb_stopDAQ (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + ai = get(handles.t_ai,'UserData'); + ao = get(handles.t_ao,'UserData'); + dio = get(handles.t_dio,'UserData'); + + stop(ai); + stop(ao); + stop(dio); + + + +% --- Executes on slider movement. +function s_speed_Callback(hObject, eventdata, handles) +% hObject handle to s_speed (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,'Value') returns position of slider +% get(hObject,'Min') and get(hObject,'Max') to determine range of slider + + set(handles.et_speed,'String',num2str(get(hObject,'Value'))); + ao = get(handles.t_ao,'UserData'); + putsample(ao,get(hObject,'Value')); % Exit according to slider + + +% --- Executes during object creation, after setting all properties. +function s_speed_CreateFcn(hObject, eventdata, handles) +% hObject handle to s_speed (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: slider controls usually have a light gray background. +if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) + set(hObject,'BackgroundColor',[.9 .9 .9]); +end + + + +function et_speed_Callback(hObject, eventdata, handles) +% hObject handle to et_speed (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 et_speed as text +% str2double(get(hObject,'String')) returns contents of et_speed as a double + + set(handles.s_speed,'Value',str2double(get(hObject,'String'))); + ao = get(handles.t_ao,'UserData'); + putsample(ao,get(handles.s_speed,'Value')); % Exit according to slider + +% --- Executes during object creation, after setting all properties. +function et_speed_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_speed (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 + + + +function et_motordir_Callback(hObject, eventdata, handles) +% hObject handle to et_motordir (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 et_motordir as text +% str2double(get(hObject,'String')) returns contents of et_motordir as a double + + +% --- Executes during object creation, after setting all properties. +function et_motordir_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_motordir (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 + +function motordir_SelectionChangeFcn(hObject, eventdata) + +%retrieve GUI data, i.e. the handles structure +handles = guidata(hObject); + +dio = get(handles.t_dio,'UserData'); + +switch get(eventdata.NewValue,'Tag') % Get Tag of selected object + case 'rb_stop' + set(handles.et_motordir,'String','3'); + putvalue(dio.Line([1 2]), [1 1]); % Stop motor + + case 'rb_close' + set(handles.et_motordir,'String','2'); + putvalue(dio.Line([1 2]), [1 0]); + + case 'rb_open' + set(handles.et_motordir,'String','1'); + putvalue(dio.Line([1 2]), [0 1]); + + otherwise + set(handles.et_motordir,'String','3'); + putvalue(dio.Line([1 2]), [1 1]); +end +%updates the handles structure +guidata(hObject, handles); + + +% --- Executes on button press in pb_pmotorI. +function pb_pmotorI_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.t_t,'UserData'),get(handles.pb_pmotorI,'UserData')); + title('Motor Current (I)') + + +% --- Executes on button press in pb_pPWM. +function pb_pPWM_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.t_t,'UserData'),get(handles.pb_pPWM,'UserData')); + title('PWM') + + +% --- Executes on button press in pb_pmotorV. +function pb_pmotorV_Callback(hObject, eventdata, handles) +% hObject handle to pb_pmotorV (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + + +function et_motorRI_Callback(hObject, eventdata, handles) + + +% --- Executes during object creation, after setting all properties. + +function et_motorRI_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_motorRI (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 pb_pmotorRI. +function pb_pmotorRI_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.pb_pmotorRI,'UserData')); + title('Motor R Current') + + + +function et_senseR_Callback(hObject, eventdata, handles) +% hObject handle to et_senseR (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 et_senseR as text +% str2double(get(hObject,'String')) returns contents of et_senseR as a double + + +% --- Executes during object creation, after setting all properties. +function et_senseR_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_senseR (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 pb_pcontrols. +function pb_pcontrols_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.pb_pcontrols,'UserData')); + title('Control Signal') + + +% --- Executes on button press in pb_pschr. +function pb_pschr_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.pb_pschr,'UserData')'); + title('Signal Characteristic') + legend('1','2','3','4') + + + +function et_ch0min_Callback(hObject, eventdata, handles) +% hObject handle to et_ch0min (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 et_ch0min as text +% str2double(get(hObject,'String')) returns contents of et_ch0min as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch0min_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch0min (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 + + + +function et_ch0max_Callback(hObject, eventdata, handles) +% hObject handle to et_ch0max (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 et_ch0max as text +% str2double(get(hObject,'String')) returns contents of et_ch0max as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch0max_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch0max (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 cb_ch0. +function cb_ch0_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch0 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch0 + + +% --- Executes on button press in cb_ch1. +function cb_ch1_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch1 + + +% --- Executes on button press in cb_ch2. +function cb_ch2_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch2 + + +% --- Executes on button press in cb_ch3. +function cb_ch3_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch3 + + +% --- Executes on button press in pb_perror. +function pb_perror_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.pb_perror,'UserData')); + title('Error') + + +% --- Executes on selection change in pm_chrs. +function pm_chrs_Callback(hObject, eventdata, handles) +% hObject handle to pm_chrs (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 pm_chrs contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_chrs + + +% --- Executes during object creation, after setting all properties. +function pm_chrs_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_chrs (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 cb_linkcontrols. +function cb_linkcontrols_Callback(hObject, eventdata, handles) +% hObject handle to cb_linkcontrols (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_linkcontrols + + +% --- Executes on button press in pb_pcontrolsA. +function pb_pcontrolsA_Callback(hObject, eventdata, handles) + figure; + plot(get(handles.pb_pcontrolsA,'UserData')); + title('Analog Control Signal') + + + +function et_Aoutmin_Callback(hObject, eventdata, handles) +% hObject handle to et_Aoutmin (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 et_Aoutmin as text +% str2double(get(hObject,'String')) returns contents of et_Aoutmin as a double + + +% --- Executes during object creation, after setting all properties. +function et_Aoutmin_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_Aoutmin (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 + + + +function et_Aoutmax_Callback(hObject, eventdata, handles) +% hObject handle to et_Aoutmax (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 et_Aoutmax as text +% str2double(get(hObject,'String')) returns contents of et_Aoutmax as a double + + +% --- Executes during object creation, after setting all properties. +function et_Aoutmax_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_Aoutmax (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 + + + +function et_errmRImin_Callback(hObject, eventdata, handles) +% hObject handle to et_errmRImin (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 et_errmRImin as text +% str2double(get(hObject,'String')) returns contents of et_errmRImin as a double + + +% --- Executes during object creation, after setting all properties. +function et_errmRImin_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_errmRImin (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 + + + +function et_errmRImax_Callback(hObject, eventdata, handles) +% hObject handle to et_errmRImax (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 et_errmRImax as text +% str2double(get(hObject,'String')) returns contents of et_errmRImax as a double + + +% --- Executes during object creation, after setting all properties. +function et_errmRImax_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_errmRImax (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 + + + +function et_ch1min_Callback(hObject, eventdata, handles) +% hObject handle to et_ch1min (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 et_ch1min as text +% str2double(get(hObject,'String')) returns contents of et_ch1min as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch1min_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch1min (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 + + + +function et_ch1max_Callback(hObject, eventdata, handles) +% hObject handle to et_ch1max (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 et_ch1max as text +% str2double(get(hObject,'String')) returns contents of et_ch1max as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch1max_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch1max (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 + + + +function et_ch2min_Callback(hObject, eventdata, handles) +% hObject handle to et_ch2min (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 et_ch2min as text +% str2double(get(hObject,'String')) returns contents of et_ch2min as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch2min_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch2min (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 + + + +function et_ch2max_Callback(hObject, eventdata, handles) +% hObject handle to et_ch2max (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 et_ch2max as text +% str2double(get(hObject,'String')) returns contents of et_ch2max as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch2max_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch2max (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 + + + +function et_ch3min_Callback(hObject, eventdata, handles) +% hObject handle to et_ch3min (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 et_ch3min as text +% str2double(get(hObject,'String')) returns contents of et_ch3min as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch3min_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch3min (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 + + + +function et_ch3max_Callback(hObject, eventdata, handles) +% hObject handle to et_ch3max (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 et_ch3max as text +% str2double(get(hObject,'String')) returns contents of et_ch3max as a double + + +% --- Executes during object creation, after setting all properties. +function et_ch3max_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ch3max (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 cb_ch1and2. +function cb_ch1and2_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch1and2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch1and2 + + +% --- Executes on button press in cb_ch2and3. +function cb_ch2and3_Callback(hObject, eventdata, handles) +% hObject handle to cb_ch2and3 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ch2and3 + + +% --- Executes on button press in cb_ann. +function cb_ann_Callback(hObject, eventdata, handles) +% hObject handle to cb_ann (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ann diff --git a/Control/InitBayesianFusion.m b/Control/InitBayesianFusion.m new file mode 100644 index 0000000..5c9d026 --- /dev/null +++ b/Control/InitBayesianFusion.m @@ -0,0 +1,44 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Initialization of BayesianFusion, sets up the weight matrix if weight +% parameters is 1. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-09 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitBayesianFusion(patRec) + +weight = patRec.control.controlAlg.parameters.weight; +bufferSize = patRec.control.controlAlg.parameters.bufferSize; + +if weight == 1 + l = 1:bufferSize; + Z = sum( exp( -0.5/bufferSize.*l) ); + k = 10.*exp(-0.5/bufferSize.*l')./Z; + k = flipud(k); + k = repmat(k,1,patRec.nOuts); +else + k = zeros(bufferSize,patRec.nOuts); +end + +patRec.control.controlAlg.prop.k = k; + +end \ No newline at end of file diff --git a/Control/InitCombinedControl.m b/Control/InitCombinedControl.m new file mode 100644 index 0000000..10e732e --- /dev/null +++ b/Control/InitCombinedControl.m @@ -0,0 +1,50 @@ +function patRec = InitCombinedControl(patRec) + + controlOne = patRec.control.controlAlg.parameters.controlOne; + controlTwo = patRec.control.controlAlg.parameters.controlTwo; + + % Initialize first controller + patRecOne = patRec; + patRecOne = InitControl_new(patRecOne,controlOne); + + % Initialize second controller + patRecTwo = patRec; + patRecTwo = InitControl_new(patRecTwo,controlTwo); + + % Set parameters from patRec to patRecOne and Two if they exist + allParameters = fieldnames( patRec.control.controlAlg.parameters ); + for iParam = 1:size(allParameters,1) + name = allParameters{iParam}; + value = patRec.control.controlAlg.parameters.(allParameters{iParam}); + + if isfield( patRecOne.control.controlAlg.parameters, name ) + patRecOne.control.controlAlg.parameters.(name) = value; + end + + if isfield( patRecTwo.control.controlAlg.parameters, name ) + patRecTwo.control.controlAlg.parameters.(name) = value; + end + + end + + % Read parameters from patRecOne and patRecTwo and store in patRec + tmp = [{'One'},{'Two'}]; + for iPatRec = 1:2 + currentPatRec = eval(['patRec',tmp{iPatRec}]); + allParameters = fieldnames( currentPatRec.control.controlAlg.parameters ); + if ~isempty(allParameters) + for iParam = 1:size( allParameters, 1 ) + currentParameter = allParameters(iParam); + patRec.control.controlAlg.parameters.(currentParameter{1}) = currentPatRec.control.controlAlg.parameters.(currentParameter{1}); + end + end + end + + patRecOne = UpdateControl(patRecOne); + patRecTwo = UpdateControl(patRecTwo); + + % Store patRecs in control properties + patRec.control.controlAlg.prop.patRecOne = patRecOne; + patRec.control.controlAlg.prop.patRecTwo = patRecTwo; + +end \ No newline at end of file diff --git a/Control/InitControl.m b/Control/InitControl.m index 877a88c..56544be 100644 --- a/Control/InitControl.m +++ b/Control/InitControl.m @@ -1,38 +1,38 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% Funtion to concentrate the calling of control algorithms -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-07-20 / Max Ortiz / Creation (moved out from RealtimePatRec) -% 20xx-xx-xx / Author / Comment on update - -function patRec = InitControl(patRec) - - if strcmp(patRec.controlAlg,'Majority vote') - patRec.outBuffer = zeros(4,patRec.nOuts); - elseif strcmp(patRec.controlAlg,'Buffer output') - patRec.outBuffer = zeros(4,patRec.nOuts); - elseif strcmp(patRec.controlAlg,'Ramp') - - end - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% Funtion to concentrate the calling of control algorithms +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-07-20 / Max Ortiz / Creation (moved out from RealtimePatRec) +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitControl(patRec) + + if strcmp(patRec.controlAlg,'Majority vote') + patRec.outBuffer = zeros(4,patRec.nOuts); + elseif strcmp(patRec.controlAlg,'Buffer output') + patRec.outBuffer = zeros(4,patRec.nOuts); + elseif strcmp(patRec.controlAlg,'Ramp') + + end + +end \ No newline at end of file diff --git a/Control/InitControl_new.m b/Control/InitControl_new.m index 2c09cce..7481a7e 100644 --- a/Control/InitControl_new.m +++ b/Control/InitControl_new.m @@ -1,103 +1,103 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% patRec = InitControl_new(patRec,type) -% -% Initializes a control algorithm onto the patRec structure. The -% control algorithm is stored in a structure called controlAlg and is -% placed at patRec.control.controlAlg. -% -% The controlAlg structure contains the name of the control -% algorithm, a funciton handle to the control algorithm script, -% parameters set by the user and properties that are to be used only -% by the algorithm itself. -% -% Each control algorithm can have its own initialization script -% setting up the properties, this should be named -% Init'MyControlAlg' ( replace 'MyControlAlg' with the name of the -% algorithm ). -% -% INPUTS: -% -% patRec - pattern recognition structure that are to be appended with -% the controlAlg structure -% -% type - a string with the name of any of the valid control -% algorithms stored in \Control\ValidControlAlgs.txt -% If type is empty or 'None', any controlAlg structure is removed -% from the patRec -% -% OUTPUTS: -% -% patRec - new pattern recognition structure with controlAlg -% structure stored inside patRec.control -% -% -%% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-05 / Joel Falk-Dahlin / Creation -% 2012-10-08 / Joel Falk-Dahlin / Added correct buffer setting from - % internal property (.prop.bufferSize) and - % not only from parameter - % (.parameter.bufferSize) allowing for - % different types of controlAlgs. -% 2012-10-10 / Joel Falk-Dahlin / Added check for outBuffer before - % initializing it, this way the buffer can - % be initialized in another manor in - % init-file -% 20xx-xx-xx / Author / Comment on update - -function patRec = InitControl_new(patRec,type) - -% Check if function is called with empty or None type -% Remove current controlAlg and return the patRec -if isempty(type) || strcmp(type,'None') - if isfield(patRec.control,'controlAlg') - patRec.control = rmfield(patRec.control,'controlAlg'); - end - -% Else, if type is not 'None' or empty, Check if it is a valid algorithm -else - % Read PostProcessors from file ValidControlAlg.txt - validControlAlg = ReadValidControlAlgs; - - % Check that the inputed type is a valid controlAlg - validTypes = []; - for i = 1:size(validControlAlg,2) - validTypes = [validTypes, validControlAlg{i}.name]; - end - validatestring(type, validTypes); % Gives error if not true - - % Find desired algorithm - desiredControlAlg = strcmp(type,validTypes); - - % Set patRec.controlAlg.name / .fnc / .parameters - % Set chosen postprocessor - patRec.control.controlAlg = validControlAlg{desiredControlAlg}; - - % Remove any output buffer that may be initialized - if isfield(patRec.control,'outBuffer') - patRec.control = rmfield(patRec.control,'outBuffer'); - end - - % Update buffers using current parameters - patRec = ReInitControl(patRec); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% patRec = InitControl_new(patRec,type) +% +% Initializes a control algorithm onto the patRec structure. The +% control algorithm is stored in a structure called controlAlg and is +% placed at patRec.control.controlAlg. +% +% The controlAlg structure contains the name of the control +% algorithm, a funciton handle to the control algorithm script, +% parameters set by the user and properties that are to be used only +% by the algorithm itself. +% +% Each control algorithm can have its own initialization script +% setting up the properties, this should be named +% Init'MyControlAlg' ( replace 'MyControlAlg' with the name of the +% algorithm ). +% +% INPUTS: +% +% patRec - pattern recognition structure that are to be appended with +% the controlAlg structure +% +% type - a string with the name of any of the valid control +% algorithms stored in \Control\ValidControlAlgs.txt +% If type is empty or 'None', any controlAlg structure is removed +% from the patRec +% +% OUTPUTS: +% +% patRec - new pattern recognition structure with controlAlg +% structure stored inside patRec.control +% +% +%% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-05 / Joel Falk-Dahlin / Creation +% 2012-10-08 / Joel Falk-Dahlin / Added correct buffer setting from + % internal property (.prop.bufferSize) and + % not only from parameter + % (.parameter.bufferSize) allowing for + % different types of controlAlgs. +% 2012-10-10 / Joel Falk-Dahlin / Added check for outBuffer before + % initializing it, this way the buffer can + % be initialized in another manor in + % init-file +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitControl_new(patRec,type) + +% Check if function is called with empty or None type +% Remove current controlAlg and return the patRec +if isempty(type) || strcmp(type,'None') + if isfield(patRec.control,'controlAlg') + patRec.control = rmfield(patRec.control,'controlAlg'); + end + +% Else, if type is not 'None' or empty, Check if it is a valid algorithm +else + % Read PostProcessors from file ValidControlAlg.txt + validControlAlg = ReadValidControlAlgs; + + % Check that the inputed type is a valid controlAlg + validTypes = []; + for i = 1:size(validControlAlg,2) + validTypes = [validTypes, validControlAlg{i}.name]; + end + validatestring(type, validTypes); % Gives error if not true + + % Find desired algorithm + desiredControlAlg = strcmp(type,validTypes); + + % Set patRec.controlAlg.name / .fnc / .parameters + % Set chosen postprocessor + patRec.control.controlAlg = validControlAlg{desiredControlAlg}; + + % Remove any output buffer that may be initialized + if isfield(patRec.control,'outBuffer') + patRec.control = rmfield(patRec.control,'outBuffer'); + end + + % Update buffers using current parameters + patRec = ReInitControl(patRec); + end % end "if type is None" \ No newline at end of file diff --git a/Control/InitMF_Hand_DC_Hardcoded.m b/Control/InitMF_Hand_DC_Hardcoded.m new file mode 100644 index 0000000..75336cf --- /dev/null +++ b/Control/InitMF_Hand_DC_Hardcoded.m @@ -0,0 +1,57 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to initialize the vector to be used for control of a +% multifuctional prosthetic device using dc motors +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2013-04-21 / Max Ortiz / Creation (removed from RealtimePatRec +% 20xx-xx-xx / Author / Comment on update + +function [pwmIDs pwmAs pwmBs] = InitMF_Hand_DC_Hardcoded(handles) + + %Initialize + motorIdx = zeros(1,10); + pwmAs = zeros(1,10); + pwmBs = zeros(1,10); + movSpeeds = zeros(1,10); + + % Get the links to the motors + for i = 1 : size(motorIdx,2) + pmID = ['handles.pm_m' num2str(i)]; + motorIdx(i) = get(eval(pmID),'Value'); + speedID = ['handles.et_speed' num2str(i)]; + movSpeeds(i) = str2double(get(eval(speedID),'String')); + end + + % Init variables for control + pwmIDs = ['A';'A';'B';'B';'C';'C';'D';'D';'E';'E']; + for i = 1 : 2 : size(pwmIDs) + pwmAs(i) = movSpeeds(i); + pwmBs(i) = 0; + pwmAs(i+1) = 0; + pwmBs(i+1) = movSpeeds(i+1); + end; + + % Arrenge according to selection + pwmIDs = pwmIDs(motorIdx); + pwmAs = pwmAs(motorIdx); + pwmBs = pwmBs(motorIdx); + +end \ No newline at end of file diff --git a/Control/InitMajorityVoteSimultaneous.m b/Control/InitMajorityVoteSimultaneous.m new file mode 100644 index 0000000..53be1e7 --- /dev/null +++ b/Control/InitMajorityVoteSimultaneous.m @@ -0,0 +1,32 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% Initialization of the MajorityVoteSimultaneous control strategy. This +% strategy uses a buffer with more elements then patRec.nOuts and thus +% have to be initialized in a seperate way. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-10 / Joel Falk-Dahlin / Creation + +function patRec = InitMajorityVoteSimultaneous(patRec) + +%patRec.control.outBuffer = zeros(patRec.control.controlAlg.parameters.bufferSize, size(patRec.movOutIdx,2)); + +end \ No newline at end of file diff --git a/Comm/InitMotors.m b/Control/InitMotors.m similarity index 97% rename from Comm/InitMotors.m rename to Control/InitMotors.m index c4b489d..c49303c 100644 --- a/Comm/InitMotors.m +++ b/Control/InitMotors.m @@ -1,38 +1,38 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Reads the file motors.def and loads the data into motor objects. -% --------------------------Updates-------------------------- -% 2012-05-29 / Nichlas Sander / Creation -% 2012-07-19 / Max Ortiz / Added fclose which is necessary to prevent -% matlab crashes due to many files open. -% 20xx-xx-xx / Author / Comment on update - -function obj = InitMotors -fid = fopen('motors.def'); -tline = fgetl(fid); -i = 1; -while(ischar(tline)) - t = textscan(tline,'%s','delimiter',','); - t = t{1}; - obj(i) = motor(t(1),str2double(t(2)),str2double(t(3))); - tline = fgetl(fid); - i = i + 1; -end - -fclose(fid); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Reads the file motors.def and loads the data into motor objects. +% --------------------------Updates-------------------------- +% 2012-05-29 / Nichlas Sander / Creation +% 2012-07-19 / Max Ortiz / Added fclose which is necessary to prevent +% matlab crashes due to many files open. +% 20xx-xx-xx / Author / Comment on update + +function obj = InitMotors +fid = fopen('motors.def'); +tline = fgetl(fid); +i = 1; +while(ischar(tline)) + t = textscan(tline,'%s','delimiter',','); + t = t{1}; + obj(i) = motor(t(1),str2double(t(2)),str2double(t(3))); + tline = fgetl(fid); + i = i + 1; +end + +fclose(fid); diff --git a/Comm/InitMovements.m b/Control/InitMovements.m similarity index 79% rename from Comm/InitMovements.m rename to Control/InitMovements.m index 26d53ec..9ac0cc7 100644 --- a/Comm/InitMovements.m +++ b/Control/InitMovements.m @@ -1,45 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Reads the file movements.def and loads the data into movement objects. -% --------------------------Updates-------------------------- -% 2012-05-29 / Nichlas Sander / Creation -% 20xx-xx-xx / Author / Comment on update - -function obj = InitMovements -fid = fopen('movements.def'); -tline = fgetl(fid); -i = 1; -while(ischar(tline)) - %Go through the string - t = textscan(tline,'%s','delimiter',','); - t = t{1}; - - %process t(5) here - m = textscan(cell2mat(t(5)),'%s','delimiter',' '); - j = 1; - clear motors; - while(j <= size(m{1},1)) - motors(j) = str2double(m{1}(j)); - j = j + 1; - end - obj(i) = movement(str2double(t(1)),t(2),str2double(t(3)),str2double(t(4)),motors); - tline = fgetl(fid); - i = i+1; -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Reads the file movements.def and loads the data into movement objects. +% --------------------------Updates-------------------------- +% 2012-05-29 / Nichlas Sander / Creation +% 2015-06-11 / Sebastian Karlsson / The directions of each motor in each +% movement are stored in motors matrix. +% 20xx-xx-xx / Author / Comment on update + +function obj = InitMovements +fid = fopen('movements.def'); +tline = fgetl(fid); +i = 1; +while(ischar(tline)) + %Go through the string + t = textscan(tline,'%s','delimiter',','); + t = t{1}; + + %process t(5) here + m = textscan(cell2mat(t(5)),'%s','delimiter',' '); + j = 1; + k = 1; + clear motors; + motors = zeros(2,size(m{1},1)/2); + while(j <= size(m{1},1)) + motors(1,k) = str2double(m{1}(j)); %Motor ID + motors(2,k) = str2double(m{1}(j+1)); %Motor Direction + j = j + 2; + k = k + 1; + end + obj(i) = movement(str2double(t(1)),t(2),str2double(t(3)),str2double(t(4)),motors); + tline = fgetl(fid); + i = i+1; +end fclose(fid); \ No newline at end of file diff --git a/Control/InitOutBuffer.m b/Control/InitOutBuffer.m index 69e84f6..341744b 100644 --- a/Control/InitOutBuffer.m +++ b/Control/InitOutBuffer.m @@ -1,94 +1,94 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% patRec = InitOutBuffer(patRec) -% -% Initializes the outBuffer stored in patRec.control. This buffer can -% be used by the control algorithms. Initialization of the buffer -% looks if the patRec has an attached control algorithm, if that -% control algorithm has either a parameter or a property called -% bufferSize. If not, the outBuffer is either created to contains one -% row and patRec.nOuts columns. If the buffer already exists it is -% reflushed to contain only zeros. -% -% INPUTS: -% -% patRec - pattern recognition structure that are to be initialized -% with an outBuffer -% -% OUTPUTS: -% -% patRec - new, updated patRec structure, that has an empty outBuffer -% stored in patRec.control.outBuffer -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-10 / Joel Falk-Dahlin / Creation - -function patRec = InitOutBuffer(patRec) - -% Is there a parameter bufferSize? -if isfield(patRec.control.controlAlg,'parameters') - if isfield(patRec.control.controlAlg.parameters,'bufferSize') - bufferSize = patRec.control.controlAlg.parameters.bufferSize; - % Is the outBuffer already initialized? - if isfield(patRec.control,'outBuffer') - % Is the size of the outBuffer correct? - if size(patRec.control.outBuffer,1) ~= bufferSize - patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); - end - % If not, initialize the outBuffer - else - patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); - end - end -end - -% Is there a property bufferSize? -if isfield(patRec.control.controlAlg,'prop') - if isfield(patRec.control.controlAlg.prop,'bufferSize') - bufferSize = patRec.control.controlAlg.prop.bufferSize; - % Is the outBuffer already initialized? - if isfield(patRec.control,'outBuffer') - % Is the size of the outBuffer correct? - if size(patRec.control.outBuffer,1) ~= bufferSize - patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); - end - % If not, initialize the outBuffer - else - patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); - end - end -end - -% If bufferSize in neither a parameter of property, check if already exist -% Initialize it to be 1, if it does not exists -if ~isfield(patRec.control,'outBuffer') - patRec = InitBuffer(patRec,[1, patRec.nOuts]); -% Reinitialize it to the same size if it already exists -else - bufferSize = size(patRec.control.outBuffer); - patRec = InitBuffer(patRec,bufferSize); -end - -end - -function patRec = InitBuffer(patRec,bufferSize) - patRec.control.outBuffer = zeros(bufferSize); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% patRec = InitOutBuffer(patRec) +% +% Initializes the outBuffer stored in patRec.control. This buffer can +% be used by the control algorithms. Initialization of the buffer +% looks if the patRec has an attached control algorithm, if that +% control algorithm has either a parameter or a property called +% bufferSize. If not, the outBuffer is either created to contains one +% row and patRec.nOuts columns. If the buffer already exists it is +% reflushed to contain only zeros. +% +% INPUTS: +% +% patRec - pattern recognition structure that are to be initialized +% with an outBuffer +% +% OUTPUTS: +% +% patRec - new, updated patRec structure, that has an empty outBuffer +% stored in patRec.control.outBuffer +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-10 / Joel Falk-Dahlin / Creation + +function patRec = InitOutBuffer(patRec) + +% Is there a parameter bufferSize? +if isfield(patRec.control.controlAlg,'parameters') + if isfield(patRec.control.controlAlg.parameters,'bufferSize') + bufferSize = patRec.control.controlAlg.parameters.bufferSize; + % Is the outBuffer already initialized? + if isfield(patRec.control,'outBuffer') + % Is the size of the outBuffer correct? + if size(patRec.control.outBuffer,1) ~= bufferSize + patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); + end + % If not, initialize the outBuffer + else + patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); + end + end +end + +% Is there a property bufferSize? +if isfield(patRec.control.controlAlg,'prop') + if isfield(patRec.control.controlAlg.prop,'bufferSize') + bufferSize = patRec.control.controlAlg.prop.bufferSize; + % Is the outBuffer already initialized? + if isfield(patRec.control,'outBuffer') + % Is the size of the outBuffer correct? + if size(patRec.control.outBuffer,1) ~= bufferSize + patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); + end + % If not, initialize the outBuffer + else + patRec = InitBuffer(patRec,[bufferSize, patRec.nOuts]); + end + end +end + +% If bufferSize in neither a parameter of property, check if already exist +% Initialize it to be 1, if it does not exists +if ~isfield(patRec.control,'outBuffer') + patRec = InitBuffer(patRec,[1, patRec.nOuts]); +% Reinitialize it to the same size if it already exists +else + bufferSize = size(patRec.control.outBuffer); + patRec = InitBuffer(patRec,bufferSize); +end + +end + +function patRec = InitBuffer(patRec,bufferSize) + patRec.control.outBuffer = zeros(bufferSize); end \ No newline at end of file diff --git a/Control/InitPropControl.m b/Control/InitPropControl.m index 9637f3c..b1588e8 100644 --- a/Control/InitPropControl.m +++ b/Control/InitPropControl.m @@ -1,50 +1,50 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% patRec = InitPropControl(patRec) -% -% Function to intialize the propControl structure to a patRec. -% Initialization is done with default parameters -% -% INPUTS: -% -% patRec - pattern recognition structure that are to use proprotional -% control -% -% OUTPUTS: -% -% patRec - patRec structure with propControl in patRec.control, using -% default parameters. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-11-27 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function patRec = InitPropControl(patRec) - - % Initialize prop control Vars if they don't exist - if ~isfield(patRec.control,'propControl') - patRec.control.propControl.propFeature = 1; - patRec.control.propControl.propMaxThresh = 5; - patRec.control.propControl.propMinThresh = 0; - patRec.control.propControl.propSpeedMap = 'linear'; - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% patRec = InitPropControl(patRec) +% +% Function to intialize the propControl structure to a patRec. +% Initialization is done with default parameters +% +% INPUTS: +% +% patRec - pattern recognition structure that are to use proprotional +% control +% +% OUTPUTS: +% +% patRec - patRec structure with propControl in patRec.control, using +% default parameters. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-27 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitPropControl(patRec) + + % Initialize prop control Vars if they don't exist + if ~isfield(patRec.control,'propControl') + patRec.control.propControl.propFeature = 1; + patRec.control.propControl.propMaxThresh = 5; + patRec.control.propControl.propMinThresh = 0; + patRec.control.propControl.propSpeedMap = 'linear'; + end + end \ No newline at end of file diff --git a/Control/InitRamp.m b/Control/InitRamp.m index 01947e7..e8fb253 100644 --- a/Control/InitRamp.m +++ b/Control/InitRamp.m @@ -1,41 +1,41 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Initialization of Ramp controlAlg. Sets up internal properties that are -% used by the algorithm. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-08 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function patRec = InitRamp(patRec) - -motors = InitMotors; -maxPct = zeros(size(motors)); -%nMisclassComp = patRec.controlAlg.parameters.nMisclassComp; - -for i = 1:size(maxPct,2) - maxPct(i) = motors(i).pct; -end - -patRec.control.controlAlg.prop.maxPct = maxPct; -patRec.control.controlAlg.prop.nPredicted = zeros(1,patRec.nOuts); -%patRec.controlAlg.prop.nPredictedBuffer = zeros(nMisclassComp+2,patRec.nOuts); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Initialization of Ramp controlAlg. Sets up internal properties that are +% used by the algorithm. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-08 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitRamp(patRec) + +motors = InitMotors; +maxPct = zeros(size(motors)); +%nMisclassComp = patRec.controlAlg.parameters.nMisclassComp; + +for i = 1:size(maxPct,2) + maxPct(i) = motors(i).pct; +end + +patRec.control.controlAlg.prop.maxPct = maxPct; +patRec.control.controlAlg.prop.nPredicted = zeros(1,patRec.nOuts); +%patRec.controlAlg.prop.nPredictedBuffer = zeros(nMisclassComp+2,patRec.nOuts); + end \ No newline at end of file diff --git a/Control/InitRampModified.m b/Control/InitRampModified.m new file mode 100644 index 0000000..feb38da --- /dev/null +++ b/Control/InitRampModified.m @@ -0,0 +1,40 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Initialization of RampModified controlAlg. Sets up internal properties that are +% used by the algorithm. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-17 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function patRec = InitRampModified(patRec) + +motors = InitMotors; +maxPct = zeros(size(motors)); +nMisclassComp = patRec.control.controlAlg.parameters.nMisclassComp; + +for i = 1:size(maxPct,2) + maxPct(i) = motors(i).pct; +end + +patRec.control.controlAlg.prop.maxPct = maxPct; +patRec.control.controlAlg.prop.nPredictedBuffer = zeros(nMisclassComp+2,patRec.nOuts); + +end \ No newline at end of file diff --git a/Control/InitRampModified2.m b/Control/InitRampModified2.m new file mode 100644 index 0000000..cc2bab7 --- /dev/null +++ b/Control/InitRampModified2.m @@ -0,0 +1,4 @@ +function patRec = InitRampModified2(patRec) + +patRec.control.controlAlg.prop.timesPredicted = zeros(1,patRec.nOuts); +patRec.control.controlAlg.prop.timesNotPredicted = zeros(1,patRec.nOuts); \ No newline at end of file diff --git a/Control/InitRampModified3.m b/Control/InitRampModified3.m new file mode 100644 index 0000000..a3f6a38 --- /dev/null +++ b/Control/InitRampModified3.m @@ -0,0 +1,3 @@ +function patRec = InitRampModified3(patRec) + +patRec.control.controlAlg.prop.timesPredicted = zeros(1,patRec.nOuts); \ No newline at end of file diff --git a/Control/InitSensors.m b/Control/InitSensors.m new file mode 100644 index 0000000..9534fbf --- /dev/null +++ b/Control/InitSensors.m @@ -0,0 +1,46 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Reads the file sensors.def and loads the data into sensor objects. +% --------------------------Updates-------------------------- +% 2015-06-11 / Sebastian Karlsson / Creation + +function obj = InitSensors + +global ctrl_dir + +sensorspath = 'sensors.def'; +if ctrl_dir + sensorspath = [ctrl_dir filesep 'sensors.def']; +end + +fid = fopen(sensorspath); +if fid == -1 + obj = -1; +else + tline = fgetl(fid); + i = 1; + while(ischar(tline)) + t = textscan(tline,'%s','delimiter',','); + t = t{1}; + obj(i) = sensor(t(1), t(2)); + tline = fgetl(fid); + i = i + 1; + end + fclose(fid); +end diff --git a/Control/MajorityVote.m b/Control/MajorityVote.m index 0c0b356..777cbe3 100644 --- a/Control/MajorityVote.m +++ b/Control/MajorityVote.m @@ -1,43 +1,43 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to compute the Majority voting control strategy. It looks at the -% latest prediction and extracts the most common -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-07 / Max Ortiz / Creation -% 2012-10-05 / Joel Falk-Dahlin / Added input and output arguments to -% match controlAlg standard. Added find -% function so outMov can be several -% outputs if there is equal ammount of -% predictions for two movements -% (simultaneous control) -% 20xx-xx-xx / Author / Comment on update - -function [patRec, outMov] = MajorityVote(patRec, outMov, outVec) - -% Remove the oldest prediction -patRec.control.outBuffer = patRec.control.outBuffer(2:end,:); -% Add the new prediction -patRec.control.outBuffer(end+1,outMov') = 1; - -%% Compute output -% Not suitable for simltaneous control -outMax = max(sum(patRec.control.outBuffer)); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to compute the Majority voting control strategy. It looks at the +% latest prediction and extracts the most common +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-07 / Max Ortiz / Creation +% 2012-10-05 / Joel Falk-Dahlin / Added input and output arguments to +% match controlAlg standard. Added find +% function so outMov can be several +% outputs if there is equal ammount of +% predictions for two movements +% (simultaneous control) +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = MajorityVote(patRec, outMov, outVec) + +% Remove the oldest prediction +patRec.control.outBuffer = patRec.control.outBuffer(2:end,:); +% Add the new prediction +patRec.control.outBuffer(end+1,outMov') = 1; + +%% Compute output +% Not suitable for simltaneous control +outMax = max(sum(patRec.control.outBuffer)); outMov = find(sum(patRec.control.outBuffer) == outMax )'; \ No newline at end of file diff --git a/Control/MajorityVoteSimultaneous.m b/Control/MajorityVoteSimultaneous.m new file mode 100644 index 0000000..dfd5936 --- /dev/null +++ b/Control/MajorityVoteSimultaneous.m @@ -0,0 +1,65 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function that extends the use of the MajorityVote strategy by remapping +% movements involving multiple DoFs to their corresponding movOutIdx, +% e.g. the outMov [2 3 6]' are mapped to the index i that corresponds to +% the same movement given by patRec.movOutIdx{i}. This way the movement +% containing all three DoFs are stored in a single number that can fill +% the buffer. Otherwise if one of the DoFs are misclassified the buffer +% will need to be filled all the way for that DoF to be predicted again. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-10 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = MajorityVoteSimultaneous(patRec, outMov, outVec) + +if ismember(patRec.nOuts,outMov) && strcmp(patRec.mov{end},'Rest') + outMov = patRec.nOuts; + % Reset buffer if rest is predicted + patRec.control.outBuffer(:) = 0; +else + % Update output buffer with the newly predicted movement + patRec.control.outBuffer(1:end-1,:) = patRec.control.outBuffer(2:end,:); + patRec.control.outBuffer(end,:) = zeros(1,size(patRec.control.outBuffer,2)); + patRec.control.outBuffer(end,outMov) = 1; + + % Count the occurances of the output vectors in outBuffer + outBuffer = patRec.control.outBuffer; + emptyRow = ( sum(outBuffer,2) == 0 ); % Remove all rows in buffer without prediction + outBuffer(emptyRow,:) = []; + counterMat = []; + while ~isempty(outBuffer) + currentMov = outBuffer(end,:); + eqMat = bsxfun(@eq, currentMov, outBuffer); + eqIdx = all(eqMat'); + + % Remove all entries that are equal and count them + counterMat = [counterMat; sum(eqIdx), currentMov]; + outBuffer(eqIdx,:) = []; + end + + % Find movement that is counted most times in buffer, if several movements + % are counted the same ammount of times, this gives the most recent + [~,I] = max(counterMat(:,1)); + outMovIdx = counterMat(I,2:end) > 0; + numberVector = 1:size(outBuffer,2); + outMov = numberVector(outMovIdx); +end diff --git a/Control/MotorsOff.m b/Control/MotorsOff.m index 31e2555..1d88231 100644 --- a/Control/MotorsOff.m +++ b/Control/MotorsOff.m @@ -1,74 +1,68 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to activate the DC or servo motors for some degrees. In the c -% of the DC motors this is given by time and the PWM duty cycle. In the -% case of servor motors, this is given only by the duty cycle. -% -% --------------------------Updates-------------------------- -% 2012-05-22 / Max Ortiz / Creation (MoveMotor) -% 2012-07-03 / Max Ortiz / Creation of specific routines for activation -% and deactivation to improve speed. - -function [motors, movement] = MotorsOff(com, movement, motors) - -if strcmp(movement.name,'Rest') - return; -end - -%pwmIDs = cell2mat(movement.idMotor); -movMotors = movement.motor; -noPIDs = size(movMotors,2); - -motorPct = []; -pwmIDs = []; - -% Get the IDs of al PWM involved in the selected movement -for i=1:length(movMotors) - motorPct = [motorPct motors(movMotors(i)).pct]; - pwmIDs = [pwmIDs cell2mat(motors(movMotors(i)).id)]; -end - - -%This only works when movements have motors with the same (motor)type -%% DC motors -if (motors(movMotors(1)).type == 0) % DC Motors - - % Get the pwm vectors according to the direction of the movement - if movement.vreDir - pwmA = zeros(1,noPIDs); - pwmB = motorPct; - else - pwmA = motorPct; - pwmB = zeros(1,noPIDs); - end - - % Stop - for i = 1 : noPIDs - if ~Update2PWMusingSCI(com, pwmIDs(i), 0, 0); - disp('Failed'); - fclose(com.io); - end - end - -%% Servo Motors -elseif motors(movMotors(1)).type == 1 - % Servor don't need to be stoped, since they will stop automatically at - % the last given position. -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to activate the DC or servo motors for some degrees. In the c +% of the DC motors this is given by time and the PWM duty cycle. In the +% case of servor motors, this is given only by the duty cycle. +% +% --------------------------Updates-------------------------- +% 2012-05-22 / Max Ortiz / Creation (MoveMotor) +% 2012-07-03 / Max Ortiz / Creation of specific routines for activation +% and deactivation to improve speed. +% 2015-06-11 / Sebastian Karlsson / Moved to motor-type identification +% to be implemented on the connected devices +% firmware instead of handled by +% this function, according to the standardized framework. +% 2015-07-07 / Enzo Mastinu / The Update2PWMusingSCI function has been +% replaced with the general SendMotorCommand, +% used to implement the control framework + + + +function [motors, movement] = MotorsOff(com, movement, motors) + +if strcmp(movement.name,'Rest') + return; +end + +noPIDs = size(movement.motor,2); + +% Activate and update +for i = 1 : noPIDs + % Check the speed Updating + motors(movement.motor(1,i)).pct = 0; %%%SERVE? + % Extract control type (defined in "motors.def" file) + ctrl_type = motors(movement.motor(1,i)).type; + % Extract motor index (defined in "motors.def" file) + motor_index = cell2mat(motors(movement.motor(1,i)).id); + % Extract movement direction (for speed control) + mov_dir = movement.motor(2,i); + + % Send motor commands + if(ctrl_type == 0) + % if in speed control, PWM must be set to 0 + if ~SendMotorCommand(com, ctrl_type, motor_index, mov_dir, 0); + disp('Failed'); + fclose(com.io); + end + + elseif(ctrl_type == 1) + % if in position control, no commands are needed for the device to + % stop + end +end \ No newline at end of file diff --git a/Control/MotorsOn.m b/Control/MotorsOn.m index d40ad13..22f8f5c 100644 --- a/Control/MotorsOn.m +++ b/Control/MotorsOn.m @@ -1,99 +1,61 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to activate the DC or servo motors. The speed of -% DC motors this is given by the PWM duty cycle. In the -% case of servor motors, the position is simply incremented. -% -% --------------------------Updates-------------------------- -% 2012-05-22 / Max Ortiz / Creation (MoveMotor) -% 2012-07-03 / Max Ortiz / Creation of specific routines for activation -% and deactivation to improve speed. - -function [motors, movement] = MotorsOn(com, movement, motors, degrees) - -if strcmp(movement.name,'Rest') - return; -end - -%pwmIDs = cell2mat(movement.idMotor); -movMotors = movement.motor; -noPIDs = size(movMotors,2); - -motorPct = []; -pwmIDs = []; - -% Get the IDs of al PWM involved in the selected movement -for i=1:length(movMotors) - motorPct = [motorPct motors(movMotors(i)).pct]; - pwmIDs = [pwmIDs cell2mat(motors(movMotors(i)).id)]; -end - -% THe following code doesn't work because this routines is only called when -% the prediction is changed, therefore the effect of the ramp cannot be -% observed in the current setup. -% Code for variable speed according to "degrees" -% mPct = 10*degrees; -% if mPct >= 100 -% mPct = 100; -% end -% motorPct(1:length(movMotors)) = mPct; - -%This only works when movements have motors with the same (motor)type -%% DC motors -if (motors(movMotors(1)).type == 0) - - % Get the pwm vectors according to the direction of the movement - if movement.vreDir - pwmA = zeros(1,noPIDs); - pwmB = motorPct; - else - pwmA = motorPct; - pwmB = zeros(1,noPIDs); - end - - % Activate them - for i = 1 : noPIDs - % Send motor values - if ~Update2PWMusingSCI(com, pwmIDs(i), pwmA(i), pwmB(i)); - disp('Failed'); - fclose(com.io); - end - end - -%% Servo Motors -elseif motors(movMotors(1)).type == 1 - - % Add the position - if(movement.vreDir) - movDeg = -degrees; - else - movDeg = degrees; - end - - motors(movMotors(1)).pct = motors(movMotors(1)).pct + movDeg; - - % Send PWM - [result motors(movMotors(1)).pct] = UpdatePWMusingSCI_PanTilt(com, pwmIDs, motors(movMotors(1)).pct); - % If no problems where encountered, the ALC must return 1 - if ~result - disp('Failed'); - fclose(handles.com.io); - end - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to activate the DC or servo motors. The speed of +% DC motors this is given by the PWM duty cycle. In the +% case of servor motors, the position is simply incremented. +% +% --------------------------Updates-------------------------- +% 2012-05-22 / Max Ortiz / Creation (MoveMotor) +% 2012-07-03 / Max Ortiz / Creation of specific routines for activation +% and deactivation to improve speed. +% 2015-06-11 / Sebastian Karlsson / Changed to update the current +% speed/position of all types of motors. +% Moved to motor-type identification +% to be implemented on the connected devices +% firmware instead of handled by +% this function, according to the standardized framework. +% 2015-07-07 / Enzo Mastinu / The Update2PWMusingSCI function has been +% replaced with the general SendMotorCommand, +% used to implement the control framework + +function [motors, movement] = MotorsOn(com, movement, motors, ctrl_val) + +if strcmp(movement.name,'Rest') + return; +end + +noPIDs = size(movement.motor,2); + +% Activate and update +for i = 1 : noPIDs + % Check the speed Updating + motors(movement.motor(1,i)).pct = ctrl_val; %%% SERVE? + % Extract control type (defined in "motors.def" file) + ctrl_type = motors(movement.motor(1,i)).type; + % Extract motor index (defined in "motors.def" file) + motor_index = cell2mat(motors(movement.motor(1,i)).id); + % Extract movement direction (for speed control) + mov_dir = movement.motor(2,i); + + % Send motor commands + if ~SendMotorCommand(com, ctrl_type, motor_index, mov_dir, ctrl_val); + disp('Failed'); % CHECK + fclose(com); + end +end diff --git a/Control/MoveMotor.m b/Control/MoveMotor.m index f953f5e..74f9602 100644 --- a/Control/MoveMotor.m +++ b/Control/MoveMotor.m @@ -1,103 +1,103 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to activate the DC or servo motors for some degrees. In the c -% of the DC motors this is given by time and the PWM duty cycle. In the -% case of servor motors, this is given only by the duty cycle. -% -% --------------------------Updates-------------------------- -% 2012-05-22 / Max Ortiz / Creation - -function [motors, movement] = MoveMotor(com, movement, movDeg,motors) - -%pwmIDs = cell2mat(movement.idMotor); -movMotors = movement.motor; -noPIDs = size(movMotors,2); - -motorPct = []; -pwmIDs = []; -motorActive = []; - -% Get the IDs of al PWM involved in the selected movement -for i=1:length(movMotors) - motorPct = [motorPct motors(movMotors(i)).pct]; - pwmIDs = [pwmIDs cell2mat(motors(movMotors(i)).id)]; -end - - -%This only works when movements have motors with the same (motor)type -%% DC motors -if (motors(movMotors(1)).type == 0) % DC Motors - pause on; - - % Get the pwm vectors according to the direction of the movement - if movement.vreDir - pwmA = zeros(1,noPIDs); - pwmB = motorPct; - else - pwmA = motorPct; - pwmB = zeros(1,noPIDs); - end - - % Relationship between degrees and time. - movTime = movDeg / 100; - - % Activate them - for i = 1 : noPIDs - % Send motor values - if ~Update2PWMusingSCI(com, pwmIDs(i), pwmA(i), pwmB(i)); - disp('Failed'); - fclose(com.io); - end - end - - % wait for the DoF to move - pause(movTime); - - % Stop - for i = 1 : noPIDs - if ~Update2PWMusingSCI(com, pwmIDs(i), 0, 0); - disp('Failed'); - fclose(com.io); - end - end - pause off; - -%% Servo Motors -elseif motors(movMotors(1)).type == 1 - - % Add the position - if(movement.vreDir) - movDeg = movDeg * -1; - end - - motors(movMotors(1)).pct = motors(movMotors(1)).pct + movDeg; - - % If no problems where encountered, the ALC must return 1 - % Send PWM - - [result motors(movMotors(1)).pct] = UpdatePWMusingSCI_PanTilt(com, pwmIDs, motors(movMotors(1)).pct); - - if ~result - disp('Failed'); - fclose(handles.com.io); - end - -end -%% End of the routines -motorsLast = motors; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to activate the DC or servo motors for some degrees. In the c +% of the DC motors this is given by time and the PWM duty cycle. In the +% case of servor motors, this is given only by the duty cycle. +% +% --------------------------Updates-------------------------- +% 2012-05-22 / Max Ortiz / Creation + +function [motors, movement] = MoveMotor(com, movement, movDeg,motors) + +%pwmIDs = cell2mat(movement.idMotor); +movMotors = movement.motor; +noPIDs = size(movMotors,2); + +motorPct = []; +pwmIDs = []; +motorActive = []; + +% Get the IDs of al PWM involved in the selected movement +for i=1:length(movMotors) + motorPct = [motorPct motors(movMotors(i)).pct]; + pwmIDs = [pwmIDs cell2mat(motors(movMotors(i)).id)]; +end + + +%This only works when movements have motors with the same (motor)type +%% DC motors +if (motors(movMotors(1)).type == 0) % DC Motors + pause on; + + % Get the pwm vectors according to the direction of the movement + if movement.vreDir + pwmA = zeros(1,noPIDs); + pwmB = motorPct; + else + pwmA = motorPct; + pwmB = zeros(1,noPIDs); + end + + % Relationship between degrees and time. + movTime = movDeg / 100; + + % Activate them + for i = 1 : noPIDs + % Send motor values + if ~Update2PWMusingSCI(com, pwmIDs(i), pwmA(i), pwmB(i)); + disp('Failed'); + fclose(com.io); + end + end + + % wait for the DoF to move + pause(movTime); + + % Stop + for i = 1 : noPIDs + if ~Update2PWMusingSCI(com, pwmIDs(i), 0, 0); + disp('Failed'); + fclose(com.io); + end + end + pause off; + +%% Servo Motors +elseif motors(movMotors(1)).type == 1 + + % Add the position + if(movement.vreDir) + movDeg = movDeg * -1; + end + + motors(movMotors(1)).pct = motors(movMotors(1)).pct + movDeg; + + % If no problems where encountered, the ALC must return 1 + % Send PWM + + [result motors(movMotors(1)).pct] = UpdatePWMusingSCI_PanTilt(com, pwmIDs, motors(movMotors(1)).pct); + + if ~result + disp('Failed'); + fclose(handles.com.io); + end + +end +%% End of the routines +motorsLast = motors; diff --git a/Control/MoveMotorWifi.m b/Control/MoveMotorWifi.m new file mode 100644 index 0000000..99453fa --- /dev/null +++ b/Control/MoveMotorWifi.m @@ -0,0 +1,49 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to activate the standard prosthetic components for +% a defined amount of time. +% +% --------------------------Updates-------------------------- +% 2013-06-03 / Max Ortiz / Creation + +function [motors, movement] = MoveMotorWifi(obj, movement, movDeg, motors) + + movMotors = movement.motor; + motorPct = motors(movMotors).pct; + + % Decode PWM id by looking at the motor and its direction + pwmID = cell2mat(motors(movMotors).id); + if pwmID == 'A' && movement.vreDir == 0 + pwmID = 'A'; + elseif pwmID == 'A' && movement.vreDir == 1 + pwmID = 'B'; + elseif pwmID == 'B' && movement.vreDir == 0 + pwmID = 'C'; + elseif pwmID == 'B' && movement.vreDir == 1 + pwmID = 'D'; + elseif pwmID == 'C' && movement.vreDir == 0 + pwmID = 'E'; + elseif pwmID == 'C' && movement.vreDir == 1 + pwmID = 'F'; + end + + time = movDeg; + ActivateSP_FixedTime(obj,pwmID,motorPct,time); + +end diff --git a/Control/Ramp.m b/Control/Ramp.m index c3224f1..216b397 100644 --- a/Control/Ramp.m +++ b/Control/Ramp.m @@ -1,98 +1,98 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Ramp control strategy. Sets speed for VRE and PWMs depending on how many -% consecutive predictions a motions has. Still to be implemented, -% misclassification protection that saves nPredicted in the case of -% intermittent misclassifications. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-16 / Joel Falk-Dahlin / Creation -% 2012-10-26 / Joel Falk-Dahlin / Changed maxSpeed to be set from desired -% output speed instead of a separate -% variable for the Ramp algorithm. This -% was necessary for prop.control -% 20xx-xx-xx / Author / Comment on update - -function [patRec, outMov] = Ramp(patRec, outMov, outVec) - -% Read Values from patRec object -maxSpeed = patRec.control.currentDegPerMov; -rampLength = patRec.control.controlAlg.parameters.rampLength; -downCount = patRec.control.controlAlg.parameters.downCount; -nPredicted = patRec.control.controlAlg.prop.nPredicted; -maxPct = patRec.control.controlAlg.prop.maxPct; - -% Save movement in index vector rather then as numbers -outMovIndex = zeros(size(nPredicted)); -outMovIndex(outMov) = 1; -outMovIndex = outMovIndex > 0; - -% Add one to counter if movement is predicted -nPredicted(outMovIndex) = nPredicted(outMovIndex) + 1; - -% Remove downCount from counter if movement is not predicted -nPredicted( ~outMovIndex ) = nPredicted(~outMovIndex) - downCount; - -% Make sure that counter is not more then rampLength or less then zero -nPredicted( nPredicted > rampLength ) = rampLength; -nPredicted( nPredicted < 0 ) = 0; - -% Save nPredicted into the patRec struct -patRec.control.controlAlg.prop.nPredicted = nPredicted; - -%% Calculate movement speeds - -% Calculate ramp gain for each movement depending on how many times they -% have been predicted -rampGain = nPredicted./ rampLength; - -% Set movement speed to maxSpeed*rampGain for now (maxSpeed can be changed -% to desired speed when proportional control is implemented) -movSpeed = maxSpeed.*rampGain; - -% Set non-predicted movements to zero-speed -movSpeed(~outMovIndex) = 0; - -%% Update VRE/ARE/Motor speeds - -% Update motor speeds -% if isfield(handles,'movList') && isfield(handles,'motors') -% movements = handles.movList(outMov); -% for i = 1:size(movements,2) -% movMotors = movements(i).motor; -% for j = 1:size(movMotors,2) -% handles.motors(movMotors(j)).pct = ... -% Speed2Pct(movSpeed(outMov(i)), maxSpeed, maxPct(movMotors(j))); -% end -% end -% end - -% Update VRE/ARE speeds -if isfield(patRec.control, 'currentDegPerMov') - patRec.control.currentDegPerMov = movSpeed; - %handles.speeds = round(handles.speeds); -end - -end - -%% Internal Speed to Pct converter -function pct = Speed2Pct(movSpeed, maxSpeed, maxPct) - pct = maxPct./maxSpeed .* movSpeed; -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Ramp control strategy. Sets speed for VRE and PWMs depending on how many +% consecutive predictions a motions has. Still to be implemented, +% misclassification protection that saves nPredicted in the case of +% intermittent misclassifications. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-16 / Joel Falk-Dahlin / Creation +% 2012-10-26 / Joel Falk-Dahlin / Changed maxSpeed to be set from desired +% output speed instead of a separate +% variable for the Ramp algorithm. This +% was necessary for prop.control +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = Ramp(patRec, outMov, outVec) + +% Read Values from patRec object +maxSpeed = patRec.control.currentDegPerMov; +rampLength = patRec.control.controlAlg.parameters.rampLength; +downCount = patRec.control.controlAlg.parameters.downCount; +nPredicted = patRec.control.controlAlg.prop.nPredicted; +maxPct = patRec.control.controlAlg.prop.maxPct; + +% Save movement in index vector rather then as numbers +outMovIndex = zeros(size(nPredicted)); +outMovIndex(outMov) = 1; +outMovIndex = outMovIndex > 0; + +% Add one to counter if movement is predicted +nPredicted(outMovIndex) = nPredicted(outMovIndex) + 1; + +% Remove downCount from counter if movement is not predicted +nPredicted( ~outMovIndex ) = nPredicted(~outMovIndex) - downCount; + +% Make sure that counter is not more then rampLength or less then zero +nPredicted( nPredicted > rampLength ) = rampLength; +nPredicted( nPredicted < 0 ) = 0; + +% Save nPredicted into the patRec struct +patRec.control.controlAlg.prop.nPredicted = nPredicted; + +%% Calculate movement speeds + +% Calculate ramp gain for each movement depending on how many times they +% have been predicted +rampGain = nPredicted./ rampLength; + +% Set movement speed to maxSpeed*rampGain for now (maxSpeed can be changed +% to desired speed when proportional control is implemented) +movSpeed = maxSpeed.*rampGain; + +% Set non-predicted movements to zero-speed +movSpeed(~outMovIndex) = 0; + +%% Update VRE/ARE/Motor speeds + +% Update motor speeds +% if isfield(handles,'movList') && isfield(handles,'motors') +% movements = handles.movList(outMov); +% for i = 1:size(movements,2) +% movMotors = movements(i).motor; +% for j = 1:size(movMotors,2) +% handles.motors(movMotors(j)).pct = ... +% Speed2Pct(movSpeed(outMov(i)), maxSpeed, maxPct(movMotors(j))); +% end +% end +% end + +% Update VRE/ARE speeds +if isfield(patRec.control, 'currentDegPerMov') + patRec.control.currentDegPerMov = movSpeed; + %handles.speeds = round(handles.speeds); +end + +end + +%% Internal Speed to Pct converter +function pct = Speed2Pct(movSpeed, maxSpeed, maxPct) + pct = maxPct./maxSpeed .* movSpeed; +end diff --git a/Control/RampModified.m b/Control/RampModified.m new file mode 100644 index 0000000..64bae8d --- /dev/null +++ b/Control/RampModified.m @@ -0,0 +1,131 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Handles misclassifications differently than Ramp. Instead of a +% downcounter it resumes the counter if the movement is predicted within +% nMisclassificationComp + 1 iterations. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-17 / Joel Falk-Dahlin / Creation +% 2012-10-26 / Joel Falk-Dahlin / Changed maxSpeed to be set from desired +% output speed instead of a separate +% variable for the Ramp algorithm. This +% was necessary for prop.control +% 20xx-xx-xx / Author / Comment on update + +function [patRec, outMov] = RampModified(patRec, outMov, outVec) + +%% Read Values from patRec object +maxSpeed = patRec.control.currentDegPerMov; +rampLength = patRec.control.controlAlg.parameters.rampLength; +nPredicted = patRec.control.controlAlg.prop.nPredictedBuffer(end,:); +maxPct = patRec.control.controlAlg.prop.maxPct; + +%% Update nPrediction buffer + +% Save movement in index vector rather then as numbers +outMovIndex = zeros(size(nPredicted)); +outMovIndex(outMov) = 1; +outMovIndex = outMovIndex > 0; + +% Add one to counter if movement is predicted +nPredicted(outMovIndex) = nPredicted(outMovIndex) + 1; + +% Set current nPredicted to zero for non-predicted movements +nPredicted(~outMovIndex) = 0; + +% Make sure that counter is not more then rampLength or less then zero +nPredicted( nPredicted > rampLength ) = rampLength; +nPredicted( nPredicted < 0 ) = 0; + +% Save nPredicted to nPredictedBuffer +patRec.control.controlAlg.prop.nPredictedBuffer(1:end-1,:) = patRec.control.controlAlg.prop.nPredictedBuffer(2:end,:); +patRec.control.controlAlg.prop.nPredictedBuffer(end,:) = nPredicted; + +%% Check for Misclassification compensation + +% Find all zeros in nPredicted buffer +zeroMat = patRec.control.controlAlg.prop.nPredictedBuffer == 0; +% Find all movements that contain atleast one zero +containZero = sum(zeroMat) > 0; +% Find all movements that does not only contain zeros in the buffer +notOnlyZeros = sum(zeroMat) < size(patRec.control.controlAlg.prop.nPredictedBuffer,1)-1; +% Find all movements that contain atleast one, but not only, zeros +movWithZero = containZero.*notOnlyZeros > 0; +% Find all movements with atleast one, but not only, zeros with non +% zero input (these are misclassified) +misclassifiedMoves = movWithZero.*nPredicted > 0; +% Find index of misclassified moves +misclassifiedMoves = find(misclassifiedMoves); + +% For all misclassified moves +for i = 1:length(misclassifiedMoves) + % Find all non-zero elements in buffer, except newest + iRow = find(patRec.control.controlAlg.prop.nPredictedBuffer(1:end-1,misclassifiedMoves(i))); + % Set current output to previous + 1 + patRec.control.controlAlg.prop.nPredictedBuffer(end,misclassifiedMoves(i)) = ... + patRec.control.controlAlg.prop.nPredictedBuffer(iRow(end),misclassifiedMoves(i))+1; +end + +% Make sure that the buffer never has larger values than allowed +index = patRec.control.controlAlg.prop.nPredictedBuffer(end,:) > rampLength; +patRec.control.controlAlg.prop.nPredictedBuffer(end,index) = rampLength; + +% Re-read the current nPredicted from the buffer (after misclass +% compenstion in done) +nPredicted = patRec.control.controlAlg.prop.nPredictedBuffer(end,:); + +%% Calculate movement speeds + +% Calculate ramp gain for each movement depending on how many times they +% have been predicted +rampGain = nPredicted./ rampLength; + +% Set movement speed to maxSpeed*rampGain for now (maxSpeed can be changed +% to desired speed when proportional control is implemented) +movSpeed = maxSpeed.*rampGain; + +% Set non-predicted movements to zero-speed +movSpeed(~outMovIndex) = 0; + +%% Update VRE/ARE/Motor speeds + +% Update motor speeds +% if isfield(handles,'movList') && isfield(handles,'motors') +% movements = handles.movList(outMov); +% for i = 1:size(movements,2) +% movMotors = movements(i).motor; +% for j = 1:size(movMotors,2) +% handles.motors(movMotors(j)).pct = ... +% Speed2Pct(movSpeed(outMov(i)), maxSpeed, maxPct(movMotors(j))); +% end +% end +% end + +% Update VRE/ARE speeds +if isfield(patRec.control, 'currentDegPerMov') + patRec.control.currentDegPerMov = movSpeed; + %handles.speeds = round(handles.speeds); +end +end + +%% Internal Speed to Pct converter +function pct = Speed2Pct(movSpeed, maxSpeed, maxPct) + pct = maxPct./maxSpeed .* movSpeed; +end diff --git a/Control/RampModified2.m b/Control/RampModified2.m new file mode 100644 index 0000000..71b0a13 --- /dev/null +++ b/Control/RampModified2.m @@ -0,0 +1,61 @@ +function [patRec, outMov] = RampModified2(patRec, outMov, outVec) + +% Read speeds +maxDegPerMov = patRec.control.currentDegPerMov; + +% Read counters +timesPredicted = patRec.control.controlAlg.prop.timesPredicted; +timesNotPredicted = patRec.control.controlAlg.prop.timesNotPredicted; + +% Read controlAlg parameters +nMisclassificationCompensation = patRec.control.controlAlg.parameters.nMisclassificationCompensation; +downCount = patRec.control.controlAlg.parameters.downCount; +nPredictionsToSteadyPhase = patRec.control.controlAlg.parameters.nPredictionsToSteadyPhase; +rampLength = patRec.control.controlAlg.parameters.rampLength; + +% Create vector with boolean indicies of predicted movements +predictedMovementsIndex = false(1,patRec.nOuts); +predictedMovementsIndex(outMov) = true; + +% Update Counters +timesPredicted(predictedMovementsIndex) = timesPredicted(predictedMovementsIndex) + 1; +timesNotPredicted(~predictedMovementsIndex) = timesNotPredicted(~predictedMovementsIndex) + 1; +timesNotPredicted(predictedMovementsIndex) = 0; + +% Catergorize movements in initial and steady phases +initialPhaseMovementsIdx = timesPredicted < nPredictionsToSteadyPhase; +steadyPhaseMovementsIdx = timesPredicted >= nPredictionsToSteadyPhase; + +% If movement is in initial phase and not classified, reset velocity +timesPredicted( initialPhaseMovementsIdx & ~predictedMovementsIndex ) = 0; + +% If movement is in steady phase and not classified, only reset velocity if +% enough number of predictions has been made without movement +steadyPhaseNotPredictedIdx = (steadyPhaseMovementsIdx & ~predictedMovementsIndex); +steadyPhaseToDecreaseLongIdx = steadyPhaseNotPredictedIdx & (timesNotPredicted == nMisclassificationCompensation+1); +steadyPhaseToDecreaseShortIdx = steadyPhaseNotPredictedIdx & (timesNotPredicted > nMisclassificationCompensation+1); +steadyPhaseToIncrease = steadyPhaseNotPredictedIdx & (timesNotPredicted <= nMisclassificationCompensation); +timesPredicted(steadyPhaseToDecreaseLongIdx) = timesPredicted(steadyPhaseToDecreaseLongIdx)-(nMisclassificationCompensation+1)*downCount; +timesPredicted(steadyPhaseToDecreaseShortIdx) = timesPredicted(steadyPhaseToDecreaseShortIdx)-downCount; +timesPredicted(steadyPhaseToIncrease) = timesPredicted(steadyPhaseToIncrease)+1; + +% If predicted movement is rest, reset all counters +if outMov == patRec.nOuts + timesPredicted(:) = 0; + timesNotPredicted(:) = 0; +end + +% Limit Counters so they don't count to inifinity +timesPredicted( timesPredicted > rampLength ) = rampLength; +timesPredicted( timesPredicted < 0 ) = 0; +timesNotPredicted( timesNotPredicted > nMisclassificationCompensation+2 ) = nMisclassificationCompensation+2; +timesNotPredicted( timesNotPredicted < 0 ) = 0; + +% Update Speeds, only output the speed of the predicted movement +rampGain = timesPredicted./rampLength; +patRec.control.currentDegPerMov = rampGain .* maxDegPerMov; +patRec.control.currentDegPerMov(~predictedMovementsIndex) = 0; + +% Save Counters +patRec.control.controlAlg.prop.timesPredicted = timesPredicted; +patRec.control.controlAlg.prop.timesNotPredicted = timesNotPredicted; \ No newline at end of file diff --git a/Control/RampModified3.m b/Control/RampModified3.m new file mode 100644 index 0000000..13fcaa3 --- /dev/null +++ b/Control/RampModified3.m @@ -0,0 +1,44 @@ +function [patRec, outMov] = RampModified3(patRec, outMov, outVec) + +if ismember(patRec.nOuts,outMov) && strcmp(patRec.mov{end},'Rest') + outMov = patRec.nOuts; + % Reset buffer if rest is predicted + patRec.control.controlAlg.prop.timesPredicted(:) = 0; +else + % Smooth the prediction with Store Last Prediction from buffer + lastPredictionInBuffer = patRec.control.outBuffer(1,:) > 0; + + % Update output buffer with the newly predicted movement + patRec.control.outBuffer(1:end-1,:) = patRec.control.outBuffer(2:end,:); + patRec.control.outBuffer(end,:) = zeros(1,size(patRec.control.outBuffer,2)); + patRec.control.outBuffer(end,outMov) = 1; + + % Save index of all movements occuring in buffer + increaseSpeedIdx = sum(patRec.control.outBuffer,1) > 0; + decreaseSpeedBigIdx = (lastPredictionInBuffer > 0) &(lastPredictionInBuffer ~= increaseSpeedIdx); + decreaseSpeedSmallIdx = ~increaseSpeedIdx & ~decreaseSpeedBigIdx; + + % Read controlAlg parameters and properties + timesPredicted = patRec.control.controlAlg.prop.timesPredicted; + downCount = patRec.control.controlAlg.parameters.downCount; + rampLength = patRec.control.controlAlg.parameters.rampLength; + bufferSize = patRec.control.controlAlg.parameters.bufferSize; + maxDegPerMov = patRec.control.currentDegPerMov; + + % Update time predicted vector. + timesPredicted( increaseSpeedIdx ) = timesPredicted( increaseSpeedIdx )+1; + timesPredicted( decreaseSpeedSmallIdx ) = timesPredicted( decreaseSpeedSmallIdx )-downCount; + timesPredicted( decreaseSpeedBigIdx ) = timesPredicted( decreaseSpeedBigIdx )- (bufferSize-1)*downCount; + + % Limit Counters so they don't count to inifinity + timesPredicted( timesPredicted > rampLength ) = rampLength; + timesPredicted( timesPredicted < 0 ) = 0; + + % Update Speeds, only output the speed of the predicted movement + rampGain = timesPredicted./rampLength; + patRec.control.currentDegPerMov(:) = 0; + patRec.control.currentDegPerMov(outMov) = rampGain(outMov) .* maxDegPerMov(outMov); + + % Save Counters + patRec.control.controlAlg.prop.timesPredicted = timesPredicted; +end \ No newline at end of file diff --git a/Control/ReInitControl.m b/Control/ReInitControl.m index e04b90a..d00a6da 100644 --- a/Control/ReInitControl.m +++ b/Control/ReInitControl.m @@ -1,56 +1,56 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% patRec = ReInitControl(patRec) -% -% Function to reinitialize the control algorithm using the parameters -% stored in the structure controlAlg.parameters. -% -% This function should be called whenever any of these parameters are -% changed inorder to make sure that the internal properties and the -% output buffer are set correctly. -% -% INPUTS: -% -% patRec - pattern recognition structure -% -% OUTPUTS: -% -% patRec - updated pattern recognition structure with reinitialized -% controlAlg using the parameters stored in controlAlg.parameters. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-15 / Joel Falk-Dahlin / Creation (Moved from InitControl_new) -% 20xx-xx-xx / Author / Comment on update - -function patRec = ReInitControl(patRec) - - % Check if additional initialization file exists for control - % algorithm, if Init'ControlAlg'.m exists, execute it. - if isfield(patRec.control,'controlAlg') - if exist(['Init', patRec.control.controlAlg.name{1}],'file') == 2 - patRec = feval(['Init', patRec.control.controlAlg.name{1}], patRec); - end - - % Check if the current Control has a Buffer size, otherwise set to 1 - patRec = InitOutBuffer(patRec); - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% patRec = ReInitControl(patRec) +% +% Function to reinitialize the control algorithm using the parameters +% stored in the structure controlAlg.parameters. +% +% This function should be called whenever any of these parameters are +% changed inorder to make sure that the internal properties and the +% output buffer are set correctly. +% +% INPUTS: +% +% patRec - pattern recognition structure +% +% OUTPUTS: +% +% patRec - updated pattern recognition structure with reinitialized +% controlAlg using the parameters stored in controlAlg.parameters. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-15 / Joel Falk-Dahlin / Creation (Moved from InitControl_new) +% 20xx-xx-xx / Author / Comment on update + +function patRec = ReInitControl(patRec) + + % Check if additional initialization file exists for control + % algorithm, if Init'ControlAlg'.m exists, execute it. + if isfield(patRec.control,'controlAlg') + if exist(['Init', patRec.control.controlAlg.name{1}],'file') == 2 + patRec = feval(['Init', patRec.control.controlAlg.name{1}], patRec); + end + + % Check if the current Control has a Buffer size, otherwise set to 1 + patRec = InitOutBuffer(patRec); + end end \ No newline at end of file diff --git a/Control/ReadSensors.m b/Control/ReadSensors.m new file mode 100644 index 0000000..ec97292 --- /dev/null +++ b/Control/ReadSensors.m @@ -0,0 +1,44 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function serving as an interface between the control framework +% of BioPatRec © and IH2 Azzurra by Prensilia SRL. The function allows +% to read the External Sensors from the hardware. Please refer +% to the IH2 Azzurra manual for more information about External Sensors +% +% --------------------------Updates-------------------------- +% 20xx-xx-xx / Author / Comment on update + +function data = ReadSensors(obj, SensorsIDs, SensorsNo) + +data = NaN*ones(1,SensorsNo); + +for n = 1:SensorsNo + + id = cell2mat(SensorsIDs(n).id); + fwrite(obj,'S'); + fwrite(obj,id); + + reply = char(fread(obj,1,'char')); + if strcmp(reply,id) + rx = fread(obj, 1, 'char'); + data(1,n) = rx; + else + % set(handles.t_msg,'String','Error on A'); + end +end \ No newline at end of file diff --git a/Control/ReadValidControlAlgs.m b/Control/ReadValidControlAlgs.m index 52909d8..b02fa3e 100644 --- a/Control/ReadValidControlAlgs.m +++ b/Control/ReadValidControlAlgs.m @@ -1,101 +1,101 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% controlAlgs = ReadValidControlAlgs() -% -% Function to read control algorithms and default parameters from the -% text file \Control\ValidControlAlgs.txt -% -% This function is used in the initialization of a control algorithm -% (InitControl.m). -% -% INPUTS: -% -% None -% -% OUTPUTS: -% -% controlAlg - a cell containing all available controlAlg structures, -% using their default parameters. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-10-08 / Joel Falk-Dahlin / Creation -% 2012-10-09 / Joel Falk-Dahlin / Changed so parameters can be floats -% 20xx-xx-xx / Author / Comment on update - -function controlAlgs = ReadValidControlAlgs() -fid = fopen('/Control/ValidControlAlgs.txt'); - -controlAlgs = []; - -% Read the fist line of file, making sure it is not empty -% or the end of file (-1) -tline = fgetl(fid); -while isempty(tline) && sum( tline == -1 ) == 0 - tline = fgetl(fid); -end - -while sum( tline == -1 ) == 0 - - % If { character is found, read ControlAlg structure - if strcmp('{',tline(1)) - currentControlAlg = struct; - tline = fgetl(fid); - name = textscan(tline,'name = %s'); - currentControlAlg.name = name{1}; - fncH = str2func(name{1}{1}); - currentControlAlg.fnc = fncH; - tline = fgetl(fid); - tline = fgetl(fid); - - % Read parameters and default values until } character is found - parameters = []; - while ~strcmp('}',tline(1)) - currentParameter = textscan(tline,'%s = %f'); - if isempty(currentParameter{2}) - currentParameter = textscan(tline,'%s = %s'); - end - - if isnumeric(currentParameter{1,2}) - parameters.(currentParameter{1,1}{1}) = double(currentParameter{1,2}); - elseif ischar(currentParameter{1,2}{1}) - parameters.(currentParameter{1,1}{1}) = currentParameter{1,2}{1}; - end - tline = fgetl(fid); - end - - % Set read parameters to current ControlAlg - currentControlAlg.parameters = parameters; - - % Store current ControlAlg - controlAlgs = [controlAlgs, {currentControlAlg}]; - - end - - tline = fgetl(fid); - while isempty(tline) && sum( tline == -1 ) == 0 - tline = fgetl(fid); - end - -end - -fclose(fid); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% controlAlgs = ReadValidControlAlgs() +% +% Function to read control algorithms and default parameters from the +% text file \Control\ValidControlAlgs.txt +% +% This function is used in the initialization of a control algorithm +% (InitControl.m). +% +% INPUTS: +% +% None +% +% OUTPUTS: +% +% controlAlg - a cell containing all available controlAlg structures, +% using their default parameters. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-08 / Joel Falk-Dahlin / Creation +% 2012-10-09 / Joel Falk-Dahlin / Changed so parameters can be floats +% 20xx-xx-xx / Author / Comment on update + +function controlAlgs = ReadValidControlAlgs() +fid = fopen('/Control/ValidControlAlgs.txt'); + +controlAlgs = []; + +% Read the fist line of file, making sure it is not empty +% or the end of file (-1) +tline = fgetl(fid); +while isempty(tline) && sum( tline == -1 ) == 0 + tline = fgetl(fid); +end + +while sum( tline == -1 ) == 0 + + % If { character is found, read ControlAlg structure + if strcmp('{',tline(1)) + currentControlAlg = struct; + tline = fgetl(fid); + name = textscan(tline,'name = %s'); + currentControlAlg.name = name{1}; + fncH = str2func(name{1}{1}); + currentControlAlg.fnc = fncH; + tline = fgetl(fid); + tline = fgetl(fid); + + % Read parameters and default values until } character is found + parameters = []; + while ~strcmp('}',tline(1)) + currentParameter = textscan(tline,'%s = %f'); + if isempty(currentParameter{2}) + currentParameter = textscan(tline,'%s = %s'); + end + + if isnumeric(currentParameter{1,2}) + parameters.(currentParameter{1,1}{1}) = double(currentParameter{1,2}); + elseif ischar(currentParameter{1,2}{1}) + parameters.(currentParameter{1,1}{1}) = currentParameter{1,2}{1}; + end + tline = fgetl(fid); + end + + % Set read parameters to current ControlAlg + currentControlAlg.parameters = parameters; + + % Store current ControlAlg + controlAlgs = [controlAlgs, {currentControlAlg}]; + + end + + tline = fgetl(fid); + while isempty(tline) && sum( tline == -1 ) == 0 + tline = fgetl(fid); + end + +end + +fclose(fid); + end \ No newline at end of file diff --git a/Control/SPC/motors.def b/Control/SPC/motors.def new file mode 100644 index 0000000..0c89706 --- /dev/null +++ b/Control/SPC/motors.def @@ -0,0 +1,3 @@ +A,0,60 +B,0,80 +C,0,20 \ No newline at end of file diff --git a/Control/SPC/movements.def b/Control/SPC/movements.def new file mode 100644 index 0000000..a724d57 --- /dev/null +++ b/Control/SPC/movements.def @@ -0,0 +1,25 @@ +0,Rest,0,0,0 0 +1,Open Hand,9,1,1 1 +2,Close Hand,9,0,1 0 +3,Flex Hand,7,0,0 1 +4,Ext Hand,7,1,0 0 +5,Pronation,8,0,2 0 +6,Supination,8,1,2 1 +24,Side Grip,13,1,0 0 +23,Fine Grip,12,1,0 0 +22,Agree,11,1,0 0 +17,Point,10,1,0 0 +7,Thumb Ext,5,1,0 0 +8,Thumb Flex,5,0,0 0 +19,Thumb Yaw Ext,6,1,0 0 +18,Thumb Yaw Flex,6,0,0 0 +20,Flex Elbow,15,1,3 0 +21,Ext Elbow,15,0,3 1 +9,Index Ext,4,1,0 0 +10,Index Flex,4,0,0 0 +11,Middle Ext,3,1,0 0 +12,Middle Flex,3,0,0 0 +13,Ring Ext,2,1,0 0 +14,Ring Flex,2,0,0 0 +15,Little Ext,1,1,0 0 +16,Little Flex,1,0,0 0 diff --git a/Control/SendMotorCommand.m b/Control/SendMotorCommand.m new file mode 100644 index 0000000..24b1b4b --- /dev/null +++ b/Control/SendMotorCommand.m @@ -0,0 +1,51 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to implement the Control Framework +% +% It waits until the ALC acknowledges the comunication, otherwise +% it exits with a failure (result = 0). +% +% --------------------------Updates-------------------------- +% 2015-07-07 / Enzo Mastinu / Created accordingly to the standardized +% framework. It sends the motor command to the +% external device. +% 20xx-xx-xx / Author / Comment + + +function result = SendMotorCommand(obj, type, index, dir, pwm) + % Send the message type + fwrite(obj,'M','char'); + % Send the motor type + fwrite(obj,type); + % Send PWM ID + fwrite(obj,index); + % Send direction + fwrite(obj,dir) + % Send speed/position + fwrite(obj,pwm) + + % If no problems where encountered, the ALC must return ID + reply = fread(obj,1); + if reply == index + result=1; + else + result=0; + return; + end +end diff --git a/Control/ShortMotorActivation.m b/Control/ShortMotorActivation.m index 8dedd93..5ecccbd 100644 --- a/Control/ShortMotorActivation.m +++ b/Control/ShortMotorActivation.m @@ -1,93 +1,93 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Funtion to activate the motors in a selected direction and by -% a selected time. It will only activate one motor. -% -% Using the comunication object (com) move the motor (motorDir) -% in direction (motorDir), at speed (movSpeed) for a time (movTime) -% -% The motor diretion is coded by integers (1,2,3...) -% motorDir = 1 = motor 1 forward -% motorDir = 2 = motor 1 backwars -% motorDir = 3 = motor 2 forward -% motorDir = 4 = motor 2 backwars -% motorDir = . = motor . . -% motorDir = . = motor . . -% -% Each motor is identified by A, B, ... and they are -% activated by two PWMs. -% --------------------------Updates-------------------------- -% 2011-11-17 / Max Ortiz / Creation - -function ShortMotorActivation(com, movSpeed, movTime, motorDir) - -switch motorDir - case 1 - pwmID = 'A'; - pwmA = 0; - pwmB = movSpeed; - case 2 - pwmID = 'A'; - pwmA = movSpeed; - pwmB = 0; - case 3 - pwmID = 'B'; - pwmA = 0; - pwmB = movSpeed; - case 4 - pwmID = 'B'; - pwmA = movSpeed; - pwmB = 0; - case 5 - pwmID = 'C'; - pwmA = 0; - pwmB = movSpeed; - case 6 - pwmID = 'C'; - pwmA = movSpeed; - pwmB = 0; - case 7 - pwmID = 'D'; - pwmA = 0; - pwmB = movSpeed; - case 8 - pwmID = 'D'; - pwmA = movSpeed; - pwmB = 0; - case 9 - pwmID = 'E'; - pwmA = 0; - pwmB = movSpeed; - case 10 - pwmID = 'E'; - pwmA = movSpeed; - pwmB = 0; -end - -% Send motor values -if Update2PWMusingSCI(com, pwmID, pwmA, pwmB); - % Wait for a little move to take place - pause(movTime); - % Stop the movement - Update2PWMusingSCI(com, pwmID, 0, 0); - %disp('Moved'); -else - disp('Failed'); - fclose(com.io); -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Funtion to activate the motors in a selected direction and by +% a selected time. It will only activate one motor. +% +% Using the comunication object (com) move the motor (motorDir) +% in direction (motorDir), at speed (movSpeed) for a time (movTime) +% +% The motor diretion is coded by integers (1,2,3...) +% motorDir = 1 = motor 1 forward +% motorDir = 2 = motor 1 backwars +% motorDir = 3 = motor 2 forward +% motorDir = 4 = motor 2 backwars +% motorDir = . = motor . . +% motorDir = . = motor . . +% +% Each motor is identified by A, B, ... and they are +% activated by two PWMs. +% --------------------------Updates-------------------------- +% 2011-11-17 / Max Ortiz / Creation + +function ShortMotorActivation(com, movSpeed, movTime, motorDir) + +switch motorDir + case 1 + pwmID = 'A'; + pwmA = 0; + pwmB = movSpeed; + case 2 + pwmID = 'A'; + pwmA = movSpeed; + pwmB = 0; + case 3 + pwmID = 'B'; + pwmA = 0; + pwmB = movSpeed; + case 4 + pwmID = 'B'; + pwmA = movSpeed; + pwmB = 0; + case 5 + pwmID = 'C'; + pwmA = 0; + pwmB = movSpeed; + case 6 + pwmID = 'C'; + pwmA = movSpeed; + pwmB = 0; + case 7 + pwmID = 'D'; + pwmA = 0; + pwmB = movSpeed; + case 8 + pwmID = 'D'; + pwmA = movSpeed; + pwmB = 0; + case 9 + pwmID = 'E'; + pwmA = 0; + pwmB = movSpeed; + case 10 + pwmID = 'E'; + pwmA = movSpeed; + pwmB = 0; +end + +% Send motor values +if Update2PWMusingSCI(com, pwmID, pwmA, pwmB); + % Wait for a little move to take place + pause(movTime); + % Stop the movement + Update2PWMusingSCI(com, pwmID, 0, 0); + %disp('Moved'); +else + disp('Failed'); + fclose(com.io); +end diff --git a/Control/StopMotor.m b/Control/StopMotor.m index cb50582..3c9a823 100644 --- a/Control/StopMotor.m +++ b/Control/StopMotor.m @@ -1,33 +1,33 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to prevent the motor to move -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-10 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - - - -function StopMotor(dio, ao) - - putvalue(dio.Line([1 2]), [1 1]); % Stop motor - if exist('ao','var') - putsample(ao,0); % Exit according to slider - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to prevent the motor to move +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-10 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + + +function StopMotor(dio, ao) + + putvalue(dio.Line([1 2]), [1 1]); % Stop motor + if exist('ao','var') + putsample(ao,0); % Exit according to slider + end diff --git a/Control/TestConnection.m b/Control/TestConnection.m new file mode 100644 index 0000000..a28687d --- /dev/null +++ b/Control/TestConnection.m @@ -0,0 +1,17 @@ +function result = TestConnection(com) + + % Open connection + if ~strcmp(com.status,'open') + fopen(com); + end + % Send test message + fwrite(com,'A','char'); + fwrite(com,'C','char') + replay = char(fread(com,1,'char')); + if strcmp(replay,'C'); + result = 1; + else + result = 0; + end + +end \ No newline at end of file diff --git a/Control/VREActivation.m b/Control/VREActivation.m index 889c047..d3c108f 100644 --- a/Control/VREActivation.m +++ b/Control/VREActivation.m @@ -1,60 +1,60 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to move the VRE in a selected direction, given distance and a -% given amount of time. -% -% The VRE communication object (vre_Com) will be used to move the DoF (movDof) -% in the specified direction (movDir) for the given distance (movDist) over -% the specified amount of time (movTime). -% -% The movDir is specified in the following manner; -% 1 - Extension -% 0 - Flexion -% -% movDof is a character indicating which DoF to activate. -% -% movDist is a percentage of distance to move. -% -% Each motor is identified by A, B, ... and they are -% activated by two PWMs. -% --------------------------Updates-------------------------- -% 2011-12-07 / Nichlas Sander / Creation -% 20xx-xx-xx / Author / Comment on update - -function tac = VREActivation(vre_Com, movSpeed, movTime, movDof, movDir, moveTac) - if ~moveTac - %Move the normal hand. - handMoved = 1; - else - %Move the TAC hand. - handMoved = 2; - end - if ~isnumeric(movSpeed) - [movSpeed, fraction] = rat(str2double(movSpeed)); - else - [movSpeed, fraction] = rat(movSpeed); - end - tac = 0; - fwrite(vre_Com,sprintf('%c%c%c%c%c',char(handMoved),char(movDof),char(movDir),char(movSpeed), char(fraction))); - ack = fread(vre_Com,1); - if ack == 't' - %If the user is within set allowance the returned ack == 't' - tac = 1; - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to move the VRE in a selected direction, given distance and a +% given amount of time. +% +% The VRE communication object (vre_Com) will be used to move the DoF (movDof) +% in the specified direction (movDir) for the given distance (movDist) over +% the specified amount of time (movTime). +% +% The movDir is specified in the following manner; +% 1 - Extension +% 0 - Flexion +% +% movDof is a character indicating which DoF to activate. +% +% movDist is a percentage of distance to move. +% +% Each motor is identified by A, B, ... and they are +% activated by two PWMs. +% --------------------------Updates-------------------------- +% 2011-12-07 / Nichlas Sander / Creation +% 20xx-xx-xx / Author / Comment on update + +function tac = VREActivation(vre_Com, movSpeed, movTime, movDof, movDir, moveTac) + if ~moveTac + %Move the normal hand. + handMoved = 1; + else + %Move the TAC hand. + handMoved = 2; + end + if ~isnumeric(movSpeed) + [movSpeed, fraction] = rat(str2double(movSpeed)); + else + [movSpeed, fraction] = rat(movSpeed); + end + tac = 0; + fwrite(vre_Com,sprintf('%c%c%c%c%c',char(handMoved),char(movDof),char(movDir),char(movSpeed), char(fraction))); + ack = fread(vre_Com,1); + if ack == 't' + %If the user is within set allowance the returned ack == 't' + tac = 1; + end end \ No newline at end of file diff --git a/Control/ValidControlAlgs.txt b/Control/ValidControlAlgs.txt index 344c328..ab18a27 100644 --- a/Control/ValidControlAlgs.txt +++ b/Control/ValidControlAlgs.txt @@ -1,28 +1,90 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% Create new ControlAlgorithms here -% -% Add parameters and default values that -% are to be read upon structure creation -% -% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -{ -name = None -Default parameters -} - -{ -name = MajorityVote -Default parameters - bufferSize = 3 -} - -{ -name = Ramp -Default parameters - downCount = 2 - rampLength = 10 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Create new PostProcessors here +% +% Add parameters and default values that +% are to be read upon object creation +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Standard Parameters +% ----------------------------------------------------- +% +% bufferSize - used by PostProcessor class to know +% how many data point to feed the current +% algorithm. It is set to 1 unless explictly +% set to something else. +% +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +{ +name = None +Default parameters +} + +{ +name = MajorityVote +Default parameters + bufferSize = 3 +} + +{ +name = MajorityVoteSimultaneous +Default parameters + bufferSize = 4 +} + +{ +name = BayesianFusion +Default parameters + bufferSize = 3 + weight = 1 +} + +{ +name = BufferOutput +Default parameters + bufferSize = 3 +} + +{ +name = Ramp +Default properties + downCount = 2 + rampLength = 10 +} + +{ +name = RampModified +Default properties + nMisclassComp = 2 + rampLength = 10 +} + +{ +name = RampModified2 +Default properties + nPredictionsToSteadyPhase = 3 + nMisclassificationCompensation = 2 + downCount = 2 + rampLength = 10 +} + +{ +name = RampModified3 +Default properties + bufferSize = 3 + downCount = 2 + rampLength = 10 +} + +{ +name = CombinedControl +Default parameters + controlOne = MajorityVoteSimultaneous + controlTwo = Ramp } \ No newline at end of file diff --git a/Comm/motor.m b/Control/motor.m similarity index 97% rename from Comm/motor.m rename to Control/motor.m index 6480282..3224605 100644 --- a/Comm/motor.m +++ b/Control/motor.m @@ -1,40 +1,40 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% A class used to keep track of which motor, pwmID/motorID, is what type of -% motor. This to differentiate between the ones in the hand and the ones -% for the pan/tilt. It also keeps track of the current position of the -% movement. -% --------------------------Updates-------------------------- -% 2012-05-25 / Nichlas Sander / Creation -% 20xx-xx-xx / Author / Comment on update - -classdef motor - properties - id - type - pct - end - methods - function obj = motor(motorId,motorType,position) - obj.id = motorId; - obj.type = motorType; - obj.pct = position; - end - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% A class used to keep track of which motor, pwmID/motorID, is what type of +% motor. This to differentiate between the ones in the hand and the ones +% for the pan/tilt. It also keeps track of the current position of the +% movement. +% --------------------------Updates-------------------------- +% 2012-05-25 / Nichlas Sander / Creation +% 20xx-xx-xx / Author / Comment on update + +classdef motor + properties + id + type + pct + end + methods + function obj = motor(motorId,motorType,position) + obj.id = motorId; + obj.type = motorType; + obj.pct = position; + end + end end \ No newline at end of file diff --git a/Comm/movement.m b/Control/movement.m similarity index 97% rename from Comm/movement.m rename to Control/movement.m index ba010c9..0b960c1 100644 --- a/Comm/movement.m +++ b/Control/movement.m @@ -1,55 +1,55 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% This is a class to keep track of the movements which are performed. It -% holds the id and direction needed to move the VRE, and the ids of the -% motors which need to be activated. -% --------------------------Updates-------------------------- -% 2012-05-25 / Nichlas Sander / Creation -% 20xx-xx-xx / Author / Comment on update - -classdef movement - properties - id - name - idVRE - vreDir - motor - end - - methods - function obj = movement(id,name,idVRE,direction,motor) - obj.id = id; - obj.name = name; - obj.idVRE = idVRE; - obj.vreDir = direction; - obj.motor = motor; - end - - function [Movements, Motors] = Activate(obj, VRE, Motor, Distance, Movements, Motors) - if(VRE) - %Activate VRE with correct Direction and Distance - disp('vre'); - end - if(Motor) - %Activate Motor with correct Direction and Distance - disp('motor'); - end - end - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% This is a class to keep track of the movements which are performed. It +% holds the id and direction needed to move the VRE, and the ids of the +% motors which need to be activated. +% --------------------------Updates-------------------------- +% 2012-05-25 / Nichlas Sander / Creation +% 20xx-xx-xx / Author / Comment on update + +classdef movement + properties + id + name + idVRE + vreDir + motor + end + + methods + function obj = movement(id,name,idVRE,direction,motor) + obj.id = id; + obj.name = name; + obj.idVRE = idVRE; + obj.vreDir = direction; + obj.motor = motor; + end + + function [Movements, Motors] = Activate(obj, VRE, Motor, Distance, Movements, Motors) + if(VRE) + %Activate VRE with correct Direction and Distance + disp('vre'); + end + if(Motor) + %Activate Motor with correct Direction and Distance + disp('motor'); + end + end + end end \ No newline at end of file diff --git a/Control/sensor.m b/Control/sensor.m new file mode 100644 index 0000000..7d5a7ab --- /dev/null +++ b/Control/sensor.m @@ -0,0 +1,35 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% A class used to keep track of sensors. +% --------------------------Updates-------------------------- +% 2012-05-25 / Sebastian Karlsson / Creation +% 20xx-xx-xx / Author / Comment on update + +classdef sensor + properties + id + name + end + methods + function obj = sensor(sensorId, sensorName) + obj.id = sensorId; + obj.name = sensorName; + end + end +end \ No newline at end of file diff --git a/GUI_BioPatRec.fig b/GUI_BioPatRec.fig index c613f2f..9193689 100644 Binary files a/GUI_BioPatRec.fig and b/GUI_BioPatRec.fig differ diff --git a/GUI_BioPatRec.m b/GUI_BioPatRec.m index da7c04f..31ca01f 100644 --- a/GUI_BioPatRec.m +++ b/GUI_BioPatRec.m @@ -45,7 +45,7 @@ % Edit the above text to modify the response to help GUI_BioPatRec -% Last Modified by GUIDE v2.5 22-Jun-2011 14:55:52 +% Last Modified by GUIDE v2.5 27-Jan-2015 08:52:57 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -107,13 +107,14 @@ function GUI_BioPatRec_OpeningFcn(hObject, eventdata, handles, varargin) varargout{1} = handles.output; -% --- Executes on button press in pb_Recordings. -function pb_Recordings_Callback(hObject, eventdata, handles) -% hObject handle to pb_Recordings (see GCBO) +% --- Executes on button press in pb_FastRecording. +function pb_FastRecording_Callback(hObject, eventdata, handles) +% hObject handle to pb_FastRecording (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) +fast = 1; +GUI_Recordings(fast); -GUI_Recordings; % --- Executes on button press in pb_PatRec. @@ -129,3 +130,19 @@ function pb_RecordingSession_Callback(hObject, eventdata, handles) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) GUI_RecordingSession; + + +% --- Executes on button press in pb_PatRec_Default. +function pb_PatRec_Default_Callback(hObject, eventdata, handles) +% hObject handle to pb_PatRec_Default (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +UseDefaults(handles.pb_PatRec_Default, 'false'); + + +% --- Executes on button press in pb_PatRec_DefaultSimul. +function pb_PatRec_DefaultSimul_Callback(hObject, eventdata, handles) +% hObject handle to pb_PatRec_DefaultSimul (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +UseDefaults(handles.pb_PatRec_DefaultSimul, 'true'); diff --git a/LICENSE.txt b/LICENSE.txt index f54ebdf..1490f54 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,21 +1,21 @@ - BioPatRec, Copyright (C) 2009 Max J. Ortiz C. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation, either version 3 of the - License, or any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - The full GNU GLP and LGPL licenses are available at - . - - This software was made open to the public with the hope that through - community contributions, we can all make the prosthetic developments - required to help patients in need. - - Everybody is welcome to sum efforts and contribute to this project. + BioPatRec, Copyright (C) 2009 Max J. Ortiz C. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 of the + License, or any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + The full GNU GLP and LGPL licenses are available at + . + + This software was made open to the public with the hope that through + community contributions, we can all make the prosthetic developments + required to help patients in need. + + Everybody is welcome to sum efforts and contribute to this project. Please contact: maxo@chalmers.se for more information. \ No newline at end of file diff --git a/PatRec/ANN/ANN_Accuracy.m b/PatRec/ANN/ANN_Accuracy.m index 44c3eab..6f779cc 100644 --- a/PatRec/ANN/ANN_Accuracy.m +++ b/PatRec/ANN/ANN_Accuracy.m @@ -1,74 +1,74 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Evaluates the accuracy for the ANN MLP -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ (maxo@chalmers.se) -% 2011-10-09 / Max Ortiz / -% - -function [accP rmse accN] = ANN_Accuracy(patRec, ANN, x, y) - - nSets = length(x(:,1)); - nM = size(y,2); % Number of movements - nSpM = nSets/nM ; % Number of sets per movement. - accN = zeros(nM,1); - accP = zeros(nM,1); - rmse = zeros(nM,1); - - if strcmp(ANN.Type,'Perceptron') - setIdx = 1; - for i = 1 : nM % Run through number of movements - cP = 0; - cN = 0; - mse = 0; - for j = 1 : nSpM % Run trhough the number of sets per movement - - %Normalize set - tSet = NormalizeSet(x(setIdx,:), patRec); - - % Evaluate ANN - ANN = EvaluateANN(tSet,ANN); - - % Decide output - rO = round(ANN.o); - - % Compute performance - cP = cP + sum(and(rO, y(setIdx,:)')); % Correct Patterns - cN = cN + sum((rO == y(setIdx,:)')); % correct neurons - - mse = mse + sum((ANN.o' - y(setIdx,:)).^2); %mean square error - - setIdx = setIdx + 1; - end - accP(i) = cP / nSpM; - accN(i) = cN / (nSpM * nM); - rmse(i) = sqrt(mse/(nSpM * nM)); % Root mean square error - end - - accP(end + 1) = mean(accP); - accN(end + 1) = mean(accN); - rmse(end + 1) = mean(rmse); - end - - % Validation routine - % 110920 MO NOTE: To be implemented - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Evaluates the accuracy for the ANN MLP +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ (maxo@chalmers.se) +% 2011-10-09 / Max Ortiz / +% + +function [accP rmse accN] = ANN_Accuracy(patRec, ANN, x, y) + + nSets = length(x(:,1)); + nM = size(y,2); % Number of movements + nSpM = nSets/nM ; % Number of sets per movement. + accN = zeros(nM,1); + accP = zeros(nM,1); + rmse = zeros(nM,1); + + if strcmp(ANN.Type,'Perceptron') + setIdx = 1; + for i = 1 : nM % Run through number of movements + cP = 0; + cN = 0; + mse = 0; + for j = 1 : nSpM % Run trhough the number of sets per movement + + %Normalize set + tSet = NormalizeSet(x(setIdx,:), patRec); + + % Evaluate ANN + ANN = EvaluateANN(tSet,ANN); + + % Decide output + rO = round(ANN.o); + + % Compute performance + cP = cP + sum(and(rO, y(setIdx,:)')); % Correct Patterns + cN = cN + sum((rO == y(setIdx,:)')); % correct neurons + + mse = mse + sum((ANN.o' - y(setIdx,:)).^2); %mean square error + + setIdx = setIdx + 1; + end + accP(i) = cP / nSpM; + accN(i) = cN / (nSpM * nM); + rmse(i) = sqrt(mse/(nSpM * nM)); % Root mean square error + end + + accP(end + 1) = mean(accP); + accN(end + 1) = mean(accN); + rmse(end + 1) = mean(rmse); + end + + % Validation routine + % 110920 MO NOTE: To be implemented + end \ No newline at end of file diff --git a/PatRec/ANN/ANN_Perceptron.m b/PatRec/ANN/ANN_Perceptron.m index 81b06ec..f9b760a 100644 --- a/PatRec/ANN/ANN_Perceptron.m +++ b/PatRec/ANN/ANN_Perceptron.m @@ -1,212 +1,221 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to train the Artificial Neural Network using the so called Back -% Propagation Algorithm -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-22 / Max Ortiz / Creation -% 2009-10-27 / Max Ortiz / Reset update -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ -% 2011-09-10 / Max Ortiz / Optimized for speed. Creationg of FastTestANN and -% FullTestANN routines -% 2012-04-01 / Max Ortiz / Change condition of passV to break training -% faster -% 20xx-xx-xx / Author / Comment on update - -function [ANN acc] = ANN_Perceptron(trSet, trOut, vSet, vOut, tType) - -%% Settings -graph2d = 1; % Show 2D graph -nRepF = 400; % Number of repeated rmse before restart -maxItr = 200; % Maximum number iterations -batchTr = 0; % Batch training (1) or sthocastic training (0) - -%% Initialize Artificial Neural Network, PSO and EA -nOn = size(trOut,2); % Number of output neurons -nIn = size(trSet,2); % Number of input neurons -nHn = [nIn nIn]; % Number of hiden neurons -%nHn = [nIn*2 nIn*2 nIn*2 nIn*2]; -%nHn = nIn*3; % Number of hiden neurons - -ANN = InitANN_Perceptron(nIn,nHn,nOn); - -% Randomize weights -+1 -ANN.w(1:max([nHn nIn nOn]),1:max([nHn nIn nOn]),1:length(nHn)+1) = -1 + rand(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1) .* 2; % weight -ANN.b(1:max(nHn),1:length(nHn)+1) = -1 + rand(max(nHn),length(nHn)+1) .* 2; % bias -tempANN = ANN; - -% For Brackpropagation -eta = 0.1; % learning rate -alpha = 0.1; -% For PSO -if strcmp(tType,'PSO') - PSO = InitPSO_MLP(ANN); -end - - -%% Train and test the ANN -% Variables for the run -rmse = zeros(1,maxItr); -sim = 0; -eval = 0; -passV = 0; % Pass test of the validation test -resetFlag = 0; -nTrSets = length(trOut(:,1)); - -if batchTr - nEvalRun = nTrSets; -else - nEvalRun = fix(nTrSets*.7); -end - -% Graph ------------------------- -if graph2d - hfig = figure; - hold on - set(hfig, 'DoubleBuffer','on'); - axis([1 maxItr 0 .3]); - hbestplot = plot(1:maxItr+1,zeros(1,maxItr+1)); - htext = text(50,0.2,sprintf('best: %4.3f',0.0)); - xlabel('simulations'); - ylabel('rmse'); - hold off - drawnow; -end -% -------------------------------- - -while sim <= maxItr && passV == 0 - sim = sim + 1; - - %% Training - % randomize the training sets - p = randperm(nTrSets); - % train ANN - if strcmp(tType,'Backpropagation') - for i = 1 : nEvalRun - ANN = EvaluateANN(trSet(p(i),:), ANN); - ANN = Backpropagation(trSet(p(i),:),trOut(p(i),:),ANN, eta, alpha); - end - elseif strcmp(tType,'PSO') - - [PSO, ANN] = PSO_MLP(PSO, ANN, trSet(p(1:nEvalRun),:),trOut(p(1:nEvalRun),:)); - - end - % Quantify the number of evaluations - eval = eval + nEvalRun; - - %% Validaion - [apV, rmse(sim)] = FastTestANN(ANN,vSet,vOut); - ANN.apV = apV; - ANN.fV = rmse(sim); - - % Save best bpANN so far - if ANN.apV >= tempANN.apV && ANN.fV <= tempANN.fV - tempANN = ANN; - end - - % Stop training if fitness is less than 0.1 and no progress is observed - if ANN.fV < 0.1 - if mean(rmse(sim-fix(sim/5):sim)) < mean(rmse(sim-fix(sim/15):sim)) - %if mean(rmse(sim-fix(sim/3):sim)) < mean(rmse(sim-fix(sim/15):sim)) - %if mean(rmse(sim-10:sim)) < mean(rmse(sim-5:sim)) % Not good for fast trainings - passV = 1; - end - end - - % Stop training if rmse is les than 1 for both Tr and V - % Validation of trSet - %[apTr, rmseTr] = FastTestANN(ANN,trSet,trOut); - %ANN.apTr = apTr; - %ANN.fTr = rmseTr; - %if ANN.fTr < 0.1 && ANN.fV < 0.1 - % passV = 1; - %end - - % Reset Back P - if sim >= 1 + nRepF * (resetFlag + 1) - if mean(rmse(sim-fix(nRepF/4):sim)) <= mean(rmse(sim-10:sim)) % Consider the last 1/4 of the training to - if ANN.fTr < 0.1 && (min(rmse(sim-5)) < 0.1 || ANN.apV > 90) - passV = 1; - else - %set(handles.t_msg,'String','Reset BP...'); - disp('Reset training...'); - resetFlag = resetFlag + 1; - %set(handles.t_bpRes,'String',num2str(resetFlag)); - ANN.w(1:max([nHn nIn nOn]),1:max([nHn nIn nOn]),1:length(nHn)+1) = -1 + rand(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1) .* 2; % weight - ANN.b(1:max(nHn),1:length(nHn)+1) = -1 + rand(max(nHn),length(nHn)+1) .* 2; % bias - end - end - end - - % 2D Graph - if graph2d - plotvector = get(hbestplot,'YData'); - plotvector(sim) = rmse(sim); - set(hbestplot,'YData',plotvector); - set(htext,'String',sprintf('best: %4.3f',tempANN.fV)); - drawnow; - end -end - -% Accept training if the fitness of the validation set < 0.1 and acc > 95 -if ANN.fV < 0.1 || ANN.apV > 95 - passV = 1; -end - -% Full TEST of the ANNs -ANN = tempANN; -[apTr, fTr, aTr] = FullTestANN(ANN,trSet,trOut); -ANN.aTr = aTr; -ANN.apTr = apTr; -ANN.fTr = fTr; - -[apV, fV, aV] = FullTestANN(ANN,vSet,vOut); -ANN.aV = aV; -ANN.apV = apV; -ANN.fV = fV; - -% General info on training performance -ANN.eval = eval; -ANN.sim = sim; - -% Return accuracy for the validation set -acc = apV; - -% Messages - -disp(['Simulations: ' num2str(sim)]); -disp(['General rmse: ' num2str(rmse(sim))]); -disp('RMES V: '); -disp(ANN.fV); -disp('Acc V: '); -disp(ANN.apV); - - -if passV - disp('%%%%%%%%%%% ANN training completed %%%%%%%%%%%%%'); -% set(handles.t_msg,'String','ANNs training done'); -else -% set(handles.t_msg,'String','ANNs training not successful'); - disp('%%%%%%%%%%% ANN training failed %%%%%%%%%%%%%'); -end - -close(hfig); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to train the Artificial Neural Network using the so called Back +% Propagation Algorithm +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-22 / Max Ortiz / Creation +% 2009-10-27 / Max Ortiz / Reset update +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% 2011-09-10 / Max Ortiz / Optimized for speed. Creationg of FastTestANN and +% FullTestANN routines +% 2012-04-01 / Max Ortiz / Change condition of passV to break training +% faster +% 20xx-xx-xx / Author / Comment on update + +function [ANN acc] = ANN_Perceptron(trSet, trOut, vSet, vOut, tType) + +%% Settings +graph2d = 1; % Show 2D graph +nRepF = 400; % Number of repeated rmse before restart +maxItr = 200; % Maximum number iterations +batchTr = 0; % Batch training (1) or sthocastic training (0) + +%% Initialize Artificial Neural Network, PSO and EA +nOn = size(trOut,2); % Number of output neurons +nIn = size(trSet,2); % Number of input neurons +nHn = [nIn nIn]; % Number of hiden neurons +%nHn = [nIn*2 nIn*2 nIn*2 nIn*2]; +%nHn = nIn*3; % Number of hiden neurons + +ANN = InitANN_Perceptron(nIn,nHn,nOn); + +% Randomize weights -+1 +ANN.w(1:max([nHn nIn nOn]),1:max([nHn nIn nOn]),1:length(nHn)+1) = -1 + rand(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1) .* 2; % weight +ANN.b(1:max(nHn),1:length(nHn)+1) = -1 + rand(max(nHn),length(nHn)+1) .* 2; % bias +tempANN = ANN; + +% For Brackpropagation +eta = 0.1; % learning rate +alpha = 0.1; +% For PSO +if strcmp(tType,'PSO') + PSO = InitPSO_MLP(ANN); +end + + +%% Train and test the ANN +% Variables for the run +rmse = zeros(1,maxItr); +sim = 0; +eval = 0; +passV = 0; % Pass test of the validation test +resetFlag = 0; +nTrSets = length(trOut(:,1)); + +if batchTr + nEvalRun = nTrSets; +else + nEvalRun = fix(nTrSets*.7); +end + +% Graph ------------------------- +if graph2d + hfig = figure; + hold on + set(hfig, 'DoubleBuffer','on'); + axis([1 maxItr 0 .3]); + hbestplot = plot(1:maxItr+1,zeros(1,maxItr+1)); + htext = text(50,0.2,sprintf('best: %4.3f',0.0)); + xlabel('simulations'); + ylabel('rmse'); + hold off + drawnow; +end +% -------------------------------- + +while sim <= maxItr && passV == 0 + sim = sim + 1; + + %% Training + % randomize the training sets + p = randperm(nTrSets); + % train ANN + if strcmp(tType,'Backpropagation') + for i = 1 : nEvalRun + ANN = EvaluateANN(trSet(p(i),:), ANN); + ANN = Backpropagation(trSet(p(i),:),trOut(p(i),:),ANN, eta, alpha); + end + elseif strcmp(tType,'PSO') + + [PSO, ANN] = PSO_MLP(PSO, ANN, trSet(p(1:nEvalRun),:),trOut(p(1:nEvalRun),:)); + + elseif strcmp(tType,'BP+PSO') + % Run backpropagation + for i = 1 : nEvalRun + ANN = EvaluateANN(trSet(p(i),:), ANN); + ANN = Backpropagation(trSet(p(i),:),trOut(p(i),:),ANN, eta, alpha); + end + % funtion to W2Pos + % Run PSO + [PSO, ANN] = PSO_MLP(PSO, ANN, trSet(p(1:nEvalRun),:),trOut(p(1:nEvalRun),:)); + end + % Quantify the number of evaluations + eval = eval + nEvalRun; + + %% Validaion + [apV, rmse(sim)] = FastTestANN(ANN,vSet,vOut); + ANN.apV = apV; + ANN.fV = rmse(sim); + + % Save best bpANN so far + if ANN.apV >= tempANN.apV && ANN.fV <= tempANN.fV + tempANN = ANN; + end + + % Stop training if fitness is less than 0.1 and no progress is observed + if ANN.fV < 0.1 + if mean(rmse(sim-fix(sim/5):sim)) < mean(rmse(sim-fix(sim/15):sim)) + %if mean(rmse(sim-fix(sim/3):sim)) < mean(rmse(sim-fix(sim/15):sim)) + %if mean(rmse(sim-10:sim)) < mean(rmse(sim-5:sim)) % Not good for fast trainings + passV = 1; + end + end + + % Stop training if rmse is les than 1 for both Tr and V + % Validation of trSet + %[apTr, rmseTr] = FastTestANN(ANN,trSet,trOut); + %ANN.apTr = apTr; + %ANN.fTr = rmseTr; + %if ANN.fTr < 0.1 && ANN.fV < 0.1 + % passV = 1; + %end + + % Reset Back P + if sim >= 1 + nRepF * (resetFlag + 1) + if mean(rmse(sim-fix(nRepF/4):sim)) <= mean(rmse(sim-10:sim)) % Consider the last 1/4 of the training to + if ANN.fTr < 0.1 && (min(rmse(sim-5)) < 0.1 || ANN.apV > 90) + passV = 1; + else + %set(handles.t_msg,'String','Reset BP...'); + disp('Reset training...'); + resetFlag = resetFlag + 1; + %set(handles.t_bpRes,'String',num2str(resetFlag)); + ANN.w(1:max([nHn nIn nOn]),1:max([nHn nIn nOn]),1:length(nHn)+1) = -1 + rand(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1) .* 2; % weight + ANN.b(1:max(nHn),1:length(nHn)+1) = -1 + rand(max(nHn),length(nHn)+1) .* 2; % bias + end + end + end + + % 2D Graph + if graph2d + plotvector = get(hbestplot,'YData'); + plotvector(sim) = rmse(sim); + set(hbestplot,'YData',plotvector); + set(htext,'String',sprintf('best: %4.3f',tempANN.fV)); + drawnow; + end +end + +% Accept training if the fitness of the validation set < 0.1 and acc > 95 +if ANN.fV < 0.1 || ANN.apV > 95 + passV = 1; +end + +% Full TEST of the ANNs +ANN = tempANN; +[apTr, fTr, aTr] = FullTestANN(ANN,trSet,trOut); +ANN.aTr = aTr; +ANN.apTr = apTr; +ANN.fTr = fTr; + +[apV, fV, aV] = FullTestANN(ANN,vSet,vOut); +ANN.aV = aV; +ANN.apV = apV; +ANN.fV = fV; + +% General info on training performance +ANN.eval = eval; +ANN.sim = sim; + +% Return accuracy for the validation set +acc = apV; + +% Messages + +disp(['Simulations: ' num2str(sim)]); +disp(['General rmse: ' num2str(rmse(sim))]); +disp('RMES V: '); +disp(ANN.fV); +disp('Acc V: '); +disp(ANN.apV); + + +if passV + disp('%%%%%%%%%%% ANN training completed %%%%%%%%%%%%%'); +% set(handles.t_msg,'String','ANNs training done'); +else +% set(handles.t_msg,'String','ANNs training not successful'); + disp('%%%%%%%%%%% ANN training failed %%%%%%%%%%%%%'); +end + +close(hfig); + diff --git a/PatRec/ANN/Backp/Backpropagation.m b/PatRec/ANN/Backp/Backpropagation.m index 4ab7b73..85ef7e5 100644 --- a/PatRec/ANN/Backp/Backpropagation.m +++ b/PatRec/ANN/Backp/Backpropagation.m @@ -1,73 +1,109 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to compute the local gradient for the back-propagation algorithm -% and back-propagate -% The right most index is the layer -% The middle is the neuron -% The left most is the input -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ - -function ANN = Backpropagation(in, out, ANN, eta, alpha) - - if strcmp(ANN.Type,'Perceptron') - ll = length(ANN.nHn); - ol = ll + 1; - - %Output layer neuron - for i=1:ANN.nOn - % Local gradient - ANN.lg(i,ol) = ANN.a .* (out(i) - ANN.o(i)) .* ANN.o(i) .* (1 - ANN.o(i)); - % Weight correction - %ANN.dw(1:ll,i,ol) = (alpha .* ANN.dw(1:ll,i,ol)) + (eta .* ANN.lg(i,ol) .* ANN.phi(1:ll,ll)); - ANN.dw(:,i,ol) = (alpha .* ANN.dw(:,i,ol)) + (eta .* ANN.lg(i,ol) .* ANN.phi(:,ll)); - ANN.db(i,ol) = (alpha .* ANN.db(i,ol)) + (eta .* ANN.lg(i,ol)); - end - %ANN.w(1:ll,:,ol) = ANN.w(1:ll,:,ol) + ANN.dw(1:ll,:,ol); - ANN.w(:,:,ol) = ANN.w(:,:,ol) + ANN.dw(:,:,ol); - ANN.b(:,ol) = ANN.b(:,ol) + ANN.db(:,ol); - - %Hiden Layers Layer - for l=ll : -1 : 2 - for i=1:ANN.nHn(l) - % Local gradient - ANN.lg(i,l) = ANN.a * (1 - ANN.phi(i,l)) * ANN.phi(i,l) * sum(ANN.lg(:,l+1) .* ANN.w(i,:,l+1)'); - % Weight correction - ANN.dw(:,i,l) = (alpha .* ANN.dw(:,i,l)) + (eta .* ANN.lg(i,l) .* ANN.phi(:,l-1)); - ANN.db(i,l) = (alpha .* ANN.db(i,l)) + (eta .* ANN.lg(i,l)); - ANN.w(:,i,l) = ANN.w(:,i,l) + ANN.dw(:,i,l); - ANN.b(i,l) = ANN.b(i,l) + ANN.db(i,l); - end - end - - %First layer neuron - l = 1; - lin = length(in); - for i=1:ANN.nHn(l) - % Local gradient - ANN.lg(i,l) = ANN.a * (1 - ANN.phi(i,l)) * ANN.phi(i,l) * sum(ANN.lg(:,l+1) .* ANN.w(i,:,l+1)'); - % Weight correction - ANN.dw(1:lin,i,l) = (alpha .* ANN.dw(1:lin,i,l)) + (eta .* ANN.lg(i,l) .* in'); - ANN.db(i,l) = (alpha .* ANN.db(i,l)) + (eta .* ANN.lg(i,l)); - ANN.w(:,i,l) = ANN.w(:,i,l) + ANN.dw(:,i,l); - ANN.b(i,l) = ANN.b(i,l) + ANN.db(i,l); - end - end \ No newline at end of file +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to compute the local gradient for the back-propagation algorithm +% and back-propagate +% The right most index is the layer +% The middle is the neuron +% The left most is the input +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% 2013-01-15 / Joel Falk-Dahlin / Vectorized calculations, now faster + +function ANN = Backpropagation(in, out, ANN, eta, alpha) + + if strcmp(ANN.Type,'Perceptron') + ll = length(ANN.nHn); + ol = ll + 1; + + %Output layer neuron + % Local gradient + ANN.lg(1:ANN.nOn,ol) = ANN.a .* (out' - ANN.o) .* ANN.o .* (1 - ANN.o); + % Weight correction + ANN.dw(:,1:ANN.nOn,ol) = (alpha .* ANN.dw(:,1:ANN.nOn,ol)) + (eta .* bsxfun(@times, ANN.lg(1:ANN.nOn,ol)', ANN.phi(:,ll)) ); + ANN.db(1:ANN.nOn,ol) = (alpha .* ANN.db(1:ANN.nOn,ol)) + (eta .* ANN.lg(1:ANN.nOn,ol)); + ANN.w(:,:,ol) = ANN.w(:,:,ol) + ANN.dw(:,:,ol); + ANN.b(:,ol) = ANN.b(:,ol) + ANN.db(:,ol); + + % OLD CODE + %Output layer neuron +% for i=1:ANN.nOn +% %Local gradient +% ANN.lg(i,ol) = ANN.a .* (out(i) - ANN.o(i)) .* ANN.o(i) .* (1 - ANN.o(i)); +% %Weight correction +% ANN.dw(1:ll,i,ol) = (alpha .* ANN.dw(1:ll,i,ol)) + (eta .* ANN.lg(i,ol) .* ANN.phi(1:ll,ll)); +% ANN.dw(:,i,ol) = (alpha .* ANN.dw(:,i,ol)) + (eta .* ANN.lg(i,ol) .* ANN.phi(:,ll)); +% ANN.db(i,ol) = (alpha .* ANN.db(i,ol)) + (eta .* ANN.lg(i,ol)); +% end +% ANN.w(1:ll,:,ol) = ANN.w(1:ll,:,ol) + ANN.dw(1:ll,:,ol); +% ANN.w(:,:,ol) = ANN.w(:,:,ol) + ANN.dw(:,:,ol); +% ANN.b(:,ol) = ANN.b(:,ol) + ANN.db(:,ol); + + + %Hiden Layers Layer + for l=ll : -1 : 2 + + % Local gradient + ANN.lg(1:ANN.nHn(l),l) = ANN.a * (1 - ANN.phi(1:ANN.nHn(l),l)) .* ANN.phi(1:ANN.nHn(l),l) .* ( ANN.w(1:ANN.nHn(l),:,l+1) * ANN.lg(:,l+1) ); + % Weight correction + ANN.dw(:,1:ANN.nHn(l),l) = (alpha .* ANN.dw(:,1:ANN.nHn(l),l)) + (eta .* bsxfun(@times, ANN.lg(1:ANN.nHn(l),l)', ANN.phi(:,l-1)) ); + ANN.db(1:ANN.nHn(l),l) = (alpha .* ANN.db(1:ANN.nHn(l),l)) + (eta .* ANN.lg(1:ANN.nHn(l),l)); + ANN.w(:,1:ANN.nHn(l),l) = ANN.w(:,1:ANN.nHn(l),l) + ANN.dw(:,1:ANN.nHn(l),l); + ANN.b(1:ANN.nHn(l),l) = ANN.b(1:ANN.nHn(l),l) + ANN.db(1:ANN.nHn(l),l); + + % OLD CODE +% for i=1:ANN.nHn(l) +% % Local gradient +% ANN.lg(i,l) = ANN.a * (1 - ANN.phi(i,l)) * ANN.phi(i,l) * sum(ANN.lg(:,l+1) .* ANN.w(i,:,l+1)'); +% % Weight correction +% ANN.dw(:,i,l) = (alpha .* ANN.dw(:,i,l)) + (eta .* ANN.lg(i,l) .* ANN.phi(:,l-1)); +% ANN.db(i,l) = (alpha .* ANN.db(i,l)) + (eta .* ANN.lg(i,l)); +% ANN.w(:,i,l) = ANN.w(:,i,l) + ANN.dw(:,i,l); +% ANN.b(i,l) = ANN.b(i,l) + ANN.db(i,l); +% end + + end + + %First layer neuron + l = 1; + lin = length(in); + + %Local gradient + ANN.lg(1:ANN.nHn(l),l) = ANN.a * (1 - ANN.phi(1:ANN.nHn(l),l)) .* ANN.phi(1:ANN.nHn(l),l) .* (ANN.w(1:ANN.nHn(l),:,l+1) * ANN.lg(:,l+1)); + %Weight correction + ANN.dw(1:lin,1:ANN.nHn(l),l) = (alpha .* ANN.dw(1:lin,1:ANN.nHn(l),l)) + (eta .* bsxfun(@times, ANN.lg(1:ANN.nHn(l),l)', in' ) ); + ANN.db(1:ANN.nHn(l),l) = (alpha .* ANN.db(1:ANN.nHn(l),l)) + (eta .* ANN.lg(1:ANN.nHn(l),l)); + ANN.w(:,1:ANN.nHn(l),l) = ANN.w(:,1:ANN.nHn(l),l) + ANN.dw(:,1:ANN.nHn(l),l); + ANN.b(1:ANN.nHn(l),l) = ANN.b(1:ANN.nHn(l),l) + ANN.db(1:ANN.nHn(l),l); + + % OLD CODE +% for i=1:ANN.nHn(l) +% % Local gradient +% ANN.lg(i,l) = ANN.a * (1 - ANN.phi(i,l)) * ANN.phi(i,l) * sum(ANN.lg(:,l+1) .* ANN.w(i,:,l+1)'); +% % Weight correction +% ANN.dw(1:lin,i,l) = (alpha .* ANN.dw(1:lin,i,l)) + (eta .* ANN.lg(i,l) .* in'); +% ANN.db(i,l) = (alpha .* ANN.db(i,l)) + (eta .* ANN.lg(i,l)); +% ANN.w(:,i,l) = ANN.w(:,i,l) + ANN.dw(:,i,l); +% ANN.b(i,l) = ANN.b(i,l) + ANN.db(i,l); +% end + end + +end + \ No newline at end of file diff --git a/PatRec/ANN/Eval/EvaluateANN.m b/PatRec/ANN/Eval/EvaluateANN.m index 1ab2835..757209b 100644 --- a/PatRec/ANN/Eval/EvaluateANN.m +++ b/PatRec/ANN/Eval/EvaluateANN.m @@ -1,80 +1,80 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Evaluation of the ANN which comprises the sum of the weights and bias per -% neuron. The neuron output is given by the activation function (Phi). -% -% Activation function: Log-sigmoid or logistic function which provides an -% output between 0 and 1. -% -% ANN.a Amplitude of the activation function -% ANN.v Vector containing th sum of neuron inputs -% ANN.phi Activation function -% ANN.o ANN output per neuron using the activation function Phi -% -% ------------------------- Updates & Contributors ------------------------ -% 2009-07-22 / Max Ortiz / Modify to hanlde the new ANN MLP -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ -% 2011-10-09 / Max Ortiz / Improved documentation -% 2011-11-23 / Joel Falk-Dahlin / Vectorized implementation for great speed -% improvement - -function ANN = EvaluateANN(inputs, ANN) - - if strcmp(ANN.Type,'Perceptron') - ll = length(ANN.nHn); - - %First Inpute Layer - - ANN.v(:,1) = ANN.w(1:length(inputs),:,1)'*inputs'+ANN.b(:,1); - ANN.phi(:,1) = 1 ./ (1 + exp(-ANN.a .* ANN.v(:,1))); - -% for i=1:ANN.nHn(1) -% ANN.v(i,1) = sum(ANN.w(1:length(inputs),i,1) .* inputs') + ANN.b(i,1); % Induced local field -% ANN.phi(i,1) = 1 /(1 + exp(-ANN.a * ANN.v(i,1))); -% end - - %Hiden Layers Layer - for j=2:ll - - ANN.v(:,j) = ANN.w(1:ANN.nHn(j-1),:,j)' * ANN.phi(1:ANN.nHn(j-1),j-1) + ANN.b(:,j); - ANN.phi(:,j) = 1 ./ (1 + exp(-ANN.a .* ANN.v(:,j))); - -% for i=1:ANN.nHn(j) -% ANN.v(i,j) = sum(ANN.w(1:ANN.nHn(j-1),i,j) .* ANN.phi(1:ANN.nHn(j-1),j-1)) + ANN.b(i,j); % Induced local field -% ANN.phi(i,j) = 1 /(1 + exp(-ANN.a * ANN.v(i,j))); -% end - - end - - %Output layer neuron - ol = ll + 1; - - ANN.v(:,ol) = ANN.w(1:ANN.nHn(end),:,ol)' * ANN.phi(1:ANN.nHn(end),ll) + ANN.b(:,ol); - ANN.o = 1 ./ (1 + exp(-ANN.a .* ANN.v(1:ANN.nOn,ol))); - -% for i=1:ANN.nOn -% ANN.v(i,ol) = sum(ANN.w(1:ANN.nHn(end),i,ol) .* ANN.phi(1:ANN.nHn(end),ll)) + ANN.b(i,ol); % Induced local field -% ANN.o(i) = 1 /(1 + exp(-ANN.a * ANN.v(i,ol))); -% end - - elseif strcmp(ANN.Type,'Other') - - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Evaluation of the ANN which comprises the sum of the weights and bias per +% neuron. The neuron output is given by the activation function (Phi). +% +% Activation function: Log-sigmoid or logistic function which provides an +% output between 0 and 1. +% +% ANN.a Amplitude of the activation function +% ANN.v Vector containing th sum of neuron inputs +% ANN.phi Activation function +% ANN.o ANN output per neuron using the activation function Phi +% +% ------------------------- Updates & Contributors ------------------------ +% 2009-07-22 / Max Ortiz / Modify to hanlde the new ANN MLP +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% 2011-10-09 / Max Ortiz / Improved documentation +% 2011-11-23 / Joel Falk-Dahlin / Vectorized implementation for great speed +% improvement + +function ANN = EvaluateANN(inputs, ANN) + + if strcmp(ANN.Type,'Perceptron') + ll = length(ANN.nHn); + + %First Inpute Layer + + ANN.v(:,1) = ANN.w(1:length(inputs),:,1)'*inputs'+ANN.b(:,1); + ANN.phi(:,1) = 1 ./ (1 + exp(-ANN.a .* ANN.v(:,1))); + +% for i=1:ANN.nHn(1) +% ANN.v(i,1) = sum(ANN.w(1:length(inputs),i,1) .* inputs') + ANN.b(i,1); % Induced local field +% ANN.phi(i,1) = 1 /(1 + exp(-ANN.a * ANN.v(i,1))); +% end + + %Hiden Layers Layer + for j=2:ll + + ANN.v(:,j) = ANN.w(1:ANN.nHn(j-1),:,j)' * ANN.phi(1:ANN.nHn(j-1),j-1) + ANN.b(:,j); + ANN.phi(:,j) = 1 ./ (1 + exp(-ANN.a .* ANN.v(:,j))); + +% for i=1:ANN.nHn(j) +% ANN.v(i,j) = sum(ANN.w(1:ANN.nHn(j-1),i,j) .* ANN.phi(1:ANN.nHn(j-1),j-1)) + ANN.b(i,j); % Induced local field +% ANN.phi(i,j) = 1 /(1 + exp(-ANN.a * ANN.v(i,j))); +% end + + end + + %Output layer neuron + ol = ll + 1; + + ANN.v(:,ol) = ANN.w(1:ANN.nHn(end),:,ol)' * ANN.phi(1:ANN.nHn(end),ll) + ANN.b(:,ol); + ANN.o = 1 ./ (1 + exp(-ANN.a .* ANN.v(1:ANN.nOn,ol))); + +% for i=1:ANN.nOn +% ANN.v(i,ol) = sum(ANN.w(1:ANN.nHn(end),i,ol) .* ANN.phi(1:ANN.nHn(end),ll)) + ANN.b(i,ol); % Induced local field +% ANN.o(i) = 1 /(1 + exp(-ANN.a * ANN.v(i,ol))); +% end + + elseif strcmp(ANN.Type,'Other') + + end \ No newline at end of file diff --git a/PatRec/ANN/Eval/FastTestANN.m b/PatRec/ANN/Eval/FastTestANN.m index a00fb8b..384759b 100644 --- a/PatRec/ANN/Eval/FastTestANN.m +++ b/PatRec/ANN/Eval/FastTestANN.m @@ -1,65 +1,65 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Purpose: -% -% Variables: -% accP Accuracy Patterns (in 100%) -% rmse Root mean square error -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Author / Creation -% 2011-09-20 /Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ -% - -function [accP rmse] = FastTestANN(ANN,x,y) - - nSets = length(x(:,1)); - nOuts = ANN.nOn; - %Get the deviation - d = zeros(nSets,nOuts); % This vector is used to validate output - - - dsum=0; - for i = 1:nSets - ANN = EvaluateANN(x(i,:),ANN); - d(i,:)= ANN.o; - dsum = dsum + sum((d(i,:)-y(i,:)).^2); - end - - % Correct neuron firing only / total sets - rD = round(d); - rY = round(y); - er = find(sum(abs(rD-rY),2) >= 1); %Find the index of incorrect patterns - accP = (1 - (length(er)/nSets)) * 100; - - % An alternative algorithm to compute pattern accuracy - % eq1 = (rD == rY); - % eq2 = sum(eq1,2); - % vY(1:nSets) = nOuts; - % eq3 = (eq2' == vY); - % ap = (sum(eq3)/nSets) * 100; - - rmse = sqrt(dsum/(nSets*nOuts)); % Root mean squere error - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Purpose: +% +% Variables: +% accP Accuracy Patterns (in 100%) +% rmse Root mean square error +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Author / Creation +% 2011-09-20 /Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% + +function [accP rmse] = FastTestANN(ANN,x,y) + + nSets = length(x(:,1)); + nOuts = ANN.nOn; + %Get the deviation + d = zeros(nSets,nOuts); % This vector is used to validate output + + + dsum=0; + for i = 1:nSets + ANN = EvaluateANN(x(i,:),ANN); + d(i,:)= ANN.o; + dsum = dsum + sum((d(i,:)-y(i,:)).^2); + end + + % Correct neuron firing only / total sets + rD = round(d); + rY = round(y); + er = find(sum(abs(rD-rY),2) >= 1); %Find the index of incorrect patterns + accP = (1 - (length(er)/nSets)) * 100; + + % An alternative algorithm to compute pattern accuracy + % eq1 = (rD == rY); + % eq2 = sum(eq1,2); + % vY(1:nSets) = nOuts; + % eq3 = (eq2' == vY); + % ap = (sum(eq3)/nSets) * 100; + + rmse = sqrt(dsum/(nSets*nOuts)); % Root mean squere error + + + + \ No newline at end of file diff --git a/PatRec/ANN/Eval/FitnessANN.m b/PatRec/ANN/Eval/FitnessANN.m index ffed5da..dc5ed23 100644 --- a/PatRec/ANN/Eval/FitnessANN.m +++ b/PatRec/ANN/Eval/FitnessANN.m @@ -1,51 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Particle Validation or in this case, validation of the ANN's weights -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2010-05-16 / Max Ortiz / New version to return both Accuracies -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ -% 2012-06-02 / Max Ortiz / Created from ValidateANN - -function fitness = FitnessANN(ANN,x,y) - - nSets = length(x(:,1)); - nOuts = ANN.nOn; - - %Get the deviation - d = zeros(nSets,nOuts); % This vector is used to validate output - - dsum=0; - for i = 1:nSets - ANN = EvaluateANN(x(i,:),ANN); - d(i,:)= ANN.o; - dsum = dsum + sum((d(i,:)-y(i,:)).^2); - end - - fitness = sqrt(dsum/(nSets*nOuts)); % for minimum - %fitness = 1/(sqrt(dsum/Nsets)) for maximum - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Particle Validation or in this case, validation of the ANN's weights +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2010-05-16 / Max Ortiz / New version to return both Accuracies +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% 2012-06-02 / Max Ortiz / Created from ValidateANN + +function fitness = FitnessANN(ANN,x,y) + + nSets = length(x(:,1)); + nOuts = ANN.nOn; + + %Get the deviation + d = zeros(nSets,nOuts); % This vector is used to validate output + + dsum=0; + for i = 1:nSets + ANN = EvaluateANN(x(i,:),ANN); + d(i,:)= ANN.o; + dsum = dsum + sum((d(i,:)-y(i,:)).^2); + end + + fitness = sqrt(dsum/(nSets*nOuts)); % for minimum + %fitness = 1/(sqrt(dsum/Nsets)) for maximum + + + + + \ No newline at end of file diff --git a/PatRec/ANN/Eval/FullTestANN.m b/PatRec/ANN/Eval/FullTestANN.m index 4a3fdcc..dbbce9f 100644 --- a/PatRec/ANN/Eval/FullTestANN.m +++ b/PatRec/ANN/Eval/FullTestANN.m @@ -1,66 +1,66 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% accN Accuracy Neurons -% accP Accuracy Patterns -% rmse Root mean square error -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ -% - -function [accP rmse accN] = FullTestANN(ANN,x,y) - - nSets = length(x(:,1)); - nM = size(y,2); % Number of movements - nSpM = nSets/nM ; % Number of sets per movement. - accN = zeros(nM,1); - accP = zeros(nM,1); - rmse = zeros(nM,1); - - setIdx = 1; - for i = 1 : nM % Run through number of movements - cP = 0; - cN = 0; - mse = 0; - for j = 1 : nSpM % Run trhough the number of sets per movement - ANN = EvaluateANN(x(setIdx,:),ANN); - rO = round(ANN.o); - cP = cP + sum(and(rO, y(setIdx,:)')); % Correct Patterns - cN = cN + sum((rO == y(setIdx,:)')); % correct neurons - - mse = mse + sum((ANN.o' - y(setIdx,:)).^2); %mean square error - - setIdx = setIdx + 1; - end - accP(i) = cP / nSpM; - accN(i) = cN / (nSpM * nM); - rmse(i) = sqrt(mse/(nSpM * nM)); % Root mean square error - end - - accP(end + 1) = mean(accP); - accN(end + 1) = mean(accN); - rmse(end + 1) = mean(rmse); - - % Validation routine - % 110920 MO NOTE: To be implemented - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% accN Accuracy Neurons +% accP Accuracy Patterns +% rmse Root mean square error +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% + +function [accP rmse accN] = FullTestANN(ANN,x,y) + + nSets = length(x(:,1)); + nM = size(y,2); % Number of movements + nSpM = nSets/nM ; % Number of sets per movement. + accN = zeros(nM,1); + accP = zeros(nM,1); + rmse = zeros(nM,1); + + setIdx = 1; + for i = 1 : nM % Run through number of movements + cP = 0; + cN = 0; + mse = 0; + for j = 1 : nSpM % Run trhough the number of sets per movement + ANN = EvaluateANN(x(setIdx,:),ANN); + rO = round(ANN.o); + cP = cP + sum(and(rO, y(setIdx,:)')); % Correct Patterns + cN = cN + sum((rO == y(setIdx,:)')); % correct neurons + + mse = mse + sum((ANN.o' - y(setIdx,:)).^2); %mean square error + + setIdx = setIdx + 1; + end + accP(i) = cP / nSpM; + accN(i) = cN / (nSpM * nM); + rmse(i) = sqrt(mse/(nSpM * nM)); % Root mean square error + end + + accP(end + 1) = mean(accP); + accN(end + 1) = mean(accN); + rmse(end + 1) = mean(rmse); + + % Validation routine + % 110920 MO NOTE: To be implemented + \ No newline at end of file diff --git a/PatRec/ANN/Eval/ValidateANN.m b/PatRec/ANN/Eval/ValidateANN.m index 111dc4e..fa120d1 100644 --- a/PatRec/ANN/Eval/ValidateANN.m +++ b/PatRec/ANN/Eval/ValidateANN.m @@ -1,75 +1,75 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Particle Validation or in this case, validation of the ANN's weights -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2010-05-16 / Max Ortiz / New vertion to return both Accuracies -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ - -function [v, fitness, d, an, ap] = ValidateANN(ANN,x,y) - - nSets = length(x(:,1)); - nOuts = ANN.nOn; - - %Get the deviation - d = zeros(nSets,nOuts); % This vector is used to validate output - - %Assume that it startes validated - v = 1; - - - dsum=0; - for i = 1:nSets - ANN = EvaluateANN(x(i,:),ANN); - d(i,:)= ANN.o; - dsum = dsum + sum((d(i,:)-y(i,:)).^2); - end - - if ~isempty(find(abs(d-y) > 0.45,1)) - v=0; - end - - rD = round(d); - rY = round(y); - - % Each output firing / total firings - an = (1 - (length(find(rD-rY)) / (size(d,1)*size(d,2)))) * 100; - - % Correct neuron firing only / total sets - er = find(sum(abs(rD-rY),2) >= 1); - ap = (1 - (length(er)/nSets)) * 100; - - % An alternative algorithm to compute pattern accuracy - % eq1 = (rD == rY); - % eq2 = sum(eq1,2); - % vY(1:nSets) = nOuts; - % eq3 = (eq2' == vY); - % ap = (sum(eq3)/nSets) * 100; - - fitness = sqrt(dsum/(nSets*nOuts)); % for minimum - %fitness = 1/(sqrt(dsum/Nsets)) for maximum - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Particle Validation or in this case, validation of the ANN's weights +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2010-05-16 / Max Ortiz / New vertion to return both Accuracies +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ + +function [v, fitness, d, an, ap] = ValidateANN(ANN,x,y) + + nSets = length(x(:,1)); + nOuts = ANN.nOn; + + %Get the deviation + d = zeros(nSets,nOuts); % This vector is used to validate output + + %Assume that it startes validated + v = 1; + + + dsum=0; + for i = 1:nSets + ANN = EvaluateANN(x(i,:),ANN); + d(i,:)= ANN.o; + dsum = dsum + sum((d(i,:)-y(i,:)).^2); + end + + if ~isempty(find(abs(d-y) > 0.45,1)) + v=0; + end + + rD = round(d); + rY = round(y); + + % Each output firing / total firings + an = (1 - (length(find(rD-rY)) / (size(d,1)*size(d,2)))) * 100; + + % Correct neuron firing only / total sets + er = find(sum(abs(rD-rY),2) >= 1); + ap = (1 - (length(er)/nSets)) * 100; + + % An alternative algorithm to compute pattern accuracy + % eq1 = (rD == rY); + % eq2 = sum(eq1,2); + % vY(1:nSets) = nOuts; + % eq3 = (eq2' == vY); + % ap = (sum(eq3)/nSets) * 100; + + fitness = sqrt(dsum/(nSets*nOuts)); % for minimum + %fitness = 1/(sqrt(dsum/Nsets)) for maximum + + + + + \ No newline at end of file diff --git a/PatRec/ANN/InitANN_Perceptron.m b/PatRec/ANN/InitANN_Perceptron.m index 3773236..4abc8e1 100644 --- a/PatRec/ANN/InitANN_Perceptron.m +++ b/PatRec/ANN/InitANN_Perceptron.m @@ -1,64 +1,64 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to initialize the Artificial Neural Network -% Note: The struct and evaluation algorithms could be shorter but less -% comprehensible -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-23 / Max Ortiz / Creation -% 2009-11-09 / Max Ortiz / Initialization of v, phi and lg to consider a number -% of output higer than the number of neurons in the hiden layer -% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous -% implementation for EMG_AQ -% 20xx-xx-xx / Author / Comment on update - -function ANN = InitANN_Perceptron(nIn,nHn,nOn) - -ANN.Type = 'Perceptron'; -ANN.nIn = nIn; -ANN.nHn = nHn; -ANN.nOn = nOn; -ANN.w = zeros(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1); % weight -ANN.b = zeros(max([nHn nOn]),length(nHn)+1); % bias -ANN.o = zeros(nOn,1); % output -ANN.a = 1; % amplitud for activation function - -% Back Propagation Algorithm -ANN.v = zeros(max([nHn nOn]),length(nHn)+1); % induced activation field -ANN.phi = zeros(max([nHn nOn]),length(nHn)); % activation function or output -ANN.lg = zeros(max([nHn nOn]),length(nHn)+1); % local gradient (lower delta) -ANN.dw = zeros(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1); % capital delta weight or change in weight -ANN.db = zeros(max([nHn nOn]),length(nHn)+1); % capital delta weight or change in weight of bias - -% Evolutionary Algorithm and PSO -ANN.aTr = 0; -ANN.apTr = 0; -ANN.fTr = inf; - -ANN.aV = 0; -ANN.apV = 0; -ANN.fV = inf; - -ANN.aT = 0; -ANN.apT = 0; -ANN.fT = inf; - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to initialize the Artificial Neural Network +% Note: The struct and evaluation algorithms could be shorter but less +% comprehensible +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-23 / Max Ortiz / Creation +% 2009-11-09 / Max Ortiz / Initialization of v, phi and lg to consider a number +% of output higer than the number of neurons in the hiden layer +% 2011-09-10 / Max Ortiz / New routine for BioPatRec based in previous +% implementation for EMG_AQ +% 20xx-xx-xx / Author / Comment on update + +function ANN = InitANN_Perceptron(nIn,nHn,nOn) + +ANN.Type = 'Perceptron'; +ANN.nIn = nIn; +ANN.nHn = nHn; +ANN.nOn = nOn; +ANN.w = zeros(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1); % weight +ANN.b = zeros(max([nHn nOn]),length(nHn)+1); % bias +ANN.o = zeros(nOn,1); % output +ANN.a = 1; % amplitud for activation function + +% Back Propagation Algorithm +ANN.v = zeros(max([nHn nOn]),length(nHn)+1); % induced activation field +ANN.phi = zeros(max([nHn nOn]),length(nHn)); % activation function or output +ANN.lg = zeros(max([nHn nOn]),length(nHn)+1); % local gradient (lower delta) +ANN.dw = zeros(max([nHn nIn nOn]),max([nHn nIn nOn]),length(nHn)+1); % capital delta weight or change in weight +ANN.db = zeros(max([nHn nOn]),length(nHn)+1); % capital delta weight or change in weight of bias + +% Evolutionary Algorithm and PSO +ANN.aTr = 0; +ANN.apTr = 0; +ANN.fTr = inf; + +ANN.aV = 0; +ANN.apV = 0; +ANN.fV = inf; + +ANN.aT = 0; +ANN.apT = 0; +ANN.fT = inf; + + + diff --git a/PatRec/ANN/MLPTest.m b/PatRec/ANN/MLPTest.m index 73f86d6..c21b580 100644 --- a/PatRec/ANN/MLPTest.m +++ b/PatRec/ANN/MLPTest.m @@ -1,41 +1,41 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Test the ANN MLP. This function was split from OneShotPatRec. -% -% ------------------------- Updates & Contributors ------------------------ -% 2012-02-26 / Max Ortiz / Creation -% 2012-03-04 / Max Ortiz / Modify outMov to be round(outVector) - -function [outMov outVector] = MLPTest(patRecTrained, tSet) - - ANN = EvaluateANN(tSet,patRecTrained.ANN); - outVector = ANN.o; - - if isfield(patRecTrained,'thOut') - % Output according to a given threshold - outMov = find(outVector>patRecTrained.thOut'); - else - % The output movement is given by any prediction over 50% - outMov = find(round(outVector)); - - % The output movement is given by the higest prediction - %[maxV, outMov] = max(outVector); - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Test the ANN MLP. This function was split from OneShotPatRec. +% +% ------------------------- Updates & Contributors ------------------------ +% 2012-02-26 / Max Ortiz / Creation +% 2012-03-04 / Max Ortiz / Modify outMov to be round(outVector) + +function [outMov outVector] = MLPTest(patRecTrained, tSet) + + ANN = EvaluateANN(tSet,patRecTrained.ANN); + outVector = ANN.o; + + if isfield(patRecTrained,'thOut') + % Output according to a given threshold + outMov = find(outVector>patRecTrained.thOut'); + else + % The output movement is given by any prediction over 50% + outMov = find(round(outVector)); + + % The output movement is given by the higest prediction + %[maxV, outMov] = max(outVector); + end + end \ No newline at end of file diff --git a/PatRec/ANN/PSO/InitPSO_MLP.m b/PatRec/ANN/PSO/InitPSO_MLP.m index 6d1eddf..90a4498 100644 --- a/PatRec/ANN/PSO/InitPSO_MLP.m +++ b/PatRec/ANN/PSO/InitPSO_MLP.m @@ -1,69 +1,69 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Use of the ANN MLP struct -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-27 / Max Ortiz / Creation -% 2012-06-01 / Max Ortiz / Adapted to new coding standard -% - -function PSO = InitPSO_MLP(ANN) - -PSO.sSize = 20; %Swarm size - -PSO.nVar = ANN.nIn * ANN.nHn(1); % Weight inputs and first layer -PSO.nVar = PSO.nVar + ANN.nHn(1); % Bias first layer -for i = 2 : length(ANN.nHn) - PSO.nVar = PSO.nVar + ANN.nHn(i-1)*ANN.nHn(i); %Weight hidden layer - PSO.nVar = PSO.nVar + ANN.nHn(i); % Bias Hiden Layers -end -PSO.nVar = PSO.nVar + ANN.nHn(end)*ANN.nOn; % Weight output -PSO.nVar = PSO.nVar + ANN.nOn; % Bias outputs - -PSO.xMin = -1; %minumum -PSO.xMax = 1; %maximum - -PSO.dt = 1; %time step lengh -PSO.alpha = 1; %constant -PSO.c1 = 2; %Constant C1 -PSO.c2 = 2; %Constant C2 - -PSO.beta = .6; %Beta for inertia weight -PSO.w = 1.4; %weigh for inertia weight -PSO.pcr = 0.1; %Craziness probability - -PSO.maxSimulations = 100; %max number of simulations - -% Initialization of Vmax -PSO.vMax = (PSO.xMax - PSO.xMin) / PSO.dt; - -PSO.opelite = 1; %input('Do you want to use elite particle? Yes (1) or No (2): '); -PSO.opcrazy = 1; %input('Do you want to use crazy operator? Yes (1) or No (2): '); - - -%Initializations -PSO.positions = PSO.xMin + rand(PSO.sSize,PSO.nVar).*(PSO.xMax - PSO.xMin); -PSO.velocities = InitVelocities(PSO.sSize,PSO.nVar,PSO.xMin,PSO.xMax,PSO.dt,PSO.alpha,PSO.vMax); - -% Initialization of best -PSO.fitness(1:PSO.sSize) = inf; -PSO.pBestFit(1:PSO.sSize) = inf; -PSO.sBestFit = inf; -PSO.pBestPos = zeros(PSO.sSize,PSO.nVar); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Use of the ANN MLP struct +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-27 / Max Ortiz / Creation +% 2012-06-01 / Max Ortiz / Adapted to new coding standard +% + +function PSO = InitPSO_MLP(ANN) + +PSO.sSize = 20; %Swarm size + +PSO.nVar = ANN.nIn * ANN.nHn(1); % Weight inputs and first layer +PSO.nVar = PSO.nVar + ANN.nHn(1); % Bias first layer +for i = 2 : length(ANN.nHn) + PSO.nVar = PSO.nVar + ANN.nHn(i-1)*ANN.nHn(i); %Weight hidden layer + PSO.nVar = PSO.nVar + ANN.nHn(i); % Bias Hiden Layers +end +PSO.nVar = PSO.nVar + ANN.nHn(end)*ANN.nOn; % Weight output +PSO.nVar = PSO.nVar + ANN.nOn; % Bias outputs + +PSO.xMin = -1; %minumum +PSO.xMax = 1; %maximum + +PSO.dt = 1; %time step lengh +PSO.alpha = 1; %constant +PSO.c1 = 2; %Constant C1 +PSO.c2 = 2; %Constant C2 + +PSO.beta = .6; %Beta for inertia weight +PSO.w = 1.4; %weigh for inertia weight +PSO.pcr = 0.1; %Craziness probability + +PSO.maxSimulations = 100; %max number of simulations + +% Initialization of Vmax +PSO.vMax = (PSO.xMax - PSO.xMin) / PSO.dt; + +PSO.opelite = 1; %input('Do you want to use elite particle? Yes (1) or No (2): '); +PSO.opcrazy = 1; %input('Do you want to use crazy operator? Yes (1) or No (2): '); + + +%Initializations +PSO.positions = PSO.xMin + rand(PSO.sSize,PSO.nVar).*(PSO.xMax - PSO.xMin); +PSO.velocities = InitVelocities(PSO.sSize,PSO.nVar,PSO.xMin,PSO.xMax,PSO.dt,PSO.alpha,PSO.vMax); + +% Initialization of best +PSO.fitness(1:PSO.sSize) = inf; +PSO.pBestFit(1:PSO.sSize) = inf; +PSO.sBestFit = inf; +PSO.pBestPos = zeros(PSO.sSize,PSO.nVar); diff --git a/PatRec/ANN/PSO/PSO_MLP.m b/PatRec/ANN/PSO/PSO_MLP.m index f875160..1ffd429 100644 --- a/PatRec/ANN/PSO/PSO_MLP.m +++ b/PatRec/ANN/PSO/PSO_MLP.m @@ -1,93 +1,93 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Particle Swarm Optimization to find ... -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-23 / Max Ortiz/ Creation -% 2012-06-02 / Max Ortiz/ Adapted for MLP - -function [PSO, ANN] = PSO_MLP(PSO, ANN, trSets, trOuts) - -if PSO.opcrazy ~= 1 - PSO.pcr = 0; -end - -% It's not need it to run over all simulations -%Run until the max number of generations -%for sim = 1:PSO.maxSimulations - - %Fitness evaluation - for i = 1:PSO.sSize - - ANN = Pos2W(ANN,PSO.positions(i,:)); %Rutine borrowed from the EA, in folder Eval - PSO.fitness(i) = FitnessANN(ANN,trSets,trOuts); - - %Particle Best - if (PSO.fitness(i) < PSO.pBestFit(i)) - PSO.pBestFit(i) = PSO.fitness(i); %particle best fitness - PSO.pBestPos(i,:) = PSO.positions(i,:); %particle best position - end - - end - - %Find the best in the swarm - for i=1:PSO.sSize - if PSO.pBestFit(i) < PSO.sBestFit - PSO.sBestFit = PSO.pBestFit(i); %Swarm best fitness - PSO.sBestPos = PSO.positions(i,:); %Swarm best position - end - end - - %Update velocity - for i = 1:PSO.sSize - cr=rand; - if cr > PSO.pcr - tempvel = UpdateVel(i, PSO.velocities, PSO.positions, PSO.pBestPos, PSO.sBestPos, PSO.c1, PSO.c2, PSO.nVar, PSO.dt, PSO.vMax, PSO.w); - else - tempvel = -PSO.vMax + 2 * rand(PSO.nVar,1) * PSO.vMax; - end - PSO.velocities(i,:) = tempvel; - end - - %Reduce inertia weight for velocity - if PSO.w > 0.3 - PSO.w = PSO.beta * PSO.w; - end - - %Update position - PSO.positions = PSO.positions + PSO.velocities * PSO.dt; -% % Limit negative values - negIdx = find(PSO.positions < PSO.xMin); - PSO.positions(negIdx) = -1; -% % Limit values over 1 - negIdx = find(PSO.positions > PSO.xMax); - PSO.positions(negIdx) = 1; - - - %Elite Partic%le - if PSO.opelite == 1 - PSO.positions(1,:) = PSO.sBestPos; %This instruction will always keep the best partical position - end - - %disp(PSO.sBestFit); - -%end -% Return the best position -ANN = Pos2W(ANN,PSO.sBestPos); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Particle Swarm Optimization to find ... +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-23 / Max Ortiz/ Creation +% 2012-06-02 / Max Ortiz/ Adapted for MLP + +function [PSO, ANN] = PSO_MLP(PSO, ANN, trSets, trOuts) + +if PSO.opcrazy ~= 1 + PSO.pcr = 0; +end + +% It's not need it to run over all simulations +%Run until the max number of generations +%for sim = 1:PSO.maxSimulations + + %Fitness evaluation + for i = 1:PSO.sSize + + ANN = Pos2W(ANN,PSO.positions(i,:)); %Rutine borrowed from the EA, in folder Eval + PSO.fitness(i) = FitnessANN(ANN,trSets,trOuts); + + %Particle Best + if (PSO.fitness(i) < PSO.pBestFit(i)) + PSO.pBestFit(i) = PSO.fitness(i); %particle best fitness + PSO.pBestPos(i,:) = PSO.positions(i,:); %particle best position + end + + end + + %Find the best in the swarm + for i=1:PSO.sSize + if PSO.pBestFit(i) < PSO.sBestFit + PSO.sBestFit = PSO.pBestFit(i); %Swarm best fitness + PSO.sBestPos = PSO.positions(i,:); %Swarm best position + end + end + + %Update velocity + for i = 1:PSO.sSize + cr=rand; + if cr > PSO.pcr + tempvel = UpdateVel(i, PSO.velocities, PSO.positions, PSO.pBestPos, PSO.sBestPos, PSO.c1, PSO.c2, PSO.nVar, PSO.dt, PSO.vMax, PSO.w); + else + tempvel = -PSO.vMax + 2 * rand(PSO.nVar,1) * PSO.vMax; + end + PSO.velocities(i,:) = tempvel; + end + + %Reduce inertia weight for velocity + if PSO.w > 0.3 + PSO.w = PSO.beta * PSO.w; + end + + %Update position + PSO.positions = PSO.positions + PSO.velocities * PSO.dt; +% % Limit negative values + negIdx = find(PSO.positions < PSO.xMin); + PSO.positions(negIdx) = -1; +% % Limit values over 1 + negIdx = find(PSO.positions > PSO.xMax); + PSO.positions(negIdx) = 1; + + + %Elite Partic%le + if PSO.opelite == 1 + PSO.positions(1,:) = PSO.sBestPos; %This instruction will always keep the best partical position + end + + %disp(PSO.sBestFit); + +%end +% Return the best position +ANN = Pos2W(ANN,PSO.sBestPos); diff --git a/PatRec/ANN/PSO/Pos2W.m b/PatRec/ANN/PSO/Pos2W.m index a7db5e6..b7c5b28 100644 --- a/PatRec/ANN/PSO/Pos2W.m +++ b/PatRec/ANN/PSO/Pos2W.m @@ -1,49 +1,49 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to decode the a vector of weight into the MLP -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-23 / Max Ortiz/ Creation - -function ANN = Pos2W(ANN,w) - - % First layer - ANN.w(1:ANN.nIn*ANN.nHn(1)) = w(1 : ANN.nIn*ANN.nHn(1)); - offset = ANN.nIn*ANN.nHn(1); - ANN.b(1:ANN.nHn(1)) = w(offset+1 : offset + ANN.nHn(1)); - offset = offset + ANN.nHn(1); - - % Hidden Layers - for i = 2 : length(ANN.nHn) - tmat = zeros(ANN.nHn(i-1), ANN.nHn(i)); - tmat(1:end) = w(offset + 1 : offset + ANN.nHn(i-1)*ANN.nHn(i)); - ANN.w(1:ANN.nHn(i-1),1:ANN.nHn(i),i) = tmat; - offset = offset + ANN.nHn(i-1)*ANN.nHn(i); - ANN.b(1:ANN.nHn(i), i) = w(offset + 1 : offset + ANN.nHn(i)); - offset = offset + ANN.nHn(i); - end - - % Last layer - tmat = zeros(ANN.nHn(end), ANN.nOn); - tmat(1:end) = w(offset + 1 : offset + ANN.nHn(end)*ANN.nOn); - ANN.w(1:ANN.nHn(end),1:ANN.nOn,end) = tmat; - offset = offset + ANN.nHn(end)*ANN.nOn; - ANN.b(1:ANN.nOn,end) = w(offset+1 : offset + ANN.nOn); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to decode the a vector of weight into the MLP +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-23 / Max Ortiz/ Creation + +function ANN = Pos2W(ANN,w) + + % First layer + ANN.w(1:ANN.nIn*ANN.nHn(1)) = w(1 : ANN.nIn*ANN.nHn(1)); + offset = ANN.nIn*ANN.nHn(1); + ANN.b(1:ANN.nHn(1)) = w(offset+1 : offset + ANN.nHn(1)); + offset = offset + ANN.nHn(1); + + % Hidden Layers + for i = 2 : length(ANN.nHn) + tmat = zeros(ANN.nHn(i-1), ANN.nHn(i)); + tmat(1:end) = w(offset + 1 : offset + ANN.nHn(i-1)*ANN.nHn(i)); + ANN.w(1:ANN.nHn(i-1),1:ANN.nHn(i),i) = tmat; + offset = offset + ANN.nHn(i-1)*ANN.nHn(i); + ANN.b(1:ANN.nHn(i), i) = w(offset + 1 : offset + ANN.nHn(i)); + offset = offset + ANN.nHn(i); + end + + % Last layer + tmat = zeros(ANN.nHn(end), ANN.nOn); + tmat(1:end) = w(offset + 1 : offset + ANN.nHn(end)*ANN.nOn); + ANN.w(1:ANN.nHn(end),1:ANN.nOn,end) = tmat; + offset = offset + ANN.nHn(end)*ANN.nOn; + ANN.b(1:ANN.nOn,end) = w(offset+1 : offset + ANN.nOn); + diff --git a/PatRec/Accuracy_patRec.m b/PatRec/Accuracy_patRec.m index 408306b..01549da 100644 --- a/PatRec/Accuracy_patRec.m +++ b/PatRec/Accuracy_patRec.m @@ -1,132 +1,203 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% Compute the overal all Accuracy of the patRec algorithm -% As it is, the number of set per class must be the same for each class -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-10-29 / Max Ortiz / Created -% 2012-03-04 / Max Ortiz / Cleaned from old commented code and include a -% validation for outMov == 0 -% 2012-04-01 / Max Ortiz / Cunfusion matrix added to the calculations -% 2012-04-01 / Max Ortiz / tTime added -% 20xx-xx-xx / Author / Comment on update - -function [acc confMat tTime] = Accuracy_patRec(patRec, tSet, tOut, confMatFlag) - -% Init variables -nM = size(patRec.mov,1); % Number of movements (total) -sM = size(tOut,1)/nM; % Sets per movement -good = zeros(size(tSet,1),1); % Keep track of the good prediction -nOut = size(tOut,2); % Number of outputs -confMat = zeros(nM,nOut+1); -tTime = zeros(1,size(tSet,1)); - -for i = 1 : size(tSet,1) - % Start the timer for testing/prediction time - tStart = tic; - %Normalize set - x = NormalizeSet(tSet(i,:), patRec); - - %% Classification - [outMov outVector] = OneShotPatRecClassifier(patRec, x); - - tTime(i) = toc(tStart); - - %% Dirty patch for simultaneous movements - % Dirty patch for classification of simultaneous movements when the - % algorithm has no way to know how many movements are mixed -% if strcmp(patRec.topology,'Single Classifier') -% if strcmp(patRec.patRecTrained(end).algorithm,'DA') ||... -% strcmp(patRec.patRecTrained(end).algorithm,'RFN') -% -% %Quick and dirty routine to evaluate 2 patterns -% % IF it's known that more than two patterns are presented -% nExpMov = length(find(tOut(i,:))); -% if nExpMov ~= 1 % More than one movement -% [Y, I] = sort(outVector,'descend'); -% outMov = I(1:nExpMov)'; -% end -% end -% end - -% % Stop when more than 1 mov is tested -% if length(find(tOut(i,:))) ~= 1 -% 0; -% end - - %% Count the number of correct predictions - if ~isempty(outMov) - if outMov ~= 0 - mask = zeros(1,nOut); - mask(outMov) = 1; - % Are these the right movements? - if tOut(i,:) == mask - good(i) = 1; - else - %stop for debuggin purposes - end - -% %Evaluate only a single movement -% if tOut(i,outMov) == 1 -% good(i) = 1; -% end - - else - %If outMov = 0, then count it for the confusion matrix as no - %prediction in an additional output - outMov = nOut+1; - end - else - %If outMov = empty, then count it for the confusion matrix as no - %prediction in an additional output - outMov = nOut+1; - end - - %Confusion Matrix - if confMatFlag - % This will only work if there is an equal number of sets per class - % in the testing sets - expectedOutIdx = fix((i-1)/sM)+1; - confMat(expectedOutIdx,outMov) = confMat(expectedOutIdx,outMov) + 1; - end -end - -tTime = mean(tTime); - -% Compute the accuracy per movement -% This will only work if there are the same number of movements -acc = zeros(nM+1,1); -for i = 1 : nM - s = 1+((i-1)*sM); - e = sM*i; - acc(i) = sum(good(s:e))/sM; -end -acc(i+1) = sum(good) / size(tSet,1); - -% Print confusion matrix -if confMatFlag - confMat = confMat ./ sM; % This will only work if there is an equal number of sets per class - figure; - imagesc(confMat); - title('Confusion Matrix') - xlabel('Movements'); - ylabel('Movements'); -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% Compute the overal all Accuracy of the patRec algorithm +% As it is, the number of set per class must be the same for each class +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-10-29 / Max Ortiz / Created +% 2012-03-04 / Max Ortiz / Cleaned from old commented code and include a +% validation for outMov == 0 +% 2012-04-01 / Max Ortiz / Cunfusion matrix added to the calculations +% 2012-04-01 / Max Ortiz / tTime added +% 2013-10-22 / Faezeh Rouhani / Additional indicators +% (precision,recall,f1,specificity,npv) +% 2012-10-30 / Max Ortiz / Clean and comment code, rename accnew to accTrue + +function [performance confMat tTime] = Accuracy_patRec(patRec, tSet, tOut, confMatFlag) + +% Init variables +nM = size(patRec.mov,1); % Number of movements (total) +sM = size(tOut,1)/nM; % Sets per movement +good = zeros(size(tSet,1),1); % Keep track of the good prediction +nOut = size(tOut,2); % Number of outputs +confMat = zeros(nM,nOut+1); +tTime = zeros(1,size(tSet,1)); +% prediction metrics +maskMat = zeros(size(tSet,1),nOut); +FN = zeros(size(tSet,1),nOut); +TN = zeros(size(tSet,1),nOut); +TP = zeros(size(tSet,1),nOut); +FP = zeros(size(tSet,1),nOut); + +for i = 1 : size(tSet,1) + % Start the timer for testing/prediction time + tStart = tic; + %Normalize set + x = NormalizeSet(tSet(i,:), patRec); + x = ApplyFeatureReduction(x, patRec); + %% Classification + [outMov outVector] = OneShotPatRecClassifier(patRec, x); + + tTime(i) = toc(tStart); + + %% Count the number of correct predictions + if ~isempty(outMov) + if outMov ~= 0 + % Create a mask to match the correct output + mask = zeros(1,nOut); + mask(outMov) = 1; + % Save the mask for future computation of prediction metrics + maskMat(i,:)=mask; + % Are these the right movements? + if tOut(i,:) == mask + good(i) = 1; + else + %stop for debuggin purposes + end + +% %Evaluate a single movement only / not suitable for simult. +% if tOut(i,outMov) == 1 +% good(i) = 1; +% end + + else + %If outMov = 0, then count it for the confusion matrix as no + %prediction in an additional output + outMov = nOut+1; + end + else + %If outMov = empty, then count it for the confusion matrix as no + %prediction in an additional output + outMov = nOut+1; + end + + %Confusion Matrix + if confMatFlag + expectedOutIdx = fix((i-1)/sM)+1; % This will only work if there is an equal number of sets per class + confMat(expectedOutIdx,outMov) = confMat(expectedOutIdx,outMov) + 1; + end +end +tTime = mean(tTime); + +% Verify that dimension of maskMat and tOut match +if size(tSet,1) ~= size(maskMat,1) + disp('error in maskMat'); +end +if size(tSet,1) ~= size(tOut,1) + disp('error in tOut'); +end +% Compute the FP, FN, TP, TN using the saved maskMat +for m=1:size(tSet,1) + for n=1:nOut + if tOut(m,n) == maskMat(m,n) + if tOut(m,n) == 1 + TP(m,n) = 1; + else + TN(m,n) = 1; + end + else + if tOut(m,n) == 1 + FN(m,n) = 1; + else + FP(m,n) = 1; + end + end + end +end + +% get total +tPs=sum(sum(TP)); +fPs=sum(sum(FP)); +tNs=sum(sum(TN)); +fNs=sum(sum(FN)); + +% Compute metrics per movement/class +% This will only work if there are the same number of movements +acc = zeros(nM+1,1); +tPvec = zeros(nOut,nM); +tNvec = zeros(nOut,nM); +fPvec = zeros(nOut,nM); +fNvec = zeros(nOut,nM); + +for i = 1 : nM + s = 1+((i-1)*sM); + e = sM*i; + acc(i) = sum(good(s:e))/sM; + tPvec(:,i)=sum(TP(s:e,:)); + tNvec(:,i)=sum(TN(s:e,:)); + fPvec(:,i)=sum(FP(s:e,:)); + fNvec(:,i)=sum(FN(s:e,:)); + + if tPvec(:,i) > sM + disp('Error on Ture Possitives'); + end + if tNvec(:,i) > size(tSet,1)-sM + disp('Error on Ture Negatives'); + end + +end +acc(i+1) = sum(good) / size(tSet,1); +tPvec = sum(tPvec)'; +tNvec = sum(tNvec)'; +fPvec = sum(fPvec)'; +fNvec = sum(fNvec)'; + +%Compute the precision per movement +precision = tPvec ./(tPvec+fPvec); +precision(end+1) = tPs/(tPs+fPs); + +%Compute the recall per movement +recall = tPvec ./(tPvec+fNvec); +recall(end+1) = tPs/(tPs+fNs); + +%Compute the specificity per movement +specificity=tNvec ./(tNvec+fPvec); +specificity(end+1)=tNs/(tNs+fPs); + +%Compute the npv per movement +npv=tNvec ./(tNvec+fNvec); +npv(end+1)=tNs/(tNs+fNs); + +%Compute the f1 per movement +f1=(2.*precision.*recall)./(precision+recall); + +% True accuracy / global accuracy +accTrue=(tPvec+tNvec)./(tPvec+fPvec+fNvec+tNvec); +accTrue(end+1)=(tPs+tNs)/(tNs+tPs+fPs+fNs); + +% Save performance metrics +performance.acc = acc*100; +performance.accTrue = accTrue*100; +performance.precision = precision*100; +performance.recall = recall*100; % Sensitivity +performance.f1 = f1; +performance.specificity= specificity*100; +performance.npv = npv*100; + +% Print confusion matrix +if confMatFlag + confMat = confMat ./ sM; % This will only work if there is an equal number of sets per class + figure; + imagesc(confMat); + title('Confusion Matrix') + xlabel('Movements'); + ylabel('Movements'); +end diff --git a/PatRec/ContainsMovementNames.m b/PatRec/ContainsMovementNames.m index 67ea617..721b5a1 100644 --- a/PatRec/ContainsMovementNames.m +++ b/PatRec/ContainsMovementNames.m @@ -1,8 +1,8 @@ -function contains = ContainsMovementNames(movements,movementNames) - contains = 0; - for i = 1:length(movements) - if strfind(movementNames{1},movements(i).name{1}) - contains = 1; - end - end +function contains = ContainsMovementNames(movements,movementNames) + contains = 0; + for i = 1:length(movements) + if strfind(movementNames{1},movements(i).name{1}) + contains = 1; + end + end end \ No newline at end of file diff --git a/PatRec/GUI_PatRec.fig b/PatRec/GUI_PatRec.fig index c847819..41cee37 100644 Binary files a/PatRec/GUI_PatRec.fig and b/PatRec/GUI_PatRec.fig differ diff --git a/PatRec/GUI_PatRec.m b/PatRec/GUI_PatRec.m index 6cd7683..f781ab0 100644 --- a/PatRec/GUI_PatRec.m +++ b/PatRec/GUI_PatRec.m @@ -19,7 +19,10 @@ % Compute the overal all Accuracy of the patRec algorithm % % ------------------------- Updates & Contributors ------------------------ -% 2011-11-25 / Max Ortiz / Created new version from EMG_AQ +% 2011-11-25 / Max Ortiz / Created new version from EMG_AQ +% 2014-11-07 / Diep Khong / Added SVM +% 2014-12-01 / Enzo Mastinu / Added the handling part for the COM port number + % information into the parameters % 20xx-xx-xx / Author / Comment on update function varargout = GUI_PatRec(varargin) @@ -46,7 +49,7 @@ % Edit the above text to modify the response to help GUI_PatRec -% Last Modified by GUIDE v2.5 06-Nov-2012 11:48:34 +% Last Modified by GUIDE v2.5 30-Oct-2013 10:35:30 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -120,84 +123,146 @@ function pb_GetFeatures_Callback(hObject, eventdata, handles) ss = []; % Dialog box to open a file - [file, path] = uigetfile('*.mat'); + [file, path] = uigetfile({'*.mat';'*.csv'}); % Check that the loaded file is a "ss" struct if ~isequal(file, 0) - load([path,file]); - if (exist('recSession','var')) % Send a recording session for data treatment + [pathstr,name,ext] = fileparts(file); + if(strcmp(ext,'.mat')) + load([path,file]); + if (exist('recSession','var')) % Send a recording session for data treatment - Load_recSession(recSession, handles); - %Enable algorithm selection - set(handles.pm_SelectAlgorithm,'Enable','on'); - set(handles.rb_all,'Enable','on'); - set(handles.rb_top2,'Enable','on'); - set(handles.rb_top3,'Enable','on'); - set(handles.rb_top4,'Enable','on'); - - elseif (exist('sigFeatures','var')) % Get sig_Features - Load_sigFeatures(sigFeatures, handles); - %Enable algorithm selection - set(handles.pm_SelectAlgorithm,'Enable','on'); - set(handles.rb_all,'Enable','on'); - set(handles.rb_top2,'Enable','on'); - set(handles.rb_top3,'Enable','on'); - set(handles.rb_top4,'Enable','on'); - set(handles.pb_RunOfflineTraining,'Enable','on'); - - elseif (exist('treated_data','var')) % Get sig_Features - Load_sigFeatures(treated_data, handles); - %Enable algorithm selection - set(handles.pm_SelectAlgorithm,'Enable','on'); - set(handles.rb_all,'Enable','on'); - set(handles.rb_top2,'Enable','on'); - set(handles.rb_top3,'Enable','on'); - set(handles.rb_top4,'Enable','on'); + Load_recSession(recSession, handles); + %Enable algorithm selection + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_all,'Enable','on'); + set(handles.rb_top2,'Enable','on'); + set(handles.rb_top3,'Enable','on'); + set(handles.rb_top4,'Enable','on'); - elseif (exist('patRec','var')) % Get patRec - Load_patRec(patRec, 'GUI_PatRec',[]); - set(handles.pm_normSets,'Enable','off'); - set(handles.pm_SelectTopology,'Enable','off'); - set(handles.pm_movMix,'Enable','off'); - set(handles.pm_normSets,'Enable','off'); -% set(handles.pb_RealtimePatRec,'Enable','on'); -% set(handles.pb_motionTest,'Enable','on'); - set(handles.pb_RealtimePatRecGUI,'Enable','on'); - %Added to enable Mov2Mov-button after loading PatRec - set(handles.pb_RealtimePatRecMov2Mov,'Enable','on'); - %Load all values from the patRec into the GUI. - set(handles.et_accuracy,'String',num2str(patRec.acc(end))); - set(handles.lb_accuracy,'String',num2str(patRec.acc(1:end-1))); - set(handles.et_trTime,'String',num2str(patRec.trTime)); - set(handles.et_tTime,'String',num2str(patRec.tTime)); - - elseif (exist('ss','var')) % keep compatibility - if ~isempty(ss) - recSession.sF = ss.Fs; - recSession.sT = ss.Ts; - recSession.nM = ss.Ne; - recSession.nR = ss.Nr; - recSession.cT = ss.Tc; - recSession.rT = ss.Tr; - recSession.cTp = ss.Psr; - recSession.mov = ss.msg; - recSession.date = ss.date; - recSession.tdata = ss.tdata; - %recSession.trdata = ss.trdata; - - Load_recSession(recSession, handles); + elseif (exist('sigFeatures','var')) % Get sig_Features + Load_sigFeatures(sigFeatures, handles); + %Enable algorithm selection + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_all,'Enable','on'); + set(handles.rb_top2,'Enable','on'); + set(handles.rb_top3,'Enable','on'); + set(handles.rb_top4,'Enable','on'); + set(handles.pb_RunOfflineTraining,'Enable','on'); + + elseif (exist('treated_data','var')) % Get sig_Features + Load_sigFeatures(treated_data, handles); %Enable algorithm selection set(handles.pm_SelectAlgorithm,'Enable','on'); set(handles.rb_all,'Enable','on'); set(handles.rb_top2,'Enable','on'); set(handles.rb_top3,'Enable','on'); set(handles.rb_top4,'Enable','on'); - else - disp('That was not a valid training matrix'); - errordlg('That was not a valid training matrix','Error'); - return; - end + + elseif (exist('patRec','var')) % Get patRec + Load_patRec(patRec, 'GUI_PatRec',[]); + set(handles.pm_normSets,'Enable','off'); + set(handles.pm_SelectTopology,'Enable','off'); + set(handles.pm_movMix,'Enable','off'); + set(handles.pm_normSets,'Enable','off'); + % set(handles.pb_RealtimePatRec,'Enable','on'); + % set(handles.pb_motionTest,'Enable','on'); + set(handles.pb_RealtimePatRecGUI,'Enable','on'); + %Added to enable Mov2Mov-button after loading PatRec + set(handles.pb_RealtimePatRecMov2Mov,'Enable','on'); + %Load all values from the patRec into the GUI. + set(handles.et_accuracy,'String',num2str(patRec.acc(end))); + set(handles.lb_accuracy,'String',num2str(patRec.acc(1:end-1))); + set(handles.et_trTime,'String',num2str(patRec.trTime)); + set(handles.et_tTime,'String',num2str(patRec.tTime)); + disp('%%%%%%%%%%% patRec loaded %%%%%%%%%%%%%'); + set(handles.t_msg,'String','patRec loaded'); + elseif (exist('ss','var')) % keep compatibility + if ~isempty(ss) + recSession.sF = ss.Fs; + recSession.sT = ss.Ts; + recSession.nM = ss.Ne; + recSession.nR = ss.Nr; + recSession.cT = ss.Tc; + recSession.rT = ss.Tr; + recSession.cTp = ss.Psr; + recSession.mov = ss.msg; + recSession.date = ss.date; + recSession.tdata = ss.tdata; + %recSession.trdata = ss.trdata; + + Load_recSession(recSession, handles); + %Enable algorithm selection + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_all,'Enable','on'); + set(handles.rb_top2,'Enable','on'); + set(handles.rb_top3,'Enable','on'); + set(handles.rb_top4,'Enable','on'); + else + disp('That was not a valid training matrix'); + errordlg('That was not a valid training matrix','Error'); + return; + end + end + else + %CSV / MCARE + + fid = fopen(file); + fullDir = strcat(path,name,ext); % We get the path of the selected file + fileDir = dir(fullDir); % We use this to get the size, which is a field of dir + movText = fgetl(fid); % We read the first line + movText = textscan(movText, '%s', 'Delimiter', ',', 'BufSize', fileDir.bytes); %Scans for objects seperated with commas. We use the filesize as buffer + recSession.mov = movText{1}; %And load them into the recSession + fclose(fid); %We need to close the file, before we can textscan it with other parameters + fid = fopen(file); + C = textscan(fid, '%s', 'Delimiter', '\n', 'BufSize', fileDir.bytes); % Scans for objects seperated by line breaks + recSession.date = C{1}{2}; + recSession.comm = C{1}{3}; + if strcmp(recSession.comm, 'COM') + recSession.comn = C{1}{4}; + end + recSession.sF = csvread(file,3,0,[3, 0, 3, 0]); + recSession.nM = csvread(file,3,1,[3, 1, 3, 1]); + recSession.sT = csvread(file, 3,2,[3,2,3,2]); + recSession.cT = csvread(file, 3,3,[3,3,3,3]); + recSession.rT = csvread(file, 3,4,[3,4,3,4]); + recSession.nR = csvread(file, 3,5,[3,5,3,5]); + recSession.nCh = csvread(file, 3,6,[3,6,3,6]); + %Loading raw data + rawData = csvread(file,4,0)'; + %Preallocate memory + recSession.tdata = zeros(recSession.sF*recSession.cT*recSession.nR*2,recSession.nCh,recSession.nM); + %Sorts the data + for movements = 1 : recSession.nM + for channels = 1 : recSession.nCh + % We iterate over the repititions, as data from MCARE is exported channel-wise (as a subset of each repitition) + % The system is like this (for 3 repititions and 4 + % channels) + %iterator = + % 1 5 9 -> First channel + % 2 6 10 -> Second Channel + % 3 7 11 -> Third Channel + % 4 8 12 -> Fourth Channel + % ^ "lines of data" E.g. "1" = first channel from first + % repition. "5" = first channel from second repitition. + % "2" = second channel from first repitition. + iterator = channels+((movements-1)*(recSession.nCh*recSession.nR)); + for repititions = 1 : recSession.nR + recSession.tdata(1+((repititions-1)*(recSession.sF*(recSession.cT+recSession.rT))):repititions*(recSession.sF*(recSession.cT+recSession.rT)),channels,movements) = rawData(:,iterator); + iterator = iterator + recSession.nCh; + end + end + end + + Load_recSession(recSession, handles); + %Enable algorithm selection + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_all,'Enable','on'); + set(handles.rb_top2,'Enable','on'); + set(handles.rb_top3,'Enable','on'); + set(handles.rb_top4,'Enable','on'); end end + @@ -208,7 +273,7 @@ function pb_RunOfflineTraining_Callback(hObject, eventdata, handles) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Close real-time testing -% close(GUI_TestPatRec_Mov2Mov); + % close(GUI_TestPatRec_Mov2Mov); set(handles.t_msg,'String','Offline PatRec Started...'); % set(handles.pb_RunOfflineTraining,'Enable','Off'); @@ -225,7 +290,7 @@ function pb_RunOfflineTraining_Callback(hObject, eventdata, handles) set(handles.t_msg,'String','Please select the mix of movements to be used'); return; end - + % Collet sigFeatures sigFeatures = get(handles.t_sigFeatures,'UserData'); if isempty(sigFeatures) @@ -241,6 +306,10 @@ function pb_RunOfflineTraining_Callback(hObject, eventdata, handles) allNormSets = get(handles.pm_normSets,'String'); normSets = char(allNormSets(get(handles.pm_normSets,'Value'))); + % Select feature reduction algorithm + allFeatReducAlg=get(handles.pm_FeatureReduction,'String'); + featReducAlg=char(allFeatReducAlg(get(handles.pm_FeatureReduction,'Value'))); + % Movements mix or individual movements? allMovMixes = get(handles.pm_movMix,'String'); movMix = char(allMovMixes(get(handles.pm_movMix,'Value'))); @@ -272,7 +341,7 @@ function pb_RunOfflineTraining_Callback(hObject, eventdata, handles) topology = char(allTopologies(get(handles.pm_SelectTopology,'Value'))); % Call rutine for offline pat rec - patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSets, alg, tType, algConf, movMix, topology, confMatFlag); + patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSets, alg, tType, algConf, movMix, topology, confMatFlag, featReducAlg); % Save and show results handles.patRec = patRec; @@ -280,12 +349,28 @@ function pb_RunOfflineTraining_Callback(hObject, eventdata, handles) % Save in GUI components to be used by statistics rutines % This has to be change - set(handles.lb_accuracy,'UserData',patRec.acc); + set(handles.lb_accuracy,'UserData',patRec.performance.acc); +% set(handles.lb_precision,'UserData',patRec.performance.precision); +% set(handles.lb_recall,'UserData',patRec.performance.recall); +% set(handles.lb_f1,'UserData',patRec.performance.f1); set(handles.et_accuracy,'UserData',patRec); % Update GUI - set(handles.et_accuracy,'String',num2str(patRec.acc(end))); - set(handles.lb_accuracy,'String',num2str(patRec.acc(1:end-1))); + set(handles.et_accuracy,'String',num2str(patRec.performance.acc(end),'%.2f')); + set(handles.lb_accuracy,'String',num2str(patRec.performance.acc(1:end-1),'%.2f')); + set(handles.et_accTrue,'String',num2str(patRec.performance.accTrue(end),'%.2f')); + set(handles.lb_accTrue,'String',num2str(patRec.performance.accTrue(1:end-1),'%.2f')); + set(handles.et_precision,'String',num2str(patRec.performance.precision(end),'%.2f')); + set(handles.lb_precision,'String',num2str(patRec.performance.precision(1:end-1),'%.2f')); + set(handles.et_recall,'String',num2str(patRec.performance.recall(end),'%.2f')); + set(handles.lb_recall,'String',num2str(patRec.performance.recall(1:end-1),'%.2f')); + set(handles.et_f1,'String',num2str(patRec.performance.f1(end),'%.2f')); + set(handles.lb_f1,'String',num2str(patRec.performance.f1(1:end-1),'%.2f')); + set(handles.et_specificity,'String',num2str(patRec.performance.specificity(end),'%.2f')); + set(handles.lb_specificity,'String',num2str(patRec.performance.specificity(1:end-1),'%.2f')); + set(handles.et_npv,'String',num2str(patRec.performance.npv(end),'%.2f')); + set(handles.lb_npv,'String',num2str(patRec.performance.npv(1:end-1),'%.2f')); + set(handles.et_trTime,'String',num2str(patRec.trTime)); set(handles.et_tTime,'String',num2str(patRec.tTime)); set(handles.pb_RealtimePatRecGUI,'Enable','on'); @@ -319,7 +404,7 @@ function pm_SelectAlgorithm_Callback(hObject, eventdata, handles) strcmp(alg,'MLP thOut') set(handles.pm_SelectTraining,'Enable','on'); - tA = {'Select Training A.','Backpropagation', 'PSO'}; + tA = {'Select Training A.','Backpropagation', 'EA', 'PSO'}; set(handles.pm_SelectTraining,'String',tA); set(handles.pb_RunOfflineTraining,'Enable','off'); set(handles.pm_normSets,'Value',4); @@ -331,7 +416,7 @@ function pm_SelectAlgorithm_Callback(hObject, eventdata, handles) set(handles.pb_RunOfflineTraining,'Enable','off'); set(handles.pm_normSets,'Value',1); - elseif strcmp(alg,'RFN') + elseif strcmp(alg,'RFN') % for LDA set(handles.pm_SelectTraining,'Enable','on'); tA = {'Select Training A.','Mean','Mean + PSO','Exclusive Mean'}; set(handles.pm_SelectTraining,'String',tA); @@ -354,8 +439,15 @@ function pm_SelectAlgorithm_Callback(hObject, eventdata, handles) set(handles.pm_SelectTraining,'String',tA); set(handles.pm_SelectTraining,'Value',1); set(handles.pb_RunOfflineTraining,'Enable','off'); - set(handles.pm_normSets,'Value',5); + set(handles.pm_normSets,'Value',5); + elseif strcmp(alg,'SVM'); % for SVM + set(handles.pm_SelectTraining,'Enable','on'); + tA = {'Select Training A.','linear', 'quadratic', 'polynomial', 'rbf', 'mlp'}; + set(handles.pm_SelectTraining,'String',tA); + set(handles.pm_SelectTraining,'Value',1); + set(handles.pb_RunOfflineTraining,'Enable','on'); + set(handles.pm_normSets,'Value',4); end @@ -712,7 +804,7 @@ function m_Stats_CurrentD_Callback(hObject, eventdata, handles) nRep = str2double(inputdlg('Write the number of repetitions','Number of Runs')); nM = size(get(handles.lb_movements,'String'),1); - confMatFlag = get(handles.cb_confMat,'Value') + confMatFlag = get(handles.cb_confMat,'Value'); % safety check if isempty(nRep) @@ -722,41 +814,49 @@ function m_Stats_CurrentD_Callback(hObject, eventdata, handles) errordlg('Invalid number','Error') return; end + + % Init variables + accCS = zeros(nRep,nM+1); + accTrue = zeros(nRep,nM+1); + precision = zeros(nRep,nM+1); + recall = zeros(nRep,nM+1); + f1 = zeros(nRep,nM+1); + specificity = zeros(nRep,nM+1); + npv = zeros(nRep,nM+1); - % run the training the given number of times - acc = zeros(nRep,nM+1); trTime = zeros(1,nRep); - tTime = zeros(1,nRep); - + tTime = zeros(1,nRep); tStd = inf; tAcc = 0; + % run the training the given number of times for i = 1 : nRep pb_RunOfflineTraining_Callback(hObject, eventdata, handles); patRec = get(handles.et_accuracy,'UserData'); - tempAcc = patRec.acc; - %tempAcc = get(handles.lb_accuracy,'UserData'); - %tempAcc = handles.patRec.acc; % Handles cannot be used because - %once the training is done, the new "patRec" is not updated into - %handles since the handles variable was recieved before calling - %the training. + tempPerformance = patRec.performance; if confMatFlag tempConfMat(:,:,i) = patRec.confMat; end - acc(i,:) = tempAcc; - trTime(i) = patRec.trTime; - tTime(i) = patRec.tTime; + accCS(i,:) = tempPerformance.acc; + accTrue(i,:) = tempPerformance.accTrue; + precision(i,:) = tempPerformance.precision; + recall(i,:) = tempPerformance.recall; + f1(i,:) = tempPerformance.f1; + specificity(i,:)= tempPerformance.specificity; + npv(i,:) = tempPerformance.npv; + trTime(i) = patRec.trTime; + tTime(i) = patRec.tTime; set(handles.t_msg,'String',['Runing ' num2str(i)]); drawnow; % Save the best patRec % if std(tempAcc(1:end-1)) <= tStd && tempAcc(end) >= tAcc - if tempAcc(end) >= tAcc + if tempPerformance.acc(end) >= tAcc % tStd = std(tempAcc(1:end-1)); - tAcc = tempAcc(end); + tAcc = tempPerformance.acc(end); tempPatRec = patRec; end @@ -769,22 +869,80 @@ function m_Stats_CurrentD_Callback(hObject, eventdata, handles) %Old way to transfer data between GUIs %set(handles.et_accuracy,'UserData',tempPatRec); - % show results - tAcc = mean(acc); - set(handles.et_accuracy,'String',num2str(tAcc(end))); - set(handles.lb_accuracy,'String',num2str(tAcc(1:end-1)')); + % Display results + tAcc = mean(accCS); + set(handles.et_accuracy,'String',num2str(tAcc(end),'%.2f')); + set(handles.lb_accuracy,'String',num2str(tAcc(1:end-1)','%.2f')); set(handles.et_trTime,'String',num2str(mean(trTime))); set(handles.et_tTime,'String',num2str(mean(tTime))); + + set(handles.et_accTrue,'String',num2str(mean(accTrue(:,end)),'%.2f')); + set(handles.lb_accTrue,'String',num2str(mean(accTrue(:,1:end-1))','%.2f')); + set(handles.et_precision,'String',num2str(mean(precision(:,end)),'%.2f')); + set(handles.lb_precision,'String',num2str(mean(precision(:,1:end-1))','%.2f')); + set(handles.et_recall,'String',num2str(mean(recall(:,end)),'%.2f')); + set(handles.lb_recall,'String',num2str(mean(recall(:,1:end-1))','%.2f')); + set(handles.et_f1,'String',num2str(mean(f1(:,end)),'%.2f')); + set(handles.lb_f1,'String',num2str(mean(f1(:,1:end-1))','%.2f')); + set(handles.et_specificity,'String',num2str(mean(specificity(:,end)),'%.2f')); + set(handles.lb_specificity,'String',num2str(mean(specificity(:,1:end-1))','%.2f')); + set(handles.et_npv,'String',num2str(mean(npv(:,end)),'%.2f')); + set(handles.lb_npv,'String',num2str(mean(npv(:,1:end-1))','%.2f')); + % plot results figure(); - boxplot(acc,'plotstyle','compact') + boxplot(accCS,'plotstyle','compact') + hold on; + plot(mean(accCS),'r*'); + xlabel('Movements'); + ylabel('Accuracy (class-specific)'); + + figure(); + boxplot(accTrue,'plotstyle','compact') + hold on; + plot(mean(accTrue),'r*'); + xlabel('Movements'); + ylabel('Accuracy (Global)'); + + figure(); + boxplot(recall,'plotstyle','compact') + hold on; + plot(mean(recall),'r*'); + xlabel('Movements'); + ylabel('Recall'); + + figure(); + boxplot(precision,'plotstyle','compact') + hold on; + plot(mean(precision),'r*'); + xlabel('Movements'); + ylabel('Precision (PPV)'); + + figure(); + boxplot(f1,'plotstyle','compact') + hold on; + plot(mean(f1),'r*'); + xlabel('Movements'); + ylabel('F1'); + + figure(); + boxplot(specificity,'plotstyle','compact') + hold on; + plot(mean(specificity),'r*'); + xlabel('Movements'); + ylabel('Specificity'); + + figure(); + boxplot(npv,'plotstyle','compact') hold on; - plot(mean(acc),'r*'); - title('Pattern recognition accuracy') + plot(mean(npv),'r*'); xlabel('Movements'); - ylabel('Accuracy'); + ylabel('Negative Predicted Value (NPV)'); + + + % Confution matrix if confMatFlag figure(); confMat = mean(tempConfMat,3); @@ -809,18 +967,42 @@ function m_Stats_CurrentD_Callback(hObject, eventdata, handles) stats.topology = patRec.topology; stats.patRecTrained = patRec.patRecTrained; stats.norm = patRec.normSets; - stats.mean = tAcc; - stats.std = std(acc); - stats.min = min(acc); - stats.max = max(acc); - stats.acc = acc; + + stats.accCS = accCS; + stats.accCSmn = mean(accCS)'; + stats.accCSstd = std(accCS)'; + + stats.accTrue = accTrue; + stats.accTruemn = mean(accTrue)'; + stats.accTruestd = std(accTrue)'; + + stats.recall = recall; + stats.recallmn = mean(recall)'; + stats.recallstd = std(recall)'; + + stats.precision = precision; + stats.precisionmn = mean(precision)'; + stats.precisionstd = std(precision)'; + + stats.f1 = f1; + stats.f1mn = mean(f1)'; + stats.f1std = std(f1)'; + + stats.specificity = specificity; + stats.specificitymn = mean(specificity)'; + stats.specificitystd= std(specificity)'; + + stats.npv = npv; + stats.npvmn = mean(npv)'; + stats.npvstd = std(npv)'; + if confMatFlag - stats.confMat = confMat; + stats.confMat = confMat; end - stats.trTime = trTime; - stats.tTime = tTime; - stats.trTimeMean = mean(trTime); - stats.tTimeMean = mean(tTime); + stats.trTime = trTime; + stats.tTime = tTime; + stats.trTimeMean= mean(trTime); + stats.tTimeMean = mean(tTime); disp(stats); save('stats.mat','stats'); @@ -874,10 +1056,24 @@ function m_Stats_Group_Callback(hObject, eventdata, handles) end nM = size(get(handles.lb_movements,'String'),1); - acc = zeros(nRep,nM+1,nS); + accCS = zeros(nRep,nM+1,nS); + accTrue = zeros(nRep,nM+1,nS); + precision = zeros(nRep,nM+1,nS); + recall = zeros(nRep,nM+1,nS); + f1 = zeros(nRep,nM+1,nS); + specificity = zeros(nRep,nM+1,nS); + npv = zeros(nRep,nM+1,nS); trTime = zeros(nRep,nS); tTime = zeros(nRep,nS); - tAcc = zeros(nS,nM+1); + + % temporal variable with subjects average + tAccCS = zeros(nS,nM+1); + tAccTrue = zeros(nS,nM+1); + tRecall = zeros(nS,nM+1); + tPrecision = zeros(nS,nM+1); + tF1 = zeros(nS,nM+1); + tSpecificity= zeros(nS,nM+1); + tNPV = zeros(nS,nM+1); for i = 1 : nS % load data @@ -897,50 +1093,61 @@ function m_Stats_Group_Callback(hObject, eventdata, handles) % run the training the given number of times for j = 1 : nRep set(handles.t_msg2,'String',['Statistics Rep: ' num2str(j) ' from subject: ' num2str(i)]); - - pb_RunOfflineTraining_Callback(hObject, eventdata, handles) + pb_RunOfflineTraining_Callback(hObject, eventdata, handles); patRec = get(handles.et_accuracy,'UserData'); - acc(j,:,i) = get(handles.lb_accuracy,'UserData'); + tempPerformance = patRec.performance; + + accCS(j,:,i) = tempPerformance.acc; + accTrue(j,:,i) = tempPerformance.accTrue; + precision(j,:,i) = tempPerformance.precision; + recall(j,:,i) = tempPerformance.recall; + f1(j,:,i) = tempPerformance.f1; + specificity(j,:,i)= tempPerformance.specificity; + npv(j,:,i) = tempPerformance.npv; + trTime(j,i) = patRec.trTime; - tTime(j,i) = patRec.tTime; + tTime(j,i) = patRec.tTime; drawnow; end - % show results - tAcc(i,:) = mean(acc(:,:,i)); - set(handles.et_accuracy,'String',num2str(tAcc(i,end))); - set(handles.lb_accuracy,'String',num2str(tAcc(i,1:end-1)')); + % save results + tAccCS(i,:) = mean(accCS(:,:,i)); + tAccTrue(i,:) = mean(accTrue(:,:,i)); + tRecall(i,:) = mean(recall(:,:,i)); + tPrecision(i,:) = mean(precision(:,:,i)); + tF1(i,:) = mean(f1(:,:,i)); + tSpecificity(i,:) = mean(specificity(:,:,i)); + tNPV(i,:) = mean(npv(:,:,i)); % plot figure(); - boxplot(acc(:,:,i),'plotstyle','compact') + boxplot(accCS(:,:,i),'plotstyle','compact') hold on; - plot(mean(acc(:,:,i)),'r*'); - title(['Pattern recognition accuracy: #' num2str(i)]); + plot(mean(accCS(:,:,i)),'r*'); xlabel('Movements'); - ylabel('Accuracy'); + ylabel('Accuracy (class-specific)'); end set(handles.t_msg2,'String',''); % plot per movement figure(); - boxplot(tAcc,'plotstyle','compact') + boxplot(tAccCS,'plotstyle','compact') hold on; - plot(mean(tAcc),'r*'); + plot(mean(tAccCS),'r*'); title('Pattern recognition accuracy, All subjects') xlabel('Movements'); - ylabel('Accuracy'); + ylabel('Accuracy (class-specific)'); % plots per subject figure(); - boxplot(tAcc(:,1:end-1)','plotstyle','compact') + boxplot(tAccCS(:,1:end-1)','plotstyle','compact') hold on; - plot(mean(tAcc(:,1:end-1),2),'r*'); + plot(mean(tAccCS(:,1:end-1),2),'r*'); title('Pattern recognition accuracy, All subjects') xlabel('Subjects'); - ylabel('Accuracy'); + ylabel('Accuracy (class-specific)'); % Signal features fIdx = get(handles.lb_features,'Value'); @@ -948,47 +1155,95 @@ function m_Stats_Group_Callback(hObject, eventdata, handles) features = features(fIdx); % Save stats - patRec = get(handles.et_accuracy,'UserData'); + patRec = get(handles.et_accuracy,'UserData'); stats.nSubjects = nS; stats.nRep = nRep; stats.nM = nM; - stats.features = features; - stats.algorithm = patRec.patRecTrained(end).algorithm; - stats.training = patRec.patRecTrained(end).training; - stats.topology = patRec.topology; - stats.norm = patRec.normSets.type; - stats.meanSub = mean(tAcc(:,end)); - stats.stdSub = std(tAcc(:,end)); - stats.minSub = min(tAcc(:,end)); - stats.maxSub = max(tAcc(:,end)); - stats.meanMov = mean(mean(tAcc(:,1:end-1))); - stats.stdMov = std(std(tAcc(:,1:end-1))); - stats.minMov = min(min(tAcc(:,1:end-1))); - stats.maxMov = max(max(tAcc(:,1:end-1))); - - stats.meanXSub = tAcc(:,end); - stats.stdXSub = std(tAcc(:,1:end-1)')'; - stats.minXSub = min(tAcc(:,1:end-1)')'; - stats.maxXSub = max(tAcc(:,1:end-1)')'; - - stats.meanXMov = mean(tAcc(:,1:end-1)); - stats.stdXMov = std(tAcc(:,1:end-1)); - stats.minXMov = min(tAcc(:,1:end-1)); - stats.maxXMov = max(tAcc(:,1:end-1)); - - stats.accXSub = tAcc(:,1:end-1)'; - stats.accXMov = tAcc; - stats.accAll = acc; + + stats.features.features = features; + stats.features.trSets = str2double(get(handles.et_trSets,'String')); + stats.features.vSets = str2double(get(handles.et_vSets,'String')); + stats.features.tSets = str2double(get(handles.et_tSets,'String')); + + stats.algorithm = patRec.patRecTrained(end).algorithm; + stats.training = patRec.patRecTrained(end).training; + stats.topology = patRec.topology; + stats.norm = patRec.normSets.type; + stats.lastPatRec = patRec; + +% stats.meanSub = mean(tAccCS(:,end)); +% stats.stdSub = std(tAccCS(:,end)); +% stats.minSub = min(tAccCS(:,end)); +% stats.maxSub = max(tAccCS(:,end)); +% stats.meanMov = mean(mean(tAccCS(:,1:end-1))); +% stats.stdMov = std(std(tAccCS(:,1:end-1))); +% stats.minMov = min(min(tAccCS(:,1:end-1))); +% stats.maxMov = max(max(tAccCS(:,1:end-1))); +% +% stats.meanXSub = tAccCS(:,end); +% stats.stdXSub = std(tAccCS(:,1:end-1)')'; +% stats.minXSub = min(tAccCS(:,1:end-1)')'; +% stats.maxXSub = max(tAccCS(:,1:end-1)')'; +% +% stats.meanXMov = mean(tAccCS(:,1:end-1)); +% stats.stdXMov = std(tAccCS(:,1:end-1)); +% stats.minXMov = min(tAccCS(:,1:end-1)); +% stats.maxXMov = max(tAccCS(:,1:end-1)); + + stats.accCS = accCS; + stats.accCSXSub = tAccCS(:,1:end-1)'; + stats.accCSXMov = tAccCS; + + stats.accTrue = accTrue; + stats.accTrueXSub = tAccTrue(:,1:end-1)'; + stats.accTrueXMov = tAccTrue; + + stats.recall = recall; + stats.recallXSub = tRecall(:,1:end-1)'; + stats.recallXMov = tRecall; + + stats.precision = recall; + stats.precisionXSub = tPrecision(:,1:end-1)'; + stats.precisionXMov = tPrecision; + + stats.f1 = f1; + stats.f1XSub = tF1(:,1:end-1)'; + stats.f1XMov = tF1; + + stats.specificity = specificity; + stats.specificityXSub = tSpecificity(:,1:end-1)'; + stats.specificityXMov = tSpecificity; + + stats.npv = npv; + stats.npvXSub = tNPV(:,1:end-1)'; + stats.npvXMov = tNPV; stats.trTime = trTime; - stats.tTime = tTime; + stats.tTime = tTime; disp(stats); save('stats.mat','stats'); - set(handles.et_accuracy,'String',num2str(stats.meanMov)); - set(handles.lb_accuracy,'String',num2str(stats.meanXMov')); - + set(handles.et_accuracy,'String',num2str(mean(tAccCS(:,end)),'%.2f')); + set(handles.lb_accuracy,'String',num2str(mean(tAccCS(:,1:end-1))','%.2f')); + + set(handles.et_accTrue,'String',num2str(mean(tAccTrue(:,end)),'%.2f')); + set(handles.lb_accTrue,'String',num2str(mean(tAccTrue(:,1:end-1))','%.2f')); + set(handles.et_precision,'String',num2str(mean(tPrecision(:,end)),'%.2f')); + set(handles.lb_precision,'String',num2str(mean(tPrecision(:,1:end-1))','%.2f')); + set(handles.et_recall,'String',num2str(mean(tRecall(:,end)),'%.2f')); + set(handles.lb_recall,'String',num2str(mean(tRecall(:,1:end-1))','%.2f')); + set(handles.et_f1,'String',num2str(mean(tF1(:,end)),'%.2f')); + set(handles.lb_f1,'String',num2str(mean(tF1(:,1:end-1))','%.2f')); + set(handles.et_specificity,'String',num2str(mean(tSpecificity(:,end)),'%.2f')); + set(handles.lb_specificity,'String',num2str(mean(tSpecificity(:,1:end-1))','%.2f')); + set(handles.et_npv,'String',num2str(mean(tNPV(:,end)),'%.2f')); + set(handles.lb_npv,'String',num2str(mean(tNPV(:,1:end-1))','%.2f')); + + set(handles.et_trTime,'String',num2str(mean(mean(trTime,2)))); + set(handles.et_tTime,'String',num2str(mean(mean(tTime,2)))); + + set(handles.t_msg,'String','Statistics completed and saved in the "stast.mat" file'); @@ -1362,3 +1617,559 @@ function cb_floorNoise_Callback(hObject, eventdata, handles) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of cb_floorNoise + + +% --- Executes on selection change in pm_FeatureReduction. +function pm_FeatureReduction_Callback(hObject, eventdata, handles) +% hObject handle to pm_FeatureReduction (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_FeatureReduction contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_FeatureReduction + allFeatures = cellstr(get(handles.lb_features,'String')); + allFeatReducAlg=get(handles.pm_FeatureReduction,'String'); + selFeatReduc=char(allFeatReducAlg(get(handles.pm_FeatureReduction,'Value'))); + if strcmp(selFeatReduc,'PCA') + set(handles.lb_features,'Value',1:length(allFeatures)); + end + + +% --- Executes during object creation, after setting all properties. +function pm_FeatureReduction_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_FeatureReduction (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 selection change in lb_precision. +function lb_precision_Callback(hObject, eventdata, handles) +% hObject handle to lb_precision (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_precision contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_precision + + +% --- Executes during object creation, after setting all properties. +function lb_precision_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_precision (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 + + +% --- Executes on selection change in listbox5. +function listbox5_Callback(hObject, eventdata, handles) +% hObject handle to listbox5 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns listbox5 contents as cell array +% contents{get(hObject,'Value')} returns selected item from listbox5 + + +% --- Executes during object creation, after setting all properties. +function listbox5_CreateFcn(hObject, eventdata, handles) +% hObject handle to listbox5 (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 + + +% --- Executes on selection change in listbox6. +function listbox6_Callback(hObject, eventdata, handles) +% hObject handle to listbox6 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns listbox6 contents as cell array +% contents{get(hObject,'Value')} returns selected item from listbox6 + + +% --- Executes during object creation, after setting all properties. +function listbox6_CreateFcn(hObject, eventdata, handles) +% hObject handle to listbox6 (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 edit12_Callback(hObject, eventdata, handles) +% hObject handle to edit12 (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 edit12 as text +% str2double(get(hObject,'String')) returns contents of edit12 as a double + + +% --- Executes during object creation, after setting all properties. +function edit12_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit12 (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 + + + +function edit13_Callback(hObject, eventdata, handles) +% hObject handle to edit13 (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 edit13 as text +% str2double(get(hObject,'String')) returns contents of edit13 as a double + + +% --- Executes during object creation, after setting all properties. +function edit13_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit13 (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 + + + +function edit14_Callback(hObject, eventdata, handles) +% hObject handle to edit14 (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 edit14 as text +% str2double(get(hObject,'String')) returns contents of edit14 as a double + + +% --- Executes during object creation, after setting all properties. +function edit14_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit14 (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 selection change in lb_recall. +function lb_recall_Callback(hObject, eventdata, handles) +% hObject handle to lb_recall (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_recall contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_recall + + +% --- Executes during object creation, after setting all properties. +function lb_recall_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_recall (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 + + +% --- Executes on selection change in lb_f1. +function lb_f1_Callback(hObject, eventdata, handles) +% hObject handle to lb_f1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_f1 contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_f1 + + +% --- Executes during object creation, after setting all properties. +function lb_f1_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_f1 (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 et_precision_Callback(hObject, eventdata, handles) +% hObject handle to et_precision (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 et_precision as text +% str2double(get(hObject,'String')) returns contents of et_precision as a double + + +% --- Executes during object creation, after setting all properties. +function et_precision_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_precision (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 + + + +function edit16_Callback(hObject, eventdata, handles) +% hObject handle to edit16 (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 edit16 as text +% str2double(get(hObject,'String')) returns contents of edit16 as a double + + +% --- Executes during object creation, after setting all properties. +function edit16_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit16 (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 + + + +function edit17_Callback(hObject, eventdata, handles) +% hObject handle to edit17 (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 edit17 as text +% str2double(get(hObject,'String')) returns contents of edit17 as a double + + +% --- Executes during object creation, after setting all properties. +function edit17_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit17 (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 + + +function edit19_Callback(hObject, eventdata, handles) +% hObject handle to edit19 (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 edit19 as text +% str2double(get(hObject,'String')) returns contents of edit19 as a double + + +% --- Executes during object creation, after setting all properties. +function edit19_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit19 (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 + + + +function edit20_Callback(hObject, eventdata, handles) +% hObject handle to edit20 (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 edit20 as text +% str2double(get(hObject,'String')) returns contents of edit20 as a double + + +% --- Executes during object creation, after setting all properties. +function edit20_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit20 (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 + + + +function et_f1_Callback(hObject, eventdata, handles) +% hObject handle to et_f1 (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 et_f1 as text +% str2double(get(hObject,'String')) returns contents of et_f1 as a double + + +% --- Executes during object creation, after setting all properties. +function et_f1_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_f1 (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 + + + +function edit22_Callback(hObject, eventdata, handles) +% hObject handle to edit22 (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 edit22 as text +% str2double(get(hObject,'String')) returns contents of edit22 as a double + + +% --- Executes during object creation, after setting all properties. +function edit22_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit22 (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 + + + +function edit23_Callback(hObject, eventdata, handles) +% hObject handle to edit23 (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 edit23 as text +% str2double(get(hObject,'String')) returns contents of edit23 as a double + + +% --- Executes during object creation, after setting all properties. +function edit23_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit23 (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 + +% % % % +function et_recall_Callback(hObject, eventdata, handles) +% hObject handle to et_recall (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 et_recall as text +% str2double(get(hObject,'String')) returns contents of et_recall as a double + + +% --- Executes during object creation, after setting all properties. +function et_recall_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_recall (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 selection change in lb_specificity. +function lb_specificity_Callback(hObject, eventdata, handles) +% hObject handle to lb_specificity (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_specificity contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_specificity + + +% --- Executes during object creation, after setting all properties. +function lb_specificity_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_specificity (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 et_specificity_Callback(hObject, eventdata, handles) +% hObject handle to et_specificity (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 et_specificity as text +% str2double(get(hObject,'String')) returns contents of et_specificity as a double + + +% --- Executes during object creation, after setting all properties. +function et_specificity_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_specificity (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 selection change in lb_npv. +function lb_npv_Callback(hObject, eventdata, handles) +% hObject handle to lb_npv (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_npv contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_npv + + +% --- Executes during object creation, after setting all properties. +function lb_npv_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_npv (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 et_npv_Callback(hObject, eventdata, handles) +% hObject handle to et_npv (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 et_npv as text +% str2double(get(hObject,'String')) returns contents of et_npv as a double + + +% --- Executes during object creation, after setting all properties. +function et_npv_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_npv (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 selection change in lb_accTrue. +function lb_accTrue_Callback(hObject, eventdata, handles) +% hObject handle to lb_accTrue (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns lb_accTrue contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_accTrue + + +% --- Executes during object creation, after setting all properties. +function lb_accTrue_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_accTrue (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 et_accTrue_Callback(hObject, eventdata, handles) +% hObject handle to et_accTrue (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 et_accTrue as text +% str2double(get(hObject,'String')) returns contents of et_accTrue as a double + + +% --- Executes during object creation, after setting all properties. +function et_accTrue_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_accTrue (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 diff --git a/PatRec/GUI_TacTest.fig b/PatRec/GUI_TacTest.fig index 8def011..c6075f3 100644 Binary files a/PatRec/GUI_TacTest.fig and b/PatRec/GUI_TacTest.fig differ diff --git a/PatRec/GUI_TestPatRec_Mov2Mov.fig b/PatRec/GUI_TestPatRec_Mov2Mov.fig index acb5527..e759841 100644 Binary files a/PatRec/GUI_TestPatRec_Mov2Mov.fig and b/PatRec/GUI_TestPatRec_Mov2Mov.fig differ diff --git a/PatRec/GUI_TestPatRec_Mov2Mov.m b/PatRec/GUI_TestPatRec_Mov2Mov.m index 43161e2..c022b60 100644 --- a/PatRec/GUI_TestPatRec_Mov2Mov.m +++ b/PatRec/GUI_TestPatRec_Mov2Mov.m @@ -47,6 +47,13 @@ % 2012-11-23 / Joel Falk-Dahlin / Moved all speeds from handles to the % patRec struct. Changed behavior of all % speed text boxes +% 2015-07-16 / Enzo Mastinu / Framework for movements and motors +% implemented, the SPC control does not need +% anymore the MoveMotorWifi or any dedicated +% SPC functions +% 2015-07-21 / Francesco Clemente / Folder select routines for the Control +% Framework. Connection to the robotic +% devices has been improved with WiFi fields % % 20xx-xx-xx / Author / Comment on update @@ -74,7 +81,7 @@ % Edit the above text to modify the response to help GUI_TestPatRec_Mov2Mov -% Last Modified by GUIDE v2.5 21-Mar-2013 10:08:43 +% Last Modified by GUIDE v2.5 21-Jul-2015 13:39:26 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -109,10 +116,13 @@ function GUI_TestPatRec_Mov2Mov_OpeningFcn(hObject, eventdata, handles, varargin % Choose default command line output for GUI_TestPatRec_Mov2Mov handles.output = hObject; global TAC +global ctrl_dir TAC.running = 0; TAC.ackTimes = 0; + + % Check if any inputs is made when calling the GUI if ~isempty(varargin) % Check if varargin{1} is a patRec @@ -136,6 +146,13 @@ function GUI_TestPatRec_Mov2Mov_OpeningFcn(hObject, eventdata, handles, varargin end end + +% serialportlist = instrhwinfo('serial'); +% serialportlist = serialportlist.SerialPorts; +% for i=1:size(serialportlist) +% set(handles.popmenu16,'String',serialportlist(i)); +% end + end % Logo image @@ -154,7 +171,7 @@ function GUI_TestPatRec_Mov2Mov_OpeningFcn(hObject, eventdata, handles, varargin guidata(hObject, handles); % UIWAIT makes GUI_TestPatRec_Mov2Mov wait for user response (see UIRESUME) -% uiwait(handles.figure1); +% uiwait(handles.Gui1); movegui(hObject,'center'); % --- Outputs from this function are returned to the command line. @@ -291,7 +308,7 @@ function pb_RealtimePatRec_Callback(hObject, eventdata, handles) % hObject handle to pb_RealtimePatRec (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - +set(hObject, 'Enable', 'off'); %set(hObject,'Enable','off'); % validation of patRec loaded if ~isfield(handles,'patRec') @@ -1114,7 +1131,6 @@ function pb_move1_Callback(hObject, eventdata, handles) % Get the degrees to move movDeg = str2double(get(handles.et_speed1,'String')); - %Check whether to use VRE if isfield(handles,'vre_Com') global TAC @@ -1127,15 +1143,24 @@ function pb_move1_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + if ~strcmp(Control_obj.status,'open') + fopen(Control_obj); + end + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); + end %Enable the button set(hObject,'Enable','on'); @@ -1169,12 +1194,20 @@ function pb_move2_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + if ~strcmp(Control_obj.status,'open') + fopen(Control_obj); + end + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1210,12 +1243,20 @@ function pb_move3_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + if ~strcmp(Control_obj.status,'open') + fopen(Control_obj); + end + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1251,12 +1292,20 @@ function pb_move4_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + if ~strcmp(Control_obj.status,'open') + fopen(Control_obj); + end + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1293,12 +1342,17 @@ function pb_move5_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1335,12 +1389,17 @@ function pb_move6_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1382,12 +1441,17 @@ function pb_move10_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1424,12 +1488,17 @@ function pb_move9_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1466,12 +1535,17 @@ function pb_move8_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1508,12 +1582,20 @@ function pb_move7_Callback(hObject, eventdata, handles) end end if get(handles.cb_motorCoupling,'Value') - % Get the communication obj - com = handles.com; + % Get the motors obj motors = handles.motors; + % Get the communication obj + Control_obj = handles.Control_obj; + if ~strcmp(Control_obj.status,'open') + fopen(Control_obj); + end + %Activate the motor direction for a short moment. - [motors,movement] = MoveMotor(com, movement, movDeg, motors); + MotorsOn(Control_obj, movement, motors, movDeg); + pause(1); + MotorsOff(Control_obj, movement, motors); + % Save data back handles.mov(mov) = movement; handles.motors = motors; guidata(hObject,handles); @@ -1526,19 +1608,28 @@ function pb_connect_Callback(hObject, eventdata, handles) % hObject handle to pb_connect (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -compath = get(handles.et_connect,'String'); -handles.com = Connect_ALC(compath); -%handles.com = MasterModuleComm(compath); -if TestConnectionALC(handles.com)==1; %Write S to stop program - set(handles.t_msg,'String','Connection established'); - guidata(hObject,handles); -else - set(handles.t_msg,'String','Wrong connection'); - fclose(handles.com.io); + +if get(handles.rb_serial, 'Value') + compath_idx = get(handles.pm_serialportipaddress,'Value'); + compath = get(handles.pm_serialportipaddress,'string'); + compath = compath(compath_idx); + BaudRate = str2double(get(handles.et_baudrateport,'String')); + Control_obj = serial(compath, 'BaudRate', BaudRate); +elseif get(handles.rb_wifi, 'Value') + ip = get(handles.pm_serialportipaddress,'String'); + port = str2double(get(handles.et_baudrateport,'String')); + Control_obj = tcpip(ip,port,'NetworkRole','client'); end +fopen(Control_obj); +set(handles.t_msg,'String','Connection established!'); + +handles.Control_obj = Control_obj; +guidata(hObject,handles); set(handles.pb_testConnection,'Enable','on'); set(handles.pb_disconnect,'Enable','on'); +set(handles.pb_sensors,'Enable','on'); + function et_connect_Callback(hObject, eventdata, handles) % hObject handle to et_connect (see GCBO) @@ -1567,10 +1658,12 @@ function pb_disconnect_Callback(hObject, eventdata, handles) % hObject handle to pb_disconnect (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -fclose(handles.com.io); + +fclose(handles.Control_obj) set(handles.t_msg,'String','Disconnected'); set(handles.pb_testConnection,'Enable','off'); set(handles.pb_disconnect,'Enable','off'); +set(handles.pb_sensors,'Enable','off'); % --- Executes on button press in pb_testConnection. function pb_testConnection_Callback(hObject, eventdata, handles) @@ -1578,13 +1671,47 @@ function pb_testConnection_Callback(hObject, eventdata, handles) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) set(handles.t_msg,'String','Testing connection...'); -if TestConnectionALC(handles.com)==1; %Write S to stop program - set(handles.t_msg,'String','Connection established'); - guidata(hObject,handles); + +if TestConnection(handles.Control_obj) + set(handles.t_msg,'String','Connection OK'); else set(handles.t_msg,'String','Wrong connection'); - fclose(handles.com.io); -end + fclose(handles.Control_obj); +end + +% % obtained the ID of the selected device +% device = get(handles.pm_prosthesis,'Value'); +% % run connecting routine accordingly +% if device == 1 % Multifunctinal prosthesis with DC motors +% if TestConnectionALC(handles.Control_obj)==1; %Write S to stop program +% set(handles.t_msg,'String','Connection established'); +% guidata(hObject,handles); +% else +% set(handles.t_msg,'String','Wrong connection'); +% fclose(handles.Control_obj.io); +% end +% elseif device == 3 % Standard prosthetic units (wireless) +% if isfield(handles,'Control_obj') +% Control_obj = handles.Control_obj; +% disp(Control_obj); +% fclose(Control_obj); +% else +% Control_obj = tcpip('192.168.100.10',65100,'NetworkRole','client'); +% end +% % Open connection +% fopen(Control_obj); +% fwrite(Control_obj,'A','char'); +% fwrite(Control_obj,'C','char') +% replay = char(fread(Control_obj,1,'char')); +% if strcmp(replay,'C'); +% set(handles.t_msg,'String','Connection established!'); +% else +% set(handles.t_msg,'String','Error'); +% end +% fclose(Control_obj); +% handles.Control_obj = Control_obj; +% guidata(hObject,handles); +% end @@ -1838,36 +1965,9 @@ function pb_socketConnect_Callback(hObject, eventdata, handles) % hObject handle to pb_socketConnect (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - set(handles.pb_socketConnect,'Enable','off'); - % Dialog box to open a file -%[file, path] = uigetfile('*.exe'); -% Check that the loaded file is a "ss" struct -%if ~isequal(file, 0) -% startString = sprintf('start /D%s %s',path,file); -% disp(startString); -% [a,b] = system(startString); -%end - -% This starts the VRE-environment. Add support for different paths? -open('Virtual Reality.exe'); - -%Retrieves specified port. -port = str2double(get(handles.et_port,'String')); - -set(handles.t_msg,'String','Waiting for client connection.'); +handles = ConnectVRE(handles,'Virtual Reality.exe'); guidata(hObject,handles); -obj = tcpip('127.0.0.1',port,'NetworkRole','server'); - -fopen(obj); -set(handles.t_msg,'String',sprintf('Server established on port %d.',port)); -handles.vre_Com = obj; -guidata(hObject,handles); - -set(handles.pb_socketDisconnect,'Enable','on'); -set(handles.pb_Camera,'Enable','on'); -set(handles.pb_ActivateArm,'Enable','on'); - % --- Executes during object creation, after setting all properties. function et_port_CreateFcn(hObject, eventdata, handles) % hObject handle to et_port (see GCBO) @@ -1880,14 +1980,8 @@ function pb_socketDisconnect_Callback(hObject, eventdata, handles) % hObject handle to pb_socketDisconnect (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -set(handles.pb_socketDisconnect,'Enable','off'); -set(handles.pb_Camera,'Enable','off'); -set(handles.pb_ActivateArm,'Enable','off'); -obj = handles.vre_Com; -fclose(obj); -set(handles.t_msg,'String','Server disconnected.'); -handles.vre_Com = obj; - set(handles.pb_socketConnect,'Enable','on'); +handles = DisconnectVRE(handles); +guidata(hObject,handles); function et_port_Callback(hObject, eventdata, handles) @@ -1927,11 +2021,10 @@ function pb_Camera_Callback(hObject, eventdata, handles) % hObject handle to pb_Camera (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -%if isfield(handles,'vre_Com') -obj = handles.vre_Com; -fwrite(obj,sprintf('%c%c%c%c','c',char(5),char(0),char(0))); -fread(obj,1); -%end +Control_obj = handles.vre_Com; +fwrite(Control_obj,sprintf('%c%c%c%c','c',char(5),char(0),char(0))); +fread(Control_obj,1); + % --- Executes on selection change in pm_controlAlg. @@ -1979,6 +2072,15 @@ function pm_controlAlg_CreateFcn(hObject, eventdata, handles) set(hObject,'String',names); + +% --- Executes on button press in pb_socketConnect2. +function pb_socketConnect2_Callback(hObject, eventdata, handles) +% hObject handle to pb_socketConnect2 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +handles = ConnectVRE(handles,'Augmented Reality.exe'); +guidata(hObject,handles); + % --- Executes on button press in cb_keys. function cb_keys_Callback(hObject, eventdata, handles) % hObject handle to cb_keys (see GCBO) @@ -2034,7 +2136,77 @@ function et_allSpeed_CreateFcn(hObject, eventdata, handles) end +% --- Executes on button press in cb_proportionalControl. +function cb_proportionalControl_Callback(hObject, eventdata, handles) +% hObject handle to cb_proportionalControl (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_proportionalControl + +% If proportional control checkbox is checked +if get(hObject,'Value') + % Create proportional control variables if patRec structure is loaded + if isfield(handles,'patRec') + % Increase maximum speed to 100 + handles.patRec.control.maxDegPerMov = ones(size(handles.patRec.control.maxDegPerMov)).*100; + set(handles.et_allSpeed,'String',100); + et_allSpeed_Callback(handles.et_allSpeed,eventdata,handles); + + % Initialize proportional control + handles.patRec = InitPropControl(handles.patRec); + + % Save guidata because it is used in GUI_ProportionalControl + guidata(hObject,handles); + + % Open proportional GUI + io.mainGUI = hObject; + setappdata(0,'selFeatures',handles.patRec.selFeatures) + GUI_ProportionalControl(io); + + % If no patRec is loaded in GUI, give message instead + else + set(t_msg,'String','No PatRec Loaded'); + end + +% If proportional control checkbox is unchecked +else + % Decrease maximum speed to 5 + handles.patRec.control.maxDegPerMov = ones(size(handles.patRec.control.maxDegPerMov)).*5; + set(handles.et_allSpeed,'String',5); + et_allSpeed_Callback(handles.et_allSpeed,eventdata,handles); + + % Remove all proportional control fields in patRec + if isfield(handles.patRec.control,'propControl') + handles.patRec.control = rmfield(handles.patRec.control,'propControl'); + end +end + +% Update GUI-handles +guidata(hObject,handles); + +% --- Executes on button press in pb_propGUI. +function pb_propGUI_Callback(hObject, eventdata, handles) +% hObject handle to pb_propGUI (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% If patRec is loaded, launch proportional Control GUI +if isfield(handles,'patRec') + + % If proportional control checkbox is unchecked, check it + if ~get(handles.cb_proportionalControl,'Value') + set(handles.cb_proportionalControl,'Value',1); + end + + io.mainGUI = hObject; + setappdata(0,'selFeatures',handles.patRec.selFeatures) + GUI_ProportionalControl(io); + +% If no patRec is loaded, give message +else + set(t_msg,'String','No PatRec Loaded'); +end % --- Executes on button press in pb_ActivateArm. @@ -2042,9 +2214,9 @@ function pb_ActivateArm_Callback(hObject, eventdata, handles) % hObject handle to pb_ActivateArm (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -obj = handles.vre_Com; -fwrite(obj,sprintf('%c%c%c%c%c','c',char(6),char(0),char(0),char(0))); -fread(obj,1); +Control_obj = handles.vre_Com; +fwrite(Control_obj,sprintf('%c%c%c%c%c','c',char(6),char(0),char(0),char(0))); +fread(Control_obj,1); % --- Executes on button press in pb_SetKeys. @@ -2062,3 +2234,255 @@ function cb_motionTestVRE_Callback(hObject, eventdata, handles) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of cb_motionTestVRE + + +% --- Executes on button press in pb_ARarm. +function pb_ARarm_Callback(hObject, eventdata, handles) +% hObject handle to pb_ARarm (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +handles = ConnectVRE(handles,'Augmented Reality ARM.exe'); +% Flex the elbow with 90 degrees. +VREActivation(handles.vre_Com,90,[],15,1,get(handles.cb_moveTAC,'Value')); +guidata(hObject,handles); + + +% --- Executes on selection change in pm_prosthesis. +function pm_prosthesis_Callback(hObject, eventdata, handles) +% hObject handle to pm_prosthesis (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_prosthesis contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_prosthesis + + +% --- Executes during object creation, after setting all properties. +function pm_prosthesis_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_prosthesis (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 cb_controls. +function cb_controls_Callback(hObject, eventdata, handles) +% hObject handle to cb_controls (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_controls + + +% --- Executes on button press in pb_enableRealTimePatRec. +function pb_enableRealTimePatRec_Callback(hObject, eventdata, handles) +% hObject handle to pb_enableRealTimePatRec (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +set(handles.pb_RealtimePatRec, 'Enable', 'on'); + + +% --- If Enable == 'on', executes on mouse press in 5 pixel border. +% --- Otherwise, executes on mouse press in 5 pixel border or over pb_ARarm. +function pb_ARarm_ButtonDownFcn(hObject, eventdata, handles) +% hObject handle to pb_ARarm (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + + +% --- Executes on button press in pb_sensors. +function pb_sensors_Callback(hObject, eventdata, handles) +% hObject handle to pb_sensors (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +GUI_Sensors(hObject, eventdata, handles); + + +function et_COM_Callback(hObject, eventdata, handles) +% hObject handle to et_COM (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 et_COM as text +% str2double(get(hObject,'String')) returns contents of et_COM as a double + + +% --- Executes during object creation, after setting all properties. +function et_COM_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_COM (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 + + + +function edit35_Callback(hObject, eventdata, handles) +% hObject handle to edit35 (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 edit35 as text +% str2double(get(hObject,'String')) returns contents of edit35 as a double + + +% --- Executes during object creation, after setting all properties. +function edit35_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit35 (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 + + + +function edit36_Callback(hObject, eventdata, handles) +% hObject handle to edit36 (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 edit36 as text +% str2double(get(hObject,'String')) returns contents of edit36 as a double + + +% --- Executes during object creation, after setting all properties. +function edit36_CreateFcn(hObject, eventdata, handles) +% hObject handle to edit36 (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 + + + +function et_baudrateport_Callback(hObject, eventdata, handles) +% hObject handle to et_baudrateport (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 et_baudrateport as text +% str2double(get(hObject,'String')) returns contents of et_baudrateport as a double + + +% --- Executes during object creation, after setting all properties. +function et_baudrateport_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_baudrateport (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 selection change in pm_serialportipaddress. +function pm_serialportipaddress_Callback(hObject, eventdata, handles) +% hObject handle to pm_serialportipaddress (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_serialportipaddress contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_serialportipaddress + + +% --- Executes during object creation, after setting all properties. +function pm_serialportipaddress_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_serialportipaddress (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 +% list all serial ports available +serialportlist = instrhwinfo('serial'); +if ~isempty(serialportlist.AvailableSerialPorts) + serialportlist = serialportlist.SerialPorts; + set(hObject,'String',serialportlist); +else + set(hObject,'String','None Available'); +end + +% --- Executes on button press in rb_serial. +function rb_serial_Callback(hObject, eventdata, handles) +% hObject handle to rb_serial (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of rb_serial +set(handles.rb_wifi,'Value',0); +set(handles.pm_serialportipaddress,'Style','popupmenu'); +% list all serial ports available +serialportlist = instrhwinfo('serial'); +if ~isempty(serialportlist.AvailableSerialPorts) + serialportlist = serialportlist.SerialPorts; + set(handles.pm_serialportipaddress,'String',serialportlist); +else + set(handles.pm_serialportipaddress,'String','None Available'); +end +set(handles.et_baudrateport,'String','BaudRate'); + +% --- Executes on button press in rb_wifi. +function rb_wifi_Callback(hObject, eventdata, handles) +% hObject handle to rb_wifi (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of rb_wifi +set(handles.rb_serial,'Value',0); +set(handles.pm_serialportipaddress,'Style','edit'); +set(handles.pm_serialportipaddress,'String','IP'); +set(handles.et_baudrateport,'String','Port'); + + +% --- Executes on button press in pb_selectctrlfolder. +function pb_selectctrlfolder_Callback(hObject, eventdata, handles) +% hObject handle to pb_selectctrlfolder (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +global ctrl_dir + +% check if another folder was added to the path before and, if yes, remove +% it from the path +if ctrl_dir + rmpath(ctrl_dir); +end + +% add the folder selected by the user to the Matlab path +ctrl_dir = uigetdir; +if ctrl_dir + addpath(ctrl_dir); +end + +% Re-Initialize control variables +% newHandles.motors = InitMotors; +% mov = InitMovements; + +handles.mov = InitMovements(); +handles.motors = InitMotors(); +% Update handles structure +guidata(hObject, handles); diff --git a/PatRec/LDA/DiscriminantAccuracy.m b/PatRec/LDA/DiscriminantAccuracy.m index 367d85d..111a8df 100644 --- a/PatRec/LDA/DiscriminantAccuracy.m +++ b/PatRec/LDA/DiscriminantAccuracy.m @@ -1,117 +1,117 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the accuracy of the DA -% Test of the testing set using the coefficients found before -% currently not the faster or smatertest way to use the coeff -% needs to be improved -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-10-02 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function acc = DiscriminantAccuracy(coeff, tSet, tOut, mov, dType) - -nM = length(mov); -good = zeros(length(tSet),1); -tIdx = 1; %Test index used to compare results with tLables -sM = length(tSet)/nM; % set per movement, NOTE this is done assuming that - % the movements have equal amount of sets (rows) - -% Run the DiscrimnantTest for each testing Set -for i = 1 : size(tSet,1) - - [outMov outVector] = DiscriminantTest(coeff,tSet(i,:),dType); - - %Quick and dirty routine to evaluate 2 patterns - % IF it's known that that more than two patterns are presented - if length(find(tOut(i,:))) ~= 1 % Only one movement - [Y, I] = sort(outVector,'descend'); - outMov = I(1:2)'; - end - - if tOut(i,outMov) == 1 % Evaluate single movement - good(i) = 1; - else - i; - end - - % for old version using labels - %if strcmp(mov(outMov),tLables(tIdx)) - % good(i) = 1; - %end - - -end - -% Old processing rutines for testing the coeff before having DiscriminantTest funtion -% which might be slower since the "if" selecting the type is executed more -% times. This is paid for modularity -% -% Linears -%if strcmp(dType,'linear') || strcmp(dType,'diaglinear') -% for i = 1 : length(tSet) -% -% tempRes = zeros(nM,nM); -% for i = 1 : nM -% for j = 1 : nM -% if i ~= j -% K = coeff(i,j).const; -% L = coeff(i,j).linear; -% tempRes(i,j) = K + tSet(tIdx,:)*L; % k + f1*L1 + f2*L2 ...... -% end -% end -% end -% [maxV, m] = max(sum(tempRes,2)); -% if strcmp(mov(m),tLables(tIdx)) -% good(i) = 1; -% end -% tIdx = tIdx + 1; -% end -% Quadratrics -% elseif strcmp(dType,'quadratic') || strcmp(dType,'diagquadratic') || strcmp(dType,'mahalanobis') -% -% for i = 1 : length(tSet) -% tempRes = zeros(nM,nM); -% for i = 1 : nM -% for j = 1 : nM -% if i ~= j -% K = coeff(i,j).const; -% L = coeff(i,j).linear; -% Q = coeff(i,j).quadratic; -% tempRes(i,j) = K + tSet(tIdx,:)*L + sum((tSet(tIdx,:)*Q) .* tSet(tIdx,:), 2); -% end -% end -% end -% [maxV, m] = max(sum(tempRes,2)); -% if strcmp(mov(m),tLables(tIdx)) -% good(i) = 1; -% end -% tIdx = tIdx + 1; -% end -% end - -acc = zeros(nM+1,1); -for i = 1 : nM - s = 1+((i-1)*sM); - e = sM*i; - acc(i) = sum(good(s:e))/sM; -end -acc(i+1) = sum(good) / length(tSet); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the accuracy of the DA +% Test of the testing set using the coefficients found before +% currently not the faster or smatertest way to use the coeff +% needs to be improved +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-10-02 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function acc = DiscriminantAccuracy(coeff, tSet, tOut, mov, dType) + +nM = length(mov); +good = zeros(length(tSet),1); +tIdx = 1; %Test index used to compare results with tLables +sM = length(tSet)/nM; % set per movement, NOTE this is done assuming that + % the movements have equal amount of sets (rows) + +% Run the DiscrimnantTest for each testing Set +for i = 1 : size(tSet,1) + + [outMov outVector] = DiscriminantTest(coeff,tSet(i,:),dType); + + %Quick and dirty routine to evaluate 2 patterns + % IF it's known that that more than two patterns are presented + if length(find(tOut(i,:))) ~= 1 % Only one movement + [Y, I] = sort(outVector,'descend'); + outMov = I(1:2)'; + end + + if tOut(i,outMov) == 1 % Evaluate single movement + good(i) = 1; + else + i; + end + + % for old version using labels + %if strcmp(mov(outMov),tLables(tIdx)) + % good(i) = 1; + %end + + +end + +% Old processing rutines for testing the coeff before having DiscriminantTest funtion +% which might be slower since the "if" selecting the type is executed more +% times. This is paid for modularity +% +% Linears +%if strcmp(dType,'linear') || strcmp(dType,'diaglinear') +% for i = 1 : length(tSet) +% +% tempRes = zeros(nM,nM); +% for i = 1 : nM +% for j = 1 : nM +% if i ~= j +% K = coeff(i,j).const; +% L = coeff(i,j).linear; +% tempRes(i,j) = K + tSet(tIdx,:)*L; % k + f1*L1 + f2*L2 ...... +% end +% end +% end +% [maxV, m] = max(sum(tempRes,2)); +% if strcmp(mov(m),tLables(tIdx)) +% good(i) = 1; +% end +% tIdx = tIdx + 1; +% end +% Quadratrics +% elseif strcmp(dType,'quadratic') || strcmp(dType,'diagquadratic') || strcmp(dType,'mahalanobis') +% +% for i = 1 : length(tSet) +% tempRes = zeros(nM,nM); +% for i = 1 : nM +% for j = 1 : nM +% if i ~= j +% K = coeff(i,j).const; +% L = coeff(i,j).linear; +% Q = coeff(i,j).quadratic; +% tempRes(i,j) = K + tSet(tIdx,:)*L + sum((tSet(tIdx,:)*Q) .* tSet(tIdx,:), 2); +% end +% end +% end +% [maxV, m] = max(sum(tempRes,2)); +% if strcmp(mov(m),tLables(tIdx)) +% good(i) = 1; +% end +% tIdx = tIdx + 1; +% end +% end + +acc = zeros(nM+1,1); +for i = 1 : nM + s = 1+((i-1)*sM); + e = sM*i; + acc(i) = sum(good(s:e))/sM; +end +acc(i+1) = sum(good) / length(tSet); \ No newline at end of file diff --git a/PatRec/LDA/DiscriminantAnalysis.m b/PatRec/LDA/DiscriminantAnalysis.m index c1bc842..1d938e6 100644 --- a/PatRec/LDA/DiscriminantAnalysis.m +++ b/PatRec/LDA/DiscriminantAnalysis.m @@ -1,72 +1,72 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to execute the discrimant analysis provided by matlab -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-06-24 / Max Ortiz / Created -% 2011-08-01 / Max Ortiz / Creation of the function DiscriminantTest -% 2011-10-02 / Max Ortiz / Creation of the function DiscriminantAccuracy -% 2012-05-20 / Max Ortiz / Move the Get_SetsLabels funtion inside this -% routne and deleted old commented code -% 20xx-xx-xx / Author / Comment on update - -%function [coeff accVset] = DiscriminantAnalysis(trSet, trLables, vSet, vLables, mov, dType) -function [coeff accVset] = DiscriminantAnalysis(dType, trSets, trOuts, vSets, vOuts, mov, movIdx) - -% Get labels required for LDA (only LDA so far) - [trLables, vLables] = GetSetsLables_Stack(mov, trOuts, vOuts, movIdx); - mov = mov(movIdx); - if size(trLables,1) ~= size(trOuts,1) - disp('Error obtaining the lables!!!!') - errordlg('Error obtaining the lables!','Discriminant A.') - return; - end - -%Apply discriminat to vset -[class,err,POSTERIOR,logp,coeff] = classify(vSets,trSets,trLables,dType); - -nM = size(mov,1); -good = zeros(size(vSets,1),1); -sM = size(vSets,1)/nM; % set per movement, NOTE this is done assuming that - % the movements have equal amount of sets (rows) - -% Run the DiscrimnantTest for each testing Set -for i = 1 : size(vSets,1) - if strcmp(class(i),vLables(i)) - good(i) = 1; - end -end - -accVset = zeros(nM,1); -for i = 1 : nM - s = 1+((i-1)*sM); - e = sM*i; - accVset(i) = sum(good(s:e))/sM; -end -accVset(i+1) = sum(good) / size(vSets,1); - -%Compute General level of accuracy for the validation set -% good = 0; -% for i = 1 : size(vSets,1) -% if strcmp(class(i),vLables(i)) -% good = good + 1; -% end -% end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to execute the discrimant analysis provided by matlab +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-06-24 / Max Ortiz / Created +% 2011-08-01 / Max Ortiz / Creation of the function DiscriminantTest +% 2011-10-02 / Max Ortiz / Creation of the function DiscriminantAccuracy +% 2012-05-20 / Max Ortiz / Move the Get_SetsLabels funtion inside this +% routne and deleted old commented code +% 20xx-xx-xx / Author / Comment on update + +%function [coeff accVset] = DiscriminantAnalysis(trSet, trLables, vSet, vLables, mov, dType) +function [coeff accVset] = DiscriminantAnalysis(dType, trSets, trOuts, vSets, vOuts, mov, movIdx) + +% Get labels required for LDA (only LDA so far) + [trLables, vLables] = GetSetsLables_Stack(mov, trOuts, vOuts, movIdx); + mov = mov(movIdx); + if size(trLables,1) ~= size(trOuts,1) + disp('Error obtaining the lables!!!!') + errordlg('Error obtaining the lables!','Discriminant A.') + return; + end + +%Apply discriminat to vset +[class,err,POSTERIOR,logp,coeff] = classify(vSets,trSets,trLables,dType); + +nM = size(mov,1); +good = zeros(size(vSets,1),1); +sM = size(vSets,1)/nM; % set per movement, NOTE this is done assuming that + % the movements have equal amount of sets (rows) + +% Run the DiscrimnantTest for each testing Set +for i = 1 : size(vSets,1) + if strcmp(class(i),vLables(i)) + good(i) = 1; + end +end + +accVset = zeros(nM,1); +for i = 1 : nM + s = 1+((i-1)*sM); + e = sM*i; + accVset(i) = sum(good(s:e))/sM; +end +accVset(i+1) = sum(good) / size(vSets,1); + +%Compute General level of accuracy for the validation set +% good = 0; +% for i = 1 : size(vSets,1) +% if strcmp(class(i),vLables(i)) +% good = good + 1; +% end +% end % accvSets = good / length(vSets); % Accuracy on the validation set \ No newline at end of file diff --git a/PatRec/LDA/DiscriminantTest.m b/PatRec/LDA/DiscriminantTest.m index 3567532..a168a85 100644 --- a/PatRec/LDA/DiscriminantTest.m +++ b/PatRec/LDA/DiscriminantTest.m @@ -1,61 +1,61 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to execute the discrimant analysis use the coeficient previusly -% calculated -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-08-01 / Max Ortiz / Created -% 2011-10-02 / Max Ortiz / Modified to return outVector and outMov - -function [outMov outVector] = DiscriminantTest(coeff, tSet, dType) - - nM = size(coeff,1); - tempRes = zeros(nM,nM); - - % Linears - if strcmp(dType,'linear') || strcmp(dType,'diaglinear') - for i = 1 : nM - for j = 1 : nM - if i ~= j - K = coeff(i,j).const; - L = coeff(i,j).linear; - tempRes(i,j) = K + tSet * L; % k + f1*L1 + f2*L2 ...... - end - end - end - - % Quadratrics - elseif strcmp(dType,'quadratic') || strcmp(dType,'diagquadratic') || strcmp(dType,'mahalanobis') - for i = 1 : nM - for j = 1 : nM - if i ~= j - K = coeff(i,j).const; - L = coeff(i,j).linear; - Q = coeff(i,j).quadratic; - tempRes(i,j) = K + tSet*L + sum((tSet * Q) .* tSet, 2); - end - end - end - end - - outVector = sum(tempRes,2); - [maxV, outMov] = max(outVector); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to execute the discrimant analysis use the coeficient previusly +% calculated +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-08-01 / Max Ortiz / Created +% 2011-10-02 / Max Ortiz / Modified to return outVector and outMov + +function [outMov outVector] = DiscriminantTest(coeff, tSet, dType) + + nM = size(coeff,1); + tempRes = zeros(nM,nM); + + % Linears + if strcmp(dType,'linear') || strcmp(dType,'diaglinear') + for i = 1 : nM + for j = 1 : nM + if i ~= j + K = coeff(i,j).const; + L = coeff(i,j).linear; + tempRes(i,j) = K + tSet * L; % k + f1*L1 + f2*L2 ...... + end + end + end + + % Quadratrics + elseif strcmp(dType,'quadratic') || strcmp(dType,'diagquadratic') || strcmp(dType,'mahalanobis') + for i = 1 : nM + for j = 1 : nM + if i ~= j + K = coeff(i,j).const; + L = coeff(i,j).linear; + Q = coeff(i,j).quadratic; + tempRes(i,j) = K + tSet*L + sum((tSet * Q) .* tSet, 2); + end + end + end + end + + outVector = sum(tempRes,2); + [maxV, outMov] = max(outVector); + end \ No newline at end of file diff --git a/PatRec/Load_patRec.m b/PatRec/Load_patRec.m index c19b0a8..c63c63a 100644 --- a/PatRec/Load_patRec.m +++ b/PatRec/Load_patRec.m @@ -1,143 +1,143 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Funtion to load "patRec" into a selected GUI -% -% --------------------------Updates-------------------------- -% 2011-11-16 / Max Ortiz / Creation -% 2012-06-01 / Nichlas Sander/ Loading movements into parameters of new patRec -% 2012-10-11 / Joel Falk-Dahlin/ Changed so the GUI now selects output -% movements same as trained movement if it -% exists -% 2012-10-12 / Joel Falk-Dahlin/ Moved loading of movList and speeds -% from GUI_TestPatRec_Mov2Mov here, now -% these lists are updated as they are -% changed in the GUI compared to before -% where these had to be loaded in -% TacTest and RealTimePatRec - -function Load_patRec(patRec, newGUI, loadMovements) - - % To make sure old patRecs still can be used, initialize max / current - % speeds - if ~isfield(patRec,'control') - patRec.control.maxDegPerMov = ones(1,patRec.nOuts); - elseif isfield(patRec,'control') - if ~isfield(patRec.control,'maxDegPerMov') - patRec.control.maxDegPerMov(1:patRec.nOuts) = 1; - end - end - - % Open Fig and load information - nG = eval([newGUI,'(patRec)']); - newHandles = guidata(nG); - - % Fill the GUI - set(newHandles.lb_features,'Value',1:length(patRec.selFeatures)); - set(newHandles.lb_features,'String',patRec.selFeatures); - set(newHandles.lb_movements,'String',patRec.mov(patRec.indMovIdx)); - set(newHandles.pm_SelectAlgorithm,'String',patRec.patRecTrained(1).algorithm); - set(newHandles.pm_SelectTraining,'String',patRec.patRecTrained(1).training); - set(newHandles.pm_normSets,'String',patRec.normSets.type); - - if exist('loadMovements','var') - if(loadMovements) - - % Fill List of Movements - % Setup variables - newHandles.motors = InitMotors; - mov = InitMovements; - newHandles.mov = mov; - movements = []; - patRecMovements = []; - - % Save Valid movements, that can be used with VRE/ARE and - % motors - i = 1; - while(size(movements,2) < size(mov,2)) - movements = [movements,mov(i).name]; - i = i+1; - end - - % Read movements trained in patRec structure - i = 1; - while length( patRec.movOutIdx{i} ) == 1 && i < size( patRec.movOutIdx,2 ) - patMov = patRec.mov{i}; - patMov = strrep(patMov,'Extend', 'Ext'); - patMov = strrep(patMov,'Pointer', 'Point'); - patRecMovements = [patRecMovements; {patMov}]; - i = i+1; - end - - % Set selectable options to valid movements for pop-menus in - % GUI_TestPatRec_Mov2Mov - for i=1:20 - s = sprintf('pm_m%d',i); - if isfield(newHandles,s) - set(newHandles.(s),'String',movements); - % If patRec has trained movement - if i <= length(patRecMovements) - % Find menu-value that correspond to trained - % movement - for j = 1:size(movements,2) - if strcmp(patRecMovements{i},movements{j}) - % Set menu to trained movement - set(newHandles.(s),'Value',j); - break; - end - end - end - - % if(size(get(newHandles.(s),'String'),1) > i) - % set(newHandles.(s),'Value',i); - % else - % set(newHandles.(s),'Value',1); - % end - - end - end - end - - % If we load the GUI_TestPatRec_Mov2Mov, then store movList and - % speeds to the handles by reading from the pop-menus and et-boxes - if strcmp(newGUI,'GUI_TestPatRec_Mov2Mov') - clear movements; - i = 1; - dropdown = sprintf('pm_m%d',i); - movementSpeed = sprintf('et_speed%d',i); - while(isfield(newHandles,dropdown) && isfield(newHandles,movementSpeed)) - movIndex = get(newHandles.(dropdown),'Value'); - movements(i) = newHandles.mov(movIndex); - speeds(i) = str2double(get(newHandles.(movementSpeed),'String')); - i = i+1; - dropdown = sprintf('pm_m%d',i); - movementSpeed = sprintf('et_speed%d',i); - end - %Save all values of speeds in the handles - newHandles.movList = movements; - %newHandles.maxDegPerMov = speeds; - end - - end - - - % Save the patRec in the handles - newHandles.patRec = patRec; - guidata(nG,newHandles); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Funtion to load "patRec" into a selected GUI +% +% --------------------------Updates-------------------------- +% 2011-11-16 / Max Ortiz / Creation +% 2012-06-01 / Nichlas Sander/ Loading movements into parameters of new patRec +% 2012-10-11 / Joel Falk-Dahlin/ Changed so the GUI now selects output +% movements same as trained movement if it +% exists +% 2012-10-12 / Joel Falk-Dahlin/ Moved loading of movList and speeds +% from GUI_TestPatRec_Mov2Mov here, now +% these lists are updated as they are +% changed in the GUI compared to before +% where these had to be loaded in +% TacTest and RealTimePatRec + +function Load_patRec(patRec, newGUI, loadMovements) + + % To make sure old patRecs still can be used, initialize max / current + % speeds + if ~isfield(patRec,'control') + patRec.control.maxDegPerMov = ones(1,patRec.nOuts); + elseif isfield(patRec,'control') + if ~isfield(patRec.control,'maxDegPerMov') + patRec.control.maxDegPerMov(1:patRec.nOuts) = 1; + end + end + + % Open Fig and load information + nG = eval([newGUI,'(patRec)']); + newHandles = guidata(nG); + + % Fill the GUI + set(newHandles.lb_features,'Value',1:length(patRec.selFeatures)); + set(newHandles.lb_features,'String',patRec.selFeatures); + set(newHandles.lb_movements,'String',patRec.mov(patRec.indMovIdx)); + set(newHandles.pm_SelectAlgorithm,'String',patRec.patRecTrained(1).algorithm); + set(newHandles.pm_SelectTraining,'String',patRec.patRecTrained(1).training); + set(newHandles.pm_normSets,'String',patRec.normSets.type); + + if exist('loadMovements','var') + if(loadMovements) + + % Fill List of Movements + % Setup variables + newHandles.motors = InitMotors; + mov = InitMovements; + newHandles.mov = mov; + movements = []; + patRecMovements = []; + + % Save Valid movements, that can be used with VRE/ARE and + % motors + i = 1; + while(size(movements,2) < size(mov,2)) + movements = [movements,mov(i).name]; + i = i+1; + end + + % Read movements trained in patRec structure + i = 1; + while length( patRec.movOutIdx{i} ) == 1 && i < size( patRec.movOutIdx,2 ) + patMov = patRec.mov{i}; + patMov = strrep(patMov,'Extend', 'Ext'); + patMov = strrep(patMov,'Pointer', 'Point'); + patRecMovements = [patRecMovements; {patMov}]; + i = i+1; + end + + % Set selectable options to valid movements for pop-menus in + % GUI_TestPatRec_Mov2Mov + for i=1:20 + s = sprintf('pm_m%d',i); + if isfield(newHandles,s) + set(newHandles.(s),'String',movements); + % If patRec has trained movement + if i <= length(patRecMovements) + % Find menu-value that correspond to trained + % movement + for j = 1:size(movements,2) + if strcmp(patRecMovements{i},movements{j}) + % Set menu to trained movement + set(newHandles.(s),'Value',j); + break; + end + end + end + + % if(size(get(newHandles.(s),'String'),1) > i) + % set(newHandles.(s),'Value',i); + % else + % set(newHandles.(s),'Value',1); + % end + + end + end + end + + % If we load the GUI_TestPatRec_Mov2Mov, then store movList and + % speeds to the handles by reading from the pop-menus and et-boxes + if strcmp(newGUI,'GUI_TestPatRec_Mov2Mov') + clear movements; + i = 1; + dropdown = sprintf('pm_m%d',i); + movementSpeed = sprintf('et_speed%d',i); + while(isfield(newHandles,dropdown) && isfield(newHandles,movementSpeed)) + movIndex = get(newHandles.(dropdown),'Value'); + movements(i) = newHandles.mov(movIndex); + speeds(i) = str2double(get(newHandles.(movementSpeed),'String')); + i = i+1; + dropdown = sprintf('pm_m%d',i); + movementSpeed = sprintf('et_speed%d',i); + end + %Save all values of speeds in the handles + newHandles.movList = movements; + %newHandles.maxDegPerMov = speeds; + end + + end + + + % Save the patRec in the handles + newHandles.patRec = patRec; + guidata(nG,newHandles); + \ No newline at end of file diff --git a/PatRec/Load_recSession.m b/PatRec/Load_recSession.m index ed496e2..9bd3e08 100644 --- a/PatRec/Load_recSession.m +++ b/PatRec/Load_recSession.m @@ -1,83 +1,84 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Funtion to load "recSession" in GUI_PatRec -% -% --------------------------Updates-------------------------- -% 2011-06-30 / Max Ortiz / Creation -% 2011-07-19 / Max Ortiz / Modified to only load the recSession, -% the signal processing has been dived inside -% the GUI_SigTreatment - -function Load_recSession(recSession, handles) - - % Removed useless fields from previus versions (EMG_AQ) - if isfield(recSession,'trdata') - recSession = rmfield(recSession,'trdata'); - end - if isfield(recSession,'cTp') - recSession = rmfield(recSession,'cTp'); - end - - % Open Fig and load information - - %st = GUI_GetSigFeatures(); - st = GUI_SigTreatment(); - stdata = guidata(st); - set(stdata.et_sF,'String',num2str(recSession.sF)); - set(stdata.et_nM,'String',num2str(recSession.nM)); - set(stdata.et_nR,'String',num2str(recSession.nR)); - set(stdata.et_cT,'String',num2str(recSession.cT)); - set(stdata.et_rT,'String',num2str(recSession.rT)); - set(stdata.lb_movements,'String',recSession.mov); - set(stdata.lb_movements,'Value',1:recSession.nM); - - if isfield(recSession,'dev') - set(stdata.t_dev,'String',recSession.dev); - else - set(stdata.t_dev,'String','Unknown'); - end - - if isfield(recSession,'nCh') - nCh = recSession.nCh; - if length(recSession.nCh) == 1 - recSession.nCh = 1:recSession.nCh; - nCh = recSession.nCh; - end - if length(recSession.nCh) ~= length(recSession.tdata(1,:,1)) - set(stdata.t_msg,'String','Error in the number of channels'); - set(handles.t_msg,'String','Error in the number of channels'); - end - else - nCh = 1:length(recSession.tdata(1,:,1)); - recSession.nCh = nCh; - end - set(stdata.lb_nCh,'String',num2str(nCh')); - set(stdata.lb_nCh,'Value',nCh); - - - %set(stdata.t_path,'UserData',path); - - %Load the whole recSession - set(stdata.t_recSession,'UserData',recSession); - % Save this GUI handles - set(stdata.t_mhandles,'UserData',handles); - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Funtion to load "recSession" in GUI_PatRec +% +% --------------------------Updates-------------------------- +% 2011-06-30 / Max Ortiz / Creation +% 2011-07-19 / Max Ortiz / Modified to only load the recSession, +% the signal processing has been dived inside +% the GUI_SigTreatment + +function Load_recSession(recSession, handles) + + % Removed useless fields from previus versions (EMG_AQ) + if isfield(recSession,'trdata') + recSession = rmfield(recSession,'trdata'); + end + if isfield(recSession,'cTp') + recSession = rmfield(recSession,'cTp'); + end + + % Open Fig and load information + + %st = GUI_GetSigFeatures(); + st = GUI_SigTreatment(); + stdata = guidata(st); + set(stdata.et_sF,'String',num2str(recSession.sF)); + set(stdata.et_downsample,'String',num2str(recSession.sF)); + set(stdata.et_nM,'String',num2str(recSession.nM)); + set(stdata.et_nR,'String',num2str(recSession.nR)); + set(stdata.et_cT,'String',num2str(recSession.cT)); + set(stdata.et_rT,'String',num2str(recSession.rT)); + set(stdata.lb_movements,'String',recSession.mov); + set(stdata.lb_movements,'Value',1:recSession.nM); + + if isfield(recSession,'dev') + set(stdata.t_dev,'String',recSession.dev); + else + set(stdata.t_dev,'String','Unknown'); + end + + if isfield(recSession,'nCh') + nCh = recSession.nCh; + if length(recSession.nCh) == 1 + recSession.nCh = 1:recSession.nCh; + nCh = recSession.nCh; + end + if length(recSession.nCh) ~= length(recSession.tdata(1,:,1)) + set(stdata.t_msg,'String','Error in the number of channels'); + set(handles.t_msg,'String','Error in the number of channels'); + end + else + nCh = 1:length(recSession.tdata(1,:,1)); + recSession.nCh = nCh; + end + set(stdata.lb_nCh,'String',num2str(nCh')); + set(stdata.lb_nCh,'Value',nCh); + + + %set(stdata.t_path,'UserData',path); + + %Load the whole recSession + set(stdata.t_recSession,'UserData',recSession); + % Save this GUI handles + set(stdata.t_mhandles,'UserData',handles); + + + + diff --git a/PatRec/Load_sigFeatures.m b/PatRec/Load_sigFeatures.m index ca7e2c1..5b27529 100644 --- a/PatRec/Load_sigFeatures.m +++ b/PatRec/Load_sigFeatures.m @@ -1,50 +1,50 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% % Funtion to load "trated_data" in GUI_PatRec -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-06-25 Max Ortiz, Created -% 20xx-xx-xx / Author / Comment on update - -function Load_sigFeatures(sigFeatures, handles) - - % Keep compatibility with previous files - sigFeatures = Compatibility_treated_data(sigFeatures); - - % Load treated data - set(handles.t_sigFeatures,'UserData',sigFeatures); - % Load information from treated data - set(handles.et_trSets,'String',num2str(sigFeatures.trSets)); - set(handles.et_vSets,'String',num2str(sigFeatures.vSets)); - set(handles.et_tSets,'String',num2str(sigFeatures.tSets)); - set(handles.lb_movements,'String',sigFeatures.mov); - - allFeatures = fieldnames(sigFeatures.trFeatures); - set(handles.lb_features,'String',allFeatures); - set(handles.lb_features,'Value',1:length(allFeatures)); - - % Enable controls - set(handles.pm_SelectAlgorithm,'Enable','on'); - set(handles.rb_top2,'Value',1); - set(handles.lb_features,'Value',[3 5]); % tstd, twl -% set(handles.lb_features,'Value',[2 7 9 13]); % tmabs, twl, tzc, tslpch EH03, HZ09, SL09 - - % User message - set(handles.t_msg,'String','Treated data loaded'); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% % Funtion to load "trated_data" in GUI_PatRec +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-06-25 Max Ortiz, Created +% 20xx-xx-xx / Author / Comment on update + +function Load_sigFeatures(sigFeatures, handles) + + % Keep compatibility with previous files + sigFeatures = Compatibility_treated_data(sigFeatures); + + % Load treated data + set(handles.t_sigFeatures,'UserData',sigFeatures); + % Load information from treated data + set(handles.et_trSets,'String',num2str(sigFeatures.trSets)); + set(handles.et_vSets,'String',num2str(sigFeatures.vSets)); + set(handles.et_tSets,'String',num2str(sigFeatures.tSets)); + set(handles.lb_movements,'String',sigFeatures.mov); + + allFeatures = fieldnames(sigFeatures.trFeatures); + set(handles.lb_features,'String',allFeatures); + set(handles.lb_features,'Value',1:length(allFeatures)); + + % Enable controls + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_top2,'Value',1); + set(handles.lb_features,'Value',[3 5]); % tstd, twl +% set(handles.lb_features,'Value',[2 7 9 13]); % tmabs, twl, tzc, tslpch EH03, HZ09, SL09 + + % User message + set(handles.t_msg,'String','Treated data loaded'); diff --git a/PatRec/Load_treated_data.m b/PatRec/Load_treated_data.m index e9c2b77..2e534cd 100644 --- a/PatRec/Load_treated_data.m +++ b/PatRec/Load_treated_data.m @@ -1,53 +1,53 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to load "trated_data" in GUI_PatRec -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-06-25 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update% - - -function Load_treated_data(treated_data, handles) - - % Keep compatibility with previous files - treated_data = Compatibility_treated_data(treated_data); - - % Load treated data - set(handles.t_treated_data,'UserData',treated_data); - % Load information from treated data - set(handles.et_trSets,'String',num2str(treated_data.trSets)); - set(handles.et_vSets,'String',num2str(treated_data.vSets)); - set(handles.et_tSets,'String',num2str(treated_data.tSets)); - set(handles.lb_movements,'String',treated_data.mov); - - allFeatures = fieldnames(treated_data.trdata); - set(handles.lb_features,'String',allFeatures); - set(handles.lb_features,'Value',1:length(allFeatures)); - - % Enable controls - set(handles.pm_SelectAlgorithm,'Enable','on'); - set(handles.rb_all,'Enable','on'); - set(handles.rb_top3,'Enable','on'); - set(handles.rb_top4,'Enable','on'); - set(handles.rb_top4,'Value',1); - set(handles.lb_features,'Value',[2 7 9 13]); % tmabs, twl, tzc, tslpch EH03, HZ09, SL09 - - % User message - set(handles.t_msg,'String','Treated data loaded'); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to load "trated_data" in GUI_PatRec +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-06-25 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update% + + +function Load_treated_data(treated_data, handles) + + % Keep compatibility with previous files + treated_data = Compatibility_treated_data(treated_data); + + % Load treated data + set(handles.t_treated_data,'UserData',treated_data); + % Load information from treated data + set(handles.et_trSets,'String',num2str(treated_data.trSets)); + set(handles.et_vSets,'String',num2str(treated_data.vSets)); + set(handles.et_tSets,'String',num2str(treated_data.tSets)); + set(handles.lb_movements,'String',treated_data.mov); + + allFeatures = fieldnames(treated_data.trdata); + set(handles.lb_features,'String',allFeatures); + set(handles.lb_features,'Value',1:length(allFeatures)); + + % Enable controls + set(handles.pm_SelectAlgorithm,'Enable','on'); + set(handles.rb_all,'Enable','on'); + set(handles.rb_top3,'Enable','on'); + set(handles.rb_top4,'Enable','on'); + set(handles.rb_top4,'Value',1); + set(handles.lb_features,'Value',[2 7 9 13]); % tmabs, twl, tzc, tslpch EH03, HZ09, SL09 + + % User message + set(handles.t_msg,'String','Treated data loaded'); diff --git a/PatRec/MotionTest.m b/PatRec/MotionTest.m index 8214307..1944ed9 100644 --- a/PatRec/MotionTest.m +++ b/PatRec/MotionTest.m @@ -1,449 +1,489 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Motion Test for to evaluate real-time performance of the patRec -% This test is implemented in such a way that the "rest" movement is -% required -% -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-01-xx / Max Ortiz / Creation from MotionTestLegacy -% 2012-05-29 / Max Ortiz / Addition of "clear" commands -% 2012-07-24 / Max Ortiz / Use fpTW to compute the predition time of the -% first prediction in order to calculate the selection time -% 2012-10-05 / Joel Falk-Dahlin / Added ApplyControl after OneShotPatRec -% to allow for the use of control algorithms in the motion test -% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl -% 2011-11-06 / Max Ortiz / Create RealimePatRec_OneShot to concentrate -% critical routines of realtime patrec -% 20xx-xx-xx / Author / Comment on update - -function motionTest = MotionTest(patRecX, handlesX) - -clear global; - -global patRec; -global handles; -global nTW; % Number of time windows evaluated -global fpTW; % Time window of the first prediction -global dataTW; % Raw data from each time windows -global tempData; % Reset tempData if it is the first call -global motorCoupling; -global vreCoupling; -global thresholdGUIData; - -% Time markers -global selTimeTic; - -% Key performance indicators -global nCorrMov; -global selTime; % Selection time (selected = expected movement) -global selTimeTW; -global compTime; % Completion time (selected = expected movement) -global compTimeTW; -global nwCompTime; % Number of time windows to consider completion time -global predictions; -global procTime; % Processing time - -% Key performance indicators for at least 1 correct prediction -global nCorrMov1; % Number of at least 1 correct number -global selTime1; % Selection time (selected = at leas 1 expected mov) -global selTime1TW; -global compTime1; % Completion time (selected = at leas 1 expected mov) -global compTime1TW; -% Variables to keep track of testing movement -global mIdx; -global m; - -%% Init variable -patRec = patRecX; -handles = handlesX; -pDiv = 2; % Peeking devider -trials = str2double(get(handles.et_trials,'String')); -nR = str2double(get(handles.et_nR,'String')); -timeOut = str2double(get(handles.et_timeOut,'String')); -nwCompTime = 20; % Number of windows to consider completion time -pause on; % Enable pauses - -%% Is threshold (thOut) used? -if(isfield(patRec.patRecTrained,'thOut')); - %Threshold GUI init - thresholdGUI = GUI_Threshold; - thresholdGUIData = guidata(thresholdGUI); - set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); - xpatch = [1 1 0 0]; - ypatch = [0 0 0 0]; - for i=0:patRec.nOuts-1 - s = sprintf('movementSelector%d',i); - s0 = sprintf('thPatch%d',i); - s1 = sprintf('meter%d',i); - axes(thresholdGUIData.(s1)); - handles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); - ylim(thresholdGUIData.(s1), [0 1]); - xlim('auto'); - set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); - if (size(patRec.mov(patRec.indMovIdx),1) < i+1); - set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); - else - set(thresholdGUIData.(s),'Value',i+1); - end - end -end - -%% Is the VRE selected? -if isfield(handles,'cb_motionTestVRE') - trainUsingVre = get(handles.cb_motionTestVRE,'Value'); -else - trainUsingVre = 0; -end - -%% Is there an option for coupling with the motors? -if isfield(handles,'cb_motorCoupling') %&& ~isfield(handles,'com') - motorCoupling = get(handles.cb_motorCoupling,'Value'); -else - motorCoupling = 0; -end - -%% Init motionTest structure -motionTest.patRec = patRec; -motionTest.sF = patRec.sF; -motionTest.tW = patRec.tW; -motionTest.trails = trials; -motionTest.nR = nR; -motionTest.timeOut = timeOut; - -%% Initialize DAQ card -% Note: A function for DAQ selection will be required when more cards are -% added - -if strcmp(patRec.dev,'ADH') - -else % at this poin everything else is SBI (e.g.NI-USB6009) - chAI = zeros(1,8); - chAI(patRec.nCh) = 1; - % create the SBI - s = InitSBI_NI(patRec.sF,timeOut,chAI); - % Change the peek time - s.NotifyWhenDataAvailableExceeds = (patRec.sF*patRec.tW)/pDiv; % Max 0.05, or 20 times per second - %Add listener - lh = s.addlistener('DataAvailable', @MotionTest_OneShot); - %Test the DAQ by ploting the data - %lh = s.addlistener('DataAvailable', @plotDataTest); -end - -%% Motion Test -% Note: Probabily this way of testing only works for the NI -% specific funtions per card might be required. - -if trainUsingVre - if ~isfield(handles,'vre_Com') - handles = ConnectVRE(handles,'Virtual Reality.exe'); - end -end - -% run over all the trails -for t = 1 : trials - - for i = 1 : 5; - msg = ['Trial: "' num2str(t) '" in: ' num2str(6-i) ' seconds']; - set(handles.t_msg,'String',msg); - pause(1); - end - - % repite the movement the chosen times - for r = 1 : nR - % Randomize the aperance of the requested movement - mIdx = randperm(patRec.nM - 1); % It doesn't include "rest" - % Run over all movements but "rest" - for m = 1 : patRec.nM - 1 - - %Select movement - movementObjects = handles.movList(patRec.movOutIdx{mIdx(m)}); - mov = patRec.mov{mIdx(m)}; - %Prepare - for i = 1 : 3; - % Warn the user - %msg = ['Relax and prepare to "' mov '" in: ' num2str(4-i) ' seconds (trial:' num2str(t) ', rep:' num2str(r) ')']; - % No warning - msg = 'Relax'; - set(handles.t_msg,'String',msg); - pause(1); - end - - % Warning to the user - fileName = ['Img/' char(mov) '.jpg']; - if ~exist(fileName,'file') - fileName = 'Img/relax.jpg'; - end - % Display image - movI = importdata(fileName); % Import Image - set(handles.a_pic,'Visible','on'); % Turn on visibility - pic = image(movI,'Parent',handles.a_pic); % set image - axis(handles.a_pic,'off'); % Remove axis tick marks - - % Init required for patRec of the selected movement - nTW = 1; % Number of time windows - fpTW = 0; % Time window of the first prediction - nCorrMov = 0; % Number of corect movements - predictions = {}; % Vector with the classifier prediction per tw - selTime = NaN; % Selection time - selTimeTW = NaN; % nTW when the selection time happen - compTime = NaN; % Completion time - compTimeTW = NaN; % nTW when the completion time happen - - nCorrMov1 = 0; % Number of corect movements of at least 1 mov - selTime1 = NaN; % Selection time of at least 1 expected mov - selTime1TW = NaN; % nTW when the selection time happen - compTime1 = NaN; % Completion time - compTime1TW = NaN; % nTW when the completion time happen - - selTimeTic = []; % Resets the time of first movement - procTime = []; % Processing time (vector) - dataTW = []; % Reset the dataTW (matrix) - tempData = []; % Reset tempData if it is the first call - - % Ask the user to execute movement - set(handles.t_msg,'String',mov); - drawnow; - %% Start test - s.startBackground(); % Start the data acquision for timeOut seconds - - % Move the VRE into place. - for i = 1:length(movementObjects) - movementObject = movementObjects(i); - if trainUsingVre - % Send values to VRE to move hand into position. - for j = 1:15 %Move it 15 times, distance of 5 each time. - VREActivation(handles.vre_Com,5,[],movementObject.idVRE, movementObject.vreDir, 0); - end - end - end - - %selTimeTic = tic; % Start counting after user instruction, - % which might not be as preciase as start counting just after a - % movement is predicted. - - % Wait until it has finished done - %s.IsDone % will report 0 - s.wait(); % rather than while - %s.IsDone % will report 1 - - %Reset the VRE. - if trainUsingVre - ResetVRE(handles.vre_Com,1,1); - end - - %% Save data - test.mov = mov; - test.nTW = nTW-1; - test.fpTW = fpTW; - test.nCorrMov = nCorrMov; - test.predictions = predictions; - test.selTime = selTime; - test.selTimeTW = selTimeTW; - test.compTime = compTime; - test.compTimeTW = compTimeTW; - % Performance for at least 1 movement - test.nCorrMov1 = nCorrMov1; - test.selTime1 = selTime1; - test.selTime1TW = selTime1TW; - test.compTime1 = compTime1; - test.compTime1TW = compTime1TW; - % Data - test.dataTW = dataTW; - test.procTime = mean(procTime); - - % Test fail? - if isnan(compTime) - test.fail = 1; - % Test failed even for 1 movement simul? - if isnan(compTime1) - test.fail1 = 1; - else - test.fail1 = 0; - end - else - test.fail = 0; - test.fail1 = 0; - end - - % Compute accuracy between fpTw to achivement of compTime - if test.fail - % Consider the accuracy during fail trials - %corrP = sum(predictions == mIdx(m)); - %test.acc = corrP / size(predictions,2); - - %Don't acount for acc in failed trials - test.acc = NaN; - - else - corrP = 0; - for i = fpTW : compTimeTW+fpTW-1 - if isequal(predictions{i},patRec.movOutIdx{mIdx(m)}') - corrP = corrP +1; - end - end - %corrP = sum(predictions{fpTW:fpTW+compTimeTW-1} == mIdx(m)); %It doesn't work for simultaneous prediction - test.acc = corrP / compTimeTW; - end - - disp(test); - motionTest.test(r,mIdx(m),t) = test; - delete(pic); - set(handles.t_msgMT,'Visible','off'); - drawnow; - end - end -end - -if trainUsingVre - handles = DisconnectVRE(handles); -end - -% Saved any modification to patRec -motionTest.patRec = patRec; - -%Delete listener SBI -delete (lh) -pause off; - -% show results -motionTest = MotionTestResults(motionTest); - -% Save test -disp(motionTest); -[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); - if isequal(filename,0) || isequal(pathname,0) - disp('User pressed cancel') - else - save([pathname,filename],'motionTest'); - end - -% Clear key variables -clear mIdx; -clear m; - -end - -function MotionTest_OneShot(src,event) - - % General - global patRec; - global handles; - global nTW; % Number of time windows evaluated - global fpTW; % Time window of the first prediction - global dataTW; % Raw data from each time windows - global tempData; - global motorCoupling; - global vreCoupling; - global thresholdGUIData; - - % Time markers - global selTimeTic; - % Key performance indicators - global procTime; - global nCorrMov; - global selTime; % Selection time - global selTimeTW; - global compTime; % Completion time - global compTimeTW; - global nwCompTime; % Number of time windows to consider completion time - global predictions; - % Key performance indicators for at least one movement - global nCorrMov1; % Number of at least 1 correct number - global selTime1; % Selection time (selected = at leas 1 expected mov) - global selTime1TW; - global compTime1; % Completion time (selected = at leas 1 expected mov) - global compTime1TW; - % Variables to keep track of testing movement - global mIdx; - global m; - - - tempData = [tempData; event.Data]; % Record all signal - - % Is there enough data for a TW? - if size(tempData,1) >= (patRec.sF*patRec.tW) - - % Save the TW data, maybe useful for further analysis - tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data - dataTW(:,:,nTW) = tData; % Save data for future analisys - - % Start of processing time - procTimeTic = tic; - - % General routine for RealtimePatRec - [outMov outVector patRec handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData); - - % Finish of processing time - procTime(nTW) = toc(procTimeTic); - - % Save the classifier prediction for statistics - predictions{nTW} = outMov; - - % Is there a prediction different than "rest"? - % This conditional considers that there is always a rest movement, - % and this has the last index, therefore rest Indx = patRec.nOuts - if isempty(selTimeTic) - % Compare each outMov to rest -% maskRest(1:size(outMov)) = patRec.nM; - maskRest(1:size(outMov)) = patRec.nOuts; - if sum(outMov ~= maskRest') - selTimeTic = tic; % Starts counting time for selection and completion - fpTW = nTW; % Consider the TW of the first moment - end - end - - % Is the output the expected classes? - if isequal(patRec.movOutIdx{mIdx(m)}, outMov') - nCorrMov = nCorrMov + 1; - if nCorrMov == 1; - selTime = toc(selTimeTic)+patRec.tW+procTime(fpTW); - selTimeTW = nTW-fpTW+1; - elseif nCorrMov == nwCompTime; - compTime = toc(selTimeTic)+patRec.tW+procTime(fpTW); - compTimeTW = nTW-fpTW+1; - set(handles.t_msgMT,'Visible','on'); - drawnow; - end - else % At least one movement is correct? - for i = 1 : size(outMov,1) - if find(patRec.movOutIdx{mIdx(m)} == outMov(i)) - nCorrMov1 = nCorrMov1 + 1; - if nCorrMov1 == 1; - selTime1 = toc(selTimeTic)+patRec.tW+procTime(fpTW); - selTime1TW = nTW-fpTW+1; - elseif nCorrMov1 == nwCompTime; - compTime1 = toc(selTimeTic)+patRec.tW+procTime(fpTW); - compTime1TW = nTW-fpTW+1; - end - break; % Break the for - end - end - end - - if ~isnan(compTime) - src.stop(); - pause(1); - end - % Next cycle - nTW = nTW + 1; - end - - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Motion Test for to evaluate real-time performance of the patRec +% This test is implemented in such a way that the "rest" movement is +% required +% +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-01-xx / Max Ortiz / Creation from MotionTestLegacy +% 2012-05-29 / Max Ortiz / Addition of "clear" commands +% 2012-07-24 / Max Ortiz / Use fpTW to compute the predition time of the +% first prediction in order to calculate the selection time +% 2012-10-05 / Joel Falk-Dahlin / Added ApplyControl after OneShotPatRec +% to allow for the use of control algorithms in the motion test +% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl +% 2012-11-06 / Max Ortiz / Create RealimePatRec_OneShot to concentrate +% critical routines of realtime patrec +% 2013-01-29 / Nichlas Sander / Added possibility to use VRE as guidance +% during the motion test. +% 2015-02-02 / Enzo Mastinu / All this function has been re-organizated +% to be compatible with the functions +% placed into COMM/AFE folder. For more +% details read RecordingSession.m log. + +% 20xx-xx-xx / Author / Comment on update + + + +function motionTest = MotionTest(patRecX, handlesX) + +clear global; + +global patRec; +global handles; +global nTW; % Number of time windows evaluated +global fpTW; % Time window of the first prediction +global dataTW; % Raw data from each time windows +global tempData; % Reset tempData if it is the first call +global motorCoupling; +global vreCoupling; +global thresholdGUIData; + +% Time markers +global selTimeTic; + +% Key performance indicators +global nCorrMov; +global selTime; % Selection time (selected = expected movement) +global selTimeTW; +global compTime; % Completion time (selected = expected movement) +global compTimeTW; +global nwCompTime; % Number of time windows to consider completion time +global predictions; +global procTime; % Processing time + +% Key performance indicators for at least 1 correct prediction +global nCorrMov1; % Number of at least 1 correct number +global selTime1; % Selection time (selected = at leas 1 expected mov) +global selTime1TW; +global compTime1; % Completion time (selected = at leas 1 expected mov) +global compTime1TW; +% Variables to keep track of testing movement +global mIdx; +global m; + +%% Init variable +patRec = patRecX; +handles = handlesX; +pDiv = 4; % Peeking devider +trials = str2double(get(handles.et_trials,'String')); +nR = str2double(get(handles.et_nR,'String')); +timeOut = str2double(get(handles.et_timeOut,'String')); +nwCompTime = 20; % Number of windows to consider completion time +pause on; % Enable pauses + +%% Is threshold (thOut) used? +if(isfield(patRec.patRecTrained,'thOut')); + %Threshold GUI init + thresholdGUI = GUI_Threshold; + thresholdGUIData = guidata(thresholdGUI); + set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); + xpatch = [1 1 0 0]; + ypatch = [0 0 0 0]; + for i=0:patRec.nOuts-1 + s = sprintf('movementSelector%d',i); + s0 = sprintf('thPatch%d',i); + s1 = sprintf('meter%d',i); + axes(thresholdGUIData.(s1)); + handles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); + ylim(thresholdGUIData.(s1), [0 1]); + xlim('auto'); + set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); + if (size(patRec.mov(patRec.indMovIdx),1) < i+1); + set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); + else + set(thresholdGUIData.(s),'Value',i+1); + end + end +end + +%% Is the VRE selected? +if isfield(handles,'cb_motionTestVRE') + trainUsingVre = get(handles.cb_motionTestVRE,'Value'); +else + trainUsingVre = 0; +end + +%% Is there an option for coupling with the motors? +if isfield(handles,'cb_motorCoupling') + motorCoupling = get(handles.cb_motorCoupling,'Value'); +else + motorCoupling = 0; +end + +%% Init motionTest structure +motionTest.patRec = patRec; +motionTest.sF = patRec.sF; +% motionTest.tW = patRec.tW; +motionTest.trails = trials; +motionTest.nR = nR; +motionTest.timeOut = timeOut; + +sF = motionTest.sF; +nCh = length(patRec.nCh); +ComPortType = patRec.comm; +deviceName = patRec.dev; + +% Get sampling time +sT = motionTest.timeOut; +tW = sT/100; % Time window size +tWs = tW*sF; % Time window samples + + +%% Motion Test +% Note: Probabily this way of testing only works for the NI +% specific funtions per card might be required. + +if trainUsingVre + if ~isfield(handles,'vre_Com') + handles = ConnectVRE(handles,'Virtual Reality.exe'); + end +end + + +% run over all the trails +for t = 1 : trials + + for i = 1 : 5; + msg = ['Trial: "' num2str(t) '" in: ' num2str(6-i) ' seconds']; + set(handles.t_msg,'String',msg); + pause(1); + end + + % repeat the movement the chosen times + for r = 1 : nR + % Randomize the aperance of the requested movement + mIdx = randperm(patRec.nM - 1); % It doesn't include "rest" + % Run over all movements but "rest" + for m = 1 : patRec.nM - 1 + + %Select movement + movementObjects = handles.movList(patRec.movOutIdx{mIdx(m)}); + mov = patRec.mov{mIdx(m)}; + %Prepare + for i = 1 : 3; + % Warn the user + %msg = ['Relax and prepare to "' mov '" in: ' num2str(4-i) ' seconds (trial:' num2str(t) ', rep:' num2str(r) ')']; + % No warning + msg = 'Relax'; + set(handles.t_msg,'String',msg); + pause(1); + end + + % Warning to the user + fileName = ['Img/' char(mov) '.jpg']; + if ~exist(fileName,'file') + fileName = 'Img/relax.jpg'; + end + % Display image + movI = importdata(fileName); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + + % Init required for patRec of the selected movement + nTW = 1; % Number of time windows + fpTW = 0; % Time window of the first prediction + nCorrMov = 0; % Number of corect movements + predictions = {}; % Vector with the classifier prediction per tw + selTime = NaN; % Selection time + selTimeTW = NaN; % nTW when the selection time happen + compTime = NaN; % Completion time + compTimeTW = NaN; % nTW when the completion time happen + + nCorrMov1 = 0; % Number of corect movements of at least 1 mov + selTime1 = NaN; % Selection time of at least 1 expected mov + selTime1TW = NaN; % nTW when the selection time happen + compTime1 = NaN; % Completion time + compTime1TW = NaN; % nTW when the completion time happen + + selTimeTic = []; % Resets the time of first movement + procTime = []; % Processing time (vector) + dataTW = []; % Reset the dataTW (matrix) + tempData = []; % Reset tempData if it is the first call + + % Ask the user to execute movement + set(handles.t_msg,'String',mov); + drawnow; + + + % Move the VRE into place. + for i = 1:length(movementObjects) + movementObject = movementObjects(i); + if trainUsingVre + % Send values to VRE to move hand into position. + for j = 1:15 %Move it 15 times, distance of 5 each time. + VREActivation(handles.vre_Com,5,[],movementObject.idVRE, movementObject.vreDir, 0); + end + end + end + + + cData = zeros(tWs,nCh); + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @MotionTest_OneShot); + + % Start DAQ + s.startBackground(); % Run in the backgroud + + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + + %%%%% Motion Test with other custom device %%%%% + else + + % Prepare handles for next function calls + handles.deviceName = deviceName; + handles.ComPortType = ComPortType; + if strcmp (ComPortType, 'COM') + handles.ComPortName = patRec.comn; + end + handles.sF = sF; + handles.sT = sT; + handles.nCh = nCh; + handles.sTall = sT; + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + for timeWindowNr = 1:sT/tW + + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + MotionTest_OneShot(0, acquireEvent); + end + + % Stop acquisition + StopAcquisition(deviceName, obj); + end + + + %Reset the VRE. + if trainUsingVre + ResetVRE(handles.vre_Com,1,1); + end + + %% Save data + test.mov = mov; + test.nTW = nTW-1; + test.fpTW = fpTW; + test.nCorrMov = nCorrMov; + test.predictions = predictions; + test.selTime = selTime; + test.selTimeTW = selTimeTW; + test.compTime = compTime; + test.compTimeTW = compTimeTW; + % Performance for at least 1 movement + test.nCorrMov1 = nCorrMov1; + test.selTime1 = selTime1; + test.selTime1TW = selTime1TW; + test.compTime1 = compTime1; + test.compTime1TW = compTime1TW; + % Data + test.dataTW = dataTW; + test.procTime = mean(procTime); + + % Test fail? + if isnan(compTime) + test.fail = 1; + % Test failed even for 1 movement simul? + if isnan(compTime1) + test.fail1 = 1; + else + test.fail1 = 0; + end + else + test.fail = 0; + test.fail1 = 0; + end + + % Compute accuracy between fpTw to achivement of compTime + if test.fail + % Consider the accuracy during fail trials + %corrP = sum(predictions == mIdx(m)); + %test.acc = corrP / size(predictions,2); + + %Don't acount for acc in failed trials + test.acc = NaN; + + else + corrP = 0; + for i = fpTW : compTimeTW+fpTW-1 + if isequal(predictions{i},patRec.movOutIdx{mIdx(m)}') + corrP = corrP +1; + end + end + %corrP = sum(predictions{fpTW:fpTW+compTimeTW-1} == mIdx(m)); %It doesn't work for simultaneous prediction + test.acc = corrP / compTimeTW; + end + + disp(test); + motionTest.test(r,mIdx(m),t) = test; + delete(pic); + set(handles.t_msgMT,'Visible','off'); + drawnow; + end + end +end + +if trainUsingVre + handles = DisconnectVRE(handles); +end + +% Saved any modification to patRec +motionTest.patRec = patRec; + +pause off; + +% show results +motionTest = MotionTestResults(motionTest); + +% Save test +disp(motionTest); +[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); + if isequal(filename,0) || isequal(pathname,0) + disp('User pressed cancel') + else + save([pathname,filename],'motionTest'); + end + +% Clear key variables +clear mIdx; +clear m; +end + + +function MotionTest_OneShot(src,event) + + % General + global patRec; + global handles; + global nTW; % Number of time windows evaluated + global fpTW; % Time window of the first prediction + global dataTW; % Raw data from each time windows + global tempData; + global motorCoupling; + global vreCoupling; + global thresholdGUIData; + + % Time markers + global selTimeTic; + % Key performance indicators + global procTime; + global nCorrMov; + global selTime; % Selection time + global selTimeTW; + global compTime; % Completion time + global compTimeTW; + global nwCompTime; % Number of time windows to consider completion time + global predictions; + % Key performance indicators for at least one movement + global nCorrMov1; % Number of at least 1 correct number + global selTime1; % Selection time (selected = at leas 1 expected mov) + global selTime1TW; + global compTime1; % Completion time (selected = at leas 1 expected mov) + global compTime1TW; + % Variables to keep track of testing movement + global mIdx; + global m; + + + tempData = [tempData; event.Data]; % Record all signal + + % Is there enough data for a TW? + if size(tempData,1) >= (patRec.sF*patRec.tW) + + % Save the TW data, maybe useful for further analysis + tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data + dataTW(:,:,nTW) = tData; % Save data for future analisys + + % Start of processing time + procTimeTic = tic; + + % General routine for RealtimePatRec + [outMov outVector patRec handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData); + + % Finish of processing time + procTime(nTW) = toc(procTimeTic); + + % Save the classifier prediction for statistics + predictions{nTW} = outMov; + + % Is there a prediction different than "rest"? + % This conditional considers that there is always a rest movement, + % and this has the last index, therefore rest Indx = patRec.nOuts + if isempty(selTimeTic) + % Compare each outMov to rest +% maskRest(1:size(outMov)) = patRec.nM; + maskRest(1:size(outMov)) = patRec.nOuts; + if sum(outMov ~= maskRest') + selTimeTic = tic; % Starts counting time for selection and completion + fpTW = nTW; % Consider the TW of the first moment + end + end + + % Is the output the expected classes? + if isequal(patRec.movOutIdx{mIdx(m)}, outMov') + nCorrMov = nCorrMov + 1; + if nCorrMov == 1; + selTime = toc(selTimeTic)+patRec.tW+procTime(fpTW); + selTimeTW = nTW-fpTW+1; + elseif nCorrMov == nwCompTime; + compTime = toc(selTimeTic)+patRec.tW+procTime(fpTW); + compTimeTW = nTW-fpTW+1; + set(handles.t_msgMT,'Visible','on'); + drawnow; + end + else % At least one movement is correct? + for i = 1 : size(outMov,1) + if find(patRec.movOutIdx{mIdx(m)} == outMov(i)) + nCorrMov1 = nCorrMov1 + 1; + if nCorrMov1 == 1; + selTime1 = toc(selTimeTic)+patRec.tW+procTime(fpTW); + selTime1TW = nTW-fpTW+1; + elseif nCorrMov1 == nwCompTime; + compTime1 = toc(selTimeTic)+patRec.tW+procTime(fpTW); + compTime1TW = nTW-fpTW+1; + end + break; % Break the for + end + end + end + +% if ~isnan(compTime) +% src.stop(); +% pause(1); +% end + % Next cycle + nTW = nTW + 1; + end + + end + diff --git a/PatRec/MotionTestResults.m b/PatRec/MotionTestResults.m index bc7cecb..82ec8a7 100644 --- a/PatRec/MotionTestResults.m +++ b/PatRec/MotionTestResults.m @@ -1,118 +1,118 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to print the results of the motion test -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-04-02 / Max Ortiz / Creation -% 2012-05-30 / Max Ortiz / Modified to return motionTest with values -% 20xx-xx-xx / Author / Comment on update - -function motionTest = MotionTestResults(motionTest) - -nSucct = zeros(motionTest.patRec.nM-1,1); - -% General matrix -for t = 1 : motionTest.trails - for m = 1 : motionTest.patRec.nM - 1 - for r = 1 : motionTest.nR - selTime(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).selTime; - selTimeTW(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).selTimeTW; - compTime(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).compTime; - compTimeTW(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).compTimeTW; - acc(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).acc; - - % Check the numer of succesful trails - if ~motionTest.test(r,m,t).fail - nSucct(m) = nSucct(m) + 1; % Number of succesful trials - end - end - end -end - -compRate = nSucct ./ (motionTest.nR*motionTest.trails); - - -%% Add a mean -compRate(end+1) = mean(compRate); -selTime(:,end+1) = nanmean(selTime,2); -compTime(:,end+1) = nanmean(compTime,2); -acc(:,end+1) = nanmean(acc,2); - -%% Save results - -motionTest.compRate = compRate; -motionTest.selTime = selTime; -motionTest.selTimeTW = selTimeTW; -motionTest.compTime = compTime; -motionTest.compTimeTW = compTimeTW; -motionTest.acc = acc; - -%% plot and save results -% Selection Time -figure(); -boxplot(selTime,'plotstyle','compact') -hold on; -plot(nanmean(selTime),'r*'); -title('Selection Time'); -xlabel('Movements (mean @ end)'); -ylabel('Seconds'); - -% Selection Time - Time Window -figure(); -boxplot(selTimeTW,'plotstyle','compact') -hold on; -plot(nanmean(selTimeTW),'r*'); -title('Selection Time - TW'); -xlabel('Movements'); -ylabel('Number of Time Windows'); - -% Completion Time -figure(); -boxplot(compTime,'plotstyle','compact') -hold on; -plot(nanmean(compTime),'r*'); -title('Completion Time'); -xlabel('Movements (mean @ end)'); -ylabel('Seconds'); - -% Completion Time - Time Window -figure(); -boxplot(compTimeTW,'plotstyle','compact') -hold on; -plot(nanmean(compTimeTW),'r*'); -title('Completion Time - TW'); -xlabel('Movements'); -ylabel('Number of Time Windows'); - -% Completion rate -figure(); -plot(compRate,'r-*'); -title('Completion rate'); -xlabel('Movements (mean @ end)'); -ylabel('% of completion'); - -% Accuracy -figure(); -boxplot(acc,'plotstyle','compact') -hold on; -plot(nanmean(acc),'r*'); -title('Prediction accuracy on completed motions'); -xlabel('Movements'); -ylabel('Accuracy'); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to print the results of the motion test +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-04-02 / Max Ortiz / Creation +% 2012-05-30 / Max Ortiz / Modified to return motionTest with values +% 20xx-xx-xx / Author / Comment on update + +function motionTest = MotionTestResults(motionTest) + +nSucct = zeros(motionTest.patRec.nM-1,1); + +% General matrix +for t = 1 : motionTest.trails + for m = 1 : motionTest.patRec.nM - 1 + for r = 1 : motionTest.nR + selTime(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).selTime; + selTimeTW(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).selTimeTW; + compTime(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).compTime; + compTimeTW(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).compTimeTW; + acc(r+(motionTest.nR*(t-1)),m) = motionTest.test(r,m,t).acc; + + % Check the numer of succesful trails + if ~motionTest.test(r,m,t).fail + nSucct(m) = nSucct(m) + 1; % Number of succesful trials + end + end + end +end + +compRate = nSucct ./ (motionTest.nR*motionTest.trails); + + +%% Add a mean +compRate(end+1) = mean(compRate); +selTime(:,end+1) = nanmean(selTime,2); +compTime(:,end+1) = nanmean(compTime,2); +acc(:,end+1) = nanmean(acc,2); + +%% Save results + +motionTest.compRate = compRate; +motionTest.selTime = selTime; +motionTest.selTimeTW = selTimeTW; +motionTest.compTime = compTime; +motionTest.compTimeTW = compTimeTW; +motionTest.acc = acc; + +%% plot and save results +% Selection Time +figure(); +boxplot(selTime,'plotstyle','compact') +hold on; +plot(nanmean(selTime),'r*'); +title('Selection Time'); +xlabel('Movements (mean @ end)'); +ylabel('Seconds'); + +% Selection Time - Time Window +figure(); +boxplot(selTimeTW,'plotstyle','compact') +hold on; +plot(nanmean(selTimeTW),'r*'); +title('Selection Time - TW'); +xlabel('Movements'); +ylabel('Number of Time Windows'); + +% Completion Time +figure(); +boxplot(compTime,'plotstyle','compact') +hold on; +plot(nanmean(compTime),'r*'); +title('Completion Time'); +xlabel('Movements (mean @ end)'); +ylabel('Seconds'); + +% Completion Time - Time Window +figure(); +boxplot(compTimeTW,'plotstyle','compact') +hold on; +plot(nanmean(compTimeTW),'r*'); +title('Completion Time - TW'); +xlabel('Movements'); +ylabel('Number of Time Windows'); + +% Completion rate +figure(); +plot(compRate,'r-*'); +title('Completion rate'); +xlabel('Movements (mean @ end)'); +ylabel('% of completion'); + +% Accuracy +figure(); +boxplot(acc,'plotstyle','compact') +hold on; +plot(nanmean(acc),'r*'); +title('Prediction accuracy on completed motions'); +xlabel('Movements'); +ylabel('Accuracy'); + diff --git a/PatRec/MotionTest_Legacy.m b/PatRec/MotionTest_Legacy.m index 1053983..3d0b915 100644 --- a/PatRec/MotionTest_Legacy.m +++ b/PatRec/MotionTest_Legacy.m @@ -1,164 +1,164 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Motion Test for to evaluate real-time performance of the patRec -% -% --------------------------Updates-------------------------- -% 2011-08-02 / Max Ortiz / Creation - - -function motionTest = MotionTest_Legacy(patRec, handles) - -trials = str2double(get(handles.et_trials,'String')); -nR = str2double(get(handles.et_nR,'String')); -timeOut = str2double(get(handles.et_timeOut,'String')); -pause on; - -%% Init motionTest structure -motionTest.sF = patRec.sF; -motionTest.tW = patRec.tW; -motionTest.trails = trials; -motionTest.nR = nR; -motionTest.timeOut = timeOut; - - -%% Initialize DAQ card -% Note: A function for DAQ selection will be required when more cards are -% added - -if strcmp(patRec.dev,'ADH') - -else % at this poin everything else is the NI - USB6009 - chAI = zeros(1,8); - chAI(patRec.nCh) = 1; - ai = InitNI(patRec.sF,timeOut,chAI); -end - -%% Motion Test -% Note: Probabily this way of testing only works for the NI -% specific funtions per card might be required. - -% run over all the trails -for t = 1 : trials - - % Randomize the aperance of the requested movement - mIdx = randperm(patRec.nM); - - % Run over all movements - for m = 1 : patRec.nM - - %Select movement - mov = patRec.mov{mIdx(m)}; - %Prepare - for i = 1 : 3; - msg = ['Relax and prepare to "' mov '" in: ' num2str(4-i) ' seconds (trial:' num2str(t) ')' ]; - set(handles.t_msg,'String',msg); - pause(1); - end - - % Init required for patRec of the selected movement - nTW = 1; % Number of time windows - nCorrMov = 0; % Number of corect movements - selTime = inf; % Selection time - selTimeTW = inf; % nTW when the selection time happen - compTime = inf; % Completion time - compTimeTW = inf; % nTW when the completion time happen - clear 'dataTW'; - - - % Execute movement - set(handles.t_msg,'String',mov); - drawnow; - start(ai); % Start the data acquision for timeOut seconds - selTimeS = tic; - - % Wait until the first samples are aquired - while ai.SamplesAcquired < patRec.sF*patRec.tW - end - % start DAQ - while ai.SamplesAcquired < patRec.sF*timeOut - - %Data Peek - data = peekdata(ai,patRec.sF*patRec.tW); - dataTW(:,:,nTW) = data; % Save data for future analisys - - %Signal processing - tSet = SignalProcessing_RealtimePatRec(data, patRec); - - % One shoot PatRec - [selMov outVector] = OneShotPatRecClassifier(patRec, tSet); - -% % Algorithm selection -% if strcmp(patRec.algorithm,'ANN'); -% -% elseif strcmp(patRec.algorithm,'DA') -% selMov = DiscriminantTest(patRec.coeff, tSet, patRec.training); -% end - - % Check the selected movement - if mIdx(m) == selMov - nCorrMov = nCorrMov + 1; - if nCorrMov == 1; - selTime = toc(selTimeS); - selTimeTW = nTW; - elseif nCorrMov == 10; - compTime = toc(selTimeS); - compTimeTW = nTW; - end - end - - % Show results - set(handles.lb_movements,'Value',selMov); - drawnow; - - % Next cycle - nTW = nTW + 1; - - end - % Finish current movement - test.mov = mov; - test.nTW = nTW-1; - test.nCorrMov = nCorrMov; - test.selTime = selTime; - test.selTimeTW = selTimeTW; - test.compTime = compTime; - test.compTimeTW = compTimeTW; - test.dataTW = dataTW; - if compTime == inf - test.fail = 1; - else - test.fail = 0; - end - disp(test); - motionTest.test(t,mIdx(m)) = test; - stop(ai); - end -end - -delete(ai); -pause off; -disp(motionTest); - -[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); - if isequal(filename,0) || isequal(pathname,0) - disp('User pressed cancel') - else - save([pathname,filename],'motionTest'); - end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Motion Test for to evaluate real-time performance of the patRec +% +% --------------------------Updates-------------------------- +% 2011-08-02 / Max Ortiz / Creation + + +function motionTest = MotionTest_Legacy(patRec, handles) + +trials = str2double(get(handles.et_trials,'String')); +nR = str2double(get(handles.et_nR,'String')); +timeOut = str2double(get(handles.et_timeOut,'String')); +pause on; + +%% Init motionTest structure +motionTest.sF = patRec.sF; +motionTest.tW = patRec.tW; +motionTest.trails = trials; +motionTest.nR = nR; +motionTest.timeOut = timeOut; + + +%% Initialize DAQ card +% Note: A function for DAQ selection will be required when more cards are +% added + +if strcmp(patRec.dev,'ADH') + +else % at this poin everything else is the NI - USB6009 + chAI = zeros(1,8); + chAI(patRec.nCh) = 1; + ai = InitNI(patRec.sF,timeOut,chAI); +end + +%% Motion Test +% Note: Probabily this way of testing only works for the NI +% specific funtions per card might be required. + +% run over all the trails +for t = 1 : trials + + % Randomize the aperance of the requested movement + mIdx = randperm(patRec.nM); + + % Run over all movements + for m = 1 : patRec.nM + + %Select movement + mov = patRec.mov{mIdx(m)}; + %Prepare + for i = 1 : 3; + msg = ['Relax and prepare to "' mov '" in: ' num2str(4-i) ' seconds (trial:' num2str(t) ')' ]; + set(handles.t_msg,'String',msg); + pause(1); + end + + % Init required for patRec of the selected movement + nTW = 1; % Number of time windows + nCorrMov = 0; % Number of corect movements + selTime = inf; % Selection time + selTimeTW = inf; % nTW when the selection time happen + compTime = inf; % Completion time + compTimeTW = inf; % nTW when the completion time happen + clear 'dataTW'; + + + % Execute movement + set(handles.t_msg,'String',mov); + drawnow; + start(ai); % Start the data acquision for timeOut seconds + selTimeS = tic; + + % Wait until the first samples are aquired + while ai.SamplesAcquired < patRec.sF*patRec.tW + end + % start DAQ + while ai.SamplesAcquired < patRec.sF*timeOut + + %Data Peek + data = peekdata(ai,patRec.sF*patRec.tW); + dataTW(:,:,nTW) = data; % Save data for future analisys + + %Signal processing + tSet = SignalProcessing_RealtimePatRec(data, patRec); + + % One shoot PatRec + [selMov outVector] = OneShotPatRecClassifier(patRec, tSet); + +% % Algorithm selection +% if strcmp(patRec.algorithm,'ANN'); +% +% elseif strcmp(patRec.algorithm,'DA') +% selMov = DiscriminantTest(patRec.coeff, tSet, patRec.training); +% end + + % Check the selected movement + if mIdx(m) == selMov + nCorrMov = nCorrMov + 1; + if nCorrMov == 1; + selTime = toc(selTimeS); + selTimeTW = nTW; + elseif nCorrMov == 10; + compTime = toc(selTimeS); + compTimeTW = nTW; + end + end + + % Show results + set(handles.lb_movements,'Value',selMov); + drawnow; + + % Next cycle + nTW = nTW + 1; + + end + % Finish current movement + test.mov = mov; + test.nTW = nTW-1; + test.nCorrMov = nCorrMov; + test.selTime = selTime; + test.selTimeTW = selTimeTW; + test.compTime = compTime; + test.compTimeTW = compTimeTW; + test.dataTW = dataTW; + if compTime == inf + test.fail = 1; + else + test.fail = 0; + end + disp(test); + motionTest.test(t,mIdx(m)) = test; + stop(ai); + end +end + +delete(ai); +pause off; +disp(motionTest); + +[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); + if isequal(filename,0) || isequal(pathname,0) + disp('User pressed cancel') + else + save([pathname,filename],'motionTest'); + end + + diff --git a/PatRec/Normalization/NormalizeSet.m b/PatRec/Normalization/NormalizeSet.m index fc5cf22..5f520ab 100644 --- a/PatRec/Normalization/NormalizeSet.m +++ b/PatRec/Normalization/NormalizeSet.m @@ -1,57 +1,57 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to normalize the testing set according to how the previously -% saved normalization parameters -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-10-09 / Max Ortiz / Created -% 2012-10-10 / Max Ortiz / Addition of Mean0Std and NormLog -% 20xx-xx-xx / Author / Comment on update - -function tSet = NormalizeSet(tSet, patRec) - - if strcmp(patRec.normSets.type,'None') - - return; - - elseif strcmp(patRec.normSets.type,'Mean0Var1') - - tSet = (tSet - patRec.normSets.nMean) ./ patRec.normSets.nVar; - - elseif strcmp(patRec.normSets.type,'Mean0Std1') - - tSet = (tSet - patRec.normSets.nMean) ./ patRec.normSets.nStd; - - elseif strcmp(patRec.normSets.type,'UnitaryRange') - - tSet = (tSet - patRec.normSets.min) ./ patRec.normSets.range; - - elseif strcmp(patRec.normSets.type,'Midrange0Range2') - - tSet = (tSet - patRec.normSets.midrange) ./ (patRec.normSets.range/2); - - elseif strcmp(patRec.normSets.type,'NormLog') - - tSet = log(abs(tSet - patRec.normSets.min) +1) ; - - else - disp('Error: No normalization method found'); - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to normalize the testing set according to how the previously +% saved normalization parameters +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-10-09 / Max Ortiz / Created +% 2012-10-10 / Max Ortiz / Addition of Mean0Std and NormLog +% 20xx-xx-xx / Author / Comment on update + +function tSet = NormalizeSet(tSet, patRec) + + if strcmp(patRec.normSets.type,'None') + + return; + + elseif strcmp(patRec.normSets.type,'Mean0Var1') + + tSet = (tSet - patRec.normSets.nMean) ./ patRec.normSets.nVar; + + elseif strcmp(patRec.normSets.type,'Mean0Std1') + + tSet = (tSet - patRec.normSets.nMean) ./ patRec.normSets.nStd; + + elseif strcmp(patRec.normSets.type,'UnitaryRange') + + tSet = (tSet - patRec.normSets.min) ./ patRec.normSets.range; + + elseif strcmp(patRec.normSets.type,'Midrange0Range2') + + tSet = (tSet - patRec.normSets.midrange) ./ (patRec.normSets.range/2); + + elseif strcmp(patRec.normSets.type,'NormLog') + + tSet = log(abs(tSet - patRec.normSets.min) +1) ; + + else + disp('Error: No normalization method found'); + end + end \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_Mean0Std1.m b/PatRec/Normalization/NormalizeSets_Mean0Std1.m index e3db5d3..9f2952b 100644 --- a/PatRec/Normalization/NormalizeSets_Mean0Std1.m +++ b/PatRec/Normalization/NormalizeSets_Mean0Std1.m @@ -1,37 +1,37 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Normalization to zero mean and unit variance -% Requires test and validation set -% -% ------------- Updates ------------- -% 2012-10-10 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [trSet vSet mn st] = NormalizeSets_Mean0Std1(trSet, vSet) - - %Get mean - mn = mean(trSet,1); - %Ger variance - st = std(trSet); - % Normalize - trSet = (trSet - mn(ones(size(trSet,1), 1), :)) ./ st(ones(size(trSet,1), 1), :); - vSet = (vSet - mn(ones(size(vSet, 1), 1), :)) ./ st(ones(size(vSet, 1), 1), :); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Normalization to zero mean and unit standard deviation +% Requires test and validation set +% +% ------------- Updates ------------- +% 2012-10-10 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [trSet vSet mn st] = NormalizeSets_Mean0Std1(trSet, vSet) + + %Get mean + mn = mean(trSet,1); + %Ger variance + st = std(trSet); + % Normalize + trSet = (trSet - mn(ones(size(trSet,1), 1), :)) ./ st(ones(size(trSet,1), 1), :); + vSet = (vSet - mn(ones(size(vSet, 1), 1), :)) ./ st(ones(size(vSet, 1), 1), :); + + \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_Mean0Var1.m b/PatRec/Normalization/NormalizeSets_Mean0Var1.m index 8e857b9..7b9f118 100644 --- a/PatRec/Normalization/NormalizeSets_Mean0Var1.m +++ b/PatRec/Normalization/NormalizeSets_Mean0Var1.m @@ -1,50 +1,50 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Normalization to zero mean and unit variance -% Requires test and validation set -% -% ------------- Updates ------------- -% 2011-10-06 / Max Ortiz / Creation (maxo@chalmers.se) -% 2011-10-10 / Max Ortiz / Normalization paramenters only taken from trSet - -function [trSet vSet mn vr] = NormalizeSets_Mean0Var1(trSet, vSet) - - %Get mean - mn = mean(trSet,1); - %Ger variance - vr = var(trSet); - % Normalize - trSet = (trSet - mn(ones(size(trSet,1), 1), :)) ./ vr(ones(size(trSet,1), 1), :); - vSet = (vSet - mn(ones(size(vSet, 1), 1), :)) ./ vr(ones(size(vSet, 1), 1), :); - - -%% Old implementation where Tr and V sets where normalized together -% %put together all the sets -% allsets = trset; -% allsets(length(trset(:,1))+1 : length(trset(:,1))+length(vset(:,1)),:) = vset; -% % get mean -% mn = mean(allsets,1); -% %get variance -% vr = var(allsets); -% %normalize each set -% trset = (trset - mn(ones(size(trset,1), 1), :)) ./ vr(ones(size(trset,1), 1), :); -% vset = (vset - mn(ones(size(vset, 1), 1), :)) ./ vr(ones(size(vset, 1), 1), :); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Normalization to zero mean and unit variance +% Requires test and validation set +% +% ------------- Updates ------------- +% 2011-10-06 / Max Ortiz / Creation (maxo@chalmers.se) +% 2011-10-10 / Max Ortiz / Normalization paramenters only taken from trSet + +function [trSet vSet mn vr] = NormalizeSets_Mean0Var1(trSet, vSet) + + %Get mean + mn = mean(trSet,1); + %Ger variance + vr = var(trSet); + % Normalize + trSet = (trSet - mn(ones(size(trSet,1), 1), :)) ./ vr(ones(size(trSet,1), 1), :); + vSet = (vSet - mn(ones(size(vSet, 1), 1), :)) ./ vr(ones(size(vSet, 1), 1), :); + + +%% Old implementation where Tr and V sets where normalized together +% %put together all the sets +% allsets = trset; +% allsets(length(trset(:,1))+1 : length(trset(:,1))+length(vset(:,1)),:) = vset; +% % get mean +% mn = mean(allsets,1); +% %get variance +% vr = var(allsets); +% %normalize each set +% trset = (trset - mn(ones(size(trset,1), 1), :)) ./ vr(ones(size(trset,1), 1), :); +% vset = (vset - mn(ones(size(vset, 1), 1), :)) ./ vr(ones(size(vset, 1), 1), :); + + \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_Midrange0Range2.m b/PatRec/Normalization/NormalizeSets_Midrange0Range2.m index a07638b..35f98f2 100644 --- a/PatRec/Normalization/NormalizeSets_Midrange0Range2.m +++ b/PatRec/Normalization/NormalizeSets_Midrange0Range2.m @@ -1,46 +1,46 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Normalization to zero mean and unit variance -% Requires all available sets -% -% ------------- Updates ------------- -% 2011-10-10 / Max Ortiz / Creation (maxo@chalmers.se) -% 20xx-xx-xx / Author / Comment on update - - -function [trSet vSet mRange mMidrange] = NormalizeSets_Midrange0Range2(trSet, vSet) - - mMin = min(trSet); % matrix min - mMax = max(trSet); %matrix max - mRange = mMax - mMin; - mMidrange = (mMax + mMin)/2; - - % Normalize by using the range which will create a distribution between - % 0 and 1 - for i = 1 : size(trSet,2) - trSet(:,i) = (trSet(:,i) - mMidrange(i)) ./ (mRange(i)/2); - end - - % Normalize the validation set from the information of training set - for i = 1 : size(vSet,2) - vSet(:,i) = (vSet(:,i) - mMidrange(i)) ./ (mRange(i)/2); - end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Normalization to zero mean and unit variance +% Requires all available sets +% +% ------------- Updates ------------- +% 2011-10-10 / Max Ortiz / Creation (maxo@chalmers.se) +% 20xx-xx-xx / Author / Comment on update + + +function [trSet vSet mRange mMidrange] = NormalizeSets_Midrange0Range2(trSet, vSet) + + mMin = min(trSet); % matrix min + mMax = max(trSet); %matrix max + mRange = mMax - mMin; + mMidrange = (mMax + mMin)/2; + + % Normalize by using the range which will create a distribution between + % 0 and 1 + for i = 1 : size(trSet,2) + trSet(:,i) = (trSet(:,i) - mMidrange(i)) ./ (mRange(i)/2); + end + + % Normalize the validation set from the information of training set + for i = 1 : size(vSet,2) + vSet(:,i) = (vSet(:,i) - mMidrange(i)) ./ (mRange(i)/2); + end + + \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_TrV.m b/PatRec/Normalization/NormalizeSets_TrV.m index e73f2b4..be6ac05 100644 --- a/PatRec/Normalization/NormalizeSets_TrV.m +++ b/PatRec/Normalization/NormalizeSets_TrV.m @@ -1,68 +1,68 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Function to normalize the Trainig and Validation Sets, the testing set -% is normalize according to how the the two latter where normalized -% -% ------------- Updates ------------- -% 2011-10-09 / Max Ortiz / -% 20xx-xx-xx / Author / Comment on update - -function [trSet vSet patRec] = NormalizeSets_TrV(normSetsType, trSet, vSet, patRec) - - if strcmp(normSetsType,'Select Normalization') - normSets.type = 'None'; - - elseif strcmp(normSetsType,'Mean0Var1') - %[trSet vSet tSet mn vr] = NormalizeSets_mean0_var1(trSet, vSet, tSet); - [trSet vSet mn vr] = NormalizeSets_Mean0Var1(trSet, vSet); - normSets.type = normSetsType; - normSets.nMean = mn; - normSets.nVar = vr; - - elseif strcmp(normSetsType,'Mean0Std1') - [trSet vSet mn st] = NormalizeSets_Mean0Std1(trSet, vSet); - normSets.type = normSetsType; - normSets.nMean = mn; - normSets.nStd = st; - - elseif strcmp(normSetsType,'UnitaryRange') - [trSet vSet mRange mMin] = NormalizeSets_UnitaryRange(trSet, vSet); - normSets.type = normSetsType; - normSets.min = mMin; - normSets.range = mRange; - - elseif strcmp(normSetsType,'Midrange0Range2') - [trSet vSet mRange mMidrange] = NormalizeSets_Midrange0Range2(trSet, vSet); - normSets.type = normSetsType; - normSets.midrange = mMidrange; - normSets.range = mRange; - - elseif strcmp(normSetsType,'NormLog') - [trSet vSet mMin] = NormalizeSets_normLog(trSet, vSet); - normSets.type = normSetsType; - normSets.min = mMin; - - else - - disp('No normalization method found'); - - end - patRec.normSets = normSets; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Function to normalize the Trainig and Validation Sets, the testing set +% is normalize according to how the the two latter where normalized +% +% ------------- Updates ------------- +% 2011-10-09 / Max Ortiz / +% 20xx-xx-xx / Author / Comment on update + +function [trSet vSet patRec] = NormalizeSets_TrV(normSetsType, trSet, vSet, patRec) + + if strcmp(normSetsType,'Select Normalization') + normSets.type = 'None'; + + elseif strcmp(normSetsType,'Mean0Var1') + %[trSet vSet tSet mn vr] = NormalizeSets_mean0_var1(trSet, vSet, tSet); + [trSet vSet mn vr] = NormalizeSets_Mean0Var1(trSet, vSet); + normSets.type = normSetsType; + normSets.nMean = mn; + normSets.nVar = vr; + + elseif strcmp(normSetsType,'Mean0Std1') + [trSet vSet mn st] = NormalizeSets_Mean0Std1(trSet, vSet); + normSets.type = normSetsType; + normSets.nMean = mn; + normSets.nStd = st; + + elseif strcmp(normSetsType,'UnitaryRange') + [trSet vSet mRange mMin] = NormalizeSets_UnitaryRange(trSet, vSet); + normSets.type = normSetsType; + normSets.min = mMin; + normSets.range = mRange; + + elseif strcmp(normSetsType,'Midrange0Range2') + [trSet vSet mRange mMidrange] = NormalizeSets_Midrange0Range2(trSet, vSet); + normSets.type = normSetsType; + normSets.midrange = mMidrange; + normSets.range = mRange; + + elseif strcmp(normSetsType,'NormLog') + [trSet vSet mMin] = NormalizeSets_normLog(trSet, vSet); + normSets.type = normSetsType; + normSets.min = mMin; + + else + + disp('No normalization method found'); + + end + patRec.normSets = normSets; + end \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_UnitaryRange.m b/PatRec/Normalization/NormalizeSets_UnitaryRange.m index cb083ae..d90565b 100644 --- a/PatRec/Normalization/NormalizeSets_UnitaryRange.m +++ b/PatRec/Normalization/NormalizeSets_UnitaryRange.m @@ -1,73 +1,73 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Normalization to zero mean and unit variance -% Requires all available sets -% -% ------------- Updates ------------- -% 2011-09-29 / Max Ortiz / Creation -% 2011-10-10 / Max Ortiz / Normalization paramenters only taken from trSet -% 20xx-xx-xx / Author / Comment on update - -function [trSet vSet mRange mMin] = NormalizeSets_UnitaryRange(trSet, vSet) - - tolerance = 0.0000001; - tempSet = trSet; - mMin = min(tempSet); - mMin = mMin - tolerance; %Quick patch for connMat - mMax = max(tempSet) + tolerance; - mRange = mMax - mMin; - - % Normalize by using the range which will create a distribution between - % 0 and 1 - for i = 1 : size(trSet,2) - trSet(:,i) = (tempSet(:,i) - mMin(i)) ./ mRange(i); - end - - % Normalize the validation set from the information of training set - for i = 1 : size(vSet,2) - vSet(:,i) = (vSet(:,i) - mMin(i)) ./ mRange(i); - vSet(find(vSet(:,i) < 0),i) = tolerance; - end - - - -%% Old implementation where Tr and V sets where normalized together -% %put together all the sets -% allSets = trSet; -% allSets(length(trSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1)),:) = vSet; -% %allSets(length(trSet(:,1))+length(vSet(:,1))+1 : -% %length(trSet(:,1))+length(vSet(:,1))+length(tSet(:,1)),:) = tSet; -% -% mMin = min(allSets); -% mMin = mMin + 0.0000001; %Quick patch for connMat -% mMax = max(allSets); -% mRange = mMax - mMin; -% -% % Normalize by using the range which will create a distribution between -% % 0 and 1 -% for i = 1 : size(allSets,2) -% allSets(:,i) = (allSets(:,i) - mMin(i)) ./ mRange(i); -% end -% -% trSet = allSets(1:size(trSet,1),:); -% vSet = allSets(length(trSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1)),:); -% %tSet = allSets(length(trSet(:,1))+length(vSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1))+length(tSet(:,1)),:); -% -% +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Normalization between 0 and 1 +% Requires all available sets +% +% ------------- Updates ------------- +% 2011-09-29 / Max Ortiz / Creation +% 2011-10-10 / Max Ortiz / Normalization paramenters only taken from trSet +% 20xx-xx-xx / Author / Comment on update + +function [trSet vSet mRange mMin] = NormalizeSets_UnitaryRange(trSet, vSet) + + tolerance = 0.0000001; + tempSet = trSet; + mMin = min(tempSet); + mMin = mMin - tolerance; %Quick patch for connMat + mMax = max(tempSet) + tolerance; + mRange = mMax - mMin; + + % Normalize by using the range which will create a distribution between + % 0 and 1 + for i = 1 : size(trSet,2) + trSet(:,i) = (tempSet(:,i) - mMin(i)) ./ mRange(i); + end + + % Normalize the validation set from the information of training set + for i = 1 : size(vSet,2) + vSet(:,i) = (vSet(:,i) - mMin(i)) ./ mRange(i); + vSet(find(vSet(:,i) < 0),i) = tolerance; + end + + + +%% Old implementation where Tr and V sets where normalized together +% %put together all the sets +% allSets = trSet; +% allSets(length(trSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1)),:) = vSet; +% %allSets(length(trSet(:,1))+length(vSet(:,1))+1 : +% %length(trSet(:,1))+length(vSet(:,1))+length(tSet(:,1)),:) = tSet; +% +% mMin = min(allSets); +% mMin = mMin + 0.0000001; %Quick patch for connMat +% mMax = max(allSets); +% mRange = mMax - mMin; +% +% % Normalize by using the range which will create a distribution between +% % 0 and 1 +% for i = 1 : size(allSets,2) +% allSets(:,i) = (allSets(:,i) - mMin(i)) ./ mRange(i); +% end +% +% trSet = allSets(1:size(trSet,1),:); +% vSet = allSets(length(trSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1)),:); +% %tSet = allSets(length(trSet(:,1))+length(vSet(:,1))+1 : length(trSet(:,1))+length(vSet(:,1))+length(tSet(:,1)),:); +% +% % \ No newline at end of file diff --git a/PatRec/Normalization/NormalizeSets_normLog.m b/PatRec/Normalization/NormalizeSets_normLog.m index d24507c..0428538 100644 --- a/PatRec/Normalization/NormalizeSets_normLog.m +++ b/PatRec/Normalization/NormalizeSets_normLog.m @@ -1,34 +1,37 @@ - -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -------------------------- Function Description ------------------------- -% logarithm Normalization -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [trSet vSet mMin]= NormalizeSets_normLog(trSet, vSet) -mMin =min(trSet); - - -trSet = log(abs(trSet - repmat(mMin,size(trSet,1),[])) +1); - -vSet = log(abs(vSet - repmat(mMin,size(vSet ,1),[])) +1); - + +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% -------------------------- Function Description ------------------------- +% logarithm Normalization +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 2014-12-04 / Ali Fouad / Fixed warning message due to empty set + +function [trSet, vSet, mMin]= NormalizeSets_normLog(trSet, vSet) +mMin =min(trSet); + +trSet = log(abs(trSet - repmat(mMin,size(trSet,1),1)) +1); + +vSet = log(abs(vSet - repmat(mMin,size(vSet ,1),1)) +1); + +% the following code produce a warning after Matlab 13a +%trSet = log(abs(trSet - repmat(mMin,size(trSet,1),[])) +1); +%vSet = log(abs(vSet - repmat(mMin,size(vSet ,1),[])) +1); + diff --git a/PatRec/OfflinePatRec.m b/PatRec/OfflinePatRec.m index c510f88..87c5cd1 100644 --- a/PatRec/OfflinePatRec.m +++ b/PatRec/OfflinePatRec.m @@ -1,205 +1,230 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to execute the Offline traning once selected from the GUI in -% Matlab -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-26 / Max Ortiz / Creation -% 2011-10-03 / Max Ortiz / Addition of individual movements routine -% 2011-11-29 / Max Ortiz / Addition of the posibility different topologies -% 2012-10-10 / Max Ortiz / Addition of algConf -% 2012-11-02 / Max Ortiz / Addition of floor noise -% 2012-11-23 / Joel Falk-Dahlin / Added initialization of speeds -% 20xx-xx-xx / Author / Comment on update - -function patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSetsType, alg, tType, algConf, movMix, topology, confMatFlag) - - %% patRec structure initialization - - patRec.nM = size(sigFeatures.mov,1); - patRec.mov = sigFeatures.mov; - patRec.sF = sigFeatures.sF; - patRec.tW = sigFeatures.tW; - patRec.nCh = sigFeatures.nCh; - patRec.dev = sigFeatures.dev; - patRec.fFilter = sigFeatures.fFilter; - patRec.sFilter = sigFeatures.sFilter; - patRec.selFeatures = selFeatures; - patRec.topology = topology; - - %% Start counting the training time - trStart = tic; - - %% Randomize data (if requested) - if randFeatures - sigFeatures = Rand_sigFeatures(sigFeatures); - end - - %% Get data sets - - if strcmp(movMix, 'All Mov') - [trSets, trOuts, vSets, vOuts, tSets, tOuts] = GetSets_Stack(sigFeatures, selFeatures); - movIdx = 1:patRec.nM; - movOutIdx = num2cell(movIdx); - elseif strcmp(movMix, 'Individual Mov') - - [trSets, trOuts, vSets, vOuts, tSets, tOuts, movIdx, movOutIdx] = GetSets_Stack_IndvMov(sigFeatures, selFeatures); - - elseif strcmp(movMix, 'Mixed Output') - - [trSets, trOuts, vSets, vOuts, tSets, tOuts, movIdx, movOutIdx] = GetSets_Stack_MixedOut(sigFeatures, selFeatures); - - end - patRec.movOutIdx = movOutIdx; - movLables = sigFeatures.mov(movIdx); - - - %% Normalize - [trSets vSets patRec] = NormalizeSets_TrV(normSetsType, trSets, vSets, patRec); - - - %% Floor noise - if strcmp(movLables(end),'Rest') - restIdx = find(trOuts(:,end)); % Get Indices of the rest sets - restSets = trSets(restIdx,:); % Get data sets related to rest - restSets = mean(restSets); % Mean for all windows - sCh = 1; % starting channel - for i = 1 : size(patRec.selFeatures,1) - eCh = sCh + size(patRec.nCh,2)-1; - floorNoise(i) = mean(restSets(sCh:eCh)); - sCh = eCh +1; - end - patRec.floorNoise = floorNoise; - end - % Note: The floor noise must be computed after normalization so it can - % be used as a threshold after SignalProcessing_Realtime in the - % real-time testing - - %% Topology and algorithm selection - if strcmp(patRec.topology,'Single Classifier') - - %patRec.patRecTrained = OfflinePatRecTraining(alg, tType, trSets, trOuts, vSets, vOuts, trLables, vLables, movLables); - patRec.patRecTrained = OfflinePatRecTraining(alg, tType, algConf, trSets, trOuts, vSets, vOuts, sigFeatures.mov, movIdx); - - elseif strcmp(patRec.topology,'Ago-antagonist') || ... - strcmp(patRec.topology,'Ago-antagonistAndMixed') - %Compute the number of DoF involved - if strcmp(movLables(end),'Rest') - nMov = size(movIdx,2) - 1; - restIdx = size(movIdx,2); - else - nMov = size(movIdx,2); - restIdx = []; - end - - % Run through all DoF and get mov 1 and 2 from each DoF plus a Mix. - for i = 1 : 2 : nMov - movIdxX = [i i+1]; - disp(['Training DoF:' num2str(round(i/2))]); - - % Train only with the Ago-antagonist movements or also the - % mixed of the remaining movements. - % If the rest movement is present. It would be considered in - % the training of each DoF - if strcmp(patRec.topology,'Ago-antagonist') - [trSetsX, trOutsX, vSetsX, vOutsX] = ... - ExtractSets_Stack(trSets, trOuts, vSets, vOuts, [movIdxX restIdx]); - movIdxX(end+1) = restIdx; - elseif strcmp(patRec.topology,'Ago-antagonistAndMixed') - [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ... - ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, [movIdxX restIdx], movLables); - end - - patRec.patRecTrained(round(i/2)) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); - - end - - elseif strcmp(patRec.topology,'One-vs-All') - % Number of selected movementes, it might be different than patRec.nM - nM = size(movIdx,2); - - % Creat a binary classifiers per movements - for i = 1 : nM - disp(['Training movement:' num2str(i)]); - movIdxX = i; - [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, movIdxX, movLables); - patRec.patRecTrained(i) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); - end - - - elseif strcmp(patRec.topology,'One-vs-One') || strcmp(patRec.topology,'One-vs-One DoF') - - nM = size(movIdx,2); % Number of selected movementes, it might be different than patRec.nM - - % Creat a matrix with binary classifiers between each movements - for i = 1 : nM - for j = i+1 : nM - disp(['Training movement:' num2str(i) ' vs ' num2str(j)]); - movIdxX = [i j]; - [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, movIdxX); - patRec.patRecTrained(i,j) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); - end - end - - elseif strcmp(patRec.topology,'All-and-One') - - % Number of selected movementes, it might be different than patRec.nM - nM = size(movIdx,2); - % Creat a binary classifiers per movements (One-Vs-All) - for i = 1 : nM - movIdxX = i; - disp(['Training movement:' num2str(i)]); - [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, movIdxX, movLables); - patRec.patRecTrained(i) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); - end - - % Creat a matrix with binary classifiers between each movements - % (One-Vs-One) - for i = 1 : nM - for j = i+1 : nM - movIdxX = [i j]; - disp(['Training movement:' num2str(i) ' vs ' num2str(j)]); - [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, movIdxX); - patRec.patRecTrainedAux(i,j) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); - end - end - - else - disp('Select topology'); - return; - end - - % Compute training/validation time. - patRec.trTime = toc(trStart); - - %% Test accuracy of the patRec - - [acc confMat tTime] = Accuracy_patRec(patRec, tSets, tOuts, confMatFlag); - patRec.tTime = tTime; - - %% Final data to the patRec - patRec.acc = acc; - patRec.confMat = confMat; - patRec.date = fix(clock); - patRec.indMovIdx = movIdx; - patRec.nOuts = size(movIdx,2); - patRec.control.maxDegPerMov = ones(1,patRec.nOuts); -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to execute the Offline traning once selected from the GUI in +% Matlab +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-26 / Max Ortiz / Creation +% 2011-10-03 / Max Ortiz / Addition of individual movements routine +% 2011-11-29 / Max Ortiz / Addition of the posibility different topologies +% 2012-10-10 / Max Ortiz / Addition of algConf +% 2012-11-02 / Max Ortiz / Addition of floor noise +% 2012-11-23 / Joel Falk-Dahlin / Added initialization of speeds +% 2013-01-02 / Max Ortiz / Added Feature Reduction variables +% Modified floor noise to compute only the first +% feature +% 2014-12-01 / Enzo Mastinu / Added the handling part for the COM port number + % information into the parameters +% 20xx-xx-xx / Author / Comment on update + +function patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSetsType, alg, tType, algConf, movMix, topology, confMatFlag, featReducAlg) + + %% patRec structure initialization + + patRec.nM = size(sigFeatures.mov,1); + patRec.mov = sigFeatures.mov; + patRec.sF = sigFeatures.sF; + patRec.tW = sigFeatures.tW; + patRec.nCh = sigFeatures.nCh; + patRec.dev = sigFeatures.dev; + patRec.fFilter = sigFeatures.fFilter; + patRec.sFilter = sigFeatures.sFilter; + patRec.selFeatures = selFeatures; + patRec.topology = topology; + patRec.featureReduction.Alg = featReducAlg; + + if isfield(sigFeatures, 'comm') + patRec.comm = sigFeatures.comm; + if isfield(sigFeatures, 'comn') + patRec.comn = sigFeatures.comn; + end + else + patRec.comm = 'N/A'; + end + + %% Start counting the training time + trStart = tic; + + %% Randomize data (if requested) + if randFeatures + sigFeatures = Rand_sigFeatures(sigFeatures); + end + + %% Get data sets + + if strcmp(movMix, 'All Mov') + [trSets, trOuts, vSets, vOuts, tSets, tOuts] = GetSets_Stack(sigFeatures, selFeatures); + movIdx = 1:patRec.nM; + movOutIdx = num2cell(movIdx); + elseif strcmp(movMix, 'Individual Mov') + + [trSets, trOuts, vSets, vOuts, tSets, tOuts, movIdx, movOutIdx] = GetSets_Stack_IndvMov(sigFeatures, selFeatures); + + elseif strcmp(movMix, 'Mixed Output') + + [trSets, trOuts, vSets, vOuts, tSets, tOuts, movIdx, movOutIdx] = GetSets_Stack_MixedOut(sigFeatures, selFeatures); + + end + patRec.movOutIdx = movOutIdx; + movLables = sigFeatures.mov(movIdx); + + + %% Normalize + [trSets vSets patRec] = NormalizeSets_TrV(normSetsType, trSets, vSets, patRec); + + %% Floor noise + if strcmp(movLables(end),'Rest') + restIdx = find(trOuts(:,end)); % Get Indices of the rest sets + restSets = trSets(restIdx,:); % Get data sets related to rest + restSets = mean(restSets); % Mean for all windows + + % Compute the floor noise of the first feature only + floorNoise = mean(restSets(1:size(patRec.nCh,2))); + + % Loop to compute the floor noise of each feature +% sCh = 1; % starting channel +% for i = 1 : size(patRec.selFeatures,1) +% eCh = sCh + size(patRec.nCh,2)-1; +% floorNoise(i) = mean(restSets(sCh:eCh)); +% sCh = eCh +1; +% end + + % Save floor noise in patRec + patRec.floorNoise = floorNoise; + end + % Note: The floor noise must be computed after normalization so it can + % be used as a threshold after SignalProcessing_Realtime in the + % real-time testing + + %% Feature Reduction + [trSets vSets,patRec]=FeatureReduction(trSets,vSets,patRec); + + %% Topology and algorithm selection + if strcmp(patRec.topology,'Single Classifier') + + %patRec.patRecTrained = OfflinePatRecTraining(alg, tType, trSets, trOuts, vSets, vOuts, trLables, vLables, movLables); + patRec.patRecTrained = OfflinePatRecTraining(alg, tType, algConf, trSets, trOuts, vSets, vOuts, sigFeatures.mov, movIdx); + + elseif strcmp(patRec.topology,'Ago-antagonist') || ... + strcmp(patRec.topology,'Ago-antagonistAndMixed') + %Compute the number of DoF involved + if strcmp(movLables(end),'Rest') + nMov = size(movIdx,2) - 1; + restIdx = size(movIdx,2); + else + nMov = size(movIdx,2); + restIdx = []; + end + + % Run through all DoF and get mov 1 and 2 from each DoF plus a Mix. + for i = 1 : 2 : nMov + movIdxX = [i i+1]; + disp(['Training DoF:' num2str(round(i/2))]); + + % Train only with the Ago-antagonist movements or also the + % mixed of the remaining movements. + % If the rest movement is present. It would be considered in + % the training of each DoF + if strcmp(patRec.topology,'Ago-antagonist') + [trSetsX, trOutsX, vSetsX, vOutsX] = ... + ExtractSets_Stack(trSets, trOuts, vSets, vOuts, [movIdxX restIdx]); + movIdxX(end+1) = restIdx; + elseif strcmp(patRec.topology,'Ago-antagonistAndMixed') + [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ... + ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, [movIdxX restIdx], movLables); + end + + patRec.patRecTrained(round(i/2)) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); + + end + + elseif strcmp(patRec.topology,'One-vs-All') || ... + strcmp(patRec.topology,'One-vs-All Th') + % Number of selected movementes, it might be different than patRec.nM + nM = size(movIdx,2); + + % Creat a binary classifiers per movements + for i = 1 : nM + disp(['Training movement:' num2str(i)]); + movIdxX = i; + [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, movIdxX, movLables); + patRec.patRecTrained(i) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); + end + + + elseif strcmp(patRec.topology,'One-vs-One') || strcmp(patRec.topology,'One-vs-One DoF') + + nM = size(movIdx,2); % Number of selected movementes, it might be different than patRec.nM + + % Creat a matrix with binary classifiers between each movements + for i = 1 : nM + for j = i+1 : nM + disp(['Training movement:' num2str(i) ' vs ' num2str(j)]); + movIdxX = [i j]; + [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, movIdxX); + patRec.patRecTrained(i,j) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); + end + end + + elseif strcmp(patRec.topology,'All-and-One') + + % Number of selected movementes, it might be different than patRec.nM + nM = size(movIdx,2); + % Creat a binary classifiers per movements (One-Vs-All) + for i = 1 : nM + movIdxX = i; + disp(['Training movement:' num2str(i)]); + [trSetsX, trOutsX, vSetsX, vOutsX, movIdxX, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, movIdxX, movLables); + patRec.patRecTrained(i) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); + end + + % Creat a matrix with binary classifiers between each movements + % (One-Vs-One) + for i = 1 : nM + for j = i+1 : nM + movIdxX = [i j]; + disp(['Training movement:' num2str(i) ' vs ' num2str(j)]); + [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, movIdxX); + patRec.patRecTrainedAux(i,j) = OfflinePatRecTraining(alg, tType, algConf, trSetsX, trOutsX, vSetsX, vOutsX, movLables, movIdxX); + end + end + + else + disp('Select topology'); + return; + end + + % Compute training/validation time. + patRec.trTime = toc(trStart); + + %% Test accuracy of the patRec + + [performance confMat tTime] = Accuracy_patRec(patRec, tSets, tOuts, confMatFlag); + patRec.tTime = tTime; + + %% Final data to the patRec + patRec.performance = performance; + patRec.confMat = confMat; + patRec.date = fix(clock); + patRec.indMovIdx = movIdx; + patRec.nOuts = size(movIdx,2); + patRec.control.maxDegPerMov = ones(1,patRec.nOuts); +end + diff --git a/PatRec/OfflinePatRecTraining.m b/PatRec/OfflinePatRecTraining.m index 2602029..04a3101 100644 --- a/PatRec/OfflinePatRecTraining.m +++ b/PatRec/OfflinePatRecTraining.m @@ -1,103 +1,89 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function indentifies the selected PatRec algorithm and then calls -% its selected training method. It requires data sets: -% -% * Training sets: trSets with trOuts -% * Validation sets: vSets with vOuts -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-11-29 / Max Ortiz / Creation out of OfflinePatRec -% 2012-05-20 / Max Ortiz / Moved the GetSetLables inside -% DiscrimiantAnalysis -% 2012-10-10 / Max Ortiz / Addition of algConf -% 20xx-xx-xx / Author / Comment on update - -function patRec = OfflinePatRecTraining(alg, tType, algConf, trSets, trOuts, vSets, vOuts, mov, movIdx) - % Select and run training - - % MLP - if strcmp(alg,'MLP') - - [MLP accV] = ANN_Perceptron(trSets, trOuts, vSets, vOuts, tType); - patRec.algorithm = 'MLP'; - patRec.training = tType; - patRec.ANN = MLP; - - elseif strcmp(alg,'MLP thOut') - - [MLP accV] = ANN_Perceptron(trSets, trOuts, vSets, vOuts, tType); - patRec.algorithm = 'MLP thOut'; - patRec.training = tType; - patRec.ANN = MLP; - % Temp hard-coded threshold - patRec.thOut(1:size(trOuts,2)) = 0.5; - - % DA - elseif strcmp(alg,'Discriminant A.') - - [coeff accV] = DiscriminantAnalysis(tType, trSets, trOuts, vSets, vOuts, mov, movIdx); - patRec.algorithm = 'DA'; - patRec.training = tType; - patRec.coeff = coeff; - - % RFN - elseif strcmp(alg,'RFN') - [connMat accV] = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts); - patRec.algorithm = 'RFN'; - patRec.training = tType; - patRec.connMat = connMat; - - % RFN threshold output - elseif strcmp(alg,'RFN thOut') - [connMat accV thOut] = RegulationFeedback_thOut(tType, trSets, trOuts, vSets, vOuts); - patRec.algorithm = 'RFN thOut'; - patRec.training = tType; - patRec.connMat = connMat; - % temp fix - thOut(1:size(connMat,1)) = thOut; - patRec.thOut = thOut; - - elseif strcmp(alg,'SOM') - [SOM accV] = SOM_Mapping(trSets, trOuts, vSets, vOuts, tType, algConf); - patRec.algorithm = 'SOM'; - patRec.training = tType; - patRec.SOM=SOM; - - elseif strcmp(alg,'SSOM') - [SSOM accV] = SSOM_Mapping(trSets, trOuts, vSets, vOuts, tType, algConf); - patRec.algorithm = 'SSOM'; - patRec.training = tType; - patRec.SSOM=SSOM; - - elseif strcmp(alg,'KNN') - [KNN accV] = EvaluateKNN(trSets, trOuts, vSets, vOuts, tType); - patRec.algorithm = 'KNN'; - patRec.training = tType; - patRec.KNN=KNN; - - end - - % Save the accuracy of the validation set as part of patRec structure; - patRec.accV = accV; - % Add the algConf variable - patRec.algConf = algConf; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function indentifies the selected PatRec algorithm and then calls +% its selected training method. It requires data sets: +% +% * Training sets: trSets with trOuts +% * Validation sets: vSets with vOuts +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-11-29 / Max Ortiz / Creation out of OfflinePatRec +% 2012-05-20 / Max Ortiz / Moved the GetSetLables inside +% DiscrimiantAnalysis +% 2012-10-10 / Max Ortiz / Addition of algConf +% 20xx-xx-xx / Author / Comment on update + +function patRec = OfflinePatRecTraining(alg, tType, algConf, trSets, trOuts, vSets, vOuts, mov, movIdx) + % Select and run training + + % MLP + if strcmp(alg,'MLP') + + [MLP accV] = ANN_Perceptron(trSets, trOuts, vSets, vOuts, tType); + patRec.algorithm = 'MLP'; + patRec.training = tType; + patRec.ANN = MLP; + + elseif strcmp(alg,'MLP thOut') + + [MLP accV] = ANN_Perceptron(trSets, trOuts, vSets, vOuts, tType); + patRec.algorithm = 'MLP thOut'; + patRec.training = tType; + patRec.ANN = MLP; + % Temp hard-coded threshold + patRec.thOut(1:size(trOuts,2)) = 0.5; + + % DA + elseif strcmp(alg,'Discriminant A.') + + [coeff accV] = DiscriminantAnalysis(tType, trSets, trOuts, vSets, vOuts, mov, movIdx); + patRec.algorithm = 'DA'; + patRec.training = tType; + patRec.coeff = coeff; + + % RFN + elseif strcmp(alg,'RFN') + [connMat accV] = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts); + patRec.algorithm = 'RFN'; + patRec.training = tType; + patRec.connMat = connMat; + + % SOM + elseif strcmp(alg,'SOM') + [SOM accV] = SOM_Mapping(trSets, trOuts, vSets, vOuts, tType, algConf); + patRec.algorithm = 'SOM'; + patRec.training = tType; + patRec.SOM=SOM; + + % SSOM + elseif strcmp(alg,'SSOM') + [SSOM accV] = SSOM_Mapping(trSets, trOuts, vSets, vOuts, tType, algConf); + patRec.algorithm = 'SSOM'; + patRec.training = tType; + patRec.SSOM=SSOM; + + end + + % Save the accuracy of the validation set as part of patRec structure; + patRec.accV = accV; + % Add the algConf variable + patRec.algConf = algConf; + end \ No newline at end of file diff --git a/PatRec/OneShotPatRec.m b/PatRec/OneShotPatRec.m index 818e4bb..0015e99 100644 --- a/PatRec/OneShotPatRec.m +++ b/PatRec/OneShotPatRec.m @@ -1,70 +1,67 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to execute a one shot pattern recognition for a single testing -% set. The patrec algorithm is here selected according to how it was -% previusly trainned -% -% OutMov : Is the index of the selected movement (only one) -% OutVector : Is a vector with the raw output of the classifier per -% movement. Multiple movements can be selected from it. -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-09-11 / Max Ortiz / Creation -% 2012-02-26 / Max Ortiz / Created MLPTest to standarize calls for testing -% routines -% 2012-03-04 / Max Ortiz / Added a validation to prevent sending empty -% outMov -% 20xx-xx-xx / Author / Comment on update - -function [outMov outVector] = OneShotPatRec(patRecTrained,tSet) - - if strcmp(patRecTrained.algorithm,'MLP') || ... - strcmp(patRecTrained.algorithm,'MLP thOut') - - [outMov outVector] = MLPTest(patRecTrained, tSet); - - elseif strcmp(patRecTrained.algorithm,'DA') - - [outMov outVector] = DiscriminantTest(patRecTrained.coeff,tSet,patRecTrained.training); - - elseif strcmp(patRecTrained.algorithm,'RFN') - - [outMov outVector] = RegulationFeedbackTest(patRecTrained.connMat, tSet'); - - elseif strcmp(patRecTrained.algorithm,'SOM') - - [outMov outVector] = SOMTest(patRecTrained,tSet); - - elseif strcmp(patRecTrained.algorithm,'SSOM') - - [outMov outVector] = SSOMTest(patRecTrained,tSet); - - elseif strcmp(patRecTrained.algorithm,'KNN') - - [outMov outVector] = KNNTest(patRecTrained,tSet); - - end - - % Validation to prevent outMov to be empty which cause problems on the - % GUI - if isempty(outMov) - outMov = 0; - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to execute a one shot pattern recognition for a single testing +% set. The patrec algorithm is here selected according to how it was +% previusly trainned +% +% OutMov : Is the index of the selected movement (only one) +% OutVector : Is a vector with the raw output of the classifier per +% movement. Multiple movements can be selected from it. +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-09-11 / Max Ortiz / Creation +% 2012-02-26 / Max Ortiz / Created MLPTest to standarize calls for testing +% routines +% 2012-03-04 / Max Ortiz / Added a validation to prevent sending empty +% outMov +% 2014-11-07 / Diep Khong / Added SVM +% 20xx-xx-xx / Author / Comment on update + +function [outMov outVector] = OneShotPatRec(patRecTrained,tSet) + + if strcmp(patRecTrained.algorithm,'MLP') || ... + strcmp(patRecTrained.algorithm,'MLP thOut') + + [outMov outVector] = MLPTest(patRecTrained, tSet); + + elseif strcmp(patRecTrained.algorithm,'DA') + + [outMov outVector] = DiscriminantTest(patRecTrained.coeff,tSet,patRecTrained.training); + + elseif strcmp(patRecTrained.algorithm,'RFN') + + [outMov outVector] = RegulationFeedbackTest(patRecTrained.connMat, tSet'); + + elseif strcmp(patRecTrained.algorithm,'SOM') + + [outMov outVector] = SOMTest(patRecTrained,tSet); + + elseif strcmp(patRecTrained.algorithm,'SSOM') + + [outMov outVector] = SSOMTest(patRecTrained,tSet); + + end + + % Validation to prevent outMov to be empty which cause problems on the + % GUI + if isempty(outMov) + outMov = 0; + end + end \ No newline at end of file diff --git a/PatRec/OneShotPatRecClassifier.m b/PatRec/OneShotPatRecClassifier.m index efc10b9..7dfc997 100644 --- a/PatRec/OneShotPatRecClassifier.m +++ b/PatRec/OneShotPatRecClassifier.m @@ -1,63 +1,71 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of a single classifier -% Simple function to keep standarizeed the call for different classifiers -% topologies -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-12-08 / Max Ortiz / Creation -% 2012-02-29 / Max Ortiz / Added a validation to prevent sending empty -% outMov -% 2012-03-04 / Max Ortiz / Moved the outMov validation to OneShotPatRec -% / this will keep cleaner this routine -% 20xx-xx-xx / Author / Comment on update - -function [outMov outVector] = OneShotPatRecClassifier(patRec, x) - - if strcmp(patRec.topology,'Single Classifier') - - [outMov outVector] = PatRec_SingleClassifier(patRec, x); - - elseif strcmp(patRec.topology,'Ago-antagonist') - - [outMov outVector] = PatRec_AgoAntagonist(patRec, x); - - elseif strcmp(patRec.topology,'Ago-antagonistAndMixed') - - [outMov outVector] = PatRec_AgoAntagonistAndMixed(patRec, x); - - elseif strcmp(patRec.topology,'One-vs-All') - - [outMov outVector] = PatRec_OneVsAll(patRec, x); - - elseif strcmp(patRec.topology,'One-vs-One') - - [outMov outVector] = PatRec_OneVsOne(patRec, x); - - elseif strcmp(patRec.topology,'All-and-One') - - [outMov outVector] = PatRec_AllAndOne(patRec, x); - - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of a single classifier +% Simple function to keep standarizeed the call for different classifiers +% topologies +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-12-08 / Max Ortiz / Creation +% 2012-02-29 / Max Ortiz / Added a validation to prevent sending empty +% outMov +% 2012-03-04 / Max Ortiz / Moved the outMov validation to OneShotPatRec +% / this will keep cleaner this routine +% 20xx-xx-xx / Author / Comment on update + +function [outMov outVector] = OneShotPatRecClassifier(patRec, x) + + if strcmp(patRec.topology,'Single Classifier') + + [outMov outVector] = PatRec_SingleClassifier(patRec, x); + + elseif strcmp(patRec.topology,'Ago-antagonist') + + [outMov outVector] = PatRec_AgoAntagonist(patRec, x); + + elseif strcmp(patRec.topology,'Ago-antagonistAndMixed') + + [outMov outVector] = PatRec_AgoAntagonistAndMixed(patRec, x); + + elseif strcmp(patRec.topology,'One-vs-All') + + [outMov outVector] = PatRec_OneVsAll(patRec, x); + + elseif strcmp(patRec.topology,'One-vs-All Th') + + [outMov outVector] = PatRec_OneVsAllT(patRec, x); + + elseif strcmp(patRec.topology,'One-vs-One') + + [outMov outVector] = PatRec_OneVsOne(patRec, x); + + elseif strcmp(patRec.topology,'One-vs-One DoF') + + [outMov outVector] = PatRec_OneVsOneDoF(patRec, x); + + elseif strcmp(patRec.topology,'All-and-One') + + [outMov outVector] = PatRec_AllAndOne(patRec, x); + + end + end \ No newline at end of file diff --git a/PatRec/OneShotRealtimePatRec.m b/PatRec/OneShotRealtimePatRec.m index 744c71a..6139604 100644 --- a/PatRec/OneShotRealtimePatRec.m +++ b/PatRec/OneShotRealtimePatRec.m @@ -1,95 +1,100 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to execute the Offline traning once selected from the GUI in -% Matlab -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-11-06 / Max Ortiz / Creation - Made an independent routine out of -% RealtimePatRec -% 2012-11-23 / Joel Falk-Dahlin / Removed handles in from control -% functions, speeds are now in patRec -% 20xx-xx-xx / Author / Comment on update - -function [outMov, outVector, patRec, handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData) - - %% Signal processing - tSet = SignalProcessing_RealtimePatRec(tData, patRec); - - %% Floor noise - % Only predict when signal is over floor noise? - if(isfield(patRec,'floorNoise')); - meanFeature1 = mean(tSet(1:size(patRec.nCh,2))); - fnoiseDiv = 1; - if meanFeature1 < (patRec.floorNoise(1)/fnoiseDiv) - outMov = patRec.nOuts; - outVector = zeros(patRec.nOuts,1); - outVector(end) = 1; - else - % One shoot PatRec - [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); - end - else - % One shoot PatRec - [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); - end - - % Safety check so the classifier cannot predict rest + a movement - % This condition assumes that rest is always the last movement - if strcmp(patRec.mov(end),'Rest') - if ismember(patRec.nOuts, outMov) | outMov == 0 - outMov = patRec.nOuts; - end - end - - %% Threshold GUI update - if(isfield(patRec.patRecTrained,'thOut')); - %set(handles.(sprintf('thPatch%d',outMov-1)), 'FaceColor', [0 1 0]); - for i=0:patRec.nOuts-1 - s0 = sprintf('thPatch%d',i); - s1 = sprintf('movementSelector%d',i); - s2 = sprintf('value%d',i); - s3 = sprintf('overrideButton%d',i); - set(handles.(s0), 'YData', [0 outVector(get(thresholdGUIData.(s1),'Value')) outVector(get(thresholdGUIData.(s1),'Value')) 0]); - % Change face colour - if find(get(thresholdGUIData.(s1),'Value') == outMov); - set(handles.(s0), 'FaceColor', [0 1 0]); - else - set(handles.(s0), 'FaceColor', [0 0 1]); - end - % Update threshold value - if(get(thresholdGUIData.(s3), 'Value') == 1); - patRec.patRecTrained.thOut(get(thresholdGUIData.(s1),'Value')) = str2num(get(thresholdGUIData.(s2),'String')); - else - set(thresholdGUIData.(s2), 'String', patRec.patRecTrained.thOut(get(thresholdGUIData.(s1),'Value'))); - end - end - end - - %% Apply Proportional control - patRec = ApplyProportionalControl(tSet, patRec); - - %% Control algorithm - [patRec, outMov] = ApplyControl(patRec, outMov, outVector); - - %% Update result on the GUI - set(handles.lb_movements,'Value',outMov); - drawnow; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to execute the Offline traning once selected from the GUI in +% Matlab +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-06 / Max Ortiz / Creation - Made an independent routine out of +% RealtimePatRec +% 2012-11-23 / Joel Falk-Dahlin / Removed handles in from control +% functions, speeds are now in patRec +% 2013-01-02 / Max Ortiz / Added routines for feature reduction +% 20xx-xx-xx / Author / Comment on update + +function [outMov, outVector, patRec, handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData) + + %% Signal processing + tSet = SignalProcessing_RealtimePatRec(tData, patRec); + + %% Floor noise + % Only predict when signal is over floor noise? + if(isfield(patRec,'floorNoise')); + meanFeature1 = mean(tSet(1:size(patRec.nCh,2))); + fnoiseDiv = 1; + if meanFeature1 < (patRec.floorNoise(1)/fnoiseDiv) + outMov = patRec.nOuts; + outVector = zeros(patRec.nOuts,1); + outVector(end) = 1; + else + % Apply feature reduction + tSet = ApplyFeatureReduction(tSet, patRec); + % One shoot PatRec + [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); + end + else + % Apply feature reduction + tSet = ApplyFeatureReduction(tSet, patRec); + % One shoot PatRec + [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); + end + + % Safety check so the classifier cannot predict rest + a movement + % This condition assumes that rest is always the last movement + if strcmp(patRec.mov(end),'Rest') + if ismember(patRec.nOuts, outMov) | outMov == 0 + outMov = patRec.nOuts; + end + end + + %% Threshold GUI update + if(isfield(patRec.patRecTrained,'thOut')); + %set(handles.(sprintf('thPatch%d',outMov-1)), 'FaceColor', [0 1 0]); + for i=0:patRec.nOuts-1 + s0 = sprintf('thPatch%d',i); + s1 = sprintf('movementSelector%d',i); + s2 = sprintf('value%d',i); + s3 = sprintf('overrideButton%d',i); + set(handles.(s0), 'YData', [0 outVector(get(thresholdGUIData.(s1),'Value')) outVector(get(thresholdGUIData.(s1),'Value')) 0]); + % Change face colour + if find(get(thresholdGUIData.(s1),'Value') == outMov); + set(handles.(s0), 'FaceColor', [0 1 0]); + else + set(handles.(s0), 'FaceColor', [0 0 1]); + end + % Update threshold value + if(get(thresholdGUIData.(s3), 'Value') == 1); + patRec.patRecTrained.thOut(get(thresholdGUIData.(s1),'Value')) = str2num(get(thresholdGUIData.(s2),'String')); + else + set(thresholdGUIData.(s2), 'String', patRec.patRecTrained.thOut(get(thresholdGUIData.(s1),'Value'))); + end + end + end + + %% Apply Proportional control + patRec = ApplyProportionalControl(tSet, patRec); + + %% Control algorithm + [patRec, outMov] = ApplyControl(patRec, outMov, outVector); + + %% Update result on the GUI + set(handles.lb_movements,'Value',outMov); + drawnow; + end \ No newline at end of file diff --git a/PatRec/PCA/ApplyFeatureReduction.m b/PatRec/PCA/ApplyFeatureReduction.m new file mode 100644 index 0000000..814531f --- /dev/null +++ b/PatRec/PCA/ApplyFeatureReduction.m @@ -0,0 +1,36 @@ +% % ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% This function is used as a hub to call any algorithm for feature reduction. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Tanuj Kumar Aluru / Creation +% 2013-01-02 / Max Ortiz / Review and corrected documentation +% / All the calls are hard coded, +% / see ApplyControl for further improvement. +% 20xx-xx-xx / Author / Comment on update + +function x = ApplyFeatureReduction(x, patRec) + + if strcmp(patRec.featureReduction.Alg,'PCA') + + x = PCATest(x ,patRec.featureReduction.eigVecTrData,patRec.selFeatures); + + end diff --git a/PatRec/PCA/FeatureReduction.m b/PatRec/PCA/FeatureReduction.m new file mode 100644 index 0000000..9308304 --- /dev/null +++ b/PatRec/PCA/FeatureReduction.m @@ -0,0 +1,36 @@ +% % ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This allows the selection of the feature reduction algorithm to be used +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update +%%------------------------------------------------------------------------- + +function [trSets vSets patRec] = FeatureReduction(trSets,vSets,patRec) + + if strcmp(patRec.featureReduction.Alg,'PCA') + % Calculating PCA on training set + [trSets eigVecTrData] = PCAFeatureReduction(trSets,patRec.selFeatures); + % Calculating PCA on validation set + vSets = PCATest(vSets,eigVecTrData,patRec.selFeatures); + patRec.featureReduction.eigVecTrData = eigVecTrData; + + end diff --git a/PatRec/PCA/PCAFeatureReduction.m b/PatRec/PCA/PCAFeatureReduction.m new file mode 100644 index 0000000..70d9d7a --- /dev/null +++ b/PatRec/PCA/PCAFeatureReduction.m @@ -0,0 +1,78 @@ + +% % ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This Function is the main algorithm perform Principal Component Analysis +% for Feature Reduction +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update +%%------------------------------------------------------------------------- +function [PCAout eigVec] = PCAFeatureReduction(inputData,selFeatures) + +recData = reshape(inputData,[],size(selFeatures,1)); + +% Computing Covariance and Eigen Decomposition +variance = cov(recData); +[E D ] = eig(variance); + +%Sort Eigen Values in Descending Order + +[eigVal index] = sort(diag(D),'descend'); + +% ---- Feature Reduction Step---------------------------------------------- +% Chose first k Principal Components + +eigVec = []; + +Threshold = 0.99; + +k= 0; + +for i = 1:length(eigVal) + Totalvar(i) = sum(eigVal(1:i))/sum(eigVal); + if Totalvar(i) >= Threshold ; + k = i; + break + end +end + +% Consider K largest Eigen vectors with corrosepoding Eigen Values + +eigVec = [eigVec,E(:,index(1:k))]; + + +% Project the Data on to EigenVectors + +ProjectedData = (recData*eigVec); +PCAout = reshape(ProjectedData,size(inputData,1),[]); +end + + + + + + + + + + + + diff --git a/PatRec/PCA/PCATest.m b/PatRec/PCA/PCATest.m new file mode 100644 index 0000000..5ecf6d7 --- /dev/null +++ b/PatRec/PCA/PCATest.m @@ -0,0 +1,31 @@ +% % ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function of Principal Component Analysis Feature Reduction +% for testing and validation sets. +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update +%%------------------------------------------------------------------------- + +function PCAData=PCATest(inputData ,eigVecTrData,selFeatures) + + recData = reshape(inputData,[],size(selFeatures,1)); + PCAData = (recData*eigVecTrData); + PCAData=reshape(PCAData,size(inputData,1),[]); diff --git a/PatRec/PSO/InitVelocities.m b/PatRec/PSO/InitVelocities.m index 1cdd023..77001a9 100644 --- a/PatRec/PSO/InitVelocities.m +++ b/PatRec/PSO/InitVelocities.m @@ -1,40 +1,40 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to initialize the positions according to the range -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-27 / Max Ortiz / Creation -% 2012-03-27 / Max Ortiz / Adapted for BioPatRec from EMG_AQ -% 2012-06-03 / Max Ortiz / Commented the velocity validation, it's not -% necessary since vMax is set for the xMax-xMin range. - -function vel = InitVelocities(sSize, nVar, xMin, xMax, dt, alpha, vMax) - -vel = alpha .* (xMin + rand(sSize,nVar) .* (xMax - xMin)) ./ dt; - -% for i = 1:sSize -% for j = 1:nVar -% if vel(i,j) < 0 && vel(i,j) < -vMax -% vel(i,j) = vMax * -1; -% elseif vel(i,j) > 0 && vel(i,j) > vMax -% vel(i,j) = vMax; -% end -% end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to initialize the positions according to the range +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-27 / Max Ortiz / Creation +% 2012-03-27 / Max Ortiz / Adapted for BioPatRec from EMG_AQ +% 2012-06-03 / Max Ortiz / Commented the velocity validation, it's not +% necessary since vMax is set for the xMax-xMin range. + +function vel = InitVelocities(sSize, nVar, xMin, xMax, dt, alpha, vMax) + +vel = alpha .* (xMin + rand(sSize,nVar) .* (xMax - xMin)) ./ dt; + +% for i = 1:sSize +% for j = 1:nVar +% if vel(i,j) < 0 && vel(i,j) < -vMax +% vel(i,j) = vMax * -1; +% elseif vel(i,j) > 0 && vel(i,j) > vMax +% vel(i,j) = vMax; +% end +% end % end \ No newline at end of file diff --git a/PatRec/PSO/UpdateVel.m b/PatRec/PSO/UpdateVel.m index 3874815..8673001 100644 --- a/PatRec/PSO/UpdateVel.m +++ b/PatRec/PSO/UpdateVel.m @@ -1,49 +1,49 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to initialize the positions according to the range -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-27 / Max Ortiz/ Creation -% 2012-03-29 / Max Ortiz/ Adapted for BioPatRec from EMG_AQ - -function tempvel = UpdateVel(pos, velocities, positions, pBestPos, sBestPos, c1, c2, nVar, dt,vMax, w) - -tempvel = zeros(nVar,1); -for j = 1:nVar - q=rand; - r=rand; - tempvel(j) = w * velocities(pos,j) + c1*q*((pBestPos(pos,j) - positions(pos,j))/dt) +... - c2*r*((sBestPos(j) - positions(pos,j))/dt); - -% % Contain velocity -% if tempvel(j) < -vMax -% tempvel(j) = -vMax; -% elseif tempvel(j) > vMax -% tempvel(j) = vMax; -% end - - % Contain velocity considering inertial weight - if tempvel(j) < -vMax - tempvel(j) = w * -vMax; - elseif tempvel(j) > vMax - tempvel(j) = w * vMax; - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to initialize the positions according to the range +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-27 / Max Ortiz/ Creation +% 2012-03-29 / Max Ortiz/ Adapted for BioPatRec from EMG_AQ + +function tempvel = UpdateVel(pos, velocities, positions, pBestPos, sBestPos, c1, c2, nVar, dt,vMax, w) + +tempvel = zeros(nVar,1); +for j = 1:nVar + q=rand; + r=rand; + tempvel(j) = w * velocities(pos,j) + c1*q*((pBestPos(pos,j) - positions(pos,j))/dt) +... + c2*r*((sBestPos(j) - positions(pos,j))/dt); + +% % Contain velocity +% if tempvel(j) < -vMax +% tempvel(j) = -vMax; +% elseif tempvel(j) > vMax +% tempvel(j) = vMax; +% end + + % Contain velocity considering inertial weight + if tempvel(j) < -vMax + tempvel(j) = w * -vMax; + elseif tempvel(j) > vMax + tempvel(j) = w * vMax; + end + end \ No newline at end of file diff --git a/PatRec/RFN/Get_connMat_TrV.m b/PatRec/RFN/Get_connMat_TrV.m index a138bf5..e0b18ac 100644 --- a/PatRec/RFN/Get_connMat_TrV.m +++ b/PatRec/RFN/Get_connMat_TrV.m @@ -1,61 +1,61 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to create the connectivity matrix -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-10-02 / Max Ortiz / Created -% 2012-03-04 / Max Ortiz / Modified to handle non-equal amout of sets per -% class -% 2012-04-07 / Max Ortiz / Modified to handle mixed outputs -% 20xx-xx-xx / Author / Comment on update - -function connMat = Get_connMat_TrV(trSet, trOut, vSet, vOut) - -% Integration of training and validation sets in one set -trSet = [trSet ; vSet]; -trOut = [trOut ; vOut]; - -%Variable -nM = size(trOut,2); % Number of Movements -nFeatures = size(trSet,2); % Number of Features -nSets = size(trSet,1); % Number of Total sets -connMat = zeros(nM,nFeatures); % Connectivity Matrix - -% Separate data sets per pattern -for i = 1 : nSets - movIdx = find(trOut(i,:)); - % This loop takes care of mixed outputs - for j = 1 : size(movIdx,2) - k = movIdx(j); - allSetsPerPattern(i,:,k) = trSet(i,:); - %(sets x features x classes) - end -end - -% Create connectivity matrix by computing the mean -for i = 1 : nM; - idx = find(allSetsPerPattern(:,1,i)); -% setsPerPattern(:,:,i) = allSetsPerPattern(idx,:,i); -% connMat(i,:) = mean(setsPerPattern(:,:,i)); - setsPerPattern = allSetsPerPattern(idx,:,i); - connMat(i,:) = mean(setsPerPattern); -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to create the connectivity matrix +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-10-02 / Max Ortiz / Created +% 2012-03-04 / Max Ortiz / Modified to handle non-equal amout of sets per +% class +% 2012-04-07 / Max Ortiz / Modified to handle mixed outputs +% 20xx-xx-xx / Author / Comment on update + +function connMat = Get_connMat_TrV(trSet, trOut, vSet, vOut) + +% Integration of training and validation sets in one set +trSet = [trSet ; vSet]; +trOut = [trOut ; vOut]; + +%Variable +nM = size(trOut,2); % Number of Movements +nFeatures = size(trSet,2); % Number of Features +nSets = size(trSet,1); % Number of Total sets +connMat = zeros(nM,nFeatures); % Connectivity Matrix + +% Separate data sets per pattern +for i = 1 : nSets + movIdx = find(trOut(i,:)); + % This loop takes care of mixed outputs + for j = 1 : size(movIdx,2) + k = movIdx(j); + allSetsPerPattern(i,:,k) = trSet(i,:); + %(sets x features x classes) + end +end + +% Create connectivity matrix by computing the mean +for i = 1 : nM; + idx = find(allSetsPerPattern(:,1,i)); +% setsPerPattern(:,:,i) = allSetsPerPattern(idx,:,i); +% connMat(i,:) = mean(setsPerPattern(:,:,i)); + setsPerPattern = allSetsPerPattern(idx,:,i); + connMat(i,:) = mean(setsPerPattern); +end + + diff --git a/PatRec/RFN/Get_connMat_eMean.m b/PatRec/RFN/Get_connMat_eMean.m index 829215d..c9b3a16 100644 --- a/PatRec/RFN/Get_connMat_eMean.m +++ b/PatRec/RFN/Get_connMat_eMean.m @@ -1,64 +1,64 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to create the connectivity matrix computing the mean with -% exclusion of values that are higher that 2 times the variance -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-05-15 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function connMat = Get_connMat_eMean(trSet, trOut, vSet, vOut) - -% Integration of training and validation sets in one set -trSet = [trSet ; vSet]; -trOut = [trOut ; vOut]; - -%Variable -nM = size(trOut,2); % Number of Movements -nFeatures = size(trSet,2); % Number of Features -nSets = size(trSet,1); % Number of Total sets -connMat = zeros(nM,nFeatures); % Connectivity Matrix - -% Separate data sets per pattern -% Tese loops are in a way necessary for mixed outputs, think about that -% before "optimizing" the routine -for i = 1 : nSets - movIdx = find(trOut(i,:)); - % This loop takes care of mixed outputs - for j = 1 : size(movIdx,2) - k = movIdx(j); - allSetsPerPattern(i,:,k) = trSet(i,:); - %(sets x features x classes) - end -end - -% Create connectivity matrix by computing the mean -for i = 1 : nM; - idx = find(allSetsPerPattern(:,1,i)); - setsPerPattern = allSetsPerPattern(idx,:,i); - % Only learn values where the mean is bigger than 2 std - meanSets = mean(setsPerPattern); - stdSets = std(setsPerPattern); - mask = (meanSets - (2*stdSets)) > 0; - connMat(i,:) = mask .* meanSets; -end -% Give to 0 values a small contribution -connMat(connMat == 0) = 0.0000000001; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to create the connectivity matrix computing the mean with +% exclusion of values that are higher that 2 times the variance +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-05-15 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function connMat = Get_connMat_eMean(trSet, trOut, vSet, vOut) + +% Integration of training and validation sets in one set +trSet = [trSet ; vSet]; +trOut = [trOut ; vOut]; + +%Variable +nM = size(trOut,2); % Number of Movements +nFeatures = size(trSet,2); % Number of Features +nSets = size(trSet,1); % Number of Total sets +connMat = zeros(nM,nFeatures); % Connectivity Matrix + +% Separate data sets per pattern +% Tese loops are in a way necessary for mixed outputs, think about that +% before "optimizing" the routine +for i = 1 : nSets + movIdx = find(trOut(i,:)); + % This loop takes care of mixed outputs + for j = 1 : size(movIdx,2) + k = movIdx(j); + allSetsPerPattern(i,:,k) = trSet(i,:); + %(sets x features x classes) + end +end + +% Create connectivity matrix by computing the mean +for i = 1 : nM; + idx = find(allSetsPerPattern(:,1,i)); + setsPerPattern = allSetsPerPattern(idx,:,i); + % Only learn values where the mean is bigger than 2 std + meanSets = mean(setsPerPattern); + stdSets = std(setsPerPattern); + mask = (meanSets - (2*stdSets)) > 0; + connMat(i,:) = mask .* meanSets; +end +% Give to 0 values a small contribution +connMat(connMat == 0) = 0.0000000001; + diff --git a/PatRec/RFN/PSO/DecodeConnMat.m b/PatRec/RFN/PSO/DecodeConnMat.m index 5e6283b..de679d6 100644 --- a/PatRec/RFN/PSO/DecodeConnMat.m +++ b/PatRec/RFN/PSO/DecodeConnMat.m @@ -1,32 +1,32 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Decode the flat connMat to connMat -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-03-29 / Max Ortiz/ Creation - -function connMat = DecodeConnMat(cM, nM, nF) - -% Flat connMat -for i=1:nM - sIdx = 1 + (nF * (i-1)); - eIdx = sIdx + nF - 1; - connMat(i,:) = cM(sIdx:eIdx); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Decode the flat connMat to connMat +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-03-29 / Max Ortiz/ Creation + +function connMat = DecodeConnMat(cM, nM, nF) + +% Flat connMat +for i=1:nM + sIdx = 1 + (nF * (i-1)); + eIdx = sIdx + nF - 1; + connMat(i,:) = cM(sIdx:eIdx); end \ No newline at end of file diff --git a/PatRec/RFN/PSO/InitPSO_RFN.m b/PatRec/RFN/PSO/InitPSO_RFN.m index 0d6bfa7..a44c5cf 100644 --- a/PatRec/RFN/PSO/InitPSO_RFN.m +++ b/PatRec/RFN/PSO/InitPSO_RFN.m @@ -1,82 +1,82 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Initialization of PSO for RFN -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-27 / Max Ortiz/ Creation -% 2012-03-29 / Max Ortiz/ Adapted for RFN - -function PSO = InitPSO_RFN(connMat) - -PSO.sSize = 20; %Swarm size -PSO.nVar = size(connMat,1)*size(connMat,2); %Number of variables -PSO.xMin = 0; %minumum -PSO.xMax = 1; %maximum - -PSO.dt = 1; %time spet lengh -PSO.alpha = 1; %constant -PSO.c1 = 2; %Constant C1 -PSO.c2 = 2; %Constant C2 - -PSO.beta = .9; %Beta for inertia weight -PSO.w = 1.4; %weigh for inertia weight -PSO.pcr = 0.1; %Craziness probability - -PSO.maxSimulations = 50; %max number of simulations - -% Initialization of Vmax -PSO.vMax = (PSO.xMax - PSO.xMin) / PSO.dt; - -PSO.opelite = 1; %input('Do you want to use elite particle? Yes (1) or No (2): '); -PSO.opcrazy = 1; %input('Do you want to use crazy operator? Yes (1) or No (2): '); - -% Flat connMat -cM = []; -for i=1:size(connMat,1) - cM = [cM connMat(i,:)]; -end - -%Initializations -% The first position will be as the connMat -PSO.positions(1,:) = cM; -% The remianing position will vary +-.5 -for i = 2 : PSO.sSize - randPos = -.5 + rand(1,PSO.nVar); % the rest +- .5 - PSO.positions(i,:) = cM + randPos; - - % Limit negative values - negIdx = find(PSO.positions(i,:) < 0); - PSO.positions(i,negIdx) = 0.0000000001; - % Limit values over 1 - negIdx = find(PSO.positions(i,:) > 1); - PSO.positions(i,negIdx) = 1; - -end - -% Random initialization of the position -% PSO.positions = PSO.xMin + rand(PSO.sSize,PSO.nVar).*(PSO.xMax - PSO.xMin); - -PSO.velocities = InitVelocities(PSO.sSize,PSO.nVar,PSO.xMin,PSO.xMax,PSO.dt,PSO.alpha,PSO.vMax); - - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Initialization of PSO for RFN +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-27 / Max Ortiz/ Creation +% 2012-03-29 / Max Ortiz/ Adapted for RFN + +function PSO = InitPSO_RFN(connMat) + +PSO.sSize = 20; %Swarm size +PSO.nVar = size(connMat,1)*size(connMat,2); %Number of variables +PSO.xMin = 0; %minumum +PSO.xMax = 1; %maximum + +PSO.dt = 1; %time spet lengh +PSO.alpha = 1; %constant +PSO.c1 = 2; %Constant C1 +PSO.c2 = 2; %Constant C2 + +PSO.beta = .9; %Beta for inertia weight +PSO.w = 1.4; %weigh for inertia weight +PSO.pcr = 0.1; %Craziness probability + +PSO.maxSimulations = 50; %max number of simulations + +% Initialization of Vmax +PSO.vMax = (PSO.xMax - PSO.xMin) / PSO.dt; + +PSO.opelite = 1; %input('Do you want to use elite particle? Yes (1) or No (2): '); +PSO.opcrazy = 1; %input('Do you want to use crazy operator? Yes (1) or No (2): '); + +% Flat connMat +cM = []; +for i=1:size(connMat,1) + cM = [cM connMat(i,:)]; +end + +%Initializations +% The first position will be as the connMat +PSO.positions(1,:) = cM; +% The remianing position will vary +-.5 +for i = 2 : PSO.sSize + randPos = -.5 + rand(1,PSO.nVar); % the rest +- .5 + PSO.positions(i,:) = cM + randPos; + + % Limit negative values + negIdx = find(PSO.positions(i,:) < 0); + PSO.positions(i,negIdx) = 0.0000000001; + % Limit values over 1 + negIdx = find(PSO.positions(i,:) > 1); + PSO.positions(i,negIdx) = 1; + +end + +% Random initialization of the position +% PSO.positions = PSO.xMin + rand(PSO.sSize,PSO.nVar).*(PSO.xMax - PSO.xMin); + +PSO.velocities = InitVelocities(PSO.sSize,PSO.nVar,PSO.xMin,PSO.xMax,PSO.dt,PSO.alpha,PSO.vMax); + + + + + + diff --git a/PatRec/RFN/PSO/PSO_RFN.m b/PatRec/RFN/PSO/PSO_RFN.m index bbf4139..00f287e 100644 --- a/PatRec/RFN/PSO/PSO_RFN.m +++ b/PatRec/RFN/PSO/PSO_RFN.m @@ -1,103 +1,103 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Particle Swarm Optimization to find ... -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-23 / Max Ortiz/ Creation -% 2012-04-01 / Max Ortiz/ Adapted for RFN - -function [PSO, connMat] = PSO_RFN(PSO, connMat, vSets, vOuts, thO) - -if PSO.opcrazy ~= 1 - PSO.pcr = 0; -end - -% Flat connMat -nM = size(connMat,1); % Number of movements -nF = size(connMat,2); % Number of features - -% Initialization of best -fitness(1:PSO.sSize) = inf; -pBestFit(1:PSO.sSize) = inf; -sBestFit = inf; - - -%Run until the max number of generations -for sim = 1:PSO.maxSimulations - - %Fitness evaluation - for i = 1:PSO.sSize - connMat = DecodeConnMat(PSO.positions(i,:), nM, nF); - fitness(i) = RegulationFeedbackFit(connMat, vSets, vOuts, nM, thO); - - %Particle Best Positions - if (fitness(i) < pBestFit(i)) - pBestFit(i) = fitness(i); %particle best fitness - pBestPos(i,:) = PSO.positions(i,:); %particle best position - end - end - - %Find the best in the swarm - for i=1:PSO.sSize - if pBestFit(i) < sBestFit - sBestFit = pBestFit(i); %Swarm best fitness - sBestPos = PSO.positions(i,:); %Swarm best position - - connMat = DecodeConnMat(sBestPos, nM, nF); - disp(RegulationFeedbackAcc(connMat, vSets, vOuts, nM)); - end - end - - %Update velocity - for i = 1:PSO.sSize - cr=rand; - if cr > PSO.pcr - tempvel = UpdateVel(i, PSO.velocities, PSO.positions, pBestPos, sBestPos, PSO.c1, PSO.c2, PSO.nVar, PSO.dt, PSO.vMax, PSO.w); - else - tempvel = -PSO.vMax + 2 * rand(PSO.nVar,1) * PSO.vMax; - end - PSO.velocities(i,:) = tempvel; - end - - %Reduce inertia weight for velocity - if PSO.w > 0.3 - PSO.w = PSO.beta * PSO.w; - end - - %Update position - PSO.positions = PSO.positions + PSO.velocities * PSO.dt; -% % Limit negative values - negIdx = find(PSO.positions < 0); - PSO.positions(negIdx) = 0.0000000001; -% % Limit values over 1 - negIdx = find(PSO.positions > 1); - PSO.positions(negIdx) = 1; - - - %Elite Particle - if PSO.opelite == 1 - PSO.positions(1,:) = sBestPos; %This instruction will always keep the best partical position - end - - disp(sBestFit); - -end -% Return the best position +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Particle Swarm Optimization to find ... +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-23 / Max Ortiz/ Creation +% 2012-04-01 / Max Ortiz/ Adapted for RFN + +function [PSO, connMat] = PSO_RFN(PSO, connMat, vSets, vOuts, thO) + +if PSO.opcrazy ~= 1 + PSO.pcr = 0; +end + +% Flat connMat +nM = size(connMat,1); % Number of movements +nF = size(connMat,2); % Number of features + +% Initialization of best +fitness(1:PSO.sSize) = inf; +pBestFit(1:PSO.sSize) = inf; +sBestFit = inf; + + +%Run until the max number of generations +for sim = 1:PSO.maxSimulations + + %Fitness evaluation + for i = 1:PSO.sSize + connMat = DecodeConnMat(PSO.positions(i,:), nM, nF); + fitness(i) = RegulationFeedbackFit(connMat, vSets, vOuts, nM, thO); + + %Particle Best Positions + if (fitness(i) < pBestFit(i)) + pBestFit(i) = fitness(i); %particle best fitness + pBestPos(i,:) = PSO.positions(i,:); %particle best position + end + end + + %Find the best in the swarm + for i=1:PSO.sSize + if pBestFit(i) < sBestFit + sBestFit = pBestFit(i); %Swarm best fitness + sBestPos = PSO.positions(i,:); %Swarm best position + + connMat = DecodeConnMat(sBestPos, nM, nF); + disp(RegulationFeedbackAcc(connMat, vSets, vOuts, nM)); + end + end + + %Update velocity + for i = 1:PSO.sSize + cr=rand; + if cr > PSO.pcr + tempvel = UpdateVel(i, PSO.velocities, PSO.positions, pBestPos, sBestPos, PSO.c1, PSO.c2, PSO.nVar, PSO.dt, PSO.vMax, PSO.w); + else + tempvel = -PSO.vMax + 2 * rand(PSO.nVar,1) * PSO.vMax; + end + PSO.velocities(i,:) = tempvel; + end + + %Reduce inertia weight for velocity + if PSO.w > 0.3 + PSO.w = PSO.beta * PSO.w; + end + + %Update position + PSO.positions = PSO.positions + PSO.velocities * PSO.dt; +% % Limit negative values + negIdx = find(PSO.positions < 0); + PSO.positions(negIdx) = 0.0000000001; +% % Limit values over 1 + negIdx = find(PSO.positions > 1); + PSO.positions(negIdx) = 1; + + + %Elite Particle + if PSO.opelite == 1 + PSO.positions(1,:) = sBestPos; %This instruction will always keep the best partical position + end + + disp(sBestFit); + +end +% Return the best position connMat = DecodeConnMat(sBestPos, nM, nF); \ No newline at end of file diff --git a/PatRec/RFN/RFN.m b/PatRec/RFN/RFN.m index 9158081..5f407a5 100644 --- a/PatRec/RFN/RFN.m +++ b/PatRec/RFN/RFN.m @@ -1,71 +1,71 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Implementation of the RFN -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-09-26 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [acc, connMat] = RFN(trSet, trOut, vSet, vOut, tSet, tOut, dType) - -% Integration of training set and validation set -trSet = [trSet ; vSet]; -trOut = [trOut ; vOut]; - -%Variable -nM = size(trOut,2); % Number of Movements -nFeatures = size(trSet,2); % Number of Features -nSets = size(trSet,1); % Number of Total sets -allSetsPerPattern = zeros(nSets,nFeatures,nM); -setsPerPattern = zeros(nSets/nM,nFeatures,nM); -connMat = zeros(nM,nFeatures); % Connectivity Matrix -tSetsPerPattern = size(tOut,1)/size(tOut,2); - - -% Separate data sets per pattern -for i = 1 : nSets - allSetsPerPattern(i,:,find(trOut(i,:))) = trSet(i,:); -end - -% Create connectivity matrix -for i = 1 : nM; - idx = find(allSetsPerPattern(:,1,i)); - setsPerPattern(:,:,i) = allSetsPerPattern(idx,:,i); - connMat(i,:) = mean(setsPerPattern(:,:,i)); -end - -%connMat = Get_connMat(trSet, trOut, vSet, vOut); - -% Test the tSet (test set) - -% for i = 1 : size(tSet,1) -% vRes = RegulationFeedback(connMat, tSet(i,:)'); -% [Y I] = max(vRes); -% -% if I == find(tOut(i,:)) -% accAll(i,find(tOut(i,:))) = 1; -% end -% end -% -% acc = sum(accAll) ./ tSetsPerPattern; -% acc(nM+1) = mean(acc); -% acc = acc'; - -acc = RegulationFeedbackAcc(connMat, tSet, tOut); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Implementation of the RFN +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-09-26 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [acc, connMat] = RFN(trSet, trOut, vSet, vOut, tSet, tOut, dType) + +% Integration of training set and validation set +trSet = [trSet ; vSet]; +trOut = [trOut ; vOut]; + +%Variable +nM = size(trOut,2); % Number of Movements +nFeatures = size(trSet,2); % Number of Features +nSets = size(trSet,1); % Number of Total sets +allSetsPerPattern = zeros(nSets,nFeatures,nM); +setsPerPattern = zeros(nSets/nM,nFeatures,nM); +connMat = zeros(nM,nFeatures); % Connectivity Matrix +tSetsPerPattern = size(tOut,1)/size(tOut,2); + + +% Separate data sets per pattern +for i = 1 : nSets + allSetsPerPattern(i,:,find(trOut(i,:))) = trSet(i,:); +end + +% Create connectivity matrix +for i = 1 : nM; + idx = find(allSetsPerPattern(:,1,i)); + setsPerPattern(:,:,i) = allSetsPerPattern(idx,:,i); + connMat(i,:) = mean(setsPerPattern(:,:,i)); +end + +%connMat = Get_connMat(trSet, trOut, vSet, vOut); + +% Test the tSet (test set) + +% for i = 1 : size(tSet,1) +% vRes = RegulationFeedback(connMat, tSet(i,:)'); +% [Y I] = max(vRes); +% +% if I == find(tOut(i,:)) +% accAll(i,find(tOut(i,:))) = 1; +% end +% end +% +% acc = sum(accAll) ./ tSetsPerPattern; +% acc(nM+1) = mean(acc); +% acc = acc'; + +acc = RegulationFeedbackAcc(connMat, tSet, tOut); diff --git a/PatRec/RFN/RegulationFeedback.m b/PatRec/RFN/RegulationFeedback.m index 70e7278..6273781 100644 --- a/PatRec/RFN/RegulationFeedback.m +++ b/PatRec/RFN/RegulationFeedback.m @@ -1,53 +1,53 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to select the way in which the connectivity matrix will be -% created -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-09-26 / Max Ortiz / Creation -% 2012-03-29 / Max Ortiz / Added the option to use PSO for the connMat -% 20xx-xx-xx / Author / Comment on update - -function [connMat accV] = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts) - -% Get connectivity Matrix -%connMat = Get_connMat(trSet, trOut); %Get connMat using all sets -if strcmp(tType,'Mean') - - connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); - -elseif strcmp(tType,'Mean + PSO') - - thO = 0; % Threshold output is only use in the RegFeedback_ThO - connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); - PSO = InitPSO_RFN(connMat); - [PSO, connMat] = PSO_RFN(PSO, connMat, vSets, vOuts, thO); - -elseif strcmp(tType,'Exclusive Mean') - - connMat = Get_connMat_eMean(trSets, trOuts, vSets, vOuts); - -else - errordlg('No training algorithm was selected','Error'); - return; -end - -% Get accuracy of the validation set -accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2)); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to select the way in which the connectivity matrix will be +% created +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-09-26 / Max Ortiz / Creation +% 2012-03-29 / Max Ortiz / Added the option to use PSO for the connMat +% 20xx-xx-xx / Author / Comment on update + +function [connMat accV] = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts) + +% Get connectivity Matrix +%connMat = Get_connMat(trSet, trOut); %Get connMat using all sets +if strcmp(tType,'Mean') + + connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); + +elseif strcmp(tType,'Mean + PSO') + + thO = 0; % Threshold output is only use in the RegFeedback_ThO + connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); + PSO = InitPSO_RFN(connMat); + [PSO, connMat] = PSO_RFN(PSO, connMat, vSets, vOuts, thO); + +elseif strcmp(tType,'Exclusive Mean') + + connMat = Get_connMat_eMean(trSets, trOuts, vSets, vOuts); + +else + errordlg('No training algorithm was selected','Error'); + return; +end + +% Get accuracy of the validation set +accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2)); diff --git a/PatRec/RFN/RegulationFeedbackAcc.m b/PatRec/RFN/RegulationFeedbackAcc.m index 1834d62..cec8be8 100644 --- a/PatRec/RFN/RegulationFeedbackAcc.m +++ b/PatRec/RFN/RegulationFeedbackAcc.m @@ -1,102 +1,102 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Compute the overal all Accuracy for a data set using RFN -% -% ------------- Updates ------------- -% [Contributors are welcome to add their email] -% 2011-09-26 / Max Ortiz / Created -% 2011-09-26 / Max Ortiz / Addition of nM and modification of the accuracy -% computation -% 2012-05-20 / Max Ortiz / Incorporated thOut to delete the additional -% thOut routines -% 20xx-xx-xx / Author / Comment on update - -function acc = RegulationFeedbackAcc(connMat, tSet, tOut, nM, thOut) - -% Variables -sM = size(tOut,1)/nM; % Sets per movement -good = zeros(size(tSet,1),1);% Keep track of the good prediction -nOut = size(tOut,2); % Number of outputs -accMat = zeros(nM,nOut); -rightOutMat = zeros(nM,nOut); -if ~exist('thOut','var') - thOut = []; -end - -for i = 1 : size(tSet,1) - - % Evaluate the data sets with he Regulation Feedback Algorithm - [outMov outVector] = RegulationFeedbackTest(connMat, tSet(i,:)',[],thOut); - -% % Quick and dirty routine to evaluate mixed-classes -% % IF it's known that more than two patterns are presented -% nExpMov = length(find(tOut(i,:))); -% if nExpMov ~= 1 % More than one movement -% [Y, I] = sort(outVector,'descend'); -% outMov = I(1:nExpMov)'; -% end - - %% Count the number of correct predictions - expectedOutIdx = find(tOut(i,:)); - if ~isempty(outMov) - if outMov ~= 0 - mask = zeros(1,nOut); - mask(outMov) = 1; - % Are these the right movements? - if tOut(i,:) == mask - good(i) = 1; - - %Confusion Matrix - % This will only considered perfect match of mixed-classes - % this must be modified to handle the accuracy of each - % pattern inside the mix - accMat(expectedOutIdx,outMov) = accMat(expectedOutIdx,outMov) + 1; - end -% %Evaluate only a single movement -% if tOut(i,outMov) == 1 -% good(i) = 1; -% end - end - end - - rightOutMat(expectedOutIdx,expectedOutIdx) = rightOutMat(expectedOutIdx,expectedOutIdx) + 1; - % This way of compute the accuracy and confMat is necessary for - % handling unbalanced data sets, such as in the case of mixed-classes - -end - -accMat = accMat ./ rightOutMat; -accMat(isinf(accMat))= NaN; -acc = nanmean(accMat,2); % This requires the statistics toolbox -% without the statistics toolbox -%accMat(isnan(accMat))= 0; -%acc = sum(accMat(accMat~=0),2)./sum(accMat~=0,2); - -acc(end+1) = mean(acc); - -% Compute the accuracy per movement -% Only work if the number of sets is the same per movement. -% acc = zeros(nM+1,1); -% for i = 1 : nM -% s = 1+((i-1)*sM); -% e = sM*i; -% acc(i) = sum(good(s:e))/sM; -% end -% acc(i+1) = sum(good) / length(tSet); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Compute the overal all Accuracy for a data set using RFN +% +% ------------- Updates ------------- +% [Contributors are welcome to add their email] +% 2011-09-26 / Max Ortiz / Created +% 2011-09-26 / Max Ortiz / Addition of nM and modification of the accuracy +% computation +% 2012-05-20 / Max Ortiz / Incorporated thOut to delete the additional +% thOut routines +% 20xx-xx-xx / Author / Comment on update + +function acc = RegulationFeedbackAcc(connMat, tSet, tOut, nM, thOut) + +% Variables +sM = size(tOut,1)/nM; % Sets per movement +good = zeros(size(tSet,1),1);% Keep track of the good prediction +nOut = size(tOut,2); % Number of outputs +accMat = zeros(nM,nOut); +rightOutMat = zeros(nM,nOut); +if ~exist('thOut','var') + thOut = []; +end + +for i = 1 : size(tSet,1) + + % Evaluate the data sets with he Regulation Feedback Algorithm + [outMov outVector] = RegulationFeedbackTest(connMat, tSet(i,:)',[],thOut); + +% % Quick and dirty routine to evaluate mixed-classes +% % IF it's known that more than two patterns are presented +% nExpMov = length(find(tOut(i,:))); +% if nExpMov ~= 1 % More than one movement +% [Y, I] = sort(outVector,'descend'); +% outMov = I(1:nExpMov)'; +% end + + %% Count the number of correct predictions + expectedOutIdx = find(tOut(i,:)); + if ~isempty(outMov) + if outMov ~= 0 + mask = zeros(1,nOut); + mask(outMov) = 1; + % Are these the right movements? + if tOut(i,:) == mask + good(i) = 1; + + %Confusion Matrix + % This will only considered perfect match of mixed-classes + % this must be modified to handle the accuracy of each + % pattern inside the mix + accMat(expectedOutIdx,outMov) = accMat(expectedOutIdx,outMov) + 1; + end +% %Evaluate only a single movement +% if tOut(i,outMov) == 1 +% good(i) = 1; +% end + end + end + + rightOutMat(expectedOutIdx,expectedOutIdx) = rightOutMat(expectedOutIdx,expectedOutIdx) + 1; + % This way of compute the accuracy and confMat is necessary for + % handling unbalanced data sets, such as in the case of mixed-classes + +end + +accMat = accMat ./ rightOutMat; +accMat(isinf(accMat))= NaN; +acc = nanmean(accMat,2); % This requires the statistics toolbox +% without the statistics toolbox +%accMat(isnan(accMat))= 0; +%acc = sum(accMat(accMat~=0),2)./sum(accMat~=0,2); + +acc(end+1) = mean(acc); + +% Compute the accuracy per movement +% Only work if the number of sets is the same per movement. +% acc = zeros(nM+1,1); +% for i = 1 : nM +% s = 1+((i-1)*sM); +% e = sM*i; +% acc(i) = sum(good(s:e))/sM; +% end +% acc(i+1) = sum(good) / length(tSet); + diff --git a/PatRec/RFN/RegulationFeedbackFit.m b/PatRec/RFN/RegulationFeedbackFit.m index b6d8973..862f1b3 100644 --- a/PatRec/RFN/RegulationFeedbackFit.m +++ b/PatRec/RFN/RegulationFeedbackFit.m @@ -1,66 +1,66 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Compute the overal all Accuracy for a data set using RFN -% -% ------------- Updates ------------- -% 2012-04-01 / Max Ortiz / Adapted from RegulationFeedbackAcc -% 20xx-xx-xx / Author / Comment on update - -function fitness = RegulationFeedbackFit(connMat, tSets, tOut, nM, thO) - -% Variables -% Compute fitness as the root mean square error of the outVector -nSets = size(tSets,1); -eSum = 0; - -% Compute fitness as the acuracy error -nOut = size(tOut,2); -good = zeros(size(tSets,1),1); % Keep track of the good prediction - -for i = 1 : size(tSets,1) - - % Evaluate the data sets with he Regulation Feedback Algorithm - if thO == 0 - [outMov outVector] = RegulationFeedbackTest(connMat, tSets(i,:)'); - else - [outMov outVector] = RegulationFeedbackTest_thOut(connMat, tSets(i,:)', thO); - end - % Compute fitness as the root mean square error of the OutVector - eSum = eSum + sum((outVector'-tOut(i,:)).^2); - - % Compute fitness as the acuracy error -% if ~isempty(outMov) -% if outMov ~= 0 -% mask = zeros(1,nOut); -% mask(outMov) = 1; -% % Are these the right movements? -% if tOut(i,:) == mask -% good(i) = 1; -% end -% end -% end - -end - -% Compute fitness as the root mean square error of the outVector -fitness = sqrt(eSum/(nSets*nM)); % for minimum - -% Compute fitness as the acuracy error -%fitness = 1-(sum(good)/nSets); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Compute the overal all Accuracy for a data set using RFN +% +% ------------- Updates ------------- +% 2012-04-01 / Max Ortiz / Adapted from RegulationFeedbackAcc +% 20xx-xx-xx / Author / Comment on update + +function fitness = RegulationFeedbackFit(connMat, tSets, tOut, nM, thO) + +% Variables +% Compute fitness as the root mean square error of the outVector +nSets = size(tSets,1); +eSum = 0; + +% Compute fitness as the acuracy error +nOut = size(tOut,2); +good = zeros(size(tSets,1),1); % Keep track of the good prediction + +for i = 1 : size(tSets,1) + + % Evaluate the data sets with he Regulation Feedback Algorithm + if thO == 0 + [outMov outVector] = RegulationFeedbackTest(connMat, tSets(i,:)'); + else + [outMov outVector] = RegulationFeedbackTest_thOut(connMat, tSets(i,:)', thO); + end + % Compute fitness as the root mean square error of the OutVector + eSum = eSum + sum((outVector'-tOut(i,:)).^2); + + % Compute fitness as the acuracy error +% if ~isempty(outMov) +% if outMov ~= 0 +% mask = zeros(1,nOut); +% mask(outMov) = 1; +% % Are these the right movements? +% if tOut(i,:) == mask +% good(i) = 1; +% end +% end +% end + +end + +% Compute fitness as the root mean square error of the outVector +fitness = sqrt(eSum/(nSets*nM)); % for minimum + +% Compute fitness as the acuracy error +%fitness = 1-(sum(good)/nSets); + diff --git a/PatRec/RFN/RegulationFeedbackTest.m b/PatRec/RFN/RegulationFeedbackTest.m index 6df7b60..74aa347 100644 --- a/PatRec/RFN/RegulationFeedbackTest.m +++ b/PatRec/RFN/RegulationFeedbackTest.m @@ -1,96 +1,96 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Regulation Feedback Algorithm created from the "rf_alg" originally -% by Tsvi Achler -% -% Inputs: -% connMat: The conectivity Matrix is made of a vector of features per pattern -% tVector: Test vector -% newY: New vector. In the absence of a suggested output, RFN randomly -% initializes an ouput in newY. -% thOut: If an output threshold is provided, it will -% consider it for the computation of the prediction. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-09-26 / Max Ortiz / Creation from "rf_alg" by Tsvi Achler -% 2011-10-09 / Max Ortiz / Added newY like an optional input -% 2012-04-01 / Max Ortiz / Ouput fixed to a single max value -% 2012-05-20 / Max Ortiz / Incorporated thOut to delete the additional -% thOut routines -% 20xx-xx-xx / Author / Comment on update - -% Regulatory Feedback Algorithm -function [outMov outVector unstable] = RegulationFeedbackTest(connMat, tVector, newY, thOut) - - numOutputs = size(connMat,1); % number of y's - steadyStateTolerance = 0.00001; % determines when steady state criteria -% salienceValues = zeros(size(tVector)); -% feedback = zeros(size(tVector)); - - itr = 0; - unstable = 0; - - numConnectionsInY = sum(connMat, 2); % calculate number of connections for normalization - - % NOTE: newY could be substitude by the output of the ANN to test - % its stability 2011-09-26 - if ~exist('newY','var') || isempty(newY) - newY = rand(numOutputs, 1);% random initial values for all y's. alternate: initial*ones(numOutputs, 1); initial = .1; -% newY = ones(numOutputs, 1);% random initial values for all y's. alternate: initial*ones(numOutputs, 1); initial = .1; - end - - oldY = Inf(numOutputs, 1); %start with infinity to overcome tolerance - - - % caluclulate new Y values and salience from old Y values and inputs. - while( sum(abs(newY - oldY)) > steadyStateTolerance ) %iterate until steady state - - itr = itr+1; %count number of iterations - oldY = newY; %advance t to t+1 - - feedback = connMat'*oldY; %determine feedback to inputs - - % It will cause an error if the feedback vector has zero values - % which comes form the connMat with only 0 values per column - salienceValues = tVector ./ feedback(feedback ~= 0); % calculate salience - newY = oldY .* (connMat * salienceValues) ./ numConnectionsInY; % calculate updated Y's - - %Watchdog - if itr == 200 - unstable = 1; - break; - end - end - outVector = newY; - - % Ouput using threshold? - if exist('thOut','var') - if ~isempty(thOut) - %mask(1:numOutputs) = thOut; - %outMov = find(outVector>mask'); - outMov = find(outVector>thOut'); - else - [maxV, outMov] = max(outVector); - end - else - [maxV, outMov] = max(outVector); - end -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Regulation Feedback Algorithm created from the "rf_alg" originally +% by Tsvi Achler +% +% Inputs: +% connMat: The conectivity Matrix is made of a vector of features per pattern +% tVector: Test vector +% newY: New vector. In the absence of a suggested output, RFN randomly +% initializes an ouput in newY. +% thOut: If an output threshold is provided, it will +% consider it for the computation of the prediction. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-09-26 / Max Ortiz / Creation from "rf_alg" by Tsvi Achler +% 2011-10-09 / Max Ortiz / Added newY like an optional input +% 2012-04-01 / Max Ortiz / Ouput fixed to a single max value +% 2012-05-20 / Max Ortiz / Incorporated thOut to delete the additional +% thOut routines +% 20xx-xx-xx / Author / Comment on update + +% Regulatory Feedback Algorithm +function [outMov outVector unstable] = RegulationFeedbackTest(connMat, tVector, newY, thOut) + + numOutputs = size(connMat,1); % number of y's + steadyStateTolerance = 0.00001; % determines when steady state criteria +% salienceValues = zeros(size(tVector)); +% feedback = zeros(size(tVector)); + + itr = 0; + unstable = 0; + + numConnectionsInY = sum(connMat, 2); % calculate number of connections for normalization + + % NOTE: newY could be substitude by the output of the ANN to test + % its stability 2011-09-26 + if ~exist('newY','var') || isempty(newY) + newY = rand(numOutputs, 1);% random initial values for all y's. alternate: initial*ones(numOutputs, 1); initial = .1; +% newY = ones(numOutputs, 1);% random initial values for all y's. alternate: initial*ones(numOutputs, 1); initial = .1; + end + + oldY = Inf(numOutputs, 1); %start with infinity to overcome tolerance + + + % caluclulate new Y values and salience from old Y values and inputs. + while( sum(abs(newY - oldY)) > steadyStateTolerance ) %iterate until steady state + + itr = itr+1; %count number of iterations + oldY = newY; %advance t to t+1 + + feedback = connMat'*oldY; %determine feedback to inputs + + % It will cause an error if the feedback vector has zero values + % which comes form the connMat with only 0 values per column + salienceValues = tVector ./ feedback(feedback ~= 0); % calculate salience + newY = oldY .* (connMat * salienceValues) ./ numConnectionsInY; % calculate updated Y's + + %Watchdog + if itr == 200 + unstable = 1; + break; + end + end + outVector = newY; + + % Ouput using threshold? + if exist('thOut','var') + if ~isempty(thOut) + %mask(1:numOutputs) = thOut; + %outMov = find(outVector>mask'); + outMov = find(outVector>thOut'); + else + [maxV, outMov] = max(outVector); + end + else + [maxV, outMov] = max(outVector); + end +end \ No newline at end of file diff --git a/PatRec/RFN/RegulationFeedback_thOut.m b/PatRec/RFN/RegulationFeedback_thOut.m index abf7a4f..aeb1328 100644 --- a/PatRec/RFN/RegulationFeedback_thOut.m +++ b/PatRec/RFN/RegulationFeedback_thOut.m @@ -1,59 +1,59 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Similar to RegulationFeedback but using a threshold to selected the -% predicted movements -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-09-26 / Max Ortiz / Creation -% 2012-03-29 / Max Ortiz / Divided for original version to _thOut -% 2012-05-20 / Max Ortiz / Eliminate the use of additional _thOut routines -% by incorporating thOut into the standard RFN *Acc -% and *Test routines -% 20xx-xx-xx / Author / Comment on update - -function [connMat accV thOut] = RegulationFeedback_thOut(tType, trSets, trOuts, vSets, vOuts) - -% Get connectivity Matrix -%connMat = Get_connMat(trSet, trOut); -%connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); -connMat = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts); - -% Hard-coded threshold -thOut = 0.45; -% Brute force methode to calculate the threshold -bestAcc = 0; -%bestVar = Inf; -for i = .4:0.01:.6 - %accV = RegulationFeedbackAcc_thOut(connMat, i, vSets, vOuts, size(vOuts,2)); - accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2), i); -% varV = var(accV(1:end-1)); - if accV(end) >= bestAcc %&& varV <= bestVar - bestAcc = accV(end); -% bestVar =varV; - thOut = i; - end -end - -disp(bestAcc); -disp(thOut); - -% Get accuracy of the validation set -%accV = RegulationFeedbackAcc_thOut(connMat, thOut, vSets, vOuts, size(vOuts,2)); -accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2), thOut); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Similar to RegulationFeedback but using a threshold to selected the +% predicted movements +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-09-26 / Max Ortiz / Creation +% 2012-03-29 / Max Ortiz / Divided for original version to _thOut +% 2012-05-20 / Max Ortiz / Eliminate the use of additional _thOut routines +% by incorporating thOut into the standard RFN *Acc +% and *Test routines +% 20xx-xx-xx / Author / Comment on update + +function [connMat accV thOut] = RegulationFeedback_thOut(tType, trSets, trOuts, vSets, vOuts) + +% Get connectivity Matrix +%connMat = Get_connMat(trSet, trOut); +%connMat = Get_connMat_TrV(trSets, trOuts, vSets, vOuts); +connMat = RegulationFeedback(tType, trSets, trOuts, vSets, vOuts); + +% Hard-coded threshold +thOut = 0.45; +% Brute force methode to calculate the threshold +bestAcc = 0; +%bestVar = Inf; +for i = .4:0.01:.6 + %accV = RegulationFeedbackAcc_thOut(connMat, i, vSets, vOuts, size(vOuts,2)); + accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2), i); +% varV = var(accV(1:end-1)); + if accV(end) >= bestAcc %&& varV <= bestVar + bestAcc = accV(end); +% bestVar =varV; + thOut = i; + end +end + +disp(bestAcc); +disp(thOut); + +% Get accuracy of the validation set +%accV = RegulationFeedbackAcc_thOut(connMat, thOut, vSets, vOuts, size(vOuts,2)); +accV = RegulationFeedbackAcc(connMat, vSets, vOuts, size(vOuts,2), thOut); diff --git a/PatRec/Rand_TrainingData.m b/PatRec/Rand_TrainingData.m index 1eb8029..cbd8ac6 100644 --- a/PatRec/Rand_TrainingData.m +++ b/PatRec/Rand_TrainingData.m @@ -1,46 +1,46 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to randomize the order of the validation data -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2009-07-21 / Max Ortiz / Change to use the treated_data struct -% 2011-06-23 / Max Ortiz / New names and coding standard -% 2011-07-19 / Max Ortiz / New names and coding standard to new struct -% sigFeatures - -function sigFeatures = Rand_TrainingData(sigFeatures ) - -temp(1:sigFeatures.trSets,:) = sigFeatures.trFeatures; -temp(sigFeatures.trSets + 1 : sigFeatures.trSets + sigFeatures.vSets,:) = sigFeatures.vFeatures; -temp(sigFeatures.trSets + sigFeatures.vSets + 1 : sigFeatures.trSets + sigFeatures.vSets + sigFeatures.tSets,:) = sigFeatures.tFeatures; - -temp2 = temp; - -for i = 1 : size(temp,1) - j = round(1 + rand * (size(temp,1)-1)); - temp(i,:) = temp2(j,:); - temp(j,:) = temp2(i,:); - temp2 = temp; -end - -sigFeatures.trFeatures = temp(1:sigFeatures.trSets,:); -sigFeatures.vFeatures = temp(sigFeatures.trSets+1:sigFeatures.trSets+sigFeatures.vSets,:); -sigFeatures.tFeatures = temp(sigFeatures.trSets+sigFeatures.vSets+1:sigFeatures.trSets+sigFeatures.vSets+sigFeatures.tSets,:); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to randomize the order of the validation data +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2009-07-21 / Max Ortiz / Change to use the treated_data struct +% 2011-06-23 / Max Ortiz / New names and coding standard +% 2011-07-19 / Max Ortiz / New names and coding standard to new struct +% sigFeatures + +function sigFeatures = Rand_TrainingData(sigFeatures ) + +temp(1:sigFeatures.trSets,:) = sigFeatures.trFeatures; +temp(sigFeatures.trSets + 1 : sigFeatures.trSets + sigFeatures.vSets,:) = sigFeatures.vFeatures; +temp(sigFeatures.trSets + sigFeatures.vSets + 1 : sigFeatures.trSets + sigFeatures.vSets + sigFeatures.tSets,:) = sigFeatures.tFeatures; + +temp2 = temp; + +for i = 1 : size(temp,1) + j = round(1 + rand * (size(temp,1)-1)); + temp(i,:) = temp2(j,:); + temp(j,:) = temp2(i,:); + temp2 = temp; +end + +sigFeatures.trFeatures = temp(1:sigFeatures.trSets,:); +sigFeatures.vFeatures = temp(sigFeatures.trSets+1:sigFeatures.trSets+sigFeatures.vSets,:); +sigFeatures.tFeatures = temp(sigFeatures.trSets+sigFeatures.vSets+1:sigFeatures.trSets+sigFeatures.vSets+sigFeatures.tSets,:); diff --git a/PatRec/Rand_sigFeatures.m b/PatRec/Rand_sigFeatures.m index c79f6ca..45e23fd 100644 --- a/PatRec/Rand_sigFeatures.m +++ b/PatRec/Rand_sigFeatures.m @@ -1,47 +1,47 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to randomize the order of the validation data -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2009-07-21 / Max Ortiz / Change to use the treated_data struct -% 2011-06-23 / Max Ortiz / New names and coding standard -% 2011-07-19 / Max Ortiz / New names and coding standard to new struct -% sigFeatures -% - -function sigFeatures = Rand_sigFeatures(sigFeatures) - -temp(1:sigFeatures.trSets,:) = sigFeatures.trFeatures; -temp(sigFeatures.trSets + 1 : sigFeatures.trSets + sigFeatures.vSets,:) = sigFeatures.vFeatures; -temp(sigFeatures.trSets + sigFeatures.vSets + 1 : sigFeatures.trSets + sigFeatures.vSets + sigFeatures.tSets,:) = sigFeatures.tFeatures; - -temp2 = temp; - -for i = 1 : size(temp,1) - j = round(1 + rand * (size(temp,1)-1)); - temp(i,:) = temp2(j,:); - temp(j,:) = temp2(i,:); - temp2 = temp; -end - -sigFeatures.trFeatures = temp(1:sigFeatures.trSets,:); -sigFeatures.vFeatures = temp(sigFeatures.trSets+1:sigFeatures.trSets+sigFeatures.vSets,:); -sigFeatures.tFeatures = temp(sigFeatures.trSets+sigFeatures.vSets+1:sigFeatures.trSets+sigFeatures.vSets+sigFeatures.tSets,:); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to randomize the order of the validation data +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2009-07-21 / Max Ortiz / Change to use the treated_data struct +% 2011-06-23 / Max Ortiz / New names and coding standard +% 2011-07-19 / Max Ortiz / New names and coding standard to new struct +% sigFeatures +% + +function sigFeatures = Rand_sigFeatures(sigFeatures) + +temp(1:sigFeatures.trSets,:) = sigFeatures.trFeatures; +temp(sigFeatures.trSets + 1 : sigFeatures.trSets + sigFeatures.vSets,:) = sigFeatures.vFeatures; +temp(sigFeatures.trSets + sigFeatures.vSets + 1 : sigFeatures.trSets + sigFeatures.vSets + sigFeatures.tSets,:) = sigFeatures.tFeatures; + +temp2 = temp; + +for i = 1 : size(temp,1) + j = round(1 + rand * (size(temp,1)-1)); + temp(i,:) = temp2(j,:); + temp(j,:) = temp2(i,:); + temp2 = temp; +end + +sigFeatures.trFeatures = temp(1:sigFeatures.trSets,:); +sigFeatures.vFeatures = temp(sigFeatures.trSets+1:sigFeatures.trSets+sigFeatures.vSets,:); +sigFeatures.tFeatures = temp(sigFeatures.trSets+sigFeatures.vSets+1:sigFeatures.trSets+sigFeatures.vSets+sigFeatures.tSets,:); diff --git a/PatRec/RealtimePatRec.m b/PatRec/RealtimePatRec.m index 4648d29..7ad7b10 100644 --- a/PatRec/RealtimePatRec.m +++ b/PatRec/RealtimePatRec.m @@ -1,357 +1,394 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to execute real-time patrec using the offline trained algorithm -% which information is stored in patRec -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-27 / Max Ortiz / Creation -% 2011-08-03 / Max Ortiz / Separation of "SignalProcessing_RealtimePatRec" -% 2011-11-17 / Max Ortiz / Added the motors coupling -% 2011-12-07 / Nichlas Sander / Added VRE Coupling and VRE commands. -% 2011-12-07 / Max Ortiz / Upgrade to Session-based interface for DAQ,the -% prevous version was called RealtimePatRec_Legacy.m -% 2012-08-13 / Morten Kristoffersen / Added GUI interface to see and control -% the threshold values for the MLP ThOut algorithm. -% 2012-10-05 / Joel Falk-Dahlin / Changed inputs and outputs of -% ApplyControl to work with updated version. -% Removed InitControl since it is -% performed inside the GUI -% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl -% 2012-11-06 / Max Ortiz / Create RealimePatRec_OneShot to concentrate -% critical routines of realtimepatrec -% 2012-11-23 / Joel Falk-Dahlin / Moved speeds from handles to patRec, -% changed VRE to use the new speeds - -% 20xx-xx-xx / Author / Comment on update -function handlesX = RealtimePatRec(patRecX, handlesX) - -clear global; -clear persistent; - -global patRec; -global handles; -global nTW; -global procT; -global motorCoupling; -global vreCoupling; -global pwmIDs; -global pwmAs; -global pwmBs; -global tempData; -global outVectorMotorLast; -%global data; % only needed for testing -global thresholdGUIData; - - -patRec = patRecX; -handles = handlesX; -nTW = 1; -procT = []; -tempData = []; -outVectorMotorLast = zeros(patRec.nOuts,1); -pDiv = 2; % Peeking devider, the fastest allowed for the DAQ - % which is 20 times per second, so 0.05 for 2k Hz -% Get sampling time -sT = str2double(get(handles.et_testingT,'String')); - -% Initialze control algorithms -%patRec = InitControl(patRec); % No longer needed, Initialization is done in GUI - -%% Is threshold (thOut) used? -if(isfield(patRec.patRecTrained,'thOut')); - %Threshold GUI init - thresholdGUI = GUI_Threshold; - thresholdGUIData = guidata(thresholdGUI); - set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); - xpatch = [1 1 0 0]; - ypatch = [0 0 0 0]; - for i=0:patRec.nOuts-1 - s = sprintf('movementSelector%d',i); - s0 = sprintf('thPatch%d',i); - s1 = sprintf('meter%d',i); - axes(thresholdGUIData.(s1)); - handles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); - ylim(thresholdGUIData.(s1), [0 1]); - xlim('auto'); - set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); - if (size(patRec.mov(patRec.indMovIdx),1) < i+1); - set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); - else - set(thresholdGUIData.(s),'Value',i+1); - end - end -end - -%% Is the VRE selected? -vreCoupling = 0; -if isfield(handles,'vre_Com'); - %If there is a vre communication, is it open? - vreCoupling = strcmp(handles.vre_Com.Status,'open'); -end - - -%% Is there an option for coupling with the motors? -if isfield(handles,'cb_motorCoupling') %&& ~isfield(handles,'com') - motorCoupling = get(handles.cb_motorCoupling,'Value'); -else - motorCoupling = 0; -end - -%Is the motor coupling selected? -if motorCoupling - - %Initialize - motorIdx = zeros(1,10); - pwmAs = zeros(1,10); - pwmBs = zeros(1,10); - movSpeeds = zeros(1,10); - - % Get the links to the motors - for i = 1 : size(motorIdx,2) - pmID = ['handles.pm_m' num2str(i)]; - motorIdx(i) = get(eval(pmID),'Value'); - speedID = ['handles.et_speed' num2str(i)]; - movSpeeds(i) = str2double(get(eval(speedID),'String')); - end - - % Init variables for control - pwmIDs = ['A';'A';'B';'B';'C';'C';'D';'D';'E';'E']; - for i = 1 : 2 : size(pwmIDs) - pwmAs(i) = movSpeeds(i); - pwmBs(i) = 0; - pwmAs(i+1) = 0; - pwmBs(i+1) = movSpeeds(i+1); - end; - - % Arrenge according to selection - pwmIDs = pwmIDs(motorIdx); - pwmAs = pwmAs(motorIdx); - pwmBs = pwmBs(motorIdx); - -end - -%% Initialize DAQ card -% Note: A function for DAQ selection will be required when more cards are -% added -if strcmp(patRec.dev,'ADH') - -else % at this poin everything else is the NI - USB6009 - chAI = zeros(1,8); % 8 ch is the limit for the USB6009 - chAI(patRec.nCh) = 1; - %Init the SBI - s = InitSBI_NI(patRec.sF,sT,chAI); - % Change the interruption time - s.NotifyWhenDataAvailableExceeds = (patRec.sF*patRec.tW)/pDiv; - lh = s.addlistener('DataAvailable', @RealtimePatRec_OneShot); - %Test the DAQ by ploting the data - %lh = s.addlistener('DataAvailable', @plotDataTest); -end - - -%% Run the Realtime PatRec -% Note: Probabily this way of testing only works for the NI -% Specific funtions per card might be required. -s.startBackground(); - -% Wait until it has finished done -%s.IsDone % will report 0 -s.wait(); % rather than while -%s.IsDone % will report 1 - -%% Finish session -%Delete listener SBI -delete (lh) - -%Stop motors -if motorCoupling - if(isfield(handles,'movList')) - for i=1 : length(handles.movList) - [handles.motors, ~] = MotorsOff(handles.com, handles.movList(i), handles.motors); - end - else - ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, 0); - end -end - -% Write the average processing time -set(handles.et_avgProcTime,'String',num2str(mean(procT(2:end)))); - -handlesX = handles; - -%Reset Threshold GUI -if(isfield(patRec.patRecTrained,'thOut')); - for i=0:patRec.nOuts-1 - s0 = sprintf('thPatch%d',i); - set(handles.(s0), 'YData', [0 0 0 0]); - %delete(GUI_Threshold); - end -end - -%Plot processing time -figure(); -hist(procT(2:end)); - -end - -function RealtimePatRec_OneShot(src,event) - - global patRec; - global nTW; - global procT; - global motorCoupling; - global vreCoupling; - global handles; - global TAC; - global pwmIDs; - global pwmAs; - global pwmBs; - global tempData; - global outVectorMotorLast; - - global thresholdGUIData; - - %Keep saving all recorded data - tempData = [tempData; event.Data]; - - %Output vector - outVectorMotor = zeros(patRec.nOuts,1); - - %Only considered the data once it has at least the size of time window - if size(tempData,1) >= (patRec.sF*patRec.tW) - - tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data - - % Start of processing time - procTimeS = tic; - - % General routine for RealtimePatRec - [outMov outVector patRec handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData); - - % GUI and control Updates - % Game control - if get(handles.cb_keys,'Value') && outMov(1) ~= 0 - keys = zeros(patRec.nM,1); - keys(outMov) = 1; - savedKeys = []; - if isfield(handles,'savedKeys') - savedKeys = handles.savedKeys; - end - SendKeys(keys,savedKeys); - end - - % Send vector to the motors - if(isfield(handles,'movList')) - if motorCoupling - % Update outvectorMotor - outVectorMotor(outMov) = 1; - % Check if the state has change - outChanged = find(xor(outVectorMotor, outVectorMotorLast)); - % Only send information to the motors that have changed - % state - for i = 1 : size(outChanged,1) - if outVectorMotor(outChanged(i)) - [handles.motors, ~] = MotorsOn(handles.com, handles.movList(outChanged(i)), handles.motors, patRec.control.currentDegPerMov(outChanged(i))); - else - [handles.motors, ~] = MotorsOff(handles.com, handles.movList(outChanged(i)), handles.motors); - end - end - end - - % To slow for hand open and close since it continuesly send - % data to the microcontroller -% perfMov = handles.movList(outMov); -% if motorCoupling -% %Activate motors here using MoveMotor (for now). -% [handles.motors, ~] = MoveMotor(handles.com, perfMov, 1, z§handles.motors); -% end - - - % VRE - if vreCoupling - for i = 1:length(outMov) - speed = patRec.control.currentDegPerMov(outMov(i)); - perfMov = handles.movList(outMov(i)); - if VREActivation(handles.vre_Com, speed, [], perfMov.idVRE, perfMov.vreDir, get(handles.cb_moveTAC,'Value')) - TAC.acktimes = TAC.acktimes + 1; - end - end - end - else % alternative way for motor control - if motorCoupling - ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, outMov); - end - - if vreCoupling - dof = round(outMov/2); - dofs = [9,7,8,0,10]; - dir = mod(outMov,2); - - if (dof == 1 && dir == 1) - dof = 5; - end - - if (dir == 1) - dir = 0; - else - dir = 1; - end - - if VREActivation(handles.vre_Com, 25, [], dofs(dof), dir, get(handles.cb_moveTAC,'Value')) == 1 - % TAC Test Completed - TAC.ackTimes = TAC.ackTimes + 1; - end - end - end - - % Next cycle - nTW = nTW + 1; - outVectorMotorLast = outVectorMotor; - % Finish of processing time - procT(nTW) = toc(procTimeS); - - % quick and dirty patch to keep the servos moving - % this is provisional - if motorCoupling - for i = 1 : size(outChanged,1) - if or(handles.movList(outChanged(i)).motor == 8, ... - handles.movList(outChanged(i)).motor == 7) - outVectorMotorLast(outChanged(i)) = 0; - end - end - end - end - end - - function plotDataTest(src,event) - persistent tempData; - global data - if(isempty(tempData)) - tempData = []; - figure(); - end - plot(event.TimeStamps, event.Data) - tempData = [tempData;event.Data]; - data = tempData; - end - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to execute real-time patrec using the offline trained algorithm +% which information is stored in patRec +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-27 / Max Ortiz / Creation +% 2011-08-03 / Max Ortiz / Separation of "SignalProcessing_RealtimePatRec" +% 2011-11-17 / Max Ortiz / Added the motors coupling +% 2011-12-07 / Nichlas Sander / Added VRE Coupling and VRE commands. +% 2011-12-07 / Max Ortiz / Upgrade to Session-based interface for DAQ, the +% prevous version was called RealtimePatRec_Legacy.m +% 2012-08-13 / Morten Kristoffersen / Added GUI interface to see and control +% the threshold values for the MLP ThOut algorithm. +% 2012-10-05 / Joel Falk-Dahlin / Changed inputs and outputs of +% ApplyControl to work with updated version. +% Removed InitControl since it is +% performed inside the GUI +% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl +% 2012-11-06 / Max Ortiz / Create RealimePatRec_OneShot to concentrate +% critical routines of realtimepatrec +% 2012-11-23 / Joel Falk-Dahlin / Moved speeds from handles to patRec, +% changed VRE to use the new speeds +% 2013-04-17 / Max Ortiz / Made independent routines for control of +% differend devices +% 2013-06-03 / Max Ortiz / Addition of necessary routines to control +% Standard proshetic components (SPC) using wifi. +% 2014-11-12 / Enzo Mastinu / Added code for ADS1299 AFE RealTime PatRec +% 2015-01-20 / Enzo Mastinu / All this function has been re-organized +% to be compatible with the functions +% placed into COMM/AFE folder. For more +% details read about RecordingSession.m with +% other custom devices for BioPatRec_TRE. + +% 20xx-xx-xx / Author / Comment on update + +function handlesX = RealtimePatRec(patRecX, handlesX) + + clear global; + clear persistent; + + global patRec; + global handles; + global nTW; + global procT; + global motorCoupling; + global vreCoupling; + global pwmIDs; + global pwmAs; + global pwmBs; + global tempData; + global outVectorMotorLast; + + %global data; % only needed for testing + global thresholdGUIData; + + patRec = patRecX; + handles = handlesX; + nTW = 1; + procT = []; + tempData = []; + outVectorMotorLast = zeros(patRec.nOuts,1); + + % Get needed info from patRec structure + sF = patRec.sF; + nCh = length(patRec.nCh); + ComPortType = patRec.comm; + deviceName = patRec.dev; + + % Get sampling time + sT = str2double(get(handles.et_testingT,'String')); + tW = sT/100; % Time window size + tWs = tW*sF; % Time window samples + + + % Initialze control algorithms + %patRec = InitControl(patRec); % No longer needed, Initialization is done in GUI + + %% Is threshold (thOut) used? + if(isfield(patRec.patRecTrained,'thOut')); + %Threshold GUI init + thresholdGUI = GUI_Threshold; + thresholdGUIData = guidata(thresholdGUI); + set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); + xpatch = [1 1 0 0]; + ypatch = [0 0 0 0]; + for i=0:patRec.nOuts-1 + s = sprintf('movementSelector%d',i); + s0 = sprintf('thPatch%d',i); + s1 = sprintf('meter%d',i); + axes(thresholdGUIData.(s1)); + handles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); + ylim(thresholdGUIData.(s1), [0 1]); + xlim('auto'); + set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); + if (size(patRec.mov(patRec.indMovIdx),1) < i+1); + set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); + else + set(thresholdGUIData.(s),'Value',i+1); + end + end + end + + %% Is the VRE selected? + vreCoupling = 0; + if isfield(handles,'vre_Com'); + %If there is a vre communication, is it open? + vreCoupling = strcmp(handles.vre_Com.Status,'open'); + end + + %% Is there an option for coupling with the motors? + if isfield(handles,'cb_motorCoupling') %&& ~isfield(handles,'com') + motorCoupling = get(handles.cb_motorCoupling,'Value'); + else + motorCoupling = 0; + end + +% % Init variables for hard-coded control (not using objects) %% CHECK +% if motorCoupling && ~isfield(handles,'movList') +% if deviceID == 1 % Multifunctinal prosthesis with DC motors +% [pwmIDs pwmAs pwmBs] = InitMF_Hand_DC_Hardcoded(handles); +% elseif deviceID == 3 % Standard prosthetic units (wireless) +% +% end +% end + + % Get connection object for control external robotic devices + if motorCoupling + if ~isfield(handles,'Control_obj') + set(handles.t_msg,'String','No connection obj found'); + return; + end + if ~strcmp(handles.Control_obj.status,'open') + fopen(handles.Control_obj); + end + end + + cData = zeros(tWs,nCh); + + %%%%% Real Time PatRec with NI DAQ card %%%%% + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @RealtimePatRec_OneShot); + + % Start DAQ + s.startBackground(); % Run in the backgroud + + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + + %%%%% Real Time PatRec with other custom device %%%%% + else + + % Prepare handles for next function calls + handles.deviceName = deviceName; + handles.ComPortType = ComPortType; + if strcmp (ComPortType, 'COM') + handles.ComPortName = patRec.comn; + end + handles.sF = sF; + handles.sT = sT; + handles.nCh = nCh; + handles.sTall = sT; + + % Delete connection object + if isfield(handles,'obj') + delete(handles.obj); + end + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + handles.obj = obj; + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + for timeWindowNr = 1:sT/tW + + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + RealtimePatRec_OneShot(0, acquireEvent); + end + + % Stop acquisition + StopAcquisition(deviceName, obj); + end + + %Stop motors + if motorCoupling + if ~strcmp(handles.Control_obj.status,'open') + fopen(handles.Control_obj); + end + if(isfield(handles,'movList')) % Is the movement obj used? + for i=1 : length(handles.movList) + [handles.motors, ~] = MotorsOff(handles.Control_obj, handles.movList(i), handles.motors); + end + else % from hardcoded GUI GUI_TestPatRec + ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, 0); + end + end + + % Write the average processing time + set(handles.et_avgProcTime,'String',num2str(mean(procT(2:end)))); + + handlesX = handles; + + %Reset Threshold GUI + if(isfield(patRec.patRecTrained,'thOut')); + for i=0:patRec.nOuts-1 + s0 = sprintf('thPatch%d',i); + set(handles.(s0), 'YData', [0 0 0 0]); + %delete(GUI_Threshold); + end + end + + %Plot processing time + figure(); + hist(procT(2:end)); + set(handles.pb_RealtimePatRec, 'Enable', 'on'); +end + + +function RealtimePatRec_OneShot(src,event) + + global patRec; + global nTW; + global procT; + global motorCoupling; + global vreCoupling; + global handles; + global TAC; + global pwmIDs; + global pwmAs; + global pwmBs; + global tempData; + global outVectorMotorLast; + global thresholdGUIData; + + %Keep saving all recorded data + tempData = [tempData; event.Data]; + + %Output vector + outVectorMotor = zeros(patRec.nOuts,1); + + %Only considered the data once it has at least the size of time window + if size(tempData,1) >= (patRec.sF*patRec.tW) + + tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data + + % Start of processing time + procTimeS = tic; + + % General routine for RealtimePatRec + [outMov outVector patRec handles] = OneShotRealtimePatRec(tData, patRec, handles, thresholdGUIData); + + % GUI and control Updates + + % Game control + if get(handles.cb_keys,'Value') && outMov(1) ~= 0 + keys = zeros(patRec.nM,1); + keys(outMov) = 1; + savedKeys = []; + if isfield(handles,'savedKeys') + savedKeys = handles.savedKeys; + end + SendKeys(keys,savedKeys); + end + + + % Robot control + if get(handles.cb_controls,'Value') &&outMov(1) ~=0 + controls = zeros(patRec.nM,1); + controls(outMov) = 1; + savedControls = []; + if isfield(handles,'savedControls') + savedControls = handles.savedControls; + end + SendControls(controls,savedControls); + end + + % Send vector to the motors + if(isfield(handles,'movList')) + if motorCoupling + % Update outvectorMotor + outVectorMotor(outMov) = 1; + % Check if the state has change + outChanged = find(xor(outVectorMotor, outVectorMotorLast)); + % Only send information to the motors that have changed state + for i = 1 : size(outChanged,1) + if outVectorMotor(outChanged(i)) + [handles.motors, ~] = MotorsOn(handles.Control_obj, handles.movList(outChanged(i)), handles.motors, patRec.control.currentDegPerMov(outChanged(i))); + else + [handles.motors, ~] = MotorsOff(handles.Control_obj, handles.movList(outChanged(i)), handles.motors); + end + end + end + + % VRE + if vreCoupling + for i = 1:length(outMov) + speed = patRec.control.currentDegPerMov(outMov(i)); + perfMov = handles.movList(outMov(i)); + if VREActivation(handles.vre_Com, speed, [], perfMov.idVRE, perfMov.vreDir, get(handles.cb_moveTAC,'Value')) + TAC.acktimes = TAC.acktimes + 1; + end + end + end + else % alternative way for motor control (hard-coded) + if motorCoupling + ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, outMov); + end + + if vreCoupling + dof = round(outMov/2); + dofs = [9,7,8,0,10]; + dir = mod(outMov,2); + + if (dof == 1 && dir == 1) + dof = 5; + end + + if (dir == 1) + dir = 0; + else + dir = 1; + end + + if VREActivation(handles.vre_Com, 25, [], dofs(dof), dir, get(handles.cb_moveTAC,'Value')) == 1 + % TAC Test Completed + TAC.ackTimes = TAC.ackTimes + 1; + end + end + end + + % Next cycle + nTW = nTW + 1; + outVectorMotorLast = outVectorMotor; + % Finish of processing time + procT(nTW) = toc(procTimeS); + + % quick and dirty patch to keep the servos moving + % this is provisional + if motorCoupling + for i = 1 : size(outChanged,1) + if or(handles.movList(outChanged(i)).motor == 8, ... + handles.movList(outChanged(i)).motor == 7) + outVectorMotorLast(outChanged(i)) = 0; + end + end + end + + + end + end + + function plotDataTest(src,event) + persistent tempData; + global data + if(isempty(tempData)) + tempData = []; + figure(); + end + plot(event.TimeStamps, event.Data) + tempData = [tempData;event.Data]; + data = tempData; + end + + + + + diff --git a/PatRec/RealtimePatRec_Legacy.m b/PatRec/RealtimePatRec_Legacy.m index d7c07f7..f76036b 100644 --- a/PatRec/RealtimePatRec_Legacy.m +++ b/PatRec/RealtimePatRec_Legacy.m @@ -1,168 +1,168 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% Function to execute real-time patrec using the offline trained algorithm -% which information is stored in patRec -% -% --------------------------Updates-------------------------- -% 2011-07-27 / Max Ortiz / Creation -% 2011-08-03 / Max Ortiz / Separation of "SignalProcessing_RealtimePatRec" -% 2011-11-17 / Max Ortiz / Added the motors coupling -% 2011-12-07 / Nichlas Sander / Added VRE Coupling and VRE commands. - -function RealtimePatRec(patRec, handles) - -% Get sampling time -sT = str2double(get(handles.et_testingT,'String')); - -%% Is there an option for coupling with the motors? -if isfield(handles,'cb_motorCoupling') %&& ~isfield(handles,'com') - motorCoupling = get(handles.cb_motorCoupling,'Value'); -else - motorCoupling = 0; -end - -if isfield(handles,'cb_VRE') %&& ~isfield(handles,'com') - vreCoupling = get(handles.cb_VRE,'Value'); -else - vreCoupling = 0; -end - -%Is the motor coupling selected? -if motorCoupling - - %Initialize - motorIdx = zeros(1,10); - pwmAs = zeros(1,10); - pwmBs = zeros(1,10); - movSpeeds = zeros(1,10); - - % Get the links to the motors - for i = 1 : size(motorIdx,2) - pmID = ['handles.pm_m' num2str(i)]; - motorIdx(i) = get(eval(pmID),'Value'); - speedID = ['handles.et_speed' num2str(i)]; - movSpeeds(i) = str2double(get(eval(speedID),'String')); - end - - % Init variables for control - pwmIDs = ['A';'A';'B';'B';'C';'C';'D';'D';'E';'E']; - for i = 1 : 2 : size(pwmIDs) - pwmAs(i) = movSpeeds(i); - pwmBs(i) = 0; - pwmAs(i+1) = 0; - pwmBs(i+1) = movSpeeds(i+1); - end; - - % Arrenge according to selection - pwmIDs = pwmIDs(motorIdx); - pwmAs = pwmAs(motorIdx); - pwmBs = pwmBs(motorIdx); - -end - -%% Initialize DAQ card -% Note: A function for DAQ selection will be required when more cards are -% added -if strcmp(patRec.dev,'ADH') - -else % at this poin everything else is the NI - USB6009 - chAI = zeros(1,8); - chAI(patRec.nCh) = 1; - %ai = InitNI(patRec.sF,sT,chAI); - s = InitSBI(patRec.sF,sT,chAI); - lh = s.addlistener('DataAvailable', @plotData); - - % Change the peek time - s.NotifyWhenDataAvailableExceeds = patRec.sF*patRec.tW; -end - -%% Testing -% Note: Probabily this way of testing only works for the NI -% Specific funtions per card might be required. - -start(ai); % Start the daya acquisition -nTW = 1; % Number of time windows - -% Wait until the first samples are aquired -while ai.SamplesAcquired < patRec.sF*patRec.tW -end -% start DAQ -while ai.SamplesAcquired < patRec.sF*sT - - % Processing time start - procTimeS = tic; - - %Data Peek - data = peekdata(ai,patRec.sF*patRec.tW); - - %Signal processing - tSet = SignalProcessing_RealtimePatRec(data, patRec); - - % One shoot PatRec - [outMov outVector] = OneShotPatRecClassifier(patRec, tSet); - % [outMov outVector] = OneShotPatRec(patRec.patRecTrained, tSet); - - % Quick patch for simultaneous rec using neural nets -% if strcmp(patRec.patRecTrained.algorithm,'ANN') -% outMov = find(round(outVector)); -% if isempty(outMov) -% outMov = size(outVector,1); -% end -% end - -% if strcmp(patRec.algorithm,'ANN'); -% -% elseif strcmp(patRec.algorithm,'DA') -% outMov = DiscriminantTest(patRec.coeff, tSet, patRec.training); -% end - - % Compute time - procT(nTW) = toc(procTimeS); - - % Show results - set(handles.lb_movements,'Value',outMov); - drawnow; - - % Send vector to the motors - if motorCoupling - ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, outMov); - end - if vreCoupling - dof = round(outMov/2); - dir = mod(outMov,2); - VREActivation(handles.vre_Com, 10, 0.1, dof, dir) - end - % Next cycle - nTW = nTW + 1; - -end -%% Finish session -%Stop motors -if motorCoupling - ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, 0); -end -%Stop acquisition -stop(ai); -delete(ai); - -set(handles.et_avgProcTime,'String',num2str(mean(procT(2:end)))); - -%Plot processing time -figure(); -hist(procT(2:end)); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% Function to execute real-time patrec using the offline trained algorithm +% which information is stored in patRec +% +% --------------------------Updates-------------------------- +% 2011-07-27 / Max Ortiz / Creation +% 2011-08-03 / Max Ortiz / Separation of "SignalProcessing_RealtimePatRec" +% 2011-11-17 / Max Ortiz / Added the motors coupling +% 2011-12-07 / Nichlas Sander / Added VRE Coupling and VRE commands. + +function RealtimePatRec(patRec, handles) + +% Get sampling time +sT = str2double(get(handles.et_testingT,'String')); + +%% Is there an option for coupling with the motors? +if isfield(handles,'cb_motorCoupling') %&& ~isfield(handles,'com') + motorCoupling = get(handles.cb_motorCoupling,'Value'); +else + motorCoupling = 0; +end + +if isfield(handles,'cb_VRE') %&& ~isfield(handles,'com') + vreCoupling = get(handles.cb_VRE,'Value'); +else + vreCoupling = 0; +end + +%Is the motor coupling selected? +if motorCoupling + + %Initialize + motorIdx = zeros(1,10); + pwmAs = zeros(1,10); + pwmBs = zeros(1,10); + movSpeeds = zeros(1,10); + + % Get the links to the motors + for i = 1 : size(motorIdx,2) + pmID = ['handles.pm_m' num2str(i)]; + motorIdx(i) = get(eval(pmID),'Value'); + speedID = ['handles.et_speed' num2str(i)]; + movSpeeds(i) = str2double(get(eval(speedID),'String')); + end + + % Init variables for control + pwmIDs = ['A';'A';'B';'B';'C';'C';'D';'D';'E';'E']; + for i = 1 : 2 : size(pwmIDs) + pwmAs(i) = movSpeeds(i); + pwmBs(i) = 0; + pwmAs(i+1) = 0; + pwmBs(i+1) = movSpeeds(i+1); + end; + + % Arrenge according to selection + pwmIDs = pwmIDs(motorIdx); + pwmAs = pwmAs(motorIdx); + pwmBs = pwmBs(motorIdx); + +end + +%% Initialize DAQ card +% Note: A function for DAQ selection will be required when more cards are +% added +if strcmp(patRec.dev,'ADH') + +else % at this poin everything else is the NI - USB6009 + chAI = zeros(1,8); + chAI(patRec.nCh) = 1; + %ai = InitNI(patRec.sF,sT,chAI); + s = InitSBI(patRec.sF,sT,chAI); + lh = s.addlistener('DataAvailable', @plotData); + + % Change the peek time + s.NotifyWhenDataAvailableExceeds = patRec.sF*patRec.tW; +end + +%% Testing +% Note: Probabily this way of testing only works for the NI +% Specific funtions per card might be required. + +start(ai); % Start the daya acquisition +nTW = 1; % Number of time windows + +% Wait until the first samples are aquired +while ai.SamplesAcquired < patRec.sF*patRec.tW +end +% start DAQ +while ai.SamplesAcquired < patRec.sF*sT + + % Processing time start + procTimeS = tic; + + %Data Peek + data = peekdata(ai,patRec.sF*patRec.tW); + + %Signal processing + tSet = SignalProcessing_RealtimePatRec(data, patRec); + + % One shoot PatRec + [outMov outVector] = OneShotPatRecClassifier(patRec, tSet); + % [outMov outVector] = OneShotPatRec(patRec.patRecTrained, tSet); + + % Quick patch for simultaneous rec using neural nets +% if strcmp(patRec.patRecTrained.algorithm,'ANN') +% outMov = find(round(outVector)); +% if isempty(outMov) +% outMov = size(outVector,1); +% end +% end + +% if strcmp(patRec.algorithm,'ANN'); +% +% elseif strcmp(patRec.algorithm,'DA') +% outMov = DiscriminantTest(patRec.coeff, tSet, patRec.training); +% end + + % Compute time + procT(nTW) = toc(procTimeS); + + % Show results + set(handles.lb_movements,'Value',outMov); + drawnow; + + % Send vector to the motors + if motorCoupling + ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, outMov); + end + if vreCoupling + dof = round(outMov/2); + dir = mod(outMov,2); + VREActivation(handles.vre_Com, 10, 0.1, dof, dir) + end + % Next cycle + nTW = nTW + 1; + +end +%% Finish session +%Stop motors +if motorCoupling + ActivateMotors(handles.com, pwmIDs, pwmAs, pwmBs, 0); +end +%Stop acquisition +stop(ai); +delete(ai); + +set(handles.et_avgProcTime,'String',num2str(mean(procT(2:end)))); + +%Plot processing time +figure(); +hist(procT(2:end)); diff --git a/PatRec/SOM/Batch Training/BatchNeighborFunction.m b/PatRec/SOM/Batch Training/BatchNeighborFunction.m index db0fe94..a48eafb 100644 --- a/PatRec/SOM/Batch Training/BatchNeighborFunction.m +++ b/PatRec/SOM/Batch Training/BatchNeighborFunction.m @@ -1,54 +1,54 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function for different Neighbor Function Bubble,Gaussian ,Cut Gaussian, -% Epanechikov and Butter worth 2nd order. -% -% Note: Bubble,Gaussian ,Cut Gaussian and Epanechikov implemented according to -% SOM toolbox Team[1] -% -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-07 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function neigh=BatchNeighborFunction(SOM,sigma) - -neighborFunction=SOM.neighFunc; -% The euclidean distance Matrix between the coordinates of the winning neuron and all -% others -neuronDist=SOM.neuronDist; - - -switch neighborFunction, - case 'bubb' - %neuronDist(neuronDist>sigma)=0; - neigh=(neuronDist<=sigma); - case 'gauss' - neigh = exp(-(neuronDist.^2)./(2*sigma^2)); - case 'cutGauss' - neigh = exp(-(neuronDist.^2)./(2*sigma^2)) .* (neuronDist<=sigma); - case 'trai' - neigh = (1-neuronDist./sigma) .* (neuronDist<=sigma); - case 'butter' - neigh =1./(1+(neuronDist./sigma).^4); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function for different Neighbor Function Bubble,Gaussian ,Cut Gaussian, +% Epanechikov and Butter worth 2nd order. +% +% Note: Bubble,Gaussian ,Cut Gaussian and Epanechikov implemented according to +% SOM toolbox Team[1] +% +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-07 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function neigh=BatchNeighborFunction(SOM,sigma) + +neighborFunction=SOM.neighFunc; +% The euclidean distance Matrix between the coordinates of the winning neuron and all +% others +neuronDist=SOM.neuronDist; + + +switch neighborFunction, + case 'bubb' + %neuronDist(neuronDist>sigma)=0; + neigh=(neuronDist<=sigma); + case 'gauss' + neigh = exp(-(neuronDist.^2)./(2*sigma^2)); + case 'cutGauss' + neigh = exp(-(neuronDist.^2)./(2*sigma^2)) .* (neuronDist<=sigma); + case 'trai' + neigh = (1-neuronDist./sigma) .* (neuronDist<=sigma); + case 'butter' + neigh =1./(1+(neuronDist./sigma).^4); end \ No newline at end of file diff --git a/PatRec/SOM/Batch Training/BatchTrainig.m b/PatRec/SOM/Batch Training/BatchTrainig.m index ec8396c..5dd4a55 100644 --- a/PatRec/SOM/Batch Training/BatchTrainig.m +++ b/PatRec/SOM/Batch Training/BatchTrainig.m @@ -1,80 +1,80 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to run the batch training.The principle of updating weight vector -% step goes by replacing each map unit by the average of the data vectors that -% were in its neighborhood. The contribution, or activation, of data vectors -% in the mean can be varied with the neighborhood function. This activation -% is given by matrix neigh. So, for each map unit the new weight vector is -% w(t+1) = sum(neigh(t)*S(t)) ./ sum(neigh(t)*A), -% wherw S sum of input vectors corresponding to wining neuron i0 , -% A is the number of sample corresponding to that wining neuron i0 -% and neigh is the neighborhood function.[1] -% -% Note: This function implemented in the same way of SOM toolbox Team[1] -% References -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-15 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function SOM=BatchTrainig(SOM,trSet,maxSim,sim) -radiusFin=SOM.radiusFin; -radiusIni=SOM.radiusIni; - -w=SOM.w; -% sample weights: each sample is weighted -weights=1; -% number of sets -nSet=size(trSet,1); -% the width of the neighbour function (linear). -radius = radiusFin + ((maxSim-(sim-1))/maxSim) * (radiusIni - radiusFin); -radius(radius==0) = eps; -knownData = ones(size(trSet,1),size(trSet,2)); -% winning neurons vector -i0 = zeros(1,nSet); -% loop over all data sets to find the winning neurons by measuring the min -% euclidean disttance -for i=1:nSet - inVec=repmat(trSet(i,:),size(w,1),1); - dist=VectorDistance(inVec,w); - [~, i0(i)]=min(dist); -end - -% Different neighborhood's functions -neigh = BatchNeighborFunction(SOM,radius); -% a partition matrix P with elements p_ij=1 if the i0(winning neuron) of data vector j is i. -p = sparse(i0,[1:nSet],weights,SOM.mUnits,nSet); -% neigh*sum of vectors corresponding to wining neuron i0 (in each Voronoi -% set) -s = neigh*(p*trSet); -% neigh*the number of vectors corresponding to wining neuron i0 (in Voronoi -% set) -a = neigh*(p*knownData); -nonZero = find(a > 0); -w(nonZero)=s(nonZero)./ a(nonZero); - - -% Save the w -SOM.w=w; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to run the batch training.The principle of updating weight vector +% step goes by replacing each map unit by the average of the data vectors that +% were in its neighborhood. The contribution, or activation, of data vectors +% in the mean can be varied with the neighborhood function. This activation +% is given by matrix neigh. So, for each map unit the new weight vector is +% w(t+1) = sum(neigh(t)*S(t)) ./ sum(neigh(t)*A), +% wherw S sum of input vectors corresponding to wining neuron i0 , +% A is the number of sample corresponding to that wining neuron i0 +% and neigh is the neighborhood function.[1] +% +% Note: This function implemented in the same way of SOM toolbox Team[1] +% References +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-15 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function SOM=BatchTrainig(SOM,trSet,maxSim,sim) +radiusFin=SOM.radiusFin; +radiusIni=SOM.radiusIni; + +w=SOM.w; +% sample weights: each sample is weighted +weights=1; +% number of sets +nSet=size(trSet,1); +% the width of the neighbour function (linear). +radius = radiusFin + ((maxSim-(sim-1))/maxSim) * (radiusIni - radiusFin); +radius(radius==0) = eps; +knownData = ones(size(trSet,1),size(trSet,2)); +% winning neurons vector +i0 = zeros(1,nSet); +% loop over all data sets to find the winning neurons by measuring the min +% euclidean disttance +for i=1:nSet + inVec=repmat(trSet(i,:),size(w,1),1); + dist=VectorDistance(inVec,w); + [~, i0(i)]=min(dist); +end + +% Different neighborhood's functions +neigh = BatchNeighborFunction(SOM,radius); +% a partition matrix P with elements p_ij=1 if the i0(winning neuron) of data vector j is i. +p = sparse(i0,[1:nSet],weights,SOM.mUnits,nSet); +% neigh*sum of vectors corresponding to wining neuron i0 (in each Voronoi +% set) +s = neigh*(p*trSet); +% neigh*the number of vectors corresponding to wining neuron i0 (in Voronoi +% set) +a = neigh*(p*knownData); +nonZero = find(a > 0); +w(nonZero)=s(nonZero)./ a(nonZero); + + +% Save the w +SOM.w=w; + diff --git a/PatRec/SOM/Batch Training/NeuronCoordinates.m b/PatRec/SOM/Batch Training/NeuronCoordinates.m index ed9ccdc..f59bc2c 100644 --- a/PatRec/SOM/Batch Training/NeuronCoordinates.m +++ b/PatRec/SOM/Batch Training/NeuronCoordinates.m @@ -1,51 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to create the map grid, it's used to create hexagonal and rectangular -% grid -% Note: The Hexagonal shape implemented in the same way of SOM toolbox Team[1] -% -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-15 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function coords=NeuronCoordinates(mSize,shape) - - -nNurons = prod(mSize); -xUnits=mSize(1); -yUnits=mSize(2); -coords = zeros(nNurons,2); - -if strcmp(shape,'hexa') -[coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); -coords(:,[1 2]) = fliplr(coords(:,[1 2])); -rowIndx = (cumsum(repmat([1],yUnits,1))-1)*xUnits; -for i=2:2:xUnits, - coords(i+rowIndx,1) = coords(i+rowIndx,1) + 0.5; -end - -elseif strcmp(shape,'rect') - [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to create the map grid, it's used to create hexagonal and rectangular +% grid +% Note: The Hexagonal shape implemented in the same way of SOM toolbox Team[1] +% +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-15 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function coords=NeuronCoordinates(mSize,shape) + + +nNurons = prod(mSize); +xUnits=mSize(1); +yUnits=mSize(2); +coords = zeros(nNurons,2); + +if strcmp(shape,'hexa') +[coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); +coords(:,[1 2]) = fliplr(coords(:,[1 2])); +rowIndx = (cumsum(repmat([1],yUnits,1))-1)*xUnits; +for i=2:2:xUnits, + coords(i+rowIndx,1) = coords(i+rowIndx,1) + 0.5; +end + +elseif strcmp(shape,'rect') + [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); +end + diff --git a/PatRec/SOM/Batch Training/NeuronDistances.m b/PatRec/SOM/Batch Training/NeuronDistances.m index 674bd3e..c95a194 100644 --- a/PatRec/SOM/Batch Training/NeuronDistances.m +++ b/PatRec/SOM/Batch Training/NeuronDistances.m @@ -1,41 +1,41 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to find the distance between each neuron inside the grid -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-15 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function dis=NeuronDistances(msize,coords) - -nNurons = prod(msize); -dis = zeros(nNurons,nNurons); - -% calculate distance from each location to each other location - -for i=1:(nNurons-1), - indx = [(i+1):nNurons]; - - dis(i,indx)=VectorDistance(coords(indx,:),coords(repmat([1]*i,nNurons-i,1),:))'; - -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to find the distance between each neuron inside the grid +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-15 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function dis=NeuronDistances(msize,coords) + +nNurons = prod(msize); +dis = zeros(nNurons,nNurons); + +% calculate distance from each location to each other location + +for i=1:(nNurons-1), + indx = [(i+1):nNurons]; + + dis(i,indx)=VectorDistance(coords(indx,:),coords(repmat([1]*i,nNurons-i,1),:))'; + +end + dis = dis + dis'; \ No newline at end of file diff --git a/PatRec/SOM/EvaluateSOM.m b/PatRec/SOM/EvaluateSOM.m index d1e9944..50f566a 100644 --- a/PatRec/SOM/EvaluateSOM.m +++ b/PatRec/SOM/EvaluateSOM.m @@ -1,124 +1,133 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function runs the selected training method then it's avoiding the overfitting -% learning by cross validation technique based on evaluation of RMSE. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [tempSOM accV]=EvaluateSOM(trSet, trOut, vSet, vOut,tType,algConf) - -graph2d = 1; % - -maxSim=50; %max simulation - passV=0; -sim=0; -SOM=InitSOM(trSet,trOut,algConf); % - -tempSOM=SOM; - - -if graph2d % 2D Graph - hfig = figure; - hold on - set(hfig, 'DoubleBuffer','on'); - axis([1 maxSim 0 .3]); - hbestplot = plot(1:maxSim+1,zeros(1,maxSim+1)); - htext = text(20,0.2,sprintf('Best RMSE: %4.4f',0.0)); - - xlabel('simulations'); - ylabel('rmse'); - hold off - drawnow; -end - - -while sim <= maxSim - % Training - sim = sim + 1; - %Stochastic Training - if strcmp(tType,'Stochastic') - SOM=StochasticTraining(trSet,SOM); - % Batch Trainig - elseif strcmp(tType,'Batch') - SOM=BatchTrainig(SOM,trSet,maxSim,sim); - % error - else - disp('Select Training Method.'); - errordlg('Select Training Method.'); - error('Select Training Method.'); - end - % add lable for each winnig neuron - neuroLabel=GetNeuronLabel(trSet,SOM); - % Save the neuron Label - SOM.neuroLabel=neuroLabel; - % test of the validation set - [apV,rmse(sim)]=FastTestSOM(SOM,vOut,vSet); - SOM.apV = apV; - SOM.fV = rmse(sim); - - % Save the best so far - if SOM.apV >= tempSOM.apV && SOM.fV <= tempSOM.fV - tempSOM = SOM; - end - - - if graph2d % 2D Graph - plotvector = get(hbestplot,'YData'); - plotvector(sim) = rmse(sim); - set(hbestplot,'YData',plotvector); - set(htext,'String',sprintf('Best RMSE: %4.4f',tempSOM.fV)); - - drawnow; - end - -end -if tempSOM.fV < 0.1 || tempSOM.apV > 95 - passV = 1; -end -[apV fV]=FullTestSOM(tempSOM,vOut,vSet); -accV=apV; -tempSOM.apV=apV; -tempSOM.fV=fV; -% Visualize U-matrix -if algConf.visualizeSOM - ShowUDMatrix(tempSOM) -end - -disp(['Simulations: ' num2str(sim)]); -disp(['General rmse: ' num2str(rmse(sim))]); -disp('RMES V: '); -disp(tempSOM.fV'); -disp('Acc V: '); -disp(tempSOM.apV'); - - -if passV - disp('%%%%%%%%%%% SOM training completed %%%%%%%%%%%%%'); - -else - - disp('%%%%%%%%%%% SOM training failed %%%%%%%%%%%%%'); -end - -close(hfig); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function runs the selected training method then it's avoiding the overfitting +% learning by cross validation technique based on evaluation of RMSE. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 2014-01-14 / Ali Fouad / Addition of "if statment" to reduce the training time +% 20xx-xx-xx / Author / Comment on update + +function [tempSOM accV]=EvaluateSOM(trSet, trOut, vSet, vOut,tType,algConf) + +graph2d = 1; % + +maxSim=50; %max simulation + passV=0; +sim=0; +SOM=InitSOM(trSet,trOut,algConf); % + +tempSOM=SOM; + + +if graph2d % 2D Graph + hfig = figure; + hold on + set(hfig, 'DoubleBuffer','on'); + axis([1 maxSim 0 .3]); + hbestplot = plot(1:maxSim+1,zeros(1,maxSim+1)); + htext = text(20,0.2,sprintf('Best RMSE: %4.4f',0.0)); + + xlabel('simulations'); + ylabel('rmse'); + hold off + drawnow; +end + + +while sim <= maxSim && passV == 0 + % Training + sim = sim + 1; + %Stochastic Training + if strcmp(tType,'Stochastic') + SOM=StochasticTraining(trSet,SOM); + % Batch Trainig + elseif strcmp(tType,'Batch') + SOM=BatchTrainig(SOM,trSet,maxSim,sim); + % error + else + disp('Select Training Method.'); + errordlg('Select Training Method.'); + error('Select Training Method.'); + end + % add lable for each winnig neuron + neuroLabel=GetNeuronLabel(trSet,SOM); + % Save the neuron Label + SOM.neuroLabel=neuroLabel; + % test of the validation set + [apV,rmse(sim)]=FastTestSOM(SOM,vOut,vSet); + SOM.apV = apV; + SOM.fV = rmse(sim); + + % Save the best so far + if SOM.apV >= tempSOM.apV && SOM.fV <= tempSOM.fV + tempSOM = SOM; + end + % terminate the training if there is no further convergence in the RMSE + if SOM.fV < 0.1 + if sim > 10 + if mean(rmse(sim-fix(sim/3):sim)) <= mean(rmse(sim-fix(sim/5):sim)) + + passV = 1; + end + end + end + + if graph2d % 2D Graph + plotvector = get(hbestplot,'YData'); + plotvector(sim) = rmse(sim); + set(hbestplot,'YData',plotvector); + set(htext,'String',sprintf('Best RMSE: %4.4f',tempSOM.fV)); + + drawnow; + end + +end +if tempSOM.fV < 0.1 || tempSOM.apV > 95 + passV = 1; +end +[apV fV]=FullTestSOM(tempSOM,vOut,vSet); +accV=apV; +tempSOM.apV=apV; +tempSOM.fV=fV; +% Visualize U-matrix +if algConf.visualizeSOM + ShowUDMatrix(tempSOM) +end + +disp(['Simulations: ' num2str(sim)]); +disp(['General rmse: ' num2str(rmse(sim))]); +disp('RMES V: '); +disp(tempSOM.fV'); +disp('Acc V: '); +disp(tempSOM.apV'); + + +if passV + disp('%%%%%%%%%%% SOM training completed %%%%%%%%%%%%%'); + +else + + disp('%%%%%%%%%%% SOM training failed %%%%%%%%%%%%%'); +end + +close(hfig); + diff --git a/PatRec/SOM/FastTestSOM.m b/PatRec/SOM/FastTestSOM.m index 297fee0..3ca2f24 100644 --- a/PatRec/SOM/FastTestSOM.m +++ b/PatRec/SOM/FastTestSOM.m @@ -1,95 +1,95 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function classify the validation sets. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [accP rmse]=FastTestSOM(SOM,vOut,x) - - - -neuroLabel=SOM.neuroLabel; -w=SOM.w; - -% The output vector. -somOut=zeros(size(vOut,1),size(vOut,2)); -% Number of data sets. -nSets=size(x,1); -% square Error. -sqErr=0; -% Number of movements. -nM=size(SOM.trOut,2); -% the Coordinate of all Neurons. -mapCoordinates=SOM.mapCoordinates; - -% loop over all validation data. -for i=1:nSets - % finding the location of winning neuron i0(x) on the map. - [i0 ,~]=FindClosest(w,x(i,:)); - % the Coordinate of the winning neuron i0. - i0Coord=mapCoordinates(i0,:); - - % loop over all coordinates of labeled neurons to find the closest . - for j=1:nM - % all labeled neurons of mov J - neuronLabelMovJ=neuroLabel(:,j); - % the index of labeled neurons movement J in neuron label matrix; - neuronLabelIndx{j}=neuronLabelMovJ(neuronLabelMovJ~=0); - % all Coordinate of all neurons movement j. - neurLabledCoords=mapCoordinates(neuronLabelIndx{j},:); - % finding the closest movement to neuron i0. - [neuronMovJ(1,j) ,d]=FindClosest(neurLabledCoords,i0Coord); - % save the min distans to movement j. - disVec(1,j)=d; - end - % min distance over all mavement neurons - minDis=min(disVec); - % finding the label movement. - [~,mov]=find(disVec==minDis); - % loop to search if the closeste neuron belong to another movement also or not. - for k=1:length(mov) - % the index of the closest neuron in neuron label matrix - neuronIndx(k)=neuronLabelIndx{mov(k)}(neuronMovJ(mov(k))); - % search that index in another movement - [~,winMov]=find(neuroLabel==neuronIndx(k)); - - outMov=unique(winMov); - - somOut(i,outMov)=1; - end - - - - % sum of square Error. - sqErr = sqErr + sum((somOut(i,:)-vOut(i,:)).^2); -end - -% error. -er = find(sum(abs(somOut-vOut),2) >= 1); -% accuracy. -accP = (1 - (length(er)/nSets)) * 100; -% root mean square error. -rmse = sqrt(sqErr/(nSets*nM)); - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function classify the validation sets. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [accP rmse]=FastTestSOM(SOM,vOut,x) + + + +neuroLabel=SOM.neuroLabel; +w=SOM.w; + +% The output vector. +somOut=zeros(size(vOut,1),size(vOut,2)); +% Number of data sets. +nSets=size(x,1); +% square Error. +sqErr=0; +% Number of movements. +nM=size(SOM.trOut,2); +% the Coordinate of all Neurons. +mapCoordinates=SOM.mapCoordinates; + +% loop over all validation data. +for i=1:nSets + % finding the location of winning neuron i0(x) on the map. + [i0 ,~]=FindClosest(w,x(i,:)); + % the Coordinate of the winning neuron i0. + i0Coord=mapCoordinates(i0,:); + + % loop over all coordinates of labeled neurons to find the closest . + for j=1:nM + % all labeled neurons of mov J + neuronLabelMovJ=neuroLabel(:,j); + % the index of labeled neurons movement J in neuron label matrix; + neuronLabelIndx{j}=neuronLabelMovJ(neuronLabelMovJ~=0); + % all Coordinate of all neurons movement j. + neurLabledCoords=mapCoordinates(neuronLabelIndx{j},:); + % finding the closest movement to neuron i0. + [neuronMovJ(1,j) ,d]=FindClosest(neurLabledCoords,i0Coord); + % save the min distans to movement j. + disVec(1,j)=d; + end + % min distance over all mavement neurons + minDis=min(disVec); + % finding the label movement. + [~,mov]=find(disVec==minDis); + % loop to search if the closeste neuron belong to another movement also or not. + for k=1:length(mov) + % the index of the closest neuron in neuron label matrix + neuronIndx(k)=neuronLabelIndx{mov(k)}(neuronMovJ(mov(k))); + % search that index in another movement + [~,winMov]=find(neuroLabel==neuronIndx(k)); + + outMov=unique(winMov); + + somOut(i,outMov)=1; + end + + + + % sum of square Error. + sqErr = sqErr + sum((somOut(i,:)-vOut(i,:)).^2); +end + +% error. +er = find(sum(abs(somOut-vOut),2) >= 1); +% accuracy. +accP = (1 - (length(er)/nSets)) * 100; +% root mean square error. +rmse = sqrt(sqErr/(nSets*nM)); + + + + diff --git a/PatRec/SOM/FullTestSOM.m b/PatRec/SOM/FullTestSOM.m index 9bc73f4..4b89fd9 100644 --- a/PatRec/SOM/FullTestSOM.m +++ b/PatRec/SOM/FullTestSOM.m @@ -1,105 +1,105 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function classify the validation sets and returns the RMSE and accuracy -% for each mov. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [accP rmse]=FullTestSOM(SOM,vOut,x) -neuroLabel=SOM.neuroLabel; -w=SOM.w; -mapCoordinates=SOM.mapCoordinates; -% Number of data sets. -nSets=size(x,1); - -% Number of movements. -nM=size(SOM.trOut,2); -nSetPerMov = nSets/nM ; % Number of sets per movement. -setIdx=1; -% loop over all validation data. -for i=1:nM - - % square Error. - sqErr=0; - cP=0; - - for j = 1 : nSetPerMov - somOut=zeros(1,size(vOut,2)); - % finding the location of winning neuron i0(x) on the map. - [i0 ~]=FindClosest(w,x(setIdx,:)); - % the Coordinate of the winning neuron i0. - i0Coord=mapCoordinates(i0,:); - % loop over all coordinates of labeled neuron to find the closest . - for k=1:nM - % all labeled neurons of mov k. - neuronLabelMovK=neuroLabel(:,k); - % the index of labeled neurons movement k in neuron label matrix; - neuronLabelIndx{k}=neuronLabelMovK(neuronLabelMovK~=0); - % all Coordinate of all neurons movement k. - neurLabledCoords=mapCoordinates(neuronLabelIndx{k},:); - - % finding the closest movement neuron i0. - [labeldNeur(1,k) ,d]=FindClosest(neurLabledCoords,i0Coord); - % save the min distans of movement k. - disVec(1,k)=d; - end - - % min distance over all mavement neurons - minDis=min(disVec); - % finding the label movement . - [~,mov]=find(disVec==minDis); - - % loop to search if the closeste neuron belong to another movement also or not. - for l=1:length(mov) - % the index of the closest neuron in neuron label matrix - neuronIndx(l)=neuronLabelIndx{mov(l)}(labeldNeur(mov(l))); - % search that index in another movement - [~,winMov]=find(neuroLabel==neuronIndx(l)); - outMov=unique(winMov); - somOut(1,outMov)=1; - end - - %correct Movement - - cM= length(find(sum(abs(somOut-vOut(setIdx,:)),2) >= 1)); - if cM==0 - correct=1; - else - correct=0; - end - cP = cP + correct; - % sum of square Error. - sqErr = sqErr + sum((somOut-vOut(setIdx,:)).^2); - setIdx=setIdx+1; - end - accP(i) = cP / nSetPerMov; - rmse(i) = sqrt(sqErr/(nSetPerMov*nM)); - -end -accP(end + 1) = mean(accP); -rmse(end + 1) = mean(rmse); - - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function classify the validation sets and returns the RMSE and accuracy +% for each mov. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [accP rmse]=FullTestSOM(SOM,vOut,x) +neuroLabel=SOM.neuroLabel; +w=SOM.w; +mapCoordinates=SOM.mapCoordinates; +% Number of data sets. +nSets=size(x,1); + +% Number of movements. +nM=size(SOM.trOut,2); +nSetPerMov = nSets/nM ; % Number of sets per movement. +setIdx=1; +% loop over all validation data. +for i=1:nM + + % square Error. + sqErr=0; + cP=0; + + for j = 1 : nSetPerMov + somOut=zeros(1,size(vOut,2)); + % finding the location of winning neuron i0(x) on the map. + [i0 ~]=FindClosest(w,x(setIdx,:)); + % the Coordinate of the winning neuron i0. + i0Coord=mapCoordinates(i0,:); + % loop over all coordinates of labeled neuron to find the closest . + for k=1:nM + % all labeled neurons of mov k. + neuronLabelMovK=neuroLabel(:,k); + % the index of labeled neurons movement k in neuron label matrix; + neuronLabelIndx{k}=neuronLabelMovK(neuronLabelMovK~=0); + % all Coordinate of all neurons movement k. + neurLabledCoords=mapCoordinates(neuronLabelIndx{k},:); + + % finding the closest movement neuron i0. + [labeldNeur(1,k) ,d]=FindClosest(neurLabledCoords,i0Coord); + % save the min distans of movement k. + disVec(1,k)=d; + end + + % min distance over all mavement neurons + minDis=min(disVec); + % finding the label movement . + [~,mov]=find(disVec==minDis); + + % loop to search if the closeste neuron belong to another movement also or not. + for l=1:length(mov) + % the index of the closest neuron in neuron label matrix + neuronIndx(l)=neuronLabelIndx{mov(l)}(labeldNeur(mov(l))); + % search that index in another movement + [~,winMov]=find(neuroLabel==neuronIndx(l)); + outMov=unique(winMov); + somOut(1,outMov)=1; + end + + %correct Movement + + cM= length(find(sum(abs(somOut-vOut(setIdx,:)),2) >= 1)); + if cM==0 + correct=1; + else + correct=0; + end + cP = cP + correct; + % sum of square Error. + sqErr = sqErr + sum((somOut-vOut(setIdx,:)).^2); + setIdx=setIdx+1; + end + accP(i) = cP / nSetPerMov; + rmse(i) = sqrt(sqErr/(nSetPerMov*nM)); + +end +accP(end + 1) = mean(accP); +rmse(end + 1) = mean(rmse); + + + + + + diff --git a/PatRec/SOM/GetNeuronLabel.m b/PatRec/SOM/GetNeuronLabel.m index 14d34b4..18dfbf4 100644 --- a/PatRec/SOM/GetNeuronLabel.m +++ b/PatRec/SOM/GetNeuronLabel.m @@ -1,42 +1,42 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function is set the class label of the all winning neuron and it returns -% culmuns of the wining neuron for each mov. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function neurLab=GetNeuronLabel(trSet,SOM) -trOut=SOM.trOut; -w=SOM.w; -for i=1:size(trSet,1); - - x=trSet(i,:); - % Index of closest neuron - [indx ,~]=FindClosest(w,x); - % finding the class lable of x - [~ ,movLabel] =find(trOut(i,:)==1); - % adding this lable to the winning neuron - i0(i,movLabel)=indx; - -end - -neurLab=i0; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function is set the class label of the all winning neuron and it returns +% culmuns of the wining neuron for each mov. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function neurLab=GetNeuronLabel(trSet,SOM) +trOut=SOM.trOut; +w=SOM.w; +for i=1:size(trSet,1); + + x=trSet(i,:); + % Index of closest neuron + [indx ,~]=FindClosest(w,x); + % finding the class lable of x + [~ ,movLabel] =find(trOut(i,:)==1); + % adding this lable to the winning neuron + i0(i,movLabel)=indx; + +end + +neurLab=i0; diff --git a/PatRec/SOM/InitSOM.m b/PatRec/SOM/InitSOM.m index 289e877..15d9c38 100644 --- a/PatRec/SOM/InitSOM.m +++ b/PatRec/SOM/InitSOM.m @@ -1,119 +1,119 @@ - -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to initialize the Artificial Neural Network (SOM). -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function SOM=InitSOM(trSet,trOut,algConf) - - - -switch algConf.shape - case 'Hexagonal Grid' - shape= 'hexa'; - case 'Rectangular Grid' - shape='rect'; - case 'Select Shape.' - - disp('%%%%%%%%%%Select Shape.%%%%%%%%%%%'); - errordlg('Select Shape.'); - error('Select Shape.'); -end -switch algConf.neighFunc - case 'Bubble' - neigh='bubb'; - case 'Gaussian' - neigh='gauss'; - case 'Cutgaussian' - neigh='cutGauss'; - case 'Triangular' - neigh='trai'; - case 'Butterworth' - neigh='butter'; - case 'Select Neighbor Function.' - disp('%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%%'); - errordlg('Select Neighbor Function.'); - error('%%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%'); - -end - - - -xUnits=ceil( (size(trSet,1)^0.5)*1.5); % the grid (map) width -yUnits=ceil( (size(trSet,1)^0.5)*1.5); % the grid (map) length -etaIni=.5; %initial learning rate parameter - -sigmaIni=ceil(xUnits/2); % the initial width of the topologic neighborhood function - -tow2=3000; % time constant's decay of the learning parameter - -tow1=tow2/log(sigmaIni); % time constant's decay of the initial width of the topologic neighborhood function - - - -mSize=[xUnits yUnits]; % the grid (map) size - - -mUnits=prod(mSize); % the total number of neuron - -mapCoordinates=NeuronCoordinates(mSize,shape); % the coordinates of the neuron in the grid and that depends on the grid's shape - - -dDim=size(trSet,2); % number of data variable - -w=RandomWeights(xUnits*yUnits,dDim,trSet); % initial weigth for each neuron in the grid where each neuron has the same number of data variable -% Unit Distance -neuronDist = NeuronDistances(mSize,mapCoordinates); - -%% - -% those parameters are for the batch training - -%mask = ones(dDim,1); - -radiusIni =max(1,ceil(max(mSize)/2)); % the initial width of the topologic neighborhood function -radiusFin=.01; % the final width of the topologic neighborhood function - -%% -SOM.t=1; -SOM.sigmaIni=sigmaIni; -SOM.tow1=tow1; -SOM.etaIni=etaIni; -SOM.tow2=tow2; -SOM.w=w; -SOM.mapCoordinates=mapCoordinates; -SOM.apV=0; -SOM.fV=Inf; -SOM.mSize=mSize; -SOM.trOut=trOut; -SOM.mUnits=mUnits; -SOM.radiusIni=radiusIni; -SOM.radiusFin=radiusFin; -SOM.neuronDist=neuronDist; -%SOM.mask=mask; -SOM.shape=shape; -SOM.neighFunc=neigh; - - - - + +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to initialize the Artificial Neural Network (SOM). +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function SOM=InitSOM(trSet,trOut,algConf) + + + +switch algConf.shape + case 'Hexagonal Grid' + shape= 'hexa'; + case 'Rectangular Grid' + shape='rect'; + case 'Select Shape.' + + disp('%%%%%%%%%%Select Shape.%%%%%%%%%%%'); + errordlg('Select Shape.'); + error('Select Shape.'); +end +switch algConf.neighFunc + case 'Bubble' + neigh='bubb'; + case 'Gaussian' + neigh='gauss'; + case 'Cutgaussian' + neigh='cutGauss'; + case 'Triangular' + neigh='trai'; + case 'Butterworth' + neigh='butter'; + case 'Select Neighbor Function.' + disp('%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%%'); + errordlg('Select Neighbor Function.'); + error('%%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%'); + +end + + + +xUnits=ceil( (size(trSet,1)^0.5)*1.5); % the grid (map) width +yUnits=ceil( (size(trSet,1)^0.5)*1.5); % the grid (map) length +etaIni=.5; %initial learning rate parameter + +sigmaIni=ceil(xUnits/2); % the initial width of the topologic neighborhood function + +tow2=3000; % time constant's decay of the learning parameter + +tow1=tow2/log(sigmaIni); % time constant's decay of the initial width of the topologic neighborhood function + + + +mSize=[xUnits yUnits]; % the grid (map) size + + +mUnits=prod(mSize); % the total number of neuron + +mapCoordinates=NeuronCoordinates(mSize,shape); % the coordinates of the neuron in the grid and that depends on the grid's shape + + +dDim=size(trSet,2); % number of data variable + +w=RandomWeights(xUnits*yUnits,dDim,trSet); % initial weigth for each neuron in the grid where each neuron has the same number of data variable +% Unit Distance +neuronDist = NeuronDistances(mSize,mapCoordinates); + +%% + +% those parameters are for the batch training + +%mask = ones(dDim,1); + +radiusIni =max(1,ceil(max(mSize)/2)); % the initial width of the topologic neighborhood function +radiusFin=.01; % the final width of the topologic neighborhood function + +%% +SOM.t=1; +SOM.sigmaIni=sigmaIni; +SOM.tow1=tow1; +SOM.etaIni=etaIni; +SOM.tow2=tow2; +SOM.w=w; +SOM.mapCoordinates=mapCoordinates; +SOM.apV=0; +SOM.fV=Inf; +SOM.mSize=mSize; +SOM.trOut=trOut; +SOM.mUnits=mUnits; +SOM.radiusIni=radiusIni; +SOM.radiusFin=radiusFin; +SOM.neuronDist=neuronDist; +%SOM.mask=mask; +SOM.shape=shape; +SOM.neighFunc=neigh; + + + + diff --git a/PatRec/SOM/RandomWeights.m b/PatRec/SOM/RandomWeights.m index 4dda51a..38d0502 100644 --- a/PatRec/SOM/RandomWeights.m +++ b/PatRec/SOM/RandomWeights.m @@ -1,32 +1,32 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to initialize the W matrix randomly in the uniform disterbution -% in [max(w) ,min(w)] -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function weights=RandomWeights(nNeurons,nInputs,inputData) -minW=min(min(inputData)); -maxW=max(max(inputData)); - -weights=minW+(maxW-minW).*rand(nNeurons,nInputs); -% weights=rand(nNeurons,nInputs); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to initialize the W matrix randomly in the uniform disterbution +% in [max(w) ,min(w)] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function weights=RandomWeights(nNeurons,nInputs,inputData) +minW=min(min(inputData)); +maxW=max(max(inputData)); + +weights=minW+(maxW-minW).*rand(nNeurons,nInputs); +% weights=rand(nNeurons,nInputs); diff --git a/PatRec/SOM/SOMTest.m b/PatRec/SOM/SOMTest.m index e541c8d..55e445a 100644 --- a/PatRec/SOM/SOMTest.m +++ b/PatRec/SOM/SOMTest.m @@ -1,96 +1,96 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to classifies the testing sets. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [outMov disVec]=SOMTest(patRecTrained,x) -% Check if there is any NaN value -tKnownNaN = ~isnan(x); -if ~isempty(find(tKnownNaN==0, 1)) - disp('You have NaN value in Testing sets'); - errordlg('You have NaN value in Testing sets'); - error('You have Complex number in Testing sets'); -end -% Check if there is any Inf value -tKnownInf = ~isinf(x); -if ~isempty(find(tKnownInf==0, 1)) - disp('You have Inf value in Testing sets'); - errordlg('You have Inf value in Testing sets'); - error('You have Complex number in Testing sets'); -end -% Check if there is any Complex number in Testing sets -tKnownComplex = ~isreal(x); -if ~isempty(find(tKnownComplex==1, 1)) - disp('You have Complex number in Testing sets'); - errordlg('You have Complex number in Testing sets'); - error('You have Complex number in Testing sets'); -end - - -w=patRecTrained.SOM.w; -nMov=size(patRecTrained.SOM.trOut,2); -somOut=zeros(1,nMov); - -neuroLabel=patRecTrained.SOM.neuroLabel; - - -% the Coordinate of all Neurons. -mapCoordinates=patRecTrained.SOM.mapCoordinates; - -% finding the location of winning neuron i0(x) on the map. -[i0 ~]=FindClosest(w,x); -% the Coordinate of the winning neuron i0. -i0Coord=mapCoordinates(i0,:); -% loop over all coordinates of labeled neurons to find the closest to i0(x). -for i=1:nMov - % all labeled neurons of mov I - neuronLabelMovI=neuroLabel(:,i); - % the index of labeled neurons movement I in neuron label matrix; - neuronLabelIndx{i}=neuronLabelMovI(neuronLabelMovI~=0); - % all Coordinate of all neurons movement I. - neurLabledCoords=mapCoordinates(neuronLabelIndx{i},:); - - % finding the closest movement to neuron i0. - [neuronMovI(1,i) ,d]=FindClosest(neurLabledCoords,i0Coord); - % save the min distans to movement I. - disVec(1,i)=d; -end -% min distance over all mavement neurons -minDis=min(disVec); -% finding the label movement. -[~,mov]=find(disVec==minDis); -% loop to search if the closeste neuron belong to another movement also or not. -for j=1:length(mov) - % the index of the closest neuron in neuron label matrix - neuronIndx(j)=neuronLabelIndx{mov(j)}(neuronMovI(mov(j))); - % search that index in another movement - [~,winMov]=find(neuroLabel==neuronIndx(j)); - - - somOut(1,unique(winMov))=1; -end -[~,outMov]=find(somOut==1); -% set the outMov has the highest prediction to let that works with different topologies. -disVec(disVec==0)=eps; -disVec=1./disVec; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to classifies the testing sets. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [outMov disVec]=SOMTest(patRecTrained,x) +% Check if there is any NaN value +tKnownNaN = ~isnan(x); +if ~isempty(find(tKnownNaN==0, 1)) + disp('You have NaN value in Testing sets'); + errordlg('You have NaN value in Testing sets'); + error('You have Complex number in Testing sets'); +end +% Check if there is any Inf value +tKnownInf = ~isinf(x); +if ~isempty(find(tKnownInf==0, 1)) + disp('You have Inf value in Testing sets'); + errordlg('You have Inf value in Testing sets'); + error('You have Complex number in Testing sets'); +end +% Check if there is any Complex number in Testing sets +tKnownComplex = ~isreal(x); +if ~isempty(find(tKnownComplex==1, 1)) + disp('You have Complex number in Testing sets'); + errordlg('You have Complex number in Testing sets'); + error('You have Complex number in Testing sets'); +end + + +w=patRecTrained.SOM.w; +nMov=size(patRecTrained.SOM.trOut,2); +somOut=zeros(1,nMov); + +neuroLabel=patRecTrained.SOM.neuroLabel; + + +% the Coordinate of all Neurons. +mapCoordinates=patRecTrained.SOM.mapCoordinates; + +% finding the location of winning neuron i0(x) on the map. +[i0 ~]=FindClosest(w,x); +% the Coordinate of the winning neuron i0. +i0Coord=mapCoordinates(i0,:); +% loop over all coordinates of labeled neurons to find the closest to i0(x). +for i=1:nMov + % all labeled neurons of mov I + neuronLabelMovI=neuroLabel(:,i); + % the index of labeled neurons movement I in neuron label matrix; + neuronLabelIndx{i}=neuronLabelMovI(neuronLabelMovI~=0); + % all Coordinate of all neurons movement I. + neurLabledCoords=mapCoordinates(neuronLabelIndx{i},:); + + % finding the closest movement to neuron i0. + [neuronMovI(1,i) ,d]=FindClosest(neurLabledCoords,i0Coord); + % save the min distans to movement I. + disVec(1,i)=d; +end +% min distance over all mavement neurons +minDis=min(disVec); +% finding the label movement. +[~,mov]=find(disVec==minDis); +% loop to search if the closeste neuron belong to another movement also or not. +for j=1:length(mov) + % the index of the closest neuron in neuron label matrix + neuronIndx(j)=neuronLabelIndx{mov(j)}(neuronMovI(mov(j))); + % search that index in another movement + [~,winMov]=find(neuroLabel==neuronIndx(j)); + + + somOut(1,unique(winMov))=1; +end +[~,outMov]=find(somOut==1); +% set the outMov has the highest prediction to let that works with different topologies. +disVec(disVec==0)=eps; +disVec=1./disVec; + diff --git a/PatRec/SOM/SOM_Mapping.m b/PatRec/SOM/SOM_Mapping.m index 3c1b28b..fd39baf 100644 --- a/PatRec/SOM/SOM_Mapping.m +++ b/PatRec/SOM/SOM_Mapping.m @@ -1,77 +1,77 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function check if there is any NaN or Inf value in training and -% validation sets then it run the training method of SOM. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function [out accV]=SOM_Mapping(trSets, trOuts, vSets, vOuts, tType,algConf) -% Check if there is any NaN value in training sets -trKnownNaN = ~isnan(trSets); -if ~isempty(find(trKnownNaN==0, 1)) - disp('You have NaN value in Training sets'); - errordlg('You have NaN value in Training sets'); - error('You have NaN value in Training sets'); - -end -% Check if there is any Inf value in training sets -trKnownInf = ~isinf(trSets); -if ~isempty(find(trKnownInf==0, 1)) - disp('You have Inf value in Training sets'); - errordlg('You have Inf value in Training sets'); - error('You have Inf value in Training sets'); -end -% Check if there is any Complex number in training sets -trKnownComplex = ~isreal(trSets); -if ~isempty(find(trKnownComplex==1, 1)) - disp('You have Complex number in Training sets'); - errordlg('You have Complex number in Training sets'); - error('You have Complex number in Training sets'); -end -% Check if there is any NaN value in validation sets -vKnownNaN = ~isnan(vSets); -if ~isempty(find(vKnownNaN==0, 1)) - disp('You have NaN value in Validation sets'); - errordlg('You have NaN value in Validation sets'); - error('You have NaN value in Validation sets'); -end -% Check if there is any Inf value in validation sets -vKnownInf = ~isinf(vSets); -if ~isempty(find(vKnownInf==0, 1)) - disp('You have Inf value in Validation sets'); - errordlg('You have Inf value in Validation sets'); - error('You have Inf value in Validation sets'); -end -% Check if there is any Complex number in Validation sets -vKnownComplex = ~isreal(vSets); -if ~isempty(find(vKnownComplex==1, 1)) - disp('You have Complex number in Validation sets'); - errordlg('You have Complex number in Validation sets'); - error('You have Complex number in Validation sets'); -end - -[out accV]=EvaluateSOM(trSets, trOuts, vSets, vOuts,tType,algConf); - -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function check if there is any NaN or Inf value in training and +% validation sets then it run the training method of SOM. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function [out accV]=SOM_Mapping(trSets, trOuts, vSets, vOuts, tType,algConf) +% Check if there is any NaN value in training sets +trKnownNaN = ~isnan(trSets); +if ~isempty(find(trKnownNaN==0, 1)) + disp('You have NaN value in Training sets'); + errordlg('You have NaN value in Training sets'); + error('You have NaN value in Training sets'); + +end +% Check if there is any Inf value in training sets +trKnownInf = ~isinf(trSets); +if ~isempty(find(trKnownInf==0, 1)) + disp('You have Inf value in Training sets'); + errordlg('You have Inf value in Training sets'); + error('You have Inf value in Training sets'); +end +% Check if there is any Complex number in training sets +trKnownComplex = ~isreal(trSets); +if ~isempty(find(trKnownComplex==1, 1)) + disp('You have Complex number in Training sets'); + errordlg('You have Complex number in Training sets'); + error('You have Complex number in Training sets'); +end +% Check if there is any NaN value in validation sets +vKnownNaN = ~isnan(vSets); +if ~isempty(find(vKnownNaN==0, 1)) + disp('You have NaN value in Validation sets'); + errordlg('You have NaN value in Validation sets'); + error('You have NaN value in Validation sets'); +end +% Check if there is any Inf value in validation sets +vKnownInf = ~isinf(vSets); +if ~isempty(find(vKnownInf==0, 1)) + disp('You have Inf value in Validation sets'); + errordlg('You have Inf value in Validation sets'); + error('You have Inf value in Validation sets'); +end +% Check if there is any Complex number in Validation sets +vKnownComplex = ~isreal(vSets); +if ~isempty(find(vKnownComplex==1, 1)) + disp('You have Complex number in Validation sets'); + errordlg('You have Complex number in Validation sets'); + error('You have Complex number in Validation sets'); +end + +[out accV]=EvaluateSOM(trSets, trOuts, vSets, vOuts,tType,algConf); + +end + + diff --git a/PatRec/SOM/Stochastic Training/Eta.m b/PatRec/SOM/Stochastic Training/Eta.m index 59b5eb0..cf59bca 100644 --- a/PatRec/SOM/Stochastic Training/Eta.m +++ b/PatRec/SOM/Stochastic Training/Eta.m @@ -1,30 +1,30 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to calculate learning rate parameter -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function eta=Eta(t,etaIni,tow2) -eta=etaIni.*exp(-t./tow2); - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to calculate learning rate parameter +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function eta=Eta(t,etaIni,tow2) +eta=etaIni.*exp(-t./tow2); + + + diff --git a/PatRec/SOM/Stochastic Training/FindClosest.m b/PatRec/SOM/Stochastic Training/FindClosest.m index 765587b..aaa60bd 100644 --- a/PatRec/SOM/Stochastic Training/FindClosest.m +++ b/PatRec/SOM/Stochastic Training/FindClosest.m @@ -1,35 +1,35 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to find the closest neuron -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [closestIdx minDist]=FindClosest(w,inpVec) -nNeuron=size(w,1); -%Repeat the input vector to avoid the iterations -inpVec = repmat(inpVec, nNeuron, 1); -%The euclidean distance between inpVec and all neurons -d=sqrt(sum((inpVec-w).^2, 2)); -%find the minimum distance and the index -[minDist closestIdx]=min(d); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to find the closest neuron +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [closestIdx minDist]=FindClosest(w,inpVec) +nNeuron=size(w,1); +%Repeat the input vector to avoid the iterations +inpVec = repmat(inpVec, nNeuron, 1); +%The euclidean distance between inpVec and all neurons +d=sqrt(sum((inpVec-w).^2, 2)); +%find the minimum distance and the index +[minDist closestIdx]=min(d); + + diff --git a/PatRec/SOM/Stochastic Training/Sigma.m b/PatRec/SOM/Stochastic Training/Sigma.m index 5643241..e92a4ca 100644 --- a/PatRec/SOM/Stochastic Training/Sigma.m +++ b/PatRec/SOM/Stochastic Training/Sigma.m @@ -1,28 +1,28 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to calculate the width of topologic neighborhood function -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function sigma=Sigma(t,sigmaIni,tow1) - sigma=sigmaIni.*exp(-t./tow1); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to calculate the width of topologic neighborhood function +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function sigma=Sigma(t,sigmaIni,tow1) + sigma=sigmaIni.*exp(-t./tow1); + diff --git a/PatRec/SOM/Stochastic Training/StochasticNeighborFunction.m b/PatRec/SOM/Stochastic Training/StochasticNeighborFunction.m index f0cba28..563be2e 100644 --- a/PatRec/SOM/Stochastic Training/StochasticNeighborFunction.m +++ b/PatRec/SOM/Stochastic Training/StochasticNeighborFunction.m @@ -1,53 +1,53 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function for different Neighbor Function Bubble,Gaussian ,Cut Gaussian, -% Epanechikov and Butter worth 2nd order. -% -% Note: Bubble,Gaussian ,Cut Gaussian and Epanechikov implemented according to -% SOM toolbox Team[1] -% -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-07 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function neigh=StochasticNeighborFunction(SOM,sigma,i0) - -neighborFunction=SOM.neighFunc; -% The euclidean distance Matrix between the coordinates of the winning neuron and all -% others -neuronDist=SOM.neuronDist; - - -switch neighborFunction, - case 'bubb' - %neuronDist(neuronDist>sigma)=0; - neigh=(neuronDist(:,i0)<=sigma); - case 'gauss' - neigh = exp(-(neuronDist(:,i0).^2)./(2*sigma^2)); - case 'cutGauss' - neigh = exp(-(neuronDist(:,i0).^2)./(2*sigma^2)) .* (neuronDist(:,i0)<=sigma); - case 'trai' - neigh = (1-neuronDist(:,i0)./sigma) .* (neuronDist(:,i0)<=sigma); - case 'butter' - neigh =1./(1+(neuronDist(:,i0)./sigma).^4); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function for different Neighbor Function Bubble,Gaussian ,Cut Gaussian, +% Epanechikov and Butter worth 2nd order. +% +% Note: Bubble,Gaussian ,Cut Gaussian and Epanechikov implemented according to +% SOM toolbox Team[1] +% +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-07 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function neigh=StochasticNeighborFunction(SOM,sigma,i0) + +neighborFunction=SOM.neighFunc; +% The euclidean distance Matrix between the coordinates of the winning neuron and all +% others +neuronDist=SOM.neuronDist; + + +switch neighborFunction, + case 'bubb' + %neuronDist(neuronDist>sigma)=0; + neigh=(neuronDist(:,i0)<=sigma); + case 'gauss' + neigh = exp(-(neuronDist(:,i0).^2)./(2*sigma^2)); + case 'cutGauss' + neigh = exp(-(neuronDist(:,i0).^2)./(2*sigma^2)) .* (neuronDist(:,i0)<=sigma); + case 'trai' + neigh = (1-neuronDist(:,i0)./sigma) .* (neuronDist(:,i0)<=sigma); + case 'butter' + neigh =1./(1+(neuronDist(:,i0)./sigma).^4); end \ No newline at end of file diff --git a/PatRec/SOM/Stochastic Training/StochasticTraining.m b/PatRec/SOM/Stochastic Training/StochasticTraining.m index 41cf0e7..3741307 100644 --- a/PatRec/SOM/Stochastic Training/StochasticTraining.m +++ b/PatRec/SOM/Stochastic Training/StochasticTraining.m @@ -1,58 +1,60 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to run the Stochastic Training -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function SOM=StochasticTraining(trSet,SOM) - -t=SOM.t; -% width of neighbour function. -sigmaIni=SOM.sigmaIni; -% constant's decay of sigma -tow1=SOM.tow1; -% learning rate parameter -etaIni=SOM.etaIni; -% constant's decay of eta -tow2=SOM.tow2; -%the weight matrix -w=SOM.w; -% Draw random samples -p=randperm(length(trSet(:,1))); -for i=1:size(trSet,1) - % width of neighbour function at time t. - sigmaT=Sigma(t,sigmaIni,tow1); - sigmaT(sigmaT==0)=eps; - % learning rate parameter at time t. - eta= Eta(t,etaIni,tow2); - %Finding the winning neuron (min euclidean distance) - [i0 ~]=FindClosest(w,trSet(p(i),:)); - %Updating the weights - w=UpdateWeights(i0,trSet(p(i),:),w,eta,sigmaT,SOM); - % update the iteration - t=t+1; - SOM.t=t; -end - -%Save the w -SOM.w=w; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to run the Stochastic Training +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 2014-01-14 / Ali Fouad / Updating of sampling step +% 20xx-xx-xx / Author / Comment on update + +function SOM=StochasticTraining(trSet,SOM) + +t=SOM.t; +% width of neighbour function. +sigmaIni=SOM.sigmaIni; +% constant's decay of sigma +tow1=SOM.tow1; +% learning rate parameter +etaIni=SOM.etaIni; +% constant's decay of eta +tow2=SOM.tow2; +%the weight matrix +w=SOM.w; +% Draw random samples +nTrPattern=fix(.7*length(trSet(:,1))); +p=randperm(length(trSet(:,1)),nTrPattern); +for i=1:nTrPattern + % width of neighbour function at time t. + sigmaT=Sigma(t,sigmaIni,tow1); + sigmaT(sigmaT==0)=eps; + % learning rate parameter at time t. + eta= Eta(t,etaIni,tow2); + %Finding the winning neuron (min euclidean distance) + [i0 ~]=FindClosest(w,trSet(p(i),:)); + %Updating the weights + w=UpdateWeights(i0,trSet(p(i),:),w,eta,sigmaT,SOM); + % update the iteration + t=t+1; + SOM.t=t; +end + +%Save the w +SOM.w=w; + diff --git a/PatRec/SOM/Stochastic Training/UpdateWeights.m b/PatRec/SOM/Stochastic Training/UpdateWeights.m index 6348793..d0cd0ec 100644 --- a/PatRec/SOM/Stochastic Training/UpdateWeights.m +++ b/PatRec/SOM/Stochastic Training/UpdateWeights.m @@ -1,51 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to update the Weight matrix -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function newW=UpdateWeights(i0,x,w,eta,sigma,SOM) - -dim=size(w,2); -% nummber of neurons. -nNeurons=size(w,1); -% Repeat the input vector to avoid the iterations -inVecMat=repmat(x,nNeurons,1); - -% Different neighborhood's functions -neigh=StochasticNeighborFunction(SOM,sigma,i0); - -% Repeat the colum of neighborhood function to avoid the loop -neigh=repmat(neigh,1,dim); -% the learning rate should not be less than 0.02 -if eta<0.02 - eta=0.02; -end -% each ray of neighborhood function * the learning rate -neigh=neigh.*eta; - -deltaW=(inVecMat-w).*neigh; - - -newW=w+deltaW; - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to update the Weight matrix +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function newW=UpdateWeights(i0,x,w,eta,sigma,SOM) + +dim=size(w,2); +% nummber of neurons. +nNeurons=size(w,1); +% Repeat the input vector to avoid the iterations +inVecMat=repmat(x,nNeurons,1); + +% Different neighborhood's functions +neigh=StochasticNeighborFunction(SOM,sigma,i0); + +% Repeat the colum of neighborhood function to avoid the loop +neigh=repmat(neigh,1,dim); +% the learning rate should not be less than 0.02 +if eta<0.02 + eta=0.02; +end +% each ray of neighborhood function * the learning rate +neigh=neigh.*eta; + +deltaW=(inVecMat-w).*neigh; + + +newW=w+deltaW; + + diff --git a/PatRec/SOM/VectorDistance.m b/PatRec/SOM/VectorDistance.m index f028dd1..5cde4be 100644 --- a/PatRec/SOM/VectorDistance.m +++ b/PatRec/SOM/VectorDistance.m @@ -1,27 +1,27 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function to find the euclidean distance -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function dist=VectorDistance(x,y) +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function to find the euclidean distance +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function dist=VectorDistance(x,y) dist=sqrt(sum((x-y).^2, 2)); \ No newline at end of file diff --git a/PatRec/SOM/Visiulaize U-matrix/CreateUDMat.m b/PatRec/SOM/Visiulaize U-matrix/CreateUDMat.m index e7c67d6..1f916d1 100644 --- a/PatRec/SOM/Visiulaize U-matrix/CreateUDMat.m +++ b/PatRec/SOM/Visiulaize U-matrix/CreateUDMat.m @@ -1,92 +1,92 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function returns the distance between each two neighbors neuron -% in the map which is represente the intermediate spot between thos two -% neighbors in U-matrix. -% Note: The implementation of this function done corresponds to SOM Toolbox -% Team: -% Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function UDMat=CreateUDMat(w,mSize,shape) - - -dim=size(w,2); - -y = mSize(2); -x = mSize(1); -w = reshape(w,[y x dim]); - -UDMat = zeros(2 * x - 1, 2 * y - 1); - - -if strcmp(shape, 'rect'), % rectangular grid - - for i=1:y - for j=1:x, - % horizontal - if j1, - disZ = (w(i,j,:) - w(i+1,j-1,:)).^2; - UDMat(2*i,2*j-2) = sqrt(sum(disZ(:))); - end - end - end - end - -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function returns the distance between each two neighbors neuron +% in the map which is represente the intermediate spot between thos two +% neighbors in U-matrix. +% Note: The implementation of this function done corresponds to SOM Toolbox +% Team: +% Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function UDMat=CreateUDMat(w,mSize,shape) + + +dim=size(w,2); + +y = mSize(2); +x = mSize(1); +w = reshape(w,[y x dim]); + +UDMat = zeros(2 * x - 1, 2 * y - 1); + + +if strcmp(shape, 'rect'), % rectangular grid + + for i=1:y + for j=1:x, + % horizontal + if j1, + disZ = (w(i,j,:) - w(i+1,j-1,:)).^2; + UDMat(2*i,2*j-2) = sqrt(sum(disZ(:))); + end + end + end + end + +end + diff --git a/PatRec/SOM/Visiulaize U-matrix/GetColor.m b/PatRec/SOM/Visiulaize U-matrix/GetColor.m index c7e6243..eef0a03 100644 --- a/PatRec/SOM/Visiulaize U-matrix/GetColor.m +++ b/PatRec/SOM/Visiulaize U-matrix/GetColor.m @@ -1,100 +1,100 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to generate different color and it return if there is more than -% mov. contribute in one and more neurons also it will return the spot -% size of the neuron if that more than mov. contribute in one and more neurons. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [color indx sizeSpotMat mixColorMat]=GetColor(SOM) - -nMov=size(SOM.neuroLabel,2); - -indx=[]; -% the size of the neuron spot the default size is .5 -sizeNeur=ones(SOM.mUnits,1).*.5; - -% in case of Mix Mov (mixcolor). -mixColor=zeros(SOM.mUnits,size(SOM.neuroLabel,2)); -for i=1:size(SOM.neuroLabel,1) - - neuron=SOM.neuroLabel(i,:); - neuron=neuron(neuron~=0); - neuron=unique(neuron); - % check the neuron i belong to which mov.! - [~, c]=find(SOM.neuroLabel==neuron); - c=unique(c'); - - ind=unique(SOM.neuroLabel(i,c)); - ind=ind(ind~=0); - % set the mov. index of neuron i equal to 1. - mixColor(ind,c)=1; - % set the spot size of neuron i equal to .5 * number of mov. - sizeNeur(ind)=size(c,2)*.5; - -end - - -% generating RGB colors -color(1,:)=[255,0,0]; -color(2,:)=[0,0,255]; -color(3,:)=[0,255,0]; -color(4,:)=[255,0,255]; -color(5,:)=[0,255,255]; -color(6,:)=[255,255,0]; -color(7,:)=[168,102,255]; -color(8,:)=[122,15,226]; -color(9,:)=[192,0,192]; -color(10,:)=[0,128,0]; -color(11,:)=[192,192,0]; -color(12,:)=[203,117,25]; -color(13,:)=[20,43,140]; -color(14,:)=[255,176,99]; -color(15,:)=[43,130,87]; -color(16,:)=[179,255,0]; -color(17,:)=[153,51,0]; -color(18,:)=[148,99,99]; -color(19,:)=[0,169,155]; -color=color./255; -% number of minxing mov -nMixColor=max(sizeNeur)/.5; -mixColorMat=zeros(size(mixColor,1),nMixColor); -sizeSpotMat=zeros(size(mixColor,1),nMixColor); - -for k=1:size(mixColor,1) - [~, col]=find(mixColor(k,:)==1); - if ~isempty(col) - mixColorMat(k,1:size(col,2))=col; - end - nMixColor=sizeNeur(k,1)/.5; - sizeSpotMat(k,1: nMixColor)=linspace(sizeNeur(k,1),.5,nMixColor); -end -for j=1:nMov - - i0=SOM.neuroLabel(:,j); - i0=i0(i0~=0); - % save the indx of the wining neuron - indx=[indx - i0]; - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to generate different color and it return if there is more than +% mov. contribute in one and more neurons also it will return the spot +% size of the neuron if that more than mov. contribute in one and more neurons. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [color indx sizeSpotMat mixColorMat]=GetColor(SOM) + +nMov=size(SOM.neuroLabel,2); + +indx=[]; +% the size of the neuron spot the default size is .5 +sizeNeur=ones(SOM.mUnits,1).*.5; + +% in case of Mix Mov (mixcolor). +mixColor=zeros(SOM.mUnits,size(SOM.neuroLabel,2)); +for i=1:size(SOM.neuroLabel,1) + + neuron=SOM.neuroLabel(i,:); + neuron=neuron(neuron~=0); + neuron=unique(neuron); + % check the neuron i belong to which mov.! + [~, c]=find(SOM.neuroLabel==neuron); + c=unique(c'); + + ind=unique(SOM.neuroLabel(i,c)); + ind=ind(ind~=0); + % set the mov. index of neuron i equal to 1. + mixColor(ind,c)=1; + % set the spot size of neuron i equal to .5 * number of mov. + sizeNeur(ind)=size(c,2)*.5; + +end + + +% generating RGB colors +color(1,:)=[255,0,0]; +color(2,:)=[0,0,255]; +color(3,:)=[0,255,0]; +color(4,:)=[255,0,255]; +color(5,:)=[0,255,255]; +color(6,:)=[255,255,0]; +color(7,:)=[168,102,255]; +color(8,:)=[122,15,226]; +color(9,:)=[192,0,192]; +color(10,:)=[0,128,0]; +color(11,:)=[192,192,0]; +color(12,:)=[203,117,25]; +color(13,:)=[20,43,140]; +color(14,:)=[255,176,99]; +color(15,:)=[43,130,87]; +color(16,:)=[179,255,0]; +color(17,:)=[153,51,0]; +color(18,:)=[148,99,99]; +color(19,:)=[0,169,155]; +color=color./255; +% number of minxing mov +nMixColor=max(sizeNeur)/.5; +mixColorMat=zeros(size(mixColor,1),nMixColor); +sizeSpotMat=zeros(size(mixColor,1),nMixColor); + +for k=1:size(mixColor,1) + [~, col]=find(mixColor(k,:)==1); + if ~isempty(col) + mixColorMat(k,1:size(col,2))=col; + end + nMixColor=sizeNeur(k,1)/.5; + sizeSpotMat(k,1: nMixColor)=linspace(sizeNeur(k,1),.5,nMixColor); +end +for j=1:nMov + + i0=SOM.neuroLabel(:,j); + i0=i0(i0~=0); + % save the indx of the wining neuron + indx=[indx + i0]; + +end diff --git a/PatRec/SOM/Visiulaize U-matrix/PlotUDMatrix.m b/PatRec/SOM/Visiulaize U-matrix/PlotUDMatrix.m index 49bf815..78abe98 100644 --- a/PatRec/SOM/Visiulaize U-matrix/PlotUDMatrix.m +++ b/PatRec/SOM/Visiulaize U-matrix/PlotUDMatrix.m @@ -1,51 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to plot the U-matrix. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function PlotUDMatrix(SOM,color,mode,coords,UDMatNeuron,xSpotSize) - -%the spot vertices -neurSyntax=SyntaxNeuron(SOM.shape); -if size(xSpotSize,1)>1 - xSpotSize=repmat(xSpotSize',size(neurSyntax,1),1); - ySpotSize=xSpotSize; -else - ySpotSize=xSpotSize; -end -x=repmat(coords(:,1)',size(neurSyntax,1),1); -y=repmat(coords(:,2)',size(neurSyntax,1),1); - -xNeurSyntax=repmat(neurSyntax(:,1),1,UDMatNeuron); -yNeurSyntax=repmat(neurSyntax(:,2),1,UDMatNeuron); - -xNeurSyntax=(x./xSpotSize+xNeurSyntax).*xSpotSize; -yNeurSyntax=(y./ySpotSize+yNeurSyntax).*ySpotSize; - -map=patch(xNeurSyntax,yNeurSyntax,color); -if strcmp(mode,'Umat') - - set(map,'EdgeColor','none'); -end -colorbar('vert') +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to plot the U-matrix. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function PlotUDMatrix(SOM,color,mode,coords,UDMatNeuron,xSpotSize) + +%the spot vertices +neurSyntax=SyntaxNeuron(SOM.shape); +if size(xSpotSize,1)>1 + xSpotSize=repmat(xSpotSize',size(neurSyntax,1),1); + ySpotSize=xSpotSize; +else + ySpotSize=xSpotSize; +end +x=repmat(coords(:,1)',size(neurSyntax,1),1); +y=repmat(coords(:,2)',size(neurSyntax,1),1); + +xNeurSyntax=repmat(neurSyntax(:,1),1,UDMatNeuron); +yNeurSyntax=repmat(neurSyntax(:,2),1,UDMatNeuron); + +xNeurSyntax=(x./xSpotSize+xNeurSyntax).*xSpotSize; +yNeurSyntax=(y./ySpotSize+yNeurSyntax).*ySpotSize; + +map=patch(xNeurSyntax,yNeurSyntax,color); +if strcmp(mode,'Umat') + + set(map,'EdgeColor','none'); +end +colorbar('vert') diff --git a/PatRec/SOM/Visiulaize U-matrix/ShowUDMatrix.m b/PatRec/SOM/Visiulaize U-matrix/ShowUDMatrix.m index 11c8464..751669a 100644 --- a/PatRec/SOM/Visiulaize U-matrix/ShowUDMatrix.m +++ b/PatRec/SOM/Visiulaize U-matrix/ShowUDMatrix.m @@ -1,93 +1,93 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to shwo Unified Distance Matrix (U-matrix).The implementation of -% visulising U-matrix is done according to Juha Vesanto, Johan Himberg, -% Esa Alhoniemi and Parhankangs,''SOM Toolbox'',Helsinki University of Technology -% ,ISBN 951-22-4951-0. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function ShowUDMatrix(SOM) - -figure -colormap(1-gray) -ax=newplot; -set(ax,'Visible','off'); -set(get(ax,'Title'),'Visible','on'); -set(ax,'XaxisLocation','Top'); -% get the Unified Distance Matrix that is the distance between each two neighbors neuron -% in the map which is represente the intermediate spot between thos two neighbors in UDMat. -colorUDMat=CreateUDMat(SOM.w,SOM.mSize,SOM.shape); - -% the size of the Unified Distance Matrix (UDMat). -UDMatSize=[2*SOM.mSize(1)-1 2*SOM.mSize(2)-1]; -UDMatNeur=UDMatSize(1)*UDMatSize(2); -colorUDMat=colorUDMat(:); - -% % the neuron of the original map will have white color (empty not relate to any mov.) -% [indxNeurMap ,~]=find(colorUDMat==0); - -% the coordinats of each spot in UDMat. -coords=UDMatCoords(UDMatSize,SOM.shape,'Umat'); - -% show the spot of the UDMat without edges in different gray level. -PlotUDMatrix(SOM,colorUDMat','Umat',coords,UDMatNeur,.5) - -% get different color for the winning neuron (active neuron); -[colorMat indx sizeNeurSpot mixColor]=GetColor(SOM); - -% the coordinats of the only neurons in the map not in UDMat. -coords=UDMatCoords(SOM.mSize,SOM.shape,'Hit'); - -% % show the neuron spot of the original map with edges with white color. -% plotUDMatrix(SOM,colorUDMat(indxNeurMap)','All',Coords,size(Coords,1),.5) - -% the size of the neuron spot. -sizeNeurSpot=sizeNeurSpot(indx,:); - -% the coordinats of only the winning neuron (active) in the map. -coords=coords(indx,:); - -% the color of only the winning neuron (active) in the map. -mixColor=mixColor(indx,:); - -for i=1:size(mixColor,2) -% the index of the wining neurons of mixColor i -[ind,~]=find(sizeNeurSpot(:,i)~=0); - -% the coordinate of the wining neurons of mixColor i -coordsHit=coords(ind,:); - -% the spot size of the wining neurons of mixColor i -spotSize=sizeNeurSpot(ind,i); - -% number of winning neurons -hitNeurons=size(coordsHit,1); - -% the color of the mixcolor i. -color=colorMat(mixColor(ind,i),:); -color=reshape(color,[1 hitNeurons 3]); - -% show the wining neuron spot of the map with edges with different color mov. -PlotUDMatrix(SOM,color,'Hit',coordsHit,hitNeurons,spotSize) -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to shwo Unified Distance Matrix (U-matrix).The implementation of +% visulising U-matrix is done according to Juha Vesanto, Johan Himberg, +% Esa Alhoniemi and Parhankangs,''SOM Toolbox'',Helsinki University of Technology +% ,ISBN 951-22-4951-0. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function ShowUDMatrix(SOM) + +figure +colormap(1-gray) +ax=newplot; +set(ax,'Visible','off'); +set(get(ax,'Title'),'Visible','on'); +set(ax,'XaxisLocation','Top'); +% get the Unified Distance Matrix that is the distance between each two neighbors neuron +% in the map which is represente the intermediate spot between thos two neighbors in UDMat. +colorUDMat=CreateUDMat(SOM.w,SOM.mSize,SOM.shape); + +% the size of the Unified Distance Matrix (UDMat). +UDMatSize=[2*SOM.mSize(1)-1 2*SOM.mSize(2)-1]; +UDMatNeur=UDMatSize(1)*UDMatSize(2); +colorUDMat=colorUDMat(:); + +% % the neuron of the original map will have white color (empty not relate to any mov.) +% [indxNeurMap ,~]=find(colorUDMat==0); + +% the coordinats of each spot in UDMat. +coords=UDMatCoords(UDMatSize,SOM.shape,'Umat'); + +% show the spot of the UDMat without edges in different gray level. +PlotUDMatrix(SOM,colorUDMat','Umat',coords,UDMatNeur,.5) + +% get different color for the winning neuron (active neuron); +[colorMat indx sizeNeurSpot mixColor]=GetColor(SOM); + +% the coordinats of the only neurons in the map not in UDMat. +coords=UDMatCoords(SOM.mSize,SOM.shape,'Hit'); + +% % show the neuron spot of the original map with edges with white color. +% plotUDMatrix(SOM,colorUDMat(indxNeurMap)','All',Coords,size(Coords,1),.5) + +% the size of the neuron spot. +sizeNeurSpot=sizeNeurSpot(indx,:); + +% the coordinats of only the winning neuron (active) in the map. +coords=coords(indx,:); + +% the color of only the winning neuron (active) in the map. +mixColor=mixColor(indx,:); + +for i=1:size(mixColor,2) +% the index of the wining neurons of mixColor i +[ind,~]=find(sizeNeurSpot(:,i)~=0); + +% the coordinate of the wining neurons of mixColor i +coordsHit=coords(ind,:); + +% the spot size of the wining neurons of mixColor i +spotSize=sizeNeurSpot(ind,i); + +% number of winning neurons +hitNeurons=size(coordsHit,1); + +% the color of the mixcolor i. +color=colorMat(mixColor(ind,i),:); +color=reshape(color,[1 hitNeurons 3]); + +% show the wining neuron spot of the map with edges with different color mov. +PlotUDMatrix(SOM,color,'Hit',coordsHit,hitNeurons,spotSize) +end diff --git a/PatRec/SOM/Visiulaize U-matrix/SyntaxNeuron.m b/PatRec/SOM/Visiulaize U-matrix/SyntaxNeuron.m index 53b7740..da9de87 100644 --- a/PatRec/SOM/Visiulaize U-matrix/SyntaxNeuron.m +++ b/PatRec/SOM/Visiulaize U-matrix/SyntaxNeuron.m @@ -1,47 +1,47 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to define the spot vertices. -% -% Note: This function implemented in the same way of SOM toolbox Team[1] -% -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function neuron=SyntaxNeuron(shape) - - -switch shape - case 'rect' - neuron=[[-.5 -.5]; ... - [-.5 .5];... - [.5 .5];... - [.5 -.5]]; - case 'hexa' - neuron=[[0 0.6667];... - [0.5 0.3333];... - [0.5 -0.3333];... - [0 -0.6667];... - [-0.5 -0.3333];... - [-0.5 0.3333]]; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to define the spot vertices. +% +% Note: This function implemented in the same way of SOM toolbox Team[1] +% +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function neuron=SyntaxNeuron(shape) + + +switch shape + case 'rect' + neuron=[[-.5 -.5]; ... + [-.5 .5];... + [.5 .5];... + [.5 -.5]]; + case 'hexa' + neuron=[[0 0.6667];... + [0.5 0.3333];... + [0.5 -0.3333];... + [0 -0.6667];... + [-0.5 -0.3333];... + [-0.5 0.3333]]; end \ No newline at end of file diff --git a/PatRec/SOM/Visiulaize U-matrix/UDMatCoords.m b/PatRec/SOM/Visiulaize U-matrix/UDMatCoords.m index 1b3979f..4a18bfe 100644 --- a/PatRec/SOM/Visiulaize U-matrix/UDMatCoords.m +++ b/PatRec/SOM/Visiulaize U-matrix/UDMatCoords.m @@ -1,56 +1,56 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to create neurons coordinates -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-08-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function coords=UDMatCoords(mSize,shape,mode) -nNurons = prod(mSize); -xUnits=mSize(1); -yUnits=mSize(2); - -switch mode - case'Hit'% wining neuron (active neuron). - % rectangular shape - [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); - % hexa shape - if strcmp(shape,'hexa') - coords(:,[1 2]) = fliplr(coords(:,[1 2])); - location=rem(coords(:,2),2) == 0; - coords(location,1)=coords(location,1)+.5; - end - case'Umat' % Unified Distance Matrix - % rectangular shape - [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); - % hexa shape - if strcmp(shape,'hexa') - coords(:,[1 2]) = fliplr(coords(:,[1 2])); - location=rem(coords(:,2),2) == 0; - coords(location,1)=coords(location,1)+.5; - location=rem(coords(:,2)+1,4) == 0; - coords(location,1)=coords(location,1)+1; - end - coords=coords/2+.5; - -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to create neurons coordinates +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function coords=UDMatCoords(mSize,shape,mode) +nNurons = prod(mSize); +xUnits=mSize(1); +yUnits=mSize(2); + +switch mode + case'Hit'% wining neuron (active neuron). + % rectangular shape + [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); + % hexa shape + if strcmp(shape,'hexa') + coords(:,[1 2]) = fliplr(coords(:,[1 2])); + location=rem(coords(:,2),2) == 0; + coords(location,1)=coords(location,1)+.5; + end + case'Umat' % Unified Distance Matrix + % rectangular shape + [coords(:,1) coords(:,2)]=ind2sub([xUnits yUnits], 1:nNurons); + % hexa shape + if strcmp(shape,'hexa') + coords(:,[1 2]) = fliplr(coords(:,[1 2])); + location=rem(coords(:,2),2) == 0; + coords(location,1)=coords(location,1)+.5; + location=rem(coords(:,2)+1,4) == 0; + coords(location,1)=coords(location,1)+1; + end + coords=coords/2+.5; + +end + diff --git a/PatRec/SSOM/EvaluateSSOM.m b/PatRec/SSOM/EvaluateSSOM.m index 385c096..ef0ac3a 100644 --- a/PatRec/SSOM/EvaluateSSOM.m +++ b/PatRec/SSOM/EvaluateSSOM.m @@ -1,126 +1,135 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function runs the selected training method then it's avoiding the overfitting -% learning by cross validation technique based on evaluation of RMSE. -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [tempSSOM accV]=EvaluateSSOM(trSet, trOut, vSet, vOut,tType,algConf) -graph2d = 1; % -%graphUdMat = 1; -maxSim=50; %max simulation -passV = 0; % Pass test of the validation test -sim=0; -SSOM=InitSSOM(trSet,trOut,algConf); % - -tempSSOM=SSOM; - - -if graph2d % 2D Graph - hfig = figure; - hold on - set(hfig, 'DoubleBuffer','on'); - axis([1 maxSim 0 .3]); - hbestplot = plot(1:maxSim+1,zeros(1,maxSim+1)); - htext = text(20,0.2,sprintf('Best RMSE: %4.4f',0.0)); - - xlabel('simulations'); - ylabel('rmse'); - hold off - drawnow; -end - - -while sim <= maxSim - % Training - sim = sim + 1; - %Stochastic Training - if strcmp(tType,'Stochastic') - SSOM=SSOMStochasticTraining(trSet,SSOM,trOut); - % Batch Trainig - elseif strcmp(tType,'Batch') - SSOM=SSOMBatchTrainig(SSOM,trSet,maxSim,sim); - % error - else - disp('Select Training Method.'); - errordlg('Select Training Method.'); - error('Select Training Method.'); - - end - % test of the validation set - [apV,rmse(sim) ]=FastTestSSOM(SSOM,vOut,vSet); - SSOM.apV = apV; - SSOM.fV = rmse(sim); - - - % Save the best so far - if SSOM.apV >= tempSSOM.apV && SSOM.fV <= tempSSOM.fV - tempSSOM = SSOM; - end - - - - if graph2d % 2D Graph - plotvector = get(hbestplot,'YData'); - plotvector(sim) = rmse(sim); - set(hbestplot,'YData',plotvector); - set(htext,'String',sprintf('Best RMSE: %4.4f',tempSSOM.fV)); - - drawnow; - end - -end - -if tempSSOM.fV < 0.1 || tempSSOM.apV > 95 - passV = 1; -end - -[apV fV]=FullTestSSOM(tempSSOM,vOut,vSet); -accV=apV; -tempSSOM.apV=apV; -tempSSOM.fV=fV; - -% Visualize Som -if algConf.visualizeSOM - tempSSOM.neuroLabel=GetNeuronLabel(trSet,tempSSOM); - ShowUDMatrix(tempSSOM) - -end - -disp(['Simulations: ' num2str(sim)]); -disp(['General rmse: ' num2str(rmse(sim))]); -disp('RMES V: '); -disp(tempSSOM.fV'); -disp('Acc V: '); -disp(tempSSOM.apV'); - -if passV - disp('%%%%%%%%%%% Supervised SOM training completed %%%%%%%%%%%%%'); - -else - - disp('%%%%%%%%%%% Supervised SOM training failed %%%%%%%%%%%%%'); -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function runs the selected training method then it's avoiding the overfitting +% learning by cross validation technique based on evaluation of RMSE. +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 2014-01-14 / Ali Fouad / Addition of "if statment" to reduce the training time +% 20xx-xx-xx / Author / Comment on update + +function [tempSSOM accV]=EvaluateSSOM(trSet, trOut, vSet, vOut,tType,algConf) +graph2d = 1; % +%graphUdMat = 1; +maxSim=50; %max simulation +passV = 0; % Pass test of the validation test +sim=0; +SSOM=InitSSOM(trSet,trOut,algConf); % + +tempSSOM=SSOM; + + +if graph2d % 2D Graph + hfig = figure; + hold on + set(hfig, 'DoubleBuffer','on'); + axis([1 maxSim 0 .3]); + hbestplot = plot(1:maxSim+1,zeros(1,maxSim+1)); + htext = text(20,0.2,sprintf('Best RMSE: %4.4f',0.0)); + + xlabel('simulations'); + ylabel('rmse'); + hold off + drawnow; +end + + +while sim <= maxSim && passV == 0 + % Training + sim = sim + 1; + %Stochastic Training + if strcmp(tType,'Stochastic') + SSOM=SSOMStochasticTraining(trSet,SSOM,trOut); + % Batch Trainig + elseif strcmp(tType,'Batch') + SSOM=SSOMBatchTrainig(SSOM,trSet,maxSim,sim); + % error + else + disp('Select Training Method.'); + errordlg('Select Training Method.'); + error('Select Training Method.'); + + end + % test of the validation set + [apV,rmse(sim) ]=FastTestSSOM(SSOM,vOut,vSet); + SSOM.apV = apV; + SSOM.fV = rmse(sim); + + + % Save the best so far + if SSOM.apV >= tempSSOM.apV && SSOM.fV <= tempSSOM.fV + tempSSOM = SSOM; + end + % terminate the training if there is no further convergence in the RMSE + if SSOM.fV < 0.1 + if sim > 10 + if mean(rmse(sim-fix(sim/3):sim)) < mean(rmse(sim-fix(sim/5):sim)) + + passV = 1; + end + end + end + + + if graph2d % 2D Graph + plotvector = get(hbestplot,'YData'); + plotvector(sim) = rmse(sim); + set(hbestplot,'YData',plotvector); + set(htext,'String',sprintf('Best RMSE: %4.4f',tempSSOM.fV)); + + drawnow; + end + +end + +if tempSSOM.fV < 0.1 || tempSSOM.apV > 95 + passV = 1; +end + +[apV fV]=FullTestSSOM(tempSSOM,vOut,vSet); +accV=apV; +tempSSOM.apV=apV; +tempSSOM.fV=fV; + +% Visualize Som +if algConf.visualizeSOM + tempSSOM.neuroLabel=GetNeuronLabel(trSet,tempSSOM); + ShowUDMatrix(tempSSOM) + +end + +disp(['Simulations: ' num2str(sim)]); +disp(['General rmse: ' num2str(rmse(sim))]); +disp('RMES V: '); +disp(tempSSOM.fV'); +disp('Acc V: '); +disp(tempSSOM.apV'); + +if passV + disp('%%%%%%%%%%% Supervised SOM training completed %%%%%%%%%%%%%'); + +else + + disp('%%%%%%%%%%% Supervised SOM training failed %%%%%%%%%%%%%'); +end + + close(hfig); \ No newline at end of file diff --git a/PatRec/SSOM/FastTestSSOM.m b/PatRec/SSOM/FastTestSSOM.m index 87c7dfc..b460d35 100644 --- a/PatRec/SSOM/FastTestSSOM.m +++ b/PatRec/SSOM/FastTestSSOM.m @@ -1,60 +1,60 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function classify the validation sets. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [accP rmse]=FastTestSSOM(SSOM,vOut,x) - -% w represent only the first columns i.e(without the output) -w=SSOM.w(:,1:size(SSOM.w,2)-SSOM.sizeSSOMOut); - - -nSets=size(x,1); -% square Error. -sqErr=0; -% Number of movements. -nM=size(SSOM.trOut,2); -SSOMOut=SSOM.SSOMOut; -% loop over all validation data. -for i=1:nSets - - - % finding the winning neuron according to movement i. - [i0 ~]=FindClosest(w,x(i,:)); - - out(i,:)=SSOMOut(i0,:); - - % sum of square Error. - sqErr = sqErr + sum((out(i,:)-vOut(i,:)).^2); -end -% error. -er = find(sum(abs(out-vOut),2) >= 1); -% accuracy. -accP = (1 - (length(er)/nSets)) * 100; -% root mean square error. -rmse = sqrt(sqErr/(nSets*nM)); - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function classify the validation sets. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [accP rmse]=FastTestSSOM(SSOM,vOut,x) + +% w represent only the first columns i.e(without the output) +w=SSOM.w(:,1:size(SSOM.w,2)-SSOM.sizeSSOMOut); + + +nSets=size(x,1); +% square Error. +sqErr=0; +% Number of movements. +nM=size(SSOM.trOut,2); +SSOMOut=SSOM.SSOMOut; +% loop over all validation data. +for i=1:nSets + + + % finding the winning neuron according to movement i. + [i0 ~]=FindClosest(w,x(i,:)); + + out(i,:)=SSOMOut(i0,:); + + % sum of square Error. + sqErr = sqErr + sum((out(i,:)-vOut(i,:)).^2); +end +% error. +er = find(sum(abs(out-vOut),2) >= 1); +% accuracy. +accP = (1 - (length(er)/nSets)) * 100; +% root mean square error. +rmse = sqrt(sqErr/(nSets*nM)); + + + + + diff --git a/PatRec/SSOM/FullTestSSOM.m b/PatRec/SSOM/FullTestSSOM.m index aa7671a..98325f9 100644 --- a/PatRec/SSOM/FullTestSSOM.m +++ b/PatRec/SSOM/FullTestSSOM.m @@ -1,78 +1,78 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function classify the validation sets. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [accP rmse]=FullTestSSOM(SSOM,vOut,x) - -% w represent only the first columns i.e(without the output) -w=SSOM.w(:,1:size(SSOM.w,2)-SSOM.sizeSSOMOut); -SSOMOut=SSOM.SSOMOut; - -% Number of data sets. -nSets=size(x,1); - -% Number of movements. -nM=size(SSOM.trOut,2); -nSetPerMov = nSets/nM ; % Number of sets per movement. -setIdx=1; -% loop over all validation data. -for i=1:nM - - % square Error. - sqErr=0; - cP=0; - - for j = 1 : nSetPerMov - - % finding the location of winning neuron i0(x) on the map. - [i0 ,~]=FindClosest(w,x(setIdx,:)); - - % finding the winning movement - prediVec=round(SSOMOut(i0,:)); - - %correct Movement - - cM= length(find(sum(abs(prediVec-vOut(setIdx,:)),2) >= 1)); - if cM==0 - correct=1; - else - correct=0; - end - cP = cP + correct; - % sum of square Error. - sqErr = sqErr + sum((prediVec-vOut(setIdx,:)).^2); - setIdx=setIdx+1; - end - accP(i) = cP / nSetPerMov; - rmse(i) = sqrt(sqErr/(nSetPerMov*nM)); - -end -accP(end + 1) = mean(accP); -rmse(end + 1) = mean(rmse); - - - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function classify the validation sets. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [accP rmse]=FullTestSSOM(SSOM,vOut,x) + +% w represent only the first columns i.e(without the output) +w=SSOM.w(:,1:size(SSOM.w,2)-SSOM.sizeSSOMOut); +SSOMOut=SSOM.SSOMOut; + +% Number of data sets. +nSets=size(x,1); + +% Number of movements. +nM=size(SSOM.trOut,2); +nSetPerMov = nSets/nM ; % Number of sets per movement. +setIdx=1; +% loop over all validation data. +for i=1:nM + + % square Error. + sqErr=0; + cP=0; + + for j = 1 : nSetPerMov + + % finding the location of winning neuron i0(x) on the map. + [i0 ,~]=FindClosest(w,x(setIdx,:)); + + % finding the winning movement + prediVec=round(SSOMOut(i0,:)); + + %correct Movement + + cM= length(find(sum(abs(prediVec-vOut(setIdx,:)),2) >= 1)); + if cM==0 + correct=1; + else + correct=0; + end + cP = cP + correct; + % sum of square Error. + sqErr = sqErr + sum((prediVec-vOut(setIdx,:)).^2); + setIdx=setIdx+1; + end + accP(i) = cP / nSetPerMov; + rmse(i) = sqrt(sqErr/(nSetPerMov*nM)); + +end +accP(end + 1) = mean(accP); +rmse(end + 1) = mean(rmse); + + + + + + diff --git a/PatRec/SSOM/InitSSOM.m b/PatRec/SSOM/InitSSOM.m index 5a3400b..6badb4d 100644 --- a/PatRec/SSOM/InitSSOM.m +++ b/PatRec/SSOM/InitSSOM.m @@ -1,120 +1,120 @@ - -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to initialize the Artificial Neural Network (Supervised SOM). -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function SSOM=InitSSOM(trSet,trOut,algConf) - - -switch algConf.shape - case 'Hexagonal Grid' - shape= 'hexa'; - case 'Rectangular Grid' - shape='rect'; - case 'Select Shape.' - - disp('%%%%%%%%%%Select Shape.%%%%%%%%%%%'); - errordlg('Select Shape.'); - error('Select Shape.'); -end -switch algConf.neighFunc - case 'Bubble' - neigh='bubb'; - case 'Gaussian' - neigh='gauss'; - case 'Cutgaussian' - neigh='cutGauss'; - case 'Triangular' - neigh='trai'; - case 'Butterworth' - neigh='butter'; - case 'Select Neighbor Function.' - disp('%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%%'); - errordlg('Select Neighbor Function.'); - error('%%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%'); - -end - - - -sizeSSOMOut=size(trOut,2); -% the grid (map) width -xUnits=ceil( (size(trSet,1)^0.5)*1.5); -% the grid (map) length -yUnits=ceil( (size(trSet,1)^0.5)*1.5); -%initial learning rate parameter -etaIni=.5; -% the initial width of the topologic neighborhood function -sigmaIni=ceil(xUnits/2); -% time constant's decay of the learning parameter -tow2=3000; -% time constant's decay of the initial width of the topologic neighborhood function -tow1=tow2/log(sigmaIni); -% the grid (map) size -mSize=[xUnits yUnits]; -% the total number of neuron -mUnits=prod(mSize); -SSOMOut=zeros(mUnits,size(trSet,2)); -% the coordinates of the neuron in the grid and that depends on the grid's shape here i used the hexa shape -mapCoordinates=NeuronCoordinates(mSize,shape); -% number of data variables -dDim=size(trSet,2); -% initial weigth for each neuron in the grid where each neuron has the same number of data variable -w=RandomWeights(xUnits*yUnits,dDim,trSet); -%% - -% those parameters are for the batch training - - -% Unit Distance -neuronDist = NeuronDistances(mSize,mapCoordinates); -% the initial width of the topologic neighborhood function -radiusIni =max(1,ceil(max(mSize)/2)); -% the final width of the topologic neighborhood function -radiusFin=.01; - -%% -SSOM.t=1; -SSOM.sigmaIni=sigmaIni; -SSOM.tow1=tow1; -SSOM.etaIni=etaIni; -SSOM.tow2=tow2; -SSOM.w=w; -SSOM.mapCoordinates=mapCoordinates; -SSOM.apV=0; -SSOM.fV=Inf; -SSOM.mSize=mSize; -SSOM.trOut=trOut; -SSOM.mUnits=mUnits; -SSOM.radiusIni=radiusIni; -SSOM.radiusFin=radiusFin; -SSOM.neuronDist=neuronDist; -SSOM.SSOMOut=SSOMOut; -SSOM.sizeSSOMOut=sizeSSOMOut; - -SSOM.shape=shape; -SSOM.neighFunc=neigh; - - - + +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to initialize the Artificial Neural Network (Supervised SOM). +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function SSOM=InitSSOM(trSet,trOut,algConf) + + +switch algConf.shape + case 'Hexagonal Grid' + shape= 'hexa'; + case 'Rectangular Grid' + shape='rect'; + case 'Select Shape.' + + disp('%%%%%%%%%%Select Shape.%%%%%%%%%%%'); + errordlg('Select Shape.'); + error('Select Shape.'); +end +switch algConf.neighFunc + case 'Bubble' + neigh='bubb'; + case 'Gaussian' + neigh='gauss'; + case 'Cutgaussian' + neigh='cutGauss'; + case 'Triangular' + neigh='trai'; + case 'Butterworth' + neigh='butter'; + case 'Select Neighbor Function.' + disp('%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%%'); + errordlg('Select Neighbor Function.'); + error('%%%%%%%%%%%%%%%% Select Neighbor Function.%%%%%%%%%%%%%%%%'); + +end + + + +sizeSSOMOut=size(trOut,2); +% the grid (map) width +xUnits=ceil( (size(trSet,1)^0.5)*1.5); +% the grid (map) length +yUnits=ceil( (size(trSet,1)^0.5)*1.5); +%initial learning rate parameter +etaIni=.5; +% the initial width of the topologic neighborhood function +sigmaIni=ceil(xUnits/2); +% time constant's decay of the learning parameter +tow2=3000; +% time constant's decay of the initial width of the topologic neighborhood function +tow1=tow2/log(sigmaIni); +% the grid (map) size +mSize=[xUnits yUnits]; +% the total number of neuron +mUnits=prod(mSize); +SSOMOut=zeros(mUnits,size(trSet,2)); +% the coordinates of the neuron in the grid and that depends on the grid's shape here i used the hexa shape +mapCoordinates=NeuronCoordinates(mSize,shape); +% number of data variables +dDim=size(trSet,2); +% initial weigth for each neuron in the grid where each neuron has the same number of data variable +w=RandomWeights(xUnits*yUnits,dDim,trSet); +%% + +% those parameters are for the batch training + + +% Unit Distance +neuronDist = NeuronDistances(mSize,mapCoordinates); +% the initial width of the topologic neighborhood function +radiusIni =max(1,ceil(max(mSize)/2)); +% the final width of the topologic neighborhood function +radiusFin=.01; + +%% +SSOM.t=1; +SSOM.sigmaIni=sigmaIni; +SSOM.tow1=tow1; +SSOM.etaIni=etaIni; +SSOM.tow2=tow2; +SSOM.w=w; +SSOM.mapCoordinates=mapCoordinates; +SSOM.apV=0; +SSOM.fV=Inf; +SSOM.mSize=mSize; +SSOM.trOut=trOut; +SSOM.mUnits=mUnits; +SSOM.radiusIni=radiusIni; +SSOM.radiusFin=radiusFin; +SSOM.neuronDist=neuronDist; +SSOM.SSOMOut=SSOMOut; +SSOM.sizeSSOMOut=sizeSSOMOut; + +SSOM.shape=shape; +SSOM.neighFunc=neigh; + + + diff --git a/PatRec/SSOM/SSOM Batch Training/SSOMBatchTrainig.m b/PatRec/SSOM/SSOM Batch Training/SSOMBatchTrainig.m index 4826691..a998caa 100644 --- a/PatRec/SSOM/SSOM Batch Training/SSOMBatchTrainig.m +++ b/PatRec/SSOM/SSOM Batch Training/SSOMBatchTrainig.m @@ -1,85 +1,85 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to run the batch training.The principle of updating weight vector -% step goes by replacing each map unit by the average of the data vectors that -% were in its neighborhood. The contribution, or activation, of data vectors -% in the mean can be varied with the neighborhood function. This activation -% is given by matrix neigh. So, for each map unit the new weight vector is -% w(t+1) = sum(neigh(t)*S(t)) ./ sum(neigh(t)*A), -% wherw S sum of input vectors corresponding to wining neuron i0 , -% A is the number of sample corresponding to that wining neuron i0 -% and neigh is the neighborhood function.[1] -% -% Note: This function implemented in the same way of SOM toolbox Team[1] -% References -% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs -% SOM Toolbox Team ,Helsinki University of Technology. -% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function SSOM=SSOMBatchTrainig(SSOM,trSet,maxSim,sim) -radiusFin=SSOM.radiusFin; -radiusIni=SSOM.radiusIni; -w=SSOM.w; -sizeSSOMOut=SSOM.sizeSSOMOut; -% sample weights: each sample is weighted -weights=1; -% number of sets -nSet=size(trSet,1); -% the width of the neighbour function. -radius = radiusFin + ((maxSim-(sim-1))/maxSim) * (radiusIni - radiusFin); -radius(radius==0) = eps; - - -knownData = ones(size(trSet,1),size(trSet,2)); -% winning neurons vector -i0 = zeros(1,nSet); -% loop over all data sets to find the winning neurons by measuring the min -% euclidean disttance -for i=1:nSet - inVec=repmat(trSet(i,:),size(w,1),1); - dist=VectorDistance(inVec,w); - [~, i0(i)]=min(dist); -end - - -% neighborhood function - -neigh = BatchNeighborFunction(SSOM,radius); -% a partition matrix p with elements p_ij=1 if the i0(winning neuron) of data vector j is i. -p = sparse(i0,[1:nSet],weights,SSOM.mUnits,nSet); -% neigh*sum of vectors corresponding to wining neuron i0 (in each Voronoi -% set) -s = neigh*(p*trSet); -% neigh*the number of vectors corresponding to wining neuron i0 (in Voronoi -% set) -a = neigh*(p*knownData); - -nonZero = find(a > 0); -w(nonZero)=s(nonZero)./ a(nonZero); -% the classifier outpu represent by last columns of the w matrix which we -% added previously in SSOM_Mapping. -SSOMOut=w(:,end-sizeSSOMOut+1:end); -SSOM.w=w; -SSOM.SSOMOut=SSOMOut; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to run the batch training.The principle of updating weight vector +% step goes by replacing each map unit by the average of the data vectors that +% were in its neighborhood. The contribution, or activation, of data vectors +% in the mean can be varied with the neighborhood function. This activation +% is given by matrix neigh. So, for each map unit the new weight vector is +% w(t+1) = sum(neigh(t)*S(t)) ./ sum(neigh(t)*A), +% wherw S sum of input vectors corresponding to wining neuron i0 , +% A is the number of sample corresponding to that wining neuron i0 +% and neigh is the neighborhood function.[1] +% +% Note: This function implemented in the same way of SOM toolbox Team[1] +% References +% [1]-Juha Vesanto, Johan Himberg, Esa Alhoniemi, and Parhankangs +% SOM Toolbox Team ,Helsinki University of Technology. +% http://www.cis.hut.fi/somtoolbox/package/papers/techrep.pdf +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function SSOM=SSOMBatchTrainig(SSOM,trSet,maxSim,sim) +radiusFin=SSOM.radiusFin; +radiusIni=SSOM.radiusIni; +w=SSOM.w; +sizeSSOMOut=SSOM.sizeSSOMOut; +% sample weights: each sample is weighted +weights=1; +% number of sets +nSet=size(trSet,1); +% the width of the neighbour function. +radius = radiusFin + ((maxSim-(sim-1))/maxSim) * (radiusIni - radiusFin); +radius(radius==0) = eps; + + +knownData = ones(size(trSet,1),size(trSet,2)); +% winning neurons vector +i0 = zeros(1,nSet); +% loop over all data sets to find the winning neurons by measuring the min +% euclidean disttance +for i=1:nSet + inVec=repmat(trSet(i,:),size(w,1),1); + dist=VectorDistance(inVec,w); + [~, i0(i)]=min(dist); +end + + +% neighborhood function + +neigh = BatchNeighborFunction(SSOM,radius); +% a partition matrix p with elements p_ij=1 if the i0(winning neuron) of data vector j is i. +p = sparse(i0,[1:nSet],weights,SSOM.mUnits,nSet); +% neigh*sum of vectors corresponding to wining neuron i0 (in each Voronoi +% set) +s = neigh*(p*trSet); +% neigh*the number of vectors corresponding to wining neuron i0 (in Voronoi +% set) +a = neigh*(p*knownData); + +nonZero = find(a > 0); +w(nonZero)=s(nonZero)./ a(nonZero); +% the classifier outpu represent by last columns of the w matrix which we +% added previously in SSOM_Mapping. +SSOMOut=w(:,end-sizeSSOMOut+1:end); +SSOM.w=w; +SSOM.SSOMOut=SSOMOut; diff --git a/PatRec/SSOM/SSOM Stochastic Training/SSOMStochasticTraining.m b/PatRec/SSOM/SSOM Stochastic Training/SSOMStochasticTraining.m index bdda69d..060913d 100644 --- a/PatRec/SSOM/SSOM Stochastic Training/SSOMStochasticTraining.m +++ b/PatRec/SSOM/SSOM Stochastic Training/SSOMStochasticTraining.m @@ -1,60 +1,62 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to run the Stochastic Training -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function SSOM=SSOMStochasticTraining(trSet,SSOM,trOut) -t=SSOM.t; -% width of neighbour function. -sigmaIni=SSOM.sigmaIni; -% constant's decay of sigma -tow1=SSOM.tow1; -% learning rate parameter -etaIni=SSOM.etaIni; -% constant's decay of eta -tow2=SSOM.tow2; -%the weight matrix -w=SSOM.w; -sizeSSOMOut=SSOM.sizeSSOMOut; - -% Draw random samples -p=randperm(length(trOut(:,1))); -for i=1:size(trSet,1) - % width of neighbour function. - sigmaT=Sigma(t,sigmaIni,tow1); - sigmaT(sigmaT==0)=eps; - % learning rate parameter - eta= Eta(t,etaIni,tow2); - %Finding the winning neuron (min euclidean distance weights matrix and input vector ) - [i0 mindist]=FindClosest(w,trSet(p(i),:)); - %Updating the weights - w=UpdateWeights(i0,trSet(p(i),:),w,eta,sigmaT,SSOM); - % increase the iteration - t=t+1; - SSOM.t=t; - -end - -SSOMOut=w(:,end-sizeSSOMOut+1:end); -SSOM.w=w; -SSOM.SSOMOut=SSOMOut; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to run the Stochastic Training +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 2014-01-14 / Ali Fouad / Updating of sampling step +% 20xx-xx-xx / Author / Comment on update + +function SSOM=SSOMStochasticTraining(trSet,SSOM,trOut) +t=SSOM.t; +% width of neighbour function. +sigmaIni=SSOM.sigmaIni; +% constant's decay of sigma +tow1=SSOM.tow1; +% learning rate parameter +etaIni=SSOM.etaIni; +% constant's decay of eta +tow2=SSOM.tow2; +%the weight matrix +w=SSOM.w; +sizeSSOMOut=SSOM.sizeSSOMOut; + +% Draw random samples +nTrPattern=fix(.7*length(trSet(:,1))); +p=randperm(length(trSet(:,1)),nTrPattern); +for i=1:nTrPattern + % width of neighbour function. + sigmaT=Sigma(t,sigmaIni,tow1); + sigmaT(sigmaT==0)=eps; + % learning rate parameter + eta= Eta(t,etaIni,tow2); + %Finding the winning neuron (min euclidean distance weights matrix and input vector ) + [i0 mindist]=FindClosest(w,trSet(p(i),:)); + %Updating the weights + w=UpdateWeights(i0,trSet(p(i),:),w,eta,sigmaT,SSOM); + % increase the iteration + t=t+1; + SSOM.t=t; + +end + +SSOMOut=w(:,end-sizeSSOMOut+1:end); +SSOM.w=w; +SSOM.SSOMOut=SSOMOut; diff --git a/PatRec/SSOM/SSOMTest.m b/PatRec/SSOM/SSOMTest.m index f71eb2d..2fe3883 100644 --- a/PatRec/SSOM/SSOMTest.m +++ b/PatRec/SSOM/SSOMTest.m @@ -1,64 +1,64 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to classifies the testing sets. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - -function [outMov predictVec]=SSOMTest(patRecTrained,x) - - -% Check if there is any NaN value -tKnownNaN = ~isnan(x); -if ~isempty(find(tKnownNaN==0, 1)) - disp('You have NaN value in Testing sets'); - errordlg('You have NaN value in Testing sets'); - error('You have Complex number in Testing sets'); -end -% Check if there is any Inf value -tKnownInf = ~isinf(x); -if ~isempty(find(tKnownInf==0, 1)) - disp('You have Inf value in Testing sets'); - errordlg('You have Inf value in Testing sets'); - error('You have Complex number in Testing sets'); -end -% Check if there is any Complex number in Testing sets -tKnownComplex = ~isreal(x); -if ~isempty(find(tKnownComplex==1, 1)) - disp('You have Complex number in Testing sets'); - errordlg('You have Complex number in Testing sets'); - error('You have Complex number in Testing sets'); -end - - -% w represent only the first columns i.e(without the output) -w=patRecTrained.SSOM.w(:,1:size(patRecTrained.SSOM.w,2)-patRecTrained.SSOM.sizeSSOMOut); -SSOMOut=patRecTrained.SSOM.SSOMOut; - -% finding the winning neuron. -[i0,~ ]=FindClosest(w,x); - - -predictVec=SSOMOut(i0,:); -% finding the winning movement -outMov=find(round(predictVec)); -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to classifies the testing sets. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + +function [outMov predictVec]=SSOMTest(patRecTrained,x) + + +% Check if there is any NaN value +tKnownNaN = ~isnan(x); +if ~isempty(find(tKnownNaN==0, 1)) + disp('You have NaN value in Testing sets'); + errordlg('You have NaN value in Testing sets'); + error('You have Complex number in Testing sets'); +end +% Check if there is any Inf value +tKnownInf = ~isinf(x); +if ~isempty(find(tKnownInf==0, 1)) + disp('You have Inf value in Testing sets'); + errordlg('You have Inf value in Testing sets'); + error('You have Complex number in Testing sets'); +end +% Check if there is any Complex number in Testing sets +tKnownComplex = ~isreal(x); +if ~isempty(find(tKnownComplex==1, 1)) + disp('You have Complex number in Testing sets'); + errordlg('You have Complex number in Testing sets'); + error('You have Complex number in Testing sets'); +end + + +% w represent only the first columns i.e(without the output) +w=patRecTrained.SSOM.w(:,1:size(patRecTrained.SSOM.w,2)-patRecTrained.SSOM.sizeSSOMOut); +SSOMOut=patRecTrained.SSOM.SSOMOut; + +% finding the winning neuron. +[i0,~ ]=FindClosest(w,x); + + +predictVec=SSOMOut(i0,:); +% finding the winning movement +outMov=find(round(predictVec)); +end + diff --git a/PatRec/SSOM/SSOM_Mapping.m b/PatRec/SSOM/SSOM_Mapping.m index c98676e..60da344 100644 --- a/PatRec/SSOM/SSOM_Mapping.m +++ b/PatRec/SSOM/SSOM_Mapping.m @@ -1,82 +1,82 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function check if there is any NaN or Inf value in training and -% validation sets then it run the training method of SOM. -% -% -% -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-09-01 / Ali Fouad / Creation -% 20xx-xx-xx / Author / Comment on update - - -function [out accV]=SSOM_Mapping(trSets, trOuts, vSets, vOuts, tType,algConf) -% Check if there is any NaN value in training sets -trKnownNaN = ~isnan(trSets); -if ~isempty(find(trKnownNaN==0, 1)) - disp('You have NaN value in Training sets'); - errordlg('You have NaN value in Training sets'); - error('You have NaN value in Training sets'); - -end -% Check if there is any Inf value in training sets -trKnownInf = ~isinf(trSets); -if ~isempty(find(trKnownInf==0, 1)) - disp('You have Inf value in Training sets'); - errordlg('You have Inf value in Training sets'); - error('You have Inf value in Training sets'); -end -% Check if there is any Complex number in training sets -trKnownComplex = ~isreal(trSets); -if ~isempty(find(trKnownComplex==1, 1)) - disp('You have Complex number in Training sets'); - errordlg('You have Complex number in Training sets'); - error('You have Complex number in Training sets'); -end -% Check if there is any NaN value in validation sets -vKnownNaN = ~isnan(vSets); -if ~isempty(find(vKnownNaN==0, 1)) - disp('You have NaN value in Validation sets'); - errordlg('You have NaN value in Validation sets'); - error('You have NaN value in Validation sets'); -end -% Check if there is any Inf value in validation sets -vKnownInf = ~isinf(vSets); -if ~isempty(find(vKnownInf==0, 1)) - disp('You have Inf value in Validation sets'); - errordlg('You have Inf value in Validation sets'); - error('You have Inf value in Validation sets'); -end -% Check if there is any Complex number in Validation sets -vKnownComplex = ~isreal(vSets); -if ~isempty(find(vKnownComplex==1, 1)) - disp('You have Complex number in Validation sets'); - errordlg('You have Complex number in Validation sets'); - error('You have Complex number in Validation sets'); -end -% adding the lalel of training sets last columns to make it Supervised. -trSets=[trSets trOuts]; - -[out accV]=EvaluateSSOM(trSets, trOuts, vSets, vOuts,tType,algConf); - -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function check if there is any NaN or Inf value in training and +% validation sets then it run the training method of SOM. +% +% +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-09-01 / Ali Fouad / Creation +% 20xx-xx-xx / Author / Comment on update + + +function [out accV]=SSOM_Mapping(trSets, trOuts, vSets, vOuts, tType,algConf) +% Check if there is any NaN value in training sets +trKnownNaN = ~isnan(trSets); +if ~isempty(find(trKnownNaN==0, 1)) + disp('You have NaN value in Training sets'); + errordlg('You have NaN value in Training sets'); + error('You have NaN value in Training sets'); + +end +% Check if there is any Inf value in training sets +trKnownInf = ~isinf(trSets); +if ~isempty(find(trKnownInf==0, 1)) + disp('You have Inf value in Training sets'); + errordlg('You have Inf value in Training sets'); + error('You have Inf value in Training sets'); +end +% Check if there is any Complex number in training sets +trKnownComplex = ~isreal(trSets); +if ~isempty(find(trKnownComplex==1, 1)) + disp('You have Complex number in Training sets'); + errordlg('You have Complex number in Training sets'); + error('You have Complex number in Training sets'); +end +% Check if there is any NaN value in validation sets +vKnownNaN = ~isnan(vSets); +if ~isempty(find(vKnownNaN==0, 1)) + disp('You have NaN value in Validation sets'); + errordlg('You have NaN value in Validation sets'); + error('You have NaN value in Validation sets'); +end +% Check if there is any Inf value in validation sets +vKnownInf = ~isinf(vSets); +if ~isempty(find(vKnownInf==0, 1)) + disp('You have Inf value in Validation sets'); + errordlg('You have Inf value in Validation sets'); + error('You have Inf value in Validation sets'); +end +% Check if there is any Complex number in Validation sets +vKnownComplex = ~isreal(vSets); +if ~isempty(find(vKnownComplex==1, 1)) + disp('You have Complex number in Validation sets'); + errordlg('You have Complex number in Validation sets'); + error('You have Complex number in Validation sets'); +end +% adding the lalel of training sets last columns to make it Supervised. +trSets=[trSets trOuts]; + +[out accV]=EvaluateSSOM(trSets, trOuts, vSets, vOuts,tType,algConf); + +end + + diff --git a/PatRec/SignalProcessing_RealtimePatRec.m b/PatRec/SignalProcessing_RealtimePatRec.m index 3b1c017..9f9275c 100644 --- a/PatRec/SignalProcessing_RealtimePatRec.m +++ b/PatRec/SignalProcessing_RealtimePatRec.m @@ -1,46 +1,55 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -%------------------------- Function Description ------------------------- -% Function to execute the general steps of signal processing required in -% real-time PatRec. -% -% ------------------------------- Updates --------------------------------- -% 2011-08-02 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function tSet = SignalProcessing_RealtimePatRec(data, patRec) - - % Apply fliters - data = ApplyFilters(patRec, data); - - % Get signal features - tFeatures = GetSigFeatures(data,patRec.sF,patRec.selFeatures); - - % Create a vector with the signal features - tSet = []; - for i = 1 : size(patRec.selFeatures,1) - tSet = [tSet tFeatures.(patRec.selFeatures{i})]; - end - - % Normalize if required - tSet = NormalizeSet(tSet,patRec); - %if patRec.norm - % tSet = ((tSet - patRec.nMean) ./ patRec.nVar); - %end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +%------------------------- Function Description ------------------------- +% Function to execute the general steps of signal processing required in +% real-time PatRec. +% +% ------------------------------- Updates --------------------------------- +% 2011-08-02 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function tSet = SignalProcessing_RealtimePatRec(data, patRec) + + % Apply fliters + data = ApplyFilters(patRec, data); + + % Apply Signal Separation algorithms if required + if isfield(patRec,'sigSeparation') + data=SignalSeparationRealtime(patRec,data); + end + + % Get signal features + tFeatures = GetSigFeatures(data,patRec.sF,patRec.selFeatures); + + % Create a vector with the signal features + tSet = []; + for i = 1 : size(patRec.selFeatures,1) + tSet = [tSet tFeatures.(patRec.selFeatures{i})]; + end + + % Normalize if required + tSet = NormalizeSet(tSet,patRec); + + % Apply Feature Reduction (PCA) if required + tSet = ApplyFeatureReduction(tSet, patRec); + + %if patRec.norm + % tSet = ((tSet - patRec.nMean) ./ patRec.nVar); + %end + end \ No newline at end of file diff --git a/PatRec/SoftMax.m b/PatRec/SoftMax.m index 6e1cd77..c50a749 100644 --- a/PatRec/SoftMax.m +++ b/PatRec/SoftMax.m @@ -1,47 +1,47 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Apply SoftMax activation function -% -% ------------- Updates ------------- -% 2011-10-09 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update -function vector = SoftMax(vector) - -%% Manual - %vector = vector - min(vector); % Offset negative numbers - vector(vector < 0) = 0; % Remove negative numbers - vector = vector ./ sum(vector); - - - -%% Automatic -% vector = softmax(vector); - - -%% Validations - - % The softmax function can returns NaN - if find(isnan(vector)) - vector(isnan(vector)) = 1; - end - - % Replace 0 for small values - vector(vector == 0) = 0.0000000001; - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Apply SoftMax activation function +% +% ------------- Updates ------------- +% 2011-10-09 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function vector = SoftMax(vector) + +%% Manual + %vector = vector - min(vector); % Offset negative numbers + vector(vector < 0) = 0; % Remove negative numbers + vector = vector ./ sum(vector); + + + +%% Automatic +% vector = softmax(vector); + + +%% Validations + + % The softmax function can returns NaN + if find(isnan(vector)) + vector(isnan(vector)) = 1; + end + + % Replace 0 for small values + vector(vector == 0) = 0.0000000001; + + diff --git a/PatRec/TacTestResults.m b/PatRec/TacTestResults.m index 8ea15a3..06cf494 100644 --- a/PatRec/TacTestResults.m +++ b/PatRec/TacTestResults.m @@ -1,155 +1,156 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to print the results of the TAC test -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-07-17 / Nichlas Sander / Created the file from MotionTest and -% changed accordingly - -function tacTest = TacTestResults(tacTest) - -nSucct = zeros(tacTest.trials,tacTest.combinations); - -% General matrix -for t = 1 : tacTest.trials - for r = 1 : tacTest.nR - for m = 1 : tacTest.combinations - selectionTime(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).selectionTime; - compTime(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).completionTime; - movements{t,m} = tacTest.trialResult(t,r,m).name; -% selTimeTW(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).selTimeTW; -% compTimeTW(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).compTimeTW; - pathEfficiency(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).pathEfficiency; - % Check the numer of succesful trails - if ~tacTest.trialResult(t,r,m).fail - nSucct(t,m) = nSucct(t,m) + 1; % Number of succesful trials - end - end - end -end - -%Save the first repetition of selectionTime and compTime. -selectionTime1 = zeros(size(selectionTime)); -selectionTime1 = selectionTime(1:tacTest.nR,1:tacTest.combinations); -comptime1 = zeros(size(compTime)); -compTime1 = compTime(1:tacTest.nR,1:tacTest.combinations); - - -%Add all movements in first trial to corresponding in later ones. -if tacTest.trials > 1 - %Set the success-rate to the first row. - for i = 1:tacTest.combinations - name = movements{1,i}; - for j = 2:tacTest.trials - for k = 1:tacTest.combinations - if strcmp(name,movements{j,k}) - nSucct(1,i) = nSucct(1,i) + nSucct(j,k); - end - end - end - end - nSucct(2:end,:) = []; - - for i = 1:tacTest.combinations - name = movements{1,i}; - for j = 2:tacTest.trials - for k = 1:tacTest.combinations - if strcmp(name,movements{j,k}) - selectionTime1(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , i) = selectionTime(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , k); - compTime1(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , i) = compTime(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , k); - end - end - end - end - %Remove the names of all other rows than the first row. - movements(2:end,:) = []; -end -compRate = nSucct ./ (tacTest.nR*tacTest.trials); -selectionTime = selectionTime1; -compTime = compTime1; - -%% Add a mean -compRate(end+1) = mean(compRate); -selectionTime(:,end+1) = nanmean(selectionTime,2); -compTime(:,end+1) = nanmean(compTime,2); -pathEfficiency(:,end+1) = nanmean(pathEfficiency,2); - -%% Save results - -tacTest.compRate = compRate; -tacTest.selectionTime = selectionTime; -tacTest.compTime = compTime; -% tacTest.selTimeTW = selTimeTW; -% tacTest.compTimeTW = compTimeTW; -tacTest.pathEfficiency = pathEfficiency; - -%% plot and save results -% Completion rate -figure(); -plot(compRate,'r-*'); -title('Completion rate'); -xlabel('Movements'); -set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); -ylabel('% of completion'); - -% Completion Time -figure(); -hold on; -if(size(compTime,1) > 1) - plot(nanmean(compTime),'r*'); - boxplot(compTime,'plotstyle','compact'); -else - plot(compTime,'o'); -end -hold off; -title('Completion Time'); -xlabel('Movements'); -set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); -ylabel('Seconds'); - -% Selection Time -figure(); -hold on; -if(size(selectionTime,1) > 1) - plot(nanmean(selectionTime),'r*'); - boxplot(selectionTime,'plotstyle','compact'); -else - plot(selectionTime,'o'); -end -hold off; -title('Selection Time'); -xlabel('Movements'); -set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); -ylabel('Seconds'); - -% % Accuracy -figure(); -hold on; -if(size(pathEfficiency,1) > 1) - plot(nanmean(pathEfficiency),'r*'); - boxplot(pathEfficiency,'plotstyle','compact'); -else - plot(pathEfficiency,'o'); -end -hold off; -title('Path efficiency'); -xlabel('Movements'); -set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); -ylabel('Accuracy'); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to print the results of the TAC test +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-07-17 / Nichlas Sander / Created the file from MotionTest and +% changed accordingly +% 2013-04-27 / Max Ortiz / Addition of movements to tacTest for further +% identification + +function tacTest = TacTestResults(tacTest) + +nSucct = zeros(tacTest.trials,tacTest.combinations); + +% General matrix +for t = 1 : tacTest.trials + for r = 1 : tacTest.nR + for m = 1 : tacTest.combinations + selectionTime(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).selectionTime; + compTime(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).completionTime; + movements{t,m} = tacTest.trialResult(t,r,m).name; +% selTimeTW(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).selTimeTW; +% compTimeTW(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).compTimeTW; + pathEfficiency(r+(tacTest.nR*(t-1)),m) = tacTest.trialResult(t,r,m).pathEfficiency; + % Check the numer of succesful trails + if ~tacTest.trialResult(t,r,m).fail + nSucct(t,m) = nSucct(t,m) + 1; % Number of succesful trials + end + end + end +end + +%Save the first repetition of selectionTime and compTime. +selectionTime1 = zeros(size(selectionTime)); +selectionTime1 = selectionTime(1:tacTest.nR,1:tacTest.combinations); +comptime1 = zeros(size(compTime)); +compTime1 = compTime(1:tacTest.nR,1:tacTest.combinations); + + +%Add all movements in first trial to corresponding in later ones. +if tacTest.trials > 1 + %Set the success-rate to the first row. + for i = 1:tacTest.combinations + name = movements{1,i}; + for j = 2:tacTest.trials + for k = 1:tacTest.combinations + if strcmp(name,movements{j,k}) + nSucct(1,i) = nSucct(1,i) + nSucct(j,k); + end + end + end + end + nSucct(2:end,:) = []; + + for i = 1:tacTest.combinations + name = movements{1,i}; + for j = 2:tacTest.trials + for k = 1:tacTest.combinations + if strcmp(name,movements{j,k}) + selectionTime1(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , i) = selectionTime(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , k); + compTime1(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , i) = compTime(((j-1)*tacTest.nR)+1 : ((j-1)*tacTest.nR)+tacTest.nR , k); + end + end + end + end + %Remove the names of all other rows than the first row. + movements(2:end,:) = []; +end +compRate = nSucct ./ (tacTest.nR*tacTest.trials); +selectionTime = selectionTime1; +compTime = compTime1; + +%% Add a mean +compRate(end+1) = mean(compRate); +selectionTime(:,end+1) = nanmean(selectionTime,2); +compTime(:,end+1) = nanmean(compTime,2); +pathEfficiency(:,end+1) = nanmean(pathEfficiency,2); + +%% Save results + +tacTest.compRate = compRate; +tacTest.selectionTime = selectionTime; +tacTest.compTime = compTime; +tacTest.pathEfficiency = pathEfficiency; +tacTest.movements = movements; + +%% plot and save results +% Completion rate +figure(); +plot(compRate,'r-*'); +title('Completion rate'); +xlabel('Movements'); +set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); +ylabel('% of completion'); + +% Completion Time +figure(); +hold on; +if(size(compTime,1) > 1) + plot(nanmean(compTime),'r*'); + boxplot(compTime,'plotstyle','compact'); +else + plot(compTime,'o'); +end +hold off; +title('Completion Time'); +xlabel('Movements'); +set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); +ylabel('Seconds'); + +% Selection Time +figure(); +hold on; +if(size(selectionTime,1) > 1) + plot(nanmean(selectionTime),'r*'); + boxplot(selectionTime,'plotstyle','compact'); +else + plot(selectionTime,'o'); +end +hold off; +title('Selection Time'); +xlabel('Movements'); +set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); +ylabel('Seconds'); + +% % Accuracy +figure(); +hold on; +if(size(pathEfficiency,1) > 1) + plot(nanmean(pathEfficiency),'r*'); + boxplot(pathEfficiency,'plotstyle','compact'); +else + plot(pathEfficiency,'o'); +end +hold off; +title('Path efficiency'); +xlabel('Movements'); +set(gca,'XTick',1:length(movements)+1,'XtickLabel',[movements 'Mean']); +ylabel('Accuracy'); + diff --git a/PatRec/Topologies/PatRec_AgoAntagonist.m b/PatRec/Topologies/PatRec_AgoAntagonist.m index 595273f..d603552 100644 --- a/PatRec/Topologies/PatRec_AgoAntagonist.m +++ b/PatRec/Topologies/PatRec_AgoAntagonist.m @@ -1,89 +1,89 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of the Ago-antagonist -% scheme. -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% 2012-03-06 / Max Ortiz / Creation from PatRec_AgoAntagonistAndMixed to do -% not considered the Mixed - -function [outMov outVector] = PatRec_AgoAntagonist(patRec, x) - - if strcmp(patRec.mov(end),'Rest') - restFlag = 1; - tempRest = []; - else - restFlag = 0; - end - outVector = []; - outMov = []; - movIdx = 1; - - for j = 1 : size(patRec.patRecTrained,2) - [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrained(j),x); - % Create outVector - if restFlag - tempRest = [tempRest ; outVectorTemp(end)]; - end - outVector = [outVector ; outVectorTemp(1:2)]; - - - % How many patterns were predicted? - nPredMov = length(outMovTemp); - if nPredMov > 0 - if restFlag - if outVectorTemp(1) > outVectorTemp(2) - outMov(end+1) = movIdx; - elseif outVectorTemp(2) > outVectorTemp(3) - outMov(end+1) = movIdx+1; - end - - % The following line doesn't worn since it does't consider - % that some classifier can predict several outputs. - %if outMovTemp ~= 3 - % outMov(end+1) = outMovTemp + (2*(j-1)); - %end - else - if outVectorTemp(1) > outVectorTemp(2) - outMov(end+1) = movIdx; - else - outMov(end+1) = movIdx+1; - end - % The following line doesn't worn since it does't consider - % that some classifier can predict several outputs. - %outMov(end+1) = outMovTemp + (2*(j-1)); - end - - end - movIdx = movIdx + 2; - end - - % Add the average of rest to the outVector - if restFlag - outVector(end+1) = mean(tempRest); - % Select rest if nothing else is selected - if isempty(outMov) - outMov = size(outVector,1); - end - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of the Ago-antagonist +% scheme. +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2012-03-06 / Max Ortiz / Creation from PatRec_AgoAntagonistAndMixed to do +% not considered the Mixed + +function [outMov outVector] = PatRec_AgoAntagonist(patRec, x) + + if strcmp(patRec.mov(end),'Rest') + restFlag = 1; + tempRest = []; + else + restFlag = 0; + end + outVector = []; + outMov = []; + movIdx = 1; + + for j = 1 : size(patRec.patRecTrained,2) + [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrained(j),x); + % Create outVector + if restFlag + tempRest = [tempRest ; outVectorTemp(end)]; + end + outVector = [outVector ; outVectorTemp(1:2)]; + + + % How many patterns were predicted? + nPredMov = length(outMovTemp); + if nPredMov > 0 + if restFlag + if outVectorTemp(1) > outVectorTemp(2) + outMov(end+1) = movIdx; + elseif outVectorTemp(2) > outVectorTemp(3) + outMov(end+1) = movIdx+1; + end + + % The following line doesn't worn since it does't consider + % that some classifier can predict several outputs. + %if outMovTemp ~= 3 + % outMov(end+1) = outMovTemp + (2*(j-1)); + %end + else + if outVectorTemp(1) > outVectorTemp(2) + outMov(end+1) = movIdx; + else + outMov(end+1) = movIdx+1; + end + % The following line doesn't worn since it does't consider + % that some classifier can predict several outputs. + %outMov(end+1) = outMovTemp + (2*(j-1)); + end + + end + movIdx = movIdx + 2; + end + + % Add the average of rest to the outVector + if restFlag + outVector(end+1) = mean(tempRest); + % Select rest if nothing else is selected + if isempty(outMov) + outMov = size(outVector,1); + end + end + end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_AgoAntagonistAndMixed.m b/PatRec/Topologies/PatRec_AgoAntagonistAndMixed.m index fd134e0..6c1ed94 100644 --- a/PatRec/Topologies/PatRec_AgoAntagonistAndMixed.m +++ b/PatRec/Topologies/PatRec_AgoAntagonistAndMixed.m @@ -1,80 +1,107 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of the Ago-antagonist -% scheme. -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-12-04 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update -function [outMov outVector] = PatRec_AgoAntagonistAndMixed(patRec, x) - - % Variables init - if strcmp(patRec.mov(end),'Rest') - restFlag = 1; - tempRest = []; - else - restFlag = 0; - end - outVector = []; - outMov = []; - movIdx = 1; - - % Go through all DoF - for j = 1 : size(patRec.patRecTrained,2) - % Run PatRec - [outMovTemp outMatrix(:,j)] = OneShotPatRec(patRec.patRecTrained(j),x); - - % Find the winner looking at the outVector - % If rest or the mixed class are the winners, outMov is not - % modified - [mMax mIdx] = max(outMatrix(:,j)); - nPredMov = length(outMovTemp); - if nPredMov > 0 & outMovTemp ~= 0 - if mIdx == 1 - outMov(end+1) = movIdx; - elseif mIdx == 2; - outMov(end+1) = movIdx +1; - end - end - movIdx = movIdx + 2; - - % Create outVector - outVector = [outVector ; outMatrix(1:2,j)]; - if restFlag - tempRest = [tempRest ; outMatrix(end,j)]; - end - - - end - % If no movement was predicted and rest exist, then rest it is. - % Add the average of rest to the outVector - if restFlag - outVector(end+1) = mean(tempRest); - % Select rest if nothing else is selected - if isempty(outMov) - outMov = size(outVector,1); - end - end - - % To comply with standard outMov format - outMov = outMov'; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of the Ago-antagonist +% scheme. +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-04 / Max Ortiz / Creation +% 2012-01-26 / Max Ortiz / Fixed bug on predictions outMovTemp = 0 +% 2013-03-03 / Max Ortiz / Revision of the whole prediction chain and +% simplification of the outMov computation +% 20xx-xx-xx / Author / Comment on update + +function [outMov outVector] = PatRec_AgoAntagonistAndMixed(patRec, x) + + % Variables init + if strcmp(patRec.mov(end),'Rest') + restFlag = 1; + tempRest = []; + else + restFlag = 0; + end + outVector = []; + outMov = []; + movIdx = 1; + + % Go through all DoF + for j = 1 : size(patRec.patRecTrained,2) + % Run PatRec + [outMovTemp outMatrix(:,j)] = OneShotPatRec(patRec.patRecTrained(j),x); + + % Create the outMov vector using the winners from each classifier + if length(outMovTemp) == 1 + if outMovTemp == 1 + outMov(end+1) = movIdx; + elseif outMovTemp == 2; + outMov(end+1) = movIdx +1; + end + + % If there is more than 1 movement predicted, take the highest + elseif length(outMovTemp) >= 1 + [mMax mIdx] = max(outMatrix(:,j)); + if mIdx == 1 + outMov(end+1) = movIdx; + elseif mIdx == 2; + outMov(end+1) = movIdx +1; + end + end + +% Code prior 2013-03-03 +% % Find the winner looking at the outVector +% % This is done to handle cases where outMovTemp has more than 1 value +% % If rest or the mixed class are the winners, outMov is not +% % modified +% [mMax mIdx] = max(outMatrix(:,j)); +% nPredMov = length(outMovTemp); +% if nPredMov > 0 & outMovTemp ~= 0 +% if mIdx == 1 +% outMov(end+1) = movIdx; +% elseif mIdx == 2; +% outMov(end+1) = movIdx +1; +% end +% end + + % Increase the Index number for the movements + movIdx = movIdx + 2; + + % Create outVector + outVector = [outVector ; outMatrix(1:2,j)]; + if restFlag + tempRest = [tempRest ; outMatrix(end,j)]; + end + + + end + % If no movement was predicted and rest exist, then rest it is. + % Add the average of rest to the outVector (this is not the best + % computation of the strenght of the rest prediction) + if restFlag + outVector(end+1) = mean(tempRest); + % Select rest if nothing else is selected + if isempty(outMov) + outMov = size(outVector,1); + end + end + + % To comply with standard outMov format + outMov = outMov'; end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_AllAndOne.m b/PatRec/Topologies/PatRec_AllAndOne.m index 0106c59..5fc0116 100644 --- a/PatRec/Topologies/PatRec_AllAndOne.m +++ b/PatRec/Topologies/PatRec_AllAndOne.m @@ -1,60 +1,60 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of the All-and-One scheme -% which is a combination between One-Vs-All and One-Vs-One where ... -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ---------------------------------- Updates ------------------------------ -% 2011-12-06 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update -function [outMov outVector] = PatRec_AllAndOne(patRec, x) - - outVector = []; - - % One-Vs-All Computation - for j = 1 : size(patRec.patRecTrained,2) - [outMovTemp outMatrix(:,j)] = OneShotPatRec(patRec.patRecTrained(j),x); - % Create the out Vector by gathering the probability of each - % movement to happen - outVector = [outVector ; outMatrix(1,j)]; - end - - % Sort the best patterns - [Y, I] = sort(outVector,'descend'); - bestMov = I(1:2)'; - - % Order the winners for later comparasion OVO - if bestMov(1) > bestMov(2) - m(1) = bestMov(2); - m(2) = bestMov(1); - else - m = bestMov; - end - - % One-Vs-One Computation - [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrainedAux(m(1),m(2)),x); - if outMovTemp == 0 - outMov = bestMov(1); - else - outMov = m(outMovTemp); - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of the All-and-One scheme +% which is a combination between One-Vs-All and One-Vs-One where ... +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ---------------------------------- Updates ------------------------------ +% 2011-12-06 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function [outMov outVector] = PatRec_AllAndOne(patRec, x) + + outVector = []; + + % One-Vs-All Computation + for j = 1 : size(patRec.patRecTrained,2) + [outMovTemp outMatrix(:,j)] = OneShotPatRec(patRec.patRecTrained(j),x); + % Create the out Vector by gathering the probability of each + % movement to happen + outVector = [outVector ; outMatrix(1,j)]; + end + + % Sort the best patterns + [Y, I] = sort(outVector,'descend'); + bestMov = I(1:2)'; + + % Order the winners for later comparasion OVO + if bestMov(1) > bestMov(2) + m(1) = bestMov(2); + m(2) = bestMov(1); + else + m = bestMov; + end + + % One-Vs-One Computation + [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrainedAux(m(1),m(2)),x); + if outMovTemp == 0 + outMov = bestMov(1); + else + outMov = m(outMovTemp); + end + end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_OneVsAll.m b/PatRec/Topologies/PatRec_OneVsAll.m index b71259b..467a9b1 100644 --- a/PatRec/Topologies/PatRec_OneVsAll.m +++ b/PatRec/Topologies/PatRec_OneVsAll.m @@ -1,49 +1,49 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of the binary classifier -% One-Versus-All -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-12-04 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update -function [outMov outVector] = PatRec_OneVsAll(patRec, x) - - outVector = []; - outMov = []; - for j = 1 : size(patRec.patRecTrained,2) - [outMovTemp outMatrix] = OneShotPatRec(patRec.patRecTrained(j),x); - - % Is one or all the winner? - nPredMov = length(outMovTemp); - if nPredMov > 0 - if outMatrix(1) > outMatrix(2) - outMov(end+1) = j; - end - end - % Create the out Vector by gathering the probability of each - % movement to happen - outVector = [outVector ; outMatrix(1)]; - end - - % To comply with standard outMov format - outMov = outMov'; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of the binary classifier +% One-Versus-All +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-04 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function [outMov outVector] = PatRec_OneVsAll(patRec, x) + + outVector = []; + outMov = []; + for j = 1 : size(patRec.patRecTrained,2) + [outMovTemp outMatrix] = OneShotPatRec(patRec.patRecTrained(j),x); + + % Is one or all the winner? + nPredMov = length(outMovTemp); + if nPredMov > 0 + if outMatrix(1) > outMatrix(2) + outMov(end+1) = j; + end + end + % Create the out Vector by gathering the probability of each + % movement to happen + outVector = [outVector ; outMatrix(1)]; + end + + % To comply with standard outMov format + outMov = outMov'; end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_OneVsAllT.m b/PatRec/Topologies/PatRec_OneVsAllT.m new file mode 100644 index 0000000..f585802 --- /dev/null +++ b/PatRec/Topologies/PatRec_OneVsAllT.m @@ -0,0 +1,48 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of the Ago-antagonist +% scheme. +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-04 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function [outMov outVector] = PatRec_OneVsAllT(patRec, x) + + outVector = []; + outMov = []; + outThrs = 0.5; + + for j = 1 : size(patRec.patRecTrained,2) + [outMovTemp outMatrix(:,j)] = OneShotPatRec(patRec.patRecTrained(j),x); + % Create the out Vector by gathering the probability of each + % movement to happen + outVector = [outVector ; outMatrix(1,j)]; + end + + % Use of a threshold + for i = 1 : size(outVector,1) + if outVector(i) >= outThrs + outMov(end+1) = i; + end + end + +end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_OneVsOne.m b/PatRec/Topologies/PatRec_OneVsOne.m index a50a30c..d017600 100644 --- a/PatRec/Topologies/PatRec_OneVsOne.m +++ b/PatRec/Topologies/PatRec_OneVsOne.m @@ -1,73 +1,73 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of One Vs One topology -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-12-04 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update -function [outMov outVector] = PatRec_OneVsOne(patRec, x) - - % Initialize matrices - outMovMatrix = zeros(size(patRec.patRecTrained,2),size(patRec.patRecTrained,2)); - outMatrix = outMovMatrix; - nOut = size(patRec.patRecTrained,1); - - % Compute the output of each classification - for j = 1 : size(patRec.patRecTrained,1) - for k = j+1 : size(patRec.patRecTrained,2) - [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrained(j,k),x); - - % How many patterns were predicted? - nPredMov = length(outMovTemp); - if nPredMov > 0 - % Count the victories of each pattern - if outVectorTemp(1) > outVectorTemp(2) - outMovMatrix(j,k) = 1; - outMovMatrix(k,j) = 0; - else - outMovMatrix(j,k) = 0; - outMovMatrix(k,j) = 1; - end - % Non-of them was predicted - else - outMovMatrix(j,k) = 0; - outMovMatrix(k,j) = 0; - end - outMatrix(j,k) = outVectorTemp(1); - outMatrix(k,j) = outVectorTemp(2); - end - end - - % Ouput selection by probability -% outVector = sum(outMovMatrix,2)./ (size(outMovMatrix,1) - 1); -% outMov = find(outVector > 0.80); - - % Output selection by threshold -% outVector = sum(outMovMatrix,2); -% outMov = find(outVector > patRec.nOut-1); - - - % Output selection by majority voting - outVector = sum(outMovMatrix,2); - [outMax outMov] = max(outVector); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of One Vs One topology +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-04 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function [outMov outVector] = PatRec_OneVsOne(patRec, x) + + % Initialize matrices + outMovMatrix = zeros(size(patRec.patRecTrained,2),size(patRec.patRecTrained,2)); + outMatrix = outMovMatrix; + nOut = size(patRec.patRecTrained,1); + + % Compute the output of each classification + for j = 1 : size(patRec.patRecTrained,1) + for k = j+1 : size(patRec.patRecTrained,2) + [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrained(j,k),x); + + % How many patterns were predicted? + nPredMov = length(outMovTemp); + if nPredMov > 0 + % Count the victories of each pattern + if outVectorTemp(1) > outVectorTemp(2) + outMovMatrix(j,k) = 1; + outMovMatrix(k,j) = 0; + else + outMovMatrix(j,k) = 0; + outMovMatrix(k,j) = 1; + end + % Non-of them was predicted + else + outMovMatrix(j,k) = 0; + outMovMatrix(k,j) = 0; + end + outMatrix(j,k) = outVectorTemp(1); + outMatrix(k,j) = outVectorTemp(2); + end + end + + % Ouput selection by probability +% outVector = sum(outMovMatrix,2)./ (size(outMovMatrix,1) - 1); +% outMov = find(outVector > 0.80); + + % Output selection by threshold +% outVector = sum(outMovMatrix,2); +% outMov = find(outVector > patRec.nOut-1); + + + % Output selection by majority voting + outVector = sum(outMovMatrix,2); + [outMax outMov] = max(outVector); + end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_OneVsOneDoF.m b/PatRec/Topologies/PatRec_OneVsOneDoF.m new file mode 100644 index 0000000..184c71d --- /dev/null +++ b/PatRec/Topologies/PatRec_OneVsOneDoF.m @@ -0,0 +1,114 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of One Vs One topology but +% it adds the modification of removing the losing movement of each DoF +% before the final computation +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-04 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update +function [outMov outVector] = PatRec_OneVsOneDoF(patRec, x) + + % Initialize matrices + outMovMatrix = zeros(size(patRec.patRecTrained,2),size(patRec.patRecTrained,2)); + outMatrix = outMovMatrix; + + % Compute the output of each classification + for j = 1 : size(patRec.patRecTrained,1) + for k = j+1 : size(patRec.patRecTrained,2) + [outMovTemp outVectorTemp] = OneShotPatRec(patRec.patRecTrained(j,k),x); + % How many patterns were predicted? + nPredMov = length(outMovTemp); + if nPredMov > 0 + % Count the victories of each pattern + if outVectorTemp(1) > outVectorTemp(2) + outMovMatrix(j,k) = 1; + outMovMatrix(k,j) = 0; + else + outMovMatrix(j,k) = 0; + outMovMatrix(k,j) = 1; + end + end + outMatrix(j,k) = outVectorTemp(1); + outMatrix(k,j) = outVectorTemp(2); + end + end + + % Remove rest from the outMatrix +% if strcmp(patRec.mov(end),'Rest') +% outMatrix = outMatrix(1:end-1,1:end-1); +% end + + % Make 0 the lossing moving in the same DoF + for j = 1 : 2 : size(patRec.patRecTrained,1) + if outMovMatrix(j,j+1) == 1 + outMovMatrix(j+1,:) = 0; + outMatrix(j+1,:) = 0; + else + outMovMatrix(j,:) = 0; + outMatrix(j,:) = 0; + end + % Try by adding an extra point to the winner + %outVector(j) = outVector(j) + outMovMatrix(j,j+1); + %outVector(j+1) = outVector(j+1) + outMovMatrix(j+1,j); + end + + % Get the outVector (average) +% outVector = sum(outMatrix,2)./ (size(outMatrix,1) - 1); + outVector = sum(outMovMatrix,2)./ (size(outMovMatrix,1) - 1); + outMov = find(sum(outMovMatrix,2) >= (size(outMovMatrix,1) - 2)); + + +% % ANN delivers simultaneous prediction directly +% if strcmp(patRec.patRecTrained(1,2).algorithm,'ANN') +% % Giving good results: +% %outVector = sum(outMatrix,2)./(size(patRec.patRecTrained,1)/2); +% % Considering the mean +% %outVector = sum(outMatrix,2)./((size(outMatrix,1) - 2)/2); +% % Mean with reduction by threshold +% outVector = sum(outMatrix,2)./ (((size(outMatrix,1) - 2)/2)+.5); +% outMov = find(round(outVector)); +% % NOTE: Threshold needs to be implemented in outMov not in +% % outVector +% else +% outVector = sum(outMovMatrix,2); +% end + + + % Check if "rest" exist and select it if nothing else is fired + if strcmp(patRec.mov(end),'Rest') && isempty(find(round(outVector), 1)) + outVector(end+1) = 1; + end + + % Check againt rest +% if strcmp(patRec.mov(end),'Rest') +% %Get the winner without rest +% [outMax outMov] = max(outVector(1:end-1)); +% if outMovMatrix(outMov,end) == 1 +% outVector(end) = 0; +% end +% end + + +% [outMax outMov] = max(outVector); + +end \ No newline at end of file diff --git a/PatRec/Topologies/PatRec_SingleClassifier.m b/PatRec/Topologies/PatRec_SingleClassifier.m index 92a6da8..b831cc3 100644 --- a/PatRec/Topologies/PatRec_SingleClassifier.m +++ b/PatRec/Topologies/PatRec_SingleClassifier.m @@ -1,34 +1,34 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute the classification output of a single classifier -% Simple function to keep standarizeed the call for different classifiers -% topologies -% -% outMov : Index of the selected patterns -% outVector : Vector the raw classification output -% -% ------------------------- Updates & Contributors ------------------------ -% 2011-12-08 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [outMov outVector] = PatRec_SingleClassifier(patRec, x) - - [outMov outVector] = OneShotPatRec(patRec.patRecTrained,x); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute the classification output of a single classifier +% Simple function to keep standarizeed the call for different classifiers +% topologies +% +% outMov : Index of the selected patterns +% outVector : Vector the raw classification output +% +% ------------------------- Updates & Contributors ------------------------ +% 2011-12-08 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [outMov outVector] = PatRec_SingleClassifier(patRec, x) + + [outMov outVector] = OneShotPatRec(patRec.patRecTrained,x); + end \ No newline at end of file diff --git a/PatRec/UseDefaults.m b/PatRec/UseDefaults.m new file mode 100644 index 0000000..b191ea6 --- /dev/null +++ b/PatRec/UseDefaults.m @@ -0,0 +1,168 @@ +%BioPatRec Data Treatment Process: +function UseDefaults(button, simultaneous) +[file, path] = uigetfile({'*.mat';'*.csv'}); +load([path,file]); +set(button, 'String', 'Wait'); +progress = waitbar(0,'PreProcessing'); +drawnow; +handles = NaN; + + if isfield(recSession,'trdata') + recSession = rmfield(recSession,'trdata'); + end + if isfield(recSession,'cTp') + recSession = rmfield(recSession,'cTp'); + end + + if isfield(recSession,'nCh') + nCh = recSession.nCh; + if length(recSession.nCh) == 1 + recSession.nCh = 1:recSession.nCh; + nCh = recSession.nCh; + end + else + nCh = 1:length(recSession.tdata(1,:,1)); + recSession.nCh = nCh; + end + +%Signal Treatment +sigTreated = RemoveTransient_cTp(recSession, 0.7); +sigTreated = AddRestAsMovement(sigTreated, recSession); +waitbar(0.2,progress); +nw = fix(sigTreated.cT * sigTreated.cTp * sigTreated.nR / 0.2); +trP = 0.4; +vP = 0.2; +tP = 0.4; + +sigTreated.eCt = sigTreated.cT*sigTreated.cTp; +overlap = 0.05; +tT = sigTreated.cT * sigTreated.cTp * sigTreated.nR; +tw = 0.2; +offset = ceil(tw/overlap); +nw = fix(tT / overlap) - offset; +trN = fix(trP * nw); +vN = fix( vP* nw); +tN = fix(tP * nw); + while trN+vN+tN < nw + tN = tN + 1; + end +%Treat +sigTreated.trSets = trN; +sigTreated.vSets = vN; +sigTreated.tSets = tN; +sigTreated.nW = nw; +sigTreated.tW = tw; +sigTreated.wOverlap = overlap; +sigTreated.fFilter = 'None'; +sigTreated.sFilter = 'None'; + +sigTreated.twSegMethod = 'Overlapped Cons'; +waitbar(0.4,progress,'Treating'); + +%% Split the data into the time windows +[trData, vData, tData] = GetData(sigTreated); +%Remove raw trated data +sigTreated = rmfield(sigTreated,'trData'); +% add the new sets of tw for tr, v and t +sigTreated.trData = trData; +sigTreated.vData = vData; +sigTreated.tData = tData; + +%sigFeatures = GetAllSigFeatures(handles, sigTreated); +sigFeatures.sF = sigTreated.sF; +sigFeatures.tW = sigTreated.tW; +sigFeatures.nCh = sigTreated.nCh; +sigFeatures.mov = sigTreated.mov; + +% temporal conditional to keep compatibility with olrder rec session +if isfield(sigTreated,'dev') + sigFeatures.dev = sigTreated.dev; +else + sigFeatures.dev = 'Unknow'; +end + +if isfield(sigTreated,'comm') + sigFeatures.comm = sigTreated.comm; + if strcmp(sigFeatures.comm, 'COM') + if isfield(sigTreated,'comn') + sigFeatures.comn = sigTreated.comn; + end + end +else + sigFeatures.comm = 'N/A'; +end + +sigFeatures.fFilter = sigTreated.fFilter; +sigFeatures.sFilter = sigTreated.sFilter; +sigFeatures.trSets = sigTreated.trSets; +sigFeatures.vSets = sigTreated.vSets; +sigFeatures.tSets = sigTreated.tSets; +waitbar(0.5,progress,'Treating'); +nM = sigTreated.nM; % Number of exercises + +for m = 1: nM + for i = 1 : sigTreated.trSets + trFeatures(i,m) = GetSigFeatures(sigTreated.trData(:,:,m,i),sigTreated.sF); + end +end +waitbar(0.6,progress,'Treating'); +for m = 1: nM + for i = 1 : sigTreated.vSets + vFeatures(i,m) = GetSigFeatures(sigTreated.vData(:,:,m,i),sigTreated.sF); + end +end +waitbar(0.7,progress,'Treating'); +for m = 1: nM + for i = 1 : sigTreated.tSets + %tFeatures(i,m) = analyze_signal(sigTreated.tData(:,:,m,i),sigTreated.sF); + tFeatures(i,m) = GetSigFeatures(sigTreated.tData(:,:,m,i),sigTreated.sF); + end +end +waitbar(0.75,progress,'Treating'); +sigFeatures.trFeatures = trFeatures; +sigFeatures.vFeatures = vFeatures; +sigFeatures.tFeatures = tFeatures; +%Offline PatRec (Top4+tcard, LDA, OvsO) +%%sigFeatures = get(handles.t_sigFeatures,'UserData'); +sigFeatures.eTrSets = trN; +sigFeatures.eVSets = vN; +sigFeatures.eTSets = tN; +%?No-norm set? +%?No-feature reduction? +waitbar(0.85,progress,'Training'); +if (strcmp(simultaneous,'false')) +movMix = 'Individual Mov'; +randFeatures = true; +confMatFlag = false; +alg = 'Discriminant A.'; +tType = 'linear'; +topology = 'One-vs-One'; +selFeatures = {'tmabs';'twl';'tzc';'tslpch2';'tcard'}; +normSets = 'Select Normalization'; +algConf = []; +featReducAlg = 'Select Reduc./Selec.'; +patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSets, alg, tType, algConf, movMix, topology, confMatFlag, featReducAlg); +handles.patRec = patRec; +Load_patRec(handles.patRec, 'GUI_TestPatRec_Mov2Mov',1); +set(button, 'String', 'Train Individual Mov)'); +waitbar(1,progress,'Training'); +close(progress); +else +movMix = 'Mixed Output'; +randFeatures = true; +confMatFlag = false; +alg = 'MLP'; +tType = 'Backpropagation'; +topology = 'Ago-antagonistAndMixed'; +selFeatures = {'tmabs';'twl';'tzc';'tslpch2';'tcard'}; +normSets = 'Midrange0Range2'; +algConf = []; +featReducAlg = 'Select Reduc./Selec.'; +patRec = OfflinePatRec(sigFeatures, selFeatures, randFeatures, normSets, alg, tType, algConf, movMix, topology, confMatFlag, featReducAlg); +handles.patRec = patRec; +Load_patRec(handles.patRec, 'GUI_TestPatRec_Mov2Mov',1); +set(button, 'String', 'Train Simultaneous Mov'); +waitbar(1,progress,'Training'); +close(progress); +end +end \ No newline at end of file diff --git a/SigFeatures/ExtractSets_Stack.m b/SigFeatures/ExtractSets_Stack.m index 8dc9813..99d8e79 100644 --- a/SigFeatures/ExtractSets_Stack.m +++ b/SigFeatures/ExtractSets_Stack.m @@ -1,78 +1,78 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function extract the corresponding set of selected movements. -% It keeps the format of xSets and xOuts but only with the rows -% corresponding to the selected movements (selSets) -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-11-29 / Max Ortiz / Creation - - -function [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, selSets) - - % Init the matrices - trSetsX = []; - trOutsX = []; - vSetsX = []; - vOutsX = []; - - % Extract the training set - for i = 1 : size(selSets,2) - % Training - setsIdx = find(trOuts(:,selSets(i))); - trSetsX = [trSetsX ; trSets(setsIdx,:)]; - nS = size(setsIdx,1); - % This would only work with equal number of sets per class - % trOutsX(1+(nS*(i-1)):nS*i,i) = 1; - - % This works for different set sizes - if isempty(trOutsX) - trOutsX(1:nS,i) = 1; - else - trOutsX(end+1:end+nS,i) = 1; - end - - % Validation - setsIdx = find(vOuts(:,selSets(i))); - vSetsX = [vSetsX ; vSets(setsIdx,:)]; - nS = size(setsIdx,1); - % This would only work with equal number of sets per class - % vOutsX(1+(nS*(i-1)):nS*i,i) = 1; - - % This works for different set sizes - if isempty(vOutsX) - vOutsX(1:nS,i) = 1; - else - vOutsX(end+1:end+nS,i) = 1; - end - - end - - - % Bad (slow) way -% for i = 1 : size(trOuts,1) -% if find(selSets == find(trOuts(i,:),1)) -% trSetsX = [trSetsX ; trSets(i,:)]; -% trOutsX = [trOutsX ; trOuts(i,:)]; -% end -% end - - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function extract the corresponding set of selected movements. +% It keeps the format of xSets and xOuts but only with the rows +% corresponding to the selected movements (selSets) +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-11-29 / Max Ortiz / Creation + + +function [trSetsX, trOutsX, vSetsX, vOutsX] = ExtractSets_Stack(trSets, trOuts, vSets, vOuts, selSets) + + % Init the matrices + trSetsX = []; + trOutsX = []; + vSetsX = []; + vOutsX = []; + + % Extract the training set + for i = 1 : size(selSets,2) + % Training + setsIdx = find(trOuts(:,selSets(i))); + trSetsX = [trSetsX ; trSets(setsIdx,:)]; + nS = size(setsIdx,1); + % This would only work with equal number of sets per class + % trOutsX(1+(nS*(i-1)):nS*i,i) = 1; + + % This works for different set sizes + if isempty(trOutsX) + trOutsX(1:nS,i) = 1; + else + trOutsX(end+1:end+nS,i) = 1; + end + + % Validation + setsIdx = find(vOuts(:,selSets(i))); + vSetsX = [vSetsX ; vSets(setsIdx,:)]; + nS = size(setsIdx,1); + % This would only work with equal number of sets per class + % vOutsX(1+(nS*(i-1)):nS*i,i) = 1; + + % This works for different set sizes + if isempty(vOutsX) + vOutsX(1:nS,i) = 1; + else + vOutsX(end+1:end+nS,i) = 1; + end + + end + + + % Bad (slow) way +% for i = 1 : size(trOuts,1) +% if find(selSets == find(trOuts(i,:),1)) +% trSetsX = [trSetsX ; trSets(i,:)]; +% trOutsX = [trOutsX ; trOuts(i,:)]; +% end +% end + + +end diff --git a/SigFeatures/ExtractSets_Stack_MixRest.m b/SigFeatures/ExtractSets_Stack_MixRest.m index d98c391..93367a7 100644 --- a/SigFeatures/ExtractSets_Stack_MixRest.m +++ b/SigFeatures/ExtractSets_Stack_MixRest.m @@ -1,115 +1,115 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec, Copyright © 2009 Max J. Ortiz C. -% BioPatRec is free software under the GNU GPL v3, or any later version. -% See the file "LICENSE" for the full license governing this code. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Chalmers -% University of Technology. Valuable authors’ contributions are mentioned -% below and in the acknowledgements in the project web page. -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project, or send your comments to: -% maxo@chalmers.se. -% -% This copyright notice must be kept in this or any new source file linked -% to BioPatRec -% -% -------------------------- Function Description ------------------------- -% This function extract the corresponding set of selected movements. -% It keeps the format of xSets and xOuts but only with the rows -% corresponding to the selected movements (selSets) -% -% It differs from ExtractSets_Stack by also including a mix of ALL the -% remaing movements in sets with a single output. -% -% ------------------------- Updates & Contributors ------------------------ -% 2012-03-04 / Max Ortiz / Creation -% 2012-04-08 / Max Ortiz / Modified to handle mixed-classes - - -function [trSetsX, trOutsX, vSetsX, vOutsX, selSets, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, selSets, movLables) - - %% Init the matrices - trSetsX = []; - trOutsX = []; - vSetsX = []; - vOutsX = []; - - %% Extract the training set - for i = 1 : size(selSets,2) - % Training - trSetsIdx = find(trOuts(:,selSets(i))); - trSetsX = [trSetsX ; trSets(trSetsIdx,:)]; - nTrS = size(trSetsIdx,1); - % This would only work with equal number of sets per class - % trOutsX(1+(nTrS*(i-1)):nTrS*i,i) = 1; - - % This works for different set sizes - if isempty(trOutsX) - trOutsX(1:nTrS,i) = 1; - else - trOutsX(end+1:end+nTrS,i) = 1; - end - - - % Validation - vSetsIdx = find(vOuts(:,selSets(i))); - vSetsX = [vSetsX ; vSets(vSetsIdx,:)]; - nVs = size(vSetsIdx,1); - % This would only work with equal number of sets per class - % vOutsX(1+(nVs*(i-1)):nVs*i,i) = 1; - - % This works for different set sizes - if isempty(vOutsX) - vOutsX(1:nVs,i) = 1; - else - vOutsX(end+1:end+nVs,i) = 1; - end - end - - - %% Get mixed sets - mixSet = []; - % Get index of non selected sets - restSets = zeros(1,size(trOuts,2)); - restSets(selSets) = 1; - - for i = 1 : size(trSets,1) - mask = and(trOuts(i,:), restSets); - if ~mask - mixSet = [mixSet ; trSets(i,:)]; - end - end - - trSetsX = [trSetsX ; mixSet]; - trOutsX(end+1:size(trSetsX,1),end+1) = 1; - - %% Get mixed sets for validation - mixSet = []; - - for i = 1 : size(vSets,1) - mask = and(vOuts(i,:), restSets); - if ~mask - mixSet = [mixSet ; vSets(i,:)]; - end - end - - vSetsX = [vSetsX ; mixSet]; - vOutsX(end+1:size(vSetsX,1),end+1) = 1; - - %% Modify lables and index - % A new lable needs to be created for the mixed sets - if ~strcmp(movLables(end),'Mixed') - movLables(end+1) = {'Mixed'}; - end - selSets(end+1) = size(movLables,1); - - - if size(trSetsX,1) ~= size(trOutsX,1) || size(vSetsX,1) ~= size(vOutsX,1) - disp('Error obtaining the lables in ExtractSets_Stack_AllButSome') - patRec = []; - return; - end - - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec, Copyright © 2009 Max J. Ortiz C. +% BioPatRec is free software under the GNU GPL v3, or any later version. +% See the file "LICENSE" for the full license governing this code. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Chalmers +% University of Technology. Valuable authors’ contributions are mentioned +% below and in the acknowledgements in the project web page. +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project, or send your comments to: +% maxo@chalmers.se. +% +% This copyright notice must be kept in this or any new source file linked +% to BioPatRec +% +% -------------------------- Function Description ------------------------- +% This function extract the corresponding set of selected movements. +% It keeps the format of xSets and xOuts but only with the rows +% corresponding to the selected movements (selSets) +% +% It differs from ExtractSets_Stack by also including a mix of ALL the +% remaing movements in sets with a single output. +% +% ------------------------- Updates & Contributors ------------------------ +% 2012-03-04 / Max Ortiz / Creation +% 2012-04-08 / Max Ortiz / Modified to handle mixed-classes + + +function [trSetsX, trOutsX, vSetsX, vOutsX, selSets, movLables] = ExtractSets_Stack_MixRest(trSets, trOuts, vSets, vOuts, selSets, movLables) + + %% Init the matrices + trSetsX = []; + trOutsX = []; + vSetsX = []; + vOutsX = []; + + %% Extract the training set + for i = 1 : size(selSets,2) + % Training + trSetsIdx = find(trOuts(:,selSets(i))); + trSetsX = [trSetsX ; trSets(trSetsIdx,:)]; + nTrS = size(trSetsIdx,1); + % This would only work with equal number of sets per class + % trOutsX(1+(nTrS*(i-1)):nTrS*i,i) = 1; + + % This works for different set sizes + if isempty(trOutsX) + trOutsX(1:nTrS,i) = 1; + else + trOutsX(end+1:end+nTrS,i) = 1; + end + + + % Validation + vSetsIdx = find(vOuts(:,selSets(i))); + vSetsX = [vSetsX ; vSets(vSetsIdx,:)]; + nVs = size(vSetsIdx,1); + % This would only work with equal number of sets per class + % vOutsX(1+(nVs*(i-1)):nVs*i,i) = 1; + + % This works for different set sizes + if isempty(vOutsX) + vOutsX(1:nVs,i) = 1; + else + vOutsX(end+1:end+nVs,i) = 1; + end + end + + + %% Get mixed sets + mixSet = []; + % Get index of non selected sets + restSets = zeros(1,size(trOuts,2)); + restSets(selSets) = 1; + + for i = 1 : size(trSets,1) + mask = and(trOuts(i,:), restSets); + if ~mask + mixSet = [mixSet ; trSets(i,:)]; + end + end + + trSetsX = [trSetsX ; mixSet]; + trOutsX(end+1:size(trSetsX,1),end+1) = 1; + + %% Get mixed sets for validation + mixSet = []; + + for i = 1 : size(vSets,1) + mask = and(vOuts(i,:), restSets); + if ~mask + mixSet = [mixSet ; vSets(i,:)]; + end + end + + vSetsX = [vSetsX ; mixSet]; + vOutsX(end+1:size(vSetsX,1),end+1) = 1; + + %% Modify lables and index + % A new lable needs to be created for the mixed sets + if ~strcmp(movLables(end),'Mixed') + movLables(end+1) = {'Mixed'}; + end + selSets(end+1) = size(movLables,1); + + + if size(trSetsX,1) ~= size(trOutsX,1) || size(vSetsX,1) ~= size(vOutsX,1) + disp('Error obtaining the lables in ExtractSets_Stack_AllButSome') + patRec = []; + return; + end + + +end diff --git a/SigFeatures/ExtractSets_Stack_MixRestEqual.m b/SigFeatures/ExtractSets_Stack_MixRestEqual.m index 932473a..7420a9b 100644 --- a/SigFeatures/ExtractSets_Stack_MixRestEqual.m +++ b/SigFeatures/ExtractSets_Stack_MixRestEqual.m @@ -1,175 +1,175 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function extract the corresponding set of selected movements. -% It keeps the format of xSets and xOuts but only with the rows -% corresponding to the selected movements (selSets) -% -% It differes from ExtractSets_Stack by also including a mix of the remaing -% movements in sets with a single output. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-12-02 / Max Ortiz / Creation - - -function [trSetsX, trOutsX, vSetsX, vOutsX, selSets, movLables] = ExtractSets_Stack_MixRestEqual(trSets, trOuts, vSets, vOuts, selSets, movLables) - - %% Init the matrices - trSetsX = []; - trOutsX = []; - vSetsX = []; - vOutsX = []; - - %% Extract the training set - for i = 1 : size(selSets,2) - % Training - trSetsIdx = find(trOuts(:,selSets(i))); - trSetsX = [trSetsX ; trSets(trSetsIdx,:)]; - nTrS = size(trSetsIdx,1); - % This would only work with equal number of sets per class - % trOutsX(1+(nTrS*(i-1)):nTrS*i,i) = 1; - - % This works for different set sizes - if isempty(trOutsX) - trOutsX(1:nTrS,i) = 1; - else - trOutsX(end+1:end+nTrS,i) = 1; - end - - % Validation - vSetsIdx = find(vOuts(:,selSets(i))); - vSetsX = [vSetsX ; vSets(vSetsIdx,:)]; - nVs = size(vSetsIdx,1); - % This would only work with equal number of sets per class - % vOutsX(1+(nVs*(i-1)):nVs*i,i) = 1; - - % This works for different set sizes - if isempty(vOutsX) - vOutsX(1:nVs,i) = 1; - else - vOutsX(end+1:end+nVs,i) = 1; - end - - end - - %% Get mixed sets - mixSet = []; - % Get index of non selected sets - restSets = zeros(1,size(trOuts,2)); - restSets(selSets) = 1; - % Setep - movStep = find(~trOuts(:,1)); - movStep = movStep(1)-1; - - % Get sets orderly one per set until the data set is completed - % Doing this sequencially assures that at least 1 set per movemnts is - % included - stopFlag = 0; - for i = 1 : nTrS - for j = i : movStep :size(trSets,1) - mask = and(trOuts(j,:), restSets); - if ~mask - mixSet = [mixSet ; trSets(j,:)]; - end - if size(mixSet,1) == nTrS - stopFlag = 1; - break; - end - end - if stopFlag - break; - end - end - -% %% Get randomly data sets from the training set -% %Randomize Idx -% setIdx = randperm(size(trOuts,1)); -% %Get data sets -% for i = 1 : size(trSets,1) -% mask = and(trOuts(setIdx(i),:), restSets); -% if ~mask -% mixSet = [mixSet ; trSets(setIdx(i),:)]; -% end -% %Stop if the number of mix sets is reached -% if size(mixSet,1) == nTrS -% break; -% end -% end - - trSetsX = [trSetsX ; mixSet]; - trOutsX(end+1:end+nTrS,end+1) = 1; - - %% Get mixed sets for validation - mixSet = []; - % Setep - movStep = find(~vOuts(:,1)); - movStep = movStep(1)-1; - - % Get sets orderly one per set until the data set is completed - stopFlag = 0; - for i = 1 : nVs - for j = i : movStep :size(vSets,1) - mask = and(vOuts(j,:), restSets); - if ~mask - mixSet = [mixSet ; vSets(j,:)]; - end - if size(mixSet,1) == nVs - stopFlag = 1; - break; - end - end - if stopFlag - break; - end - end - - % Get randomly data sets from the validation set -% %Randomize Idx -% setIdx = randperm(size(vOuts,1)); -% %Get data sets -% for i = 1 : size(vSets,1) -% mask = and(vOuts(setIdx(i),:), restSets); -% if ~mask -% mixSet = [mixSet ; vSets(setIdx(i),:)]; -% end -% %Stop if the number of mix sets is reached -% if size(mixSet,1) == nVs -% break; -% end -% end - - vSetsX = [vSetsX ; mixSet]; - vOutsX(end+1:end+nVs,end+1) = 1; - - %% Modify lables and index - % A new lable needs to be created for the mixed sets - if ~strcmp(movLables(end),'Mixed') - movLables(end+1) = {'Mixed'}; - end - selSets(end+1) = size(movLables,1); - - - if size(trSetsX,1) ~= size(trOutsX,1) || size(vSetsX,1) ~= size(vOutsX,1) - disp('Error obtaining the lables in ExtractSets_Stack_AllButSome') - patRec = []; - return; - end - - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function extract the corresponding set of selected movements. +% It keeps the format of xSets and xOuts but only with the rows +% corresponding to the selected movements (selSets) +% +% It differes from ExtractSets_Stack by also including a mix of the remaing +% movements in sets with a single output. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-12-02 / Max Ortiz / Creation + + +function [trSetsX, trOutsX, vSetsX, vOutsX, selSets, movLables] = ExtractSets_Stack_MixRestEqual(trSets, trOuts, vSets, vOuts, selSets, movLables) + + %% Init the matrices + trSetsX = []; + trOutsX = []; + vSetsX = []; + vOutsX = []; + + %% Extract the training set + for i = 1 : size(selSets,2) + % Training + trSetsIdx = find(trOuts(:,selSets(i))); + trSetsX = [trSetsX ; trSets(trSetsIdx,:)]; + nTrS = size(trSetsIdx,1); + % This would only work with equal number of sets per class + % trOutsX(1+(nTrS*(i-1)):nTrS*i,i) = 1; + + % This works for different set sizes + if isempty(trOutsX) + trOutsX(1:nTrS,i) = 1; + else + trOutsX(end+1:end+nTrS,i) = 1; + end + + % Validation + vSetsIdx = find(vOuts(:,selSets(i))); + vSetsX = [vSetsX ; vSets(vSetsIdx,:)]; + nVs = size(vSetsIdx,1); + % This would only work with equal number of sets per class + % vOutsX(1+(nVs*(i-1)):nVs*i,i) = 1; + + % This works for different set sizes + if isempty(vOutsX) + vOutsX(1:nVs,i) = 1; + else + vOutsX(end+1:end+nVs,i) = 1; + end + + end + + %% Get mixed sets + mixSet = []; + % Get index of non selected sets + restSets = zeros(1,size(trOuts,2)); + restSets(selSets) = 1; + % Setep + movStep = find(~trOuts(:,1)); + movStep = movStep(1)-1; + + % Get sets orderly one per set until the data set is completed + % Doing this sequencially assures that at least 1 set per movemnts is + % included + stopFlag = 0; + for i = 1 : nTrS + for j = i : movStep :size(trSets,1) + mask = and(trOuts(j,:), restSets); + if ~mask + mixSet = [mixSet ; trSets(j,:)]; + end + if size(mixSet,1) == nTrS + stopFlag = 1; + break; + end + end + if stopFlag + break; + end + end + +% %% Get randomly data sets from the training set +% %Randomize Idx +% setIdx = randperm(size(trOuts,1)); +% %Get data sets +% for i = 1 : size(trSets,1) +% mask = and(trOuts(setIdx(i),:), restSets); +% if ~mask +% mixSet = [mixSet ; trSets(setIdx(i),:)]; +% end +% %Stop if the number of mix sets is reached +% if size(mixSet,1) == nTrS +% break; +% end +% end + + trSetsX = [trSetsX ; mixSet]; + trOutsX(end+1:end+nTrS,end+1) = 1; + + %% Get mixed sets for validation + mixSet = []; + % Setep + movStep = find(~vOuts(:,1)); + movStep = movStep(1)-1; + + % Get sets orderly one per set until the data set is completed + stopFlag = 0; + for i = 1 : nVs + for j = i : movStep :size(vSets,1) + mask = and(vOuts(j,:), restSets); + if ~mask + mixSet = [mixSet ; vSets(j,:)]; + end + if size(mixSet,1) == nVs + stopFlag = 1; + break; + end + end + if stopFlag + break; + end + end + + % Get randomly data sets from the validation set +% %Randomize Idx +% setIdx = randperm(size(vOuts,1)); +% %Get data sets +% for i = 1 : size(vSets,1) +% mask = and(vOuts(setIdx(i),:), restSets); +% if ~mask +% mixSet = [mixSet ; vSets(setIdx(i),:)]; +% end +% %Stop if the number of mix sets is reached +% if size(mixSet,1) == nVs +% break; +% end +% end + + vSetsX = [vSetsX ; mixSet]; + vOutsX(end+1:end+nVs,end+1) = 1; + + %% Modify lables and index + % A new lable needs to be created for the mixed sets + if ~strcmp(movLables(end),'Mixed') + movLables(end+1) = {'Mixed'}; + end + selSets(end+1) = size(movLables,1); + + + if size(trSetsX,1) ~= size(trOutsX,1) || size(vSetsX,1) ~= size(vOutsX,1) + disp('Error obtaining the lables in ExtractSets_Stack_AllButSome') + patRec = []; + return; + end + + +end diff --git a/SigFeatures/ExtractSigFeature.m b/SigFeatures/ExtractSigFeature.m index f8570ee..4bebffe 100644 --- a/SigFeatures/ExtractSigFeature.m +++ b/SigFeatures/ExtractSigFeature.m @@ -1,40 +1,40 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% The different with GetSigFeatures is that this routines extracts a single -% feature from a complete time series. GetSigFeatures can extract several -% features for a single time window. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-06-03 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function fData = ExtractSigFeature(data,sF,fID) - -tS = size(data,1); % Total samples -twS = 0.2 * sF; % Time window samples, considering tw of 200 ms -overlapS = 0.02*sF; % Overlap samples considering 20 ms -fData = []; - -for i = 1 : overlapS : tS-twS - feature = GetSigFeatures(data(i:i+twS,:), sF, {fID}); - fData = [fData ; feature.(fID)]; -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% The difference with GetSigFeatures is that this routines extracts a single +% feature from a complete time series. GetSigFeatures can extract several +% features for a single time window. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-03 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function fData = ExtractSigFeature(data,sF,fID) + +tS = size(data,1); % Total samples +twS = 0.2 * sF; % Time window samples, considering tw of 200 ms +overlapS = 0.02*sF; % Overlap samples considering 20 ms +fData = []; + +for i = 1 : overlapS : tS-twS + feature = GetSigFeatures(data(i:i+twS,:), sF, {fID}); + fData = [fData ; feature.(fID)]; +end + + diff --git a/SigFeatures/ExtractSigFeatureVar.m b/SigFeatures/ExtractSigFeatureVar.m new file mode 100644 index 0000000..0405126 --- /dev/null +++ b/SigFeatures/ExtractSigFeatureVar.m @@ -0,0 +1,41 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% The difference with GetSigFeatures is that this routines extracts a single +% feature from a complete time series. GetSigFeatures can extract several +% features for a single time window. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-06-03 / Max Ortiz / Creation +% 2014-12-25 / Max Ortiz / Made twS and overlapS input variables +% 20xx-xx-xx / Author / Comment on update + +function fData = ExtractSigFeatureVar(data,sF,fID,twS,overlapS) + +tS = size(data,1); % Total samples +%twS = 0.2 * sF; % Time window samples, considering tw of 200 ms +%overlapS = 0.02*sF; % Overlap samples considering 20 ms +fData = []; + +for i = 1 : overlapS : tS-twS + feature = GetSigFeatures(data(i:i+twS,:), sF, {fID}); + fData = [fData ; feature.(fID)]; +end + + diff --git a/SigFeatures/GetAllSigFeatures.m b/SigFeatures/GetAllSigFeatures.m index f0d26cf..dc33855 100644 --- a/SigFeatures/GetAllSigFeatures.m +++ b/SigFeatures/GetAllSigFeatures.m @@ -1,96 +1,109 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function recieves sigTreated and returns sigFeatures which is a -% matrix of structs of (sets x movements) where each struct contains the -% signals features identfied by their name code (ID) -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-27 / Max Ortiz / Creation from EMG_AQ routines -% 20xx-xx-xx / Author / Comment on update - -function sigFeatures = GetAllSigFeatures(handles, sigTreated) - - sigFeatures.sF = sigTreated.sF; - sigFeatures.tW = sigTreated.tW; - sigFeatures.nCh = sigTreated.nCh; - sigFeatures.mov = sigTreated.mov; - - % temporal conditional to keep compatibility with olrder rec session - if isfield(sigTreated,'dev') - sigFeatures.dev = sigTreated.dev; - else - sigFeatures.dev = 'Unknow'; - end - - sigFeatures.fFilter = sigTreated.fFilter; - sigFeatures.sFilter = sigTreated.sFilter; - sigFeatures.trSets = sigTreated.trSets; - sigFeatures.vSets = sigTreated.vSets; - sigFeatures.tSets = sigTreated.tSets; - - nM = sigTreated.nM; % Number of exercises - - set(handles.t_msg,'String','Extracting ALL features for training...'); - drawnow; - for m = 1: nM - for i = 1 : sigTreated.trSets - trFeatures(i,m) = GetSigFeatures(sigTreated.trData(:,:,m,i),sigTreated.sF); - end - end - - set(handles.t_msg,'String','Extracting ALL features for validation...'); - drawnow; - for m = 1: nM - for i = 1 : sigTreated.vSets - vFeatures(i,m) = GetSigFeatures(sigTreated.vData(:,:,m,i),sigTreated.sF); - end - end - - set(handles.t_msg,'String','Extracting ALL features for testing...'); - drawnow; - for m = 1: nM - for i = 1 : sigTreated.tSets - %tFeatures(i,m) = analyze_signal(sigTreated.tData(:,:,m,i),sigTreated.sF); - tFeatures(i,m) = GetSigFeatures(sigTreated.tData(:,:,m,i),sigTreated.sF); - end - end - - sigFeatures.trFeatures = trFeatures; - sigFeatures.vFeatures = vFeatures; - sigFeatures.tFeatures = tFeatures; - -end -% for e = 1: Ne -% for i = 1 : sigTreated.nw -% iidx = 1 + (assize*(i-1)); -% eidx = assize+(assize*(i-1)); -% tempdata(i,e) = analyze_signal(data(iidx:eidx,:,e),sigTreated.sF); -% end -% end -% -% %trPr = 0.6; % Percentage to be used for training -% %Ntr = round(nR * nTw * trPr); % Compute Number of trainning for the whole contraction time -% %Nv = round(nR * nTw * (1-trPr)/2); % Compute Number of validation -% trSets = sigTreated.trSets; -% vSets = sigTreated.vSets; -% tSets = sigTreated.tSets; -% trdata = tempdata(1:trSets,:); -% vdata = tempdata(trSets+1:trSets+vSets,:); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function recieves sigTreated and returns sigFeatures which is a +% matrix of structs of (sets x movements) where each struct contains the +% signals features identfied by their name code (ID) +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-27 / Max Ortiz / Creation from EMG_AQ routines +% 2014-12-01 / Enzo Mastinu / Added the handling part for the COM port number + % information into the parameters +% 20xx-xx-xx / Author / Comment on update + +function sigFeatures = GetAllSigFeatures(handles, sigTreated) + + sigFeatures.sF = sigTreated.sF; + sigFeatures.tW = sigTreated.tW; + sigFeatures.nCh = sigTreated.nCh; + sigFeatures.mov = sigTreated.mov; + sigFeatures.scaled = sigTreated.scaled; + sigFeatures.noise = sigTreated.noise; + + % temporal conditional to keep compatibility with olrder rec session + if isfield(sigTreated,'dev') + sigFeatures.dev = sigTreated.dev; + else + sigFeatures.dev = 'Unknow'; + end + + if isfield(sigTreated,'comm') + sigFeatures.comm = sigTreated.comm; + if isfield(sigTreated,'comn') + sigFeatures.comn = sigTreated.comn; + end + else + sigFeatures.comm = 'N/A'; + end + + sigFeatures.fFilter = sigTreated.fFilter; + sigFeatures.sFilter = sigTreated.sFilter; + sigFeatures.trSets = sigTreated.trSets; + sigFeatures.vSets = sigTreated.vSets; + sigFeatures.tSets = sigTreated.tSets; + + nM = sigTreated.nM; % Number of exercises + + set(handles.t_msg,'String','Extracting ALL features for training...'); + drawnow; + for m = 1: nM + for i = 1 : sigTreated.trSets + trFeatures(i,m) = GetSigFeatures(sigTreated.trData(:,:,m,i),sigTreated.sF); + end + end + + set(handles.t_msg,'String','Extracting ALL features for validation...'); + drawnow; + for m = 1: nM + for i = 1 : sigTreated.vSets + vFeatures(i,m) = GetSigFeatures(sigTreated.vData(:,:,m,i),sigTreated.sF); + end + end + + set(handles.t_msg,'String','Extracting ALL features for testing...'); + drawnow; + for m = 1: nM + for i = 1 : sigTreated.tSets + %tFeatures(i,m) = analyze_signal(sigTreated.tData(:,:,m,i),sigTreated.sF); + tFeatures(i,m) = GetSigFeatures(sigTreated.tData(:,:,m,i),sigTreated.sF); + end + end + + sigFeatures.trFeatures = trFeatures; + sigFeatures.vFeatures = vFeatures; + sigFeatures.tFeatures = tFeatures; + +end +% for e = 1: Ne +% for i = 1 : sigTreated.nw +% iidx = 1 + (assize*(i-1)); +% eidx = assize+(assize*(i-1)); +% tempdata(i,e) = analyze_signal(data(iidx:eidx,:,e),sigTreated.sF); +% end +% end +% +% %trPr = 0.6; % Percentage to be used for training +% %Ntr = round(nR * nTw * trPr); % Compute Number of trainning for the whole contraction time +% %Nv = round(nR * nTw * (1-trPr)/2); % Compute Number of validation +% trSets = sigTreated.trSets; +% vSets = sigTreated.vSets; +% tSets = sigTreated.tSets; +% trdata = tempdata(1:trSets,:); +% vdata = tempdata(trSets+1:trSets+vSets,:); % tdata = tempdata(trSets+vSets+1:trSets+vSets+tSets,:); \ No newline at end of file diff --git a/SigFeatures/GetFFT.m b/SigFeatures/GetFFT.m index 4b362dc..062b8fe 100644 --- a/SigFeatures/GetFFT.m +++ b/SigFeatures/GetFFT.m @@ -1,50 +1,61 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Routine based in matlab examples, further optimization is probabily -% possible -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% Max Ortiz 2009-04-29 Creation -% Max Ortiz 2011-07-28 Adapted to BioPatRec - - -function pF = GetFFT(pF) - - cF = 1000; - - % Fast Fourier Transform - NFFT = 2^nextpow2(pF.sp); % Next power of 2 from number of samples - dataf = fft(pF.data,NFFT)/pF.sp; % Gets the fast fourier transform - pF.fftData = 2*abs(dataf((1:NFFT/2+1),:)); % Get the half of the data considering abs values, - % since it is simetric and we - % only look at the half, it is multiply for 2 - pF.fftData(1,:) = 0; % The first element is made 0 to reduce artifats of low fqs. - - pF.fftDataT = sum(pF.fftData); % Sum of all frequency contributions - - pF.fV = pF.sF/2*linspace(0,1,NFFT/2+1); % Creates the frequency vector - - % Cuff the matrix to Fc to analysis - cS = round(cF * length(pF.fftData(:,1)) / (pF.sF/2)); - pF.fftData = pF.fftData(1:cS,:); - pF.fV = pF.fV(1:cS); - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Routine based in matlab examples, further optimization is probabily +% possible +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% Max Ortiz 2009-04-29 Creation for EMG_AQ (old BioPatRec) +% Max Ortiz 2011-07-28 Adapted to BioPatRec +% Max Ortiz 2013-10-09 Fixed identation and add commented code for ploting + + +function pF = GetFFT(pF) + + cF = pF.sF/2; + + % Fast Fourier Transform + NFFT = 2^nextpow2(pF.sp); % Next power of 2 from number of samples + dataf = fft(pF.data,NFFT)/pF.sp; % Gets the fast fourier transform + pF.fftData = 2*abs(dataf((1:NFFT/2+1),:)); % Get the half of the data considering abs values, + % since it is simetric and we + % only look at the half, it is multiply for 2 + + pF.fftData(1,:) = 0; % The first element is made 0 to reduce artifats of low fqs. + + pF.fftDataT = sum(pF.fftData); % Sum of all frequency contributions + + pF.fV = pF.sF/2*linspace(0,1,NFFT/2+1); % Creates the frequency vector + + % Plot for visualization if required + % figure(); + % plot(pF.fV,pF.fftData(:,1)) + + % Cuff the matrix to cF for analysis + cF = 1000; % Cut frequency for features stimation + % If sF > 1kH, the estimation of frequency related features + % will be within 0 to 1kH + if pF.fV(end) > cF + cS = round(cF * length(pF.fftData(:,1)) / (pF.sF/2)); + pF.fftData = pF.fftData(1:cS,:); + pF.fV = pF.fV(1:cS); + end + + + diff --git a/SigFeatures/GetSetsLables_Stack.m b/SigFeatures/GetSetsLables_Stack.m index d69dc18..0edb2a4 100644 --- a/SigFeatures/GetSetsLables_Stack.m +++ b/SigFeatures/GetSetsLables_Stack.m @@ -1,58 +1,58 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% Function to obtain the corresponding movements from each raw of data in -% the sets -% -% ------------- Updates ------------- -% 11-06-24 / Max Ortiz / Creation -% 11-11-30 / Max Ortiz / Removed tLables which are never used. - -function [trLables, vLables] = GetSetsLables_Stack(mov, trOut, vOut, movIdxIndv) -%function [trLables, vLables, tLables] = GetSetsLables_Stack(mov, trOut, -%vOut, tOut, movIdxIndv) - - movIndv = mov(movIdxIndv); - - - trLables = []; - vLables = []; - tLables = []; - - for i = 1 : size(trOut,1) - trLables = [trLables;movIndv(find(trOut(i,:)))]; - end - - for i = 1 : size(vOut,1) - vLables = [vLables;movIndv(find(vOut(i,:)))]; - end - -% for i = 1 : length(tOut) -% idxMov = find(tOut(i,:)); -% % check the number of labels involved -% if size(idxMov,2) == 1 -% tLables = [tLables; movIndv(find(tOut(i,:)))]; -% else -% strLabel = []; -% for j = 1 : size(idxMov,2) -% strLabel = [strLabel char(movIndv(idxMov(j))) ' + ']; -% end -% strLabel = strLabel(1:end-3); -% tLables = [tLables; strLabel]; -% end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% Function to obtain the corresponding movements from each raw of data in +% the sets +% +% ------------- Updates ------------- +% 11-06-24 / Max Ortiz / Creation +% 11-11-30 / Max Ortiz / Removed tLables which are never used. + +function [trLables, vLables] = GetSetsLables_Stack(mov, trOut, vOut, movIdxIndv) +%function [trLables, vLables, tLables] = GetSetsLables_Stack(mov, trOut, +%vOut, tOut, movIdxIndv) + + movIndv = mov(movIdxIndv); + + + trLables = []; + vLables = []; + tLables = []; + + for i = 1 : size(trOut,1) + trLables = [trLables;movIndv(find(trOut(i,:)))]; + end + + for i = 1 : size(vOut,1) + vLables = [vLables;movIndv(find(vOut(i,:)))]; + end + +% for i = 1 : length(tOut) +% idxMov = find(tOut(i,:)); +% % check the number of labels involved +% if size(idxMov,2) == 1 +% tLables = [tLables; movIndv(find(tOut(i,:)))]; +% else +% strLabel = []; +% for j = 1 : size(idxMov,2) +% strLabel = [strLabel char(movIndv(idxMov(j))) ' + ']; +% end +% strLabel = strLabel(1:end-3); +% tLables = [tLables; strLabel]; +% end % end \ No newline at end of file diff --git a/SigFeatures/GetSets_Stack.m b/SigFeatures/GetSets_Stack.m index 9e206a9..c7c6616 100644 --- a/SigFeatures/GetSets_Stack.m +++ b/SigFeatures/GetSets_Stack.m @@ -1,99 +1,99 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% % This function will create matrices of training, validation and test sets -% All movements will be STACK one over each other -% -% input: trFeatures contains the splitted data, is a Nsplits x Nexercises structure matrix -% vFeatures is similar to trFeatures -% features contains the name of the charactaristics to be used -% output: trsets are the normalized training sets -% vsets are the normalized validation sets -% trOut contains the correspondet outputs -% vOut contains the correspondet outputs -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-26 / Max Ortiz / Creation -% 2009-07-21 / Max Ortiz / To hanlde "treated_data" struct and selection of the number of set -% 2011-06-24 / Max Ortiz / Update to new coding standard and name to stack - -function [trSet, trOut, vSet, vOut, tSet, tOut] = GetSets_Stack(sigFeatures, features) - -nM = length(sigFeatures.trFeatures(1,:)); % Number of movements -trSets = sigFeatures.eTrSets; % effective number of sets for trainning - -if isempty(sigFeatures.vFeatures) - vSets = 0; -else - vSets = sigFeatures.eVSets; % Number of sets for valdiation -end - -if isempty(sigFeatures.tFeatures) - tSets = 0; -else - tSets = sigFeatures.eTSets; % Number of sets for testing -end - -Ntrset = trSets * nM; -Nvset = vSets * nM; -Ntset = tSets * nM; -trSet = zeros(Ntrset, length(features)); -vSet = zeros(Nvset , length(features)); -tSet = zeros(Ntset , length(features)); -trOut = zeros(Ntrset, nM); -vOut = zeros(Nvset , nM); -tOut = zeros(Ntset , nM); - -for e = 1 : nM; - % Training - for r = 1 : trSets - sidx = r + (trSets*(e-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); - trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); - li = le + 1; - end - trOut(sidx,e) = 1; - end - % Validation - for r = 1 : vSets - sidx = r + (vSets*(e-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); - vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); - li = le + 1; - end - vOut(sidx,e) = 1; - end - % Test - for r = 1 : tSets - sidx = r + (tSets*(e-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); - tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); - li = le + 1; - end - tOut(sidx,e) = 1; - end -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% % This function will create matrices of training, validation and test sets +% All movements will be STACK one over each other +% +% input: trFeatures contains the splitted data, is a Nsplits x Nexercises structure matrix +% vFeatures is similar to trFeatures +% features contains the name of the charactaristics to be used +% output: trsets are the normalized training sets +% vsets are the normalized validation sets +% trOut contains the correspondet outputs +% vOut contains the correspondet outputs +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-26 / Max Ortiz / Creation +% 2009-07-21 / Max Ortiz / To hanlde "treated_data" struct and selection of the number of set +% 2011-06-24 / Max Ortiz / Update to new coding standard and name to stack + +function [trSet, trOut, vSet, vOut, tSet, tOut] = GetSets_Stack(sigFeatures, features) + +nM = length(sigFeatures.trFeatures(1,:)); % Number of movements +trSets = sigFeatures.eTrSets; % effective number of sets for trainning + +if isempty(sigFeatures.vFeatures) + vSets = 0; +else + vSets = sigFeatures.eVSets; % Number of sets for valdiation +end + +if isempty(sigFeatures.tFeatures) + tSets = 0; +else + tSets = sigFeatures.eTSets; % Number of sets for testing +end + +Ntrset = trSets * nM; +Nvset = vSets * nM; +Ntset = tSets * nM; +trSet = zeros(Ntrset, length(features)); +vSet = zeros(Nvset , length(features)); +tSet = zeros(Ntset , length(features)); +trOut = zeros(Ntrset, nM); +vOut = zeros(Nvset , nM); +tOut = zeros(Ntset , nM); + +for e = 1 : nM; + % Training + for r = 1 : trSets + sidx = r + (trSets*(e-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); + trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); + li = le + 1; + end + trOut(sidx,e) = 1; + end + % Validation + for r = 1 : vSets + sidx = r + (vSets*(e-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); + vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); + li = le + 1; + end + vOut(sidx,e) = 1; + end + % Test + for r = 1 : tSets + sidx = r + (tSets*(e-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); + tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); + li = le + 1; + end + tOut(sidx,e) = 1; + end +end + + diff --git a/SigFeatures/GetSets_Stack_IndvMov.m b/SigFeatures/GetSets_Stack_IndvMov.m index 8bfc7a9..2f9f9f4 100644 --- a/SigFeatures/GetSets_Stack_IndvMov.m +++ b/SigFeatures/GetSets_Stack_IndvMov.m @@ -1,161 +1,161 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% This function will create matrices of training, validation and test sets -% - All movements will be STACK one over each other, this is, each set of -% movements will be the row and the colums are made of the features. -% - The number of columbs is given by the nuber of channels times the -% features -% - The value of the first features in each channel is then follow for the -% value of the second features in each channel and so on. -% -% NOTE: The main difference with GetSets_Stack is that the mixed movements -% are only considered in the testing set -% -% input: trFeatures contains the splitted data, is a Nsplits x Nexercises structure matrix -% vFeatures is similar to trFeatures -% features contains the name of the charactaristics to be used -% output: trsets are the normalized training sets -% vsets are the normalized validation sets -% trOut contains the correspondet outputs -% vOut contains the correspondet outputs -% -% ------------- Updates ------------- -% 2011-10-03 / Max Ortiz / Created -% 20xx-xx-xx / Author / Comment on update - -function [trSet, trOut, vSet, vOut, tSet, tOut, movIdx, movOutIdx] = GetSets_Stack_IndvMov(sigFeatures, features) - -%Variables -movIdx = []; -movIdxMix = []; - -% Find the mixed movements by looking for "+" -% use of a temporal index to match the output, this assumes that the order -% of the output is the same as the order of the movements -tempIdx = 1; -for i = 1 : size(sigFeatures.mov,1) - if isempty(strfind(sigFeatures.mov{i},'+')) - movIdx = [movIdx i]; - movOutIdx{i} = tempIdx; % Index for the output of each movement - tempIdx = tempIdx + 1; - else - movIdxMix = [movIdxMix i]; - end -end - -nMi = size(movIdx,2); % Number of movements individuals -nMm = size(movIdxMix,2); % Number of movements mixed - -trSets = sigFeatures.eTrSets; % effective number of sets for trainning - -if isempty(sigFeatures.vFeatures) - vSets = 0; -else - vSets = sigFeatures.eVSets; % Number of sets for valdiation -end - -if isempty(sigFeatures.tFeatures) - tSets = 0; -else - tSets = sigFeatures.eTSets; % Number of sets for testing -end - -Ntrset = trSets * nMi; -Nvset = vSets * nMi; -Ntset = tSets * nMi; - -trSet = zeros(Ntrset, length(features)); -vSet = zeros(Nvset , length(features)); -tSet = zeros(Ntset , length(features)); - -trOut = zeros(Ntrset, nMi); -vOut = zeros(Nvset , nMi); -tOut = zeros(Ntset , nMi); - -% Stack data sets for individual movements - -for j = 1 : nMi; - e = movIdx(j); - % Training - for r = 1 : trSets - sidx = r + (trSets*(j-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); - trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); % Get each feature per channel - li = le + 1; - end - trOut(sidx,j) = 1; - end - % Validation - for r = 1 : vSets - sidx = r + (vSets*(j-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); - vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); - li = le + 1; - end - vOut(sidx,j) = 1; - end - % Test - for r = 1 : tSets - sidx = r + (tSets*(e-1)); % Use e instead of j for test - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); - tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); - li = le + 1; - end - tOut(sidx,j) = 1; - end -end - -% Extract information for mixed patterns -for j = 1 : nMm; - e = movIdxMix(j); % index of the movement - %find mixed movements - for i = 1 : nMi - ii = movIdx(i); - if isempty(strfind(sigFeatures.mov{e},sigFeatures.mov{ii})) - idxMix(i) = 0; - else - idxMix(i) = 1; - end - end - - % Test - for r = 1 : tSets - sidx = r + (tSets*(e-1)); - li = 1; - for i = 1 : length(features) - le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); - tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); - li = le + 1; - end - tOut(sidx,:) = idxMix; - end - - movOutIdx{e} = find(idxMix); - -end - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% This function will create matrices of training, validation and test sets +% - All movements will be STACK one over each other, this is, each set of +% movements will be the row and the colums are made of the features. +% - The number of columbs is given by the nuber of channels times the +% features +% - The value of the first features in each channel is then follow for the +% value of the second features in each channel and so on. +% +% NOTE: The main difference with GetSets_Stack is that the mixed movements +% are only considered in the testing set +% +% input: trFeatures contains the splitted data, is a Nsplits x Nexercises structure matrix +% vFeatures is similar to trFeatures +% features contains the name of the charactaristics to be used +% output: trsets are the normalized training sets +% vsets are the normalized validation sets +% trOut contains the correspondet outputs +% vOut contains the correspondet outputs +% +% ------------- Updates ------------- +% 2011-10-03 / Max Ortiz / Created +% 20xx-xx-xx / Author / Comment on update + +function [trSet, trOut, vSet, vOut, tSet, tOut, movIdx, movOutIdx] = GetSets_Stack_IndvMov(sigFeatures, features) + +%Variables +movIdx = []; +movIdxMix = []; + +% Find the mixed movements by looking for "+" +% use of a temporal index to match the output, this assumes that the order +% of the output is the same as the order of the movements +tempIdx = 1; +for i = 1 : size(sigFeatures.mov,1) + if isempty(strfind(sigFeatures.mov{i},'+')) + movIdx = [movIdx i]; + movOutIdx{i} = tempIdx; % Index for the output of each movement + tempIdx = tempIdx + 1; + else + movIdxMix = [movIdxMix i]; + end +end + +nMi = size(movIdx,2); % Number of movements individuals +nMm = size(movIdxMix,2); % Number of movements mixed + +trSets = sigFeatures.eTrSets; % effective number of sets for trainning + +if isempty(sigFeatures.vFeatures) + vSets = 0; +else + vSets = sigFeatures.eVSets; % Number of sets for valdiation +end + +if isempty(sigFeatures.tFeatures) + tSets = 0; +else + tSets = sigFeatures.eTSets; % Number of sets for testing +end + +Ntrset = trSets * nMi; +Nvset = vSets * nMi; +Ntset = tSets * nMi; + +trSet = zeros(Ntrset, length(features)); +vSet = zeros(Nvset , length(features)); +tSet = zeros(Ntset , length(features)); + +trOut = zeros(Ntrset, nMi); +vOut = zeros(Nvset , nMi); +tOut = zeros(Ntset , nMi); + +% Stack data sets for individual movements + +for j = 1 : nMi; + e = movIdx(j); + % Training + for r = 1 : trSets + sidx = r + (trSets*(j-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); + trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); % Get each feature per channel + li = le + 1; + end + trOut(sidx,j) = 1; + end + % Validation + for r = 1 : vSets + sidx = r + (vSets*(j-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); + vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); + li = le + 1; + end + vOut(sidx,j) = 1; + end + % Test + for r = 1 : tSets + sidx = r + (tSets*(e-1)); % Use e instead of j for test + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); + tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); + li = le + 1; + end + tOut(sidx,j) = 1; + end +end + +% Extract information for mixed patterns +for j = 1 : nMm; + e = movIdxMix(j); % index of the movement + %find mixed movements + for i = 1 : nMi + ii = movIdx(i); + if isempty(strfind(sigFeatures.mov{e},sigFeatures.mov{ii})) + idxMix(i) = 0; + else + idxMix(i) = 1; + end + end + + % Test + for r = 1 : tSets + sidx = r + (tSets*(e-1)); + li = 1; + for i = 1 : length(features) + le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); + tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); + li = le + 1; + end + tOut(sidx,:) = idxMix; + end + + movOutIdx{e} = find(idxMix); + +end + + + + diff --git a/SigFeatures/GetSets_Stack_MixedOut.m b/SigFeatures/GetSets_Stack_MixedOut.m index 4ce8bc2..3e8189c 100644 --- a/SigFeatures/GetSets_Stack_MixedOut.m +++ b/SigFeatures/GetSets_Stack_MixedOut.m @@ -1,180 +1,180 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------- Function Description ------------- -% This function creates matrices of training, validation and test sets, -% however, the number of outputs is reduced to the number of single -% movements. The mixed movementes are part of the training, validation and -% testing sets. -% -% - All movements will be STACK one over each other, this is, each set of -% movements (vector of features) will be a row. -% - The number of columbs is given by the nuber of channels times the features -% - The features in the first channel are follow by the features of the -% second channel and so on. -% -% ------------- Updates ------------- -% 2012-04-06 / Max Ortiz / Created -% 20xx-xx-xx / Author / Comment on update - -function [trSet, trOut, vSet, vOut, tSet, tOut, movIdx, movOutIdx] = GetSets_Stack_MixedOut(sigFeatures, features) - -%Variables -movIdx = []; % Index of individual movements -movIdxMix = []; % Index of mixed movements -nFeatures = size(features,1); - -% Find the mixed movements by looking for "+" -% use of a temporal index to match the output, this assumes that the order -% of the output is the same as the order of the movements -tempIdx = 1; -for i = 1 : size(sigFeatures.mov,1) - if isempty(strfind(sigFeatures.mov{i},'+')) - movIdx = [movIdx i]; - movOutIdx{i} = tempIdx; % Index for the output of each movement - tempIdx = tempIdx + 1; - else - movIdxMix = [movIdxMix i]; - end -end - -nMi = size(movIdx,2); % Number of movements individuals -nMm = size(movIdxMix,2); % Number of movements mixed - -trSets = sigFeatures.eTrSets; % effective number of sets for trainning - -if isempty(sigFeatures.vFeatures) - vSets = 0; -else - vSets = sigFeatures.eVSets; % Number of sets for valdiation -end - -if isempty(sigFeatures.tFeatures) - tSets = 0; -else - tSets = sigFeatures.eTSets; % Number of sets for testing -end - -Ntrset = trSets * nMi; -Nvset = vSets * nMi; -Ntset = tSets * nMi; - -trSet = zeros(Ntrset, nFeatures); -vSet = zeros(Nvset , nFeatures); -tSet = zeros(Ntset , nFeatures); - -trOut = zeros(Ntrset, nMi); -vOut = zeros(Nvset , nMi); -tOut = zeros(Ntset , nMi); - -% Stack data sets for individual movements - -for j = 1 : nMi; - e = movIdx(j); - % Training - for r = 1 : trSets - %sidx = r + (trSets*(j-1)); - sidx = r + (trSets*(e-1)); % Use e instead of j for test - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); - trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); % Get each feature per channel - li = le + 1; - end - trOut(sidx,j) = 1; - end - % Validation - for r = 1 : vSets - %sidx = r + (vSets*(j-1)); - sidx = r + (vSets*(e-1)); % Use e instead of j for test - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); - vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); - li = le + 1; - end - vOut(sidx,j) = 1; - end - % Test - for r = 1 : tSets - sidx = r + (tSets*(e-1)); % Use e instead of j for test - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); - tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); - li = le + 1; - end - tOut(sidx,j) = 1; - end -end - -% Extract information for mixed patterns -for j = 1 : nMm; - e = movIdxMix(j); % index of the movement - %find mixed movements - for i = 1 : nMi - ii = movIdx(i); - if isempty(strfind(sigFeatures.mov{e},sigFeatures.mov{ii})) - idxMix(i) = 0; - else - idxMix(i) = 1; - end - end - - % Training - for r = 1 : trSets - sidx = r + (trSets*(e-1)); - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); - trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); - li = le + 1; - end - trOut(sidx,:) = idxMix; - end - - % Validation - for r = 1 : vSets - sidx = r + (vSets*(e-1)); - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); - vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); - li = le + 1; - end - vOut(sidx,:) = idxMix; - end - - % Test - for r = 1 : tSets - sidx = r + (tSets*(e-1)); - li = 1; - for i = 1 : nFeatures - le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); - tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); - li = le + 1; - end - tOut(sidx,:) = idxMix; - end - - movOutIdx{e} = find(idxMix); - -end - - - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------- Function Description ------------- +% This function creates matrices of training, validation and test sets, +% however, the number of outputs is reduced to the number of single +% movements. The mixed movementes are part of the training, validation and +% testing sets. +% +% - All movements will be STACK one over each other, this is, each set of +% movements (vector of features) will be a row. +% - The number of columbs is given by the nuber of channels times the features +% - The features in the first channel are follow by the features of the +% second channel and so on. +% +% ------------- Updates ------------- +% 2012-04-06 / Max Ortiz / Created +% 20xx-xx-xx / Author / Comment on update + +function [trSet, trOut, vSet, vOut, tSet, tOut, movIdx, movOutIdx] = GetSets_Stack_MixedOut(sigFeatures, features) + +%Variables +movIdx = []; % Index of individual movements +movIdxMix = []; % Index of mixed movements +nFeatures = size(features,1); + +% Find the mixed movements by looking for "+" +% use of a temporal index to match the output, this assumes that the order +% of the output is the same as the order of the movements +tempIdx = 1; +for i = 1 : size(sigFeatures.mov,1) + if isempty(strfind(sigFeatures.mov{i},'+')) + movIdx = [movIdx i]; + movOutIdx{i} = tempIdx; % Index for the output of each movement + tempIdx = tempIdx + 1; + else + movIdxMix = [movIdxMix i]; + end +end + +nMi = size(movIdx,2); % Number of movements individuals +nMm = size(movIdxMix,2); % Number of movements mixed + +trSets = sigFeatures.eTrSets; % effective number of sets for trainning + +if isempty(sigFeatures.vFeatures) + vSets = 0; +else + vSets = sigFeatures.eVSets; % Number of sets for valdiation +end + +if isempty(sigFeatures.tFeatures) + tSets = 0; +else + tSets = sigFeatures.eTSets; % Number of sets for testing +end + +Ntrset = trSets * nMi; +Nvset = vSets * nMi; +Ntset = tSets * nMi; + +trSet = zeros(Ntrset, nFeatures); +vSet = zeros(Nvset , nFeatures); +tSet = zeros(Ntset , nFeatures); + +trOut = zeros(Ntrset, nMi); +vOut = zeros(Nvset , nMi); +tOut = zeros(Ntset , nMi); + +% Stack data sets for individual movements + +for j = 1 : nMi; + e = movIdx(j); + % Training + for r = 1 : trSets + %sidx = r + (trSets*(j-1)); + sidx = r + (trSets*(e-1)); % Use e instead of j for test + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); + trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); % Get each feature per channel + li = le + 1; + end + trOut(sidx,j) = 1; + end + % Validation + for r = 1 : vSets + %sidx = r + (vSets*(j-1)); + sidx = r + (vSets*(e-1)); % Use e instead of j for test + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); + vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); + li = le + 1; + end + vOut(sidx,j) = 1; + end + % Test + for r = 1 : tSets + sidx = r + (tSets*(e-1)); % Use e instead of j for test + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); + tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); + li = le + 1; + end + tOut(sidx,j) = 1; + end +end + +% Extract information for mixed patterns +for j = 1 : nMm; + e = movIdxMix(j); % index of the movement + %find mixed movements + for i = 1 : nMi + ii = movIdx(i); + if isempty(strfind(sigFeatures.mov{e},sigFeatures.mov{ii})) + idxMix(i) = 0; + else + idxMix(i) = 1; + end + end + + % Training + for r = 1 : trSets + sidx = r + (trSets*(e-1)); + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.trFeatures(r,e).(features{i})); + trSet(sidx,li:le) = sigFeatures.trFeatures(r,e).(features{i}); + li = le + 1; + end + trOut(sidx,:) = idxMix; + end + + % Validation + for r = 1 : vSets + sidx = r + (vSets*(e-1)); + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.vFeatures(r,e).(features{i})); + vSet(sidx,li:le) = sigFeatures.vFeatures(r,e).(features{i}); + li = le + 1; + end + vOut(sidx,:) = idxMix; + end + + % Test + for r = 1 : tSets + sidx = r + (tSets*(e-1)); + li = 1; + for i = 1 : nFeatures + le = li - 1 + length(sigFeatures.tFeatures(r,e).(features{i})); + tSet(sidx,li:le) = sigFeatures.tFeatures(r,e).(features{i}); + li = le + 1; + end + tOut(sidx,:) = idxMix; + end + + movOutIdx{e} = find(idxMix); + +end + + + + diff --git a/SigFeatures/GetSigFeatures.m b/SigFeatures/GetSigFeatures.m index 058a455..cfd6459 100644 --- a/SigFeatures/GetSigFeatures.m +++ b/SigFeatures/GetSigFeatures.m @@ -1,493 +1,493 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to Breakdown the time and frecuency features -% Input : data Matrix of MxN where the rows are the channels -% : sF Sampling Frequency -% : fID features ID, if not fID given, it compute the hard-coded -% ones -% Output: features Signal features is an struct -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-27 / Max Ortiz / Creation from the old analyze_signal fuction in -% EMG_AQ in 2009 -% 2012-07-19 / Max Ortyiz / Add LoadFeaturesID funtion instead of -% hard-coded IDs -% 2012-11-23 / Max Ortyiz / Vectorized implementation of tzc and tslpch2 -% for speed improvement -% -% 20xx-xx-xx / Author / Comment on update - -function xFeatures = GetSigFeatures(data,sF,fID) - - % If not features ID were receved, then compute the following ones: - if ~exist('fID','var') - fID = LoadFeaturesIDs; - end - - % General information required to calculate different signal features - % other processing is added by specific futures in their functions - procFeatures.ch = length(data(1,:)); - procFeatures.sp = length(data(:,1)); - procFeatures.sF = sF; - procFeatures.data = data; - procFeatures.absdata = abs(data); - procFeatures.f = {}; - - % Add data of the fast fourier transform if a frequency feature is - % required - % This verification needs to be optimized - for i = 1 : size(fID,1) - temp = fID{i}; - if temp(1) == 'f' - procFeatures = GetFFT(procFeatures); - break; - end - end - - % Calculate signal features - for i = 1 : size(fID,1) - fName = ['GetSigFeatures_' fID{i}]; - procFeatures = feval(fName, procFeatures); - end - - xFeatures = procFeatures.f; - -end - -% ----------------------------------------------- -function pF = GetSigFeatures_tmn(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tmn = mean(pF.data); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tmabs(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tmabs = mean(pF.absdata); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tmd(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tmd = median(pF.data); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tstd(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tstd = std(pF.data); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tvar(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tvar = var(pF.data); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_twl(pF) -% Waveform Length (acumulative changes in the length) -% 2011-07-27 Max Ortiz / Creation - mdata = [zeros(1,pF.ch) ; pF.data(1:pF.sp-1,:)]; - pF.f.twl = sum(abs(pF.data - mdata)); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_trms(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.trms = sqrt(sum(pF.absdata .^ 2)/pF.sp); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tzc(pF) -% 2011-07-27 Max Ortiz / Creation - %check if tmabs is available - if ~isfield(pF.f,'tmabs') - pF = GetSigFeatures_tmabs(pF); - end - - tmp = repmat(pF.f.tmabs,[size(pF.data,1),1] ); - zc = ( pF.data >= tmp ) - (pF.data < tmp ); - pF.f.tzc = sum( ( zc(1:pF.sp-1,:) - zc(2:pF.sp,:) ) ~= 0); - -% % Zero Crossing / using the abs mean as threshold -% for i = 1 : pF.ch -% zc = (pF.data(:,i) >= pF.f.tmabs(i)) - (pF.data(:,i) < pF.f.tmabs(i)); -% pF.f.tzc(i) = sum((zc(1:pF.sp-1) - zc(2:pF.sp)) ~= 0); -% end - -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tpks(pF) -% 2011-07-27 Max Ortiz / Creation - % Peaks using rms value - - if ~isfield(pF.f,'trms') - pF = GetSigFeatures_trms(pF); - end - if ~isfield(pF,'pks') - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); - pF.pks{i} = pks; - pF.locs{i} = locs; - end - end - - for i = 1 : pF.ch - pF.f.tpks(i) = size(pF.pks{i},2); - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tmpks(pF) -% 2011-07-27 Max Ortiz / Creation - % Mean of peaks using rms value - - if ~isfield(pF.f,'trms') - pF = GetSigFeatures_trms(pF); - end - if ~isfield(pF,'pks') - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); - pF.pks{i} = pks; - pF.locs{i} = locs; - end - end - - for i = 1 : pF.ch - pF.f.tmpks(i) = mean(pF.pks{i}); - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tmvel(pF) -% 2011-07-27 Max Ortiz / Creation - % Mean firing velocity using the peaks - - if ~isfield(pF.f,'trms') - pF = GetSigFeatures_trms(pF); - end - if ~isfield(pF,'pks') - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); - pF.pks{i} = pks; - pF.locs{i} = locs; - end - end - if ~isfield(pF,'pksData') - for i = 1 : pF.ch - pF.pksData{i} = pF.data(pF.locs{1}, i); % Only data from the peaks - pF.diffPksData{i} = diff(pF.pksData{i}); % Get the diff of the peaks or velocity of the peaks - end - end - - for i = 1 : pF.ch - if isempty(pF.diffPksData{i}) - pF.f.tmvel(i) = 0; - else - pF.f.tmvel(i) = mean(abs(pF.diffPksData{i})); % Get mean of the firing velocity - end - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tslpch1(pF) -% 2011-07-27 Max Ortiz / Creation - % Slope Changes using the rms pks - % needs to be reviewed - - if ~isfield(pF.f,'trms') - pF = GetSigFeatures_trms(pF); - end - if ~isfield(pF.f,'tmvel') - pF = GetSigFeatures_tmvel(pF); - end - if ~isfield(pF,'pks') - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); - pF.pks{i} = pks; - pF.locs{i} = locs; - end - end - if ~isfield(pF,'pksData') - for i = 1 : pF.ch - pF.pksData{i} = pF.data(pF.locs{1}, i); % Only data from the peaks - pF.diffPksData{i} = diff(pF.pksData{i}); % Get the diff of the peaks or velocity of the peaks - end - end - - for i = 1 : pF.ch - if isempty(pF.diffPksData{i}) - pF.f.tslpch1(i) = 0; - else - tmax = max(pF.diffPksData{i}); - if tmax > pF.f.tmvel(i) - pF.f.tslpch1(i) = length(findpeaks(pF.diffPksData{i},'minpeakheight',pF.f.tmvel(i))); - else - pF.f.tslpch1(i) = 0; - end - end - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tslpch2(pF) -% 2011-07-27 Max Ortiz / Creation - % Slope Changes using the diff of the raw signal and the computing - % zero crossing - - if ~isfield(pF,'diffData') - pF.diffData = diff(pF.data); % Get the diff - end - - zc = (pF.diffData > 0 ) - (pF.diffData < 0); - pF.f.tslpch2 = sum( abs( zc(1:end-1,:) - zc(2:end,:) ) > 1 ); - -% for i = 1 : pF.ch -% zc = (pF.diffData(:,i) > 0) - (pF.diffData(:,i) < 0); -% pF.f.tslpch2(i) = sum(abs(zc(1:end-1) - zc(2:end)) > 1); -% end - -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tpwr(pF) -% 2011-07-27 Max Ortiz / Creation - pF.f.tpwr = sum(pF.absdata.^2)/pF.sp; -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tcr(pF) -% 2011-07-27 Max Ortiz / Creation - % Correlation - % Close to 1 means mutual increment - % Close to -1 means mutual decrement - % Close to 0 is no correlation or no-linear correlation - mcr = corrcoef(pF.data); - k=1; - for i = 1: pF.ch - for j = i+1 : pF.ch - pF.f.tcr(k) = mcr(i,j); - k=k+1; - end - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tcv(pF) -% 2011-07-27 Max Ortiz / Creation - % Covariance - % Note: It is possible that the covariance is not required because corr is - % computer already - mcr = cov(pF.data); - k=1; - for i = 1: pF.ch - for j = i+1 : pF.ch - pF.f.tcv(k) = mcr(i,j); - k=k+1; - end - end -end - -% ######################### Frequency Features ################### - -function pF = GetSigFeatures_fwl(pF) -% 2011-07-27 Max Ortiz / Creation - % Waveform Length (acumulative changes in the length) - tempdataf = [zeros(1,pF.ch) ; pF.fftData(1:end-1,:)]; - pF.f.fwl = sum(abs(pF.fftData - tempdataf)); -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_fmn(pF) -% 2011-07-27 Max Ortiz / Creation - % Mean Frequency - for ch = 1 : pF.ch - fmn = 0; - for i = 1 : length(pF.fftData(:,1)) - if fmn <= pF.fftDataT(ch)/2 - fmn = fmn + pF.fftData(i,ch); - else - break; - end - end - pF.f.fmn(ch) = pF.fV(i-1); - end -end -% ----------------------------------------------- - -function pF = GetSigFeatures_fmd(pF) -% 2011-07-27 Max Ortiz / Creation - % Median Frequency - if ~isfield(pF.f,'fwl') - pF = GetSigFeatures_fwl(pF); - end - tempdataf = [zeros(1,pF.ch) ; pF.fftData(1:end-1,:)]; - for ch = 1 : pF.ch - fmd = 0; - for i = 1 : length(pF.fftData(:,1)) - if fmd <= pF.f.fwl(ch)/2 - fmd = fmd + abs(pF.fftData(i,ch) - tempdataf(i,ch)); - else - break; - end - end - pF.f.fmd(ch) = pF.fV(i-1); - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_fpmn(pF) -% 2011-07-27 Max Ortiz / Creation - % Find the highest frequency peaks and gets its mean - if ~isfield(pF,'fPks') - nP = 5; % Number of peaks to be used - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); - pF.fPks(:,i) = pks(1:nP); - pF.fLocs(:,i) = locs(1:nP); - end - end - - for ch = 1 : pF.ch - pF.f.fpmn(ch) = mean(pF.fV(pF.fLocs(:,ch))); - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_fpmd(pF) -% 2011-07-27 Max Ortiz / Creation - % Find the highest frequency peaks and gets its mean - if ~isfield(pF,'fPks') - nP = 5; % Number of peaks to be used - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); - pF.fPks(:,i) = pks(1:nP); - pF.fLocs(:,i) = locs(1:nP); - end - end - - for ch = 1 : pF.ch - pF.f.fpmd(ch) = median(pF.fV(pF.fLocs(:,ch))); - end -end -% ----------------------------------------------- - -function pF = GetSigFeatures_fpstd(pF) -% 2011-07-27 Max Ortiz / Creation - % Find the highest frequency peaks and gets its mean - if ~isfield(pF,'fPks') - nP = 5; % Number of peaks to be used - for i = 1 : pF.ch - [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); - pF.fPks(:,i) = pks(1:nP); - pF.fLocs(:,i) = locs(1:nP); - end - end - - for ch = 1 : pF.ch - pF.f.fpstd(ch) = std(pF.fV(pF.fLocs(:,ch))); - end -end - -% ----------------------------------------------- - -function pF = GetSigFeatures_tdam(pF) -% 2012-05-22 Max Ortiz / Creation, found in FP10 - - temp = zeros(size(pF.data)); - temp(1:end-1,:) = pF.data(2:end,:); % Compute k+1 - diffAmp = abs(temp - pF.data); % compute the absulute difference - pF.f.tdam = sum(diffAmp(1:end-1,:)) ./ (pF.sp-1); - -end - -function pF = GetSigFeatures_tfd(pF) -% 2012-06-06 Max Ortiz / Creation, found in GS97 - - mdata = [zeros(1,pF.ch) ; pF.data(1:pF.sp-1,:)]; - absDiff = abs(pF.data - mdata); - L = sum(absDiff); - n = pF.sp; %Data points or samples - % This is not calculated properly, max of absDiff is only the max - % distance between adjacent points and not all the points in the set - d = max(absDiff); % Max distance between two points. - - pF.f.tfd = log(n) ./ (log(n) + (d./L)); - -end - -function pF = GetSigFeatures_tmfl(pF) -% 2012-06-06 Max Ortiz / Creation, found in AK10 -% Maximum Fractal Length - - N = pF.sp; %Total samples - m = 1; %Initial time - - for k = 1 : 9 : 10; - limTop = floor((N-m)/k); - for i = 1 : limTop - a = m+(i*k); - b = m+((i-1)*k); - tempL(i,:) = abs(pF.data(a,:) - pF.data(b,:)); - end - L(k,:) = sum(tempL) .* ((N-1)/(limTop*k)) ./ k; - clear tempL; - end - - pF.f.tmfl = L(1,:); - - pF.L = L; - -end - -function pF = GetSigFeatures_tfdh(pF) -% 2012-06-06 Max Ortiz / Creation, found in AK10 -% Fractal dimension using Higuchi algorithm - - if ~isfield(pF.f,'tmfl') - pF = GetSigFeatures_tmfl(pF); - end - - dX = log(pF.L(1,:))-log(pF.L(10,:)); - dY = log(10)-log(1); - pF.f.tfdh = dX./dY; - -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to Breakdown the time and frecuency features +% Input : data Matrix of MxN where the rows are the channels +% : sF Sampling Frequency +% : fID features ID, if not fID given, it compute the hard-coded +% ones +% Output: features Signal features is an struct +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-27 / Max Ortiz / Creation from the old analyze_signal fuction in +% EMG_AQ in 2009 +% 2012-07-19 / Max Ortyiz / Add LoadFeaturesID funtion instead of +% hard-coded IDs +% 2012-11-23 / Max Ortyiz / Vectorized implementation of tzc and tslpch2 +% for speed improvement +% +% 20xx-xx-xx / Author / Comment on update + +function xFeatures = GetSigFeatures(data,sF,fID) + + % If not features ID were receved, then compute the following ones: + if ~exist('fID','var') + fID = LoadFeaturesIDs; + end + + % General information required to calculate different signal features + % other processing is added by specific futures in their functions + procFeatures.ch = length(data(1,:)); + procFeatures.sp = length(data(:,1)); + procFeatures.sF = sF; + procFeatures.data = data; + procFeatures.absdata = abs(data); + procFeatures.f = {}; + + % Add data of the fast fourier transform if a frequency feature is + % required + % This verification needs to be optimized + for i = 1 : size(fID,1) + temp = fID{i}; + if temp(1) == 'f' + procFeatures = GetFFT(procFeatures); + break; + end + end + + % Calculate signal features + for i = 1 : size(fID,1) + fName = ['GetSigFeatures_' fID{i}]; + procFeatures = feval(fName, procFeatures); + end + + xFeatures = procFeatures.f; + +end + +% ----------------------------------------------- +function pF = GetSigFeatures_tmn(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tmn = mean(pF.data); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tmabs(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tmabs = mean(pF.absdata); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tmd(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tmd = median(pF.data); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tstd(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tstd = std(pF.data); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tvar(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tvar = var(pF.data); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_twl(pF) +% Waveform Length (acumulative changes in the length) +% 2011-07-27 Max Ortiz / Creation + mdata = [zeros(1,pF.ch) ; pF.data(1:pF.sp-1,:)]; + pF.f.twl = sum(abs(pF.data - mdata)); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_trms(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.trms = sqrt(sum(pF.absdata .^ 2)/pF.sp); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tzc(pF) +% 2011-07-27 Max Ortiz / Creation + %check if tmabs is available + if ~isfield(pF.f,'tmabs') + pF = GetSigFeatures_tmabs(pF); + end + + tmp = repmat(pF.f.tmabs,[size(pF.data,1),1] ); + zc = ( pF.data >= tmp ) - (pF.data < tmp ); + pF.f.tzc = sum( ( zc(1:pF.sp-1,:) - zc(2:pF.sp,:) ) ~= 0); + +% % Zero Crossing / using the abs mean as threshold +% for i = 1 : pF.ch +% zc = (pF.data(:,i) >= pF.f.tmabs(i)) - (pF.data(:,i) < pF.f.tmabs(i)); +% pF.f.tzc(i) = sum((zc(1:pF.sp-1) - zc(2:pF.sp)) ~= 0); +% end + +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tpks(pF) +% 2011-07-27 Max Ortiz / Creation + % Peaks using rms value + + if ~isfield(pF.f,'trms') + pF = GetSigFeatures_trms(pF); + end + if ~isfield(pF,'pks') + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); + pF.pks{i} = pks; + pF.locs{i} = locs; + end + end + + for i = 1 : pF.ch + pF.f.tpks(i) = size(pF.pks{i},2); + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tmpks(pF) +% 2011-07-27 Max Ortiz / Creation + % Mean of peaks using rms value + + if ~isfield(pF.f,'trms') + pF = GetSigFeatures_trms(pF); + end + if ~isfield(pF,'pks') + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); + pF.pks{i} = pks; + pF.locs{i} = locs; + end + end + + for i = 1 : pF.ch + pF.f.tmpks(i) = mean(pF.pks{i}); + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tmvel(pF) +% 2011-07-27 Max Ortiz / Creation + % Mean firing velocity using the peaks + + if ~isfield(pF.f,'trms') + pF = GetSigFeatures_trms(pF); + end + if ~isfield(pF,'pks') + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); + pF.pks{i} = pks; + pF.locs{i} = locs; + end + end + if ~isfield(pF,'pksData') + for i = 1 : pF.ch + pF.pksData{i} = pF.data(pF.locs{1}, i); % Only data from the peaks + pF.diffPksData{i} = diff(pF.pksData{i}); % Get the diff of the peaks or velocity of the peaks + end + end + + for i = 1 : pF.ch + if isempty(pF.diffPksData{i}) + pF.f.tmvel(i) = 0; + else + pF.f.tmvel(i) = mean(abs(pF.diffPksData{i})); % Get mean of the firing velocity + end + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tslpch1(pF) +% 2011-07-27 Max Ortiz / Creation + % Slope Changes using the rms pks + % needs to be reviewed + + if ~isfield(pF.f,'trms') + pF = GetSigFeatures_trms(pF); + end + if ~isfield(pF.f,'tmvel') + pF = GetSigFeatures_tmvel(pF); + end + if ~isfield(pF,'pks') + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.absdata(:,i),'minpeakheight',pF.f.trms(i)); + pF.pks{i} = pks; + pF.locs{i} = locs; + end + end + if ~isfield(pF,'pksData') + for i = 1 : pF.ch + pF.pksData{i} = pF.data(pF.locs{1}, i); % Only data from the peaks + pF.diffPksData{i} = diff(pF.pksData{i}); % Get the diff of the peaks or velocity of the peaks + end + end + + for i = 1 : pF.ch + if isempty(pF.diffPksData{i}) + pF.f.tslpch1(i) = 0; + else + tmax = max(pF.diffPksData{i}); + if tmax > pF.f.tmvel(i) + pF.f.tslpch1(i) = length(findpeaks(pF.diffPksData{i},'minpeakheight',pF.f.tmvel(i))); + else + pF.f.tslpch1(i) = 0; + end + end + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tslpch2(pF) +% 2011-07-27 Max Ortiz / Creation + % Slope Changes using the diff of the raw signal and the computing + % zero crossing + + if ~isfield(pF,'diffData') + pF.diffData = diff(pF.data); % Get the diff + end + + zc = (pF.diffData > 0 ) - (pF.diffData < 0); + pF.f.tslpch2 = sum( abs( zc(1:end-1,:) - zc(2:end,:) ) > 1 ); + +% for i = 1 : pF.ch +% zc = (pF.diffData(:,i) > 0) - (pF.diffData(:,i) < 0); +% pF.f.tslpch2(i) = sum(abs(zc(1:end-1) - zc(2:end)) > 1); +% end + +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tpwr(pF) +% 2011-07-27 Max Ortiz / Creation + pF.f.tpwr = sum(pF.absdata.^2)/pF.sp; +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tcr(pF) +% 2011-07-27 Max Ortiz / Creation + % Correlation + % Close to 1 means mutual increment + % Close to -1 means mutual decrement + % Close to 0 is no correlation or no-linear correlation + mcr = corrcoef(pF.data); + k=1; + for i = 1: pF.ch + for j = i+1 : pF.ch + pF.f.tcr(k) = mcr(i,j); + k=k+1; + end + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tcv(pF) +% 2011-07-27 Max Ortiz / Creation + % Covariance + % Note: It is possible that the covariance is not required because corr is + % computer already + mcr = cov(pF.data); + k=1; + for i = 1: pF.ch + for j = i+1 : pF.ch + pF.f.tcv(k) = mcr(i,j); + k=k+1; + end + end +end + +% ######################### Frequency Features ################### + +function pF = GetSigFeatures_fwl(pF) +% 2011-07-27 Max Ortiz / Creation + % Waveform Length (acumulative changes in the length) + tempdataf = [zeros(1,pF.ch) ; pF.fftData(1:end-1,:)]; + pF.f.fwl = sum(abs(pF.fftData - tempdataf)); +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_fmn(pF) +% 2011-07-27 Max Ortiz / Creation + % Mean Frequency + for ch = 1 : pF.ch + fmn = 0; + for i = 1 : length(pF.fftData(:,1)) + if fmn <= pF.fftDataT(ch)/2 + fmn = fmn + pF.fftData(i,ch); + else + break; + end + end + pF.f.fmn(ch) = pF.fV(i-1); + end +end +% ----------------------------------------------- + +function pF = GetSigFeatures_fmd(pF) +% 2011-07-27 Max Ortiz / Creation + % Median Frequency + if ~isfield(pF.f,'fwl') + pF = GetSigFeatures_fwl(pF); + end + tempdataf = [zeros(1,pF.ch) ; pF.fftData(1:end-1,:)]; + for ch = 1 : pF.ch + fmd = 0; + for i = 1 : length(pF.fftData(:,1)) + if fmd <= pF.f.fwl(ch)/2 + fmd = fmd + abs(pF.fftData(i,ch) - tempdataf(i,ch)); + else + break; + end + end + pF.f.fmd(ch) = pF.fV(i-1); + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_fpmn(pF) +% 2011-07-27 Max Ortiz / Creation + % Find the highest frequency peaks and gets its mean + if ~isfield(pF,'fPks') + nP = 5; % Number of peaks to be used + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); + pF.fPks(:,i) = pks(1:nP); + pF.fLocs(:,i) = locs(1:nP); + end + end + + for ch = 1 : pF.ch + pF.f.fpmn(ch) = mean(pF.fV(pF.fLocs(:,ch))); + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_fpmd(pF) +% 2011-07-27 Max Ortiz / Creation + % Find the highest frequency peaks and gets its mean + if ~isfield(pF,'fPks') + nP = 5; % Number of peaks to be used + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); + pF.fPks(:,i) = pks(1:nP); + pF.fLocs(:,i) = locs(1:nP); + end + end + + for ch = 1 : pF.ch + pF.f.fpmd(ch) = median(pF.fV(pF.fLocs(:,ch))); + end +end +% ----------------------------------------------- + +function pF = GetSigFeatures_fpstd(pF) +% 2011-07-27 Max Ortiz / Creation + % Find the highest frequency peaks and gets its mean + if ~isfield(pF,'fPks') + nP = 5; % Number of peaks to be used + for i = 1 : pF.ch + [pks, locs] = findpeaks(pF.fftData(:,i),'SORTSTR','descend'); + pF.fPks(:,i) = pks(1:nP); + pF.fLocs(:,i) = locs(1:nP); + end + end + + for ch = 1 : pF.ch + pF.f.fpstd(ch) = std(pF.fV(pF.fLocs(:,ch))); + end +end + +% ----------------------------------------------- + +function pF = GetSigFeatures_tdam(pF) +% 2012-05-22 Max Ortiz / Creation, found in FP10 + + temp = zeros(size(pF.data)); + temp(1:end-1,:) = pF.data(2:end,:); % Compute k+1 + diffAmp = abs(temp - pF.data); % compute the absulute difference + pF.f.tdam = sum(diffAmp(1:end-1,:)) ./ (pF.sp-1); + +end + +function pF = GetSigFeatures_tfd(pF) +% 2012-06-06 Max Ortiz / Creation, found in GS97 + + mdata = [zeros(1,pF.ch) ; pF.data(1:pF.sp-1,:)]; + absDiff = abs(pF.data - mdata); + L = sum(absDiff); + n = pF.sp; %Data points or samples + % This is not calculated properly, max of absDiff is only the max + % distance between adjacent points and not all the points in the set + d = max(absDiff); % Max distance between two points. + + pF.f.tfd = log(n) ./ (log(n) + (d./L)); + +end + +function pF = GetSigFeatures_tmfl(pF) +% 2012-06-06 Max Ortiz / Creation, found in AK10 +% Maximum Fractal Length + + N = pF.sp; %Total samples + m = 1; %Initial time + + for k = 1 : 9 : 10; + limTop = floor((N-m)/k); + for i = 1 : limTop + a = m+(i*k); + b = m+((i-1)*k); + tempL(i,:) = abs(pF.data(a,:) - pF.data(b,:)); + end + L(k,:) = sum(tempL) .* ((N-1)/(limTop*k)) ./ k; + clear tempL; + end + + pF.f.tmfl = L(1,:); + + pF.L = L; + +end + +function pF = GetSigFeatures_tfdh(pF) +% 2012-06-06 Max Ortiz / Creation, found in AK10 +% Fractal dimension using Higuchi algorithm + + if ~isfield(pF.f,'tmfl') + pF = GetSigFeatures_tmfl(pF); + end + + dX = log(pF.L(1,:))-log(pF.L(10,:)); + dY = log(10)-log(1); + pF.f.tfdh = dX./dY; + +end + diff --git a/SigFeatures/GetSigFeatures_tcard.m b/SigFeatures/GetSigFeatures_tcard.m new file mode 100644 index 0000000..6253df0 --- /dev/null +++ b/SigFeatures/GetSigFeatures_tcard.m @@ -0,0 +1,39 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% Compute cardinality +% +% I found out that an wrong implementation (trenx) of the rough entropy was +% given improved results than any other feature. This wrong implementation +% turned out to be the "cardinality" of the set. Max Ortz +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-05-01 / Max Ortiz / Created +% 20xx-xx-xx / Author / Comment on update + + +function pF = GetSigFeatures_tcard(pF) + for ch = 1 : pF.ch + % Get the number of different values and their number of repetitions + v = unique(pF.data(:,ch)); + m = size(v,1); % Number of unique values, or cardinality + pF.f.tcard(ch) = m; + end +end \ No newline at end of file diff --git a/SigFeatures/GetSigFeatures_tren.m b/SigFeatures/GetSigFeatures_tren.m index 0a4ee8b..0d47234 100644 --- a/SigFeatures/GetSigFeatures_tren.m +++ b/SigFeatures/GetSigFeatures_tren.m @@ -1,51 +1,51 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% -% Compute the rough entropy -% This implementation corresponds to Zhong et al. 2011 -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-04-09 / Max Ortiz / Created -% 20xx-xx-xx / Author / Comment on update - -function pF = GetSigFeatures_tren(pF) - % Compute the Rough Entropy per channel - u = pF.sp; % Univers or in this case samples (elements) - for ch = 1 : pF.ch - - % Get the number of different values and their number of repetitions - [v q] = unique(pF.data(:,ch)); - m = size(v,1); % Number of unique values - % Sort q (last apperance) to compute how many apperances each value had - sq = sort(q); - - % Compute the first value - card = zeros(m,1); - card(1) = sq(1); % How many elements are there of the first element - rEn = (card(1)/u) * log2(1/card(1)); - % Compute the rest of the values - for i = 2 : m - % Collect the number of aperances - card(i) = sq(i) - sq(i-1); - rEn = rEn + ((card(i)/u) * log2(1/card(i))); - end - pF.f.tren(ch) = -rEn; - end -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% +% Compute the rough entropy +% This implementation corresponds to Zhong et al. 2011 +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-04-09 / Max Ortiz / Created +% 20xx-xx-xx / Author / Comment on update + +function pF = GetSigFeatures_tren(pF) + % Compute the Rough Entropy per channel + u = pF.sp; % Univers or in this case samples (elements) + for ch = 1 : pF.ch + + % Get the number of different values and their number of repetitions + [v q] = unique(pF.data(:,ch)); + m = size(v,1); % Number of unique values + % Sort q (last apperance) to compute how many apperances each value had + sq = sort(q); + + % Compute the first value + card = zeros(m,1); + card(1) = sq(1); % How many elements are there of the first element + rEn = (card(1)/u) * log2(1/card(1)); + % Compute the rest of the values + for i = 2 : m + % Collect the number of aperances + card(i) = sq(i) - sq(i-1); + rEn = rEn + ((card(i)/u) * log2(1/card(i))); + end + pF.f.tren(ch) = -rEn; + end +end diff --git a/SigFeatures/LoadFeaturesIDs.m b/SigFeatures/LoadFeaturesIDs.m index e5c7f4f..a9b630d 100644 --- a/SigFeatures/LoadFeaturesIDs.m +++ b/SigFeatures/LoadFeaturesIDs.m @@ -1,45 +1,45 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% -% Reads the file features.def and loads the data into motor objects. -% -% --------------------------Updates-------------------------- -% 2012-07-18 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function fID = LoadFeaturesIDs - -fileid = fopen('features.def'); -tline = fgetl(fileid); -i=1; -fID = {}; -while ischar(tline) && ~isempty(tline) - t = textscan(tline,'%s'); - t = t{1}; - fID(i) = t(1); - %disp(t{1}); - tline = fgetl(fileid); - i=i+1; -end - -fID = fID'; % It made a vector to keep compatibility with the rest of BioPatRec - -fclose(fileid); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% +% Reads the file features.def and loads the data into motor objects. +% +% --------------------------Updates-------------------------- +% 2012-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function fID = LoadFeaturesIDs + +fileid = fopen('features.def'); +tline = fgetl(fileid); +i=1; +fID = {}; +while ischar(tline) && ~isempty(tline) + t = textscan(tline,'%s'); + t = t{1}; + fID(i) = t(1); + %disp(t{1}); + tline = fgetl(fileid); + i=i+1; +end + +fID = fID'; % It made a vector to keep compatibility with the rest of BioPatRec + +fclose(fileid); + + diff --git a/SigFeatures/features.def b/SigFeatures/features.def index 5d62e9d..4288a6e 100644 --- a/SigFeatures/features.def +++ b/SigFeatures/features.def @@ -1,53 +1,57 @@ -tmabs % Time: Mean absolute value -tstd % Time: Standard deviation -tvar % Time: Variance -twl % Time: wave length -trms % Time: RMS -tzc % Time: Zerp crossing -tslpch2 % Time: Slope changes -tpwr % Time: Power -tdam % Time: Difference absolute mean value -tmfl % Time: Maximum fractal length -tfdh % Time: Fractal dimension Higuchi -tfd % Time: Fractal dimension -tren % Time: Rough Entropy - - -NOTE: Not all features are used constantly so -some of them are left out for speed - -All features: - -Time: - -tmn -tmabs -tmd -tstd -tvar -twl -trms -tzc -tpks -tmpks -tmvel -tslpch1 -tslpch2 -tpwr -tcr -tcv -tdam % Time: Difference absolute mean value -tmfl % Time: Maximum fractal length -tfdh % Time: Fractal dimension Higuchi -tfd % Time: Fractal dimension -tren % Time: Rough Entropy - - -Frequency: - -fwl -fmn -fmd -fpmn -fpmd -fpstd \ No newline at end of file +tmabs % Time: Mean absolute value +tstd % Time: Standard deviation +tvar % Time: Variance +twl % Time: wave length +trms % Time: RMS +tzc % Time: Zerp crossing +tslpch2 % Time: Slope changes +tpwr % Time: Power +tdam % Time: Difference absolute mean value +tmfl % Time: Maximum fractal length +tfdh % Time: Fractal dimension Higuchi +tfd % Time: Fractal dimension +tcard % Time: Cardinality +tren % Time: Rough Entropy +fwl % Freq: wave length +fmn % Freq: mean +fmd % Freq: median + +NOTE: Not all features are used constantly so +some of them are left out to improve speed + +All features: + +Time: + +tmn +tmabs +tmd +tstd +tvar +twl +trms +tzc +tpks +tmpks +tmvel +tslpch1 +tslpch2 +tpwr +tcr +tcv +tdam % Time: Difference absolute mean value +tmfl % Time: Maximum fractal length +tfdh % Time: Fractal dimension Higuchi +tfd % Time: Fractal dimension +tcard % Time: Cardinality +tren % Time: Rough Entropy + + +Frequency: + +fwl % Freq: wave length +fmn % Freq: mean +fmd % Freq: median +fpmn % Freq: peak mean +fpmd % Freq: peak median +fpstd % Freq: peak std \ No newline at end of file diff --git a/SigRecordings/Compatibility_recSession.m b/SigRecordings/Compatibility_recSession.m index d973830..0fe239d 100644 --- a/SigRecordings/Compatibility_recSession.m +++ b/SigRecordings/Compatibility_recSession.m @@ -1,45 +1,45 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to keep the compatibility with recorded sessions in older versions of -% the BioPatRec, so the EMG_AQ -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-11 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function recSession = Compatibility_recSession(ss) - - tempF = fieldnames(ss); - if strcmp(tempF(1),'Fs') - - recSession.sF = ss.Fs; - recSession.sT = ss.Ts; - recSession.nM = ss.Ne; - recSession.nR = ss.Nr; - recSession.cT = ss.Tc; - recSession.rT = ss.Tr; - recSession.cTp = ss.Psr; - recSession.date = ss.date; - recSession.mov = ss.msg; - - recSession.tdata = ss.tdata; - recSession.trdata = ss.trdata; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to keep the compatibility with recorded sessions in older versions of +% the BioPatRec, so the EMG_AQ +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-11 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function recSession = Compatibility_recSession(ss) + + tempF = fieldnames(ss); + if strcmp(tempF(1),'Fs') + + recSession.sF = ss.Fs; + recSession.sT = ss.Ts; + recSession.nM = ss.Ne; + recSession.nR = ss.Nr; + recSession.cT = ss.Tc; + recSession.rT = ss.Tr; + recSession.cTp = ss.Psr; + recSession.date = ss.date; + recSession.mov = ss.msg; + + recSession.tdata = ss.tdata; + recSession.trdata = ss.trdata; + end \ No newline at end of file diff --git a/SigRecordings/DataShow.m b/SigRecordings/DataShow.m index dda23fe..7b2b3dc 100644 --- a/SigRecordings/DataShow.m +++ b/SigRecordings/DataShow.m @@ -1,95 +1,85 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to Show the SAVED data on the GUI -% Input = ai object, chp channels pressences -% Output = data and time -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-15 / Max Ortiz / Creation -% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation -% for EMG_AQ - -function DataShow(handles,cdata, sF, sT) - - tt = 0:1/sF:sT-1/sF; % Create vector of time - nS = length(cdata(:,1)); % It used to be sF*sT but due to change in lenght witht training data - nCh = size(cdata,2); - - %Fast Fourier Transform - NFFT = 2^nextpow2(nS); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(cdata(1:nS,:),NFFT)/nS; - m = 2*abs(dataf((1:NFFT/2),:)); - m(1,:) =0; - - - if nCh >= 1 - axes(handles.a_t0); - plot(tt(1:length(cdata(:,1))),cdata(:,1)); - axes(handles.a_f0); - plot(f,m(:,1)); - end - - if nCh >= 2 - axes(handles.a_t1); - plot(tt(1:length(cdata(:,1))),cdata(:,2)); - axes(handles.a_f1); - plot(f,m(:,2)); - end - if nCh >= 3 - axes(handles.a_t2); - plot(tt(1:length(cdata(:,1))),cdata(:,3)); - axes(handles.a_f2); - plot(f,m(:,3)); - end - if nCh >= 4 - axes(handles.a_t3); - plot(tt(1:length(cdata(:,1))),cdata(:,4)); - axes(handles.a_f3); - plot(f,m(:,4)); - end - if nCh >= 5 - axes(handles.a_t4); - plot(tt(1:length(cdata(:,1))),cdata(:,5)); -% axes(handles.a_f0); -% plot(f,m(:,1)); - end - - if nCh >= 6 - axes(handles.a_t5); - plot(tt(1:length(cdata(:,1))),cdata(:,6)); -% axes(handles.a_f1); -% plot(f,m(:,2)); - end - if nCh >= 7 - axes(handles.a_t6); - plot(tt(1:length(cdata(:,1))),cdata(:,7)); - % axes(handles.a_f2); - % plot(f,m(:,3)); - end - if nCh >= 8 - axes(handles.a_t7); - plot(tt(1:length(cdata(:,1))),cdata(:,8)); - % axes(handles.a_f3); - % plot(f,m(:,4)); - end - - -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to Show the SAVED data on the GUI +% Input = ai object, chp channels pressences +% Output = data and time +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-15 / Max Ortiz / Creation +% 2011-09-20 / Max Ortiz / New routine for BioPatRec based in previous implementation +% for EMG_AQ +% 2013-06-01 / Max Ortiz / Fixed an issue with ploting when cdata is +% slightly bigger that it should be (NI DAQ issues) +% 2015-02-20 / Enzo Mastinu / Added the scaling of the data: now every channel plot will be + % dynamically and automatically resize to fit in the proper portion + % of the main plot. This is to avoid overlapping of channels + % waveforms and to have always the best zoom for every channel. +% 2015-02-23 / Enzo Mastinu / The scale of every channel plot is now the + % same scale of the channel which has the + % maximum absolute value + + +function DataShow(handles,cdata, sF, sT) + + tt = 0:1/sF:sT-1/sF; % Create vector of time + nS = length(cdata(:,1)); % It used to be sF*sT but due to change in lenght witht training data + nCh = size(cdata,2); + + if size(tt,2) ~= size(cdata,1) + nSd = size(cdata,1)- size(tt,2); + tt(1,end:end+nSd) = 0; + end + + % Initialize plots + ampPP = 5; + ymin = -ampPP*2/3; + ymax = ampPP * nCh - ampPP*1/3; + + %Fast Fourier Transform + NFFT = 2^nextpow2(nS); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(cdata(1:nS,:),NFFT)/nS; + m = 2*abs(dataf((1:NFFT/2),:)); + + % Offset and scale the data + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + Kt = ampPP/(2*max(max(abs(cdata)))); + Kf = ampPP/(max(max(abs(m)))); + for j = 1 : nCh + tempData(:,j) = cdata(:,j)*Kt + offVector(j); + fData(:,j) = m(:,j)*Kf + offVector(j); + end + + % plot + axes(handles.a_t0); + plot(tt(1:length(tempData(:,1))),tempData); + set(handles.a_t0,'YTick',offVector); + set(handles.a_t0,'YTickLabel',0:nCh-1); + ylim(handles.a_t0, [ymin ymax]); + axes(handles.a_f0); + plot(f,fData); + set(handles.a_f0,'YTick',offVector); + set(handles.a_f0,'YTickLabel',0:nCh-1); + xlim(handles.a_f0, [0,sF/2]); + ymax = ampPP * nCh; + ylim(handles.a_f0, [ymin ymax]); + +end diff --git a/SigRecordings/FastRecordingSession.m b/SigRecordings/FastRecordingSession.m new file mode 100644 index 0000000..929ce00 --- /dev/null +++ b/SigRecordings/FastRecordingSession.m @@ -0,0 +1,213 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment, for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offline data process as feature extraction or filter etc. + +% 20xx-xx-xx / Author / Comment + + + +function [cdata, sF, sT] = FastRecordingSession(varargin) + + global handles; + global allData; + global timeStamps; + global samplesCounter; + allData = []; + handles = varargin{1}; + afeSettings = varargin{2}; + + % Get required informations from afeSettings structure + nCh = afeSettings.channels; + sF = afeSettings.sampleRate; + deviceName = afeSettings.name; + ComPortType = afeSettings.ComPortType; + if strcmp(ComPortType, 'COM') + ComPortName = afeSettings.ComPortName; + end + + % Save back acquisition parameters to the handles + handles.nCh = nCh; + handles.sF = sF; + handles.ComPortType = ComPortType; + if strcmp(ComPortType, 'COM') + handles.ComPortName = ComPortName; + end + handles.deviceName = deviceName; + % To avoid bugs in RecordingSession_ShowData function + handles.fast = 1; + handles.rep = 1; + handles.cT = 0; + handles.rT = 0; + handles.rampStatus = 0; + + % Setting for data peeking + sT = handles.sT; + handles.sT = sT; + handles.sTall = sT; + tW = handles.tW; + tWs = tW*sF; % Time window samples + handles.tWs = tWs; + timeStamps = 0:1/sF:tW-1/sF; % Create vector of time + + + %% Initialize GUI.. + + pause on; + + % Initialize plots, offset the data + ampPP = 5; + sData = zeros(tWs,nCh); + fData = zeros(tWs,nCh); + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + for i = 1 : nCh + sData(:,i) = sData(:,i) + offVector(i); + fData(:,i) = fData(:,i) + offVector(i); + end + + % Draw figure + ymin = -ampPP*2/3; + ymax = ampPP * nCh - ampPP*1/3; + p_t0 = plot(handles.a_t0, timeStamps, sData); + handles.p_t0 = p_t0; + xlim(handles.a_t0, [0,tW]); + ylim(handles.a_t0, [ymin ymax]); + set(handles.a_t0,'YTick',offVector); + set(handles.a_t0,'YTickLabel',0:nCh-1); + p_f0 = plot(handles.a_f0,timeStamps,fData); + handles.p_f0 = p_f0; + xlim(handles.a_f0, [0,sF/2]); + ylim(handles.a_f0, [ymin ymax]); + set(handles.a_f0,'YTick',offVector); + set(handles.a_f0,'YTickLabel',0:nCh-1); + + % Initialization of progress bar + xpatch = [0 0 0 0]; + ypatch = [0 0 1 1]; + axes(handles.a_prog); + handles.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); + + % Allocation of resource to improve speed, total data + recSessionData = zeros(sF*sT, nCh); + + + %% Starting Session.. + + % Warning to the user + set(handles.t_msg,'String','start'); + drawnow; + + % Run + timeStamps = 0:1/sF:tW-1/sF; % Timestamps used the time vector + currentTv = 1; % Current time vector + tV = timeStamps(currentTv):1/sF:(tW-1/sF)+timeStamps(currentTv); % Time vector used for drawing graphics + currentTv = currentTv - 1 + tWs; % Updated everytime tV is updated + acquireEvent.TimeStamps = tV'; + + %%%%% NI DAQ card %%%%% + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @RecordingSession_ShowData); + + % Start DAQ + cData = zeros(sF*sT, nCh); + s.startBackground(); % Run in the backgroud + + startTimerTic = tic; + pause(sT - toc(startTimerTic)); + + % Repetitions other devices + else + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + samplesCounter = 1; + cData = zeros(tWs, nCh); + + for timeWindowNr = 1:sT/tW + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + RecordingSession_ShowData(0, acquireEvent); % plot data and add cData to allData vector + samplesCounter = samplesCounter + tWs; + end + + % Stop acquisition + StopAcquisition(deviceName, obj); + end + + % NI DAQ card: "You must delete the listener once the operation is complete" + if strcmp(ComPortType,'NI'); + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + end + + % Save Data + recSessionData = allData; + allData = []; % clean global data for next movement + + + %% Session finish.. + set(handles.t_msg,'String','Session Terminated'); % Show message about acquisition completed + fileName = 'Img/Agree.jpg'; + movI = importdata(fileName); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + set(handles.a_prog,'visible','off'); + set(handles.hPatch,'Xdata',[0 0 0 0]); + + % Data Plot + cdata = recSessionData; + DataShow(handles,cdata,sF,sT); + + % Set visible the offline plot and process panels + set(handles.uipanel9,'Visible','on'); + set(handles.uipanel7,'Visible','on'); + set(handles.uipanel8,'Visible','on'); + set(handles.txt_it,'visible','on'); + set(handles.txt_ft,'visible','on'); + set(handles.et_it,'visible','on'); + set(handles.et_ft,'visible','on'); + set(handles.txt_if,'visible','on'); + set(handles.txt_ff,'visible','on'); + set(handles.et_if,'visible','on'); + set(handles.et_ff,'visible','on'); + + chVector = 0:nCh-1; + set(handles.lb_channels, 'String', chVector); +end diff --git a/SigRecordings/GUI_AFEselection.fig b/SigRecordings/GUI_AFEselection.fig index e0c9fb6..446a96f 100644 Binary files a/SigRecordings/GUI_AFEselection.fig and b/SigRecordings/GUI_AFEselection.fig differ diff --git a/SigRecordings/GUI_AFEselection.m b/SigRecordings/GUI_AFEselection.m index d3335e3..e44de8c 100644 --- a/SigRecordings/GUI_AFEselection.m +++ b/SigRecordings/GUI_AFEselection.m @@ -21,6 +21,12 @@ % ------------------------- Updates & Contributors ------------------------ % [Contributors are welcome to add their email] % 20xx-xx-xx / Max Ortiz / Creation +% 2013-08-23 / Morten Kristoffersen / Trimmed the interface down to one +% popup menu, reorganised the GUI_AFESelection data. +% 2013-09-20 / Pontus Lövinger / Added the option for ramp recording which + % calls the ramp recording functions +% 2014-11-10 / Enzo Mastinu / include the code for ADS1299 AFE, optimization of + % ramp functions and their callings % 20xx-xx-xx / Author / Comment on update function varargout = GUI_AFEselection(varargin) @@ -47,7 +53,7 @@ % Edit the above text to modify the response to help GUI_AFEselection -% Last Modified by GUIDE v2.5 25-Feb-2014 15:47:08 +% Last Modified by GUIDE v2.5 24-Feb-2015 11:25:48 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -118,6 +124,9 @@ function pb_record_Callback(hObject, eventdata, handles) % handles structure with handles and user data (see GUIDATA) % get(handles.cb_active0,'Value') +global offsetDelete; +offsetDelete = get(handles.cb_offset,'Value'); + % AFE_settings.active=[get(handles.cb_active0,'Value');get(handles.cb_active1,'Value');get(handles.cb_active2,'Value')]; % AFE_settings.active @@ -127,78 +136,69 @@ function pb_record_Callback(hObject, eventdata, handles) delete(instrfind) end -% Which device is active -AFE_settings.ADS.active=get(handles.cb_active0,'Value'); -% AFE_settings.ADS.active -AFE_settings.RHA.active=get(handles.cb_active1,'Value'); -% AFE_settings.RHA.active -AFE_settings.NI.active=get(handles.cb_active2,'Value'); -% AFE_settings.NI.active +% % Which device is active +% AFE_settings.ADS.active=get(handles.cb_active0,'Value'); +% % AFE_settings.ADS.active +% AFE_settings.RHA.active=get(handles.cb_active1,'Value'); +% % AFE_settings.RHA.active +% AFE_settings.NI.active=get(handles.cb_active2,'Value'); +% % AFE_settings.NI.active % Get devices name -AFE_settings.ADS.name=get(handles.et_name0,'String'); -AFE_settings.RHA.name=get(handles.et_name1,'String'); - -dev = get(handles.pm_name2,'String'); -selDev = get(handles.pm_name2,'Value'); -AFE_settings.NI.name= dev(selDev); +% AFE_settings.ADS.name=get(handles.et_name0,'String'); +% AFE_settings.RHA.name=get(handles.et_name1,'String'); +dev = get(handles.pm_name,'String'); +selDev = get(handles.pm_name,'Value'); +AFE_settings.name = dev(selDev); +deviceName = AFE_settings.name; -%% Sampling frequencie -% SR must be change to sF -contents = cellstr(get(handles.pm_sampleRate0,'String')); -SR0=str2double(contents{get(handles.pm_sampleRate0,'Value')}); -contents = cellstr(get(handles.pm_sampleRate1,'String')); -SR1=str2double(contents{get(handles.pm_sampleRate1,'Value')}); - -contents = cellstr(get(handles.pm_sampleRate2,'String')); -SR2=str2double(contents{get(handles.pm_sampleRate2,'Value')}); +%% Sampling frequency +contents = cellstr(get(handles.pm_sampleRate, 'String')); +sF = str2double(contents{get(handles.pm_sampleRate,'Value')}); % AFE_settings.sampleRate=[SR0;SR1;SR2]; % AFE_settings.sampleRate -AFE_settings.ADS.sampleRate=SR0; -AFE_settings.RHA.sampleRate=SR1; -AFE_settings.NI.sampleRate=SR2; -%% Number of channels -AFE_settings.ADS.channels = str2double(get(handles.et_chs0,'String')); -AFE_settings.RHA.channels = str2double(get(handles.et_chs1,'String')); -AFE_settings.NI.channels = str2double(get(handles.et_chs2,'String')); +AFE_settings.sampleRate=sF; +%% Number of channels +AFE_settings.channels = str2double(get(handles.et_chs,'String')); +nCh = AFE_settings.channels; %% % Communication Port -contents = cellstr(get(handles.ComPortType0,'String')); -CPT0=contents{get(handles.ComPortType0,'Value')}; - -contents = cellstr(get(handles.ComPortType1,'String')); -CPT1=contents{get(handles.ComPortType1,'Value')}; +contents = cellstr(get(handles.ComPortType,'String')); +ComPortType=contents{get(handles.ComPortType,'Value')}; +AFE_settings.ComPortType=ComPortType; -contents = cellstr(get(handles.ComPortType2,'String')); -CPT2=contents{get(handles.ComPortType2,'Value')}; +if strcmp(AFE_settings.ComPortType,'COM') + ComPortName = get(handles.ComPortName,'String'); +% AFE_settings.ComPortType=strcat(ComPortType,ComPortName); + AFE_settings.ComPortName=strcat(ComPortType,ComPortName); +end -AFE_settings.ComPortType={CPT0;CPT1;CPT2}; % AFE_settings.ComPortType -AFE_settings.ADS.ComPortType=CPT0; -AFE_settings.RHA.ComPortType=CPT1; -% AFE_settings.NI.ComPortType=CPT2; +% AFE_settings.ADS.ComPortType=CPT0; +% AFE_settings.RHA.ComPortType=CPT1; +% % AFE_settings.NI.ComPortType=CPT2; % AFE_settings.show=[get(handles.show0,'Value');get(handles.show1,'Value');get(handles.show2,'Value')]; % AFE_settings.show -AFE_settings.ADS.show=get(handles.show0,'Value'); -% AFE_settings.ADS.show -AFE_settings.RHA.show=get(handles.show1,'Value'); -% AFE_settings.RHA.show -AFE_settings.NI.show=get(handles.show2,'Value'); -% AFE_settings.NI.show +% AFE_settings.ADS.show=get(handles.show0,'Value'); +% % AFE_settings.ADS.show +% AFE_settings.RHA.show=get(handles.show1,'Value'); +% % AFE_settings.RHA.show +% AFE_settings.NI.show=get(handles.show2,'Value'); +% % AFE_settings.NI.show -AFE_settings.prepare=get(handles.prepare,'Value'); +AFE_settings.prepare = get(handles.prepare,'Value'); % GUI_AFEselection(Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle) % cdata = recording_session(Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle); @@ -210,22 +210,43 @@ function pb_record_Callback(hObject, eventdata, handles) mov=handles.varargin{5}; hGUI_Rec=handles.varargin{6}; vreMovements = handles.varargin{7}; +rampStatus = handles.varargin{8}; +fast = handles.varargin{9}; + +if(fast) + + % Fast recording session + [cdata, sF, sT] = FastRecordingSession(hGUI_Rec,AFE_settings); + tempdata = cdata; % variable useful for offline data processing + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); +else -[cdata, sF] = RecordingSession(nM,nR,cT,rT,mov,hGUI_Rec,AFE_settings,get(handles.cb_trainVRE,'Value'),vreMovements,get(handles.cb_VRELeftHand,'Value'));%Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle); - -% Fs=handles.varargin{1}; -% Nr=handles.varargin{3}; -% Tc=handles.varargin{4}; -% Tr=handles.varargin{5}; -%Moved from Recoding Session Fig -sT = (cT+rT)*nR; -save('cdata.mat','cdata','sF','sT'); -close(GUI_AFEselection); -close(GUI_RecordingSession); - -% close(recording_session_fig); - -% close(get(hObject,'Parent')) + % If ramp training has been selected in GUI_RecordingSession the ramp + % parameters should be obtained and the rampRecordingSession file is run + if rampStatus + [rampMin, minData] = ObtainRampMin(hGUI_Rec,AFE_settings,get(handles.cb_trainVRE,'Value'));%Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle + [rampMax, maxData] = ObtainRampMax(nM,mov,hGUI_Rec,AFE_settings,get(handles.cb_trainVRE,'Value'),vreMovements, get(handles.cb_VRELeftHand,'Value'));%Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle + rampParams = {rampMin rampMax minData maxData}; + [cdata, sF] = RecordingSession(nM,nR,cT,rT,mov,hGUI_Rec,AFE_settings,get(handles.cb_trainVRE,'Value'),vreMovements,get(handles.cb_VRELeftHand,'Value'),rampStatus,rampParams);%Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle,rampParams); + else + [cdata, sF] = RecordingSession(nM,nR,cT,rT,mov,hGUI_Rec,AFE_settings,get(handles.cb_trainVRE,'Value'),vreMovements,get(handles.cb_VRELeftHand,'Value'),rampStatus);%Fs,Ne,Nr,Tc,Tr,Psr,msg,EMG_AQhandle); + end + % Fs=handles.varargin{1}; + % Nr=handles.varargin{3}; + % Tc=handles.varargin{4}; + % Tr=handles.varargin{5}; + %Moved from Recoding Session Fig + sT = (cT+rT)*nR; + cdata = cdata(:,:,size(cdata,3)); + tempdata = cdata; + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); + close(GUI_AFEselection); + close(GUI_RecordingSession); + + % close(recording_session_fig); + + % close(get(hObject,'Parent')) +end % --- Executes during object creation, after setting all properties. function pb_record_CreateFcn(hObject, eventdata, handles) @@ -260,65 +281,19 @@ function default_CreateFcn(hObject, eventdata, handles) % handles empty - handles not created until after all CreateFcns called -% --- Executes on selection change in pm_sampleRate2. -function pm_sampleRate2_Callback(hObject, eventdata, handles) -% hObject handle to pm_sampleRate2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hints: contents = cellstr(get(hObject,'String')) returns pm_sampleRate2 contents as cell array -% contents{get(hObject,'Value')} returns selected item from pm_sampleRate2 - - -% --- Executes during object creation, after setting all properties. -function pm_sampleRate2_CreateFcn(hObject, eventdata, handles) -% hObject handle to pm_sampleRate2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles empty - handles not created until after all CreateFcns called - -% Hint: popupmenu 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 selection change in pm_sampleRate1. -function pm_sampleRate1_Callback(hObject, eventdata, handles) -% hObject handle to pm_sampleRate1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hints: contents = cellstr(get(hObject,'String')) returns pm_sampleRate1 contents as cell array -% contents{get(hObject,'Value')} returns selected item from pm_sampleRate1 - - -% --- Executes during object creation, after setting all properties. -function pm_sampleRate1_CreateFcn(hObject, eventdata, handles) -% hObject handle to pm_sampleRate1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles empty - handles not created until after all CreateFcns called - -% Hint: popupmenu 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 selection change in pm_sampleRate0. -function pm_sampleRate0_Callback(hObject, eventdata, handles) -% hObject handle to pm_sampleRate0 (see GCBO) +% --- Executes on selection change in pm_sampleRate. +function pm_sampleRate_Callback(hObject, eventdata, handles) +% hObject handle to pm_sampleRate (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hints: contents = cellstr(get(hObject,'String')) returns pm_sampleRate0 contents as cell array -% contents{get(hObject,'Value')} returns selected item from pm_sampleRate0 +% Hints: contents = cellstr(get(hObject,'String')) returns pm_sampleRate contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_sampleRate % --- Executes during object creation, after setting all properties. -function pm_sampleRate0_CreateFcn(hObject, eventdata, handles) -% hObject handle to pm_sampleRate0 (see GCBO) +function pm_sampleRate_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_sampleRate (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -328,11 +303,10 @@ function pm_sampleRate0_CreateFcn(hObject, eventdata, handles) set(hObject,'BackgroundColor','white'); end - - - +%%The function below detects the available COM porst, I just leave it there +%%for now in case that we need it. % --- Executes on selection change in ComPortType0. -function ComPortType0_Callback(hObject, eventdata, handles) +%function ComPortType0_Callback(hObject, eventdata, handles) % hObject handle to ComPortType0 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) @@ -341,90 +315,26 @@ function ComPortType0_Callback(hObject, eventdata, handles) % contents{get(hObject,'Value')} returns selected item from ComPortType0 -% --- Executes during object creation, after setting all properties. -function ComPortType0_CreateFcn(hObject, eventdata, handles) -% hObject handle to ComPortType0 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles empty - handles not created until after all CreateFcns called - -% Hint: popupmenu 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 - - -s=instrhwinfo('serial'); -if not(isfield(s,'SerialPorts')) - s.SerialPorts = {'Not Available'}; -elseif isempty(s.SerialPorts) - s.SerialPorts = {'Not Available'}; -end -set(hObject,'String',[s.SerialPorts]); - - - - -% --- Executes on selection change in ComPortType1. -function ComPortType1_Callback(hObject, eventdata, handles) -% hObject handle to ComPortType1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hints: contents = cellstr(get(hObject,'String')) returns ComPortType1 contents as cell array -% contents{get(hObject,'Value')} returns selected item from ComPortType1 - - -% --- Executes during object creation, after setting all properties. -function ComPortType1_CreateFcn(hObject, eventdata, handles) -% hObject handle to ComPortType1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles empty - handles not created until after all CreateFcns called - -% Hint: popupmenu 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 -s=instrhwinfo('serial'); -if not(isfield(s,'SerialPorts')) - s.SerialPorts = {'Not Available'}; -elseif isempty(s.SerialPorts) - s.SerialPorts = {'Not Available'}; -end -set(hObject,'String',[s.SerialPorts]); - - -% --- Executes on selection change in ComPortType2. -function ComPortType2_Callback(hObject, eventdata, handles) -% hObject handle to ComPortType2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hints: contents = cellstr(get(hObject,'String')) returns ComPortType2 contents as cell array -% contents{get(hObject,'Value')} returns selected item from ComPortType2 - - -% --- Executes during object creation, after setting all properties. -function ComPortType2_CreateFcn(hObject, eventdata, handles) -% hObject handle to ComPortType2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles empty - handles not created until after all CreateFcns called - -% Hint: popupmenu 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 during object creation, after setting all properties. +% function ComPortType0_CreateFcn(hObject, eventdata, handles) +% % hObject handle to ComPortType0 (see GCBO) +% % eventdata reserved - to be defined in a future version of MATLAB +% % handles empty - handles not created until after all CreateFcns called +% +% % Hint: popupmenu 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 +% +% % s=instrhwinfo('serial'); % if not(isfield(s,'SerialPorts')) % s.SerialPorts = {'Not Available'}; +% elseif isempty(s.SerialPorts) +% s.SerialPorts = {'Not Available'}; % end -% set(hObject,'String',[s.SerialPorts;{'NI'}]); -set(hObject,'String',{'NI'}); -set(hObject,'Value',1) -% set(hObject,'Value',length(s.SerialPorts)+1) - +% set(hObject,'String',[s.SerialPorts]); function bytesSamples2_Callback(hObject, eventdata, handles) @@ -495,19 +405,18 @@ function bytesSamples0_CreateFcn(hObject, eventdata, handles) end - -function et_name0_Callback(hObject, eventdata, handles) -% hObject handle to et_name0 (see GCBO) +function pm_name_Callback(hObject, eventdata, handles) +% hObject handle to pm_name (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 et_name0 as text -% str2double(get(hObject,'String')) returns contents of et_name0 as a double +% Hints: get(hObject,'String') returns contents of pm_name as text +% str2double(get(hObject,'String')) returns contents of pm_name as a double % --- Executes during object creation, after setting all properties. -function et_name0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_name0 (see GCBO) +function pm_name_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_name (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -517,88 +426,6 @@ function et_name0_CreateFcn(hObject, eventdata, handles) set(hObject,'BackgroundColor','white'); end - - -function et_name1_Callback(hObject, eventdata, handles) -% hObject handle to et_name1 (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 et_name1 as text -% str2double(get(hObject,'String')) returns contents of et_name1 as a double - - -% --- Executes during object creation, after setting all properties. -function et_name1_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_name1 (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 - - - -function pm_name2_Callback(hObject, eventdata, handles) -% hObject handle to pm_name2 (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 pm_name2 as text -% str2double(get(hObject,'String')) returns contents of pm_name2 as a double - - -% --- Executes during object creation, after setting all properties. -function pm_name2_CreateFcn(hObject, eventdata, handles) -% hObject handle to pm_name2 (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 cb_active0. -function cb_active0_Callback(hObject, eventdata, handles) -% hObject handle to cb_active0 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_active0 - - -% --- Executes on button press in cb_active1. -function cb_active1_Callback(hObject, eventdata, handles) -% hObject handle to cb_active1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_active1 - - -% --- Executes on button press in cb_active2. -function cb_active2_Callback(hObject, eventdata, handles) -% hObject handle to cb_active2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_active2 - - - - - - -% -% set(hObject,'String',{'8000';'4000';'2000';'1000';'500'}) - - % --- Executes during object creation, after setting all properties. function uipanel3_CreateFcn(hObject, eventdata, handles) % hObject handle to uipanel3 (see GCBO) @@ -676,20 +503,22 @@ function edit15_CreateFcn(hObject, eventdata, handles) set(hObject,'BackgroundColor','white'); end - - -function et_chs0_Callback(hObject, eventdata, handles) -% hObject handle to et_chs0 (see GCBO) +function et_chs_Callback(hObject, eventdata, handles) +% hObject handle to et_chs (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 et_chs0 as text -% str2double(get(hObject,'String')) returns contents of et_chs0 as a double - +% Hints: get(hObject,'String') returns contents of et_chs as text +% str2double(get(hObject,'String')) returns contents of et_chs as a double +if str2double(get(hObject,'String')) == 8 + set(handles.pm_sampleRate,'Value',2) +elseif str2double(get(hObject,'String')) == 6 + set(handles.pm_sampleRate,'Value',1) +end % --- Executes during object creation, after setting all properties. -function et_chs0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_chs0 (see GCBO) +function et_chs_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_chs (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -700,46 +529,68 @@ function et_chs0_CreateFcn(hObject, eventdata, handles) end +% --- Executes on button press in cb_trainVRE. +function cb_trainVRE_Callback(hObject, eventdata, handles) +% hObject handle to cb_trainVRE (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_trainVRE + +set(handles.cb_VRELeftHand,'Enable', 'on'); -function et_chs1_Callback(hObject, eventdata, handles) -% hObject handle to et_chs1 (see GCBO) +% --- Executes on selection change in ComPortType. +function ComPortType_Callback(hObject, eventdata, handles) +% hObject handle to ComPortType (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 et_chs1 as text -% str2double(get(hObject,'String')) returns contents of et_chs1 as a double +% Hints: contents = cellstr(get(hObject,'String')) returns ComPortType contents as cell array +% contents{get(hObject,'Value')} returns selected item from ComPortType +contents = cellstr(get(handles.ComPortType,'String')); +ComPortType = contents{get(handles.ComPortType,'Value')}; +if strcmp(ComPortType,'COM') + set(handles.ComPortName,'Enable', 'on'); +else + set(handles.ComPortName,'Enable', 'off'); +end % --- Executes during object creation, after setting all properties. -function et_chs1_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_chs1 (see GCBO) +function ComPortType_CreateFcn(hObject, eventdata, handles) +% hObject handle to ComPortType (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. +% Hint: popupmenu 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 cb_VRELeftHand. +function cb_VRELeftHand_Callback(hObject, eventdata, handles) +% hObject handle to cb_VRELeftHand (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_VRELeftHand + + -function et_chs2_Callback(hObject, eventdata, handles) -% hObject handle to et_chs2 (see GCBO) +function ComPortName_Callback(hObject, eventdata, handles) +% hObject handle to ComPortName (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 et_chs2 as text -% str2double(get(hObject,'String')) returns contents of et_chs2 as a double -if str2double(get(hObject,'String')) == 8 - set(handles.pm_sampleRate2,'Value',2) -elseif str2double(get(hObject,'String')) == 6 - set(handles.pm_sampleRate2,'Value',1) -end +% Hints: get(hObject,'String') returns contents of ComPortName as text +% str2double(get(hObject,'String')) returns contents of ComPortName as a double + % --- Executes during object creation, after setting all properties. -function et_chs2_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_chs2 (see GCBO) +function ComPortName_CreateFcn(hObject, eventdata, handles) +% hObject handle to ComPortName (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -750,20 +601,10 @@ function et_chs2_CreateFcn(hObject, eventdata, handles) end -% --- Executes on button press in cb_trainVRE. -function cb_trainVRE_Callback(hObject, eventdata, handles) -% hObject handle to cb_trainVRE (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_trainVRE - -set(handles.cb_VRELeftHand,'Enable', 'on'); - -% --- Executes on button press in cb_VRELeftHand. -function cb_VRELeftHand_Callback(hObject, eventdata, handles) -% hObject handle to cb_VRELeftHand (see GCBO) +% --- Executes on button press in cb_offset. +function cb_offset_Callback(hObject, eventdata, handles) +% hObject handle to cb_offset (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hint: get(hObject,'Value') returns toggle state of cb_VRELeftHand +% Hint: get(hObject,'Value') returns toggle state of cb_offset diff --git a/SigRecordings/GUI_RecordingSession.fig b/SigRecordings/GUI_RecordingSession.fig index d6ae410..a544f4a 100644 Binary files a/SigRecordings/GUI_RecordingSession.fig and b/SigRecordings/GUI_RecordingSession.fig differ diff --git a/SigRecordings/GUI_RecordingSession.m b/SigRecordings/GUI_RecordingSession.m index d0167a6..20fb35c 100644 --- a/SigRecordings/GUI_RecordingSession.m +++ b/SigRecordings/GUI_RecordingSession.m @@ -21,6 +21,7 @@ % ------------------------- Updates & Contributors ------------------------ % [Contributors are welcome to add their email] % 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Pontus Lövinger / Added an alternative for ramp recording % 20xx-xx-xx / Author / Comment on update function varargout = GUI_RecordingSession(varargin) @@ -47,7 +48,7 @@ % Edit the above text to modify the response to help GUI_RecordingSession -% Last Modified by GUIDE v2.5 17-May-2012 09:47:59 +% Last Modified by GUIDE v2.5 19-Sep-2013 09:13:52 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -96,9 +97,6 @@ function GUI_RecordingSession_OpeningFcn(hObject, eventdata, handles, varargin) %remove the axis tick marks axis off - - - %clear value of msg set(handles.et_msg,'Value',1); @@ -122,7 +120,6 @@ function GUI_RecordingSession_OpeningFcn(hObject, eventdata, handles, varargin) varargout{1} = handles.output; - function et_Fs_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) @@ -360,8 +357,10 @@ function et_msg_Callback(hObject, eventdata, handles) % --- Executes on button press in pb_Record. function pb_Record_Callback(hObject, eventdata, handles) % get the EMG_AQ Handles - h1 = GUI_Recordings; - hGUI_Rec = guidata(h1); + fast = 0; + h1 = GUI_Recordings(fast); + hGUI_Rec = guidata(h1); + rampStatus = get(handles.cb_ramp,'Value'); %psr = str2double(get(handles.et_Psr,'String')); % Percentage of the exercise time to be consider for training %sF = str2double(get(handles.et_Fs,'String')); % Sampling Frequency @@ -421,7 +420,8 @@ function pb_Record_Callback(hObject, eventdata, handles) end end - GUI_AFEselection(nM,nR,cT,rT,mov,hGUI_Rec,vreMovements) + fast = 0; + GUI_AFEselection(nM,nR,cT,rT,mov,hGUI_Rec,vreMovements,rampStatus,fast) %GUI_AFEselection(sF,nM,nR,cT,rT,psr,mov,hGUI_Rec) % Moved to AFE_select @@ -444,3 +444,12 @@ function cb_simultaneous_Callback(hObject, eventdata, handles) % handles structure with handles and user data (see GUIDATA) % Hint: get(hObject,'Value') returns toggle state of cb_simultaneous + + +% --- Executes on button press in cb_ramp. +function cb_ramp_Callback(hObject, eventdata, handles) +% hObject handle to cb_ramp (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hint: get(hObject,'Value') returns toggle state of cb_ramp diff --git a/SigRecordings/GUI_RecordingSessionShow.m b/SigRecordings/GUI_RecordingSessionShow.m index 61c5c49..e533ad2 100644 --- a/SigRecordings/GUI_RecordingSessionShow.m +++ b/SigRecordings/GUI_RecordingSessionShow.m @@ -288,15 +288,26 @@ function pb_load_Callback(hObject, eventdata, handles) nM = get(handles.pm_nM,'Value'); % number of excersices or movements recSession = get(handles.pm_data,'UserData'); sT = recSession.sT; + EMG_AQhandle.nCh = recSession.nCh; + EMG_AQhandle.deviceName = recSession.dev; + nCh = recSession.nCh; + deviceName = recSession.dev; cdata = recSession.tdata(:,:,nM); + if isfield(recSession,'comm') + EMG_AQhandle.ComPortType = recSession.comm; + ComPortType = recSession.comm; + else + EMG_AQhandle.ComPortType = 'NI'; + ComPortType = 'NI'; + end %if get(handles.pm_data,'Value') == 1 % cdata = recSession.tdata(:,:,nM); %else % cdata = recSession.trdata(:,:,nM); %end DataShow(EMG_AQhandle,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); - + tempdata = cdata; + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); % --- Executes on button press in pb_cancel. diff --git a/SigRecordings/GUI_Recordings.fig b/SigRecordings/GUI_Recordings.fig index f189f1d..f520be7 100644 Binary files a/SigRecordings/GUI_Recordings.fig and b/SigRecordings/GUI_Recordings.fig differ diff --git a/SigRecordings/GUI_Recordings.m b/SigRecordings/GUI_Recordings.m index 7ea452f..8426d19 100644 --- a/SigRecordings/GUI_Recordings.m +++ b/SigRecordings/GUI_Recordings.m @@ -1,3 +1,4 @@ + % ---------------------------- Copyright Notice --------------------------- % This file is part of BioPatRec © which is open and free software under % the GNU Lesser General Public License (LGPL). See the file "LICENSE" for @@ -21,8 +22,23 @@ % ------------------------- Updates & Contributors ------------------------ % [Contributors are welcome to add their email] % 20xx-xx-xx / Max Ortiz / Creation +% 20xx-09-19 / Pontus Lövinger / Added plot and text for ramp recording recording +% 2015-01-23 / Pontus Lövinger / New recording session GUI: it has been added the + % possibility to plot more then 8 channels (for both time + % and frequency plots) +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offlinedata process as feature extraction or filter etc. + % 20xx-xx-xx / Author / Comment on update + + function varargout = GUI_Recordings(varargin) % GUI_Recordings M-file for GUI_Recordings.fig % GUI_Recordings, by itself, creates a new GUI_Recordings or raises the existing @@ -47,7 +63,7 @@ % Edit the above text to modify the response to help GUI_Recordings -% Last Modified by GUIDE v2.5 03-Jun-2012 19:04:56 +% Last Modified by GUIDE v2.5 24-Feb-2015 16:47:40 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... @@ -94,6 +110,16 @@ function GUI_Recordings_OpeningFcn(hObject, eventdata, handles, varargin) % Update handles structure guidata(hObject, handles); +fast = varargin{1}; +if(fast) + set(handles.et_tW,'visible','on'); + set(handles.et_sT,'visible','on'); + set(handles.txt_tW,'visible','on'); + set(handles.txt_sT,'visible','on'); + set(handles.pb_Start,'visible','on'); +end + + % UIWAIT makes GUI_Recordings wait for user response (see UIRESUME) % uiwait(handles.figure1); @@ -109,206 +135,21 @@ function GUI_Recordings_OpeningFcn(hObject, eventdata, handles, varargin) varargout{1} = handles.output; -% --- Executes on button press in pb_StartRecording. -function pb_StartRecording_Callback(hObject, eventdata, handles) - - sF = str2double(get(handles.et_Fs,'String')); - sT = str2double(get(handles.et_Ts,'String')); - pT = str2double(get(handles.et_Tp,'String')); - - % Get chAI (String identifying each channel - % the number of channels to record is selected automatically from the graphs - sCh(1) = get(handles.cb_ch0,'Value'); - sCh(2) = get(handles.cb_ch1,'Value'); - sCh(3) = get(handles.cb_ch2,'Value'); - sCh(4) = get(handles.cb_ch3,'Value'); - sCh(5) = get(handles.cb_ch4,'Value'); - sCh(6) = get(handles.cb_ch5,'Value'); - sCh(7) = get(handles.cb_ch6,'Value'); - sCh(8) = get(handles.cb_ch7,'Value'); - - % Legacy routines - %[ai,chp] = Init_NI_AI(handles,sF,sT,8); & DAQ using legacy - %cdata = NI_DataShow(handles,ai,chp,sF,sT,pT); - - cdata = DAQShow_SBI(handles,sCh,sF,sT,pT); - - save('cdata.mat','cdata','sF','sT'); - - -function et_Fs_Callback(hObject, eventdata, handles) -% hObject handle to et_Fs (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 et_Fs as text -% str2double(get(hObject,'String')) returns contents of et_Fs as a double - -input = str2double(get(hObject,'String')); -if (isempty(input)) - set(hObject,'String','0') -end -guidata(hObject, handles); - - -% --- Executes during object creation, after setting all properties. -function et_Fs_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_Fs (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 - - - -function et_Ts_Callback(hObject, eventdata, handles) -% hObject handle to et_Ts (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 et_Ts as text -% str2double(get(hObject,'String')) returns contents of et_Ts as a double -input = str2double(get(hObject,'String')); -if (isempty(input)) - set(hObject,'String','0') -end -guidata(hObject, handles); - - -% --- Executes during object creation, after setting all properties. -function et_Ts_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_Ts (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 - - - -function et_Tp_Callback(hObject, eventdata, handles) -% hObject handle to et_Tp (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 et_Tp as text -% str2double(get(hObject,'String')) returns contents of et_Tp as a double -input = str2double(get(hObject,'String')); -if (isempty(input)) - set(hObject,'String','0') -end -guidata(hObject, handles); - - -% --- Executes during object creation, after setting all properties. -function et_Tp_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_Tp (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 pb_initai. -function pb_initai_Callback(hObject, eventdata, handles) -% hObject handle to pb_initai (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) -% Get user input from GUI - - -% --- Executes on button press in cb_filter50hz. -function cb_filter50hz_Callback(hObject, eventdata, handles) -% hObject handle to cb_filter50hz (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_filter50hz - - -% --- Executes on button press in cb_filterBP. -function cb_filterBP_Callback(hObject, eventdata, handles) -% hObject handle to cb_filterBP (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_filterBP - - -% --- Executes on button press in cb_filter80Hz. -function cb_filter80Hz_Callback(hObject, eventdata, handles) -% hObject handle to cb_filter80Hz (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_filter80Hz - - -% --- Executes on button press in cb_ch0. -function cb_ch0_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch0 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_ch0 - - -% --- Executes on button press in cb_ch1. -function cb_ch1_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch1 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_ch1 - - -% --- Executes on button press in cb_ch2. -function cb_ch2_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch2 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_ch2 - - -% --- Executes on button press in cb_ch3. -function cb_ch3_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch3 (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) - -% Hint: get(hObject,'Value') returns toggle state of cb_ch3 - - - -function et_if0_Callback(hObject, eventdata, handles) +function et_if_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) set(hObject,'String','0') end - xmax = str2double(get(handles.et_ff0,'String')); + xmax = str2double(get(handles.et_ff,'String')); set(handles.a_f0,'XLim',[input xmax]); - set(handles.a_f1,'XLim',[input xmax]); - set(handles.a_f2,'XLim',[input xmax]); - set(handles.a_f3,'XLim',[input xmax]); guidata(hObject, handles); % --- Executes during object creation, after setting all properties. -function et_if0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_if0 (see GCBO) +function et_if_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_if (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -319,25 +160,21 @@ function et_if0_CreateFcn(hObject, eventdata, handles) end - -function et_ff0_Callback(hObject, eventdata, handles) +function et_ff_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) set(hObject,'String','0') end - xmin = str2double(get(handles.et_if0,'String')); + xmin = str2double(get(handles.et_if,'String')); set(handles.a_f0,'XLim',[xmin input]); - set(handles.a_f1,'XLim',[xmin input]); - set(handles.a_f2,'XLim',[xmin input]); - set(handles.a_f3,'XLim',[xmin input]); guidata(hObject, handles); % --- Executes during object creation, after setting all properties. -function et_ff0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_ff0 (see GCBO) +function et_ff_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ff (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -348,7 +185,6 @@ function et_ff0_CreateFcn(hObject, eventdata, handles) end - function et_n_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) @@ -390,8 +226,7 @@ function et_fc1_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end - - + function et_fc2_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); @@ -422,32 +257,28 @@ function pb_ApplyButter_Callback(hObject, eventdata, handles) cF2 = str2double(get(handles.et_fc2,'String')); % Load matrix load('cdata.mat'); - cdata = ApplyButterFilter(sF, N, cF1, cF2, cdata); - DataShow(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = ApplyButterFilter(sF, N, cF1, cF2, tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); -function et_it0_Callback(hObject, eventdata, handles) +function et_it_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) set(hObject,'String','0') end - xmax = str2double(get(handles.et_ft0,'String')); + xmax = str2double(get(handles.et_ft,'String')); set(handles.a_t0,'XLim',[input xmax]); - set(handles.a_t1,'XLim',[input xmax]); - set(handles.a_t2,'XLim',[input xmax]); - set(handles.a_t3,'XLim',[input xmax]); - set(handles.a_t4,'XLim',[input xmax]); - set(handles.a_t5,'XLim',[input xmax]); - set(handles.a_t6,'XLim',[input xmax]); - set(handles.a_t7,'XLim',[input xmax]); guidata(hObject, handles); % --- Executes during object creation, after setting all properties. -function et_it0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_it0 (see GCBO) +function et_it_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_it (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -458,28 +289,20 @@ function et_it0_CreateFcn(hObject, eventdata, handles) end - -function et_ft0_Callback(hObject, eventdata, handles) +function et_ft_Callback(hObject, eventdata, handles) input = str2double(get(hObject,'String')); if (isempty(input)) set(hObject,'String','0') end - xmin = str2double(get(handles.et_it0,'String')); + xmin = str2double(get(handles.et_it,'String')); set(handles.a_t0,'XLim',[xmin input]); - set(handles.a_t1,'XLim',[xmin input]); - set(handles.a_t2,'XLim',[xmin input]); - set(handles.a_t3,'XLim',[xmin input]); - set(handles.a_t4,'XLim',[xmin input]); - set(handles.a_t5,'XLim',[xmin input]); - set(handles.a_t6,'XLim',[xmin input]); - set(handles.a_t7,'XLim',[xmin input]); guidata(hObject, handles); % --- Executes during object creation, after setting all properties. -function et_ft0_CreateFcn(hObject, eventdata, handles) -% hObject handle to et_ft0 (see GCBO) +function et_ft_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_ft (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called @@ -503,43 +326,143 @@ function m_load_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- function t_load_ClickedCallback(hObject, eventdata, handles) -% Callback function run when the Open menu item is selected -ss = []; -[file, path] = uigetfile('*.mat'); - if ~isequal(file, 0) - load([path,file]); - if(exist('sF','var')) == 1 % Load current data - DataShow(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); - elseif exist('recSession','var') || ... % Load session - exist('ss','var') - df = GUI_RecordingSessionShow(); - dfdata = guidata(df); - if ~isempty(ss) - recSession = Compatibility_recSession(ss); - end - set(dfdata.et_Fs,'String',num2str(recSession.sF)); - set(dfdata.et_Ne,'String',num2str(recSession.nM)); - set(dfdata.et_Nr,'String',num2str(recSession.nR)); - set(dfdata.et_Tc,'String',num2str(recSession.cT)); - set(dfdata.et_Tr,'String',num2str(recSession.rT)); - set(dfdata.et_msg,'String',recSession.mov); - sNe = 1:recSession.nM; - set(dfdata.pm_nM,'String',num2str(sNe')); - set(dfdata.pm_data,'UserData',recSession); % Save Struct in user data - set(dfdata.t_mhandles,'UserData',handles); % Save this GUI handles - if isfield(recSession,'cmt') - set(dfdata.et_cmt,'String',recSession.cmt); - else - set(dfdata.et_cmt,'String','No Comment'); - end - if isfield(recSession,'dev') - set(dfdata.t_dev,'String',recSession.dev); + % Callback function run when the Open menu item is selected + ss = []; + [file, path] = uigetfile({'*.mat';'*.csv'}); + if ~isequal(file, 0) + [pathstr,name,ext] = fileparts(file); + if(strcmp(ext,'.mat')) + load([path,file]); + if(exist('sF','var')) == 1 % Load current data + if(exist('cdata','var')) == 1 % Load current data (fix compatibility issues) + DataShow(handles,cdata,sF,sT); + tempdata = cdata; + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); + elseif(exist('cData','var')) == 1 + DataShow(handles,cData,sF,sT); + tempdata = cdata; + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); + end + elseif exist('recSession','var') || ... % Load session + exist('ss','var') + df = GUI_RecordingSessionShow(); + dfdata = guidata(df); + if ~isempty(ss) + recSession = Compatibility_recSession(ss); + end + set(dfdata.et_Fs,'String',num2str(recSession.sF)); + set(dfdata.et_Ne,'String',num2str(recSession.nM)); + set(dfdata.et_Nr,'String',num2str(recSession.nR)); + set(dfdata.et_Tc,'String',num2str(recSession.cT)); + set(dfdata.et_Tr,'String',num2str(recSession.rT)); + set(dfdata.et_msg,'String',recSession.mov); + sNe = 1:recSession.nM; + set(dfdata.pm_nM,'String',num2str(sNe')); + set(dfdata.pm_data,'UserData',recSession); % Save Struct in user data + set(dfdata.t_mhandles,'UserData',handles); % Save this GUI handles + if isfield(recSession,'cmt') + set(dfdata.et_cmt,'String',recSession.cmt); + else + set(dfdata.et_cmt,'String','No Comment'); + end + if isfield(recSession,'dev') + set(dfdata.t_dev,'String',recSession.dev); + else + set(dfdata.t_dev,'String','Unknown'); + end + end else - set(dfdata.t_dev,'String','Unknown'); + %CSV / MCARE + fid = fopen(file); + fullDir = strcat(path,name,ext); % We get the path of the selected file + fileDir = dir(fullDir); % We use this to get the size, which is a field of dir + movText = fgetl(fid); % We read the first line + movText = textscan(movText, '%s', 'Delimiter', ',', 'BufSize', fileDir.bytes); %Scans for objects seperated with commas + recSession.mov = movText{1}; %And load them into the recSession + fclose(fid); %We need to close the file, before we can textscan it with other parameters + fid = fopen(file); + C = textscan(fid, '%s', 'Delimiter', '\n', 'BufSize', fileDir.bytes); % Scans for objects seperated by line breaks + recSession.date = C{1}{2}; + recSession.comm = C{1}{3}; + recSession.sF = csvread(file,3,0,[3, 0, 3, 0]); + recSession.nM = csvread(file,3,1,[3, 1, 3, 1]); + recSession.sT = csvread(file, 3,2,[3,2,3,2]); + recSession.cT = csvread(file, 3,3,[3,3,3,3]); + recSession.rT = csvread(file, 3,4,[3,4,3,4]); + recSession.nR = csvread(file, 3,5,[3,5,3,5]); + recSession.nCh = csvread(file, 3,6,[3,6,3,6]); + %Loading raw data + rawData = csvread(file,4,0)'; + %Preallocate memory + recSession.tdata = zeros(recSession.sF*recSession.cT*recSession.nR*2,recSession.nCh,recSession.nM); + %Sorts the data + for movements = 1 : recSession.nM + for channels = 1 : recSession.nCh + % We iterate over the repititions, as data from MCARE is exported channel-wise (as a subset of each repitition) + % The system is like this (for 3 repititions and 4 + % channels) + %iterator = + % 1 5 9 -> First channel + % 2 6 10 -> Second Channel + % 3 7 11 -> Third Channel + % 4 8 12 -> Fourth Channel + % ^ "lines of data" E.g. "1" = first channel from first + % repition. "5" = first channel from second repitition. + % "2" = second channel from first repitition. + iterator = channels+((movements-1)*(recSession.nCh*recSession.nR)); + for repititions = 1 : recSession.nR + recSession.tdata(1+((repititions-1)*(recSession.sF*(recSession.cT+recSession.rT))):repititions*(recSession.sF*(recSession.cT+recSession.rT)),channels,movements) = rawData(:,iterator); + iterator = iterator + recSession.nCh; + end + end + end + + df = GUI_RecordingSessionShow(); + dfdata = guidata(df); + if ~isempty(ss) + recSession = Compatibility_recSession(ss); + end + set(dfdata.et_Fs,'String',num2str(recSession.sF)); + set(dfdata.et_Ne,'String',num2str(recSession.nM)); + set(dfdata.et_Nr,'String',num2str(recSession.nR)); + set(dfdata.et_Tc,'String',num2str(recSession.cT)); + set(dfdata.et_Tr,'String',num2str(recSession.rT)); + set(dfdata.et_msg,'String',recSession.mov); + sNe = 1:recSession.nM; + set(dfdata.pm_nM,'String',num2str(sNe')); + set(dfdata.pm_data,'UserData',recSession); % Save Struct in user data + set(dfdata.t_mhandles,'UserData',handles); % Save this GUI handles + if isfield(recSession,'cmt') + set(dfdata.et_cmt,'String',recSession.cmt); + else + set(dfdata.et_cmt,'String','No Comment'); + end + if isfield(recSession,'dev') + set(dfdata.t_dev,'String',recSession.dev); + else + set(dfdata.t_dev,'String','Unknown'); + end end end + + % Set visible the offline plot and process panels + set(handles.uipanel9,'Visible','on'); + set(handles.uipanel7,'Visible','on'); + set(handles.uipanel8,'Visible','on'); + set(handles.txt_it,'visible','on'); + set(handles.txt_ft,'visible','on'); + set(handles.et_it,'visible','on'); + set(handles.et_ft,'visible','on'); + set(handles.txt_if,'visible','on'); + set(handles.txt_ff,'visible','on'); + set(handles.et_if,'visible','on'); + set(handles.et_ff,'visible','on'); + if exist('recSession','var') + chVector = 0:recSession.nCh-1; + else + chVector = 0:size(cdata,2)-1; end + set(handles.lb_channels, 'String', chVector); % -------------------------------------------------------------------- @@ -557,37 +480,11 @@ function m_record_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- -function m_Rstandardsession_Callback(hObject, eventdata, handles) -%Function that calls the standard recording session - Fs = 10000; % Sampling Frequency - Ne = 4; % number of excersices or movements - Nr = 10; % number of excersice repetition - Tc = 2; % time that the contractions should last - Tr = 3; % relaxing time - Psr = .5; % Percentage of the escersice time to be consider for training - msg = {'Open Hand'; - 'Close Hand'; - 'Flex Hand'; - 'Extend Hand'}; - %'Pronation '; - %'Supination '}; - - cdata = recording_session(Fs,Ne,Nr,Tc,Tr,Psr,msg,handles); - Ts = (Tc+Tr)*Nr; - save('cdata.mat','cdata','Fs','Ts'); - - -% -------------------------------------------------------------------- -function m_Recordoneshot_Callback(hObject, eventdata, handles) - pb_StartRecording_Callback(hObject, eventdata, handles) - - -% -------------------------------------------------------------------- function m_Rcustomizedsession_Callback(hObject, eventdata, handles) %Call the figure recording_Session_fig and pass this figure handles GUI_RecordingSession; - + % -------------------------------------------------------------------- function m_filters_Callback(hObject, eventdata, handles) % hObject handle to m_filters (see GCBO) @@ -596,168 +493,264 @@ function m_filters_Callback(hObject, eventdata, handles) % -------------------------------------------------------------------- -function m_Fcustomized_Callback(hObject, eventdata, handles) -% hObject handle to m_Fcustomized (see GCBO) -% eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) +function m_Fplh_Callback(hObject, eventdata, handles) + load('cdata.mat'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = BSbutterPLHarmonics(sF,tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); % -------------------------------------------------------------------- -function m_Fbandstop_Callback(hObject, eventdata, handles) -% hObject handle to m_Fbandstop (see GCBO) +function m_FBSbutter_Callback(hObject, eventdata, handles) +% hObject handle to m_FBSbutter (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - + % -------------------------------------------------------------------- -function m_Fplh_Callback(hObject, eventdata, handles) +function m_spatialFilterDDF_Callback(hObject, eventdata, handles) +% hObject handle to m_spatialFilterDDF (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) load('cdata.mat'); - cdata = BSbutterPLHarmonics(sF,cdata); - data_show(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = SpatialFilterDDF(tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); % -------------------------------------------------------------------- -function m_FBSbutter_Callback(hObject, eventdata, handles) -% hObject handle to m_FBSbutter (see GCBO) +function m_spatialFilterSDF_Callback(hObject, eventdata, handles) +% hObject handle to m_spatialFilterSDF (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) + load('cdata.mat'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = SpatialFilterSDF(tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); % -------------------------------------------------------------------- -function m_Pattern_Recognition_Callback(hObject, eventdata, handles) - pattern_recognition_fig(); - -% -------------------------------------------------------------------- -function m_PR_train_ANN_Callback(hObject, eventdata, handles) -% hObject handle to m_PR_train_ANN (see GCBO) +function m_spatialFilterDDFAbs_Callback(hObject, eventdata, handles) +% hObject handle to m_spatialFilterDDFAbs (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) + load('cdata.mat'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = SpatialFilterDDFAbs(tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); -% -------------------------------------------------------------------- -function m_Control_Callback(hObject, eventdata, handles) +% --- Executes on selection change in pm_features. +function pm_features_Callback(hObject, eventdata, handles) +% hObject handle to pm_features (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) +% Hints: contents = cellstr(get(hObject,'String')) returns pm_features contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_features -% -------------------------------------------------------------------- -function m_signalanalysis_Callback(hObject, eventdata, handles) - signalchrs_fig(); +% --- Executes during object creation, after setting all properties. +function pm_features_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_features (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called -% -------------------------------------------------------------------- -function m_onemotorTP_Callback(hObject, eventdata, handles) - one_motro_test_panel_fig(); +% Hint: popupmenu 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 cb_ch4. -function cb_ch4_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch4 (see GCBO) +% --- Executes on button press in pb_extract. +function pb_extract_Callback(hObject, eventdata, handles) +% hObject handle to pb_extract (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hint: get(hObject,'Value') returns toggle state of cb_ch4 + allF = get(handles.pm_features,'String'); + fID = char(allF(get(handles.pm_features,'Value'))); + load('cdata.mat'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + fD = 0.02*sF; % considering an overlap of 20 ms + tempdata = ExtractSigFeature(tempdata,sF,fID); +% sF = sF/fD; % Adjust the sample frequency by the overlap + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); -% --- Executes on button press in cb_ch5. -function cb_ch5_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch5 (see GCBO) +% -------------------------------------------------------------------- +function m_F50hz_Callback(hObject, eventdata, handles) +% hObject handle to m_F50hz (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) + load('cdata.mat'); + handles.nCh = size(tempdata,2); + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + tempdata = Filter50hz(sF,tempdata); + DataShow(handles,tempdata,sF,sT); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); -% Hint: get(hObject,'Value') returns toggle state of cb_ch5 - - -% --- Executes on button press in cb_ch6. -function cb_ch6_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch6 (see GCBO) +% --- Executes on selection change in lb_channels. +function lb_channels_Callback(hObject, eventdata, handles) +% hObject handle to lb_channels (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hint: get(hObject,'Value') returns toggle state of cb_ch6 +% Hints: contents = cellstr(get(hObject,'String')) returns lb_channels contents as cell array +% contents{get(hObject,'Value')} returns selected item from lb_channels -% --- Executes on button press in cb_ch7. -function cb_ch7_Callback(hObject, eventdata, handles) -% hObject handle to cb_ch7 (see GCBO) +% --- Executes during object creation, after setting all properties. +function lb_channels_CreateFcn(hObject, eventdata, handles) +% hObject handle to lb_channels (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB -% handles structure with handles and user data (see GUIDATA) +% handles empty - handles not created until after all CreateFcns called -% Hint: get(hObject,'Value') returns toggle state of cb_ch7 +% 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 Untitled_1_Callback(hObject, eventdata, handles) -% hObject handle to Untitled_1 (see GCBO) +% --- Executes on button press in pb_plotAll. +function pb_plotAll_Callback(hObject, eventdata, handles) +% hObject handle to pb_plotAll (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) + load('cdata.mat'); + handles.nCh = nCh; + handles.ComPortType = ComPortType; + handles.deviceName = deviceName; + DataShow(handles,cdata,sF,sT); + tempdata = cdata; + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); + set(handles.pb_plotSelected,'enable','on'); - -% -------------------------------------------------------------------- -function m_spatialFilterDDF_Callback(hObject, eventdata, handles) -% hObject handle to m_spatialFilterDDF (see GCBO) + +% --- Executes on button press in pb_plotSelected. +function pb_plotSelected_Callback(hObject, eventdata, handles) +% hObject handle to pb_plotSelected (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) + % Load data load('cdata.mat'); - cdata = SpatialFilterDDF(cdata); - data_show(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); + %Selected channels + Ch = get(handles.lb_channels,'Value'); + tempdata = tempdata(:,Ch); + tt = 0:1/sF:(length(tempdata)-1)/sF; + axes(handles.a_t0); + plot(tt, tempdata); + %Fast Fourier Transform + nS = length(tempdata); + NFFT = 2^nextpow2(nS); + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(tempdata(1:nS,:),NFFT)/nS; + m = 2*abs(dataf((1:NFFT/2),:)); + axes(handles.a_f0); + plot(f,m); + save('cdata.mat','cdata','tempdata','sF','sT','nCh','ComPortType','deviceName'); + set(handles.pb_plotSelected,'enable','off'); + + + +% --- Executes when figure1 is resized. +function figure1_ResizeFcn(hObject, eventdata, handles) +% hObject handle to figure1 (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) -% -------------------------------------------------------------------- -function m_spatialFilterSDF_Callback(hObject, eventdata, handles) -% hObject handle to m_spatialFilterSDF (see GCBO) +% --- Executes on button press in pb_Start. +function pb_Start_Callback(hObject, eventdata, handles) +% hObject handle to pb_Start (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - load('cdata.mat'); - cdata = SpatialFilterSDF(cdata); - data_show(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); + fast = 1; + sT = str2double(get(handles.et_sT,'String')); + tW = str2double(get(handles.et_tW,'String')); + handles.sT = sT; + handles.tW = tW; + GUI_AFEselection(0,0,0,0,0,handles,0,0,fast); -% -------------------------------------------------------------------- -function m_spatialFilterDDFAbs_Callback(hObject, eventdata, handles) -% hObject handle to m_spatialFilterDDFAbs (see GCBO) + +function et_sT_Callback(hObject, eventdata, handles) +% hObject handle to et_sT (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - load('cdata.mat'); - cdata = SpatialFilterDDFAbs(cdata); - data_show(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); +% Hints: get(hObject,'String') returns contents of et_sT as text +% str2double(get(hObject,'String')) returns contents of et_sT as a double -% --- Executes on selection change in pm_features. -function pm_features_Callback(hObject, eventdata, handles) -% hObject handle to pm_features (see GCBO) + +% --- Executes during object creation, after setting all properties. +function et_sT_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_sT (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 + + +function et_tW_Callback(hObject, eventdata, handles) +% hObject handle to et_tW (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) -% Hints: contents = cellstr(get(hObject,'String')) returns pm_features contents as cell array -% contents{get(hObject,'Value')} returns selected item from pm_features +% Hints: get(hObject,'String') returns contents of et_tW as text +% str2double(get(hObject,'String')) returns contents of et_tW as a double % --- Executes during object creation, after setting all properties. -function pm_features_CreateFcn(hObject, eventdata, handles) -% hObject handle to pm_features (see GCBO) +function et_tW_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_tW (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called -% Hint: popupmenu controls usually have a white background on Windows. +% 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 pb_extract. -function pb_extract_Callback(hObject, eventdata, handles) -% hObject handle to pb_extract (see GCBO) +% -------------------------------------------------------------------- +function m_Spatial_Callback(hObject, eventdata, handles) +% hObject handle to m_Spatial (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) - allF = get(handles.pm_features,'String'); - fID = char(allF(get(handles.pm_features,'Value'))); - load('cdata.mat'); - cdata = ExtractSigFeature(cdata,sF,fID); - DataShow(handles,cdata,sF,sT); - save('cdata.mat','cdata','sF','sT'); +% -------------------------------------------------------------------- +function m_Recordings_Callback(hObject, eventdata, handles) +% hObject handle to m_Recordings (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + set(handles.et_tW,'visible','on'); + set(handles.et_sT,'visible','on'); + set(handles.txt_tW,'visible','on'); + set(handles.txt_sT,'visible','on'); + set(handles.pb_Start,'visible','on'); + \ No newline at end of file diff --git a/SigRecordings/ObtainRampMax.m b/SigRecordings/ObtainRampMax.m new file mode 100644 index 0000000..87aed64 --- /dev/null +++ b/SigRecordings/ObtainRampMax.m @@ -0,0 +1,350 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2009-04-17 / Max Ortiz / Creation +% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording +% 2011-06-00 / Per and Gustav / Added the analog front end sections +% 2011-06-29 / Max Ortiz / Optimization to be integrated in the whole system and Fixed to new coding standard. + % Any filtering was removed from this routine + % Filtering and any other signal processing should be done in + % a singal treatment routine +% 2011-08-04 / Max Ortiz / The 10% of extra indication for the user + % to contract was removed. +% 2012-02-xx / Max Ortiz / Upgrade DAQ routines for MATLAB R2011b, SBI + % Old version was kept as: + % RecordinSession_Legacy +% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels + % However, the NI doesn't allow to skip channels +% 2012-04-30 / Max Ortiz / The possibility of simultaneous recordings was + % was removed since it didn't worked with the SBI + % in the current implementation. To see how the + % simultaneus recordings were done, see + % RecordingSession_Legacy +% 2012-12-07 / Nichlas Sander / Added VRE as an option during training. + % Movements to display are loaded in + % varargin{8}. This since previous movements + % were simply loaded as strings. +% 2013-03-07 / Nichlas Sander / When training Arm Flex/Extend the system + % will automatically change the view so the + % user can see the movement. +% 2013-08-23 / Morten Kristoffersen / Updated the recording sessions to support the new GUI_AFESelection structure +% 2013-09-19 / Pontus Lövinger / Copy of RecordingSession.m + % Now used to obatin the effort during rest + % Removed plotting functions, only use one + % repetiotionm always 3 sec contraction + % (relax), no VRE, changed instructions to user +% 2014-11-19 / Enzo Mastinu / Added the ADS1299 AFE routines, modified the + % abs based mean into RMS based mean, set the + % time window size to be samplingTime/100, RMS + % mean is done "manually" for Matlab compatibility + % reasons +% 2015-01-13 / Enzo Mastinu / The control of the different devices is now + % managed in other several functions placed + % into COMM/AFE folder. See recordingSession.m +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offlinedata process as feature extraction or filter etc. + +% 20xx-xx-xx / Author / Comment + + + +function [rampMax, maxData] = ObtainRampMax(varargin) + + global handles; + global allData; + global timeStamps; + global samplesCounter; + + allData = []; + nM = varargin{1}; + cT = 3; + mov = varargin{2}; + handles = varargin{3}; + afeSettings = varargin{4}; + trainWithVr = varargin{5}; + vreMovements = varargin{6}; + vreLeftHand = varargin{7}; + + % Get required informations from afeSettings structure + nCh = afeSettings.channels; + sF = afeSettings.sampleRate; + deviceName = afeSettings.name; + ComPortType = afeSettings.ComPortType; + if strcmp(ComPortType, 'COM') + ComPortName = afeSettings.ComPortName; + end + + % Save back acquisition parameters to the handles + handles.cT = cT; + handles.nCh = nCh; + handles.sF = sF; + handles.ComPortType = ComPortType; + if strcmp(ComPortType, 'COM') + handles.ComPortName = ComPortName; + end + handles.deviceName = deviceName; + % To avoid bugs in RecordingSession_ShowData function + handles.fast = 1; + handles.rep = 1; + handles.rT = cT; + handles.rampStatus = 0; + + % Initialization of sampling time + sT = cT; + sTall = cT; + handles.sTall = sTall; + handles.sT = sT; + + % Setting for data peeking + tW = sT/100; % Time window size + tWs = tW*sF; % Time window samples + handles.tWs = tWs; + timeStamps = 0:1/sF:tW-1/sF; % Create vector of time + + + %% Initialize GUI.. + + % Initialization of the VRE for training if required + if trainWithVr + % Parameters for the movement in the VRE + distance = 60; + numJumps = 30; + % Open and connect to the VRE + open('Virtual Reality.exe'); + handles.vreCommunication = tcpip('127.0.0.1',23068,'NetworkRole','server'); + fopen(handles.vreCommunication); + + %Set up VRE to not return any data. This will speed up the + %communication. + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(7),char(0),char(0),char(0))); + + % Send value to show Arm if that value is chosen. + sent = 0; + for i = 1:nM + for j = 1:length(vreMovements{i}) + movement = vreMovements{i}{j}; + if ismember(movement.id,[20 21]) && sent == 0 + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(6),char(1),char(0),char(0))); + sent = 1; + end + end + end + + if vreLeftHand + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(5),char(1),char(0),char(0))); + end + end + + pause on; + + % Initialize plots, offset the data + ampPP = 5; + sData = zeros(tWs,nCh); + fData = zeros(tWs,nCh); + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + for i = 1 : nCh + sData(:,i) = sData(:,i) + offVector(i); + fData(:,i) = fData(:,i) + offVector(i); + end + + % Draw figure + ymin = -ampPP*2/3; + ymax = ampPP * nCh - ampPP*1/3; + p_t0 = plot(handles.a_t0, timeStamps, sData); + handles.p_t0 = p_t0; + xlim(handles.a_t0, [0,tW]); + ylim(handles.a_t0, [ymin ymax]); + set(handles.a_t0,'YTick',offVector); + set(handles.a_t0,'YTickLabel',0:nCh-1); + p_f0 = plot(handles.a_f0,timeStamps,fData); + handles.p_f0 = p_f0; + xlim(handles.a_f0, [0,sF/2]); + ylim(handles.a_f0, [ymin ymax]); + set(handles.a_f0,'YTick',offVector); + set(handles.a_f0,'YTickLabel',0:nCh-1); + + % Initialization of progress bar + xpatch = [0 0 0 0]; + ypatch = [0 0 1 1]; + % set(handles.figure1,'CurrentAxes',handles.a_prog); + axes(handles.a_prog); + handles.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); + + % Allocation of resource to improve speed, total data + recSessionData = zeros(sF*sTall, nCh, nM); + + + %% Starting Session.. + + % Warning to the user + set(handles.t_msg,'String','Get ready for Maximum Voluntary Contraction'); + pause(7); + importdata('Img/relax.jpg'); % Import Image + drawnow; + + handles.contraction = 1; + + % Run all movements or excersices + for ex = 1 : nM + + timeStamps = 0:1/sF:tW-1/sF; % Timestamps used the time vector + currentTv = 1; % Current time vector + tV = timeStamps(currentTv):1/sF:(tW-1/sF)+timeStamps(currentTv); % Time vector used for drawing graphics + currentTv = currentTv - 1 + tWs; % Updated everytime tV is updated + acquireEvent.TimeStamps = tV'; + + disp(['Start ex: ' num2str(ex) ]) + + % Warning to the user + fileName = ['Img/' char(mov(ex)) '.jpg']; + if ~exist(fileName,'file') + fileName = 'Img/relax.jpg'; + end + + movI = importdata(fileName); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + + % Show warning to prepare + set(handles.t_msg,'String',['Get ready for Maximum Effort ' mov(ex) ' in 3 s']); + pause(1); + set(handles.t_msg,'String',['Get ready for Maximum Effort ' mov(ex) ' in 2 s']); + pause(1); + set(handles.t_msg,'String',['Get ready for Maximum Effort ' mov(ex) ' in 1 s']); + pause(1); + + % Minimum Maximum Contraction with NI DAQ card + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @RecordingSession_ShowData); + + % Start DAQ + s.startBackground(); % Run in the backgroud + + % Contraction + set(handles.t_msg,'String',mov(ex)); + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + startContractionTic = tic; + if trainWithVr + numberOfMovements = length(vreMovements{ex}); + tempJumps = numJumps/numberOfMovements; + tempDistance = round(distance/tempJumps); + vreString = ''; + for i = 1:numberOfMovements + movement = vreMovements{ex}{i}; + vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); + end + for j = 1:tempJumps + fwrite(handles.vreCommunication,vreString); + end + end + pause(cT - toc(startContractionTic)); + + % Minimum Voluntary Contraction with other devices + else + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + % new contraction, the GUI must be updated + set(handles.t_msg,'String',mov(ex)); + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + drawnow; + if trainWithVr + numberOfMovements = length(vreMovements{ex}); + tempJumps = numJumps/numberOfMovements; + tempDistance = round(distance/tempJumps); + vreString = ''; + for i = 1:numberOfMovements + movement = vreMovements{ex}{i}; + vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); + end + for j = 1:tempJumps + fwrite(handles.vreCommunication,vreString); + end + end + + samplesCounter = 1; % variable used to track the progressing time of the recording session + tic + for timeWindowNr = 1:sT/tW + + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + RecordingSession_ShowData(0, acquireEvent); % plot data and add cData to allData vector + + samplesCounter = samplesCounter + tWs; + end + toc + + % Stop acquisition, contraction time expired + StopAcquisition(deviceName, obj); + + end + + % NI DAQ card: "You must delete the listener once the operation is complete" + if strcmp(ComPortType,'NI'); + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + end + + % Save Data + recSessionData(:,:,ex) = allData(:,:); + allData = []; % clean global data for next movement + + end + + set(handles.a_pic,'Visible','off'); % Turn OFF visibility + delete(pic); % Delete image + set(handles.t_msg,'String','Maximum and Minimum Session Terminated'); % Show message about acquisition + pause(3); + + if trainWithVr + fclose(handles.vreCommunication); + end + + %% Get the max value and organize them acccording to the selected movements + maxData = recSessionData(1:cT*sF,:,:); % Take only contraction part, from 0 to cT [s] + percent = (cT/100)*20; + cleaned = maxData(percent*sF:(cT-percent)*sF-1,:,:); % Remove the 20% from the begin and from the end of the data + avgSample = sqrt(mean((cleaned.^2),1)); % RMS Mean value compatible with old version of Matlab + + chMean = mean(avgSample); % Averages the time windows then averages the channels + rampMax = squeeze(chMean); + +end diff --git a/SigRecordings/ObtainRampMin.m b/SigRecordings/ObtainRampMin.m new file mode 100644 index 0000000..c9ca2ea --- /dev/null +++ b/SigRecordings/ObtainRampMin.m @@ -0,0 +1,265 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2009-04-17 / Max Ortiz / Creation +% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording +% 2011-06-00 / Per and Gustav / Added the analog front end sections +% 2011-06-29 / Max Ortiz / Optimization to be integrated in the whole system and Fixed to new coding standard. + % Any filtering was removed from this routine + % Filtering and any other signal processing should be done in + % a singal treatment routine +% 2011-08-04 / Max Ortiz / The 10% of extra indication for the user + % to contract was removed. +% 2012-02-xx / Max Ortiz / Upgrade DAQ routines for MATLAB R2011b, SBI + % Old version was kept as: + % RecordinSession_Legacy +% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels + % However, the NI doesn't allow to skip channels +% 2012-04-30 / Max Ortiz / The possibility of simultaneous recordings was + % was removed since it didn't worked with the SBI + % in the current implementation. To see how the + % simultaneus recordings were done, see + % RecordingSession_Legacy +% 2012-12-07 / Nichlas Sander / Added VRE as an option during training. + % Movements to display are loaded in + % varargin{8}. This since previous movements + % were simply loaded as strings. +% 2013-03-07 / Nichlas Sander / When training Arm Flex/Extend the system + % will automatically change the view so the + % user can see the movement. +% 2013-08-23 / Morten Kristoffersen / Updated the recording sessions to support the new GUI_AFESelection structure +% 2013-09-19 / Pontus Lövinger / Copy of RecordingSession.m + % Now used to obatin the effort during rest + % Removed plotting functions, only use one + % repetiotionm always 3 sec contraction + % (relax), no VRE, changed instructions to user +% 2014-11-19 / Enzo Mastinu / Added the ADS1299 AFE routines, modified the + % abs based mean into RMS based mean, set the + % time window size to be samplingTime/100, RMS + % mean is done "manually" for Matlab compatibility + % reasons +% 2015-01-13 / Enzo Mastinu / The control of the different devices is now + % managed in other several functions placed + % into COMM/AFE folder. See recordingSession.m +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offlinedata process as feature extraction or filter etc. + +% 20xx-xx-xx / Author / Comment + + + +function [rampMin, minData] = ObtainRampMin(varargin) + + global handles; + global allData; + global timeStamps; + global samplesCounter; + + allData = []; + nR = 1; % Only one repetition + rT = 3; % Always use 3 sec relaxation time + handles = varargin{1}; + afeSettings = varargin{2}; + + % Get required informations from afeSettings structure + nCh = afeSettings.channels; + sF = afeSettings.sampleRate; + deviceName = afeSettings.name; + ComPortType = afeSettings.ComPortType; + if strcmp(ComPortType, 'COM') + ComPortName = afeSettings.ComPortName; + end + + % Save back acquisition parameters to the handles + handles.nR = nR; + handles.rT = rT; + handles.nCh = nCh; + handles.sF = sF; + handles.ComPortType = ComPortType; + if strcmp(ComPortType, 'COM') + handles.ComPortName = ComPortName; + end + handles.deviceName = deviceName; + % To avoid bugs in RecordingSession_ShowData function + handles.fast = 1; + handles.rep = 1; + handles.cT = rT; + handles.rampStatus = 0; + + % Initialization of sampling time + sT = rT; + sTall = rT; + handles.sTall = sTall; + handles.sT = sT; + + % Setting for data peeking + tW = sT/100; % Time window size + tWs = tW*sF; % Time window samples + handles.tWs = tWs; + timeStamps = 0:1/sF:tW-1/sF; % Create vector of time + + + %% Initialize GUI.. + pause on; + + % Initialize plots, offset the data + ampPP = 5; + sData = zeros(tWs,nCh); + fData = zeros(tWs,nCh); + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + for i = 1 : nCh + sData(:,i) = sData(:,i) + offVector(i); + fData(:,i) = fData(:,i) + offVector(i); + end + + % Draw figure + ymin = -ampPP*2/3; + ymax = ampPP * nCh - ampPP*1/3; + p_t0 = plot(handles.a_t0, timeStamps, sData); + handles.p_t0 = p_t0; + xlim(handles.a_t0, [0,tW]); + ylim(handles.a_t0, [ymin ymax]); + set(handles.a_t0,'YTick',offVector); + set(handles.a_t0,'YTickLabel',0:nCh-1); + p_f0 = plot(handles.a_f0,timeStamps,fData); + handles.p_f0 = p_f0; + xlim(handles.a_f0, [0,sF/2]); + ylim(handles.a_f0, [ymin ymax]); + set(handles.a_f0,'YTick',offVector); + set(handles.a_f0,'YTickLabel',0:nCh-1); + + % Initialization of progress bar + xpatch = [0 0 0 0]; + ypatch = [0 0 1 1]; + % set(handles.figure1,'CurrentAxes',handles.a_prog); + axes(handles.a_prog); + handles.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); + + + %% Starting Session.. + + % Warning to the user + set(handles.t_msg,'String','Keep a relaxed/rest position, avoid every contraction'); + relax = importdata('Img/relax.jpg'); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(relax,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + drawnow; + pause(7); + + handles.contraction = 0; + + % for ex = 1 : nM + ex = 1; + + % Show warning to prepare + set(handles.t_msg,'String','Get ready to Relax in 3 s'); + pause(1); + set(handles.t_msg,'String','Get ready to Relax in 2 s'); + pause(1); + set(handles.t_msg,'String','Get ready to Relax in 1 s'); + pause(1); + + timeStamps = 0:1/sF:tW-1/sF; % Timestamps used the time vector + currentTv = 1; % Current time vector + tV = timeStamps(currentTv):1/sF:(tW-1/sF)+timeStamps(currentTv); % Time vector used for drawing graphics + currentTv = currentTv - 1 + tWs; % Updated everytime tV is updated + acquireEvent.TimeStamps = tV'; + + % Minimum Voluntary Contraction with NI DAQ card + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @RecordingSession_ShowData); + + % Start DAQ + cData = zeros(sF*sT, nCh); + s.startBackground(); % Run in the backgroud + + % Contraction + set(handles.t_msg,'String','Relax'); + startRelaxationTic = tic; + pause(rT - toc(startRelaxationTic)); + + % Minimum Voluntary Contraction with other devices + else + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + % update the GUI + set(handles.t_msg,'String','Relax'); + + samplesCounter = 1; % variable used to track the progressing time of the recording session + tic + for timeWindowNr = 1:sT/tW + + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + RecordingSession_ShowData(0, acquireEvent); % plot data and add cData to allData vector + + samplesCounter = samplesCounter + tWs; + end + toc + + % Stop acquisition, "contraction" time expired + StopAcquisition(deviceName, obj); + + end + + % NI DAQ card: "You must delete the listener once the operation is complete" + if strcmp(ComPortType,'NI'); + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + end + + set(handles.a_pic,'Visible','off'); % Turn OFF visibility + delete(pic); % Delete image + set(handles.t_msg,'String','Relaxed State Recorded'); % Show message about acquisition + pause(3); + + + %% Get the minimum voluntary contraction informations from allData vector + minData = allData(1:rT*sF,:); % Take only "contraction" part, from 0 to rT [s] + percent = (rT/100)*20; + cleaned = minData(percent*sF:(rT-percent)*sF-1,:); % Remove the 20% from the begin and from the end of the data +% avgSample = mean(rms(cleaned),1); % RMS Mean value over the samples + avgSample = sqrt(mean((cleaned.^2),1)); % RMS Mean value compatible with old version of Matlab + + chMean = mean(avgSample); % Averages over the channels + rampMin = chMean(:,:,1); % Get the averge minimum value + % rampMin = squeeze(chMean); + +end diff --git a/SigRecordings/RecordingSession.m b/SigRecordings/RecordingSession.m index b78fb32..610227e 100644 --- a/SigRecordings/RecordingSession.m +++ b/SigRecordings/RecordingSession.m @@ -1,719 +1,536 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% ------------------- Function Description ------------------ -% Function to Record Exc Sessions -% -% --------------------------Updates-------------------------- -% 2009-04-17 / Max Ortiz / Creation -% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording -% 2011-06-00 / Per and Gustav / Added the analog front end sections -% 2011-06-29 / Max Ortiz / Optimization to be integrated in the whole system and Fixed to new coding standard. - % Any filtering was removed from this routine - % Filtering and any other signal processing should be done in - % a singal treatment routine -% 2011-08-04 / Max Ortiz / The 10% of extra indication for the user - % to contract was removed. -% 2012-02-xx / Max Ortiz / Upgrade DAQ routines for MATLAB R2011b, SBI - % Old version was kept as: - % RecordinSession_Legacy -% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels - % However, the NI doesn't allow to skip channels -% 2012-04-30 / Max Ortiz / The possibility of simultaneous recordings was - % was removed since it didn't worked with the SBI - % in the current implementation. To see how the - % simultaneus recordings were done, see - % RecordingSession_Legacy -% 2012-12-07 / Nichlas Sander / Added VRE as an option during training. - % Movements to display are loaded in - % varargin{8}. This since previous movements - % were simply loaded as strings. -% 20xx-xx-xx / Author / Comment - - - -function [cdata, sF] = RecordingSession(varargin) - -global handles; -global allData; - -allData = []; -nM = varargin{1}; -nR = varargin{2}; -cT = varargin{3}; -rT = varargin{4}; -mov = varargin{5}; -handles = varargin{6}; -afeSettings = varargin{7}; -trainWithVr = varargin{8}; -vreMovements = varargin{9}; -vreLeftHand = varargin{10}; - -distance = 90; -numJumps = 45; - -sT = (cT+rT)*nR; % Sampling time, it is the time of contraction + - % Time of relaxation x Number of repetitions - -% Get number of channels and sampling frequency -% for the device to be displayed -if afeSettings.NI.show - nCh = afeSettings.NI.channels; - sF = afeSettings.NI.sampleRate; -elseif afeSettings.ADS.show - nCh = afeSettings.ADS.channels; - sF = afeSettings.ADS.sampleRate; -elseif afeSettings.RHA.show - nCh = afeSettings.RHA.channels; - sF = afeSettings.RHA.sampleRate; -end - -if trainWithVr - open('Virtual Reality.exe'); - handles.vreCommunication = tcpip('127.0.0.1',23068,'NetworkRole','server'); - fopen(handles.vreCommunication); - - %Set up VRE to not return any data. This will speed up the - %communication. - fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(7),char(0),char(0),char(0))); - - % Send value to show Arm if that value is chosen. - sent = 0; - for i = 1:nM - for j = 1:length(vreMovements{i}) - movement = vreMovements{i}{j}; - if ismember(movement.id,[20 21]) && sent == 0 - fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(6),char(1),char(0),char(0))); - sent = 1; - end - end - end - - if vreLeftHand - fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(5),char(1),char(0),char(0))); - end -end - -handles.sF = sF; -handles.cT = cT; -handles.rT = rT; -handles.nCh = nCh; - -pause on; - -%% Initialize plots -% Create handles for the plots -% this is faster than creating the plot everytime -tt = 0:1/sF:sT/100-1/sF; % Create data for sT / 100 -ymin = -3; -ymax = 3; - -% Init the plots -if nCh >= 1 - %axes(handles.a_t0); - p_t0 = plot(handles.a_t0,tt,tt); - xlim('auto'); - ylim(handles.a_t0, [ymin ymax]); - handles.p_t0 = p_t0; - %axes(handles.a_f0); - p_f0 = plot(handles.a_f0,1,1); - handles.p_f0 = p_f0; -end -if nCh >= 2 - p_t1 = plot(handles.a_t1,tt,tt); - ylim(handles.a_t1, [ymin ymax]); - p_f1 = plot(handles.a_f1,1,1); - handles.p_t1 = p_t1; - handles.p_f1 = p_f1; -end -if nCh >= 3 - p_t2 = plot(handles.a_t2,tt,tt); - ylim(handles.a_t2, [ymin ymax]); - p_f2 = plot(handles.a_f2,1,1); - handles.p_t2 = p_t2; - handles.p_f2 = p_f2; -end - -if nCh >= 4 - p_t3 = plot(handles.a_t3,tt,tt); - ylim(handles.a_t3, [ymin ymax]); - p_f3 = plot(handles.a_f3,1,1); - handles.p_t3 = p_t3; - handles.p_f3 = p_f3; -end - -if nCh >= 5 - p_t4 = plot(handles.a_t4,tt,tt); - ylim(handles.a_t4, [ymin ymax]); - %axes(handles.a_f4); - %p_f4 = plot(1,1); - handles.p_t4 = p_t4; -end - -if nCh >= 6 - p_t5 = plot(handles.a_t5,tt,tt); - ylim(handles.a_t5, [ymin ymax]); - %axes(handles.a_f5); - %p_f5 = plot(1,1); - handles.p_t5 = p_t5; -end - -if nCh >= 7 - p_t6 = plot(handles.a_t6,tt,tt); - ylim(handles.a_t6, [ymin ymax]); - %axes(handles.a_f6); - %p_f6 = plot(1,1); - handles.p_t6 = p_t6; -end - -if nCh >= 8 - p_t7 = plot(handles.a_t7,tt,tt); - ylim(handles.a_t7, [ymin ymax]); - %axes(handles.a_f7); - %p_f7 = plot(1,1); - handles.p_t7 = p_t7; -end - -%% Initialization of progress bar -xpatch = [0 0 0 0]; -ypatch = [0 0 1 1]; -%set(handles.figure1,'CurrentAxes',handles.a_prog); -axes(handles.a_prog); -handles.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); - -%% Initialization of the effort bar -xpatch = [1 1 0 0]; -ypatch = [0 0 0 0]; -axes(handles.a_effort0); -handles.hPatch0 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort1); -handles.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort1); -handles.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort2); -handles.hPatch2 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort3); -handles.hPatch3 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort4); -handles.hPatch4 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort5); -handles.hPatch5 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort6); -handles.hPatch6 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(handles.a_effort7); -handles.hPatch7 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -handles.effortMax = 2; - - -%% Initialize DAQ card -if afeSettings.NI.active - %afeSettings.NI.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - % instruction from Per and Gustav, why - % would you overwrite the selected sF? - - % All following sF needs to be changed to - % invidual sF in order to make it work - % /Per - %ai = Init_NI_AI(handles,afeSettings.NI.sampleRate,sT,nCh); %Legacy - %Init SBI - sCh = 1:nCh; - s = InitSBI_NI(afeSettings.NI.sampleRate,sT,sCh); - s.NotifyWhenDataAvailableExceeds = (sF*sT)/100; % PEEK time - lh = s.addlistener('DataAvailable', @RecordingSession_ShowData); - - dev = afeSettings.NI.name; - -end -if afeSettings.ADS.active - Amp=12; - Vref=2.4*2; %*2 is from bipolar reference - ByteDepth=3; - afeSettings.ADS.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - dataFormat=2; - ADS = AFE_PICCOLO(afeSettings.ADS.ComPortType,afeSettings.ADS.sampleRate, ... - sT,nCh,Amp,Vref,dataFormat,afeSettings.ADS.name,ByteDepth); -end -if afeSettings.RHA.active - Amp=200; - Vref=2.5; - ByteDepth=2; - afeSettings.RHA.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - dataFormat=1; - RHA = AFE_PICCOLO(afeSettings.RHA.ComPortType,afeSettings.RHA.sampleRate, ... - sT,nCh,Amp,Vref,dataFormat,afeSettings.RHA.name,ByteDepth); -end - -%% Allocation of resource to improve speed, total data - -sbiData = zeros(sF*sT,nCh,nM); -ADStdata = zeros(sF*sT,nCh,nM); -RHAtdata = zeros(sF*sT,nCh,nM); - -% Warning to the user -set(handles.t_msg,'String','Get ready to start: 3'); -pause(1); -set(handles.t_msg,'String','Get ready to start: 2'); -pause(1); -set(handles.t_msg,'String','Get ready to start: 1'); -pause(1); - -relax = importdata('Img/relax.jpg'); % Import Image -drawnow; - -%% Run all movements or excersices -for ex = 1 : nM - disp(['Start ex: ' num2str(ex) ]) - - % Warning to the user - fileName = ['Img/' char(mov(ex)) '.jpg']; - if ~exist(fileName,'file') - fileName = 'Img/relax.jpg'; - end - - movI = importdata(fileName); % Import Image - set(handles.a_pic,'Visible','on'); % Turn on visibility - %axes(handles.a_pic); % get handles - pic = image(movI,'Parent',handles.a_pic); % set image - axis(handles.a_pic,'off'); % Remove axis tick marks - - % Show warning to prepare - set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 3 s']); - pause(1); - set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 2 s']); - pause(1); - set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 1 s']); - %set(handles.a_pic,'Visible','off'); % Turn OFF visibility - %delete(pic); % Delete image - pause(1); - - %% Dummy Contraction - set(handles.t_msg,'String',mov(ex)); - if afeSettings.prepare - if trainWithVr - numberOfMovements = length(vreMovements{ex}); - tempJumps = numJumps/numberOfMovements; - tempDistance = round(distance/tempJumps); - vreString = ''; - for i = 1:numberOfMovements - movement = vreMovements{ex}{i}; - vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); - end - for j = 1:tempJumps - fwrite(handles.vreCommunication,vreString); - end - end - - pause(cT); - set(handles.t_msg,'String','Relax'); - if trainWithVr - fwrite(handles.vreCommunication,sprintf(sprintf('%c%c%c%c%c','r',char(1),char(1),char(1),char(1)))); - end - pic = image(relax,'Parent',handles.a_pic); % set image - axis(handles.a_pic,'off'); % Remove axis tick marks - pause(rT); - end - - - %% Start DAQ - if afeSettings.NI.active - % start(ai); - % Run in the backgroud - s.startBackground(); - end - if afeSettings.ADS.active - ADS.startRecording - end - if afeSettings.RHA.active - RHA.startRecording - end - - %% Repetitions - for rep = 1 : nR - handles.rep = rep; - - % Contraction - set(handles.t_msg,'String',mov(ex)); - pic = image(movI,'Parent',handles.a_pic); % set image - axis(handles.a_pic,'off'); % Remove axis tick marks - handles.contraction = 1; - startContractionTic = tic; - if trainWithVr - numberOfMovements = length(vreMovements{ex}); - tempJumps = numJumps/numberOfMovements; - tempDistance = round(distance/tempJumps); - vreString = ''; - for i = 1:numberOfMovements - movement = vreMovements{ex}{i}; - vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); - end - for j = 1:tempJumps - fwrite(handles.vreCommunication,vreString); - end - end - pause(cT - toc(startContractionTic)); - - % Relax - set(handles.t_msg,'String','Relax'); - startRelaxingTic = tic; - if trainWithVr - for i = 1:numJumps - fwrite(handles.vreCommunication,sprintf(sprintf('%c%c%c%c%c',char(1),char(14),char(1),char(distance/numJumps),char(1)))); - end - end - pic = image(relax,'Parent',handles.a_pic); % set image - axis(handles.a_pic,'off'); % Remove axis tick marks - handles.contraction = 0; - pause(rT - toc(startRelaxingTic)); - end - - %% Save Data - if afeSettings.NI.active - %check if is done - if ~s.IsDone - s.wait(); - end - sbiData(:,:,ex) = allData; - % clean global data for next movement - allData = []; - - end - if afeSettings.RHA.active -% disp('RHA:') -% disp(RHA.SamplesAcquired) -% disp(RHA.bytesAcquired) -% disp(size(RHA.data)) - data = [RHA.data ; RHA.storeFromBuffer]; -% disp(size(data)) -% disp(size(RHAtdata)) - RHAtdata(:,:,ex)=data * (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); %Converting to input referred voltage - end - if afeSettings.ADS.active -% disp('ADS:') -% disp(ADS.SamplesAcquired) -% disp(ADS.bytesAcquired) -% disp(size(data)) - - data = [ADS.data ; ADS.storeFromBuffer]; -% disp(size(data)) -% disp(size(ADStdata)) - ADStdata(:,:,ex)=data * (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); %Converting to input referred voltage - end - -end - - -set(handles.t_msg,'String','Session Terminated'); % Show message about acquisition - -%% Save data and compute training data using cTp -if afeSettings.NI.active - delete(lh); - NItdata=sbiData; -else - NItdata=[]; -end -if afeSettings.ADS.active - ADStdata=ADStdata; - %ADStrdata=ComputeTrainingData(ADStdata,sF,cT,rT,nR,nM,cTp); -else - ADStdata=[]; - %ADStrdata=[]; -end - -if afeSettings.RHA.active - RHAtdata=RHAtdata; - %RHAtrdata=ComputeTrainingData(RHAtdata,sF,cT,rT,nR,nM,cTp); -else - RHAtdata=[]; - %RHAtrdata=[]; -end - - -%% Save Session to file -recSession.sF = sF; -recSession.sT = sT; -recSession.cT = cT; -recSession.rT = rT; -recSession.nM = nM; -recSession.nR = nR; -recSession.nCh = nCh; -recSession.dev = dev; -recSession.mov = mov; -recSession.date = fix(clock); -recSession.cmt = inputdlg('Additional comment on the recording session','Comments'); - -[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); - if isequal(filename,0) || isequal(pathname,0) - disp('User pressed cancel') - else - disp(['User selected ', fullfile(pathname, filename)]) - if afeSettings.NI.active - recSession.tdata = NItdata; - save([pathname,filename],'recSession'); - - %recSession.trdata = NItrdata; -% if exist([pathname 'NI\'],'dir') == 0 -% mkdir(pathname,'NI') -% end -% save([pathname, 'NI\',filename],'recSession'); - end - if afeSettings.ADS.active - recSession.tdata = ADStdata; - %recSession.trdata = ADStrdata; - %Possible to add string with device info for example recSession.device=afeSettings.ADS.name; - if exist([pathname 'ADS1298\'],'dir') == 0 - mkdir(pathname,'ADS1298') - end - save([pathname, 'ADS1298\',filename],'recSession'); - - % not needed here any more? -% if filters.PLH || filters.BP -% recSession.tdata = ADStdataFiltered; -% % recSession.trdata = ADStrdataFiltered; -% if exist([pathname 'ADS1298Filtered\'],'dir') == 0 -% mkdir(pathname,'ADS1298Filtered') -% end -% save([pathname,'ADS1298Filtered\',filename],'recSession'); -% end - end - if afeSettings.RHA.active - recSession.tdata = RHAtdata; - %recSession.trdata = RHAtrdata; - %Possible to add string with device info for example recSession.device=afeSettings.RHA.name; - if exist([pathname 'RHA2216\'],'dir') == 0 - mkdir(pathname,'RHA2216') - end - save([pathname 'RHA2216\',filename],'recSession'); - - % not needed here any more? -% if filters.PLH || filters.BP -% recSession.tdata = RHAtdataFiltered; -% %recSession.trdata = RHAtrdataFiltered; -% if exist([pathname 'RHA2216Filtered\'],'dir') == 0 -% mkdir(pathname,'RHA2216Filtered') -% end -% save([pathname,'RHA2216Filtered\',filename],'recSession'); -% end - end - end - -% Copy acquired data from the last excersice into cdata -% Display it -disp(recSession); - -if afeSettings.NI.show - data = NItdata(:,:,end); -elseif afeSettings.ADS.show - data = ADStdata(:,:,end).* (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); -elseif afeSettings.RHA.show - data = RHAtdata(:,:,end).* (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); -end - -chIdx=1; -if nCh >= 1 - cdata(:,1) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 2 - cdata(:,2) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 3 - cdata(:,3) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 4 - cdata(:,4) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 5 - cdata(:,5) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 6 - cdata(:,6) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 7 - cdata(:,7) = data(:,chIdx); - chIdx=chIdx+1; -end -if nCh >= 8 - cdata(:,8) = data(:,chIdx); -end - -if trainWithVr - fclose(handles.vreCommunication); -end - -DataShow(handles,cdata,sF,sT); -set(handles.a_pic,'Visible','off'); % Turn OFF visibility -delete(pic); % Delete image -end - - -function RecordingSession_ShowData(src,event) - - global handles; - global allData; - persistent timeStamps; - - % Get info from hendles - sF = handles.sF; - nCh = handles.nCh; - effortMax = handles.effortMax; - rep = handles.rep; - cT = handles.cT; - rT = handles.rT; - - - % Get data - if(isempty(allData)) % Fist DAQ callback - timeStamps = []; - end - - tempData = event.Data; - allData = [allData; tempData]; - timeStamps = [timeStamps; event.TimeStamps]; - - %% Status bar update - %thisToc = timeStamps(end) - ((rep-1)*(cT+rT)); - %lastToc = (cT+rT); - if handles.contraction - thisToc = timeStamps(end) - ((rep-1)*(cT+rT)); - lastToc = cT; - else - thisToc = timeStamps(end) - ((rep*cT)+((rep-1)*rT)); - lastToc = rT; - end - - x =1-(thisToc/lastToc); -% set(handles.figure1,'CurrentAxes',handles.a_prog); - set(handles.hPatch,'Xdata',[0 x x 0]); - - - %% Display peeked Data - aNs = length(tempData(:,1)); - NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(tempData(1:aNs,:),NFFT)/aNs; - m = 2*abs(dataf((1:NFFT/2),:)); - - - chIdx = 1;%Channel Index for map data - if nCh >= 1 - p_t0 = handles.p_t0; - p_f0 = handles.p_f0; - set(p_t0,'YData',tempData(:,chIdx)); - set(p_f0,'XData',f); - set(p_f0,'YData',m(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch0,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - end - if nCh >= 2 - p_t1 = handles.p_t1; - p_f1 = handles.p_f1; - set(p_t1,'YData',tempData(:,chIdx)); - set(p_f1,'XData',f); - set(p_f1,'YData',m(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch1,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - end - if nCh >= 3 - p_t2 = handles.p_t2; - p_f2 = handles.p_f2; - set(p_t2,'YData',tempData(:,chIdx)); - set(p_f2,'XData',f); - set(p_f2,'YData',m(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch2,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - end - if nCh >= 4 - p_t3 = handles.p_t3; - p_f3 = handles.p_f3; - set(p_t3,'YData',tempData(:,chIdx)); - set(p_f3,'XData',f); - set(p_f3,'YData',m(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch3,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - end - if nCh >= 5 - p_t4 = handles.p_t4; - set(p_t4,'YData',tempData(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch4,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - %set(p_f4,'XData',f); - %set(p_f4,'YData',m(:,chIdx)); - end - if nCh >= 6 - p_t5 = handles.p_t5; - set(p_t5,'YData',tempData(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch5,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - %set(p_f5,'XData',f); - %set(p_f5,'YData',m(:,chIdx)); - end - if nCh >= 7 - p_t6 = handles.p_t6; - set(p_t6,'YData',tempData(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch6,'Ydata',[0 x x 0]); - - chIdx=chIdx+1; - %set(p_f6,'XData',f); - %set(p_f6,'YData',m(:,chIdx)); - end - if nCh >= 8 - p_t7 = handles.p_t7; - set(p_t7,'YData',tempData(:,chIdx)); - % Update effort bar - xT = mean(abs(tempData(:,chIdx))); - x = xT / effortMax; - set(handles.hPatch7,'Ydata',[0 x x 0]); - - %set(p_f7,'XData',f); - %set(p_f7,'YData',m(:,chIdx)); - end - - -end - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2009-04-17 / Max Ortiz / Creation +% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording +% 2011-06-00 / Per and Gustav / Added the analog front end sections +% 2011-06-29 / Max Ortiz / Optimization to be integrated in the whole system and Fixed to new coding standard. + % Any filtering was removed from this routine + % Filtering and any other signal processing should be done in + % a singal treatment routine +% 2011-08-04 / Max Ortiz / The 10% of extra indication for the user + % to contract was removed. +% 2012-02-xx / Max Ortiz / Upgrade DAQ routines for MATLAB R2011b, SBI + % Old version was kept as: + % RecordinSession_Legacy +% 2012-03-27 / Max Ortiz / Bug fixed when an arbitrary selection of channels + % However, the NI doesn't allow to skip channels +% 2012-04-30 / Max Ortiz / The possibility of simultaneous recordings was + % was removed since it didn't worked with the SBI + % in the current implementation. To see how the + % simultaneus recordings were done, see + % RecordingSession_Legacy +% 2012-12-07 / Nichlas Sander / Added VRE as an option during training. + % Movements to display are loaded in + % varargin{8}. This since previous movements + % were simply loaded as strings. +% 2013-03-07 / Nichlas Sander / When training Arm Flex/Extend the system + % will automatically change the view so the + % user can see the movement. +% 2013-08-23 / Morten Kristoffersen / Updated the recording sessions to support + % the new GUI_AFESelection structure +% 2014-11-10 / Enzo Mastinu / include routines for ADS1299 AFE recordings using + % the "afeSettings.name" property to differentiate them, + % add the ramp routines, set the time window + % size to be samplingTime/100, delete the + % peeking time field in the GUI, RMS mean is done + % "manually" for Matlab compatibility + % reasons +% 2015-01-12 / Enzo Mastinu / Divided the RecordingSession function into + % several functions: ConnectDevice(), + % SetDeviceStartAcquisition(), + % Acquire_tWs(), StopAcquisition(). + % These functions has been moved into COMM/AFE + % folder in separate files. All the parameters + % pass and global variables has been optimized + % due to the new functions. Now this file is + % totally independent from the inner working of + % the all devices. In this way, to introduce a + % new device for acquisition you need to modify + % the files in COMM folder, leaving the recording + % session file almost inalterate. +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment, for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offline data process as feature extraction or filter etc. + +% 20xx-xx-xx / Author / Comment + + + +function [cdata, sF] = RecordingSession(varargin) + + global handles; + global allData; + global timeStamps; + global samplesCounter; + allData = []; + nM = varargin{1}; + nR = varargin{2}; + cT = varargin{3}; + rT = varargin{4}; + mov = varargin{5}; + handles = varargin{6}; + afeSettings = varargin{7}; + trainWithVr = varargin{8}; + vreMovements = varargin{9}; + vreLeftHand = varargin{10}; + rampStatus = varargin{11}; + + % Get required informations from afeSettings structure + nCh = afeSettings.channels; + sF = afeSettings.sampleRate; + deviceName = afeSettings.name; + ComPortType = afeSettings.ComPortType; + if strcmp(ComPortType, 'COM') + ComPortName = afeSettings.ComPortName; + end + + % Save back acquisition parameters to the handles + handles.nR = nR; + handles.cT = cT; + handles.rT = rT; + handles.nCh = nCh; + handles.sF = sF; + handles.ComPortType = ComPortType; + if strcmp(ComPortType, 'COM') + handles.ComPortName = ComPortName; + end + handles.deviceName = deviceName; + handles.rampStatus = rampStatus; + handles.fast = 0; + + % Initialization of sampling time + sTall = (cT+rT)*nR; + sT = cT+rT; + handles.sTall = sTall; + handles.sT = sT; + + % Setting for data peeking + tW = sT/100; % Time window size + tWs = tW*sF; % Time window samples + handles.tWs = tWs; + timeStamps = 0:1/sF:tW-1/sF; % Create vector of time + + + %% Initialize GUI.. + + % Initialization of the VRE for training if required + if trainWithVr + % Parameters for the movement in the VRE + distance = 60; + numJumps = 30; + % Open and connect to the VRE + open('Virtual Reality.exe'); + handles.vreCommunication = tcpip('127.0.0.1',23068,'NetworkRole','server'); + fopen(handles.vreCommunication); + + %Set up VRE to not return any data. This will speed up the + %communication. + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(7),char(0),char(0),char(0))); + + % Send value to show Arm if that value is chosen. + sent = 0; + for i = 1:nM + for j = 1:length(vreMovements{i}) + movement = vreMovements{i}{j}; + if ismember(movement.id,[20 21]) && sent == 0 + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(6),char(1),char(0),char(0))); + sent = 1; + end + end + end + + if vreLeftHand + fwrite(handles.vreCommunication,sprintf('%c%c%c%c%c','c',char(5),char(1),char(0),char(0))); + end + end + + pause on; + + % Offset the data on plots + ampPP = 5; + ymin = -ampPP*2/3; + ymax = ampPP * nCh - ampPP*1/3; + sData = zeros(tWs,nCh); + fData = zeros(tWs,nCh); + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + for i = 1 : nCh + sData(:,i) = sData(:,i) + offVector(i); + fData(:,i) = fData(:,i) + offVector(i); + end + + if rampStatus + rampParams = varargin{12}; + % make the ramp objects visible + set(handles.a_effortPlot,'Visible','on'); + set(handles.txt_effortPlot,'Visible','on'); + % Init the effort tracking plot and draw the guide line + p_effortPlot = plot(handles.a_effortPlot,linspace(0,cT,sF*cT),linspace(0,100,sF*cT),'LineWidth',2); + ylim(handles.a_effortPlot, [0 100]); + xlim(handles.a_effortPlot, [0 cT]); + handles.p_effortPlot = p_effortPlot; + axes(handles.a_effortPlot) + hLine = line('XData', 0, 'YData', 0, 'Color', 'r', 'Marker', 'o', 'MarkerSize', 8, 'LineWidth', 2); + handles.hLine = hLine; + end + + % Initialization of progress bar + xpatch = [0 0 0 0]; + ypatch = [0 0 1 1]; + axes(handles.a_prog); + handles.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); + + % Allocation of resource to improve speed, total data + recSessionData = zeros(sF*sTall, nCh, nM); + + + %% Starting Session.. + + % Warning to the user + set(handles.t_msg,'String','Get ready to start: 3'); + pause(1); + set(handles.t_msg,'String','Get ready to start: 2'); + pause(1); + set(handles.t_msg,'String','Get ready to start: 1'); + pause(1); + relax = importdata('Img/relax.jpg'); % Import Image + drawnow; + + % Run all movements or exercise + for ex = 1 : nM + + timeStamps = 0:1/sF:tW-1/sF; % Timestamps used the time vector + currentTv = 1; % Current time vector + tV = timeStamps(currentTv):1/sF:(tW-1/sF)+timeStamps(currentTv); % Time vector used for drawing graphics + currentTv = currentTv - 1 + tWs; % Updated everytime tV is updated + acquireEvent.TimeStamps = tV'; + + if rampStatus == 1 + % Update ramp params for this exercise + handles.RampMin = rampParams{1}; + handles.currentRampMax = rampParams{2}(ex); + end + + disp(['Start ex: ' num2str(ex) ]) + + % Warning to the user + fileName = ['Img/' char(mov(ex)) '.jpg']; + if ~exist(fileName,'file') + fileName = 'Img/relax.jpg'; + end + + movI = importdata(fileName); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + + % Show warning to prepare + set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 3 s']); + pause(1); + set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 2 s']); + pause(1); + set(handles.t_msg,'String',['Get ready for ' mov(ex) ' in 1 s']); + pause(1); + + % Dummy Contraction + set(handles.t_msg,'String',mov(ex)); + if afeSettings.prepare + if trainWithVr + numberOfMovements = length(vreMovements{ex}); + tempJumps = numJumps/numberOfMovements; + tempDistance = round(distance/tempJumps); + vreString = ''; + for i = 1:numberOfMovements + movement = vreMovements{ex}{i}; + vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); + end + for j = 1:tempJumps + fwrite(handles.vreCommunication,vreString); + end + end + + pause(cT); + set(handles.t_msg,'String','Relax'); + if trainWithVr + fwrite(handles.vreCommunication,sprintf(sprintf('%c%c%c%c%c','r',char(1),char(1),char(1),char(1)))); + end + pic = image(relax,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + pause(rT); + end + + % Draw figure + p_t0 = plot(handles.a_t0, timeStamps, sData); + handles.p_t0 = p_t0; + xlim(handles.a_t0, [0,tW]); + ylim(handles.a_t0, [ymin ymax]); + set(handles.a_t0,'YTick',offVector); + set(handles.a_t0,'YTickLabel',0:nCh-1); + p_f0 = plot(handles.a_f0, timeStamps, fData); + handles.p_f0 = p_f0; + xlim(handles.a_f0, [0,sF/2]); + ylim(handles.a_f0, [ymin ymax]); + set(handles.a_f0,'YTick',offVector); + set(handles.a_f0,'YTickLabel',0:nCh-1); + + % Repetitions + %%%%% NI DAQ card %%%%% + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sTall,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @RecordingSession_ShowData); + + % Start DAQ + cData = zeros(sF*sTall, nCh, nM); + s.startBackground(); % Run in the backgroud + + for rep = 1 : nR + handles.rep = rep; + % Contraction + set(handles.t_msg,'String',mov(ex)); + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + handles.contraction = 1; + startContractionTic = tic; + if trainWithVr + numberOfMovements = length(vreMovements{ex}); + tempJumps = numJumps/numberOfMovements; + tempDistance = round(distance/tempJumps); + vreString = ''; + for i = 1:numberOfMovements + movement = vreMovements{ex}{i}; + vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); + end + for j = 1:tempJumps + fwrite(handles.vreCommunication,vreString); + end + end + pause(cT - toc(startContractionTic)); + % Relax + set(handles.t_msg,'String','Relax'); + startRelaxingTic = tic; + if trainWithVr + for i = 1:numJumps + fwrite(handles.vreCommunication,sprintf(sprintf('%c%c%c%c%c',char(1),char(14),char(1),char(distance/numJumps),char(1)))); + end + end + pic = image(relax,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + handles.contraction = 0; + pause(rT - toc(startRelaxingTic)); + end + + % Repetitions other devices + else + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + + for rep = 1 : nR + + rep + handles.rep = rep; + handles.contraction = 1; % 1 means contraction, 0 means relaxation + samplesCounter = 1; % variable used to track the progressing time of the recording session + UpdateGUI = 1; + cData = zeros(tWs, nCh); + + tic + for timeWindowNr = 1:sT/tW + + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + RecordingSession_ShowData(0, acquireEvent); % plot data and add cData to allData vector + + samplesCounter = samplesCounter + tWs; + switch handles.contraction + case 1 + % CONTRACTION + if (samplesCounter/sF) <= cT + % contraction time not expired yet + if UpdateGUI == 1 + % new contraction, the GUI must be updated + set(handles.t_msg,'String',mov(ex)); + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + drawnow; + if trainWithVr + numberOfMovements = length(vreMovements{ex}); + tempJumps = numJumps/numberOfMovements; + tempDistance = round(distance/tempJumps); + vreString = ''; + for i = 1:numberOfMovements + movement = vreMovements{ex}{i}; + vreString = sprintf('%s%c%c%c%c%c',vreString,char(1),char(movement.idVRE),char(movement.vreDir),char(tempDistance),char(1)); + end + for j = 1:tempJumps + fwrite(handles.vreCommunication,vreString); + end + end + UpdateGUI = 0; + end + else + % contraction time expired + handles.contraction = 0; % 1 means contraction, 0 means relaxation + UpdateGUI = 1; + samplesCounter = 1; + end + case 0 + % RELAXATION + if (samplesCounter/sF) <= rT + % relaxation time not expired yet + if UpdateGUI == 1 + % new relaxation, the GUI must be updated + set(handles.t_msg,'String','Relax'); + pic = image(relax,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + drawnow; + if trainWithVr + for i = 1:numJumps + fwrite(handles.vreCommunication,sprintf(sprintf('%c%c%c%c%c',char(1),char(14),char(1),char(distance/numJumps),char(1)))); + end + end + UpdateGUI = 0; + end + else + % relaxation time expired + handles.contraction = 1; % 1 means contraction, 0 means relaxation + if rep ~= nR + UpdateGUI = 1; + end + samplesCounter = 1; + end + otherwise + set(handles.t_msg,'String','Error with the Contraction-Relaxation switch statement'); + end + end + toc + end + + % Stop acquisition + StopAcquisition(deviceName, obj); + end + + % NI DAQ card: "You must delete the listener once the operation is complete" + if strcmp(ComPortType,'NI'); + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + end + + % Save Data + recSessionData(:,:,ex) = allData(:,:); + % Plot movement just recorded + DataShow(handles, allData, sF, sTall); + % Clean global data for next movement + allData = []; + + end + + + %% Session finish.. + + % Save data into cdata output matrix + cdata = recSessionData(:,:,:); + + set(handles.t_msg,'String','Session Terminated'); % Show message about acquisition completed + fileName = 'Img/Agree.jpg'; + movI = importdata(fileName); % Import Image + set(handles.a_pic,'Visible','on'); % Turn on visibility + pic = image(movI,'Parent',handles.a_pic); % set image + axis(handles.a_pic,'off'); % Remove axis tick marks + + % Save Session to file + recSession.sF = sF; + recSession.sT = sTall; + recSession.cT = cT; + recSession.rT = rT; + recSession.nM = nM; + recSession.nR = nR; + recSession.nCh = nCh; + recSession.dev = deviceName; + recSession.comm = ComPortType; + if strcmp(ComPortType, 'COM') + recSession.comn = ComPortName; + end + recSession.mov = mov; + recSession.date = fix(clock); + recSession.cmt = inputdlg('Additional comment on the recording session','Comments'); + if rampStatus + recSession.ramp.rampMin = rampParams{1}; % Save the ramp parameters to the file + recSession.ramp.rampMax = rampParams{2}; + recSession.ramp.minData = rampParams{3}; + recSession.ramp.maxData = rampParams{4}; + end + + [filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); + if isequal(filename,0) || isequal(pathname,0) + disp('User pressed cancel') + else + disp(['User selected ', fullfile(pathname, filename)]) + recSession.tdata = recSessionData; + save([pathname,filename],'recSession'); + end + disp(recSession); + + if trainWithVr + fclose(handles.vreCommunication); + end + + % Turn OFF visibility + set(handles.a_prog,'visible','off'); + if(rampStatus) + set(handles.a_effortPlot,'visible','off'); + set(handles.txt_effortPlot,'visible','off'); + set(p_effortPlot,'visible','off'); + set(handles.hLine,'visible','off'); + end + set(handles.hPatch,'Xdata',[0 0 0 0]); + + % Set visible the offline plot and process panels + set(handles.uipanel9,'Visible','on'); + set(handles.uipanel7,'Visible','on'); + set(handles.uipanel8,'Visible','on'); + set(handles.txt_it,'visible','on'); + set(handles.txt_ft,'visible','on'); + set(handles.et_it,'visible','on'); + set(handles.et_ft,'visible','on'); + set(handles.txt_if,'visible','on'); + set(handles.txt_ff,'visible','on'); + set(handles.et_if,'visible','on'); + set(handles.et_ff,'visible','on'); + + chVector = 0:nCh-1; + set(handles.lb_channels, 'String', chVector); + +end diff --git a/SigRecordings/RecordingSession_Legacy.m b/SigRecordings/RecordingSession_Legacy.m index f03988e..0eaf3b0 100644 --- a/SigRecordings/RecordingSession_Legacy.m +++ b/SigRecordings/RecordingSession_Legacy.m @@ -1,657 +1,657 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to Record Exc Sessions -% Input : -% Fs = Sampling frequenicy -% nM = number of excersices or movements -% nR = number of excersice repetition -% cT = time that the contractions should last -% rT = relaxing time -% cTp = Porcentage of the signal to record -% mov = message to be send to the user -% hGUI_Rec= handles of the axes to plot -% Output = total data and data of interest -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-17 / Max Ortiz / Creation -% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording -% 2011-06 / Per and Gustav / added the analog front end sections -% 2011-06-29 / Max ORtiz / Optimization to be integrated in the whole system and Fixed to new coding standard. - % Any filgering was removed from this routine - % Filtering and any other signal processing should be done in - % a singal treatment routine -% 2011-08-04 / Max Ortiz / % The 10% of extra indication for the user to contract was - % removed. - - - -function [cdata, sF] = RecordingSession_Legacy(varargin) - -nM = varargin{1}; -nR = varargin{2}; -cT = varargin{3}; -rT = varargin{4}; -mov = varargin{5}; -hGUI_Rec = varargin{6}; -afeSettings = varargin{7}; - -% Get number of channels -if afeSettings.NI.show - nCh = afeSettings.NI.channels; - sF = afeSettings.NI.sampleRate; -elseif afeSettings.ADS.show - nCh = afeSettings.ADS.channels; - sF = afeSettings.ADS.sampleRate; -elseif afeSettings.RHA.show - nCh = afeSettings.RHA.channels; - sF = afeSettings.RHA.sampleRate; -end - -%% Initialize plots -% Create handles for the plots -% this is faster than creating the plot everytime -tt = 0:1/sF:cT/100-1/sF; -ymin = -3; -ymax = 3; - - -if nCh >= 1 - %axes(hGUI_Rec.a_t0); - p_t0 = plot(hGUI_Rec.a_t0,tt,tt); - ylim(hGUI_Rec.a_t0, [ymin ymax]); - %axes(hGUI_Rec.a_f0); - p_f0 = plot(hGUI_Rec.a_f0,1,1); -end -if nCh >= 2 - p_t1 = plot(hGUI_Rec.a_t1,tt,tt); - ylim(hGUI_Rec.a_t1, [ymin ymax]); - p_f1 = plot(hGUI_Rec.a_f1,1,1); -end -if nCh >= 3 - p_t2 = plot(hGUI_Rec.a_t2,tt,tt); - ylim(hGUI_Rec.a_t2, [ymin ymax]); - p_f2 = plot(hGUI_Rec.a_f2,1,1); -end - -if nCh >= 4 - p_t3 = plot(hGUI_Rec.a_t3,tt,tt); - ylim(hGUI_Rec.a_t3, [ymin ymax]); - p_f3 = plot(hGUI_Rec.a_f3,1,1); -end - -if nCh >= 5 - p_t4 = plot(hGUI_Rec.a_t4,tt,tt); - ylim(hGUI_Rec.a_t4, [ymin ymax]); - %axes(hGUI_Rec.a_f4); - %p_f4 = plot(1,1); -end - -if nCh >= 6 - p_t5 = plot(hGUI_Rec.a_t5,tt,tt); - ylim(hGUI_Rec.a_t5, [ymin ymax]); - %axes(hGUI_Rec.a_f5); - %p_f5 = plot(1,1); -end - -if nCh >= 7 - p_t6 = plot(hGUI_Rec.a_t6,tt,tt); - ylim(hGUI_Rec.a_t6, [ymin ymax]); - %axes(hGUI_Rec.a_f6); - %p_f6 = plot(1,1); -end - -if nCh >= 8 - p_t7 = plot(hGUI_Rec.a_t7,tt,tt); - ylim(hGUI_Rec.a_t7, [ymin ymax]); - %axes(hGUI_Rec.a_f7); - %p_f7 = plot(1,1); -end - - -%% -% Initialize DAQ card -sT = (cT+rT)*nR; % Sampling time, it is the time of contraction + - % Time of relaxation x Number of repetitions - - -if afeSettings.NI.active - %afeSettings.NI.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - % instruction from Per and Gustav, why - % would you overwrite the selected sF? - - % All following sF needs to be changed to - % invidual sF in order to make it work - % /Per - ai = Init_NI_AI(hGUI_Rec,afeSettings.NI.sampleRate,sT,nCh); - dev = afeSettings.NI.name; -end -if afeSettings.ADS.active - Amp=12; - Vref=2.4*2; %*2 is from bipolar reference - ByteDepth=3; - afeSettings.ADS.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - dataFormat=2; - ADS = AFE_PICCOLO(afeSettings.ADS.ComPortType,afeSettings.ADS.sampleRate, ... - sT,nCh,Amp,Vref,dataFormat,afeSettings.ADS.name,ByteDepth); -end -if afeSettings.RHA.active - Amp=200; - Vref=2.5; - ByteDepth=2; - afeSettings.RHA.sampleRate=sF; %overrides the individual samplerate choise in AFS_select - dataFormat=1; - RHA = AFE_PICCOLO(afeSettings.RHA.ComPortType,afeSettings.RHA.sampleRate, ... - sT,nCh,Amp,Vref,dataFormat,afeSettings.RHA.name,ByteDepth); -end - -%% Initialization of progress bar -xpatch = [0 0 0 0]; -ypatch = [0 0 1 1]; -%set(hGUI_Rec.figure1,'CurrentAxes',hGUI_Rec.a_prog); -axes(hGUI_Rec.a_prog); -hGUI_Rec.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); - -xpatch = [1 1 0 0]; -ypatch = [0 0 0 0]; -axes(hGUI_Rec.a_effort0); -hGUI_Rec.hPatch0 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort1); -hGUI_Rec.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort1); -hGUI_Rec.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort2); -hGUI_Rec.hPatch2 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort3); -hGUI_Rec.hPatch3 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort4); -hGUI_Rec.hPatch4 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort5); -hGUI_Rec.hPatch5 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort6); -hGUI_Rec.hPatch6 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -axes(hGUI_Rec.a_effort7); -hGUI_Rec.hPatch7 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); -effortMax = 2; - -%% -% Allocation of resource to improve speed, total data - % Identified problem if the different devices have different sF - % then different amount of data is comming from the differnt devices - % also problem in the counting of incoming data, needs to be changed so it - % expects right amount of data /Per -tdata = zeros(sF*sT,nCh,nM); -ADStdata = zeros(sF*sT,nCh,nM); -RHAtdata = zeros(sF*sT,nCh,nM); - -% Warning to the user -if afeSettings.prepare - set(hGUI_Rec.t_msg,'String','Get ready to start: 3'); - pause(1); - set(hGUI_Rec.t_msg,'String','Get ready to start: 2'); - pause(1); - set(hGUI_Rec.t_msg,'String','Get ready to start: 1'); - pause(1); -end -relax = importdata('Img/relax.jpg'); % Import Image - - -for ex = 1 : nM - disp(['Start ex: ' num2str(ex) ]) - - % Warning to the user - fileName = ['Img/' char(mov(ex)) '.jpg']; - if ~exist(fileName,'file') - fileName = 'Img/relax.jpg'; - end - - %movI = importdata(['Img/mov' num2str(ex) '.jpg']); % Import Image - movI = importdata(fileName); % Import Image - set(hGUI_Rec.a_pic,'Visible','on'); % Turn on visibility - %axes(hGUI_Rec.a_pic); % get hGUI_Rec - pic = image(movI,'Parent',hGUI_Rec.a_pic); % set image - axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks - - if afeSettings.prepare - set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 3 s']); - pause(1); - set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 2 s']); - pause(1); - set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 1 s']); - %set(hGUI_Rec.a_pic,'Visible','off'); % Turn OFF visibility - %delete(pic); % Delete image - pause(1); - end - - %% Dummy Contraction - set(hGUI_Rec.t_msg,'String',mov(ex)); - if afeSettings.prepare - pause(cT); - set(hGUI_Rec.t_msg,'String','Relax'); - pic = image(relax,'Parent',hGUI_Rec.a_pic); % set image - axis off; % Remove axis tick marks - pause(rT); - end - - - %% Start DAQ - if afeSettings.NI.active - start(ai); - end - if afeSettings.ADS.active - ADS.startRecording - end - if afeSettings.RHA.active - RHA.startRecording - end - - - for rep = 1 : nR - - while afeSettings.NI.active && afeSettings.NI.show && (ai.SamplesAcquired < (cT+rT)*sF*rep) || ... - afeSettings.ADS.active && afeSettings.ADS.show && (ADS.SamplesAcquired < (cT+rT)*sF*rep*nCh) || ... - afeSettings.RHA.active && afeSettings.RHA.show && (RHA.SamplesAcquired < (cT+rT)*sF*rep*nCh) - - %sF in both condition needs to be changed to the invidual samplings - %frequencies of the different devices - - %Instructions to the user - if afeSettings.NI.active && afeSettings.NI.show && (ai.SamplesAcquired <= sF*cT*rep + sF*rT*(rep-1)) || ... - afeSettings.ADS.active && afeSettings.ADS.show && (ADS.SamplesAcquired <= (sF*cT*rep + sF*rT*(rep-1)) * nCh) || ... - afeSettings.RHA.active && afeSettings.RHA.show && (RHA.SamplesAcquired <= (sF*cT*rep + sF*rT*(rep-1)) * nCh) - - set(hGUI_Rec.t_msg,'String',mov(ex)); - %axes(hGUI_Rec.a_pic); - pic = image(movI,'Parent',hGUI_Rec.a_pic); % set image - axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks - - % Status bar update - lastToc = sF*cT; - thisToc = ai.SamplesAcquired - (sF*cT*(rep-1)) - sF*rT*(rep-1); - else - set(hGUI_Rec.t_msg,'String','Relax'); - pic = image(relax,'Parent',hGUI_Rec.a_pic); % set image - axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks - - % Status bar update - lastToc = sF*rT; - thisToc = ai.SamplesAcquired - (sF*cT*rep) - sF*rT*(rep-1); - - end - % Status bar update - x =1-(thisToc/lastToc); - set(hGUI_Rec.figure1,'CurrentAxes',hGUI_Rec.a_prog); - set(hGUI_Rec.hPatch,'Xdata',[0 x x 0]); - drawnow; - - %--------------------------------- - if afeSettings.NI.show - data = peekdata(ai,cT*sF/100); - %data=data/1700; %Converting to input referred voltage - elseif afeSettings.ADS.show - data = ADS.storeFromBuffer; - - ADS.data = [ADS.data ; data]; - - if size(ADS.data,1) > (cT*sF/100) - data = (ADS.data(end-(cT*sF/100)+1:end,:) ).* (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8) )); %Converting to input referred voltage - else - data = zeros((cT*sF/100),nCh); - end - elseif afeSettings.RHA.show - data = RHA.storeFromBuffer; - - RHA.data = [RHA.data ; data]; - if size(RHA.data,1) > (cT*sF/100) - data = (RHA.data(end-(cT*sF/100)+1:end,:) ).* (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); %Converting to input referred voltage - else - data = zeros((cT*sF/100),nCh); - end - end - - aNs = length(data(:,1)); - NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples - f = sF/2*linspace(0,1,NFFT/2); - dataf = fft(data(1:aNs,:),NFFT)/aNs; - m = 2*abs(dataf((1:NFFT/2),:)); - - - chi = 1;%Channel Index for map data - if nCh >= 1 - set(p_t0,'YData',data(:,chi)); - set(p_f0,'XData',f); - set(p_f0,'YData',m(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch0,'Ydata',[0 x x 0]); - - chi=chi+1; - end - if nCh >= 2 - set(p_t1,'YData',data(:,chi)); - set(p_f1,'XData',f); - set(p_f1,'YData',m(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch1,'Ydata',[0 x x 0]); - - chi=chi+1; - end - if nCh >= 3 - set(p_t2,'YData',data(:,chi)); - set(p_f2,'XData',f); - set(p_f2,'YData',m(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch2,'Ydata',[0 x x 0]); - - chi=chi+1; - end - if nCh >= 4 - set(p_t3,'YData',data(:,chi)); - set(p_f3,'XData',f); - set(p_f3,'YData',m(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch3,'Ydata',[0 x x 0]); - - chi=chi+1; - end - if nCh >= 5 - set(p_t4,'YData',data(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch4,'Ydata',[0 x x 0]); - - chi=chi+1; - %set(p_f4,'XData',f); - %set(p_f4,'YData',m(:,chi)); - end - if nCh >= 6 - set(p_t5,'YData',data(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch5,'Ydata',[0 x x 0]); - - chi=chi+1; - %set(p_f5,'XData',f); - %set(p_f5,'YData',m(:,chi)); - end - if nCh >= 7 - set(p_t6,'YData',data(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch6,'Ydata',[0 x x 0]); - - chi=chi+1; - %set(p_f6,'XData',f); - %set(p_f6,'YData',m(:,chi)); - end - if nCh >= 8 - set(p_t7,'YData',data(:,chi)); - % Update effort bar - xT = mean(abs(data(:,chi))); - x = xT / effortMax; - set(hGUI_Rec.hPatch7,'Ydata',[0 x x 0]); - - %set(p_f7,'XData',f); - %set(p_f7,'YData',m(:,chi)); - end - - - %--------------------------------- - end - - end - - %Check if all data has arrived from the other devices - while (afeSettings.NI.active && (ai.SamplesAcquired < (cT+rT)*sF*nR)) || ... - (afeSettings.ADS.active && (ADS.SamplesAcquired < (cT+rT)*sF*nR*nCh)) || ... - (afeSettings.RHA.active && (RHA.SamplesAcquired < (cT+rT)*sF*nR*nCh)) - - pause(1) - disp('Waiting for more data') - if afeSettings.NI.active - disp('NI') - disp((cT+rT)*sF*nR-ai.SamplesAcquired) - disp([ai.SamplesAcquired ai.SamplesAcquired*4]) - end - if afeSettings.RHA.active - disp('RHA') - disp((cT+rT)*sF*nR*nCh-RHA.SamplesAcquired) - disp(RHA.SamplesAcquired) - end - if afeSettings.ADS.active - disp('ADS') - disp((cT+rT)*sF*nR*nCh-ADS.SamplesAcquired) - disp(ADS.SamplesAcquired) - disp((cT+rT)*sF*nR*nCh) - end - end - - % Save Data - if afeSettings.NI.active -% disp('NI:') -% ai.SamplesAcquired - wait(ai,sT+1); - [data,tt,abstime] = getdata(ai); -% disp(['date = ' num2str(fix(abstime))]) -% size(data) -% size(tdata) - tdata(:,:,ex) = data; % / 1.70e3; %Converting to input referred voltage - end - if afeSettings.RHA.active -% disp('RHA:') -% disp(RHA.SamplesAcquired) -% disp(RHA.bytesAcquired) -% disp(size(RHA.data)) - data = [RHA.data ; RHA.storeFromBuffer]; -% disp(size(data)) -% disp(size(RHAtdata)) - RHAtdata(:,:,ex)=data * (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); %Converting to input referred voltage - end - - if afeSettings.ADS.active -% disp('ADS:') -% disp(ADS.SamplesAcquired) -% disp(ADS.bytesAcquired) -% disp(size(data)) - - data = [ADS.data ; ADS.storeFromBuffer]; -% disp(size(data)) -% disp(size(ADStdata)) - ADStdata(:,:,ex)=data * (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); %Converting to input referred voltage - end - - -end -set(hGUI_Rec.t_msg,'String','Session Terminated'); % Show message about acquisition - -%% Save data and compute training data using cTp -if afeSettings.NI.active - stop(ai); - delete(ai); - NItdata=tdata; - %NItrdata=ComputeTrainingData(tdata,sF,cT,rT,nR,nM,cTp); -else - NItdata=[]; - %NItrdata=[]; -end - -if afeSettings.ADS.active - ADStdata=ADStdata; - %ADStrdata=ComputeTrainingData(ADStdata,sF,cT,rT,nR,nM,cTp); -else - ADStdata=[]; - %ADStrdata=[]; -end - -if afeSettings.RHA.active - RHAtdata=RHAtdata; - %RHAtrdata=ComputeTrainingData(RHAtdata,sF,cT,rT,nR,nM,cTp); -else - RHAtdata=[]; - %RHAtrdata=[]; -end - - -%% Save Session to file -% date = [];%fix(abstime); -recSession.sF = sF; -recSession.sT = sT; -recSession.cT = cT; -recSession.rT = rT; -%recSession.cTp = cTp; -recSession.nM = nM; -recSession.nR = nR; -recSession.nCh = nCh; -recSession.dev = dev; -recSession.mov = mov; -recSession.date = fix(clock); -recSession.cmt = inputdlg('Additional comment on the recording session','Comments'); - -[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); - if isequal(filename,0) || isequal(pathname,0) - disp('User pressed cancel') - else - disp(['User selected ', fullfile(pathname, filename)]) - if afeSettings.NI.active - recSession.tdata = NItdata; - %recSession.trdata = NItrdata; - if exist([pathname 'NI\'],'dir') == 0 - mkdir(pathname,'NI') - end - save([pathname, 'NI\',filename],'recSession'); - end - if afeSettings.ADS.active - recSession.tdata = ADStdata; - %recSession.trdata = ADStrdata; - %Possible to add string with device info for example recSession.device=afeSettings.ADS.name; - if exist([pathname 'ADS1298\'],'dir') == 0 - mkdir(pathname,'ADS1298') - end - save([pathname, 'ADS1298\',filename],'recSession'); - - % not needed here any more? -% if filters.PLH || filters.BP -% recSession.tdata = ADStdataFiltered; -% % recSession.trdata = ADStrdataFiltered; -% if exist([pathname 'ADS1298Filtered\'],'dir') == 0 -% mkdir(pathname,'ADS1298Filtered') -% end -% save([pathname,'ADS1298Filtered\',filename],'recSession'); -% end - end - if afeSettings.RHA.active - recSession.tdata = RHAtdata; - %recSession.trdata = RHAtrdata; - %Possible to add string with device info for example recSession.device=afeSettings.RHA.name; - if exist([pathname 'RHA2216\'],'dir') == 0 - mkdir(pathname,'RHA2216') - end - save([pathname 'RHA2216\',filename],'recSession'); - - % not needed here any more? -% if filters.PLH || filters.BP -% recSession.tdata = RHAtdataFiltered; -% %recSession.trdata = RHAtrdataFiltered; -% if exist([pathname 'RHA2216Filtered\'],'dir') == 0 -% mkdir(pathname,'RHA2216Filtered') -% end -% save([pathname,'RHA2216Filtered\',filename],'recSession'); -% end - end -end - -% Copy acquired data from the last excersice into cdata -% Display it -disp(recSession); - -if afeSettings.NI.show - data = NItdata(:,:,end); -elseif afeSettings.ADS.show - data = ADStdata(:,:,end).* (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); -elseif afeSettings.RHA.show - data = RHAtdata(:,:,end).* (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); -end - -chi=1; -if nCh >= 1 - cdata(:,1) = data(:,chi); - chi=chi+1; -end -if nCh >= 2 - cdata(:,2) = data(:,chi); - chi=chi+1; -end -if nCh >= 3 - cdata(:,3) = data(:,chi); - chi=chi+1; -end -if nCh >= 4 - cdata(:,4) = data(:,chi); - chi=chi+1; -end -if nCh >= 5 - cdata(:,5) = data(:,chi); - chi=chi+1; -end -if nCh >= 6 - cdata(:,6) = data(:,chi); - chi=chi+1; -end -if nCh >= 7 - cdata(:,7) = data(:,chi); - chi=chi+1; -end -if nCh >= 8 - cdata(:,8) = data(:,chi); -end - - -data_show(hGUI_Rec,cdata,sF,sT); -set(hGUI_Rec.a_pic,'Visible','off'); % Turn OFF visibility -delete(pic); % Delete image -end - -% function trdata = ComputeTrainingData(tdata,sF,cT,rT,nR,nM,cTp) -% %Compute Traning Data -% -% for ex = 1 : nM -% tempdata =[]; -% for rep = 1 : nR -% % Samples of the exersice to be consider for training -% % (sF*cT*cTp) Number of the samples that wont be consider for training -% % (sF*cT*rep) Number of samples that takes a contraction -% % (sF*rT*rep) Number of samples that takes a relaxation -% is = (sF*cT*cTp) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)) + 1; -% fs = (sF*cT) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)); -% tempdata = [tempdata ; tdata(is:fs,:,ex)]; -% end -% trdata(:,:,ex) = tempdata; -% end -% +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to Record Exc Sessions +% Input : +% Fs = Sampling frequenicy +% nM = number of excersices or movements +% nR = number of excersice repetition +% cT = time that the contractions should last +% rT = relaxing time +% cTp = Porcentage of the signal to record +% mov = message to be send to the user +% hGUI_Rec= handles of the axes to plot +% Output = total data and data of interest +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-17 / Max Ortiz / Creation +% 2009-06-29 / Max Ortiz / A dummy repeticion added before start recording +% 2011-06 / Per and Gustav / added the analog front end sections +% 2011-06-29 / Max ORtiz / Optimization to be integrated in the whole system and Fixed to new coding standard. + % Any filgering was removed from this routine + % Filtering and any other signal processing should be done in + % a singal treatment routine +% 2011-08-04 / Max Ortiz / % The 10% of extra indication for the user to contract was + % removed. + + + +function [cdata, sF] = RecordingSession_Legacy(varargin) + +nM = varargin{1}; +nR = varargin{2}; +cT = varargin{3}; +rT = varargin{4}; +mov = varargin{5}; +hGUI_Rec = varargin{6}; +afeSettings = varargin{7}; + +% Get number of channels +if afeSettings.NI.show + nCh = afeSettings.NI.channels; + sF = afeSettings.NI.sampleRate; +elseif afeSettings.ADS.show + nCh = afeSettings.ADS.channels; + sF = afeSettings.ADS.sampleRate; +elseif afeSettings.RHA.show + nCh = afeSettings.RHA.channels; + sF = afeSettings.RHA.sampleRate; +end + +%% Initialize plots +% Create handles for the plots +% this is faster than creating the plot everytime +tt = 0:1/sF:cT/100-1/sF; +ymin = -3; +ymax = 3; + + +if nCh >= 1 + %axes(hGUI_Rec.a_t0); + p_t0 = plot(hGUI_Rec.a_t0,tt,tt); + ylim(hGUI_Rec.a_t0, [ymin ymax]); + %axes(hGUI_Rec.a_f0); + p_f0 = plot(hGUI_Rec.a_f0,1,1); +end +if nCh >= 2 + p_t1 = plot(hGUI_Rec.a_t1,tt,tt); + ylim(hGUI_Rec.a_t1, [ymin ymax]); + p_f1 = plot(hGUI_Rec.a_f1,1,1); +end +if nCh >= 3 + p_t2 = plot(hGUI_Rec.a_t2,tt,tt); + ylim(hGUI_Rec.a_t2, [ymin ymax]); + p_f2 = plot(hGUI_Rec.a_f2,1,1); +end + +if nCh >= 4 + p_t3 = plot(hGUI_Rec.a_t3,tt,tt); + ylim(hGUI_Rec.a_t3, [ymin ymax]); + p_f3 = plot(hGUI_Rec.a_f3,1,1); +end + +if nCh >= 5 + p_t4 = plot(hGUI_Rec.a_t4,tt,tt); + ylim(hGUI_Rec.a_t4, [ymin ymax]); + %axes(hGUI_Rec.a_f4); + %p_f4 = plot(1,1); +end + +if nCh >= 6 + p_t5 = plot(hGUI_Rec.a_t5,tt,tt); + ylim(hGUI_Rec.a_t5, [ymin ymax]); + %axes(hGUI_Rec.a_f5); + %p_f5 = plot(1,1); +end + +if nCh >= 7 + p_t6 = plot(hGUI_Rec.a_t6,tt,tt); + ylim(hGUI_Rec.a_t6, [ymin ymax]); + %axes(hGUI_Rec.a_f6); + %p_f6 = plot(1,1); +end + +if nCh >= 8 + p_t7 = plot(hGUI_Rec.a_t7,tt,tt); + ylim(hGUI_Rec.a_t7, [ymin ymax]); + %axes(hGUI_Rec.a_f7); + %p_f7 = plot(1,1); +end + + +%% +% Initialize DAQ card +sT = (cT+rT)*nR; % Sampling time, it is the time of contraction + + % Time of relaxation x Number of repetitions + + +if afeSettings.NI.active + %afeSettings.NI.sampleRate=sF; %overrides the individual samplerate choise in AFS_select + % instruction from Per and Gustav, why + % would you overwrite the selected sF? + + % All following sF needs to be changed to + % invidual sF in order to make it work + % /Per + ai = Init_NI_AI(hGUI_Rec,afeSettings.NI.sampleRate,sT,nCh); + dev = afeSettings.NI.name; +end +if afeSettings.ADS.active + Amp=12; + Vref=2.4*2; %*2 is from bipolar reference + ByteDepth=3; + afeSettings.ADS.sampleRate=sF; %overrides the individual samplerate choise in AFS_select + dataFormat=2; + ADS = AFE_PICCOLO(afeSettings.ADS.ComPortType,afeSettings.ADS.sampleRate, ... + sT,nCh,Amp,Vref,dataFormat,afeSettings.ADS.name,ByteDepth); +end +if afeSettings.RHA.active + Amp=200; + Vref=2.5; + ByteDepth=2; + afeSettings.RHA.sampleRate=sF; %overrides the individual samplerate choise in AFS_select + dataFormat=1; + RHA = AFE_PICCOLO(afeSettings.RHA.ComPortType,afeSettings.RHA.sampleRate, ... + sT,nCh,Amp,Vref,dataFormat,afeSettings.RHA.name,ByteDepth); +end + +%% Initialization of progress bar +xpatch = [0 0 0 0]; +ypatch = [0 0 1 1]; +%set(hGUI_Rec.figure1,'CurrentAxes',hGUI_Rec.a_prog); +axes(hGUI_Rec.a_prog); +hGUI_Rec.hPatch = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); + +xpatch = [1 1 0 0]; +ypatch = [0 0 0 0]; +axes(hGUI_Rec.a_effort0); +hGUI_Rec.hPatch0 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort1); +hGUI_Rec.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort1); +hGUI_Rec.hPatch1 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort2); +hGUI_Rec.hPatch2 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort3); +hGUI_Rec.hPatch3 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort4); +hGUI_Rec.hPatch4 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort5); +hGUI_Rec.hPatch5 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort6); +hGUI_Rec.hPatch6 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +axes(hGUI_Rec.a_effort7); +hGUI_Rec.hPatch7 = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','xor','visible','on'); +effortMax = 2; + +%% +% Allocation of resource to improve speed, total data + % Identified problem if the different devices have different sF + % then different amount of data is comming from the differnt devices + % also problem in the counting of incoming data, needs to be changed so it + % expects right amount of data /Per +tdata = zeros(sF*sT,nCh,nM); +ADStdata = zeros(sF*sT,nCh,nM); +RHAtdata = zeros(sF*sT,nCh,nM); + +% Warning to the user +if afeSettings.prepare + set(hGUI_Rec.t_msg,'String','Get ready to start: 3'); + pause(1); + set(hGUI_Rec.t_msg,'String','Get ready to start: 2'); + pause(1); + set(hGUI_Rec.t_msg,'String','Get ready to start: 1'); + pause(1); +end +relax = importdata('Img/relax.jpg'); % Import Image + + +for ex = 1 : nM + disp(['Start ex: ' num2str(ex) ]) + + % Warning to the user + fileName = ['Img/' char(mov(ex)) '.jpg']; + if ~exist(fileName,'file') + fileName = 'Img/relax.jpg'; + end + + %movI = importdata(['Img/mov' num2str(ex) '.jpg']); % Import Image + movI = importdata(fileName); % Import Image + set(hGUI_Rec.a_pic,'Visible','on'); % Turn on visibility + %axes(hGUI_Rec.a_pic); % get hGUI_Rec + pic = image(movI,'Parent',hGUI_Rec.a_pic); % set image + axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks + + if afeSettings.prepare + set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 3 s']); + pause(1); + set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 2 s']); + pause(1); + set(hGUI_Rec.t_msg,'String',['Get ready for ' mov(ex) ' in 1 s']); + %set(hGUI_Rec.a_pic,'Visible','off'); % Turn OFF visibility + %delete(pic); % Delete image + pause(1); + end + + %% Dummy Contraction + set(hGUI_Rec.t_msg,'String',mov(ex)); + if afeSettings.prepare + pause(cT); + set(hGUI_Rec.t_msg,'String','Relax'); + pic = image(relax,'Parent',hGUI_Rec.a_pic); % set image + axis off; % Remove axis tick marks + pause(rT); + end + + + %% Start DAQ + if afeSettings.NI.active + start(ai); + end + if afeSettings.ADS.active + ADS.startRecording + end + if afeSettings.RHA.active + RHA.startRecording + end + + + for rep = 1 : nR + + while afeSettings.NI.active && afeSettings.NI.show && (ai.SamplesAcquired < (cT+rT)*sF*rep) || ... + afeSettings.ADS.active && afeSettings.ADS.show && (ADS.SamplesAcquired < (cT+rT)*sF*rep*nCh) || ... + afeSettings.RHA.active && afeSettings.RHA.show && (RHA.SamplesAcquired < (cT+rT)*sF*rep*nCh) + + %sF in both condition needs to be changed to the invidual samplings + %frequencies of the different devices + + %Instructions to the user + if afeSettings.NI.active && afeSettings.NI.show && (ai.SamplesAcquired <= sF*cT*rep + sF*rT*(rep-1)) || ... + afeSettings.ADS.active && afeSettings.ADS.show && (ADS.SamplesAcquired <= (sF*cT*rep + sF*rT*(rep-1)) * nCh) || ... + afeSettings.RHA.active && afeSettings.RHA.show && (RHA.SamplesAcquired <= (sF*cT*rep + sF*rT*(rep-1)) * nCh) + + set(hGUI_Rec.t_msg,'String',mov(ex)); + %axes(hGUI_Rec.a_pic); + pic = image(movI,'Parent',hGUI_Rec.a_pic); % set image + axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks + + % Status bar update + lastToc = sF*cT; + thisToc = ai.SamplesAcquired - (sF*cT*(rep-1)) - sF*rT*(rep-1); + else + set(hGUI_Rec.t_msg,'String','Relax'); + pic = image(relax,'Parent',hGUI_Rec.a_pic); % set image + axis(hGUI_Rec.a_pic,'off'); % Remove axis tick marks + + % Status bar update + lastToc = sF*rT; + thisToc = ai.SamplesAcquired - (sF*cT*rep) - sF*rT*(rep-1); + + end + % Status bar update + x =1-(thisToc/lastToc); + set(hGUI_Rec.figure1,'CurrentAxes',hGUI_Rec.a_prog); + set(hGUI_Rec.hPatch,'Xdata',[0 x x 0]); + drawnow; + + %--------------------------------- + if afeSettings.NI.show + data = peekdata(ai,cT*sF/100); + %data=data/1700; %Converting to input referred voltage + elseif afeSettings.ADS.show + data = ADS.storeFromBuffer; + + ADS.data = [ADS.data ; data]; + + if size(ADS.data,1) > (cT*sF/100) + data = (ADS.data(end-(cT*sF/100)+1:end,:) ).* (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8) )); %Converting to input referred voltage + else + data = zeros((cT*sF/100),nCh); + end + elseif afeSettings.RHA.show + data = RHA.storeFromBuffer; + + RHA.data = [RHA.data ; data]; + if size(RHA.data,1) > (cT*sF/100) + data = (RHA.data(end-(cT*sF/100)+1:end,:) ).* (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); %Converting to input referred voltage + else + data = zeros((cT*sF/100),nCh); + end + end + + aNs = length(data(:,1)); + NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(data(1:aNs,:),NFFT)/aNs; + m = 2*abs(dataf((1:NFFT/2),:)); + + + chi = 1;%Channel Index for map data + if nCh >= 1 + set(p_t0,'YData',data(:,chi)); + set(p_f0,'XData',f); + set(p_f0,'YData',m(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch0,'Ydata',[0 x x 0]); + + chi=chi+1; + end + if nCh >= 2 + set(p_t1,'YData',data(:,chi)); + set(p_f1,'XData',f); + set(p_f1,'YData',m(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch1,'Ydata',[0 x x 0]); + + chi=chi+1; + end + if nCh >= 3 + set(p_t2,'YData',data(:,chi)); + set(p_f2,'XData',f); + set(p_f2,'YData',m(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch2,'Ydata',[0 x x 0]); + + chi=chi+1; + end + if nCh >= 4 + set(p_t3,'YData',data(:,chi)); + set(p_f3,'XData',f); + set(p_f3,'YData',m(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch3,'Ydata',[0 x x 0]); + + chi=chi+1; + end + if nCh >= 5 + set(p_t4,'YData',data(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch4,'Ydata',[0 x x 0]); + + chi=chi+1; + %set(p_f4,'XData',f); + %set(p_f4,'YData',m(:,chi)); + end + if nCh >= 6 + set(p_t5,'YData',data(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch5,'Ydata',[0 x x 0]); + + chi=chi+1; + %set(p_f5,'XData',f); + %set(p_f5,'YData',m(:,chi)); + end + if nCh >= 7 + set(p_t6,'YData',data(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch6,'Ydata',[0 x x 0]); + + chi=chi+1; + %set(p_f6,'XData',f); + %set(p_f6,'YData',m(:,chi)); + end + if nCh >= 8 + set(p_t7,'YData',data(:,chi)); + % Update effort bar + xT = mean(abs(data(:,chi))); + x = xT / effortMax; + set(hGUI_Rec.hPatch7,'Ydata',[0 x x 0]); + + %set(p_f7,'XData',f); + %set(p_f7,'YData',m(:,chi)); + end + + + %--------------------------------- + end + + end + + %Check if all data has arrived from the other devices + while (afeSettings.NI.active && (ai.SamplesAcquired < (cT+rT)*sF*nR)) || ... + (afeSettings.ADS.active && (ADS.SamplesAcquired < (cT+rT)*sF*nR*nCh)) || ... + (afeSettings.RHA.active && (RHA.SamplesAcquired < (cT+rT)*sF*nR*nCh)) + + pause(1) + disp('Waiting for more data') + if afeSettings.NI.active + disp('NI') + disp((cT+rT)*sF*nR-ai.SamplesAcquired) + disp([ai.SamplesAcquired ai.SamplesAcquired*4]) + end + if afeSettings.RHA.active + disp('RHA') + disp((cT+rT)*sF*nR*nCh-RHA.SamplesAcquired) + disp(RHA.SamplesAcquired) + end + if afeSettings.ADS.active + disp('ADS') + disp((cT+rT)*sF*nR*nCh-ADS.SamplesAcquired) + disp(ADS.SamplesAcquired) + disp((cT+rT)*sF*nR*nCh) + end + end + + % Save Data + if afeSettings.NI.active +% disp('NI:') +% ai.SamplesAcquired + wait(ai,sT+1); + [data,tt,abstime] = getdata(ai); +% disp(['date = ' num2str(fix(abstime))]) +% size(data) +% size(tdata) + tdata(:,:,ex) = data; % / 1.70e3; %Converting to input referred voltage + end + if afeSettings.RHA.active +% disp('RHA:') +% disp(RHA.SamplesAcquired) +% disp(RHA.bytesAcquired) +% disp(size(RHA.data)) + data = [RHA.data ; RHA.storeFromBuffer]; +% disp(size(data)) +% disp(size(RHAtdata)) + RHAtdata(:,:,ex)=data * (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); %Converting to input referred voltage + end + + if afeSettings.ADS.active +% disp('ADS:') +% disp(ADS.SamplesAcquired) +% disp(ADS.bytesAcquired) +% disp(size(data)) + + data = [ADS.data ; ADS.storeFromBuffer]; +% disp(size(data)) +% disp(size(ADStdata)) + ADStdata(:,:,ex)=data * (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); %Converting to input referred voltage + end + + +end +set(hGUI_Rec.t_msg,'String','Session Terminated'); % Show message about acquisition + +%% Save data and compute training data using cTp +if afeSettings.NI.active + stop(ai); + delete(ai); + NItdata=tdata; + %NItrdata=ComputeTrainingData(tdata,sF,cT,rT,nR,nM,cTp); +else + NItdata=[]; + %NItrdata=[]; +end + +if afeSettings.ADS.active + ADStdata=ADStdata; + %ADStrdata=ComputeTrainingData(ADStdata,sF,cT,rT,nR,nM,cTp); +else + ADStdata=[]; + %ADStrdata=[]; +end + +if afeSettings.RHA.active + RHAtdata=RHAtdata; + %RHAtrdata=ComputeTrainingData(RHAtdata,sF,cT,rT,nR,nM,cTp); +else + RHAtdata=[]; + %RHAtrdata=[]; +end + + +%% Save Session to file +% date = [];%fix(abstime); +recSession.sF = sF; +recSession.sT = sT; +recSession.cT = cT; +recSession.rT = rT; +%recSession.cTp = cTp; +recSession.nM = nM; +recSession.nR = nR; +recSession.nCh = nCh; +recSession.dev = dev; +recSession.mov = mov; +recSession.date = fix(clock); +recSession.cmt = inputdlg('Additional comment on the recording session','Comments'); + +[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); + if isequal(filename,0) || isequal(pathname,0) + disp('User pressed cancel') + else + disp(['User selected ', fullfile(pathname, filename)]) + if afeSettings.NI.active + recSession.tdata = NItdata; + %recSession.trdata = NItrdata; + if exist([pathname 'NI\'],'dir') == 0 + mkdir(pathname,'NI') + end + save([pathname, 'NI\',filename],'recSession'); + end + if afeSettings.ADS.active + recSession.tdata = ADStdata; + %recSession.trdata = ADStrdata; + %Possible to add string with device info for example recSession.device=afeSettings.ADS.name; + if exist([pathname 'ADS1298\'],'dir') == 0 + mkdir(pathname,'ADS1298') + end + save([pathname, 'ADS1298\',filename],'recSession'); + + % not needed here any more? +% if filters.PLH || filters.BP +% recSession.tdata = ADStdataFiltered; +% % recSession.trdata = ADStrdataFiltered; +% if exist([pathname 'ADS1298Filtered\'],'dir') == 0 +% mkdir(pathname,'ADS1298Filtered') +% end +% save([pathname,'ADS1298Filtered\',filename],'recSession'); +% end + end + if afeSettings.RHA.active + recSession.tdata = RHAtdata; + %recSession.trdata = RHAtrdata; + %Possible to add string with device info for example recSession.device=afeSettings.RHA.name; + if exist([pathname 'RHA2216\'],'dir') == 0 + mkdir(pathname,'RHA2216') + end + save([pathname 'RHA2216\',filename],'recSession'); + + % not needed here any more? +% if filters.PLH || filters.BP +% recSession.tdata = RHAtdataFiltered; +% %recSession.trdata = RHAtrdataFiltered; +% if exist([pathname 'RHA2216Filtered\'],'dir') == 0 +% mkdir(pathname,'RHA2216Filtered') +% end +% save([pathname,'RHA2216Filtered\',filename],'recSession'); +% end + end +end + +% Copy acquired data from the last excersice into cdata +% Display it +disp(recSession); + +if afeSettings.NI.show + data = NItdata(:,:,end); +elseif afeSettings.ADS.show + data = ADStdata(:,:,end).* (ADS.vref/(ADS.amplification*2^(ADS.byteDepth*8))); +elseif afeSettings.RHA.show + data = RHAtdata(:,:,end).* (RHA.vref/(RHA.amplification*2^(RHA.byteDepth*8))); +end + +chi=1; +if nCh >= 1 + cdata(:,1) = data(:,chi); + chi=chi+1; +end +if nCh >= 2 + cdata(:,2) = data(:,chi); + chi=chi+1; +end +if nCh >= 3 + cdata(:,3) = data(:,chi); + chi=chi+1; +end +if nCh >= 4 + cdata(:,4) = data(:,chi); + chi=chi+1; +end +if nCh >= 5 + cdata(:,5) = data(:,chi); + chi=chi+1; +end +if nCh >= 6 + cdata(:,6) = data(:,chi); + chi=chi+1; +end +if nCh >= 7 + cdata(:,7) = data(:,chi); + chi=chi+1; +end +if nCh >= 8 + cdata(:,8) = data(:,chi); +end + + +data_show(hGUI_Rec,cdata,sF,sT); +set(hGUI_Rec.a_pic,'Visible','off'); % Turn OFF visibility +delete(pic); % Delete image +end + +% function trdata = ComputeTrainingData(tdata,sF,cT,rT,nR,nM,cTp) +% %Compute Traning Data +% +% for ex = 1 : nM +% tempdata =[]; +% for rep = 1 : nR +% % Samples of the exersice to be consider for training +% % (sF*cT*cTp) Number of the samples that wont be consider for training +% % (sF*cT*rep) Number of samples that takes a contraction +% % (sF*rT*rep) Number of samples that takes a relaxation +% is = (sF*cT*cTp) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)) + 1; +% fs = (sF*cT) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)); +% tempdata = [tempdata ; tdata(is:fs,:,ex)]; +% end +% trdata(:,:,ex) = tempdata; +% end +% % end \ No newline at end of file diff --git a/SigRecordings/RecordingSession_ShowData.m b/SigRecordings/RecordingSession_ShowData.m new file mode 100644 index 0000000..fb1e716 --- /dev/null +++ b/SigRecordings/RecordingSession_ShowData.m @@ -0,0 +1,177 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% ------------------- Function Description ------------------ +% Function to Record Exc Sessions +% +% --------------------------Updates-------------------------- +% 2015-01-26 / Enzo Mastinu / A new GUI_Recordings has been developed for the + % BioPatRec_TRE release. Now it is possible to + % plot more then 8 channels at the same moment, for + % time and frequency plots both. It is faster and + % perfectly compatible with the ramp recording + % session. At the end of the recording session it + % is possible to check all channels individually, + % apply offline data process as feature extraction or filter etc. +% 2015-02-20 / Enzo Mastinu / Added the scaling of the data: now every channel plot will be + % dynamically and automatically resize to fit in the proper portion + % of the main plot. This is to avoid overlapping of channels + % waveforms and to have always the best zoom for every channel. +% 2015-02-23 / Enzo Mastinu / The scale of every channel plot is now the + % same scale of the channel which has the + % maximum absolute value +% 2015-02-24 / Enzo Mastinu / Now it is possible to choose if delete or not + % the offset introduced by the AFE from the time + % window plot + +% 20xx-xx-xx / Author / Comment + + + +function RecordingSession_ShowData(src, event) + + global handles; + global allData; + global timeStamps; + global samplesCounter; + global offsetDelete; + global plotGain; + + % Get required info from handles + sF = handles.sF; + nCh = handles.nCh; + rep = handles.rep; + cT = handles.cT; + rT = handles.rT; + sT = handles.sT; + ComPortType = handles.ComPortType; + rampStatus = handles.rampStatus; + if rampStatus + rampMin = handles.RampMin; + rampMax = handles.currentRampMax; + end + p_t0 = handles.p_t0; + p_f0 = handles.p_f0; + + % Get data from tempData and add to allData global vector + if(isempty(allData)) % Fist DAQ callback + timeStamps = []; + % the variable plotGain must be reloaded on every starting of a new + % recording, the reason of set it on a huge values is that in this + % way we are sure that this value will be overwritten with a lower + % value, see the code below for more details + plotGain = 10000000; + end + tempData = event.Data; + allData = [allData; tempData]; + timeStamps = [timeStamps; event.TimeStamps]; + + + %% Status bar update + if handles.fast + if strcmp(ComPortType,'NI') + % NI DAQ card + x = 1-(timeStamps(end)/sT); + else + x = 1-(samplesCounter/(sT*sF)); + end + else + if strcmp(ComPortType,'NI') + % NI DAQ card + if handles.contraction + thisToc = timeStamps(end) - ((rep-1)*(cT+rT)); + lastToc = cT; + else + thisToc = timeStamps(end) - ((rep*cT)+((rep-1)*rT)); + lastToc = rT; + end + x = 1-(thisToc/lastToc); + else + % other devices + if handles.contraction + x = 1-(samplesCounter/(cT*sF)); + else + x = 1-(samplesCounter/(rT*sF)); + end + end + end + set(handles.hPatch,'Xdata',[0 x x 0]); + drawnow; + + + if rampStatus + %% Uppdate ramp effort tracker + % Absolute value over all the channels and the current data + if handles.contraction + chAvgRMS = mean(sqrt(mean((tempData.^2),2))); % RMS Mean value on all Chs (compatible with old version of Matlab) + effortRatio = 100*(abs((chAvgRMS-rampMin)/(rampMax-rampMin))); + if effortRatio > 100 + effortRatio = 100; + end + if strcmp(ComPortType,'NI') + x = timeStamps(end)-(rep-1)*(cT+rT); + else + x = (samplesCounter/sF); + end + set(handles.hLine,'XData', x,'Ydata', effortRatio); + else + set(handles.hLine,'XData', 0,'Ydata', 0); + end + end + + + %% Display peeked Data + + aNs = length(tempData(:,1)); + NFFT = 2^nextpow2(aNs); % Next power of 2 from number of samples + f = sF/2*linspace(0,1,NFFT/2); + dataf = fft(tempData(1:aNs,:),NFFT)/aNs; + m = 2*abs(dataf((1:NFFT/2),:)); + set(p_f0,'XData',f); + + % Offset the plot of the different channels to fit into the main figure + ampPP = 5; + offVector = 0:nCh-1; + offVector = offVector .* ampPP; + + if offsetDelete + % delete the offset of the AFE and add offsets to plot channels in same graph + offset = mean(tempData); + for j = 1 : nCh + tempData(:,j) = tempData(:,j) - offset(j); + end + end + % calculate single channel's plot gain for frequency window + Kf = ampPP/(2*(max(max(abs(m))))); + % calculate single channel's plot gain for time window + % the idea is that the gain is automatically scaled depending on the absolute maximum + % value found in this new recording. In this way the gain will be changed + % dynamically to be able to discern a "rest" from a "contraction" plot + K = ampPP/(2*(max(max(abs(tempData))))); + if K < plotGain + % if the signals in the different windows is getting bigger the gain + % must be reduced consequently, the channels plots must always fit + % the main plot + plotGain = K; + end + % plot a new tWs sized window + for j = 1 : nCh + set(p_t0(j),'YData',tempData(:,j)*plotGain + offVector(j)); % add offsets to plot channels in same graph + set(p_f0(j),'YData',m(:,j)*Kf + offVector(j)); + end + drawnow + +end \ No newline at end of file diff --git a/SigRecordings/Split_recSession_Ch_Independent.m b/SigRecordings/Split_recSession_Ch_Independent.m index 4740bd4..bbc6a2a 100644 --- a/SigRecordings/Split_recSession_Ch_Independent.m +++ b/SigRecordings/Split_recSession_Ch_Independent.m @@ -1,52 +1,52 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function the slipt the information of recording sessions in different -% channels -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Otiz / Creation -% 20xx-xx-xx / Author / Comment on update - - -function [rS1 rS2] = Split_recSession_Ch(chA,chB) - - [file, path] = uigetfile('*.mat'); - if ~isequal(file, 0) - load([path,file]); - if exist('recSession','var') - % Make a copy of the original recording session - rS1 = recSession; - rS2 = recSession; - - rS1.tdata = rS1.tdata(:,chA,:); - rS1.trdata = rS1.trdata(:,chA,:); - rS1.nCh = length(chA); - recSession = rS1; - save([path,'\BiLong_',file],'recSession') - - rS2.tdata = rS2.tdata(:,chB,:); - rS2.trdata = rS2.trdata(:,chB,:); - rS2.nCh = length(chB); - recSession = rS2; - save([path,'\BiTrans_',file],'recSession') - - end - end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function the slipt the information of recording sessions in different +% channels +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Otiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function [rS1 rS2] = Split_recSession_Ch(chA,chB) + + [file, path] = uigetfile('*.mat'); + if ~isequal(file, 0) + load([path,file]); + if exist('recSession','var') + % Make a copy of the original recording session + rS1 = recSession; + rS2 = recSession; + + rS1.tdata = rS1.tdata(:,chA,:); + rS1.trdata = rS1.trdata(:,chA,:); + rS1.nCh = length(chA); + recSession = rS1; + save([path,'\BiLong_',file],'recSession') + + rS2.tdata = rS2.tdata(:,chB,:); + rS2.trdata = rS2.trdata(:,chB,:); + rS2.nCh = length(chB); + recSession = rS2; + save([path,'\BiTrans_',file],'recSession') + + end + end + diff --git a/SigTreatment/AddNoise_recSession.m b/SigTreatment/AddNoise_recSession.m new file mode 100644 index 0000000..a9086c4 --- /dev/null +++ b/SigTreatment/AddNoise_recSession.m @@ -0,0 +1,86 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to add white noise to a rec_Session using random numbers with +% mean equal to the mean of the signal, and standard deviation (std) as +% perentage of the maximum std in all channels and all movements. +% +% input : recSession Recording session +% pStd Percentagle of standard deviation +% +% output: recSession +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2014-12-30 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function recSession = AddNoise_recSession(recSession, pStd) + +% Parameters +cTp = 0.4; % percentage of the contraction time to be considered from the raw signal +tW = 0.2; % time window length +tI = 0.02; % time increment +sF = recSession.sF; +cT = recSession.cT; +rT = recSession.rT; +nS = recSession.sF * recSession.sT; +eRed = (1-cTp)/2; % effective reduction at the begining and at the end of contraction + +%% Extract the portion of interest of the raw signal using the cTp +for mov = 1 : recSession.nM + tempEMGData = []; + tempRestData = []; + for rep = 1 : recSession.nR + % Samples of the exersice to be consider for training + % (sF*cT*(cTp-1)) Number of the samples that wont be consider for training + % (sF*cT*rep) Number of samples that takes a contraction + % (sF*rT*rep) Number of samples that takes a relaxation + % EMG + is = fix((sF*cT*(1-cTp-eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)) + 1); + fs = fix((sF*cT*(cTp+eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1))); + tempEMGData = [tempEMGData ; recSession.tdata(is:fs,:,mov)]; + % floor noise + is = fix((sF*cT*rep) + (sF*rT*(1-cTp-eRed)) + (sF*rT*(rep-1)) + 1); + fs = fix((sF*cT*rep) + (sF*rT*(cTp+eRed)) + (sF*rT*(rep-1))); + tempRestData = [tempRestData ; recSession.tdata(is:fs,:,mov)]; + end + emgData(:,:,mov) = tempEMGData; + restData(:,:,mov) = tempRestData; +end + +%% Extract standard deviation (EMG, and mean (floor noise) +twS = tW * sF; % Time window samples +overlapS = tI*sF; % Time increment samples +for mov = 1 : recSession.nM + emgDataMov = emgData(:,:,mov); + emgFeature(:,mov) = mean(ExtractSigFeatureVar(emgDataMov,sF,'tstd',twS,overlapS)); + restDataMov = restData(:,:,mov); + restFeature(:,mov) = mean(ExtractSigFeatureVar(restDataMov,sF,'tmn',twS,overlapS)); +end +% Get maximum variance for EMG and mean var for the rest/floor noise +maxEmgStd = max(max(emgFeature)); +meanRest = mean(mean(restFeature)); + +%% Generate white noise matrix +meanNoise = meanRest; +stdNoise = pStd * maxEmgStd; +noiseMat = meanNoise + stdNoise .* randn(nS,size(recSession.nCh,2),recSession.nM); + +%% Add noise to the recSession +recSession.tdata = recSession.tdata + noiseMat; + diff --git a/SigTreatment/AddRestAsMovement.m b/SigTreatment/AddRestAsMovement.m index fb74cdf..e949887 100644 --- a/SigTreatment/AddRestAsMovement.m +++ b/SigTreatment/AddRestAsMovement.m @@ -1,92 +1,92 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% funtion to add information about rest or no movement as an actuall -% movemen for training -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - - -function sigTreated = AddRestAsMovement(sigTreated, recSession) - - sF = recSession.sF; - cT = recSession.cT; - rT = recSession.rT; - nR = recSession.nR; - nM = recSession.nM; - tdata = recSession.tdata; - - % Collect the 50% to 75% of rest in between each contraction per each - % movement - for ex = 1 : nM - tempdata =[]; - for rep = 1 : nR - % Samples of the exersice to be consider for training - % (sF*cT*rep) Number of samples that takes a contraction - % (sF*rT*rep) Number of samples that takes a relaxation - is = fix((sF*cT*rep) + (sF*rT*.5) + (sF*rT*(rep-1)) + 1); - fs = fix((sF*cT*rep) + (sF*rT*.75) + (sF*rT*(rep-1))); - tempdata = [tempdata ; tdata(is:fs,:,ex)]; - end - trData(:,:,ex) = tempdata; - end - - % Gather the required amount of data for a movement - % The rest data set is made with contributions from all movements rest - % period - totSamp = size(sigTreated.trData,1); - sampXmov = fix(totSamp / sigTreated.nM); - sd = totSamp - sampXmov * sigTreated.nM; %samples difference - -% if totSamp ~= sampXmov * sigTreated.nM; -% disp(['"Rest" not fitted with ' num2str(sd) ' samples']); -% errordlg(['"Rest" not fitted with ' num2str(sd) ' samples'],'Error'); -% end - - restData = []; - %Using the first samples of each movement - is = 1; - fs = sampXmov; - for ex = 1 : nM - restData = [restData ; trData(is:fs,:,ex)]; - end - - % If the rest data set wasn't completed from the information of all - % rest periods, then it willbe completed using the information from - % the last rest period of the 1st movement - if size(restData,1) ~= totSamp - restData = [restData ; trData(end-sd+1:end,:,1)]; - end - - %Random selection of the sets to be use - -% trDL = size(trData,1); -% while size(restData,1) ~= size(sigTreated.trData,1) -% ex = fix(1 + (nM-1).*rand); -% sOff = fix(0 + (trDL-sampXmov).*rand); -% is = sOff + 1; -% fs = sOff + sampXmov; -% restData = [restData ; trData(is:fs,:,ex)]; -% end - - sigTreated.nM = sigTreated.nM+1; - sigTreated.mov(sigTreated.nM) = {'Rest'}; - sigTreated.trData(:,:,sigTreated.nM) = restData; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% funtion to add information about rest or no movement as an actuall +% movemen for training +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function sigTreated = AddRestAsMovement(sigTreated, recSession) + + sF = recSession.sF; + cT = recSession.cT; + rT = recSession.rT; + nR = recSession.nR; + nM = recSession.nM; + tdata = recSession.tdata; + + % Collect the 50% to 75% of rest in between each contraction per each + % movement + for ex = 1 : nM + tempdata =[]; + for rep = 1 : nR + % Samples of the exersice to be consider for training + % (sF*cT*rep) Number of samples that takes a contraction + % (sF*rT*rep) Number of samples that takes a relaxation + is = fix((sF*cT*rep) + (sF*rT*.5) + (sF*rT*(rep-1)) + 1); + fs = fix((sF*cT*rep) + (sF*rT*.75) + (sF*rT*(rep-1))); + tempdata = [tempdata ; tdata(is:fs,:,ex)]; + end + trData(:,:,ex) = tempdata; + end + + % Gather the required amount of data for a movement + % The rest data set is made with contributions from all movements rest + % period + totSamp = size(sigTreated.trData,1); + sampXmov = fix(totSamp / sigTreated.nM); + sd = totSamp - sampXmov * sigTreated.nM; %samples difference + +% if totSamp ~= sampXmov * sigTreated.nM; +% disp(['"Rest" not fitted with ' num2str(sd) ' samples']); +% errordlg(['"Rest" not fitted with ' num2str(sd) ' samples'],'Error'); +% end + + restData = []; + %Using the first samples of each movement + is = 1; + fs = sampXmov; + for ex = 1 : nM + restData = [restData ; trData(is:fs,:,ex)]; + end + + % If the rest data set wasn't completed from the information of all + % rest periods, then it willbe completed using the information from + % the last rest period of the 1st movement + if size(restData,1) ~= totSamp + restData = [restData ; trData(end-sd+1:end,:,1)]; + end + + %Random selection of the sets to be use + +% trDL = size(trData,1); +% while size(restData,1) ~= size(sigTreated.trData,1) +% ex = fix(1 + (nM-1).*rand); +% sOff = fix(0 + (trDL-sampXmov).*rand); +% is = sOff + 1; +% fs = sOff + sampXmov; +% restData = [restData ; trData(is:fs,:,ex)]; +% end + + sigTreated.nM = sigTreated.nM+1; + sigTreated.mov(sigTreated.nM) = {'Rest'}; + sigTreated.trData(:,:,sigTreated.nM) = restData; diff --git a/SigTreatment/ApplySignalSeparation.m b/SigTreatment/ApplySignalSeparation.m new file mode 100644 index 0000000..1627331 --- /dev/null +++ b/SigTreatment/ApplySignalSeparation.m @@ -0,0 +1,36 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This Function Projecting ICA Unmixing Matrix on Training,Validation and +% Testing sets on Segmented Data. +% +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-20 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update + + +function [trData vData tData]=ApplySignalSeparation(sigTreated,trData, vData, tData) + + if strcmp(sigTreated.sigSeperation.Alg,'ICA') + [trData vData tData]=ICAPreprocess(sigTreated,trData,vData,tData); + + end + \ No newline at end of file diff --git a/SigTreatment/Compatibility_treated_data.m b/SigTreatment/Compatibility_treated_data.m index 0eb1354..f2b9855 100644 --- a/SigTreatment/Compatibility_treated_data.m +++ b/SigTreatment/Compatibility_treated_data.m @@ -1,56 +1,56 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to keep the compatibility with data treated in older versions of -% the software -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-06-30 / Max Ortiz / Creation -% 2012-05-17 / Max Ortiz / update to sigFeatures - - -function sigFeatures = Compatibility_treated_data(treated_data) - - tempF = fieldnames(treated_data); - if strcmp(tempF(1),'Fs') - - sigFeatures.sF = treated_data.Fs; - sigFeatures.tW = treated_data.tw; - sigFeatures.nCh = 1:4; - sigFeatures.dev = 'AD2/3'; - -% sigFeatures.nR = treated_data.Nr; -% sigFeatures.eTs = treated_data.eTs; -% sigFeatures.nw = treated_data.nw; - - sigFeatures.fFilter = treated_data.filters; - sigFeatures.sFilter = 1; - - - sigFeatures.trSets = treated_data.trN; - sigFeatures.vSets = treated_data.vN; - sigFeatures.tSets = treated_data.tN; - sigFeatures.trFeatures = treated_data.trdata; - sigFeatures.vFeatures = treated_data.vdata; - sigFeatures.tFeatures = treated_data.tdata; - sigFeatures.mov = treated_data.msg; - - else - sigFeatures = treated_data; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to keep the compatibility with data treated in older versions of +% the software +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-06-30 / Max Ortiz / Creation +% 2012-05-17 / Max Ortiz / update to sigFeatures + + +function sigFeatures = Compatibility_treated_data(treated_data) + + tempF = fieldnames(treated_data); + if strcmp(tempF(1),'Fs') + + sigFeatures.sF = treated_data.Fs; + sigFeatures.tW = treated_data.tw; + sigFeatures.nCh = 1:4; + sigFeatures.dev = 'AD2/3'; + +% sigFeatures.nR = treated_data.Nr; +% sigFeatures.eTs = treated_data.eTs; +% sigFeatures.nw = treated_data.nw; + + sigFeatures.fFilter = treated_data.filters; + sigFeatures.sFilter = 1; + + + sigFeatures.trSets = treated_data.trN; + sigFeatures.vSets = treated_data.vN; + sigFeatures.tSets = treated_data.tN; + sigFeatures.trFeatures = treated_data.trdata; + sigFeatures.vFeatures = treated_data.vdata; + sigFeatures.tFeatures = treated_data.tdata; + sigFeatures.mov = treated_data.msg; + + else + sigFeatures = treated_data; end \ No newline at end of file diff --git a/SigTreatment/ComputeSignalSeparation.m b/SigTreatment/ComputeSignalSeparation.m new file mode 100644 index 0000000..9c4d723 --- /dev/null +++ b/SigTreatment/ComputeSignalSeparation.m @@ -0,0 +1,36 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This Function Computing ICA on 60% of Raw Treated Data(40% Trainig and +% 20% validation Data) for All Movements +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-20 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update + +function sigTreated=ComputeSignalSeparation(sigTreated) + + +if strcmp(sigTreated.sigSeperation.Alg,'ICA') + + ICAUnmixMat=ICA(sigTreated.trData(1:size(sigTreated.trData,1)*.6,:,:)); + + sigTreated.sigSeperation.ICAUnmixMat=ICAUnmixMat; +end \ No newline at end of file diff --git a/SigTreatment/Downsample_recSession.m b/SigTreatment/Downsample_recSession.m new file mode 100644 index 0000000..a8a7fdf --- /dev/null +++ b/SigTreatment/Downsample_recSession.m @@ -0,0 +1,41 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to downsampel the data in a recording session (recSession) +% +% input: recSession (struct) +% dS = downsample frequency or new frequency +% output: recSession (struct) +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2014-12-05 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function recSession = Downsample_recSession(recSession, dS) + +dsFactor = recSession.sF/dS; + +if ~mod(dsFactor,1) + recSession.tdata = downsample(recSession.tdata,dsFactor); + recSession.sF = dS; +else + errordlg('Downsample frequency is not a module of original frequency','Error'); +end + + diff --git a/SigTreatment/Frequency Filters/ApplyButterFilter.m b/SigTreatment/Frequency Filters/ApplyButterFilter.m index 2f0140b..ea002bc 100644 --- a/SigTreatment/Frequency Filters/ApplyButterFilter.m +++ b/SigTreatment/Frequency Filters/ApplyButterFilter.m @@ -1,32 +1,32 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Apply the requested BW filter to data -% -% ------------------------- Updates & Contributors ------------------------ -% 2009-04-16 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment - - -function [dataf] = ApplyButterFilter(Fs,N,Fc1,Fc2,data) - -[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2)); -[sos_var,g] = zp2sos(z, p, k); -Hd = dfilt.df2sos(sos_var, g); -dataf = filter(Hd,data); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Apply the requested BW filter to data +% +% ------------------------- Updates & Contributors ------------------------ +% 2009-04-16 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment + + +function [dataf] = ApplyButterFilter(Fs,N,Fc1,Fc2,data) + +[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2)); +[sos_var,g] = zp2sos(z, p, k); +Hd = dfilt.df2sos(sos_var, g); +dataf = filter(Hd,data); + diff --git a/SigTreatment/Frequency Filters/ApplyFilters.m b/SigTreatment/Frequency Filters/ApplyFilters.m index e471b8c..1c26a98 100644 --- a/SigTreatment/Frequency Filters/ApplyFilters.m +++ b/SigTreatment/Frequency Filters/ApplyFilters.m @@ -1,63 +1,63 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% General function to call other filter functions if selected -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-27 / Max Ortiz / Creation -% 2012-03-11 / Max Ortiz / Added DDF Abs - -function data = ApplyFilters(sigTreated, data) - - - %% Frequency filters - sF = sigTreated.sF; - -% disp('Frequency filtering data...'); - - if strcmp(sigTreated.fFilter,'None') - % Do nothing and exit if - elseif strcmp(sigTreated.fFilter,'PLH') - data = BSbutterPLHarmonics(sF, data); - elseif strcmp(sigTreated.fFilter,'BP 20-1k') - data = FilterBP(sF, data,20,1000); - elseif strcmp(sigTreated.fFilter,'BP 70-1k') - data = FilterBP(sF, data,70,1000); - end - -% disp('Frequency Filtering Done'); - - %% Spatial filters -% disp('Spatial filtering data...'); - - if strcmp(sigTreated.sFilter,'None') - % Do nothing and exit if - elseif strcmp(sigTreated.sFilter,'SDF') - data = SpatialFilterSDF(data); - elseif strcmp(sigTreated.sFilter,'DDF') - data = SpatialFilterDDF(data); - elseif strcmp(sigTreated.sFilter,'DDF Abs') - data = SpatialFilterDDFAbs(data); - disp('Warning: Signals have been converted to their absulute value'); - end - -% disp('Spatial Filtering Done'); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% General function to call other filter functions if selected +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-27 / Max Ortiz / Creation +% 2012-03-11 / Max Ortiz / Added DDF Abs + +function data = ApplyFilters(sigTreated, data) + + + %% Frequency filters + sF = sigTreated.sF; + +% disp('Frequency filtering data...'); + + if strcmp(sigTreated.fFilter,'None') + % Do nothing and exit if + elseif strcmp(sigTreated.fFilter,'PLH') + data = BSbutterPLHarmonics(sF, data); + elseif strcmp(sigTreated.fFilter,'BP 20-1k') + data = FilterBP(sF, data,20,1000); + elseif strcmp(sigTreated.fFilter,'BP 70-1k') + data = FilterBP(sF, data,70,1000); + end + +% disp('Frequency Filtering Done'); + + %% Spatial filters +% disp('Spatial filtering data...'); + + if strcmp(sigTreated.sFilter,'None') + % Do nothing and exit if + elseif strcmp(sigTreated.sFilter,'SDF') + data = SpatialFilterSDF(data); + elseif strcmp(sigTreated.sFilter,'DDF') + data = SpatialFilterDDF(data); + elseif strcmp(sigTreated.sFilter,'DDF Abs') + data = SpatialFilterDDFAbs(data); + disp('Warning: Signals have been converted to their absulute value'); + end + +% disp('Spatial Filtering Done'); + + end \ No newline at end of file diff --git a/SigTreatment/Frequency Filters/BSbutterPLHarmonics.m b/SigTreatment/Frequency Filters/BSbutterPLHarmonics.m index 941ffab..ab846b5 100644 --- a/SigTreatment/Frequency Filters/BSbutterPLHarmonics.m +++ b/SigTreatment/Frequency Filters/BSbutterPLHarmonics.m @@ -1,38 +1,38 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% [Give a short summary about the principle of your function here.] -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [data] = BSbutterPLHarmonics(Fs, data) - -N = 20; % Order -for i = 0 : 11 - Fc1 = 49 + 50*i; % First Cutoff Frequency - Fc2 = 51 + 50*i; % Second Cutoff Frequency - - [z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2), 'stop'); - [sos_var,g] = zp2sos(z, p, k); - Hd = dfilt.df2sos(sos_var, g); - data = filter(Hd,data); -end - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% [Give a short summary about the principle of your function here.] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [data] = BSbutterPLHarmonics(Fs, data) + +N = 20; % Order +for i = 0 : 11 + Fc1 = 49 + 50*i; % First Cutoff Frequency + Fc2 = 51 + 50*i; % Second Cutoff Frequency + + [z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2), 'stop'); + [sos_var,g] = zp2sos(z, p, k); + Hd = dfilt.df2sos(sos_var, g); + data = filter(Hd,data); +end + diff --git a/SigTreatment/Frequency Filters/Filter50hz.m b/SigTreatment/Frequency Filters/Filter50hz.m index 28ab01b..91660d7 100644 --- a/SigTreatment/Frequency Filters/Filter50hz.m +++ b/SigTreatment/Frequency Filters/Filter50hz.m @@ -1,37 +1,39 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% [Give a short summary about the principle of your function here.] -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [dataf] = Filter50hz (Fs, data) - -N = 20; % Order -Fc1 = 40; % First Cutoff Frequency -Fc2 = 60; % Second Cutoff Frequency - -[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2), 'stop'); - -[sos_var,g] = zp2sos(z, p, k); -Hd50 = dfilt.df2sos(sos_var, g); - -dataf = filter(Hd50,data); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% [Give a short summary about the principle of your function here.] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [dataf] = Filter50hz (Fs, data) + +N = 6; % Order +Fc1 = 49; % First Cutoff Frequency +Fc2 = 51; % Second Cutoff Frequency + +[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2), 'stop'); + +[sos_var,g] = zp2sos(z, p, k); +Hd50 = dfilt.df2sos(sos_var, g); + +dataf = filter(Hd50,data); + + diff --git a/SigTreatment/Frequency Filters/FilterBP.m b/SigTreatment/Frequency Filters/FilterBP.m index 7ef96b3..b77d04a 100644 --- a/SigTreatment/Frequency Filters/FilterBP.m +++ b/SigTreatment/Frequency Filters/FilterBP.m @@ -1,36 +1,36 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Band-pass filter -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-18 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [dataf] = FilterBP (Fs, data, cF1, cF2) - -N = 4; % Order - -% Calculate the zpk values using the BUTTER function. -[z,p,k] = butter(N/2, [cF1 cF2]/(Fs/2)); - -[sos_var,g] = zp2sos(z, p, k); -Hd = dfilt.df2sos(sos_var, g); - -dataf = filter(Hd,data); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Band-pass filter +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [dataf] = FilterBP (Fs, data, cF1, cF2) + +N = 4; % Order + +% Calculate the zpk values using the BUTTER function. +[z,p,k] = butter(N/2, [cF1 cF2]/(Fs/2)); + +[sos_var,g] = zp2sos(z, p, k); +Hd = dfilt.df2sos(sos_var, g); + +dataf = filter(Hd,data); + diff --git a/SigTreatment/Frequency Filters/FilterBP_EMG.m b/SigTreatment/Frequency Filters/FilterBP_EMG.m index 150a383..01973d2 100644 --- a/SigTreatment/Frequency Filters/FilterBP_EMG.m +++ b/SigTreatment/Frequency Filters/FilterBP_EMG.m @@ -1,38 +1,38 @@ -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% [Give a short summary about the principle of your function here.] -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [dataf] = FilterBP_EMG(Fs, data) - -N = 20; % Order -Fc1 = 70; % First Cutoff Frequency -Fc2 = 1000; % Second Cutoff Frequency - -% Calculate the zpk values using the BUTTER function. -[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2)); - -[sos_var,g] = zp2sos(z, p, k); -Hd = dfilt.df2sos(sos_var, g); - -dataf = filter(Hd,data); - +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% [Give a short summary about the principle of your function here.] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [dataf] = FilterBP_EMG(Fs, data) + +N = 20; % Order +Fc1 = 70; % First Cutoff Frequency +Fc2 = 1000; % Second Cutoff Frequency + +% Calculate the zpk values using the BUTTER function. +[z,p,k] = butter(N/2, [Fc1 Fc2]/(Fs/2)); + +[sos_var,g] = zp2sos(z, p, k); +Hd = dfilt.df2sos(sos_var, g); + +dataf = filter(Hd,data); + diff --git a/SigTreatment/Frequency Filters/FilterData.m b/SigTreatment/Frequency Filters/FilterData.m index c2efcd5..d72d284 100644 --- a/SigTreatment/Frequency Filters/FilterData.m +++ b/SigTreatment/Frequency Filters/FilterData.m @@ -1,42 +1,42 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Funtion to filter the received data according to filtering option at the -% GUI -% Input = Data and GUI handles -% Output = Filtered data -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-04-15 / Max Ortiz / Creation -% 2012-11-25 / Max Ortiz / Update to BioPatRec coding standard -% 20xx-xx-xx / Author / Comment on update - -function data = FilterData(data, handles, Fs) - - if get(handles.cb_filter50hz,'Value') - data = Filter50hz(Fs, data); - end - - if get(handles.cb_filterBP,'Value') - data = FilterBP(Fs, data); - end - - if get(handles.cb_filter80Hz,'Value') - data = FilterHP80hz(Fs, data); - end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Funtion to filter the received data according to filtering option at the +% GUI +% Input = Data and GUI handles +% Output = Filtered data +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-04-15 / Max Ortiz / Creation +% 2012-11-25 / Max Ortiz / Update to BioPatRec coding standard +% 20xx-xx-xx / Author / Comment on update + +function data = FilterData(data, handles, Fs) + + if get(handles.cb_filter50hz,'Value') + data = Filter50hz(Fs, data); + end + + if get(handles.cb_filterBP,'Value') + data = FilterBP(Fs, data); + end + + if get(handles.cb_filter80Hz,'Value') + data = FilterHP80hz(Fs, data); + end diff --git a/SigTreatment/Frequency Filters/FilterHP80hz.m b/SigTreatment/Frequency Filters/FilterHP80hz.m index 9cb93d2..c477423 100644 --- a/SigTreatment/Frequency Filters/FilterHP80hz.m +++ b/SigTreatment/Frequency Filters/FilterHP80hz.m @@ -1,39 +1,39 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% [Give a short summary about the principle of your function here.] -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function [dataf] = FilterHP80hz (Fs, data) - -N = 20; % Order -Fc = 80; % Cutoff Frequency - -% Calculate the zpk values using the BUTTER function. -[z,p,k] = butter(N, Fc/(Fs/2), 'high'); - -[sos_var,g] = zp2sos(z, p, k); -Hd = dfilt.df2sos(sos_var, g); - -dataf = filter(Hd,data); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% [Give a short summary about the principle of your function here.] +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function [dataf] = FilterHP80hz (Fs, data) + +N = 20; % Order +Fc = 80; % Cutoff Frequency + +% Calculate the zpk values using the BUTTER function. +[z,p,k] = butter(N, Fc/(Fs/2), 'high'); + +[sos_var,g] = zp2sos(z, p, k); +Hd = dfilt.df2sos(sos_var, g); + +dataf = filter(Hd,data); + + diff --git a/SigTreatment/GUI_SigTreatment.fig b/SigTreatment/GUI_SigTreatment.fig index 38fd26d..18a1cc1 100644 Binary files a/SigTreatment/GUI_SigTreatment.fig and b/SigTreatment/GUI_SigTreatment.fig differ diff --git a/SigTreatment/GUI_SigTreatment.m b/SigTreatment/GUI_SigTreatment.m index 0ee8474..b25be8d 100644 --- a/SigTreatment/GUI_SigTreatment.m +++ b/SigTreatment/GUI_SigTreatment.m @@ -47,7 +47,7 @@ % Edit the above text to modify the response to help GUI_SigTreatment -% Last Modified by GUIDE v2.5 26-Jul-2012 16:53:37 +% Last Modified by GUIDE v2.5 03-Jan-2015 18:23:03 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; @@ -120,7 +120,7 @@ function pb_treat_Callback(hObject, eventdata, handles) set(handles.t_msg,'String','Extracting signal features'); drawnow; sigFeatures = GetAllSigFeatures(handles, sigTreated); - + sigFeatures.sigSeperation=sigTreated.sigSeperation; % Get back in the parent GUI ---------------------------------------- phandles = get(handles.t_mhandles,'UserData'); % get parent GUI handles @@ -448,7 +448,31 @@ function pb_preProcessing_Callback(hObject, eventdata, handles) sigTreated = PreProcessing(handles); %Computer numer of sequencially avialable windows -------------------- - nw = fix(sigTreated.cT * sigTreated.cTp * sigTreated.nR / str2double(get(handles.et_tw,'String'))); +% nw = fix(sigTreated.cT * sigTreated.cTp * sigTreated.nR / str2double(get(handles.et_tw,'String'))); +% set(handles.et_nw,'String',num2str(nw)); +% +% trP = str2double(get(handles.et_trP,'String')); +% trN = fix(trP * nw); +% set(handles.et_trN,'String',num2str(trN)); +% +% vP = str2double(get(handles.et_vP,'String')); +% vN = fix( vP* nw); +% set(handles.et_vN,'String',num2str(vN)); +% +% tP = str2double(get(handles.et_tP,'String')); +% tN = fix(tP * nw); +% set(handles.et_tN,'String',num2str(tN)); +% set(handles.t_totN,'String',num2str(trN+vN+tN)); +% set(handles.t_totP,'String',num2str(trP+vP+tP)); + + % Computer the number of windows using overlapping + set(handles.et_wOverlap,'Enable','on'); + overlap = str2double(get(handles.et_wOverlap,'String')); + + tT = sigTreated.cT * sigTreated.cTp * sigTreated.nR; + tw = str2double(get(handles.et_tw,'String')); + offset = ceil(tw/overlap); + nw = fix(tT / overlap) - offset; set(handles.et_nw,'String',num2str(nw)); trP = str2double(get(handles.et_trP,'String')); @@ -461,11 +485,24 @@ function pb_preProcessing_Callback(hObject, eventdata, handles) tP = str2double(get(handles.et_tP,'String')); tN = fix(tP * nw); + %add test time windows so that it matches the total amount of + %windows + while trN+vN+tN < nw + tN = tN + 1; + end set(handles.et_tN,'String',num2str(tN)); set(handles.t_totN,'String',num2str(trN+vN+tN)); set(handles.t_totP,'String',num2str(trP+vP+tP)); %Disable and enable bottons ------------------------------------------- + set(handles.lb_movements,'Enable','off'); + set(handles.lb_nCh,'Enable','off'); + set(handles.et_downsample,'Enable','off'); + set(handles.et_noise,'Enable','off'); + set(handles.et_nM,'Enable','off'); + set(handles.et_cTp,'Enable','off'); + set(handles.cb_rest,'Enable','off'); + set(handles.pm_scaling,'Enable','off'); set(handles.pb_preProcessing,'Enable','off'); set(handles.pb_treat,'Enable','on'); set(handles.pb_treatFolder,'Enable','on'); @@ -694,3 +731,95 @@ function et_cTp_Callback(hObject, eventdata, handles) % Hints: get(hObject,'String') returns contents of et_cTp as text % str2double(get(hObject,'String')) returns contents of et_cTp as a double + + +% --- Executes on selection change in pm_SignalSeparation. +function pm_SignalSeparation_Callback(hObject, eventdata, handles) +% hObject handle to pm_SignalSeparation (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_SignalSeparation contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_SignalSeparation + + +% --- Executes during object creation, after setting all properties. +function pm_SignalSeparation_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_SignalSeparation (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 et_downsample_Callback(hObject, eventdata, handles) +% hObject handle to et_downsample (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 et_downsample as text +% str2double(get(hObject,'String')) returns contents of et_downsample as a double + + +% --- Executes during object creation, after setting all properties. +function et_downsample_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_downsample (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 selection change in pm_scaling. +function pm_scaling_Callback(hObject, eventdata, handles) +% hObject handle to pm_scaling (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles structure with handles and user data (see GUIDATA) + +% Hints: contents = cellstr(get(hObject,'String')) returns pm_scaling contents as cell array +% contents{get(hObject,'Value')} returns selected item from pm_scaling + + +% --- Executes during object creation, after setting all properties. +function pm_scaling_CreateFcn(hObject, eventdata, handles) +% hObject handle to pm_scaling (see GCBO) +% eventdata reserved - to be defined in a future version of MATLAB +% handles empty - handles not created until after all CreateFcns called + +% Hint: popupmenu 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 et_noise_Callback(hObject, eventdata, handles) +% hObject handle to et_noise (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 et_noise as text +% str2double(get(hObject,'String')) returns contents of et_noise as a double + + +% --- Executes during object creation, after setting all properties. +function et_noise_CreateFcn(hObject, eventdata, handles) +% hObject handle to et_noise (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 diff --git a/SigTreatment/GetData.m b/SigTreatment/GetData.m index 362e4dd..f65a2f9 100644 --- a/SigTreatment/GetData.m +++ b/SigTreatment/GetData.m @@ -1,117 +1,117 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% This function will create matrices of training, validation and testing data -% by splitting the original data -% It will also send the data to the routine to break down its -% characteristics -% -% input: Data is a Nsamples x Nchannels x Nexercises matrix -% sigTreated struct with the information required for the data -% treatment -% output: trdata are the split training data from the original recording time -% vdata are the split validation data -% tdata are the split testing data -% -% NOTE: Optimization could be implemented -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2009-07-15 / Max Ortiz / Include time splits -% 2009-07-15 / Max Ortiz / Adaptation to work with treated_data struct -% 2011-07-19 / Max Ortiz / Modification to only deliver the data of -% the time windows and no the signal features -% and use of the sigTreated struct -% 2012-06-13 / Max Ortiz / Addition of a tolerance in the verification of -% eCtc and eCt since matlab presision on the doubles operation was screwing -% the comparison - -function [trdata, vdata, tdata] = GetData (sigTreated) - - data = sigTreated.trData; % trData only contains information from the contraction - nM = length(data(1,1,:)); % Number of movements - - % Some validations - ssize = fix(length(data(:,1,1))/sigTreated.nR); % Samples Size of a repetition or Number of samples that makes a repetition - eCt = sigTreated.eCt; % Due to several issues with matlab this was separated - eCtc = ssize/sigTreated.sF; % to more lines of code - - %if eCtc ~= eCt - if abs(eCtc - eCt) > 0.0000001 % a tolerance had to be introduce due to matlab doubles inacuracy - disp('ERROR!!!! No match between samples and eCt'); - errordlg('No match between samples and eCt','Error'); - return; - end - - if sigTreated.trSets + sigTreated.vSets + sigTreated.tSets ~= sigTreated.nW % Verification - disp('ERROR!!!! No match in total number of sets'); - errordlg('No match in total number of sets','Error'); - return; - end - - % Get Data - if strcmp(sigTreated.twSegMethod,'Non Overlapped') - - nTw = sigTreated.eCt/sigTreated.tW; % Number of time windows per eCt - if fix(nTw*sigTreated.nR) ~= sigTreated.nW % Verification - disp('ERROR!!!! No match between number of time windows'); - errordlg('No match between number of time windows','Error'); - return; - end - - assize = fix(ssize /nTw); % Absolute number of samples that corresponde to the window time of a repetition - - for e = 1: nM - for i = 1 : sigTreated.nW - iidx = 1 + (assize*(i-1)); - eidx = assize+(assize*(i-1)); - %tempdata(i,e) = analyze_signal(data(iidx:eidx,:,e),sigTreated.sF); - tempdata(:,:,e,i) = data(iidx:eidx,:,e); - end - end - - elseif strcmp(sigTreated.twSegMethod,'Overlapped Cons') - - tWsamples = sigTreated.tW * sigTreated.sF; % Samples corresponding Time window - oS = sigTreated.wOverlap * sigTreated.sF; % Samples correcponding overlap - - for e = 1: nM - for i = 1 : sigTreated.nW - iidx = 1 + (oS * (i-1)); - eidx = tWsamples + (oS *(i-1)); - tempdata(:,:,e,i) = data(iidx:eidx,:,e); - end - end - - - - elseif strcmp(sigTreated.twSegMethod,'Overlapped Rand') - - end - - - trSets = sigTreated.trSets; - vSets = sigTreated.vSets; - tSets = sigTreated.tSets; - trdata = tempdata(:,:,:,1:trSets); - vdata = tempdata(:,:,:,trSets+1:trSets+vSets); - tdata = tempdata(:,:,:,trSets+vSets+1:trSets+vSets+tSets); - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function will create matrices of training, validation and testing data +% by splitting the original data +% It will also send the data to the routine to break down its +% characteristics +% +% input: Data is a Nsamples x Nchannels x Nexercises matrix +% sigTreated struct with the information required for the data +% treatment +% output: trdata are the split training data from the original recording time +% vdata are the split validation data +% tdata are the split testing data +% +% NOTE: Optimization could be implemented +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2009-07-15 / Max Ortiz / Include time splits +% 2009-07-15 / Max Ortiz / Adaptation to work with treated_data struct +% 2011-07-19 / Max Ortiz / Modification to only deliver the data of +% the time windows and no the signal features +% and use of the sigTreated struct +% 2012-06-13 / Max Ortiz / Addition of a tolerance in the verification of +% eCtc and eCt since matlab presision on the doubles operation was screwing +% the comparison + +function [trdata, vdata, tdata] = GetData (sigTreated) + + data = sigTreated.trData; % trData only contains information from the contraction + nM = length(data(1,1,:)); % Number of movements + + % Some validations + ssize = fix(length(data(:,1,1))/sigTreated.nR); % Samples Size of a repetition or Number of samples that makes a repetition + eCt = sigTreated.eCt; % Due to several issues with matlab this was separated + eCtc = ssize/sigTreated.sF; % to more lines of code + + %if eCtc ~= eCt + if abs(eCtc - eCt) > 0.0000001 % a tolerance had to be introduce due to matlab doubles inacuracy + disp('ERROR!!!! No match between samples and eCt'); + errordlg('No match between samples and eCt','Error'); + return; + end + + if sigTreated.trSets + sigTreated.vSets + sigTreated.tSets ~= sigTreated.nW % Verification + disp('ERROR!!!! No match in total number of sets'); + errordlg('No match in total number of sets','Error'); + return; + end + + % Get Data + if strcmp(sigTreated.twSegMethod,'Non Overlapped') + + nTw = sigTreated.eCt/sigTreated.tW; % Number of time windows per eCt + if fix(nTw*sigTreated.nR) ~= sigTreated.nW % Verification + disp('ERROR!!!! No match between number of time windows'); + errordlg('No match between number of time windows','Error'); + return; + end + + assize = fix(ssize /nTw); % Absolute number of samples that corresponde to the window time of a repetition + + for e = 1: nM + for i = 1 : sigTreated.nW + iidx = 1 + (assize*(i-1)); + eidx = assize+(assize*(i-1)); + %tempdata(i,e) = analyze_signal(data(iidx:eidx,:,e),sigTreated.sF); + tempdata(:,:,e,i) = data(iidx:eidx,:,e); + end + end + + elseif strcmp(sigTreated.twSegMethod,'Overlapped Cons') + + tWsamples = sigTreated.tW * sigTreated.sF; % Samples corresponding Time window + oS = sigTreated.wOverlap * sigTreated.sF; % Samples correcponding overlap + + for e = 1: nM + for i = 1 : sigTreated.nW + iidx = 1 + (oS * (i-1)); + eidx = tWsamples + (oS *(i-1)); + tempdata(:,:,e,i) = data(iidx:eidx,:,e); + end + end + + + + elseif strcmp(sigTreated.twSegMethod,'Overlapped Rand') + + end + + + trSets = sigTreated.trSets; + vSets = sigTreated.vSets; + tSets = sigTreated.tSets; + trdata = tempdata(:,:,:,1:trSets); + vdata = tempdata(:,:,:,trSets+1:trSets+vSets); + tdata = tempdata(:,:,:,trSets+vSets+1:trSets+vSets+tSets); + + end \ No newline at end of file diff --git a/SigTreatment/ICA/ICA.m b/SigTreatment/ICA/ICA.m new file mode 100644 index 0000000..b13513e --- /dev/null +++ b/SigTreatment/ICA/ICA.m @@ -0,0 +1,141 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function performs Independent Coponent Analysis for Treated +% as Prprocessing using Fast Fixed Point Algorithm . +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-08-01 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update + + +function ICAUnmixMat = ICA(data) + +% Centering and PCA +allMovData=[]; +for i=1:size(data,3) + allMovData=[allMovData + data(:,:,i)]; +end + +m = mean(allMovData)'; +meanData = allMovData' - m*ones(1,size(allMovData,1)); +variance = cov(meanData'); +[E D] = eig(variance'); +[Val index] = sort(diag(D),'descend'); + +% Whitening + +whitenData = (sqrt (D)^-1) * E'; +dewhitenData = E * sqrt (D); +ProjData = whitenData*meanData; + + +% Computing Mixing and Demixing Matrix +X = ProjData; +[vectorSize, numSamples] = size(X); + +B = zeros(vectorSize); % Basis Vector + +% parameters +epsilon = 0.0001; % Stopping Criterion +maxNumIterations = 1000; +myy = 1; +stroke = 0; + +for l=1:vectorSize + + w=rand(vectorSize,1); + w = w - B * B' * w; + w = w / norm(w); + wOld = zeros(size(w)); + wOld2 = zeros(size(w)); + + % This Hyvarinen's fixed point algorithm from FASTICA Matlab Package. + for j=1:maxNumIterations + + if norm(w-wOld)< epsilon | norm(w+wOld)< epsilon + + break + + elseif (~stroke)& norm(w-wOld2) maxNumIterations/2; + % + myy = .5*myy; + wOld2 = wOld; + wOld = w; + % + EXGpow3 = (X * ((X' * w) .^ 3)) / numSamples; + Beta = w' * EXGpow3; + w = w - myy * (EXGpow3 - Beta * w) / (3 - Beta); + else + wOld2 = wOld; + wOld = w; + w = (X * ((X' * w) .^ 3)) / numSamples - 3 * w; + + end + w = w - B * B' * w; + w = w/norm(w); + end + + fprintf('Algoritm converged for [%d] iterations \n',j); + + + B(:, l) = w; + A(:,l) = dewhitenData * w; + W(l,:) = w' * whitenData; + + +end +ICAUnmixMat=W'; + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SigTreatment/ICA/ICAPreprocess.m b/SigTreatment/ICA/ICAPreprocess.m new file mode 100644 index 0000000..b1651cd --- /dev/null +++ b/SigTreatment/ICA/ICAPreprocess.m @@ -0,0 +1,64 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This Function Performs Independent component analysis for Training +% Validation and testing. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-10-20 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update + +function [trData,vData,tData]=ICAPreprocess(sigTreated,trData,vData,tData) + + + + + W=sigTreated.sigSeperation.ICAUnmixMat; + + % Projecting ICA Unmixing Matrix on Training Sets +% + for i=1:size(trData,3) + for j=1:size(trData,4) + tempTrData(:,:,i,j)= trData(:,:,i,j)*W; + + end + end + +% +% % Projecting ICA Unmixing Matrix on Validation Sets + + for i=1:size(vData,3) + for j=1:size(vData,4) + tempVData(:,:,i,j)= vData(:,:,i,j)*W; + + end + end + +% % Projecting ICA Unmixing Matrix on Testing Sets + for i=1:size(tData,3) + for j=1:size(tData,4) + tempTData(:,:,i,j)= tData(:,:,i,j)*W; + + end + end + + trData=tempTrData; + vData=tempVData; + tData=tData; + \ No newline at end of file diff --git a/SigTreatment/PlotFFT.m b/SigTreatment/PlotFFT.m new file mode 100644 index 0000000..2e9d956 --- /dev/null +++ b/SigTreatment/PlotFFT.m @@ -0,0 +1,67 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Plot the FFT of a vector given in data. It has a routine to smooth the +% graphical representation using a sliding averaging window. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2013-08-01 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function PlotFFT(data, sF, color) + + nS = length(data(:,1)); % It used to be sF*sT but due to change in lenght witht training data + sT = nS/sF; + tt = 0:1/sF:sT-1/sF; % Create vector of time + + if size(tt,2) ~= size(data,1) + nSd = size(data,1)- size(tt,2); + tt(1,end:end+nSd) = 0; + end + + %Fast Fourier Transform + NFFT = 2^nextpow2(nS); % Next power of 2 from number of samples +% NFFT = 1024; + dataf = fft(data,NFFT)/nS; + f = sF/2*linspace(0,1,NFFT/2+1); + m = 2*abs(dataf(1:NFFT/2+1)); + m(1:2) = 0; + + % Smooth + n = 3; + nn = 2; + for j = 1 :nn + clear mT; + for i = n+1: size(m,1)-n + mT(i,1) = mean(m(i-n:i+n)); + end + mT(end:end+n)=0; + m = mT; + end + + % Normalize + vMax = max(m); + m = m ./vMax; + +% figure(); + plot(f,m,color); + title('Single-Sided Amplitude Spectrum of y(t)') + xlabel('Frequency (Hz)') + ylabel('|Y(f)|') \ No newline at end of file diff --git a/SigTreatment/PreProcessing.m b/SigTreatment/PreProcessing.m index d25712d..fece001 100644 --- a/SigTreatment/PreProcessing.m +++ b/SigTreatment/PreProcessing.m @@ -1,74 +1,107 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to pre-process bioelectric recordings. It's call from the -% treatment GUI and requires the handles. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-07-07 / Max Ortiz / Moved out from the preProcessing botton -% 20xx-xx-xx / Author / Comment on update - -function sigTreated = PreProcessing(handles) - - % Get the recSession - set(handles.t_msg,'String','Loading recSession...'); - recSession = get(handles.t_recSession,'UserData'); - - %Remove movements if required %--------------------------------------- - movSel = get(handles.lb_movements,'Value'); - nM = str2double(get(handles.et_nM,'String')); - - if nM ~= length(movSel) - recSession = Split_recSession_Mov(movSel, recSession); - end - - %Remove channels if required %--------------------------------------- - chSel = get(handles.lb_nCh,'Value'); - - if length(recSession.nCh) ~= length(chSel) - allCh = get(handles.lb_nCh,'String'); - for i = 1 : length(chSel) - channels(i) = str2double(allCh(chSel(i))); - end - - recSession = Split_recSession_Ch(channels, recSession); - - end - - %Remove trasient %--------------------------------------------------- - cTp = str2double(get(handles.et_cTp,'String')); - sigTreated = RemoveTransient_cTp(recSession, cTp); - - %Add rest as a movement data %--------------------------------------- - if get(handles.cb_rest,'Value') - sigTreated = AddRestAsMovement(sigTreated, recSession); - % It informs the user of the changes made, however it conflics when - % a whole folder is treated -% set(handles.et_nM,'String',num2str(sigTreated.nM)); -% set(handles.lb_movements,'Value',1:sigTreated.nM); -% set(handles.lb_movements,'String',sigTreated.mov); - -% movSel = [movSel sigTreated.nM]; -% set(handles.lb_movements,'Value',movSel); - end - - % Upload sigtreated to the GUI---------------------------------------- - set(handles.t_sigTreated,'UserData',sigTreated); - set(handles.t_msg,'String','sigTreated uploaded'); - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to pre-process bioelectric recordings. It's called from the +% treatment GUI and requires the handles. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-07-07 / Max Ortiz / Moved out from the preProcessing botton +% 2014-12-06 / Max Ortiz / Added downsampling option +% 2014-12-28 / Max Ortiz / Added scaling option +% 20xx-xx-xx / Author / Comment on update + +function sigTreated = PreProcessing(handles) + + % Get the recSession + set(handles.t_msg,'String','Loading recSession...'); + recSession = get(handles.t_recSession,'UserData'); + + %Remove movements if required %--------------------------------------- + movSel = get(handles.lb_movements,'Value'); + nM = str2double(get(handles.et_nM,'String')); + + if nM ~= length(movSel) + recSession = Split_recSession_Mov(movSel, recSession); + end + + %Remove channels, if required %--------------------------------------- + chSel = get(handles.lb_nCh,'Value'); + + if length(recSession.nCh) ~= length(chSel) + allCh = get(handles.lb_nCh,'String'); + for i = 1 : length(chSel) + channels(i) = str2double(allCh(chSel(i))); + end + + recSession = Split_recSession_Ch(channels, recSession); + + end + + % Downsample, if required %--------------------------------------- + sF = str2double(get(handles.et_sF,'String')); + dS = str2double(get(handles.et_downsample,'String')); + if sF ~= dS + if recSession.sF < dS + errordlg('The downsample frequency is higher than the original sF','Error'); + set(handles.t_msg,'String','Error in downsample frequency'); + set(handles.et_downsample,'String',num2str(recSession.sF)); + else + recSession = Downsample_recSession(recSession, dS); + end + end + + % Add noise, if required %--------------------------------------- + pStd = str2double(get(handles.et_noise,'String')); + if pStd ~= 0 + recSession = AddNoise_recSession(recSession, pStd); + end + recSession.noise = pStd; + + % Scaling, if required %--------------------------------------- + scalingV = get(handles.pm_scaling,'Value'); + scalingS = get(handles.pm_scaling,'String'); + scalingBits = str2double(scalingS{scalingV}); + if scalingV ~= 1 % If other than None + recSession = Scale_recSession(recSession, scalingBits); + end + recSession.scaled = scalingBits; + + %% Change from recSession to sigTreated + + %Remove trasient %--------------------------------------------------- + cTp = str2double(get(handles.et_cTp,'String')); + sigTreated = RemoveTransient_cTp(recSession, cTp); + + %Add rest as a movement data %--------------------------------------- + if get(handles.cb_rest,'Value') + sigTreated = AddRestAsMovement(sigTreated, recSession); + % It informs the user of the changes made, however it conflics when + % a whole folder is treated +% set(handles.et_nM,'String',num2str(sigTreated.nM)); +% set(handles.lb_movements,'Value',1:sigTreated.nM); +% set(handles.lb_movements,'String',sigTreated.mov); + +% movSel = [movSel sigTreated.nM]; +% set(handles.lb_movements,'Value',movSel); + end + + % Upload sigtreated to the GUI---------------------------------------- + set(handles.t_sigTreated,'UserData',sigTreated); + set(handles.t_msg,'String','sigTreated uploaded'); + diff --git a/SigTreatment/RemoveTransient_cTp.m b/SigTreatment/RemoveTransient_cTp.m index 6ed9c0d..17e4be2 100644 --- a/SigTreatment/RemoveTransient_cTp.m +++ b/SigTreatment/RemoveTransient_cTp.m @@ -1,66 +1,66 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to compute Traning Data according to the contraction time -% percentage (cTp) -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 20xx-xx-xx / Max Ortiz / Creation -% 2011-07-19 / Max Ortiz / Updated to consider cTp before and after -% contraction -% 20xx-xx-xx / Author / Comment on update - -function sigTreated = RemoveTransient_cTp(recSession, cTp) - - sF = recSession.sF; - cT = recSession.cT; - rT = recSession.rT; - nR = recSession.nR; - nM = recSession.nM; - tdata = recSession.tdata; - - % New structured for the signal treated - sigTreated = recSession; - sigTreated.cTp = cTp; - eRed = (1-cTp)/2; % effective reduction at the begining and at the end of contraction - - % Removed useless fields for following operations - if isfield(sigTreated,'tdata') - sigTreated = rmfield(sigTreated,'tdata'); - end - if isfield(sigTreated,'trdata') - sigTreated = rmfield(sigTreated,'trdata'); - end - - for ex = 1 : nM - tempdata =[]; - for rep = 1 : nR - % Samples of the exersice to be consider for training - % (sF*cT*(cTp-1)) Number of the samples that wont be consider for training - % (sF*cT*rep) Number of samples that takes a contraction - % (sF*rT*rep) Number of samples that takes a relaxation - is = fix((sF*cT*(1-cTp-eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)) + 1); - fs = fix((sF*cT*(cTp+eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1))); - tempdata = [tempdata ; tdata(is:fs,:,ex)]; - end - trData(:,:,ex) = tempdata; - end - - sigTreated.trData = trData; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to compute Traning Data according to the contraction time +% percentage (cTp) +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 20xx-xx-xx / Max Ortiz / Creation +% 2011-07-19 / Max Ortiz / Updated to consider cTp before and after +% contraction +% 20xx-xx-xx / Author / Comment on update + +function sigTreated = RemoveTransient_cTp(recSession, cTp) + + sF = recSession.sF; + cT = recSession.cT; + rT = recSession.rT; + nR = recSession.nR; + nM = recSession.nM; + tdata = recSession.tdata; + + % New structured for the signal treated + sigTreated = recSession; + sigTreated.cTp = cTp; + eRed = (1-cTp)/2; % effective reduction at the begining and at the end of contraction + + % Removed useless fields for following operations + if isfield(sigTreated,'tdata') + sigTreated = rmfield(sigTreated,'tdata'); + end + if isfield(sigTreated,'trdata') + sigTreated = rmfield(sigTreated,'trdata'); + end + + for ex = 1 : nM + tempdata =[]; + for rep = 1 : nR + % Samples of the exersice to be consider for training + % (sF*cT*(cTp-1)) Number of the samples that wont be consider for training + % (sF*cT*rep) Number of samples that takes a contraction + % (sF*rT*rep) Number of samples that takes a relaxation + is = fix((sF*cT*(1-cTp-eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1)) + 1); + fs = fix((sF*cT*(cTp+eRed)) + (sF*cT*(rep-1)) + (sF*rT*(rep-1))); + tempdata = [tempdata ; tdata(is:fs,:,ex)]; + end + trData(:,:,ex) = tempdata; + end + + sigTreated.trData = trData; end \ No newline at end of file diff --git a/SigTreatment/Scale_recSession.m b/SigTreatment/Scale_recSession.m new file mode 100644 index 0000000..1a3c005 --- /dev/null +++ b/SigTreatment/Scale_recSession.m @@ -0,0 +1,66 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to scale the data in a recording session (recSession) +% to integers as adquired by the ADC using 2^(n-1) n=bits +% (n-1) is used because one bit is required by the sign (+ or -) +% n (bits) = 8, 10, 12, 14, 16 +% 2^n = 256, 1024, 4096, 16384, 32768 +% 2^(n-1) = 128, 256, 1024, 4096, 16384 +% +% Given the signal x, make values of x fall on the interval [a,b] +% x_scaled = (x-min(x))*(b-a)/(max(x)-min(x)) + a; +% +% input: recSession (struct) +% scalingBits = number of bits to be fitted +% output: recSession (struct) +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2014-12-28 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function recSession = Scale_recSession(recSession, scalingBits) + +if scalingBits == 8 + a = 128; +elseif scalingBits == 10 + a = 256; +elseif scalingBits == 12 + a = 1024; +elseif scalingBits == 14 + a = 4096; +elseif scalingBits == 16 + a = 16384; +else + errordlg('Scaling failed','Error'); + return; +end +b = a; +a = a * -1; + +% Range of the original aquisition +minX = -5; +maxX = 5; + +% Scale +for i=1:length(recSession.tdata(1,1,:)) + recSession.tdata(:,:,i) = round((recSession.tdata(:,:,i) - minX) .* (b-a) ./ (maxX-minX) + a); +end + + diff --git a/SigTreatment/SignalSeparationRealtime.m b/SigTreatment/SignalSeparationRealtime.m new file mode 100644 index 0000000..bd34e34 --- /dev/null +++ b/SigTreatment/SignalSeparationRealtime.m @@ -0,0 +1,33 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% This function performs Independent Coponent Analysis in Realtime +% as Prprocessing using Fast Fixed Point Algorithm . +% +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-01 / Tanuj Kumar Aluru / Creation +% 20xx-xx-xx / Author / Comment on update + +function data = SignalSeparationRealtime(patRec, data) + + if strcmp(patRec.sigSeperation.Alg,'ICA') + data=data*patRec.sigSeperation.ICAUnmixMat; + end +end diff --git a/SigTreatment/Spatial Filters/SpatialFilterDDF.m b/SigTreatment/Spatial Filters/SpatialFilterDDF.m index 2c98b76..e4d6b9f 100644 --- a/SigTreatment/Spatial Filters/SpatialFilterDDF.m +++ b/SigTreatment/Spatial Filters/SpatialFilterDDF.m @@ -1,52 +1,52 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to apply the spatial filter 2A - B - C (double differential) -% conidering the electrodes circunferencial arrengment ...| C | A | B |... -% the number of channels can be grater than 3 but not less than 3 -% NOTE: Considerations must be made on how the electrodes were conected to -% the amplifiers inputs -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-18 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function data = SpatialFilterDDF(data) - - nCh = length(data(1,:,1)); - - % Compute the filter - for i = 1 : nCh - A = i; - % Compute B - if i == nCh - B = 1; - else - B = i + 1; - end - % Compute C - if i == 1 - C = nCh; - else - C = i - 1; - end - tempData(:,A,:) = (data(:,A,:) .* 2) - data(:,B,:) - data(:,C,:); - end - - data = tempData; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to apply the spatial filter 2A - B - C (double differential) +% conidering the electrodes circunferencial arrengment ...| C | A | B |... +% the number of channels can be grater than 3 but not less than 3 +% NOTE: Considerations must be made on how the electrodes were conected to +% the amplifiers inputs +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function data = SpatialFilterDDF(data) + + nCh = length(data(1,:,1)); + + % Compute the filter + for i = 1 : nCh + A = i; + % Compute B + if i == nCh + B = 1; + else + B = i + 1; + end + % Compute C + if i == 1 + C = nCh; + else + C = i - 1; + end + tempData(:,A,:) = (data(:,A,:) .* 2) - data(:,B,:) - data(:,C,:); + end + + data = tempData; diff --git a/SigTreatment/Spatial Filters/SpatialFilterDDFAbs.m b/SigTreatment/Spatial Filters/SpatialFilterDDFAbs.m index fba57dd..576263c 100644 --- a/SigTreatment/Spatial Filters/SpatialFilterDDFAbs.m +++ b/SigTreatment/Spatial Filters/SpatialFilterDDFAbs.m @@ -1,60 +1,60 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to apply the spatial filter abs(2A - B - C) double differential -% conidering the electrodes circunferencial arrengment ...| C | A | B |... -% the number of channels can be grater than 3 but not less than 3 -% It returns a ABS value as well -% NOTE: Considerations must be made on how the electrodes were conected to -% the amplifiers inputs -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-18 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function data = SpatialFilterDDFAbs(data) - - nCh = length(data(1,:,1)); - data = abs(data); - - % Compute the filter - for i = 1 : nCh - A = i; - % Compute B - if i == nCh - B = 1; - else - B = i + 1; - end - % Compute C - if i == 1 - C = nCh; - else - C = i - 1; - end - tempData(:,A,:) = (data(:,A,:) .* 2) - data(:,B,:) - data(:,C,:); - - % Eliminates negative values - for j = 1 : size(tempData,3) - [v vIdx] = find(tempData(:,A,j)' < 0); - tempData(vIdx,A,j) = 0; - end - end - - data = tempData; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to apply the spatial filter abs(2A - B - C) double differential +% conidering the electrodes circunferencial arrengment ...| C | A | B |... +% the number of channels can be grater than 3 but not less than 3 +% It returns a ABS value as well +% NOTE: Considerations must be made on how the electrodes were conected to +% the amplifiers inputs +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function data = SpatialFilterDDFAbs(data) + + nCh = length(data(1,:,1)); + data = abs(data); + + % Compute the filter + for i = 1 : nCh + A = i; + % Compute B + if i == nCh + B = 1; + else + B = i + 1; + end + % Compute C + if i == 1 + C = nCh; + else + C = i - 1; + end + tempData(:,A,:) = (data(:,A,:) .* 2) - data(:,B,:) - data(:,C,:); + + % Eliminates negative values + for j = 1 : size(tempData,3) + [v vIdx] = find(tempData(:,A,j)' < 0); + tempData(vIdx,A,j) = 0; + end + end + + data = tempData; diff --git a/SigTreatment/Spatial Filters/SpatialFilterSDF.m b/SigTreatment/Spatial Filters/SpatialFilterSDF.m index 094e591..fae606e 100644 --- a/SigTreatment/Spatial Filters/SpatialFilterSDF.m +++ b/SigTreatment/Spatial Filters/SpatialFilterSDF.m @@ -1,48 +1,48 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to apply the spatial filter A - B (single differential) conidering -% the electrodes circunferencial arrengment ... | A | B | C | ... -% the number of channels can be grater than 4 but not less than 2 -% NOTE: Considerations must be made on how the electrodes were conected to -% the amplifiers inputs -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-18 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function data = SpatialFilterSDF(data) - - nCh = length(data(1,:,1)); - - % Compute the filter - for i = 1 : nCh - A = i; - % Compute B - if i == nCh - B = 1; - else - B = i + 1; - end - tempData(:,A,:) = data(:,A,:) + data(:,B,:); - end - - data = tempData; - - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to apply the spatial filter A - B (single differential) conidering +% the electrodes circunferencial arrengment ... | A | B | C | ... +% the number of channels can be grater than 4 but not less than 2 +% NOTE: Considerations must be made on how the electrodes were conected to +% the amplifiers inputs +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function data = SpatialFilterSDF(data) + + nCh = length(data(1,:,1)); + + % Compute the filter + for i = 1 : nCh + A = i; + % Compute B + if i == nCh + B = 1; + else + B = i + 1; + end + tempData(:,A,:) = data(:,A,:) + data(:,B,:); + end + + data = tempData; + + diff --git a/SigTreatment/Spatial Filters/SpatialFilter_1.m b/SigTreatment/Spatial Filters/SpatialFilter_1.m new file mode 100644 index 0000000..360bfb7 --- /dev/null +++ b/SigTreatment/Spatial Filters/SpatialFilter_1.m @@ -0,0 +1,73 @@ +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to apply the spatial filter 2A-B-D considering a circunferencial +% arrengment of electrode A - B - C- D - ... +% The number of channels can be grater than 4 but not less than 3 +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-18 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + +function sigTreated = SpatialFilter_1() + + [file, path] = uigetfile('*.mat'); + if ~isequal(file, 0) + load([path,file]); + if exist('recSession','var') + nCh = length(recSession.tdata(1,:,1)); + sigTreated = recSession; + + % Removed useless fields for following operations + if isfield(sigTreated,'tdata') + sigTreated = rmfield(sigTreated,'tdata'); + end + if isfield(sigTreated,'trdata') + sigTreated = rmfield(sigTreated,'trdata'); + end + + % Compute the filter + if sigTreated.nCh == nCh; + trdata = recSession.trdata; + for i = 1 : nCh + A = i; + % Compute B + if i == nCh + B = 1; + else + B = i + 1; + end + % Compute D + if i == 1 + D = nCh; + else + D = i - 1; + end + tempData(:,A,:) = (trdata(:,A,:) .* 2) - trdata(:,B,:) - trdata(:,D,:); + end + else + disp('nCh does not match tdata matrix'); + end + + sigTreated.trdata = tempdata; + + end + end +end + diff --git a/SigTreatment/Split_recSession_Ch.m b/SigTreatment/Split_recSession_Ch.m index b321c99..08b0742 100644 --- a/SigTreatment/Split_recSession_Ch.m +++ b/SigTreatment/Split_recSession_Ch.m @@ -1,29 +1,29 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function the slipt the information of recording sessions in different -% channels -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-07-21 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - -function recSession = Split_recSession_Ch(channels, recSession) - - recSession.tdata = recSession.tdata(:,channels,:); - recSession.nCh = channels; +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function the slipt the information of recording sessions in different +% channels +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-07-21 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + +function recSession = Split_recSession_Ch(channels, recSession) + + recSession.tdata = recSession.tdata(:,channels,:); + recSession.nCh = channels; diff --git a/SigTreatment/Split_recSession_Mov.m b/SigTreatment/Split_recSession_Mov.m index 84b46ed..cfc2002 100644 --- a/SigTreatment/Split_recSession_Mov.m +++ b/SigTreatment/Split_recSession_Mov.m @@ -1,32 +1,32 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to reduced the number of recorded movements -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2011-08-04 / Max Ortiz / Creation -% 20xx-xx-xx / Author / Comment on update - - - -function recSession = Split_recSession_Mov(mov, recSession) - - recSession.tdata = recSession.tdata(:,:,mov); - recSession.nM = length(mov); - recSession.mov = recSession.mov(mov); +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to reduced the number of recorded movements +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2011-08-04 / Max Ortiz / Creation +% 20xx-xx-xx / Author / Comment on update + + + +function recSession = Split_recSession_Mov(mov, recSession) + + recSession.tdata = recSession.tdata(:,:,mov); + recSession.nM = length(mov); + recSession.mov = recSession.mov(mov); diff --git a/SigTreatment/TreatData.m b/SigTreatment/TreatData.m index 98777a4..1330d1f 100644 --- a/SigTreatment/TreatData.m +++ b/SigTreatment/TreatData.m @@ -1,73 +1,87 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to treat the raw data -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2009-07-20 / Max Ortiz / Creation -% 2011-07-27 / Max Ortiz / Update to coding standard -% 2011-07-27 / Max Ortiz / Moved the "updated sigTreated" instructions out -% of the GUI push bottom -% 20xx-xx-xx / Author / Comment on update - -function sigTreated = TreatData(handles, sigTreated) - - %% Update sigTreated - fFilters = get(handles.pm_frequencyFilters,'String'); - fFiltersSel = get(handles.pm_frequencyFilters,'Value'); - sigTreated.fFilter = fFilters(fFiltersSel); - - sFilters = get(handles.pm_spatialFilters,'String'); - sFiltersSel = get(handles.pm_spatialFilters,'Value'); - sigTreated.sFilter = sFilters(sFiltersSel); - - sigTreated.eCt = sigTreated.cT * sigTreated.cTp; % Effective contraction time - sigTreated.wOverlap = str2double(get(handles.et_wOverlap,'String')); - sigTreated.tW = str2double(get(handles.et_tw,'String')); - sigTreated.nW = str2double(get(handles.et_nw,'String')); - sigTreated.trSets = str2double(get(handles.et_trN,'String')); - sigTreated.vSets = str2double(get(handles.et_vN,'String')); - sigTreated.tSets = str2double(get(handles.et_tN,'String')); - - twSegMethods = get(handles.pm_twSegMethod,'String'); - twSegMethodsSel = get(handles.pm_twSegMethod,'Value'); - sigTreated.twSegMethod = twSegMethods(twSegMethodsSel); - - - %% Filters - set(handles.t_msg,'String','Applying filters...'); - sigTreated.trData = ApplyFilters(sigTreated, sigTreated.trData); - set(handles.t_msg,'String','Filters applied'); - - - %% Split the data into the time windows - set(handles.t_msg,'String','Segmenting data...'); - disp('Segmenting data...'); - [trData, vData, tData] = GetData(sigTreated); - %Remove raw trated data - sigTreated = rmfield(sigTreated,'trData'); - set(handles.t_msg,'String','Data segmented'); - disp('Data segmented'); - - % add the new sets of tw for tr, v and t - sigTreated.trData = trData; - sigTreated.vData = vData; - sigTreated.tData = tData; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to treat the raw data +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2009-07-20 / Max Ortiz / Creation +% 2011-07-27 / Max Ortiz / Update to coding standard +% 2011-07-27 / Max Ortiz / Moved the "updated sigTreated" instructions out +% of the GUI push bottom +% 20xx-xx-xx / Author / Comment on update + +function sigTreated = TreatData(handles, sigTreated) + + %% Update sigTreated + fFilters = get(handles.pm_frequencyFilters,'String'); + fFiltersSel = get(handles.pm_frequencyFilters,'Value'); + sigTreated.fFilter = fFilters(fFiltersSel); + + sFilters = get(handles.pm_spatialFilters,'String'); + sFiltersSel = get(handles.pm_spatialFilters,'Value'); + sigTreated.sFilter = sFilters(sFiltersSel); + + sigTreated.eCt = sigTreated.cT * sigTreated.cTp; % Effective contraction time + sigTreated.wOverlap = str2double(get(handles.et_wOverlap,'String')); + sigTreated.tW = str2double(get(handles.et_tw,'String')); + sigTreated.nW = str2double(get(handles.et_nw,'String')); + sigTreated.trSets = str2double(get(handles.et_trN,'String')); + sigTreated.vSets = str2double(get(handles.et_vN,'String')); + sigTreated.tSets = str2double(get(handles.et_tN,'String')); + + twSegMethods = get(handles.pm_twSegMethod,'String'); + twSegMethodsSel = get(handles.pm_twSegMethod,'Value'); + sigTreated.twSegMethod = twSegMethods(twSegMethodsSel); + + allSigSeperaAlg = get(handles.pm_SignalSeparation,'String'); + selSigSeperaAlg = allSigSeperaAlg(get(handles.pm_SignalSeparation,'Value')); + sigTreated.sigSeperation.Alg= selSigSeperaAlg; + + %% Filters + set(handles.t_msg,'String','Applying filters...'); + sigTreated.trData = ApplyFilters(sigTreated, sigTreated.trData); + set(handles.t_msg,'String','Filters applied'); + + %% Signal Separation Alg - Compute + + set(handles.t_msg,'String','Computing SP...'); + sigTreated=ComputeSignalSeparation(sigTreated); + set(handles.t_msg,'String','SP Computed'); + + + %% Split the data into the time windows + set(handles.t_msg,'String','Segmenting data...'); + disp('Segmenting data...'); + [trData, vData, tData] = GetData(sigTreated); + %Remove raw trated data + sigTreated = rmfield(sigTreated,'trData'); + set(handles.t_msg,'String','Data segmented'); + disp('Data segmented'); + + %% Sig Separation Algortihms - Apply + + [trData vData tData]=ApplySignalSeparation(sigTreated,trData, vData, tData); + + + % add the new sets of tw for tr, v and t + sigTreated.trData = trData; + sigTreated.vData = vData; + sigTreated.tData = tData; + end \ No newline at end of file diff --git a/VRE/CalculatePathLength.m b/VRE/CalculatePathLength.m index 184ca84..457a751 100644 --- a/VRE/CalculatePathLength.m +++ b/VRE/CalculatePathLength.m @@ -1,81 +1,81 @@ -% pathLength = CalculatePathLength(ssTraj,target,allowance) -% -% Calculates path length of a state space trajectory, removing any -% movements within the allowance space. -% -% INPUTS: -% -% ssTraj - Coordinates of the trajectrory in state space, each -% coordinate should be stored in the rows of the matrix ssTraj. -% -% target - Coordinates to the target in state space, should be a -% row vector. -% -% allowance - the number of degrees that are considered to be close -% enough to the target. The allowance space is contained by the box -% target (plus minus) allowance / 2. - -function pathLength = CalculatePathLength(ssTraj,target,allowance) - -pathLength = 0; - -posOld = ssTraj(1,:); -for iPos = 2:size(ssTraj,1) - - posNew = ssTraj(iPos,:); - - % Check if system jumped into allowance space - if InAllowanceSpace(posNew,target,allowance) && ~InAllowanceSpace(posOld,target,allowance) - - crossingPoint = FindCrossing(posOld,posNew,target,allowance); - pathLength = pathLength + norm(crossingPoint - posOld); - - % Check if system jumped out of allowance space - elseif InAllowanceSpace(posOld,target,allowance) && ~InAllowanceSpace(posNew,target,allowance) - - crossingPoint = FindCrossing( posNew, posOld,target,allowance ); - pathLength = pathLength + norm(crossingPoint - posNew); - - % Check if trajectory is inside allowance space - elseif InAllowanceSpace(posOld,target,allowance) && InAllowanceSpace(posNew,target,allowance) - - % Check if trajectory is outside of allowance space - elseif ~InAllowanceSpace(posOld,target,allowance) && ~InAllowanceSpace(posNew,target,allowance) - pathLength = pathLength + norm(posNew - posOld); - end - - posOld = posNew; - -end - -function crossingPoint = FindCrossing(posOut,posIn,target,allowance) - -len = norm( posIn - posOut ); % Calculate length between posOld and posNew -dir = (posIn - posOut)./len; % Calculate unity direction between pos1 and pos2 - -while len > 1e-5 - - posTmp = posOut+len/2.*dir; % Take half a step between out and in - - % If the new position is inside the allowance space we have stepped too far - if InAllowanceSpace(posTmp,target,allowance) - posIn = posTmp; % move the inside position to tmp position - - % else if it is outside we have stepped to short - else - posOut = posTmp; % move the outside position to tmp position - end - - len = norm( posIn - posOut ); % recalculate the length between the two points - -end - -crossingPoint = posIn; - -function inside = InAllowanceSpace(pos,target,allowance) - -inside = 0; - -if norm(pos-target) < allowance - inside = 1; +% pathLength = CalculatePathLength(ssTraj,target,allowance) +% +% Calculates path length of a state space trajectory, removing any +% movements within the allowance space. +% +% INPUTS: +% +% ssTraj - Coordinates of the trajectrory in state space, each +% coordinate should be stored in the rows of the matrix ssTraj. +% +% target - Coordinates to the target in state space, should be a +% row vector. +% +% allowance - the number of degrees that are considered to be close +% enough to the target. The allowance space is contained by the box +% target (plus minus) allowance / 2. + +function pathLength = CalculatePathLength(ssTraj,target,allowance) + +pathLength = 0; + +posOld = ssTraj(1,:); +for iPos = 2:size(ssTraj,1) + + posNew = ssTraj(iPos,:); + + % Check if system jumped into allowance space + if InAllowanceSpace(posNew,target,allowance) && ~InAllowanceSpace(posOld,target,allowance) + + crossingPoint = FindCrossing(posOld,posNew,target,allowance); + pathLength = pathLength + norm(crossingPoint - posOld); + + % Check if system jumped out of allowance space + elseif InAllowanceSpace(posOld,target,allowance) && ~InAllowanceSpace(posNew,target,allowance) + + crossingPoint = FindCrossing( posNew, posOld,target,allowance ); + pathLength = pathLength + norm(crossingPoint - posNew); + + % Check if trajectory is inside allowance space + elseif InAllowanceSpace(posOld,target,allowance) && InAllowanceSpace(posNew,target,allowance) + + % Check if trajectory is outside of allowance space + elseif ~InAllowanceSpace(posOld,target,allowance) && ~InAllowanceSpace(posNew,target,allowance) + pathLength = pathLength + norm(posNew - posOld); + end + + posOld = posNew; + +end + +function crossingPoint = FindCrossing(posOut,posIn,target,allowance) + +len = norm( posIn - posOut ); % Calculate length between posOld and posNew +dir = (posIn - posOut)./len; % Calculate unity direction between pos1 and pos2 + +while len > 1e-5 + + posTmp = posOut+len/2.*dir; % Take half a step between out and in + + % If the new position is inside the allowance space we have stepped too far + if InAllowanceSpace(posTmp,target,allowance) + posIn = posTmp; % move the inside position to tmp position + + % else if it is outside we have stepped to short + else + posOut = posTmp; % move the outside position to tmp position + end + + len = norm( posIn - posOut ); % recalculate the length between the two points + +end + +crossingPoint = posIn; + +function inside = InAllowanceSpace(pos,target,allowance) + +inside = 0; + +if norm(pos-target) < allowance + inside = 1; end \ No newline at end of file diff --git a/VRE/CreateMovMatrix.m b/VRE/CreateMovMatrix.m index 6c2455c..0de92c5 100644 --- a/VRE/CreateMovMatrix.m +++ b/VRE/CreateMovMatrix.m @@ -1,111 +1,111 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function used by the StateSpaceTracker, creates a matrix that corresponds -% to the different movements trained in the patRec. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-11-23 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function [movMatrix, movMatrixNorm] = CreateMovMatrix(patRec) - - %indMovIdx = patRec.indMovIdx; % Read movement indexes - %movMatrix = zeros(length(indMovIdx),3); % Preset movMatrix for speed - - %for i = 1:length(indMovIdx) % Loop through all output movement patRec has - k = 1; - for i = patRec.indMovIdx - - %moves = regexp(patRec.mov{indMovIdx(i)},'\W+\W','split'); % Read current movement (could be individual or simultaneous) - moves = regexp(patRec.mov{i},'\W+\W','split'); % Read current movement (could be individual or simultaneous) - - outMovTmp = []; - - for j = 1:length(moves) % Loop through all movement that current output is (1 if individual several if simultaneous) - - if strcmp(moves{j},'Open Hand') % If read movement is Open hand, map to 1 - outMovTmp = [outMovTmp; 1]; - end - - if strcmp(moves{j},'Close Hand') % If read movement is Close Hand, map to 2 - outMovTmp = [outMovTmp; 2]; - end - - if strcmp(moves{j},'Flex Hand') % If read movement is Flex Hand, map to 3 - outMovTmp = [outMovTmp; 3]; - end - - if strcmp(moves{j},'Extend Hand') % If read movement is Extend Hand, map to 4 - outMovTmp = [outMovTmp; 4]; - end - - if strcmp(moves{j},'Pronation') % If read movement is Pronation, map to 5 - outMovTmp = [outMovTmp; 5]; - end - - if strcmp(moves{j},'Supination') % If read movement is Supination, map to 6 - outMovTmp = [outMovTmp; 6]; - end - - if strcmp(moves{j},'Rest') % If read movement is Rest, map to 7 - outMovTmp = [outMovTmp; 7]; - end - - end - - movement = [0,0,0]; - - for j = 1:length(outMovTmp) - - switch outMovTmp(j) - case 1 % Open Hand - dim = 1; - dir = 1; - case 2 % Close Hand - dim = 1; - dir = -1; - case 3 % Flex Hand - dim = 2; - dir = 1; - case 4 % Extend Hand - dim = 2; - dir = -1; - case 5 % Pronation - dim = 3; - dir = 1; - case 6 % Supination - dim = 3; - dir = -1; - case 7 - dim = []; - dir = 0; - end - - movement(dim) = movement(dim) + dir; - - end - - movMatrix(k,:) = movement; - k = k+1; - - end - - movMatrixNorm = movMatrix(1:end-1,:) ./ repmat( sqrt( diag(movMatrix(1:end-1,:)*movMatrix(1:end-1,:)') ), [1,3] ) ; - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function used by the StateSpaceTracker, creates a matrix that corresponds +% to the different movements trained in the patRec. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-23 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function [movMatrix, movMatrixNorm] = CreateMovMatrix(patRec) + + %indMovIdx = patRec.indMovIdx; % Read movement indexes + %movMatrix = zeros(length(indMovIdx),3); % Preset movMatrix for speed + + %for i = 1:length(indMovIdx) % Loop through all output movement patRec has + k = 1; + for i = patRec.indMovIdx + + %moves = regexp(patRec.mov{indMovIdx(i)},'\W+\W','split'); % Read current movement (could be individual or simultaneous) + moves = regexp(patRec.mov{i},'\W+\W','split'); % Read current movement (could be individual or simultaneous) + + outMovTmp = []; + + for j = 1:length(moves) % Loop through all movement that current output is (1 if individual several if simultaneous) + + if strcmp(moves{j},'Open Hand') % If read movement is Open hand, map to 1 + outMovTmp = [outMovTmp; 1]; + end + + if strcmp(moves{j},'Close Hand') % If read movement is Close Hand, map to 2 + outMovTmp = [outMovTmp; 2]; + end + + if strcmp(moves{j},'Flex Hand') % If read movement is Flex Hand, map to 3 + outMovTmp = [outMovTmp; 3]; + end + + if strcmp(moves{j},'Extend Hand') % If read movement is Extend Hand, map to 4 + outMovTmp = [outMovTmp; 4]; + end + + if strcmp(moves{j},'Pronation') % If read movement is Pronation, map to 5 + outMovTmp = [outMovTmp; 5]; + end + + if strcmp(moves{j},'Supination') % If read movement is Supination, map to 6 + outMovTmp = [outMovTmp; 6]; + end + + if strcmp(moves{j},'Rest') % If read movement is Rest, map to 7 + outMovTmp = [outMovTmp; 7]; + end + + end + + movement = [0,0,0]; + + for j = 1:length(outMovTmp) + + switch outMovTmp(j) + case 1 % Open Hand + dim = 1; + dir = 1; + case 2 % Close Hand + dim = 1; + dir = -1; + case 3 % Flex Hand + dim = 2; + dir = 1; + case 4 % Extend Hand + dim = 2; + dir = -1; + case 5 % Pronation + dim = 3; + dir = 1; + case 6 % Supination + dim = 3; + dir = -1; + case 7 + dim = []; + dir = 0; + end + + movement(dim) = movement(dim) + dir; + + end + + movMatrix(k,:) = movement; + k = k+1; + + end + + movMatrixNorm = movMatrix(1:end-1,:) ./ repmat( sqrt( diag(movMatrix(1:end-1,:)*movMatrix(1:end-1,:)') ), [1,3] ) ; + diff --git a/VRE/CurrentPosition.m b/VRE/CurrentPosition.m new file mode 100644 index 0000000..eb06e1e --- /dev/null +++ b/VRE/CurrentPosition.m @@ -0,0 +1,88 @@ +function obj = CurrentPosition(varargin) + + persistent target allowance positions distance movements classifier tempdistance + + if(length(varargin) < 1) + return + end + obj = []; + if ischar(varargin{1}) + switch(varargin{1}) + case 'init' + classifier = varargin{2}; + allowance = varargin{3}; + movements = varargin{4}; + + max = 0; + for i = 1:length(movements) + if movements(i).idVRE > max + max = movements(i).idVRE; + end + end + + positions = zeros(1,max); + case 'target' + + distance = 0; + tempdistance = 0; + + index = varargin{2}; + dist = varargin{3}; + + movement = movements(index); + target = zeros(1,length(positions)); + + for i = 1:length(movement) + if movement(i).vreDir == 0 + target(movement(i).idVRE) = -1 * dist; + else + target(movement(i).idVRE) = dist; + end + end + + positions = zeros(1,length(positions)); + + case 'move' + %Make sure within limit and Check if inside, if not, move it. + newPos = positions; + + index = varargin{2}; + speeds = varargin{3}; + + movement = movements(index); + + for i = 1:length(movement) + id = movement(i).idVRE; + if id > 0 + if movement(i).vreDir == 0 + newPos(id) = newPos(id) - speeds(index(i)); + else + newPos(id) = newPos(id) + speeds(index(i)); + end + end + end + + movedDistance = abs(EuclidDist(newPos,positions)); + + if abs(EuclidDist(newPos,target)) < allowance + tempdistance = tempdistance + movedDistance; + else + distance = distance + movedDistance + tempdistance; + tempdistance = 0; + end + positions = newPos; + + case 'get' + start = zeros(1,length(target)); + + dofs = length(nonzeros(target)); + + l = sqrt((5^2)/dofs); + + finish = abs(target) - (target~=0)*l; %Get shortest distance moving from start. + %Perfect, incl Allowance. + perfect = EuclidDist(finish,start); + obj = perfect/distance; + end + end +end \ No newline at end of file diff --git a/VRE/MoveSS.m b/VRE/MoveSS.m index 86a2f55..2571ab1 100644 --- a/VRE/MoveSS.m +++ b/VRE/MoveSS.m @@ -1,64 +1,64 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function used by the StateSpaceTracker, moves the system in the state -% space using -% - Last Position -% - movement matrix -% - outMovIdx ( separate for all combined movements, used with movement matrix ) -% - outMov ( multiple indexes, one for each DoF, used with speeds ) -% - speeds -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-11-23 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function ssPos = MoveSS(ssPos,movMatrix,outMov,speeds) - -% Only take the desired movements from movMatrix -%movMat = movMatrix(outMovIdx,:); -movMat = movMatrix(outMov,:); -% Take the desired speeds (1 for individual, several for simultaneous) -speeds = speeds(outMov); - -for i = 1:size(movMat,1) - %movMat(i,:) = movMat(i,:)./norm(movMat(i,:)); % Normalize each movement - movMat(i,:) = movMat(i,:).*speeds(i); -end - -% Sum up simultaneous movements to a single movement -movMat = sum(movMat,1); - - -ssPos = ssPos + movMat; % Move the position in state space - -% % Limit each dimension to the range [-50,50] (Nichlas percent units) -% ssPos( ssPos > 50 ) = 50; -% ssPos( ssPos < -50 ) = -50; - -% Create Boundary inside state space -ssPos( ssPos > 90 ) = 90; -ssPos( ssPos < -90 ) = -90; - -% Open / Close hand work differently, can only move a 100 degrees -if ssPos(1) > 50 - ssPos(1) = 50; -elseif ssPos(1) < -50 - ssPos(1) = -50; -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function used by the StateSpaceTracker, moves the system in the state +% space using +% - Last Position +% - movement matrix +% - outMovIdx ( separate for all combined movements, used with movement matrix ) +% - outMov ( multiple indexes, one for each DoF, used with speeds ) +% - speeds +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-23 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function ssPos = MoveSS(ssPos,movMatrix,outMov,speeds) + +% Only take the desired movements from movMatrix +%movMat = movMatrix(outMovIdx,:); +movMat = movMatrix(outMov,:); +% Take the desired speeds (1 for individual, several for simultaneous) +speeds = speeds(outMov); + +for i = 1:size(movMat,1) + %movMat(i,:) = movMat(i,:)./norm(movMat(i,:)); % Normalize each movement + movMat(i,:) = movMat(i,:).*speeds(i); +end + +% Sum up simultaneous movements to a single movement +movMat = sum(movMat,1); + + +ssPos = ssPos + movMat; % Move the position in state space + +% % Limit each dimension to the range [-50,50] (Nichlas percent units) +% ssPos( ssPos > 50 ) = 50; +% ssPos( ssPos < -50 ) = -50; + +% Create Boundary inside state space +ssPos( ssPos > 90 ) = 90; +ssPos( ssPos < -90 ) = -90; + +% Open / Close hand work differently, can only move a 100 degrees +if ssPos(1) > 50 + ssPos(1) = 50; +elseif ssPos(1) < -50 + ssPos(1) = -50; +end diff --git a/VRE/TACTest.m b/VRE/TACTest.m index 09b4e7c..ff711de 100644 --- a/VRE/TACTest.m +++ b/VRE/TACTest.m @@ -1,388 +1,461 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% ------------------- Function Description ------------------ -% A TAC Test is performed using the VRE. It then uses the TacTestResult -% function to display the gathered data. -% -% The function is written in such a way that it requires the movement -% "rest" to run properly. -% --------------------------Updates-------------------------- -% [Contributors are welcome to add their email] -% 2012-06-07 / Nichlas Sander / Creation of TACTest -% 2012-08-08 / Nichlas Sander / Data is saved in correct order. -% 2012-08-08 / Nichlas Sander / Added calculations of path efficiency. -% 2012-10-05 / Joel Falk-Dahlin / Changed ApplyControl to work with new version -% Removed InitControl since is perfomed -% within the GUI -% 2012-10-05 / Joel Falk-Dahlin / Changed speed to be read from mainGUI -% handles. This way TAC-test works the same -% way as the realtime patRec. Changed so -% the predicted movement is outputed to -% mainGUI. -% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl -% 2012-11-23 / Joel Falk-Dahlin / Moved speeds to patRec from handles, -% added a tracker to keep track of the state space position during TAC-test -% trajectories can be plotted with -% GUI_SSPresentation -% Added ResetControl to make sure control -% is reinitialized between trials - -function success = TACTest(patRecX, handlesX) -clear global; - -%global speed -global time -global patRec; -global handles; -global tempData; - -global wantedMovementId; -global tacComplete; -global firstTacTime; -global startTimer; -global completionTime; -global selectionTime; -global selectionTimeA; -global nTW; -global recordedMovements; -global thresholdGUIData - -patRec = patRecX; -handles = handlesX; -pDiv = 2; %Event is fired every TW/value milliseconds, ie 100ms if TW = 200ms & pDiv = 2. -trials = str2double(get(handles.tb_trials,'String')); -reps = str2double(get(handles.tb_repetitions,'String')); -timeOut = str2double(get(handles.tb_executeTime,'String')); -allowance = str2double(get(handles.tb_allowance,'String')); -%speed = str2double(get(handles.tb_speed,'String')); -time = str2double(get(handles.tb_time,'String')); - -pause on; %Enable pausing - -tacComplete = 0; -firstTacTime = []; - -tacTest.patRec = patRec; -tacTest.sF = patRec.sF; -tacTest.tW = patRec.tW; -tacTest.trials = trials; -tacTest.nR = reps; -tacTest.timeOut = timeOut; - -% Is threshold (thOut) used? -if(isfield(patRec.patRecTrained,'thOut')); - %Threshold GUI init - thresholdGUI = GUI_Threshold; - thresholdGUIData = guidata(thresholdGUI); - set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); - xpatch = [1 1 0 0]; - ypatch = [0 0 0 0]; - for i=0:patRec.nOuts-1 - s = sprintf('movementSelector%d',i); - s0 = sprintf('thPatch%d',i); - s1 = sprintf('meter%d',i); - axes(thresholdGUIData.(s1)); - handles.patRecHandles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); - ylim(thresholdGUIData.(s1), [0 1]); - xlim('auto'); - set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); - if (size(patRec.mov(patRec.indMovIdx),1) < i+1); - set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); - else - set(thresholdGUIData.(s),'Value',i+1); - end - end -end - -% Initialize DAQ card -% Note: A function for DAQ selection will be required when more cards are -% added -if strcmp(patRec.dev,'ADH') - -else % at this point everything else is SBI (e.g.NI-USB6009) - chAI = zeros(1,8); - chAI(patRec.nCh) = 1; - % create the SBI - s = InitSBI_NI(patRec.sF,timeOut,chAI); - % Change the peek time - s.NotifyWhenDataAvailableExceeds = (patRec.sF*patRec.tW)/pDiv; % Max 0.05, or 20 times per second - %Add listener - lh = s.addlistener('DataAvailable', @TACTest_OneShot); - %Test the DAQ by ploting the data - %lh = s.addlistener('DataAvailable', @plotDataTest); -end - -%Initialise the control algorithm. -%patRec = InitControl(patRec); % No longer needed, initialization is performed inside the GUI - -% Start the test -tempData = []; - -com = handles.vre_Com; - -%Sends a value to set the TAC hand to ON. -fwrite(com,sprintf('%c%c%c%c','c',char(2),char(1),char(0))); -fread(com,1); - -fwrite(com,sprintf('%c%c%c%c','c',char(3),char(allowance),char(0))); -fread(com,1); - -TrackStateSpace('initialize',patRec,allowance); - -%Run through all the trials -for t = 1 : trials - %Create a random order for the wanted movements. - indexOrder = GetMovementCombination(handles.dofs,patRec.nOuts-1); - tacTest.combinations = size(indexOrder,1); - for r = 1 : reps - set(handles.txt_status,'String',sprintf('Trial: %d , Rep: %d.',t,r)); - - %Loop through all of the movements - for i = 1 : size(indexOrder,1) - completionTime = NaN; - selectionTime = NaN; - selectionTimeA = NaN; - startTimer = []; - recordedMovements = []; - tacComplete = 0; - nTW = 1; - wantedMovementId = []; - printName = ''; - - - %Reset the TAC hand. Own function? - fwrite(com,sprintf('%c%c%c%c','r','t',char(0),char(0))); - fread(com,1); - - fwrite(com,sprintf('%c%c%c%c','r','1',char(0),char(0))); - fread(com,1); - - %Get all random movements for this set of movements. - index = indexOrder(i,:); - - set(handles.txt_status,'String','Wait!'); - pause(2); - name = 'Wanted: '; - %distance = randi(5,1) * 15 + 50; - distance = 40; - for j = 1:length(index) - movementIndex = patRec.movOutIdx{index(j)}; - listOfMovements = handles.movList; - movement = listOfMovements(movementIndex); - name = strcat(name,movement.name,','); - printName = strcat(printName,upper(movement.name{1}(regexp(movement.name{1}, '\<.'))),','); - for temp_index = 1:distance - VREActivation(com, 1, [], movement.idVRE, movement.vreDir, 1); - end - wantedMovementId = [wantedMovementId; movementIndex]; - end - %Remove the last comma. Other way of solving it? - name{1}(end) = []; - - set(handles.txt_status,'String',name); - - TrackStateSpace('target',index, distance); % ONLY WORKS IF DISTANCE IS THE SAME IN ALL DOFS - - % Reset the controller between trials - patRec = ReInitControl(patRec); - - %Start the listener, to allow for movements. - s.startBackground(); - %Wait until the background firing is finished. - s.wait(); - - test.recordedMovements = recordedMovements; - test.completionTime = completionTime; - test.selectionTime = selectionTime; - test.selectionTimeA = selectionTimeA; - - %Record data, present it. - test.fail = isnan(completionTime); - - if(test.fail) - test.pathEfficiency = NaN; - else - test.pathEfficiency = TrackStateSpace('single'); - end - - test.movement = movement; - test.name = printName(1:end-1); %Use something else? - - %Save the data to the trialResult in each trial, repetitition - %and movement. - tacTest.trialResult(t,r,i) = test; - - tempData = []; - end - end -end - -tacTest.ssTracker = TrackStateSpace('read'); - - - -% Save test -[filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); -if isequal(filename,0) || isequal(pathname,0) - disp('User pressed cancel') -else - save([pathname,filename],'tacTest'); -end - -%Display results -tacTest = TacTestResults(tacTest); -end - -function TACTest_OneShot(src,event) -pTime = tic; -global patRec; -global handles; -global nTW; % Number of time windows evaluated -global fpTW; % First time window with any movement. -global dataTW; % Raw data from each time windows -global tempData; -%global speed; -global time; - -global wantedMovement; -global wantedMovementId; - -global completionTime; -global selectionTime; -global selectionTimeA; -global tacComplete; -global processingTime; -global firstTacTime; -global startTimer; -global recordedMovements; -global thresholdGUIData - -tempData = [tempData; event.Data]; - -if size(tempData,1) >= (patRec.sF * patRec.tW) - tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data - dataTW(:,:,nTW) = tData; % Save data for future analisys - - %Start counting processing time - processingTimeTic = tic; - - % General routine for RealtimePatRec - [outMov, outVector, patRec, handles.patRecHandles] = OneShotRealtimePatRec(tData, patRec, handles.patRecHandles, thresholdGUIData); - TrackStateSpace('move',outMov, patRec.control.currentDegPerMov); - -% %Signal processing -% tSet = SignalProcessing_RealtimePatRec(tData, patRec); -% -% % Only predict when signal is over floor noise? -% meanFeature1 = mean(tSet(1:size(patRec.nCh,2))); -% if meanFeature1 < (patRec.floorNoise(1)/1) -% outMov = patRec.nOuts; -% outVector = zeros(patRec.nOuts,1); -% else -% % One shoot PatRec -% [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); -% if outMov == 0 -% outMov = patRec.nOuts; -% end -% end -% -% -% % Apply Proportional control -% handles = 1ApplyProportionalControl(tData,patRec,handles); -% -% %Apply control algorithms. -% [patRec, outMov, handles] = ApplyControl(patRec, outMov, outVector, handles); -% -% % Update MainGUI to show outputed Mov -% set(handles.patRecHandles.lb_movements,'Value',outMov); -% drawnow; - - processingTime(nTW) = toc(processingTimeTic); - %Apply Majority Vote filtering of movements - %[patRec outMov] = MajorityVote(patRec,outMov); - - %Check whether to start timer for completionTime and selectionTime. - if isempty(startTimer) && isempty(find(outMov == patRec.nM)) - startTimer = tic; - fpTW = nTW; - end - %Ensure that on movement or recording of time is done after the TAC has - %completed. - - if ~tacComplete - %Get movement from the list of movements. - movement = handles.movList(outMov); - speed = patRec.control.currentDegPerMov(outMov); - - %Temporary time - if ~isempty(startTimer) - tempTime = toc(startTimer); - if isnan(selectionTime) && sum(ismember(outMov,wantedMovementId)) - selectionTime = tempTime+patRec.tW+processingTime(fpTW); - end - - if isnan(selectionTimeA) && sum(ismember(wantedMovementId, outMov)) - selectionTimeA = tempTime+patRec.tW+processingTime(fpTW); - end - - end - %Only add the recorded movement if we are not yet done. - - if(length(movement)>1) - name = movement(1).name; - for i = 2:length(movement) - name = strcat(name,',',movement(i).name); - end - else - name = movement.name; - end - set(handles.txt_status2,'String',name); - - for i = 1:length(outMov) - recordedMovements = [recordedMovements; movement(i).name, speed(i)]; - dof = movement(i).idVRE; - dir = movement(i).vreDir; - - if (VREActivation(handles.vre_Com,speed(i),[],dof,dir,0)) - if (isempty(firstTacTime)) - firstTacTime = tic; - else - heldTime = toc(firstTacTime); - if(heldTime > time) - set(handles.txt_status2,'String','Movement Completed!'); - completionTime = toc(startTimer); - completionTime = completionTime - time; - tacComplete = 1; - %Stop the acquisition and move on to the next movement. - src.stop(); - %Pause 1 second once the movement is completed. - pause(1); - %This means that the TAC-test is completed. This value - %is set so no more motion is completed. - else - set(handles.txt_status2,'String',sprintf('Movement reached. Hold for %0.02f more seconds.',time-heldTime)); - end - end - else - firstTacTime = []; - end - end - end - nTW = nTW + 1; -end +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% ------------------- Function Description ------------------ +% A TAC Test is performed using the VRE. It then uses the TacTestResult +% function to display the gathered data. +% +% The function is written in such a way that it requires the movement +% "rest" to run properly. +% --------------------------Updates-------------------------- +% [Contributors are welcome to add their email] +% 2012-06-07 / Nichlas Sander / Creation of TACTest +% 2012-08-08 / Nichlas Sander / Data is saved in correct order. +% 2012-08-08 / Nichlas Sander / Added calculations of path efficiency. +% 2012-10-05 / Joel Falk-Dahlin / Changed ApplyControl to work with new version +% Removed InitControl since is perfomed +% within the GUI +% 2012-10-05 / Joel Falk-Dahlin / Changed speed to be read from mainGUI +% handles. This way TAC-test works the same +% way as the realtime patRec. Changed so +% the predicted movement is outputed to +% mainGUI. +% 2012-10-26 / Joel Falk-Dahlin / Added ApplyProportionalControl +% 2012-11-23 / Joel Falk-Dahlin / Moved speeds to patRec from handles, +% added a tracker to keep track of the state space position during TAC-test +% trajectories can be plotted with +% GUI_SSPresentation +% Added ResetControl to make sure control +% is reinitialized between trials +% 2013-06-10 / Nichlas Sander / Changed the tracker used for state space +% tracking to one that is not limited to +% a set number of movements. +% 2015-02-02 / Enzo Mastinu / All this function has been re-organizated +% to be compatible with the functions +% placed into COMM/AFE folder. For more +% details read RecordingSession.m log. +% 2015-02-27 / Enzo Mastinu / Fix some bugs with the custom devices TAC +% test. + +% 20xx-xx-xx / Author / Comment on update + + + +function success = TACTest(patRecX, handlesX) + clear global; + + %global speed + global time + global patRec; + global handles; + global tempData; + + global wantedMovementId; + global tacComplete; + global firstTacTime; + global startTimer; + global completionTime; + global selectionTime; + global selectionTimeA; + global nTW; + global recordedMovements; + global thresholdGUIData + + patRec = patRecX; + handles = handlesX; + + pDiv = 2; %Event is fired every TW/value milliseconds, ie 100ms if TW = 200ms & pDiv = 2. + trials = str2double(get(handles.tb_trials,'String')); + reps = str2double(get(handles.tb_repetitions,'String')); + timeOut = str2double(get(handles.tb_executeTime,'String')); + allowance = str2double(get(handles.tb_allowance,'String')); + %speed = str2double(get(handles.tb_speed,'String')); + time = str2double(get(handles.tb_time,'String')); + + pause on; %Enable pausing + + tacComplete = 0; + firstTacTime = []; + + % Get needed info from patRec structure + tacTest.patRec = patRec; + tacTest.sF = patRec.sF; + % tacTest.tW = patRec.tW; + tacTest.trials = trials; + tacTest.nR = reps; + tacTest.timeOut = timeOut; + + sF = tacTest.sF; + nCh = length(patRec.nCh); + ComPortType = patRec.comm; + deviceName = patRec.dev; + + % Get sampling time + sT = tacTest.timeOut; + tW = sT/100; % Time window size + tWs = tW*sF; % Time window samples + + % Is threshold (thOut) used? + if(isfield(patRec.patRecTrained,'thOut')); + %Threshold GUI init + thresholdGUI = GUI_Threshold; + thresholdGUIData = guidata(thresholdGUI); + set(GUI_Threshold,'CloseRequestFcn', 'set(GUI_Threshold, ''Visible'', ''off'')'); + xpatch = [1 1 0 0]; + ypatch = [0 0 0 0]; + for i=0:patRec.nOuts-1 + s = sprintf('movementSelector%d',i); + s0 = sprintf('thPatch%d',i); + s1 = sprintf('meter%d',i); + axes(thresholdGUIData.(s1)); + handles.patRecHandles.(s0) = patch(xpatch,ypatch,'b','EdgeColor','b','EraseMode','normal','visible','on'); + ylim(thresholdGUIData.(s1), [0 1]); + xlim('auto'); + set(thresholdGUIData.(s),'String',patRec.mov(patRec.indMovIdx)); + if (size(patRec.mov(patRec.indMovIdx),1) < i+1); + set(thresholdGUIData.(s),'Value',size(patRec.indMovIdx,2)); + else + set(thresholdGUIData.(s),'Value',i+1); + end + end + end + + %Initialise the control algorithm. + %patRec = InitControl(patRec); % No longer needed, initialization is performed inside the GUI + + % Start the test + tempData = []; + + com = handles.vre_Com; + + %Sends a value to set the TAC hand to ON. + fwrite(com,sprintf('%c%c%c%c','c',char(2),char(1),char(0))); + fread(com,1); + + fwrite(com,sprintf('%c%c%c%c','c',char(3),char(allowance),char(0))); + fread(com,1); + + CurrentPosition('init',patRec,allowance, handles.movList); + TrackStateSpace('initialize',patRec,allowance); + + %Run through all the trials + for t = 1 : trials + %Create a random order for the wanted movements. + indexOrder = GetMovementCombination(handles.dofs,patRec.nOuts-1); + tacTest.combinations = size(indexOrder,1); + for r = 1 : reps + set(handles.txt_status,'String',sprintf('Trial: %d , Rep: %d.',t,r)); + + %Loop through all of the movements + for i = 1 : size(indexOrder,1) + completionTime = NaN; + selectionTime = NaN; + selectionTimeA = NaN; + startTimer = []; + recordedMovements = []; + tacComplete = 0; + nTW = 1; + wantedMovementId = []; + printName = ''; + + + %Reset the TAC hand. Own function? + fwrite(com,sprintf('%c%c%c%c','r','t',char(0),char(0))); + fread(com,1); + + fwrite(com,sprintf('%c%c%c%c','r','1',char(0),char(0))); + fread(com,1); + + %Get all random movements for this set of movements. + index = indexOrder(i,:); + + set(handles.txt_status,'String','Wait!'); + pause(2); + name = 'Wanted: '; + %distance = randi(5,1) * 15 + 50; + distance = 40; + for j = 1:length(index) + movementIndex = patRec.movOutIdx{index(j)}; + listOfMovements = handles.movList; + movement = listOfMovements(movementIndex); + name = strcat(name,movement.name,','); + printName = strcat(printName,upper(movement.name{1}(regexp(movement.name{1}, '\<.'))),','); + for temp_index = 1:distance + VREActivation(com, 1, [], movement.idVRE, movement.vreDir, 1); + end + wantedMovementId = [wantedMovementId; movementIndex]; + end + %Remove the last comma. Other way of solving it? + name{1}(end) = []; + + set(handles.txt_status,'String',name); + + CurrentPosition('target',index, distance); + TrackStateSpace('target',index, distance); % ONLY WORKS IF DISTANCE IS THE SAME IN ALL DOFS + + + % Reset the controller between trials + patRec = ReInitControl(patRec); + + cData = zeros(tWs,nCh); + if strcmp (ComPortType, 'NI') + + % Init SBI + sCh = 1:nCh; + s = InitSBI_NI(sF,sT,sCh); + s.NotifyWhenDataAvailableExceeds = tWs; % PEEK time + lh = s.addlistener('DataAvailable', @TACTest_OneShot); + + % Start DAQ + s.startBackground(); % Run in the backgroud + + if ~s.IsDone % check if is done + s.wait(); + end + delete(lh); + + %%%%% Real Time PatRec with other custom device %%%%% + else + + % Prepare handles for next function calls + handles.deviceName = deviceName; + handles.ComPortType = ComPortType; + if strcmp (ComPortType, 'COM') + handles.ComPortName = patRec.comn; + end + handles.sF = sF; + handles.sT = sT; + handles.nCh = nCh; + handles.sTall = sT; + handles.t_msg = handles.txt_status; + + % Connect the chosen device, it returns the connection object + obj = ConnectDevice(handles); + + % Set the selected device and Start the acquisition + SetDeviceStartAcquisition(handles, obj); + handles.CommObj = obj; + handles.success = 0; + + for timeWindowNr = 1:sT/tW + cData = Acquire_tWs(deviceName, obj, nCh, tWs); % acquire a new time window of samples + acquireEvent.Data = cData; + TACTest_OneShot(0, acquireEvent); + if handles.success + % if the previous movement was "success" we can + % stop this acquisition and pass to the next + break + end + end + % Stop acquisition + StopAcquisition(deviceName, obj); + end + + + test.recordedMovements = recordedMovements; + test.completionTime = completionTime; + test.selectionTime = selectionTime; + test.selectionTimeA = selectionTimeA; + + %Record data, present it. + test.fail = isnan(completionTime); + + test.allowance = allowance; + test.distance = distance; + + if(test.fail) + test.pathEfficiency = NaN; + else + %This is not used for path efficiency any longer + %test.pathEfficiency = TrackStateSpace('single'); + test.pathEfficiency = CurrentPosition('get'); + end + + test.movement = listOfMovements(wantedMovementId); + test.name = printName(1:end-1); %Use something else? + + %Save the data to the trialResult in each trial, repetitition + %and movement. + tacTest.trialResult(t,r,i) = test; + + tempData = []; + end + end + end + + tacTest.ssTracker = TrackStateSpace('read'); + + % Save test + [filename, pathname] = uiputfile({'*.mat','MAT-files (*.mat)'},'Save as', 'Untitled.mat'); + if isequal(filename,0) || isequal(pathname,0) + disp('User pressed cancel') + else + save([pathname,filename],'tacTest'); + end + + %Display results + tacTest = TacTestResults(tacTest); +end + + + +function TACTest_OneShot(src,event) + pTime = tic; + global patRec; + global handles; + global nTW; % Number of time windows evaluated + global fpTW; % First time window with any movement. + global dataTW; % Raw data from each time windows + global tempData; + %global speed; + global time; + + global wantedMovement; + global wantedMovementId; + + global completionTime; + global selectionTime; + global selectionTimeA; + global tacComplete; + global processingTime; + global firstTacTime; + global startTimer; + global recordedMovements; + global thresholdGUIData + + tempData = [tempData; event.Data]; + + if size(tempData,1) >= (patRec.sF * patRec.tW) + tData = tempData(end-patRec.sF*patRec.tW+1:end,:); %Copy the temporal data to the test data + dataTW(:,:,nTW) = tData; % Save data for future analisys + + %Start counting processing time + processingTimeTic = tic; + + % General routine for RealtimePatRec + [outMov, outVector, patRec, handles.patRecHandles] = OneShotRealtimePatRec(tData, patRec, handles.patRecHandles, thresholdGUIData); + TrackStateSpace('move',outMov, patRec.control.currentDegPerMov); + CurrentPosition('move',outMov, patRec.control.currentDegPerMov); + + % %Signal processing + % tSet = SignalProcessing_RealtimePatRec(tData, patRec); + % + % % Only predict when signal is over floor noise? + % meanFeature1 = mean(tSet(1:size(patRec.nCh,2))); + % if meanFeature1 < (patRec.floorNoise(1)/1) + % outMov = patRec.nOuts; + % outVector = zeros(patRec.nOuts,1); + % else + % % One shoot PatRec + % [outMov, outVector] = OneShotPatRecClassifier(patRec, tSet); + % if outMov == 0 + % outMov = patRec.nOuts; + % end + % end + % + % + % % Apply Proportional control + % handles = 1ApplyProportionalControl(tData,patRec,handles); + % + % %Apply control algorithms. + % [patRec, outMov, handles] = ApplyControl(patRec, outMov, outVector, handles); + % + % % Update MainGUI to show outputed Mov + % set(handles.patRecHandles.lb_movements,'Value',outMov); + % drawnow; + + processingTime(nTW) = toc(processingTimeTic); + %Apply Majority Vote filtering of movements + %[patRec outMov] = MajorityVote(patRec,outMov); + + %Check whether to start timer for completionTime and selectionTime. + if isempty(startTimer) && isempty(find(outMov == patRec.nM)) + startTimer = tic; + fpTW = nTW; + end + %Ensure that on movement or recording of time is done after the TAC has + %completed. + + if ~tacComplete + %Get movement from the list of movements. + movement = handles.movList(outMov); + speed = patRec.control.currentDegPerMov(outMov); + + %Temporary time + if ~isempty(startTimer) + tempTime = toc(startTimer); + if isnan(selectionTime) && sum(ismember(outMov,wantedMovementId)) + selectionTime = tempTime+patRec.tW+processingTime(fpTW); + end + + if isnan(selectionTimeA) && sum(ismember(wantedMovementId, outMov)) + selectionTimeA = tempTime+patRec.tW+processingTime(fpTW); + end + + end + %Only add the recorded movement if we are not yet done. + + if(length(movement)>1) + name = movement(1).name; + for i = 2:length(movement) + name = strcat(name,',',movement(i).name); + end + else + name = movement.name; + end + set(handles.txt_status2,'String',name); + + performedMovements = []; + + for i = 1:length(outMov) + performedMovements = [performedMovements, {movement(i), speed(i)}]; + dof = movement(i).idVRE; + dir = movement(i).vreDir; + + if (VREActivation(handles.vre_Com,speed(i),[],dof,dir,0)) + if (isempty(firstTacTime)) + firstTacTime = tic; + else + heldTime = toc(firstTacTime); + if(heldTime > time) + set(handles.txt_status2,'String','Movement Completed!'); + completionTime = toc(startTimer); + completionTime = completionTime - time; + tacComplete = 1; + %Stop the acquisition and move on to the next movement. + if strcmp (handles.ComPortName, 'NI') + src.stop(); + else + handles.success = 1; + end + %Pause 1 second once the movement is completed. + pause(1); + %This means that the TAC-test is completed. This value + %is set so no more motion is completed. + else + set(handles.txt_status2,'String',sprintf('Movement reached. Hold for %0.02f more seconds.',time-heldTime)); + end + end + else + firstTacTime = []; + end + end + recordedMovements = [recordedMovements; {performedMovements}]; + end + nTW = nTW + 1; + end end \ No newline at end of file diff --git a/VRE/TrackStateSpace.m b/VRE/TrackStateSpace.m index b1acdd5..a4b5e14 100644 --- a/VRE/TrackStateSpace.m +++ b/VRE/TrackStateSpace.m @@ -1,146 +1,146 @@ -% ---------------------------- Copyright Notice --------------------------- -% This file is part of BioPatRec © which is open and free software under -% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for -% the full license governing this code and copyrights. -% -% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and -% Chalmers University of Technology. All authors’ contributions must be kept -% acknowledged below in the section "Updates % Contributors". -% -% Would you like to contribute to science and sum efforts to improve -% amputees’ quality of life? Join this project! or, send your comments to: -% maxo@chalmers.se. -% -% The entire copyright notice must be kept in this or any source file -% linked to BioPatRec. This will ensure communication with all authors and -% acknowledge contributions here and in the project web page (optional). -% -% -------------------------- Function Description ------------------------- -% Function to track the state space position of the system during TAC-test -% The results can be viewed in GUI_SSPresentation later. -% -% TrackStateSpace('initialize',patRec,allowance) - Initializes all -% parameters needed to keep track of the state space system. Should be -% executed before TAC-test starts -% -% TrackStateSpace('target', movIndex, distance) - Creates a target position -% in state space. movIndex should be the patRec.movOutIdx, that -% corresponds to the targeted motion, distance a number that sets the -% distance to the target in all DoFs. -% -% TrackStateSpace('move', outMov, speeds) - Moves the system in state space -% -% ssTracker = TrackStateSpace('read') - Return a structure containing all -% the state space information. -% -% ------------------------- Updates & Contributors ------------------------ -% [Contributors are welcome to add their email] -% 2012-11-23 / Joel Falk-Dahlin / Creation -% 20xx-xx-xx / Author / Comment on update - -function ssObj = TrackStateSpace(varargin) - -persistent classifiers controllers controlParams movMatrix ssTargets ssTrajectories allowance - -if ischar(varargin{1}) - - if strcmpi(varargin{1},'initialize') - - patRec = varargin{2}; - allowance = varargin{3}; - - movMatrix = CreateMovMatrix(patRec); - ssTargets = []; - ssTrajectories = []; - - classifiers = {patRec}; - - if isfield(patRec,'controlAlg') - - controllers = patRec.controlAlg.name; - controlParams = {cell(1,1)}; - params = fieldnames(patRec.controlAlg.parameters); - paramVec = []; - for i = 1:length(params) - paramName = params(i); - paramValue = patRec.controlAlg.parameters.(params{i}); - paramVec = [paramVec; paramName, {paramValue}]; - end - controlParams{1}{1} = paramVec; - - else - controllers = {'None'}; - controlParams = {{[]}}; - end - - elseif strcmpi(varargin{1},'target') - - index = varargin{2}; - distance = varargin{3}; - - if length(index) > 1 - movement = sum( movMatrix(index,:) ); - else - movement = movMatrix(index,:); - end - - newTarget = movement.*distance; - ssTargets = [ssTargets, {newTarget}]; % Save the new target - - ssTrajectories = [ssTrajectories; {[0, 0, 0]}]; % Create new position - - elseif strcmpi(varargin{1},'move') - - ssTrajectory = ssTrajectories{end}; - ssPos = ssTrajectory(end,:); - outMov = varargin{2}; - speeds = varargin{3}; - -% outMovIdx = []; - -% for i = 1:length(classifiers{1}.movOutIdx) -% if length(outMov) == length(classifiers{1}.movOutIdx{i}) -% if classifiers{1}.movOutIdx{i} == outMov' -% outMovIdx = i; -% break; -% end -% end -% end -% -% if isempty(outMovIdx) -% outMovIdx = length(classifiers{1}.movOutIdx); -% end - - newPos = MoveSS(ssPos,movMatrix,outMov,speeds); % Calculate new position in state space - - newTrajectory = [ssTrajectory; newPos]; % Update the trajectory - ssTrajectories{end} = newTrajectory; % Save the trajectory - - elseif strcmpi(varargin{1},'read') - - ssObj.classifiers = classifiers; - ssObj.controllers = controllers; - ssObj.controlParams = controlParams; - - ssObj.ssTrajectories = ssTrajectories; - - ssObj.ssTargets = ssTargets; - ssObj.nReps = 1; - ssObj.allowance = allowance; - - elseif strcmpi(varargin{1},'single') - ssTrajectory = ssTrajectories{end}; - ssTarget = ssTargets{end}; - - - userPath = CalculatePathLength(ssTrajectory, ssTarget, allowance); - perfectPath = CalculatePathLength([0 0 0; ssTarget], ssTarget, allowance); - - %Will round the value to nearest value with accuracy of 3-decimal - %places. - ssObj = round((perfectPath / userPath)*1000) / 1000; - end - -else - +% ---------------------------- Copyright Notice --------------------------- +% This file is part of BioPatRec © which is open and free software under +% the GNU Lesser General Public License (LGPL). See the file "LICENSE" for +% the full license governing this code and copyrights. +% +% BioPatRec was initially developed by Max J. Ortiz C. at Integrum AB and +% Chalmers University of Technology. All authors’ contributions must be kept +% acknowledged below in the section "Updates % Contributors". +% +% Would you like to contribute to science and sum efforts to improve +% amputees’ quality of life? Join this project! or, send your comments to: +% maxo@chalmers.se. +% +% The entire copyright notice must be kept in this or any source file +% linked to BioPatRec. This will ensure communication with all authors and +% acknowledge contributions here and in the project web page (optional). +% +% -------------------------- Function Description ------------------------- +% Function to track the state space position of the system during TAC-test +% The results can be viewed in GUI_SSPresentation later. +% +% TrackStateSpace('initialize',patRec,allowance) - Initializes all +% parameters needed to keep track of the state space system. Should be +% executed before TAC-test starts +% +% TrackStateSpace('target', movIndex, distance) - Creates a target position +% in state space. movIndex should be the patRec.movOutIdx, that +% corresponds to the targeted motion, distance a number that sets the +% distance to the target in all DoFs. +% +% TrackStateSpace('move', outMov, speeds) - Moves the system in state space +% +% ssTracker = TrackStateSpace('read') - Return a structure containing all +% the state space information. +% +% ------------------------- Updates & Contributors ------------------------ +% [Contributors are welcome to add their email] +% 2012-11-23 / Joel Falk-Dahlin / Creation +% 20xx-xx-xx / Author / Comment on update + +function ssObj = TrackStateSpace(varargin) + +persistent classifiers controllers controlParams movMatrix ssTargets ssTrajectories allowance + +if ischar(varargin{1}) + + if strcmpi(varargin{1},'initialize') + + patRec = varargin{2}; + allowance = varargin{3}; + + movMatrix = CreateMovMatrix(patRec); + ssTargets = []; + ssTrajectories = []; + + classifiers = {patRec}; + + if isfield(patRec,'controlAlg') + + controllers = patRec.controlAlg.name; + controlParams = {cell(1,1)}; + params = fieldnames(patRec.controlAlg.parameters); + paramVec = []; + for i = 1:length(params) + paramName = params(i); + paramValue = patRec.controlAlg.parameters.(params{i}); + paramVec = [paramVec; paramName, {paramValue}]; + end + controlParams{1}{1} = paramVec; + + else + controllers = {'None'}; + controlParams = {{[]}}; + end + + elseif strcmpi(varargin{1},'target') + + index = varargin{2}; + distance = varargin{3}; + + if length(index) > 1 + movement = sum( movMatrix(index,:) ); + else + movement = movMatrix(index,:); + end + + newTarget = movement.*distance; + ssTargets = [ssTargets, {newTarget}]; % Save the new target + + ssTrajectories = [ssTrajectories; {[0, 0, 0]}]; % Create new position + + elseif strcmpi(varargin{1},'move') + + ssTrajectory = ssTrajectories{end}; + ssPos = ssTrajectory(end,:); + outMov = varargin{2}; + speeds = varargin{3}; + +% outMovIdx = []; + +% for i = 1:length(classifiers{1}.movOutIdx) +% if length(outMov) == length(classifiers{1}.movOutIdx{i}) +% if classifiers{1}.movOutIdx{i} == outMov' +% outMovIdx = i; +% break; +% end +% end +% end +% +% if isempty(outMovIdx) +% outMovIdx = length(classifiers{1}.movOutIdx); +% end + + newPos = MoveSS(ssPos,movMatrix,outMov,speeds); % Calculate new position in state space + + newTrajectory = [ssTrajectory; newPos]; % Update the trajectory + ssTrajectories{end} = newTrajectory; % Save the trajectory + + elseif strcmpi(varargin{1},'read') + + ssObj.classifiers = classifiers; + ssObj.controllers = controllers; + ssObj.controlParams = controlParams; + + ssObj.ssTrajectories = ssTrajectories; + + ssObj.ssTargets = ssTargets; + ssObj.nReps = 1; + ssObj.allowance = allowance; + + elseif strcmpi(varargin{1},'single') + ssTrajectory = ssTrajectories{end}; + ssTarget = ssTargets{end}; + + + userPath = CalculatePathLength(ssTrajectory, ssTarget, allowance); + perfectPath = CalculatePathLength([0 0 0; ssTarget], ssTarget, allowance); + + %Will round the value to nearest value with accuracy of 3-decimal + %places. + ssObj = round((perfectPath / userPath)*1000) / 1000; + end + +else + end \ No newline at end of file diff --git a/VRE/UpdateTAC/CalculateTacPath.m b/VRE/UpdateTAC/CalculateTacPath.m new file mode 100644 index 0000000..1e61580 --- /dev/null +++ b/VRE/UpdateTAC/CalculateTacPath.m @@ -0,0 +1,47 @@ +function tacTest = CalculateTacPath(tacTest) + s = size(tacTest.trialResult); + tacTest.allowance = 5; + tacTest.distance = 40; + + movements = InitMovements(); + + for trial = 1:s(1) %loop over each trial + for rep = 1:s(2) %loop over each repetition + for comb = 1:s(3) %loop over each combination + result = tacTest.trialResult(trial,rep,comb); + + %Set the correct movements from names. + names = regexp(result.name,',','split'); + movement = []; + for i = 1:length(names) + movement = [movement, GetMovementFromName(names(i),movements)]; + end + result.movement = movement; + + % Set recordedMovements correctly + maximumMovement = tacTest.patRec.control.maxDegPerMov(1); %Only get the first since they are all the same. + movementJumpSize = tacTest.patRec.control.controlAlg.parameters.rampLength; + movementJump = maximumMovement / movementJumpSize; + movementDecrease = tacTest.patRec.control.controlAlg.parameters.downCount * movementJump; + + maxId = 0; + for i = 1:length(movements) + if(movements(i).idVRE > maxId) + maxId = movements(i).idVRE; + end + end + + lastKnownSpeed = zeros(1,maxId); %An array that says last known speed of movements. + + for record = 1:length(result.recordedMovements) + newSpeeds = lastKnownSpeed; + currentMovement = GetMovementFromName(result.recordedMovements(record,1),movements); + currentSpeed = result.recordedMovements(record,2); + newSpeeds(currentMovement.idVRE) = currentSpeed; + end + + tacTest.trialResult(trial,rep,comb) = result; + end + end + end +end \ No newline at end of file diff --git a/VRE/UpdateTAC/GetMovementFromName.m b/VRE/UpdateTAC/GetMovementFromName.m new file mode 100644 index 0000000..bb86f8d --- /dev/null +++ b/VRE/UpdateTAC/GetMovementFromName.m @@ -0,0 +1,11 @@ +function movement = GetMovementFromName(name,movements) + + movement = movements(1); + name = ShortToName(name); + + for i = 1:length(movements) + if strcmp(movements(i).name,name) + movement = movements(i); + end + end +end \ No newline at end of file diff --git a/VRE/UpdateTAC/ShortToName.m b/VRE/UpdateTAC/ShortToName.m new file mode 100644 index 0000000..06738a3 --- /dev/null +++ b/VRE/UpdateTAC/ShortToName.m @@ -0,0 +1,23 @@ +function name = ShortToName(name) +if iscell(name) + name = name{1}; +end + switch name + case 'CH' + name = 'Close Hand'; + case 'OH' + name = 'Open Hand'; + case 'FH' + name = 'Flex Hand'; + case 'EH' + name = 'Extend Hand'; + case 'FE' + name = 'Flex Elbow'; + case 'EE' + name = 'Extend Elbow'; + case 'P' + name = 'Pronation'; + case 'S' + name = 'Supination'; + end +end \ No newline at end of file diff --git a/VRE/bin/Release/ogre.cfg b/VRE/bin/Release/ogre.cfg index 49fe7dc..b9c305c 100644 --- a/VRE/bin/Release/ogre.cfg +++ b/VRE/bin/Release/ogre.cfg @@ -1,13 +1,13 @@ -Render System=OpenGL Rendering Subsystem - -[OpenGL Rendering Subsystem] -Colour Depth=32 -Display Frequency=N/A -FSAA=0 -Fixed Pipeline Enabled=Yes -Full Screen=No -RTT Preferred Mode=FBO -VSync=No -VSync Interval=1 -Video Mode=1024 x 768 -sRGB Gamma Conversion=No +Render System=OpenGL Rendering Subsystem + +[OpenGL Rendering Subsystem] +Colour Depth=32 +Display Frequency=N/A +FSAA=0 +Fixed Pipeline Enabled=Yes +Full Screen=No +RTT Preferred Mode=FBO +VSync=No +VSync Interval=1 +Video Mode=1024 x 768 +sRGB Gamma Conversion=No diff --git a/VRE/bin/Release/plugins.cfg b/VRE/bin/Release/plugins.cfg index 6e61c34..7573b1a 100644 --- a/VRE/bin/Release/plugins.cfg +++ b/VRE/bin/Release/plugins.cfg @@ -1,17 +1,17 @@ -# Defines plugins to load - -# Define plugin folder -PluginFolder=. - -# Define plugins -# Plugin=RenderSystem_Direct3D9 -# Plugin=RenderSystem_Direct3D11 -Plugin=RenderSystem_GL -# Plugin=RenderSystem_GLES -# Plugin=RenderSystem_GLES2 -# Plugin=Plugin_ParticleFX -# Plugin=Plugin_BSPSceneManager -# Plugin=Plugin_CgProgramManager -# Plugin=Plugin_PCZSceneManager -# Plugin=Plugin_OctreeZone -# Plugin=Plugin_OctreeSceneManager +# Defines plugins to load + +# Define plugin folder +PluginFolder=. + +# Define plugins +# Plugin=RenderSystem_Direct3D9 +# Plugin=RenderSystem_Direct3D11 +Plugin=RenderSystem_GL +# Plugin=RenderSystem_GLES +# Plugin=RenderSystem_GLES2 +# Plugin=Plugin_ParticleFX +# Plugin=Plugin_BSPSceneManager +# Plugin=Plugin_CgProgramManager +# Plugin=Plugin_PCZSceneManager +# Plugin=Plugin_OctreeZone +# Plugin=Plugin_OctreeSceneManager diff --git a/VRE/bin/Release/quakemap.cfg b/VRE/bin/Release/quakemap.cfg index f98c7d2..f76ad15 100644 --- a/VRE/bin/Release/quakemap.cfg +++ b/VRE/bin/Release/quakemap.cfg @@ -1,2 +1,2 @@ -Archive: ../../media/packs/chiropteraDM.pk3 -Map: maps/chiropteradm.bsp +Archive: ../../media/packs/chiropteraDM.pk3 +Map: maps/chiropteradm.bsp diff --git a/VRE/bin/Release/resources.cfg b/VRE/bin/Release/resources.cfg index a4218ae..39397e8 100644 --- a/VRE/bin/Release/resources.cfg +++ b/VRE/bin/Release/resources.cfg @@ -1,16 +1,16 @@ -# Resources required by the sample browser and most samples. -[Essential] - -# Common sample resources needed by many of the samples. -# Rarely used resources should be separately loaded by the -# samples which require them. -[Popular] -FileSystem=../media/materials/scripts -FileSystem=../media/materials/textures -FileSystem=../media/models - -[General] -FileSystem=../media - -# Materials for visual tests -[Tests] +# Resources required by the sample browser and most samples. +[Essential] + +# Common sample resources needed by many of the samples. +# Rarely used resources should be separately loaded by the +# samples which require them. +[Popular] +FileSystem=../media/materials/scripts +FileSystem=../media/materials/textures +FileSystem=../media/models + +[General] +FileSystem=../media + +# Materials for visual tests +[Tests] diff --git a/VRE/bin/Release/samples.cfg b/VRE/bin/Release/samples.cfg index 7eb97f7..e2879ed 100644 --- a/VRE/bin/Release/samples.cfg +++ b/VRE/bin/Release/samples.cfg @@ -1,37 +1,37 @@ -SampleFolder=. -SamplePlugin=Sample_BezierPatch -SamplePlugin=Sample_BSP -SamplePlugin=Sample_CameraTrack -SamplePlugin=Sample_CelShading -SamplePlugin=Sample_Character -SamplePlugin=Sample_Compositor -SamplePlugin=Sample_CubeMapping -SamplePlugin=Sample_DeferredShading -SamplePlugin=Sample_Dot3Bump -SamplePlugin=Sample_DynTex -SamplePlugin=Sample_DualQuaternion -SamplePlugin=Sample_FacialAnimation -SamplePlugin=Sample_Fresnel -SamplePlugin=Sample_Grass -SamplePlugin=Sample_Instancing -SamplePlugin=Sample_Isosurf -SamplePlugin=Sample_Lighting -SamplePlugin=Sample_NewInstancing -SamplePlugin=Sample_Ocean -SamplePlugin=Sample_ParticleGS -SamplePlugin=Sample_ParticleFX -SamplePlugin=Sample_ShaderSystem -SamplePlugin=Sample_Shadows -SamplePlugin=Sample_SkeletalAnimation -SamplePlugin=Sample_SkyBox -SamplePlugin=Sample_SkyDome -SamplePlugin=Sample_SkyPlane -SamplePlugin=Sample_Smoke -SamplePlugin=Sample_SphereMapping -SamplePlugin=Sample_SSAO -SamplePlugin=Sample_Terrain -SamplePlugin=Sample_TextureArray -SamplePlugin=Sample_TextureFX -SamplePlugin=Sample_Transparency -SamplePlugin=Sample_VolumeTex -SamplePlugin=Sample_Water +SampleFolder=. +SamplePlugin=Sample_BezierPatch +SamplePlugin=Sample_BSP +SamplePlugin=Sample_CameraTrack +SamplePlugin=Sample_CelShading +SamplePlugin=Sample_Character +SamplePlugin=Sample_Compositor +SamplePlugin=Sample_CubeMapping +SamplePlugin=Sample_DeferredShading +SamplePlugin=Sample_Dot3Bump +SamplePlugin=Sample_DynTex +SamplePlugin=Sample_DualQuaternion +SamplePlugin=Sample_FacialAnimation +SamplePlugin=Sample_Fresnel +SamplePlugin=Sample_Grass +SamplePlugin=Sample_Instancing +SamplePlugin=Sample_Isosurf +SamplePlugin=Sample_Lighting +SamplePlugin=Sample_NewInstancing +SamplePlugin=Sample_Ocean +SamplePlugin=Sample_ParticleGS +SamplePlugin=Sample_ParticleFX +SamplePlugin=Sample_ShaderSystem +SamplePlugin=Sample_Shadows +SamplePlugin=Sample_SkeletalAnimation +SamplePlugin=Sample_SkyBox +SamplePlugin=Sample_SkyDome +SamplePlugin=Sample_SkyPlane +SamplePlugin=Sample_Smoke +SamplePlugin=Sample_SphereMapping +SamplePlugin=Sample_SSAO +SamplePlugin=Sample_Terrain +SamplePlugin=Sample_TextureArray +SamplePlugin=Sample_TextureFX +SamplePlugin=Sample_Transparency +SamplePlugin=Sample_VolumeTex +SamplePlugin=Sample_Water diff --git a/VRE/bin/media/materials/scripts/Arm.material b/VRE/bin/media/materials/scripts/Arm.material index 438dd43..f0cc8df 100644 --- a/VRE/bin/media/materials/scripts/Arm.material +++ b/VRE/bin/media/materials/scripts/Arm.material @@ -1,16 +1,16 @@ -material Grey -{ - technique - { - pass - { - depth_bias 1 - diffuse 0.800000 0.800000 0.800000 - specular 0.500000 0.500000 0.500000 12.500000 - texture_unit - { - texture grey_image.jpg - } - } - } -} +material Grey +{ + technique + { + pass + { + depth_bias 1 + diffuse 0.800000 0.800000 0.800000 + specular 0.500000 0.500000 0.500000 12.500000 + texture_unit + { + texture grey_image.jpg + } + } + } +} diff --git a/VRE/bin/media/materials/scripts/tacArm.material b/VRE/bin/media/materials/scripts/tacArm.material index 5b14bbe..6e6fbcc 100644 --- a/VRE/bin/media/materials/scripts/tacArm.material +++ b/VRE/bin/media/materials/scripts/tacArm.material @@ -1,18 +1,18 @@ -material Green -{ - technique - { - pass - { - scene_blend alpha_blend - depth_bias 0 - diffuse vertexcolour - specular 0.500000 0.500000 0.500000 12.500000 - texture_unit - { - texture green_image.jpg - alpha_op_ex source1 src_manual src_current 0.5 - } - } - } -} +material Green +{ + technique + { + pass + { + scene_blend alpha_blend + depth_bias 0 + diffuse vertexcolour + specular 0.500000 0.500000 0.500000 12.500000 + texture_unit + { + texture green_image.jpg + alpha_op_ex source1 src_manual src_current 0.5 + } + } + } +}