matlab环境下的参数检索
我正在Matlab中试验ode45。我已经学会了如何将参数传递给ode函数,但我仍然有一个问题。假设我想计算汽车的轨迹(速度曲线),我有一个函数,例如,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
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