3

Matlabでode45を試しています。パラメータをode関数に渡す方法を学びましたが、まだ質問があります。車の軌道(速度プロファイル)を計算したいとします。たとえばgetAcceleration、車の加速度だけでなく、適切なギアも与える関数があります。[acceleration, gear] = getAcceleration(speed,modelStructure)ここmodelStructureで、は車のモデルを表します。

ode関数は次のようになります。

function [dy] = car(t,y,modelStructure)

dy           = zeros(2,1);
dy(1)        = y(2);
[dy(2),gear] = getAcceleration(y(1),modelStructure);

次に、このようにOde45インテグレーターを呼び出します。

tInit = 0;
tEnd  = 5,
[t,y] = ode45(@car,[tInit tEnd], [speedInitial,accelerationInitial],options,modelStructure);

問題は、ベクトル格納ギアを取得するにはどうすればよいですか?私はのようなものを持っているべきですか、それともベクトル内にある[t,y,gear]=ode45(....)べきですか?geary


私は自分のコードに取り組んでおり、イベント関数を使用して、車の「ギア」の変更を(イベントとして)取得できるようになりました。今、私は同じコードに関連する新しい問題を抱えています。de'dy'ベクトルを評価すると、さらに値Zを取得できると想像してください。これにより、加速度計算(getAcceleration)の呼び出しを大幅に高速化できます。

function [dy] = car(t,y,modelStructure)

dy           = zeros(2,1);
dy(1)        = y(2);
[dy(2),Z(t)] = getAcceleration(y(1),modelStructure,Z(t-1)); 

また、初期条件でZを計算できると仮定します。問題は、Z導関数を計算できないことです。

Z値を渡して、それを統合せずにステッピングをスローする方法はありますか?

みんなありがとう。

4

1 に答える 1

5

最初に: 微分方程式の初期値がなぜ初速度 ( speedInitial) と初加速度 ( accelerationInitial) なのですか? つまり、微分方程式は、加速度 ( ) とジャーク ( ) (加速度の時間微分) を各時間 でcar計算します。それは間違っているようです...初期値は初期位置()と初期速度()でなければなりません。しかし、私はあなたのモデルを知りません、私は間違っているかもしれません.y(1)y(2)tpositionInitialspeedInitial

さて、gearソリューションを直接取得します。ハッキングせずにはできませんode45。これも論理的です。あなたもdyいつも直接手に入れることはできませんよね?それode45は設定方法ではありません。

私がここに見る2つの方法があります:

グローバル変数

免責事項:この方法は使用しないでください。ここでは、ほとんどの人が最初の試みとして何をするかを示しています。

gearグローバル変数に格納できます。これはおそらくコーディングの量が最も少ないですが、最も不便な結果でもあります。

global ts gear ii

ii    = 1;
tInit = 0;
tEnd  = 5,
[t,y] = ode45(...
    @(t,y) car(t,y,modelStructure), ...
    [tInit tEnd], ...
    [speedInitial, accelerationInitial], options);

...

function [dy] = car(t,y,modelStructure)
global ts gear ii

dy    = zeros(2,1);
dy(1) = y(2);
[dy(2),gear(ii)] = getAcceleration(y(1),modelStructure);

ts(ii) = t;
ii = ii + 1;

ただし、 の性質上、これにより、によって拒否された中間ポイントおよび/またはポイントを含む時間と関連付けode45の配列が得られます。したがって、後でそれらをフィルタリングする必要があります。tsgearode45

ts( ~ismember(ts, t) ) = [];

もう一度言いますが、これは私がお勧めする方法ではありません。グローバル変数を使用するのは、テストや簡単な作業を行うときだけですが、常にすぐに他のソリューションに移行してください。また、グローバル変数は の (サブ) 反復ごとに大きくなりますode45。これは許容できないパフォーマンス ペナルティです。

次の方法を使用することをお勧めします。

解決後のコール

これもあなたの場合にはそれほど難しいことではなく、私がお勧めする方法です。まず、微分方程式を次のように修正し、通常どおりに解きます。

tInit = 0;
tEnd  = 5,
[t,y] = ode45(...
    @(t,y) car(t,y,modelStructure), ...
    [tInit tEnd], ...
    [speedInitial, accelerationInitial], options);

...

function [dy, gear] = car(t,y,modelStructure)    

dy    = [0;0];
dy(1) = y(2);
[dy(2),gear] = getAcceleration(y(1),modelStructure);

ode45完了したら、次のようにします。

gear = zeros(size(t));
for ii = 1:numel(t)
    [~, gear(ii)] = car(t(ii), y(ii,:).', modelStructure); 
end

これにより、車が時々持っているすべてのギアが得られますt

ここで見られる唯一の欠点は、単独で使用するcarよりも多くの関数評価が必要ode45になることです。carしかし、これは、 の各評価に数秒以上かかる場合にのみ、実際の問題になります。これは、セットアップでは当てはまらないと思われます。

于 2012-11-27T08:13:43.137 に答える