2017-03-27 88 views
0

我是相當新的Matlab和這個ODE求解器,下面是我的代碼:Matlab的ODE求解永遠困由於小步長

的main.m

format short; 

tspan=[0 5]; 
y0=[0.30;-0.30;0;-0;0]; 


[t,y]=ode23s(@(t,y) pend(t,y),tspan,y0); 

figure(1) 
%subplot(2,1,1); 
plot(t,y(:,1),t,y(:,2),'k--') 
set(gcf,'Position',[100,500,450,180]); 
xlabel('time [s]'); 
legend('q_1','q_2') 
ylabel('leg angle [rad]'); 

figure(2) 
%subplot(2,1,2); 
plot(t,y(:,5)) 
set(gcf,'Position',[100,500,450,180]); 
xlabel('time [s]') 
ylabel('locomotion [m]') 

pend.m

%the following function contains the right hand side of the 
%differential equation of the form 
%M(t,y)*y'=F(t,y) 
%i.e. it contains F(t,y).it is also stored in a separate filenamed, pend.m. 
function yp= pend(t,y) 
m = 5;     %leg masses [kg]  suggested: 5 
       %'shin' length [m]  suggested: 0.5 
b = 0.5;    %'thigh' length [m]  suggested: 0.5 

L = 2*b; 

q=y(1:2); 
dq=y(3:4); 
Ox=y(5); 

rho=0; 

k0=50; %Nm/rad 

v = 0; 
Hsw= L*cos(q(1)); % Height of leg1 
Hst= L*cos(q(2)); % Height of leg2 
H1 = L - Hsw; 
H2 = L - Hst; 

if dq(1)<0 
    Fid1=1; 
else Fid1=0; 
end 
if dq(2)<0 
    Fid2=1; 
else Fid2=0; 
end  

F1 = -15000*min(H1-0.03*L,0)*Fid1; %N 
F2 = -15000*min(H2-0.03*L,0)*Fid2; 

Fc1 = F1*L*sin(q(1)); 
Fc2 = F2*L*sin(q(2)); 

Fc=[Fc1;Fc2]; 
M=[m*b^2 0;0 m*b^2]; 
Ko=k0*[1 -1; -1 1]+m*9.8*b*[1 0; 0 1]; 
D=M; 

ddq=inv(M)*(-rho*D*dq-Ko*q+Fc); 

dOx=0; 
if Fid1==1 
    dOx=-L*dq(1)*cos(q(1))*sign(F1); 
end 
if Fid2==1 
dOx=-L*dq(2)*cos(q(2))*sign(F2); 
end 

yp=[dq;ddq;dOx]; 

我在這裏面臨的問題是時間跨度t隨着時間的推移會隨着時間的推移而逐漸減小,例如在20秒內爲0.1到0.8,在5分鐘內爲0.8到0.9等,這意味着它永遠不會達到時間限制,因此停留在循環中。

我試過不同的解算器,如ode45也嘗試給RelTol和AbsTol的不同值來控制步長,但失敗。它在前幾個步驟中確實有所作爲,但隨後又一次變得緩慢。

當我使用解算器ode15s,它給出了一個警告

「失敗在t = 9.246943e-01。無法滿足集成公差 而不減小步長低於最小允許值 (1.776357e -15)在時間t「。

並且只繪製圖表直到0.92秒。

歡迎任何建議或幫助解決此問題。

謝謝。

回答

0

具有自適應步長的ODE求解器需要平滑的ODE函數。第四階求解器預計ODE函數至少是連續可微的4倍。

您的ODE函數有跳躍和扭結。解算器將它們感知爲非常大且混亂振盪的較高微分值。爲了補償和恢復收斂順序,步長減小,進一步增加計算的微分值,因爲你的函數不是真正可微分的,直到步長增量變得小於最小有效浮點增量,觸發你所看到的錯誤。

使用"events"停止並重新啓動整合過程,恰好是那些不平滑的模型更改。