How do i replace Euler's method with ode45?
2 ビュー (過去 30 日間)
古いコメントを表示
KLETECH MOTORSPORTS
2020 年 11 月 21 日
コメント済み: Alan Stevens
2020 年 11 月 30 日
Hi, I'm trying to replace the Section of the code that uses Euler's methos to solve the ode by ode45,
and i have the individual codes, but i'm unsure how to insert one into another:
First, I have my main code, which uses Euler's method to solve the ode( TBH, i'm not sure if it even solves an ode, because there isn't
an explicitly defined ode in the code, more like a rotation matrix, but it gives me the output of an oscillating pendulum)
(Basically, i do not understand how the motion of the pendulum is plotted using a rotation matrix)
function Animation
% A script to animate the motion of the simple pendulum
clc
clear
close all;
disp('Specify the initial angle of the pendulum in degrees, e.g., 50')
disp('or press ENTER for the default value.')
theta=input('Initial angular displacement of the pendulum= ');
if isempty(theta)
theta=50
else
theta;
end
theta=theta*pi/180; % convert from degrees to radians
disp('Specify the final time, e.g. tfinal = 25')
disp('or press ENTER for default value.')
tfinal=input('Final time tfinal = ');
if isempty(tfinal)
tfinal=10
else
tfinal;
end
data_init=[0 0; -4 0]; %pendulum length
% rotation matrix
R=[cos(theta) -sin(theta);sin(theta) cos(theta)];
data=R*data_init; % initial pendulum position
bar=line('xdata',[0 data(1)],'ydata',...
[0 data(2)]','linewidth',3);
mass=line('xdata',data(1),'ydata',data(2),'marker','o',...
'markersize',15,'MarkerFaceColor','b');
hinge=line('xdata',0,'ydata',0,'marker','o',...
'markersize',7);
axis([-5 5 -5 5])
grid % comment this out if you do like the grid
set(gca,'Fontsize',14)
set(gca,'dataaspectratio',[1 1 1])
box on
dt=0.03; % step−size for solving differential
% equations can be arbitrarily selected
t=0; % initial time
thetadot=0; % initial angular speed
disp('Can maximize the display so you can see the action better,')
disp('then press ENTER.')
disp('If you are happy with the display size, press ENTER.')
pause
v = VideoWriter('pendulum4.avi');
open(v);
% solve the diff eqns using the Euler's method
while(t<tfinal)
t=t+dt;
theta = theta + thetadot*dt;
thetadot=thetadot - 5*sin(theta)*dt; %−0.01*thetadot;
% you can add some friction
R=[cos(theta) -sin(theta);sin(theta) cos(theta)];
datanew=R*data_init;
% change the property values of the bar and hinge objects
set(bar,'xdata',[0 datanew(1)],'ydata',[0 datanew(2)]);
set(mass,'xdata',datanew(1),'ydata',datanew(2));
set(hinge,'xdata',0,'ydata',0)
set(gca,'dataaspectratio',[1 1 1])
drawnow;
% get the frame and write to the file
frame = getframe(gcf);
writeVideo(v,frame);
end
% close the video writer
close(v);
end
Next, I have my code which uses ode45 to solve the equation of motion of the pendulum, which solves both the linear and nonlinear equations of motion using two functions, pend_l ( for linear) and pend_n ( for nonlinear)
clear all;
clc;
clf;
tic;
tspan = 0:0.01:20;
a=pi/8;
b=0;
x0 = [a; b];
[t1,x] = ode45(@pend_l,tspan,x0);
X1 = x(:,1);
X2 = x(:,2);
y0 = [a ; b];
[t2,y] = ode45(@pend_n,tspan,y0);
Y1 = y(:,1);
Y2 = y(:,2);
%figure(1);
subplot(2,2,1);
plot(t1,X1); %linear disp vs time
xlabel('Time (s)');
ylabel('Displacement (rad)');
hold on;
grid on;
plot(t2,Y1); %nonlinear disp vs time
legend('Linear','Non Linear');
%figure(2);
subplot(2,2,2);
plot(t1,X2); %linear velocity vs time
xlabel('Time (s)');
ylabel('Velocity (rad/s)');
hold on;
grid on;
plot(t2,Y2); %nonlinear velocity vs time
subplot(2,2,3);
plot(X1,X2); %linear vel vs disp
hold on;
plot(Y1,Y2); %nonlinear vel vs disp
xlabel('Displacement (rad)');
ylabel('Velocity (rad/s)');
grid on;
toc;
function ydot = pend_n(t2,y)
wsq=3.5; % same value of wsq in both cases is required
ydot = [y(2); -wsq*sin(y(1))];
end
function xdot = pend_l(t1,x)
wsq=3.5;
xdot = [x(2); -wsq*x(1)];
end
0 件のコメント
採用された回答
Alan Stevens
2020 年 11 月 21 日
Here's one way. I've simplified the data input - you can add the bells and whistes!
% A script to animate the motion of the simple pendulum
theta0=deg2rad(50);
tfinal=10;
thetadot0=0; % initial angular speed
tspan = [0 tfinal];
IC = [theta0 thetadot0];
[t, Y] = ode45(@odefn, tspan,IC);
theta = Y(:,1);
thetadot = Y(:,2);
data_init=[0 0; -4 0]; %pendulum length
R=[cos(theta(1)) -sin(theta(1));sin(theta(1)) cos(theta(1))];
data=R*data_init; % initial pendulum position
bar=line('xdata',[0 data(1)],'ydata',...
[0 data(2)]','linewidth',3);
mass=line('xdata',data(1),'ydata',data(2),'marker','o',...
'markersize',15,'MarkerFaceColor','b');
hinge=line('xdata',0,'ydata',0,'marker','o',...
'markersize',7);
axis([-5 5 -5 5])
grid % comment this out if you do like the grid
set(gca,'Fontsize',14)
set(gca,'dataaspectratio',[1 1 1])
box on
for i=2:numel(t)
R=[cos(theta(i)) -sin(theta(i));sin(theta(i)) cos(theta(i))];
datanew=R*data_init;
set(bar,'xdata',[0 datanew(1)],'ydata',[0 datanew(2)]);
set(mass,'xdata',datanew(1),'ydata',datanew(2));
set(hinge,'xdata',0,'ydata',0)
set(gca,'dataaspectratio',[1 1 1])
drawnow;
frame = getframe(gcf);
end
function dYdt = odefn(~,Y)
theta = Y(1);
thetadot = Y(2);
dYdt = [thetadot;
-5*sin(theta)];
end
11 件のコメント
Alan Stevens
2020 年 11 月 30 日
The matrix data_init specifies the positions of the pivot point (0,0) and the pendulum mass at rest (0, -4). The R value is a rotation matrix that rotates the line between the pivot and the mass. Initially, R uses theta(1), so the pendulum immediatelyrotates to 50 degrees from the vertical. The value of theta then changes every timestep, so R changes and the rotates the pendulum to its new position (the new positions are ste in datanew).
その他の回答 (0 件)
参考
カテゴリ
Help Center および File Exchange で Numerical Integration and Differential Equations についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!