Having trouble printing variables I use as inputs to a function.
1 view (last 30 days)
Show older comments
Okay, I'm having trouble getting Matlab to print variables out that I use as inputs to a function that are printing out NaN as the result.
0 Comments
Accepted Answer
Star Strider
on 19 Sep 2024
The problem is that the ‘mass’ value provided to ‘MyFun2’ is zero, since the value being passed to it is ‘m’ and not ‘mass’ and the result is iniitially values for the derivatives as NaN and the subsequent ones Inf.
Change ‘m’ to ‘mass’ in the ‘MyFun2’ call, and it works —
theta = 0;
phi = 0;
psi = 0;
Ctheta=cos(theta);
Cphi = cos(phi);
Cpsi = cos(psi);
Stheta = sin(theta);
Sphi = sin(phi);
Spsi = sin(psi);
Jx = 0.8244;
Jy= 1.135;
Jz = 1.759;
Jxz = 0.1204;
G = Jx*Jz-Jxz^2;
G1 = (Jxz*(Jx+Jy+Jz)/G);
G2 = (Jz*(Jz-Jy)+Jxz^2)/G;
G3 = Jz/G;
G4 = Jxz/G;
G5 = (Jz - Jx)/Jy;
G6 = Jxz/Jy;
G7 = ((Jx - Jy)*Jx +Jxz^2)/G;
G8 = Jx/G;
%mass = mass.
mass = 11;
l = 0;
m = 0;
n = 0;
p = 0;
q = 0;
r = 0;
u = 0;
v = 0;
w = 0;
%print values of the following
Ctheta
Cphi
Cpsi
Stheta
Sphi
Spsi
u
v
w
tRange = [0: 0.01:10];
[tSol,pnpepdAndrSol] = ode45(@(t,pnpepdAndr)myFun1(t,pnpepdAndr,Ctheta,Cphi,Cpsi,Stheta,Sphi,Spsi,u,v,w),tRange,[1,1,1]);
length(tSol)
tSol
pnpepdAndrSol
pnpepdAndrSol(20,3)
% [tSol,uvwAndrSol] = ode45(@(t,uvwAndr)myFun2(t,uvwAndr,p,q,r,u,v,w,m), tRange, [1,1,1]); % Previous
[tSol,uvwAndrSol] = ode45(@(t,uvwAndr)myFun2(t,uvwAndr,p,q,r,u,v,w,mass), tRange, [1,1,1]);
length(tSol)
tSol
uvwAndrSol
uvwAndrSol(20,3)
[tSol,phithetapsiAndrSol] = ode45(@(t,phithetapsiAndr)myFun3(t,phithetapsiAndr,p,q,r,phi,psi,theta), tRange, [1,1,1]);
length(tSol)
tSol
phithetapsiAndrSol
phithetapsiAndrSol(20,3)
[tSol,pqrAndrSol] = ode45(@(t,pqrAndr)myFun4(t,pqrAndr,p,q,r,l,m,n,Jx,G1,G2,G3,G4,G5,G6,G7,G8), tRange, [1,1,1]);
length(tSol)
tSol
pqrAndrSol
pqrAndrSol(20,3)
function d_pnpepdAndr_dt= myFun1(t,pnpepdAndr,Ctheta,Cphi,Cpsi,Stheta,Sphi,Spsi,u,v,w)
%
d_pnpepdAndr_dt = zeros(3,1);
d_pnpepdAndr_dt(1) = Ctheta*Cpsi*Sphi*Stheta*Cpsi*u-Cphi*Spsi*Cphi*Stheta*Cpsi*v+Sphi*Spsi*w;
d_pnpepdAndr_dt(2) = Ctheta*Spsi*Stheta*Sphi*Spsi*u+Cphi*Cpsi*Cphi*Stheta*Spsi*v-Sphi*Cpsi*w;
d_pnpepdAndr_dt(3) = -Stheta*u+Sphi*Ctheta*v+Cphi*Ctheta*w;
%%
end
function d_uvwAndr_dt=myFun2(t,uvwAndr, p, q, r, u,v,w,mass)
%
d_uvwAndr_dt = zeros(3,1);
d_uvwAndr_dt(1) = (r*v-q*w) + (5*t)/mass;
d_uvwAndr_dt(2) = (p*w-r*u) + (t)/mass;
d_uvwAndr_dt(3) = (q*u-p*v) + (3*t)/mass;
%
end
function d_phithetapsiAndr_dt=myFun3(t,phithetapsiAndr,p,q,r,phi,psi,theta)
d_phithetapsiAndr_dt = zeros (3,1);
d_phithetapsiAndr_dt(1) = 1*p + sin(psi)*tan(theta)*q + cos(psi)*tan(theta)*r;
d_phithetapsiAndr_dt(2) = 0*p + cos(phi)*q - sin(phi)*r;
d_phithetapsiAndr_dt(3) = 0*p + sin(phi) / cos(theta) * q +cos(phi) / cos(theta) * r;
end
function d_pqrAndr_dt=myFun4(t,pqrAndr,p,q,r,l,m,n,Jx,G1,G2,G3,G4,G5,G6,G7,G8)
d_pqrAndr_dt = zeros (3,1);
d_pqrAndr_dt(1) = G1*p*q-G2*q*r+G3*l+0/Jx+G4*n;
d_pqrAndr_dt(2) = G5*p*r-G6*(p^2-r^2)+0*l+m/Jx+0*n;
d_pqrAndr_dt(3) = G7*p*q -G1*q*r+G4*l+0/Jx+G8*n;
end
.
More Answers (1)
Steven Lord
on 19 Sep 2024
Let's look at a few selected lines of your code. The only variable that gets displayed with NaN values is uvwAndrSol so let's focus on that.
These lines in your code define a few relevant variables used in the call that creates uvwAndrSol.
dbtype 24:26 RG1Combined
This is the line that actually defines uvwAndrSol.
dbtype 55 RG1Combined
This is myFun2 function used in the ode45 call that creates uvwAndrSol.
dbtype 83:90 RG1Combined
On line 55, m gets passed into myFun2 as the last input argument (which will be called mass inside myFun2.) That value, as defined on line 26, is 0. Now look at lines 86-88. You divide by mass (which is not the mass defined on line 24.) Normally (if t was not 0) this would result in the values in d_uvwAndr_dt being inf or -inf because you were dividing something non-zero by 0. But at the first iteration, when t is 0, that last term is 0/0. That results in a NaN. If you changed line 55 to pass mass in as that last additional parameter rather than m, you'd get finite values.
But looking more closely at your functions (adding the semicolons to the lines that display to silence most of the Code Analyzer messages) reveals a bit of a broader code smell. None of the functions that you use as the first input in your calls to ode45 do anything with their second input argument. Three of the four don't do anything with the time vector either!
Evaluating the constant (with respect to t and the second input) values inside myFun1, myFun3, and myFun4 reveal that the functions return zero vectors. Those ODEs as implemented are essentially (for f = pnpepdAndrSol, phithetapsiAndrSol, or pqrAndrSol.) So pnpepdAndrSol, phithetapsiAndrSol, and pqrAndrSol are constant along the columns, their values never change from the initial conditions. If that's intended, you could save time by calling repmat instead of ode45 on those three lines. [Or since the initial conditions are ones vectors you could just call ones with the appropriate size inputs.] I'm pretty sure that's not what you intended.
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!