Simulink学习笔记——S-Function

    前言:

          构建S函数大致分为四种方法:M语言的S函数、C Mex S函数、利用S-Function Builder模块以及利用Legacy Code Tool模块。本文先讲解利用Level 1 M S函数模板搭建的S函数模块,然后介绍比较常用的且门槛低的S函数构建方法 ——  利用S-Function Builder模块。

一、熟悉 Level 1 M S函数模板

    已知我们的状态空间方程为:dx=-x+u;y=x,对应的系统传递函数为G=1/(s+1),搭建模型如下所示:

其中Parameter Initialization 用于初始化参数 x_initial,如下所示:

我们双击S-Function模块,可以看到对话框如下:

单击 Edit,可以看到基于Level 1 M S函数模板写的S函数,如下所示:

运行程序,可以看到:

显然,两个结果是一样的。

二、利用Level 1 M S函数模板构建分段函数

     熟悉了模板以后,我们就可以自己动手实现一些简单的需求,假如我们需要构建一个如下所示的分段函数:

现在我们搭建模型,如下所示:

双击S-function模块,如下:

点击Edit,查看我们利用该模板写的S函数:

function [sys,x0,str,ts,simStateCompliance] = fenDuan_func(t,x,u,flag)

switch flag,

  case 0,
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;

  case 1,
    sys=mdlDerivatives(t,x,u);
    
  case 2,
    sys=mdlUpdate(t,x,u);

  case 3,
    sys=mdlOutputs(t,x,u);

  case 4,
    sys=mdlGetTimeOfNextVarHit(t,x,u);


  case 9,
    sys=mdlTerminate(t,x,u);

  otherwise
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));

end


function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes;

sizes.NumContStates  = 0;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;  

sys = simsizes(sizes);
x0  = [];
str = [];
ts  = [0 0];

simStateCompliance = 'UnknownSimState';

function sys=mdlDerivatives(t,x,u)

sys = [];


function sys=mdlUpdate(t,x,u)

sys = [];


function sys=mdlOutputs(t,x,u)
if u<1
    sys = 3 * sqrt(u);
elseif  u>=1 && u<3
    sys = 3;
elseif  u>=3 && u<4
    sys = 3 -(u-3)^2; 
elseif  u>=4 && u<5
    sys = 2;
elseif  u>=5 && u<6
    sys = 2 -(u-5)^2; 
else
    sys = 1;
end


function sys=mdlGetTimeOfNextVarHit(t,x,u)

sampleTime = 1;   
sys = t + sampleTime;

function sys=mdlTerminate(t,x,u)

sys = [];


显然,算法实现的部分在mdlOutput函数部分。

运行模型,得到结果如下:

三、利用Level 1 M S函数模板完成信号的叠加

      假如我现在有两个信号,一个是正弦信号,一个是随机信号,我需要把这两个信号进行叠加,如下所示:

      当然这非常的简单,用加法模块就可以完成,但是我想利用S函数模块来做,也是一个很简单的应用。首先我们搭建模型如下:

其中Parameter Initialization 用于初始化参数 A(如果是减法运算,这里可以改成A=[1  -1]),如下所示:

双击S-function模块,如下:

点击Edit,查看我们利用该模板写的S函数:

function [sys,x0,str,ts,simStateCompliance] = my_sfunc(t,x,u,flag,A)

switch flag,

  case 0,
    [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;

  case 1,
    sys=mdlDerivatives(t,x,u);
    
  case 2,
    sys=mdlUpdate(t,x,u);

  case 3,
    sys=mdlOutputs(t,x,u,A);

  case 4,
    sys=mdlGetTimeOfNextVarHit(t,x,u);

  case 9,
    sys=mdlTerminate(t,x,u);

  otherwise
    DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));

end


function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes

sizes = simsizes;

sizes.NumContStates  = 0;
sizes.NumDiscStates  = 0;
sizes.NumOutputs     = 1;
sizes.NumInputs      = 2;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;  

sys = simsizes(sizes);
x0  = [];
str = [];
ts  = [0 0];

simStateCompliance = 'UnknownSimState';

function sys=mdlDerivatives(t,x,u)

sys = [];


function sys=mdlUpdate(t,x,u)

sys = [];


function sys=mdlOutputs(t,x,u,A)
sys =  A * u ;


function sys=mdlGetTimeOfNextVarHit(t,x,u)

sampleTime = 1;   
sys = t + sampleTime;

function sys=mdlTerminate(t,x,u)

sys = [];


运行模型,得到结果如下所示:

显然,两个结果是一样的。

四、S-Function Builder模块

       接下来我们构建一个简单的滤波程序 ,首先添加S-Function Builder模块以及相关的模块到模型中,如下所示:

         使用S-Function Builder对话框可以指定由S-Function Builder块构建的S函数的属性。 双击S-Function Builder模块图标,得到如下界面:

设置Initialization页面,如下所示:

Data Properities页面上设置输入输出端口属性及参数属性,如下所示:

在Outputs页面输入计算模块输出的代码:

在Discrete Update页面输入代码:

将参数filter_coef设置为double类型,其值设置为0.005,然后再单击右上角的Build按钮,如下:

可以看到成功编译:

设置模型的jie'解算器,如下:

运行模型,得到结果:

   

猜你喜欢

转载自blog.csdn.net/weixin_41695564/article/details/81149673