3

我试图弄清楚如何在 Simulink 模型的子系统中求解 ODE 系统。基本上,在模拟时钟的每个滴答声(固定步长)发生的对该子系统的每次调用都需要求解 ODE。所以子系统有一个不同的“时钟”。

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

如果您对如何完成此操作有任何想法,我将不胜感激。我欢迎不同的方法。

谢谢你。

编辑

下面给出一个简单的例子。mu它试图通过随机改变参数来求解范德波尔方程。这是我目前的主要想法,由于上面提到的问题,它不起作用。

这是子系统的主要模型:

在此处输入图像描述

这是子系统:

在此处输入图像描述

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

在此处输入图像描述

4

2 回答 2

3

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

于 2015-08-27T15:59:23.650 回答
1

这将比Phil Goddard 的解决方案复杂一些。优点是它允许您在必要时生成独立代码,而外部函数与独立代码生成不兼容。

从 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如果您需要更多参数,您可以添加更多参数。

于 2015-08-29T19:48:43.720 回答