Matlab ode45检索参数 [英] matlab ode45 retrieving parameters
问题描述
我正在Matlab中试用ode45.我已经学习了如何将参数传递给ode函数,但是我仍然有一个问题.假设我想计算汽车的轨迹(速度曲线),并且有一个函数,例如getAcceleration
,它给了我汽车的加速度,但也给了我正确的档位:[acceleration, gear] = getAcceleration(speed,modelStructure)
其中,modelStructure
代表汽车的型号.
I'm experimenting with ode45 in Matlab. I've learned how to pass parameters to the ode function but I still have a question. Let's suppose that I want to compute the trajectory (speed profile) of a Car and I have a function, e.g. getAcceleration
, that gives me the acceleration of the car but also the right gear: [acceleration, gear] = getAcceleration(speed,modelStructure)
where modelStructure
represents the model of the car.
ode函数为:
function [dy] = car(t,y,modelStructure)
dy = zeros(2,1);
dy(1) = y(2);
[dy(2),gear] = getAcceleration(y(1),modelStructure);
然后我以这种方式称呼Ode45集成商:
Then I call the Ode45 integrator in this way:
tInit = 0;
tEnd = 5,
[t,y] = ode45(@car,[tInit tEnd], [speedInitial,accelerationInitial],options,modelStructure);
问题是:如何获得向量存储齿轮?我应该有类似[t,y,gear]=ode45(....)
的东西还是gear
应该在y
向量之内?
The problem is: how do I get the vector storing gears? Should I have something like [t,y,gear]=ode45(....)
or should gear
be within the y
vector?
我一直在编写代码,并使用事件功能,现在可以获取汽车的齿轮"变化(作为事件). 现在,我有一个与相同代码有关的新问题. 想象一下,当我评估"dy"向量时,我可以得到另一个值Z,这使我可以极大地提高加速度计算(getAcceleration)的速度:
I've been working on my code and using the events function I'm now able to get the car 'gears' changes (as events). Now I have a new problem related to the same code. Imagine that when I evaluate de 'dy' vector I'm able to get a further value Z which let me to have a massive speed up calling the acceleration computation (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导数.
and suppose that I'm also able to compute Z at the initial condition. The problem is that I'm not able to compute the Z derivative.
有没有一种方法可以传递Z值而不整合步进?
Is there a way to pass Z value throw the stepping without integrating it?
谢谢大家.
推荐答案
首先:为什么微分方程的初始值是初始速度(speedInitial
)和初始加速度(accelerationInitial
)?这意味着,微分方程car
将在每次t
处计算加速度(y(1)
)和加速度率(y(2)
),即加速度的时间导数.这似乎是不正确的...我想说初始值应该是初始位置(positionInitial
)和初始速度(speedInitial
).但是,我不知道您的模型,我可能是错的.
First off: why are the initial values to the differential equation the initial speed (speedInitial
) and the initial acceleration (accelerationInitial
)? That means that the differential equation car
will be computing the acceleration (y(1)
) and the jerk (y(2)
), the time-derivative of the acceleration, at each time t
. That seems incorrect...I would say the initial values should be the initial position (positionInitial
) and the initial speed (speedInitial
). But, I don't know your model, I could be wrong.
现在,直接在解决方案中获得gear
:您不能,除非没有破解ode45
.这也是合乎逻辑的;您也不能一直都直接获取dy
,可以吗?但这不是设置ode45
的方式.
Now, getting the gear
in the solution directlty: you can't, not without hacking ode45
. This is also logical; you also cannot get dy
at all times directly, can you? That's just not how ode45
is set up.
我在这里看到两种解决方法:
There's two ways out I see here:
免责声明 :请勿使用此方法.只是在这里显示大多数人会做的第一次尝试.
您可以将gear
存储在全局变量中.它可能是最少的编码量,但也是最不方便的结果:
You can store gear
in a global variable. It's probably the least amount of coding, but also the least convenient outcome:
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
的性质,这将为您提供一系列时间ts
和关联的gear
,其中包含中间点和/或被ode45
拒绝的点.因此,您之后必须对这些内容进行过滤:
But, due to the nature of ode45
, this will get you an array of times ts
and associated gear
which contains intermediate points and/or points that got rejected by ode45
. So, you'll have to filter for those afterwards:
ts( ~ismember(ts, t) ) = [];
我再说一遍:这是我推荐的方法 不 .仅在测试或执行一些快速处理工作时才使用全局变量,但始终非常迅速地转向其他解决方案.同样,全局变量在ode45
的每个(子)重复项处增长,这是不可接受的性能损失.
I'll say it again: this is NOT the method I'd recommend. Only use global variables when testing or doing some quick-n-dirty stuff, but always very quickly shift towards other solutions. Also, the global variables grow at each (sub-)iteration of ode45
, which is an unacceptable performance penalty.
最好使用下一种方法:
对于您的情况,这也不是一件难事,也是我建议您采取的方式.首先,如下修改微分方程,然后按正常方式求解:
This is also not too hard for your case, and the way I'd recommend you to go. First, modify the differential equation as below, and solve as normal:
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
完成后,执行以下操作:
and then after ode45
completes, do this:
gear = zeros(size(t));
for ii = 1:numel(t)
[~, gear(ii)] = car(t(ii), y(ii,:).', modelStructure);
end
这有时会为您提供汽车所需的所有挡位(c11).
That will get you all the gears the car would have at times t
.
我在这里看到的唯一缺点是,与ode45
单独使用相比,您对car
进行的函数评估要多得多.但是,如果每个car
评估时间都在几秒或更长时间内,这只是一个实际问题,我怀疑在您的设置中情况并非如此.
The only drawback that I can see here is that you'll have many more function evaluations of car
than ode45
would use by itself. But this is only a real problem if each evaluation of car
takes in the order of seconds or longer, which I suspect is not the case in your setup.
这篇关于Matlab ode45检索参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!