在Simulink中解决子系统内的ODE

时间:2015-08-27 13:31:45

标签: matlab simulink matlab-coder subsystem

我正在试图弄清楚如何在Simulink模型中解决子系统内的ODE系统。基本上,每次调用此子系统(在模拟时钟的每个刻度处发生(固定步骤))都需要求解ODE。因此,子系统就像是一个不同的“时钟”。

我有一个M文件,它实现了ODE系统的功能。目前,我有一个MATLAB功能块。它需要很多参数,我可以从基础工作区获得(通过evalin并在开头使用coder.extrinsic('evalin'))。但我不允许定义function_handle对象或内部函数来参数化ode *使用的函数。我想如果我能够解决这个区块中的ODE,我就能解决我的问题。但这些限制正在“破坏”它。

如果您对如何实现这一目标有任何想法,我将不胜感激。我欢迎不同的方法。

谢谢。

修改

下面给出一个简单的例子。它试图通过随机改变mu参数来解决van der Pol方程。这是我目前的主要想法,因为上面提到的问题而无效。

这是子系统的主要模型:

enter image description here

这是子系统:

enter image description here

这是MATLAB功能块实现(注意@符号中有错误,因为不允许定义function_handle对象):

enter image description here

2 个答案:

答案 0 :(得分:3)

只需将MATLAB功能块用作包装器即可。将大部分代码放入“标准”MATLAB函数(即可从MATLAB调用,而不是MATLAB函数块),并从MATLAB函数块调用该函数(在将其定义为coder.extrinsic之后)。

答案 1 :(得分:1)

这比Phil Goddard's solution复杂一点。优点是它允许您在必要时生成独立代码,而外部函数与独立代码生成不兼容。

从MATLAB R2014b开始,代码生成支持函数ode23ode45,因此,如果MATLAB版本至少是新版本,则适用。假设这样,您看到的主要限制是代码生成不支持匿名函数。

使用持久变量模拟匿名函数参数

但是,可以使用具有持久性的常规函数​​来模拟这些参数化的匿名函数。要使用参数mu模拟您的函数,请创建一个MATLAB文件odefcn.m

function x = odefcn(t,y)
%#codegen
persistent mu;
if isempty(mu)
  % Adjust based on actual size, type and complexity
  mu = 0;
end
if ischar(t) && strcmp(t,'set')
  % Syntax to set parameter
  mu = y;
else
  x = [y(2); mu*(1-y(1)^2)*y(2)-y(1)];
end

然后在MATLAB功能块中,使用:

function y = fcn(mu)
%#codegen
% Set parameter
odefcn('set',mu);

% Solve ODE
[~,Y] = ode45(@odefcn,[0, 20], [2; 0]);
y = Y(end,1);

这应该适用于模拟和代码生成。如果需要更多参数,可以向odefcn添加更多参数。