Given two systems with damper/spring:
First system's simulink model with step time 2, final value 0.5:
Simulink of the second system with same input:
I have to find the code using dsolve and ode45 to generate the same graph with Simulink. Given values are:
m1 = 500
c1 = 1200
k1 = 25000
k2 = 15000
m2 = 50
I tried to find dsolve but it couldn't solve it. So I got to use ode45, and I am totally lost.
Differential equation of the first system:
syms x(t) y(t)
Dy = diff(y,t);
Dx = diff(x,t);
D2x = diff(x,2,t);
cond = [x(0)==0, y(0)==0, Dy(0)==0, Dx(0)==5];
eqn33 = D2x + (2*0.2121*0.1414*Dx) + (0.1414^2)*x==2*0.2121*0.1414*Dy+(0.1414^2)*y;
sol33 = dsolve(eqn33,cond)
pretty(sol33)
Answer updated to match Simulink model implementation
To use ode45, you first need to write a function that computes the derivative of you input vector (i.e. your differential equation), and store that function in a separate file with the function name as the filename. Please note that the ode solvers can only solve first-order differential equations, so you first need to do a bit of work to convert your second-order differential equation to a first-order one. For more details, see the documentation on ode45.
Based on what you have done in your Simulink model, D2y is known for all values of t (it's the step input), so we need to integrate it with respect to time to get Dy and y. So our state vector is X = [x; Dx; y; Dy] and our function looks like (stored in diff_eqn.m):
function dX = diff_eqn(t,X)
m1=500;
c=1200;
k1=25000;
dX(1) = X(2); % Dx
dX(2) = -(1/m1)*(c*(X(2)-X(4)/m1) + k1*(X(1)-X(3)/m1));; % D2x
dX(3) = X(4); % Dy
if t<2
dX(4) = 0; % D2y
else
dX(4) = 0.5;
end
as dX = [Dx; D2x; Dy; D2y].
In your script or your MATLAB command window, you can then call the ode solver (initial conditions all being equal to zero for Dx, x, Dy and y, as per your Simulink model):
[t,X] = ode45(#diff_eqn,[0 20],[0; 0; 0; 0]);
Adjust the ode solver options (e.g. max step size, etc...) to get results with more data points. To get the same plot as in your Simulink model, you can then process the results from the ode solver:
D2x = diff(X(:,2))./diff(t);
D2x = [0; D2x];
D2y = zeros(size(D2x));
D2y(t>=2) = 0.5;
plot(t,[D2y 500*D2x])
grid on
xlabel('Time [s]')
legend('D2y','m1*D2x','Location','NorthEast')
Which gives the following plot, matching the results from your Simulink model:
Related
I have a discrete ODE, where u is the input and y is the output and dy is the derivative of y.
dy = #(y, u) 229.888852 - 0.050251*y + 3.116311*u + 0.000075 * y^2
I want to simulate this system with a ODE-solver e.g ODE45. But ODE45 requries a time vector t e.g
tspan = [0 5];
y0 = 0;
[t,y] = ode45(#(t,y) 2*t, tspan, y0);
And I don't have the t in my discrete ODE. I found it difficult to use ODE45 or other ODE-solvers in MATLAB / Octave because they don't handle discrete ODE's.
My question is simple:
How to simulate a discrete ODE in MATLAB with adaptive step size?
I have got this model for glucose and insulin, and system of differential equations:
Where:
G(t) - the plasma glucose concentration at time t
I(t) - the plasma insulin concentration at time t
X(t)- the interstitial insulin at time t
Gb - the basal plasma glucose concentration
Ib - the basal plasma insulin concentration
which describe the model. I must do an algorithm to estimate parameters with use ode45 in matlab.
Test data is as follows:
I am not sure how write function for ode45, my idea is as follows:
function [] = cwiczenie3_1a(dane)
a=size(dane);
u=[];
y=[];
for i=1:a(1,1)
g(i,1)=dane(i,2);
j(i,1)=dane(i,3);
end
[x t]=ode45(#funkcjajeden,[0 100],[0,0])
end
function [dg] = funkcjajeden(t,g)
gb=350;
d=0.1;
ib=120;
k1=1;
k2=2;
k3=1;
dg=zeros(size(g));
dg(1)=(k1*(gb-g(1)))-d*g(1);
dg(2)=(k2*(g(2)-ib))-k3*d;
end
Taking a look to the documentation for ode45 to solve the system of differential equations you should write the function in a file, odefcn.m in this case:
function dg = odefcn(g,k1,k2,k3,gb,ib,d)
dg = zeros(size(g));
dg(1) = k1*(gb-g(1)) - d*g(1);
dg(2) = k2*(g(2)-ib) - k3*d;
And then in another file you solve it by doing:
gb = 350;
d = 0.1;
ib = 120;
k1 = 1;
k2 = 2;
k3 = 1;
tspan = [0 100];
g0 = [0 0];
[t,g] = ode45(#(t,g) odefcn(g,k1,k2,k3,gb,ib,d), tspan, g0);
plot(t,g(:,1),t,g(:,2))
This way you obtain the values for both G(t) an I(t) for that initial values and parameters:
Image
Then, you can compare to the test data and find the value of the parameters.
I need some help with finding solution to Cauchy problem in Matlab.
The problem:
y''+10xy = 0, y(0) = 7, y '(0) = 3
Also I need to plot the graph.
I wrote some code but, I'm not sure whether it's correct or not. Particularly in function section.
Can somebody check it? If it's not correct, where I made a mistake?
Here is separate function in other .m file:
function dydx = funpr12(x,y)
dydx = y(2)+10*x*y
end
Main:
%% Cauchy problem
clear all, clc
xint = [0,5]; % interval
y0 = [7;3]; % initial conditions
% numerical solution using ode45
sol = ode45(#funpr12,xint,y0);
xx = [0:0.01:5]; % vector of x values
y = deval(sol,xx); % vector of y values
plot(xx,y(1,:),'r', 'LineWidth',3)
legend('y1(x)')
xlabel('x')
ylabel('y(x)')
I get this graph:
ode45 and its related ilk are only designed to solve first-order differential equations which are of the form y' = .... You need to do a bit of work if you want to solve second-order differential questions.
Specifically, you'll have to represent your problem as a system of first-order differential equations. You currently have the following ODE:
y'' + 10xy = 0, y(0) = 7, y'(0) = 3
If we rearrange this to solve for y'', we get:
y'' = -10xy, y(0) = 7, y'(0) = 3
Next, you'll want to use two variables... call it y1 and y2, such that:
y1 = y
y2 = y'
The way you have built your code for ode45, the initial conditions that you specified are exactly this - the guess using y and its first-order guess y'.
Taking the derivative of each side gives:
y1' = y'
y2' = y''
Now, doing some final substitutions we get this final system of first-order differential equations:
y1' = y2
y2' = -10*x*y1
If you're having trouble seeing this, simply remember that y1 = y, y2 = y' and finally y2' = y'' = -10*x*y = -10*x*y1. Therefore, you now need to build your function so that it looks like this:
function dydx = funpr12(x,y)
y1 = y(2);
y2 = -10*x*y(1);
dydx = [y1 y2];
end
Remember that the vector y is a two element vector which represents the value of y and the value of y' respectively at each time point specified at x. I would also argue that making this an anonymous function is cleaner. It requires less code:
funpr12 = #(x,y) [y(2); -10*x*y(1)];
Now go ahead and solve it (using your code):
%%// Cauchy problem
clear all, clc
funpr12 = #(x,y) [y(2); -10*x*y(1)]; %// Change
xint = [0,5]; % interval
y0 = [7;3]; % initial conditions
% numerical solution using ode45
sol = ode45(funpr12,xint,y0); %// Change - already a handle
xx = [0:0.01:5]; % vector of x values
y = deval(sol,xx); % vector of y values
plot(xx,y(1,:),'r', 'LineWidth',3)
legend('y1(x)')
xlabel('x')
ylabel('y(x)')
Take note that the output when simulating the solution to the differential equation by deval will be a two column matrix. The first column is the solution to the system while the second column is the derivative of the solution. As such, you'll want to plot the first column, which is what the plot syntax is doing.
I get this plot now:
I am trying to model a SIR epidemic model in matlab and simulink. I think I've already done it in matlab but for some reason my simulink model won't work. It just shows straight lines in a scope. This is my function to calculate differential equations.
function dx = sir(t, x)
dx = [0; 0; 0];
beta = .5;
delta = .3;
dx(1) = -beta * x(1) * x(2);
dx(2) = beta * x(1) * x(2) - delta * x(2);
dx(3) = delta * x(2);
end
This is my workspace code to show plot
and this is mu simulink with yields this strange plot and this is after autoscaling with initial conditions set to S = 7900000 and R = 0 and I = 10
The List of Signals property of the summation block that is being fed by the Product3 and Product2 blocks should be |+- instead of |--.
I have based my solution off the example provided by Matlab - solving a third order differential equation.
My problem is that I have to solve the third order differential equation, y'''+3y''+2y'+y=4u, by using the ode23 solver and plot the step response.
Here is what I have so far.
function dy = diffuy( t, y )
%Split uy into variables in equation
%y'''+3y''+2y'+y=4u
%Have to take third order equation and convert to 1st order
%y0 = y
%y1 = y0'
%y2 = y1'
%y3 = y2'
%y0' = y1
%y1' = y2
%y2' = y3
%y3' = y''' = -3*y2-2*y1-y0+4*u
%Assume that y(0)= 0, y'(0)=0, y''(0)=0, no initial conditions
u = #(t) heaviside(t);
dy = zeros(4,1);
dy(1) = y(2);
dy(2) = y(3);
dy(3) = y(4);
dy(4) = -3*y(3)-2*y(2)-y(1)+4*u(t);
end
In my main file, I have the code:
[T, Y]=ode23(#diffuy,[0 20],[0 0 0 0]);
figure(1)
plot(T,Y(:,1))
A=[0 1 0;0 0 1; -1 -2 -3]
B=[0;0;4]
C=[1 0 0]
D=[0]
sys4=ss(A,B,C,D)
figure(2)
step(sys4)
The problem I am having is that the step response produced from using the state-space representation commands in MATLAB do not match the step response produced by the ode23, so I assumed that I solved the differential equation incorrectly. Any tips or comments would be very helpful.
Step Response from ss commands:
Step Response from using ode23:
I'm not sure how the linked question got the correct answer because you're actually solving a fourth-order equation using their methodology.
The right hand-side vector given to the ODE suite should only have n entries for an n-order problem.
In your case, the change of variables
results in the third order system
with the initial conditions
.
Changing diffuy to
function dy = diffuy( t, y )
dy = zeros(3,1);
dy(1) = y(2);
dy(2) = y(3);
dy(3) = -3*y(3)-2*y(2)-y(1)+4*u(t);
end
gives a solution that matches the state-space model.