Finding upward intervals in box movement
    3 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Dominik
 el 19 de Oct. de 2024
  
    
    
    
    
    Comentada: Dominik
 el 22 de Oct. de 2024
            I am trying to analyse EMG und kinematic data while lifting a box. I only need to evaluate the data while the box is moving up. But i have problems with setting up the intervals. The intervals often start too early (upper plot) while the box still stands on the floor.  I have the kinematic data attached. The z coordinate ist in BoxZ. 
My idea was to find the index for the peaks and to define the upwards movement. After that i evaluated the min in each interval and safed the frame intervals in a cell. I also calculated the Frames for the Emg Data, which was recorded with a different rate.
One of the problems is, that the box gets dropped on a wooden floor, so there is a slight bump after each repetitions. I tried to fix that problem with the while-loop.
As you can see in the image, there also seem to be some jumps in the frames (upper plot: box-movement for 1 interval, lower plot: ankle-degree in the given interval).
Hopefully someone can help me with this problem. 
%Ziel Funktion: Aufteilen der Bewegungsintervalle in die einzelnen
%Aufwärtsbewegungen. Ausgabe sind die zugehörigen Frames
function [frame_intervalle, sec_intervalle, frame_intervalle_EMG] = ...
       aufteilung_intervalle(box_trial)
%Auslesen der z-Koordinate von Box
box_z = box_trial(:,3);
Fs_Qualisys = 340; %Framerate von 340 Hertz
Fs_EMG = 2000;
%Basishöhe definiert durch erste 10 Frames des Trials
frames_1to10 = box_z(1:10,1);
basis_box_z = mean(frames_1to10);
%Bewegung beginnt ab +2 Standardabweichungen
bewegung = box_z > basis_box_z + 2*std(frames_1to10);
%Aufwärtsbewegung einbauen durch for-Schleife
len = length(box_z);
aufwaerts = zeros([len,1]);
for n = 2 : len
    %Vorheriges Element kleiner als das jetzige?
    aufwaerts(n) = (box_z(n) > box_z(n-1));
end
%Beide Bedingungen verbinden
bewegung_hoch = (bewegung == 1) & (aufwaerts == 1);
%Finde Frame in x-Variable mit Ende Aufwärtsbewegung (def als Maximum)
[~, x_max_box] = findpeaks(box_z, ...
    MinPeakDistance = 1000, MinPeakHeight = 300);
%for-Schleife um Matrix mit Spaltenvektoren als Zeit 
%zwischen Maxima (zugehörige x-Werte)
intervalle = zeros([len,15]);
for m = 2:15
    for n = 1 : len
        intervalle(n,1) = n < x_max_box(1);
        intervalle(n,m) = (x_max_box(m-1) < n) & ...
            (n < x_max_box(m));
    end
end
%Unterteilen der Aufwärtsbewegungen in einzelne Wiederholungen
intervall_aufwaerts = intervalle & bewegung_hoch;
%Sicherstellen, dass Bewegung tatsächlich am Boden anfängt.
index = zeros([1,15]);
start = zeros([1,15]);
start_index = zeros([1,15]);
kontrolle = 10;
for k = 1:15
    %Finde Minimum in jeder Aufwärtsbewegung
    [~, index(k)] = min(box_z(intervall_aufwaerts(:,k)));
    %Definiere Startwert für Aufwärtsbewegung
    start(k) = find(intervall_aufwaerts(:,k), 1, 'first');
    start_index(k) = start(k) + index(k);
    durchschnitt_folge = mean([box_z(start_index(k) +30),box_z(start_index(k)+40), ...
        box_z(start_index(k)+50)]);
    %Machmal wird Tiefpunkt erreicht durch unabsichtliches Absinken
    %der Holzplatte. Kontrolle
    while abs(box_z(start_index(k)) - durchschnitt_folge) < kontrolle ...
        | box_z(start_index(k)) < basis_box_z
        start_index(k) = start_index(k) +1;
    end
    %Setze alle Werte davor auf 0 (logical)
    intervall_aufwaerts(1:start_index(k), k) = 0;
end
%Vektor zum Bestimmen der Intervalle
zeit = (1:len)';
zeit_matrix = repmat(zeit, 1, 15);
%Bestimmen der Frames der Aufwärtsbewegung
%Abspeichern in cell
frame_intervalle = cell(1,15);
sec_intervalle = cell(1,15);
frame_intervalle_EMG = cell(1,15);
for col = 1:size(zeit_matrix,2)
    rowsWithOnes = intervall_aufwaerts(:, col);
    % Werte aus der aktuellen Spalte behalten, wo der logische Array 1 ist
    frame_intervalle{col} = zeit_matrix(rowsWithOnes, col);
    %Umrechnen der Frames in Sekunden zur Weiterverarbeitung in EMG
    sec_intervalle{col} = frame_intervalle{col}/Fs_Qualisys;
    frame_intervalle_EMG{col} = (min(round(sec_intervalle{col}*Fs_EMG)): ...
    max(round(sec_intervalle{col}*Fs_EMG)))';
end
end
0 comentarios
Respuesta aceptada
  Taylor
    
 el 21 de Oct. de 2024
        I would recommend looking at the findpeaks function. It includes some name-value arguments like MinPeakHeight that I think will help you better isolate the true peaks from the "drop" peaks.
Más respuestas (0)
Ver también
Categorías
				Más información sobre Statistics and Machine Learning Toolbox en Help Center y File Exchange.
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

