Hello everyone,
for my research project I'm trying to let a robot move a sine curve (only in a z axis up and down). The problem is, that if two points are very close to each other (i.e. 0.2mm) the robot gets really slow, stays still for like half a second and then moves on, so the total time isn't the same. Now in my code I'm trying to delete every second point (and then double the time in between these points in RoboDK), but I can't figure out how to do this in an if loop. Like really important is, that the extreme values must be kept, so the robot can move to the endpositions and I'll get a sine curve.
Here's my code so far:
clear;
A = 50;
t = 0.05;
x = 0:0.05:10*pi;
y = -A*sin(x) + 389.387; %389.387 is the start position of the robot, he only moves in z-axis
T = (1:length(x))*t;
figure(1)
plot(T,y,'.')
xlabel('time')
ylabel('distance')
hold on
%%
newpoints = zeros(1,(length(y)));
newpoints(1,1) = y(1,1);
for i = 3:length(y)
if (y(i) - y(i-1)) < 0.2 %Check, if distance under 0.2mm
if (sign(y(i)-y(i-1))) ~= (sign((y(i-1)-y(i-2)))) %Check if it's an extreme value, because of sign change
newpoints(i-1) = y(i-1);
elseif i == 1:2:length(y) %This is where the trouble begins, I dont't know how to tell Matlab to delete every second point
newpoints(i-1) = [];
end
end
end
figure(1)
plot(T,newpoints,'r.')
xlabel('time')
ylabel('distance')
I'm using Matlab R2020 for academic use. I'd be really glad if you guys could help me out!

 채택된 답변

Adam Danz
Adam Danz 2021년 5월 3일
편집: Adam Danz 2021년 5월 3일

1 개 추천

To delete every second element in an array starting with element #2,
x(2:2:end) = [];
or starting with element #1,
x(1:2:end) = [];
But to ensure you never delete the endpoints,
x(2:2:end-1) = [];
To preserve indexing, you can insert NaN values instead of removing elements,
x(2:2:end) = nan;
x(1:2:end) = nan;
x(2:2:end-1) = nan;

댓글 수: 7

Bruce Rogers
Bruce Rogers 2021년 5월 3일
Thanks for your help Adam, but this isn't working for me in my if loop. I'll get the same array
Adam Danz
Adam Danz 2021년 5월 3일
편집: Adam Danz 2021년 5월 3일
Why do you need to use a loop? Just to clarify, x in my answer is just a generic variable and has nothing to do with the variables in your code.
If you want to remove every 2nd element of an array, this is the most effective method. If that's not the goal, I'll need a clearer explanation.
Looking at your loop, it appears that it can be vectorized so there's no need to use a loop. But before I can help you replace the loop with a few lines of code, if that's what you want to do, it would be helpful to have a clearer understanding of the goal.
For example, this condition,
if (y(i) - y(i-1)) < 0.2
could be replaced by ,
z = -diff(y) < 0.2
Hello Adam,
I need a loop to clarify if the distance between two points is nearer than 0.2mm. This is in the red cycled area.
z = -diff(y) < 0.2
is a really good idea, so i only have to compare ones and zeros. I'll change the code and accept your answer, if this solved my problem.
Scott MacKenzie
Scott MacKenzie 2021년 5월 4일
편집: Scott MacKenzie 2021년 5월 4일
A picture is worth a thousand words! I really wasn't sure what you were after until I saw your plot. Here's something that might help. Really, it's just a combination of what Adam proposed and your visualization, except that I'm using the pythagorean distance between points, which might make more sense.
% your example data
x = 0:0.05:10*pi;
y = -50*sin(x) + 389.387;
threshold = 0.8; % distance from neighbor threshold
z = sqrt(diff(x).^2 + diff(y).^2); % distance between points
lessThan = z < threshold; % points below threshold (logical)
% default point color (grey)
c = repmat([.2 .2 .2], length(x), 1);
c(lessThan, 1) = 1; % red for points below threshold
scatter(x, y, 5, c, 'filled'); % show points close to their neighbour
So, sequences of 1s in the lessThan vector are the logical indices of the points your are concerned with. These are the red points above.
Bruce Rogers
Bruce Rogers 2021년 5월 4일
Thanks Scott! That's exactly what I needed, it helped me a lot. I think for my next question I'll use a picture ^^
Adam Danz
Adam Danz 2021년 5월 4일
편집: Adam Danz 2021년 5월 4일
> I need a loop to clarify if the distance between two points is nearer than 0.2mm.
Scott's advice is spot-on.
Alternatively, instead of
z = sqrt(diff(x).^2 + diff(y).^2);
you could use,
z = hypot(diff(x), diff(y));
which is probably the same thing in Scott's approach (we don't have access to the hypot code) but the documentation claims that hypot avoids underflow and overflow. I compared both approaches and they are equally speedy and the difference in results is less than 4.4409e-16 which is just roundoff error.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Scott MacKenzie
Scott MacKenzie 2021년 5월 3일
편집: Scott MacKenzie 2021년 5월 3일

0 개 추천

As per your question (Delete every second element in array) ...
x = 1:10
y = x(rem(x,2)==1)
Output:
x =
1 2 3 4 5 6 7 8 9 10
y =
1 3 5 7 9

댓글 수: 2

Bruce Rogers
Bruce Rogers 2021년 5월 3일
Hello Scott, thanks for your answer, the problem is, that I don't know how to run this in an if loop, in my case this doesn't work and I get the same array
Philipp Brogli
Philipp Brogli 2024년 1월 12일
The problem with this aproach is that it just removes any value that is divideable by 2. If you have a different vector x, for example [1,3,5,7,9], then it wouldn't work anymore.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 MATLAB Coder에 대해 자세히 알아보기

질문:

2021년 5월 3일

댓글:

2024년 1월 12일

Community Treasure Hunt

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

Start Hunting!

Translated by