Plot values changing with events in one continous graph
Show older comments
Hello,
I need help plotting a value, let's call it p. I have 3 different events set up and p should change depending on which event is active. I want a continous plot with only the value from the active event. I tried putting them inside the existing functions as nested functions, I tried codeing the values inside my main loop, I don't get a proper plot.
The functions should be as followed:
Events:
ZustandI: p=0
ZustandII: p=k2*(y(1)-y(3)-s)
ZustandIII: p=k2*(y(1)-y(3)+s)
Can you help me? My code is down below.
function mfc
clc
%%parameters
m1=10; m2=10; m3=500; k3=300; k2=(k3*(m1+m2))/m3; my=m1/(m1+m2); FW=0; s=0.5; r=0.5; om=5; dv0s=1; dv0=dv0s-my*r*om;
%%starting parameters
tspan = [0 100];
tstart = tspan(1);
tend = tspan(end);
y0 = [0 dv0 0 0];
% initiate starting function
t = tstart;
y = y0;
fcn = @eqmi;
opt = odeset('Events', @ZustandI);
ateout = [];
ayeout = [];
aieout = [];
%%main loop
while t(end) < tend
% Integrate until event-function stops it
[at,ay,ate,aye,aie] = ode45(fcn, [t(end) tend], y(end,:), opt);
% new starting parameters
t = cat(1, t, at(2:end));
y = cat(1, y, ay(2:end,:));
ateout = [ateout; ate];
ayeout = [ayeout; aye];
aieout = [aieout; aie];
% new functions and events
if (-s<y(end,1)-y(end,3) && y(end,1)-y(end,3)<s)
fcn = @eqmi;
opt = odeset('Events', @ZustandI);
elseif y(end,1)-y(end,3)<=-s
fcn = @eqmii;
opt = odeset('Events', @ZustandII);
elseif y(end,1)-y(end,3)>=s
fcn = @eqmiii;
opt = odeset('Events', @ZustandIII);
end
end
figure(1);
plot(t,p) % this should detect events
hold on
plot(ateout,ayeout(:,1))
xlabel('time');
ylabel('test');
title('test');
legend('p');
%%functions
function dy=eqmi(t,y)
dy=zeros(5,1);
dy(1)=y(2);
dy(2)=my*r*om^2*sin(om*t);
dy(3)=y(4);
dy(4)=(FW*sin(w3*t)-k3*y(3))/m3;
dy(5)=0;
end
function dy=eqmii(t,y)
dy=zeros(5,1);
dy(1)=y(2);
dy(2)=my*r*om^2*sin(om*t)-(k2*(y(1)-y(3)-s))/(m1+m2);
dy(3)=y(4);
dy(4)=(FW*sin(w3*t)-k3*y(3)+k2*(y(1)-y(3)-s))/m3;
dy(5)=k2*(y(1)-y(3)-s);
end
function dy=eqmiii(t,y)
dy=zeros(5,1);
dy(1)=y(2);
dy(2)=my*r*om^2*sin(om*t)-(k2*(y(1)-y(3)+s))/(m1+m2);
dy(3)=y(4);
dy(4)=(FW*sin(w3*t)-k3*y(3)+k2*(y(1)-y(3)+s))/m3;
dy(5)=k2*(y(1)-y(3)+s);
end
%%Events
function [value,isterminal,direction] = ZustandI(t,y)
value = [double(y(1)-y(3)>-s),double(y(1)-y(3)<s)];
isterminal = [1,1];
direction = [0,0];
end
function [value,isterminal,direction] = ZustandII(t,y)
value = double(y(1)-y(3)<=-s);
isterminal = 1;
direction = 0;
end
function [value,isterminal,direction] = ZustandIII(t,y)
value = double(y(1)-y(3)>=s);
isterminal = 1;
direction = 0;
end
end
2 Comments
Jan
on 7 Nov 2018
I do not understand, what the question is exactly. "I want a continous plot with only the value from the active event" - this is not clear. In " I tried putting them", what is "them" and what does "nothing works" mean explicitly?
Answers (1)
Jan
on 8 Nov 2018
ateout = [];
ayeout = [];
aieout = [];
dy5 = [];
while t(end) < tend
% Integrate until event-function stops it
[at,ay,ate,aye,aie] = ode45(fcn, [t(end) tend], y(end,:), opt);
% new starting parameters
t = cat(1, t, at(2:end));
y = cat(1, y, ay(2:end,:));
dy = fcn(at.', ay.');
dy5 = cat(1, dy5, dy(:, 5)); % Or: cat(1, dy5, dy(5, :).') ???
Now modify your functions to be integrated such, that they handle a vector input also:
function dy = eqmi(t, y)
dy = zeros(5, numel(t));
dy(1, :) = y(2, :);
dy(2, :) = my * r * om^2 * sin(om * t);
dy(3, :) = y(4, :);
dy(4, :) = (FW * sin(w3 * t) - k3 * y(3, :)) / m3;
dy(5, :) = 0;
end
!UNTESTED! Care for transposing the inputs and/or outputs t and y.
6 Comments
Jan
on 8 Nov 2018
p = cat(1, dy5, dy(5,:)); or cat(1, dy5, dy(5,:).')
The second part of this is useless and should drop an error. I've added this comment only, because I'm not sure, if the variables have to be transposed or not.
t and p must have the same size after this code ran. Please post your code, if there are still problems.
Jan
on 8 Nov 2018
Ah, yes: If you have
t = cat(1, t, at(2:end));
you need crop the first elemet of dy also.
dy5 = cat(1, dy5, dy(5, 2:end).');
But
p = cat(1, dy5, dy(5,:).');
is not useful, because you do not accumulate dy5 anymore. Equivalently to concatenating t cumulatively with at, you collect the dy in dy5.
Lennart
on 9 Nov 2018
Lennart
on 9 Nov 2018
Categories
Find more on Calendar in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!