matlab环境下的参数检索

matlab环境下的参数检索,matlab,parameters,ode,Matlab,Parameters,Ode,我正在Matlab中试验ode45。我已经学会了如何将参数传递给ode函数,但我仍然有一个问题。假设我想计算汽车的轨迹(速度曲线),我有一个函数,例如,getAcceleration,它给我汽车的加速度,但也给我正确的档位:[acceleration,gear]=getAcceleration(speed,modelStructure),其中modelStructure表示汽车的模型 ode功能将是: function [dy] = car(t,y,modelStructure) dy

我正在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(…)
的东西,还是
gear
应该在
y
向量内


我一直在编写代码,并使用事件功能,现在我能够获得汽车“档位”的变化(作为事件)。 现在我遇到了一个与同一代码相关的新问题。 想象一下,当我计算de'dy'向量时,我能够得到一个更进一步的值Z,这让我可以大大加快调用加速度计算(getAcceleration)的速度:

假设我也能在初始条件下计算Z。问题是我不能计算Z导数

有没有一种方法可以传递Z值而不积分步进


谢谢大家。

首先:为什么微分方程的初始值是初始速度(
speedInitial
)和初始加速度(
accelerationInitial
)?这意味着微分方程
car
将计算加速度(
y(1)
)和急动(
y(2)
),即每次
t
时加速度的时间导数。这似乎不正确……我认为初始值应该是初始位置(
positionInitial
)和初始速度(
speedInitial
)。但是,我不知道你的模型,我可能错了

现在,直接在解决方案中获得
装备
:你不能,除非黑客
ode45
。这也是合乎逻辑的;您也不能一直直接获得dy,对吗?这不是
ode45
的设置方式

我在这里看到了两条出路:

全局变量 免责声明:不要使用此方法。这里只是为了展示大多数人在第一次尝试时会做些什么。

您可以将
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
的性质,这将获得一个时间数组
ts
和相关
gear
,其中包含中间点和/或被
ode45
拒绝的点。因此,您必须在之后过滤这些内容:

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
本身使用的要多得多。但这只是一个真正的问题,如果每次对
汽车
的评估都需要几秒钟或更长的时间,我怀疑在您的设置中并非如此

嗨,罗迪!谢谢你的回答!首先,关于初始条件,你是完全正确的:它们应该是speedInitial和positionInitial。由于这个限制,我很惊讶,如果我有一个与齿轮相关的事件呢?我的意思是,在集成过程中有一种“齿轮控制”是可能的,也是可行的,我该怎么做呢?我是否使用了错误的积分方法?再次感谢。@MatlabUser:关于
ode45
,有很多东西需要学习。例如,您的建议可以通过使用所谓的事件函数来实现;看见可能需要一段时间才能掌握,但完全值得;这是一个非常强大的概念,我还没有在任何其他语言的任何其他工具中遇到过。@MatlabUser:另外,正如我所说的:这并不是一个真正的限制。很简单,你所做的已经远远超出了任何常规的常规颂歌,
ode45
的目的!我会听从你的建议,调查事件的使用情况。非常感谢。
gear = zeros(size(t));
for ii = 1:numel(t)
    [~, gear(ii)] = car(t(ii), y(ii,:).', modelStructure); 
end