Не знаете, как исправить ошибки с помощью команды «ODE45»

У меня возникли проблемы с тем, как исправить мой скрипт, особенно с помощью команды ODE45.

Это то, что у меня есть до сих пор:

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

Недавно я думал, что проблемы были с моими переменными, поэтому я определил их все как глобальные.

Когда я пытаюсь запустить следующее в командном окне:

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

Я получаю эти ошибки:

>> [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);

Я пытался исследовать его на Mathworks и других веб-сайтах, но не мог понять, в чем проблема.

Я также не очень хорошо знаком с функцией ODE45.

Любая помощь приветствуется. Спасибо.


person Scotch Jones    schedule 25.02.2021    source источник


Ответы (1)


Вы определяете локальную функцию внутри файла сценария? Если это так, имейте в виду, что локальные функции видны только в том файле, где они определены. Они не видны функциям в других файлах и не могут быть вызваны из командного окна. (Ссылка)

Вам нужно либо вызвать ode45(...DynEqn1...) из файла скрипта, а не из командной строки, либо создать отдельный файл, чтобы сделать функцию видимой для внешнего мира.

person Vicky    schedule 25.02.2021
comment
Итак, чтобы уточнить, вы имеете в виду добавить строку [t, y] = ode45(...) в сам скрипт? Например, поставить его после «конца»? Я попытался сделать это, но все равно получил сообщение об ошибке. - person Scotch Jones; 26.02.2021
comment
Поэтому я сделал это снова, и мне пришлось поставить [t, y] = ode45(...) до запуска функции и программы. Но теперь я пытаюсь построить график, скажем, w1_dot vs t, но получаю ошибки, говорящие, что «w1_dot» не определено. Есть ли у вас какие-либо советы, чтобы облегчить эту проблему? попробую с ним повозится - person Scotch Jones; 26.02.2021
comment
Это проблема с областью действия ваших переменных: w1_dot объявлен внутри DynEqn1(), поэтому к нему нельзя получить доступ из основного скрипта (из которого, я думаю, вы вызываете plot()). В любом случае, если вы хотите показать текущий прогресс решения по ходу ode45(), вам просто нужно установить встроенную опцию: opts=odeset('OutputFcn',@odeplot); ode45(..., opts); - person Vicky; 26.02.2021
comment
Кажется, я могу вызвать переменную только из самой функции, поэтому, если я наберу «disp (soln)» до конца, она появится в серии вектор-столбца. Но если я попытаюсь вызвать что-то вне функции, это не сработает. Кроме того, я пытался установить все как глобальные переменные, но это тоже не сработало. - person Scotch Jones; 26.02.2021
comment
Ой, извините, не заметил вашего ответа. Хорошо, я попробую это, спасибо - person Scotch Jones; 26.02.2021
comment
Вау, спасибо. Это сработало. - person Scotch Jones; 26.02.2021