首页 文章

在Simulink中解决子系统内的ODE

提问于
浏览
2

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

我有一个M文件,它实现了ODE系统的功能 . 目前,我有一个MATLAB功能块 . 它需要很多参数,我可以从基础工作区获得(通过 evalin 并在开头使用 coder.extrinsic('evalin') ) . 但我'm not allowed to define function_handle objects or inner functions to parameterize the function that is used by ode*. I think that if I'能够解决这个区块中的ODE,我已经解决了我的问题 . 但这些限制是"ruining"它 .

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

谢谢 .

EDIT

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

这是子系统的主要模型:

enter image description here

这是子系统:

enter image description here

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

enter image description here

2 回答

  • 1

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

  • 3

    这将比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 添加更多参数 .

相关问题