Plot values changing with events in one continous graph
Mostrar comentarios más antiguos
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 comentarios
Jan
el 7 de Nov. de 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?
Respuestas (1)
Jan
el 8 de Nov. de 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 comentarios
Jan
el 8 de Nov. de 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
el 8 de Nov. de 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
el 9 de Nov. de 2018
Lennart
el 9 de Nov. de 2018
Categorías
Más información sobre Calendar en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!