I'm having trouble with my code when I add an if condition to check if B_body(3) is less than 1e-5.
Without the if condition, everything works fine.
But when I add the if condition, I get a warning and B_body(3) values become NaN.
I've tried several solutions, but nothing works.
Any ideas on how to fix this?
epsilon=1e-5;
if abs(B_body(3))<epsilon
T_rw=[0;0;0];
else
T_rw = [0; 0; 1] * (B_body' * T_commanded) / (B_body(3));
end

댓글 수: 11

We don't have enough code to know what happens next, but almost certainly what then occurs after the T_rw vector is set to identically zero is that B_body(3) also becomes identically zero and then the first step after that you end up with a case of
0/0
ans = NaN
which is where the NaN comes from. Beyond that, all hope is lost.
You'll need some other special casing to deal with whatever is supposed to happend afterwards, but the model as written doesn't handle the case when whatever T_rw represents becomes identically zero.
Steven Lord
Steven Lord 2024년 8월 7일
But when I add the if condition, I get a warning
What is the full and exact text of the warning message? Please show us all the text displayed in orange in the Command Window. The exact text may be useful and/or necessary to determine what's going on and how to avoid the warning.
Rik
Rik 2024년 8월 7일
If you put your code in your question or a comment, you can run it. That way you can confirm we will see the same error as you.
As others rightly mentioned, looks like the issue might be arising from the division by B_body(3) when it is very close to zero which leads to division by zero which in turn might be the reason for NaNs.
To avoid this, you can add a small value (like delta) to the denominator to prevent division by zero. You can try this out:
epsilon = 1e-5;
delta = 1e-6;
if abs(B_body(3)) < epsilon
T_rw = [0; 0; 0];
else
T_rw = [0; 0; 1] * (B_body' * T_commanded) / (B_body(3) + delta);
end
This approach slightly modifies the calculation, so make sure it still meets your requirements. If precision is crucial, you might need to handle the code more carefully.
I hope this is beneficial to you. If you need further assistance, please feel free to reach out.
Stephen23
Stephen23 2024년 8월 8일
편집: Stephen23 2024년 8월 8일
"when it is very close to zero which leads to division by zero which in turn might be the reason for NaN"
Dividing zero by zero leads to NaN. Even dividing zero by the nearest value closest to zero (i.e. the smallest subnormal) does not produce NaN:
0/eps(0)
ans = 0
0/0
ans = NaN
Being "very close to zero" is not sufficient.
Sahas
Sahas 2024년 8월 8일
Thanks you @Stephen23 for clearing that out.
dpb
dpb 2024년 8월 8일
편집: dpb 2024년 8월 8일
And, just for good measure, anything nonzero divided by 0 produces a signed Inf, not NaN.
eps(0)/0
ans = Inf
realmax/0
ans = Inf
ADDENDUM:
(1)/(-0)
ans = -Inf
(-1/0)
ans = -Inf
(-1)/(-0)
ans = Inf
NOTA BENE: the sign is based on the sign of the quotient; the (-0) in the denominator is also significant. This can be helpful in some branch analyses...
And, just for good measure, anything nonzero divided by 0 produces Inf, not NaN
To be technically correct it produces an infinite value, not necessarily positive Inf.
y = (-1)/0
y = -Inf
There are three non-finite values in MATLAB: Inf, -Inf, and NaN. Those are the values for which the built-in isfinite function will return false, but only the first two will have isinf return true.
x = [1; Inf; -Inf; NaN; 5];
fin = isfinite(x);
infinite = isinf(x);
results = table(x, fin, infinite, VariableNames = ["value", "is finite", "is infinite"])
results = 5x3 table
value is finite is infinite _____ _________ ___________ 1 true false Inf false true -Inf false true NaN false false 5 true false
dpb
dpb 2024년 8월 8일
OK, Steven, you're correct...I didn't mean to imply all would return +Inf...I added the (I thought implied) "signed".... :)
Alexandra
Alexandra 2024년 8월 9일
Thank you all for your helpful suggestions and for taking the time to assist me with my question. I think I have finally found a solution that works for my needs.
You don't neceessarily have to divide by zero to get an infinite value, either...anything that would produce a result greater than the magnitude of realmax or less than realmin will do...division, multiplication or a function like an exponential with positive magnitude...
exp(709)
ans = 8.2184e+307
exp(710)
ans = Inf

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

답변 (0개)

카테고리

도움말 센터File Exchange에서 Data Type Identification에 대해 자세히 알아보기

태그

질문:

2024년 8월 7일

댓글:

dpb
2024년 8월 10일

Community Treasure Hunt

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

Start Hunting!

Translated by