1

I am having trouble figuring out how to fix my script, specifically using the ODE45 command.

This is what I have so far:

clc; clear all;

global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40 IC

I11 = 160;
I22 = 400;
I33 = 400;
Mx = 0;
My = 0;
Mz = 45;

w10 = 2;
w20 = -1;
w30 = 1;

eps10 = 0;
eps20 = 0;
eps30 = 0;
eps40 = 1;

IC = [w10 w20 w30 eps10 eps20 eps30 eps40];


function soln = DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)
global I11 I22 I33 Mx My Mz w10 w20 w30 eps10 eps20 eps30 eps40 

w1 = y(1);
w2 = y(2);
w3 = y(3);
eps1 = y(4);
eps2 = y(5);
eps3 = y(6);
eps4 = y(7);


w1_dot = Mx - w2*w3*(I33-I22)/I11;
w2_dot = My - w1*w3*(I11-I33)/I22;
w3_dot = Mz - w1*w2*(I22-I11)/I33;

eps1_dot = .5*(w1*eps4-w2*eps3+w3*eps2);
eps2_dot = .5*(w1*eps3+w2*eps4-w3*eps1);
eps3_dot = .5*(-w1*eps2+w2*eps1+w3*eps4);
eps4_dot = -.5*(w1*eps1+w2*eps2+w3*eps3);

soln = [w1_dot; w2_dot; w3_dot; eps1_dot; eps2_dot; eps3_dot; eps4_dot];
end

I recently though the issues was with my variables, which is why I defined them all as global.

When I try to run the following in the command window:

[t, y] = ode45(@(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);

I get these errors:

>> [t, y] = ode45(@(t,y) DynEqn1(t,y,I11,I22,I33,Mx,My,Mz), [0 30], IC);
Undefined function or variable 'DynEqn1'.

Error in @(t,y)DynEqn1(t,y,I11,I22,I33,Mx,My,Mz)

Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:});   % ODE15I sets args{1} to yp0.

Error in ode45 (line 115)
    odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);

I've tried researching it on Mathworks and other websites, but couldn't figure out what is the issue.

I'm not too familiar using the 'ODE45' function as well.

Any help is appreciated. Thank you.

Scotch Jones
  • 25
  • 1
  • 6

1 Answers1

1

Are you defining a local function inside a script file? If so, bear in mind that "Local functions are only visible within the file where they are defined. They are not visible to functions in other files, and cannot be called from the Command Window." (Ref.)

You need to either call ode45(...DynEqn1...) from the script file, rather than the command line, or create a separate file to make the function visible to the outside world.

Vicky
  • 969
  • 1
  • 11
  • 19
  • So to clarify, you mean add that [t, y] = ode45(...) line in the script itself? So put it after the 'end', for example? I tried to do that, but still got the error message. – Scotch Jones Feb 26 '21 at 02:13
  • So I did it again and had to put the [t, y] = ode45(...) before the function and the program ran. But now I am trying to plot, say w1_dot vs t, but I get errors saying 'w1_dot' is undefined. Do you have any tips to alleviate this issue? I'm going to try to mess around with it – Scotch Jones Feb 26 '21 at 02:19
  • This is an issue with the scope of your variables: `w1_dot` is declared inside `DynEqn1()`, so it cannot be accessed from the main script (which I guess is where you are calling `plot()` from). In any case, if you want to show the current progress of the solution as `ode45()` goes, you just need to set a built-in option: `opts=odeset('OutputFcn',@odeplot); ode45(..., opts);` – Vicky Feb 26 '21 at 02:35
  • It seems I can only call the variable from within the function itself, so if I type 'disp(soln)' before the end, it pops up in a series of column vector. But if I try to call anything outside the function, it doesn't work. Furthermore, I tried to set everything as global variables, but that didn't work either – Scotch Jones Feb 26 '21 at 02:40
  • 1
    Oh sorry, didn't notice your reply. Okay I will try that, thank you – Scotch Jones Feb 26 '21 at 02:41