我正在试图弄清楚如何在Simulink模型中解决子系统内的ODE系统。基本上,每次调用此子系统(在模拟时钟的每个刻度处发生(固定步骤))都需要求解ODE。因此,子系统就像是一个不同的“时钟”。
我有一个M文件,它实现了ODE系统的功能。目前,我有一个MATLAB功能块。它需要很多参数,我可以从基础工作区获得(通过evalin
并在开头使用coder.extrinsic('evalin')
)。但我不允许定义function_handle对象或内部函数来参数化ode *使用的函数。我想如果我能够解决这个区块中的ODE,我就能解决我的问题。但这些限制正在“破坏”它。
如果您对如何实现这一目标有任何想法,我将不胜感激。我欢迎不同的方法。
谢谢。
修改
下面给出一个简单的例子。它试图通过随机改变mu
参数来解决van der Pol方程。这是我目前的主要想法,因为上面提到的问题而无效。
这是子系统的主要模型:
这是子系统:
这是MATLAB功能块实现(注意@符号中有错误,因为不允许定义function_handle对象):
答案 0 :(得分:3)
只需将MATLAB功能块用作包装器即可。将大部分代码放入“标准”MATLAB函数(即可从MATLAB调用,而不是MATLAB函数块),并从MATLAB函数块调用该函数(在将其定义为coder.extrinsic之后)。
答案 1 :(得分:1)
这比Phil Goddard's solution复杂一点。优点是它允许您在必要时生成独立代码,而外部函数与独立代码生成不兼容。
从MATLAB R2014b开始,代码生成支持函数ode23
和ode45
,因此,如果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
添加更多参数。