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),搭建模型如下所示:

Simulink学习笔记——S-Function_第1张图片

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

Simulink学习笔记——S-Function_第2张图片

我们双击S-Function模块,可以看到对话框如下:
Simulink学习笔记——S-Function_第3张图片

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

 

运行程序,可以看到:

Simulink学习笔记——S-Function_第4张图片

Simulink学习笔记——S-Function_第5张图片

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

 

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

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

Simulink学习笔记——S-Function_第6张图片

现在我们搭建模型,如下所示:
Simulink学习笔记——S-Function_第7张图片

双击S-function模块,如下:
Simulink学习笔记——S-Function_第8张图片

点击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函数部分。

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

Simulink学习笔记——S-Function_第9张图片

 

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

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

Simulink学习笔记——S-Function_第10张图片

      当然这非常的简单,用加法模块就可以完成,但是我想利用S函数模块来做,也是一个很简单的应用。首先我们搭建模型如下:
Simulink学习笔记——S-Function_第11张图片

 

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

Simulink学习笔记——S-Function_第12张图片

双击S-function模块,如下:

Simulink学习笔记——S-Function_第13张图片

点击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 = [];


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

Simulink学习笔记——S-Function_第14张图片

Simulink学习笔记——S-Function_第15张图片

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

 

四、S-Function Builder模块

 

 

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

Simulink学习笔记——S-Function_第16张图片

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

Simulink学习笔记——S-Function_第17张图片

设置Initialization页面,如下所示:

Simulink学习笔记——S-Function_第18张图片

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

Simulink学习笔记——S-Function_第19张图片

Simulink学习笔记——S-Function_第20张图片

Simulink学习笔记——S-Function_第21张图片

Simulink学习笔记——S-Function_第22张图片

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

Simulink学习笔记——S-Function_第23张图片

在Discrete Update页面输入代码:

Simulink学习笔记——S-Function_第24张图片

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

Simulink学习笔记——S-Function_第25张图片

可以看到成功编译:

Simulink学习笔记——S-Function_第26张图片

设置模型的jie'解算器,如下:
Simulink学习笔记——S-Function_第27张图片

运行模型,得到结果:
Simulink学习笔记——S-Function_第28张图片

 

   欢迎小伙伴关注我的公众号!

Simulink学习笔记——S-Function_第29张图片

 

你可能感兴趣的:(Simulink)