概述
前言:
构建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'解算器,如下:
运行模型,得到结果:
欢迎小伙伴关注我的公众号!
最后
以上就是自然康乃馨为你收集整理的Simulink学习笔记——S-Function的全部内容,希望文章能够帮你解决Simulink学习笔记——S-Function所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复