我正在模擬具有質量彈簧和雙擺的(有點奇怪的)系統的運動方程,爲此我有一個質量矩陣和函數f(x),並調用ode45解決在Matlab中將衍生值保存在ode45中
M*x' = f(x,t);
我有5個狀態變量,q = [QDOT,PHI,phiDot,R,rDot]'; (刪除Q因爲沒有什麼依賴於它,QDot是最新的。) 現在,爲了計算一些力量,我還想保存rDotDot的計算值,ode45計算每個積分步驟的計算值,但是ode45不會給出這個結果。我已經搜索了一下,但是我發現的唯一的兩個解決方案是 a)將它變成一個三階問題,並將phiDotDot和rDotDot添加到狀態向量中。我想盡可能地避免這種情況,因爲它已經是非線性的,這實際上使事情變得更糟,並縮短了計算時間。
b)增加狀態直接計算函數,如here所述。然而,在他說的例子中,在質量矩陣中添加了一行零。它是有道理的,因爲否則它將整合導數,而不僅僅是在一點上評估它,但另一方面它使質量矩陣單數。似乎沒有爲我工作...
這似乎是這樣一個基本的東西(想要的狀態向量的派生值),有沒有很明顯,我沒有想到? (或者不太明顯的東西也可以......)
哦,全局變量不是很好,因爲ode45幾次調用f()函數,同時細化它的步驟,所以全局變量的大小和返回的狀態向量q完全不匹配。
萬一有人需要它,下面的代碼:
%(Initialization of parameters are above this line)
options = odeset('Mass',@massMatrix);
[T,q] = ode45(@f, tspan,q0,options);
function dqdt = f(t,q,p)
% q = [qDot phi phiDot r rDot]';
dqdt = zeros(size(q));
dqdt(1) = -R/L*q(1) - kb/L*q(3) +vs/L;
dqdt(2) = q(3);
dqdt(3) = kt*q(1) + mp*sin(q(2))*lp*g;
dqdt(4) = q(5);
dqdt(5) = mp*lp*cos(q(2))*q(3)^2 - ks*q(4) - (mb+mp)*g;
end
function M = massMatrix(~,q)
M = [
1 0 0 0 0;
0 1 0 0 0;
0 0 mp*lp^2 0 -mp*lp*sin(q(2));
0 0 0 1 0;
0 0 mp*lp*sin(q(2)) 0 (mb+mp)
];
end
嗨,+1爲優秀的答案,並帶來很多功能,我沒有注意到我的注意!但我使用Adrian的解決方案,僅僅因爲它更簡單。稍後可能會在你的程序中實現它,因爲在運行時也可以繪製加速度。謝謝!:) – 2013-05-14 11:18:02
@Rody Oldenhuis除了'deriv = f(t,q)',還有'f(t,q)'內的其他變量,這個方法還能輸出其他依賴於時間的輸出嗎? – kyle 2016-06-27 04:29:25
@kww取決於當然的具體情況......你有什麼想法? – 2016-06-27 08:03:08