Finding consecutive number and only keeping the nearest to a number

3 views (last 30 days)
Hello,
I got some data from a robot movement and now I want to find the nearest of the consecutive numbers to the number 389.387. This is my code so far, but I have no idea how to do the "closest to 389.387" loop. Sadly, there is no point with 389.387, so I can't just search for this number... Look at the picture attached, the red circled area is where the numbers near 389.387 are. I'm grateful for your ideas!
for i = 1:length(z_irl)
if z_irl(i) > 389.2 && z_irl(i) < 389.5 % z_irl is the whole robot movement and I tried to only keep the
% numbers near 389.387
y_temp_r(i) = z_irl(i);
end
%y_temp(i) = 0;
end
[row_r,col_r,value_r]=find(y_temp_r); %with this line I get all the information needed of the numbers near 389.387
smallnr = zeros(1,b); %b is 10, there should only be 10 Numbers near 389.387
for i = 1:length(row_r)
difference(i) = abs(value_r(i) - 389.387);
end
i = 2;
if diff(row_r)==1 %and this is where I don't know how to continue, I dont know how to
%do a <> query only for the consecutive numbers, it's
if difference(i-1) < difference(i) %driving me insane (ノಠ益ಠ)ノ彡┻━┻ and I think i need two counters,
%one for counting the line of the smallest number and one for counting
smallnumber(i-1) = difference(i-1); %the number of the consecutive number
else
smallnumber(i-1) = difference(i);
end
i = i + 1;
end
I'm using Matlab R2020b for academic use.

Accepted Answer

Image Analyst
Image Analyst on 4 Jun 2021
Bruce, I'd probably use findpeaks on the difference between your signal and your constant:
[~, indexesOfPeaks] = findpeaks(-abs(y - yConstant))
yCrossings = y(indexesOfPeaks)
Here's a full demo:
t = linspace(0, 42, 500);
period = 42/5;
y = -100 * sin(2 * pi * t / period) + 389.387;
subplot(2, 1, 1);
plot(t, y, 'b-', 'LineWidth', 2);
grid on;
title('Original Signal');
xlabel('Time');
ylabel('Distance');
yConstant = 389.387;
yDiff = -abs(y - yConstant);
% Let's see it.
subplot(2, 1, 2);
plot(t, yDiff, 'b-', 'LineWidth', 2);
grid on;
title('Difference from the constant');
xlabel('Time');
ylabel('Distance');
% Find the peaks
[~, indexesOfPeaks] = findpeaks(yDiff)
yCrossings = y(indexesOfPeaks)
% Plot over original signal
subplot(2, 1, 1);
hold on;
plot(t(indexesOfPeaks), yCrossings, 'r.', 'MarkerSize', 15);
hold off;
You could also try ismembertol() but that might possibly give you multiple indexes at each location and you'd have to detect that and pick the closest one.

More Answers (1)

Bruce Rogers
Bruce Rogers on 7 Jun 2021
Edited: Bruce Rogers on 7 Jun 2021
Hello Image Analyst,
this solution is really nice and almost working fine for me. The problem is, that the signal is not really a sine curve, it's the up and down movement of a robotarm in the z-axis, so that your programm gives me more yCrossings. In the figure you can see how it looks like. Also, I attached the whole z-axis movement (z_axis.txt), so you can see the original signal.
With
rowsToDelete = yCrossings < 380 | yCrossings > 420;
yCrossings(rowsToDelete) = [];
I managed to remove the marked values at the turning points, but in the beginning there are three marked values, which is wrong. I'd like to use the last one as the first of the 10 "389.387" values.

Products

Community Treasure Hunt

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

Start Hunting!