我一直试图重新创建以下论文中的情节:
http://iopscience.iop.org/article/10.1088/0964-1726/4/4/006/meta
我试图重新创建的情节在第267页的右上角,具体来说,$ x(t)$ vs. $ t $。
论文中使用的ODE是 $$米\ DDOT {X}(T)+ k_0x(T)+ K_1(X(t)的-x_s)= 0 $$ 其中$ x_s $是$ x_s = x(t_r)$定义的分段常量函数,只要$ \ dot {x}(t_r)= 0 $。
使用值$ m = 1,k_0 = 150,$和$ k_1 = 50生成绘图。$
解决此问题的代码如下:
tstart = 0;
tfinal = 2;
tspan = [tstart tfinal];
u0 = [1; 0];
refine = 4;
options = odeset('Events', @resetevent , 'OutputSel' , 1, 'Refine', refine);
tout = tstart;
uout = u0';
teout = [];
ueout = [];
ieout = [];
ue = [];
while tout(end) < tfinal
% Solve until the first terminal event.
[t, u, te, ue, ie] = ode45(@(t,u) sys(t, u, ue), [tstart tfinal] , u0, options);
% Accumulate output. This could be passed out as output arguments.
nt = length(t);
tout = [tout; t(2:nt)];
uout = [uout; u(2:nt,:)];
teout = [teout; te]; % Events at tstart are never reported.
ueout = [ueout; ue];
ieout = [ieout; ie];
% Set the new initial conditions, with .9 attenuation (??).
u0 = [u(nt,1) ; u(nt,2)];
% A good guess of a valid first timestep is the length of the last valid
% timestep, so use it for faster computation. 'refine' is 4 by default.
options = odeset(options,'InitialStep',t(nt)-t(nt-refine),...
'MaxStep',t(nt)-t(1));
tstart = t(nt);
end
figure(1)
set(gcf,'units','normalized','outerposition',[0 0 1 1])
subplot(2,1,1);
plot(tout,uout(:,1));
title(['Time history of $x(t)$'],'interpreter','latex','fontsize',20)
ylabel('$x$','interpreter','latex','fontsize',15)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)
grid on
hold on
subplot(2,1,2);
plot(tout,uout(:,2))
title('Time history of $\dot{x}(t)$','interpreter','latex','fontsize',20)
ylabel('$\dot{x}$','interpreter','latex','fontsize',15)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)
grid on
hold on
subplot(2,1,1);
stairs(teout,ueout(:,1))
title('Time history of $x_s(t)$','interpreter','latex','fontsize',20)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)
grid on
hold on
%
function dz = sys(t, z , us)
dz = zeros(2,1);
if isempty(us) == 1
us = 0;
else
us;
end
% if isempty(us) == 1
% us = 0;
% elseif us(1) == 1
% us(1) = -1;
% else
% us;
% end
m = 1;
k0 = 150;
k1 = 50;
dz(1) = z(2);
dz(2) = - ((k0 + k1)/m)*z(1) + (k1/m)*us(1);
end
% Reset Event Function
function [lookfor, stop, direction] = resetevent(t, z)
% Locate the time when xdot passes through zero in any direction
% and stop integration.
lookfor = z(2); % when xdot = 0
stop = 1; % stop the integration
direction = 0; % any direction
end
使用u0=[u(nt,1) ; 0]
作为重启初始条件生成的图是
我有几个与此相关的问题:
让我感到困惑的是,由于某种原因,Matlab确实找到了 $ \ dot {x} $的第一个零并输入到函数中,但是 关于ODE Event Location的文档说它跳过了第一个 终端事件。这可能是我做错的事情,但我无法做到 看看它是什么。
如果你看一下$ \ dot {x}(t)$的情节,在它经过零的点上,我的初始条件是从 它结束的最后一个值,它在图中给出了一个扭结,这意味着衍生物不匹配。我试过了 使用0作为初始值,这对我来说很有意义,但它会导致求解器发散。然而,似乎衍生品匹配稍好一些。 我不确定0.9衰减是什么,我试着搞砸了 那无济于事。
如果您在函数sys
中使用注释代码,它将强制us
的值,并且该图将看起来像文章中的那个,但它太具体而不是我想要做的是什么,因为我想将重置的想法扩展到不同的ODE。
我还注意到,如果我将初始条件设置为u0 = [1 ; -eps]
,它实际上将从零开始,但不会精确归零,从而生成正确的图。
感谢您的帮助!