Undefined function or variable 'x'.

2 次查看(过去 30 天)
I'm trying to plot different values for x given different values for theta. The way I've written it only allows me to have valid x values if I have theta < 0.7854 (the value of pi/4, it won't let me type pi/4 and have it be valid) and not when theta == 0.7854, even though that is the range I have given it. I don't understand why it's happening. Note - the ode solver is for a couple other plots that I have working just fine, so that's not super important here. The t's are also going to be used as a conditional elseif statement once this part works.
function SatelliteDespin
%constants
m = 4; %mass of attached weight in kg
R = 3; %radius of satellite in meters
%initialized the intial angles in radians from almost zero to almost pi
theta = linspace(0,pi/4,100)
phi=linspace(pi/4,2*pi,100);
psi = pi/4 + phi;
%solve ode
tspan = 0:200:350; %range of t
phi0 = pi/4; %initial phi angle
[t,phidot]=ode45(@myDeriv,tspan,phi0);
if theta < 0.7854
x = R.*cos(theta);
y = R.*sin(theta);
elseif theta == 0.7854
x = (R.*cos(psi))+((R.*phi).*sin(psi));
y = (R.*sin(psi))-((R.*phi).*cos(psi));
end
plot(x,y,'r','LineWidth',2)
grid
xlabel('x')
ylabel('y')
function primes = myDeriv(t,phi)
%constants
m = 4; %mass of weight in kg
M = 2600; %mass of satellite in kg
R = 3; %radius in meters
%calculated constants
I = 0.5*M*R^2;
w0 = 5;
primes = w0*(((I/2*m)+R^2-(R*phi).^2)/((I/2*m)+R^2+(R*phi).^2));
Which gives this error:
Undefined function or variable 'x'.
Error in SatelliteDeSpin (line 63)
plot(x,y,'r','LineWidth',2)

回答(1 个)

Walter Roberson
Walter Roberson 2019-4-18
You define theta as a vector. Then you call ode45, which will not change theta. Then you test if theta < 0.7854. With theta being a vector, that if applied to a logical vector. MATLAB considers the test true only if all elements in the vectors are non-zero, so your test is equivalent to if all(theta < 0.7854) . If there is even one entry in the vector that the condition does not hold for, then the test is false. You then elseif theta == 0.7854 . That tests the values in theta against being bit-for-bit identical to what 0.7854 gets converted to. Again if there is even one entry in the vector that the condition does not hold for, then the test is false. If we suppose that one element in the vector is greater than or equal to 0.7854 then the first test would fail; then because only 0 or 1 of the elements compare bit-for-bit equal to 0.7854, the second test will fail. Those are the only two ways that x and y get defined, so x and y will not have any value after this.
  6 个评论
Tori Knapp
Tori Knapp 2019-4-18
Thank you, that seems to work. I'm wondering if this option still hold if I wanted to impose another condition? So when theta is greater than pi/4 AND t > 149.377, could I still use a mask? Is there a way to give a mask two conditions? Apologies for not including the t condition previously, I thought I had but I have been beating my head against a wall with this and it's been frustrating.
Walter Roberson
Walter Roberson 2019-4-18
After your ode, t is going to be a vector of variable length.
You construct tspan = 0:200:350 but that happens to be only [0, 200], and when you pass a vector of length 2 as the tspan, then ode*() will return data for various intermediate times -- whatever it feels like. The reported results will generally not correspond to the time values it calls your functions for; the results will generally be reported as synthesized by surrounding conditions in order to maintain the tolerance conditions. If you wanted the times 0, 200, and 350 reported on, you would have to pass [0 200 350] (a vector of length 3 or more) as the tspan, and then it would report on only those particular times.
So you will get a list of times out from the first output of ode45, and those will not correspond to any particular theta or psi or phi vector elements -- theta and psi and phi vectors are not inputs to your myDeriv function. The phi that is the argument for myDeriv is not the vector of values: it is the scalar boundary condition initialized with phi0 = pi/4 and permitted to evolve according to the derivative you calculate by myDeriv.
Now, you could replicate your values theta and psi and phi vectors an arbitrary number of times forming a grid of them and at coordinates then arbitrarily associated with time, you could put in the connection to time that you ask for. I have to wonder if it has any physical meaning, though.
It would perhap make more sense to me to take the phidot that are output from ode45(), and work backwards from them to find the corresponding theta and psi implied from them, and then perhaps work from there to the x and y according to your formula (including the time component). I do not know what those would mean at the moment, but it would at least have some meaningful connection to the output of the ode. If you are going to do this, then it would make sense to write formula for calculating theta and psi from a given phi, under the assumption that they are driven in tandom.
One thing to watch out for is that it would not surprise me at all if the output phidot was outside the bound of your [pi/4, 2*pi] segment.
Note: phidot is a misleading variable name for the output from ode45. The output in that slot is not the derivatives: it is the calculated boundary conditions, the (numeric) integrals of the derivatives.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Ordinary Differential Equations 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by