Find specific area of a rotational speed curve

3 views (last 30 days)
I'm writing a script that evaluates a rotational speed curve (see "fig_rpmMsh.png") that has been measured at the main shaft of a shredder machine. To obtain this somewhat smooth curve I've already used a sgolay filter. In the curve you can see that the operating speed of the main shaft is ~24 RPM, respectively ~ -24 RPM if the shredder is reversing.
For further calculations I need to group some of the areas of the curve. I've found a way to group the speeds around 0 RPM, around the operating speeds (i.e. ~24 RPM and ~ -24 RPM) and when speed drops occur, but I'm struggling to find a way to group the idle speeds (see "fig_rpmMsh_idleSpeed.png").
Until now I've tried to compute the first and second derivatives of this curve and further I've tried to formulate a criterion which matches the start and the end of these areas. So far I came to no useful result.
In the appendix I've added the time array ('') and the rotational speed array ('').
I really start to run out of ideas and I would appreciate any help. Thank you!
I'm using the following tools:
MATLAB Version 9.12 (R2022a)
Optimization Toolbox Version 9.3 (R2022a)
Signal Processing Toolbox Version 9.0 (R2022a)
Best Regards

Accepted Answer

Mathieu NOE
Mathieu NOE on 11 Jan 2023
hi Konrad
tried a few things
first I think you could drastically reduce your sampling rate by a factor 1000 !
this graph does not need more than 1000 samples and you have over 800,000 samples acquired !!
the rest I let you discorver below
each individual portion (red segments) is stored in data_store (cell array) for further processing if needed
all the best
t = readmatrix('t.csv');
rpmMsh = readmatrix('rpmMsh.csv');
% decimation
decim_fact = 1000; %
samples = numel(t);
ind = decim_fact/2:decim_fact:samples;
t = t(ind);
rpmMsh = rpmMsh(ind);
% smooth again
rpmMsh_s = smoothdata(rpmMsh,'gaussian',10);
[dy, ddy] = firstsecondderivatives(t,rpmMsh_s);
% lower and hugher limits for idle RPM
low = 4;
high = 12;
ind = (dy>low & dy<high);
% find contiguous buffers (eliminate spurious isolated data)
min_contiguous_samples = 8;
% now define start en end point of "red" segments
[begin,ends] = find_start_end_group(ind);
length_ind = ends - begin;
ind2= length_ind>min_contiguous_samples; % check if their length is valid (above min_contiguous_samples value)
begin = begin(ind2); % selected points
ends = ends(ind2); % selected points
hold on
for ci = 1:length(begin)
ind = (begin(ci):ends(ci));
xx = t(ind);
yy = rpmMsh(ind);
data_store{ci} = [xx(:) yy(:)]; % 2 columns : time / data
hold off
legend('raw data decimated','smoothed','extracted');
function [begin,ends] = find_start_end_group(ind)
% This locates the beginning /ending points of data groups
D = diff([0;ind(:);0]);
begin = find(D == 1);
ends = find(D == -1) - 1;
function [dy, ddy] = firstsecondderivatives(x,y)
% The function calculates the first & second derivative of a function that is given by a set
% of points. The first derivatives at the first and last points are calculated by
% the 3 point forward and 3 point backward finite difference scheme respectively.
% The first derivatives at all the other points are calculated by the 2 point
% central approach.
% The second derivatives at the first and last points are calculated by
% the 4 point forward and 4 point backward finite difference scheme respectively.
% The second derivatives at all the other points are calculated by the 3 point
% central approach.
n = length (x);
dy = zeros;
ddy = zeros;
% Input variables:
% x: vector with the x the data points.
% y: vector with the f(x) data points.
% Output variable:
% dy: Vector with first derivative at each point.
% ddy: Vector with second derivative at each point.
dy(1) = (-3*y(1) + 4*y(2) - y(3)) / (2*(x(2) - x(1))); % First derivative
ddy(1) = (2*y(1) - 5*y(2) + 4*y(3) - y(4)) / (x(2) - x(1))^2; % Second derivative
for i = 2:n-1
dy(i) = (y(i+1) - y(i-1)) / (x(i+1) - x(i-1));
ddy(i) = (y(i-1) - 2*y(i) + y(i+1)) / (x(i-1) - x(i))^2;
dy(n) = (y(n-2) - 4*y(n-1) + 3*y(n)) / (2*(x(n) - x(n-1)));
ddy(n) = (-y(n-3) + 4*y(n-2) - 5*y(n-1) + 2*y(n)) / (x(n) - x(n-1))^2;
Mathieu NOE
Mathieu NOE on 12 Jan 2023
Moved: Adam Danz on 12 Jan 2023
hello Konrad
yes I didn't use the second derivative even I looked at it to see if it was interesting but indeed not really.
the code can be further enhanced and modified according to your own ideas ... this is just a starting point
all the best for the future

Sign in to comment.

More Answers (0)


Find more on Time-Frequency Analysis in Help Center and File Exchange




Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!