ODE功能的连续图

时间:2013-05-28 14:44:32

标签: matlab motion differential-equations

我有一个ODE求解器工作得很好而且平滑,但我需要在一个图中绘制所有。连接图(1)+(3)和图(2)+(4),我必须设置启动和停止条件,但它对我不起作用,我处于死胡同。我尝试用x_m设置结束条件而没有结果。

options = odeset('Events',@events);

[t,y] = ode45(@ph1,[0,w_max],[0,0], options);
figure(1),plot(t,y(:,1));

x_n = y(:,1);
v_n = y(:,2);
x_m = x_n(end);
v_m = v_n(end);
q = max (t);


 d_v1 =diff(y(:,2));    
%d_t1 = diff(t);
%a_c1 = d_v1./d_t1;
 t_c1 = t(1:end-1);
%t_h1 = d_t1./2;

figure (2)
plot((t_c1),d_v1,'r') 
set(gca,'FontName','Times New Roman CE')
title('Rychlost')
xlabel('\it t\rm [s]')
ylabel('\it v_n\rm [m*s^{-1}]')
hold on

[t,y] = ode45(@ph2,[0,w_max],[0,0], options);
figure(3),plot(t,(y(:,1)));

d_v =diff(y(:,2));     
%d_t = diff(t);
%a_c = d_v./d_t;
t_c = t(1:end-1);
%t_h = d_t./2;

figure(4),plot((t_c),(d_v), 'g' );

% d_v2 =diff(d_v);     
% d_t2 = diff(d_t);
% a_c2 = d_v2./(d_t2.*d_t2);
% t_c2 = t(1:end-2);

% figure(5),plot((t_c2),a_c2 , 'r');

function [value,isterminal,direction] = events(t,y)

global ch

value = y(1) - ch;  
isterminal = 1;        
direction = 0;        




function dx = ph1(tt,x)
global F1 c m_c Ff p w s ln f_t sig dstr Ren pn Fex Fzmax xz xn l Fz m_n

Fpp = F1 + c*x(1); 

 if pn<0
     pn=abs(pn);
 end

if x(1)<ln

    pn=spline(w,p,tt)-((2*sig)/dstr*Ren);    
    Fex=3.1416.*f_t.*pn.*(ln-x(1));
end

if x(1)<42e-5
     Fz = Fzmax*(1-(1/xz)*(x(1)+l));   
end

if x(1)>44e-3
    m_c=m_c-m_n;
end


dx=[x(2);((spline(w,p,tt)*s)-Fpp-Ff-Fex-Fz)./m_c];

 function dx=ph2(tt,x)

 global Fv Ft m_z g f Fzp alfa m_nbp c

        Ft=m_z*g*f;
        Fv = 2*f*(Fzp/cos(alfa));

        if x(1)>0.44

        m_z=m_z+m_nbp

        end

        dx = [x(2);((x(1)*c)-Ft-Fv)/m_z];

2 个答案:

答案 0 :(得分:0)

好吧,让我先说一下:我不确定我有答案,因为我无法复制你的问题(你的代码没有运行......),由于某种原因,我仍然无法发表评论。但我想我可以帮助你。

予。看起来你正在分别解决两个ODE,但两次同时使用vecotr [0 w_max]。您可以(并且我建议)将两个ODE放入一个函数dx = diffeq(args)中,然后简单地将dx作为行向量。您可能遇到的问题是,任何ODE求解器将针对不同的数学函数使用不同的时间步长。现在你可能想用'MaxStep'和'MinStep'调节那个时间步长,但是不要这样做。与简单的积分器相比,您将放松速度和精度以及matlab中ODE求解器的所有优势。你应该将微分方程放在同一个函数中,即使它们根本没有逻辑连接。您可以更轻松地处理数据。

II。一旦你解决了同一函数中的两个微分方程,因此在同一个ode45 / ode23的运行中,它们将具有完全相同的时间向量。此外,解决方案向量将具有相同的大小。比较它们应该是一件容易的事。但是,我不明白你怎么不能“连接”这些数字。因为如果你总是使用'​​plot(x,y)'而不是'plot(y)'进行绘图,那么它们应该完美对齐。例如:

 figure

 plot(t1,y1)

 hold on

 plot(t2, y2)

你会注意到我使用't1'和't2',你应该这样做。在你当前的代码中,你用第二个't'覆盖你的第一个't',这对于调试是不好的。

III。只是另一个建议:你正在做像

这样的事情
 x_n = y(:,1);

 v_n = y(:,2);

相反,您可以为索引创建结构并将变量名存储在那里。然后,您永远不会按编号访问变量,而只能访问这些索引。例如:

 ind.x_n = 1;

 ind.v_n = 2;

以后的微分方程:      dy(ind.x_n)= ...      dy(ind.v_n)= ... 一旦你有更多的代码和更多的状态,它将帮助你很多。

IV。这让我想到了最后一点。更多州!你用全局变量做的事情非常非常糟糕!调试几乎是不可能的,你的代码也会慢下来。我在diffeq中使用过一次全局变量,并且减速率约为30%。

  • 如果你有变量,你需要“生存”一个步骤,让我们假设你想在下一步中使用旧的'F1',那么你应该从中获得一个状态。这当然意味着,你实际上可以推导它。我不知道你在模拟什么,所以我说不出来。试试吧!

  • 如果您有变量,您只在一个时间步骤中计算并且仅在特定时间步骤中需要它们,则实际上不需要将变量设置为全局变量。它只会造成伤害!

我希望这不是太多,它帮助了你。如果没有,请提供指向git存储库的链接,例如可执行代码。这样它只是一个猜谜游戏......

答案 1 :(得分:0)

我用这个:

yy=y(:,1);
tt=t;
figure(3),plot(t+tt(end),abs((y(end:-1:1,1))),tt,yy);

其中(t,y)来自第一个ODE,(tt,yy)来自第二个。也许可以为某人提供帮助