2013-05-28 45 views
-1

我有一個ODE求解器,工程很好,很流暢,但我需要在一個圖中繪製所有圖。連接圖(1)+(3)和圖(2)+(4),我必須設置啓動和停止條件,但它不適用於我,我是在死衚衕。我試圖用x_m設置結束條件而沒有結果。ODE函數的連續繪圖

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]; 
+0

你是什麼意思連接? – HebeleHododo

+0

類似@HebeleHododo評論,你想要一切都繪製在一個情節,或者你想要4個副劇? –

+0

連續功能。當ph1結束時,在一個繪圖中啓動ph2 – user2401142

回答

0

好讓我這樣說第一:我不知道我有,我不能複製你的問題的回答(你的代碼犯規運行...),並由於某種原因,我還不能發表評論。但我想我可以幫助你。

I.看起來你正在分別求解兩個ODE,但是兩個時間都是同一時間vecotr [0 w_max]。你可以(我建議)將兩個ODE放入一個函數dx = diffeq(args),並簡單地將dx作爲一個行向量。您可能遇到的問題是任何ODE求解器都會針對不同的數學函數使用不同的時間步長。現在你可能會試圖用'MaxStep'和'MinStep'來調節時間步,但是不要那樣做。與簡單集成器相比,您將失去matlab中ODE解算器的速度和準確性以及所有優勢。您應該將微分方程放入相同的函數中,即使它們根本不是邏輯連接。你處理數據更容易。

二,一旦你在同一個函數中求解了兩個微分方程,並且因此在相同的運行中,他們將具有完全相同的時間向量。另外,解矢量將具有相同的大小。那麼比較它們應該是一件容易的事。但是,我不明白你如何不能「連接」數字。因爲如果你總是用'plot(x,y)'而不是'plot(y)'進行繪圖,他們應該完全對齊。例如:

figure 

plot(t1,y1) 

hold on 

plot(t2, y2) 

你會注意到我使用't1'和't2',你應該這樣做。在你當前的代碼中,你用第二個't'覆蓋你的第一個't',對於調試是不利的。

三,只是一個建議:你正在做的東西一樣

x_n = y(:,1); 

v_n = y(:,2); 

相反,你可以創建索引的結構和變量名存放在那裏。那麼你絕不會通過數字來訪問變量,而只能通過這些索引來訪問變量例如:

ind.x_n = 1; 

ind.v_n = 2; 

後來在微分方程: DY(ind.x_n)= ... DY(ind.v_n)= ... 它會幫助你很多,一旦你有更多的代碼和更多的狀態。四,參考文獻這使我想到最後一點。更多的州!你用全局變量做的事情非常非常糟糕!調試幾乎是不可能的,而且你的代碼變慢了。我在diffeq中使用了一次全局變量,並且減速了大約30%。

  • 如果你有變量,你需要「生存」一個時間步長,可以說你想用你的老「F1」在下一步,那麼你應該做的狀態出來。這當然意味着,你實際上可以得到它。我不知道你在模擬什麼,所以我不知道。去嘗試一下!

  • 如果你有變量,你只能在一個時間步中計算出來,並且只需要它們,那麼實際上就不需要使變量變成全局變量。它只會傷害!

我希望這不是太多,它幫助你。如果沒有,請提供一個鏈接到git倉庫,例如使用可執行代碼。這樣,它只是一個猜謎遊戲...

+0

僅供參考,我不認爲您首先猜測哪些海報正在做什麼(或嘗試做)是正確的。看[這個問題](http://stackoverflow.com/questions/16768447/matlab-ode-start-stop-conditions)。兩個ODE不能同時模擬,因爲第二個ODE的初始條件取決於第一個(通過事件)的終止狀態。當然,這裏的代碼根本就沒有表現出來,或者說清楚了。 – horchler

+0

而你對全局變量的討論就在眼前。沒有理由在這裏使用它們。 – horchler

+0

@horchler據我所知,需要有一個使用全局變量的理由,而不是相反。功能輸入和輸出應始終有效。特別是在這種情況下,系統是一個諧波振盪器,有更好的選擇。 – Cat

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)從第二。也許可以幫助別人