S-function是系统函数(System Function)的简称,可以十分方便地用来描述各种动态系统,尤其是复杂的动态系统,属于simulink动态系统的核心。我们常用的Simulink工具箱都是通过S-Function实现的,如果想开发一个新的模块或工具箱,S-Function可能是最好的选择。
今天,将分两部分内容来介绍S-Function。
1)S-Function简介:简要介绍S-Function的关键信息,理解S-Function的工作过程。
2)电机模型的S-Function实现:以直流电机这一物理对象作为代表,通过S-Function实现电机的动态过程设计。
之前写过一篇文章《Simulink中4种电机建模方式》,有朋友留言比较完美但缺少S-Function,今天借着这个机会一并补上。
1、S-Function简介
学习S-Function的最佳方式是先熟悉Matlab自带的模板,一般在以下路径:C:\Program Files\MATLAB\toolbox\simulink\blocks。
一共40多行代码,主要包括1个主函数和6个子函数,模板代码如下:
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(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 DAS('Simulink:blocks:unhandledFlag', num2str(flag)); end function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; = 0; = 0; = 0; = 0; = 1; = 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) sys = []; function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];
主函数:通过flag来选择执行对应的子函数。
mdlInitializeSizes:定义系统的初始条件、采样时间等。
mdlDerivatives:计算连续状态的微分,即dx/dt。
mdlUpdate:计算离散状态x(K+1)。
mdlOutputs:计算输出y。
mdlGetTimeOfNextVarHit:计算离散状态的下一次采样时间。
mdlTerminate:结束函数。
需要注意的是,对于特定的系统可能仅需要调度部分子函数即可完成系统的设计。例如,对于仅存在连续状态的系统,只需要调度mdlInitializeSizes、mdlDerivatives、mdlOutputs、mdlTerminate等4个子函数。这些都是S-Function通过flag去自动实现的。
2、电机模型的S-Function实现
在介绍以前,先回顾一下前面介绍的状态空间搭建电机模型的方法。
选取电流I、转速w作为状态变量,转速w作为输出,直流电机的状态方程和输出方程可表达为:
式中红色部分分别对应系统矩阵A、b、C。使用State-Space模块,完成以上的状态方程搭建,模型如下图。
使用S-Function搭建电机模型时,会借用到上面的参数A、b、C。具体搭建步骤如下:
1)把模板改为mo,并新建一个空的mdl文件,也可以命名为modl。
两个文件放在一起并置于当前目录下,不然m文件后面无法被mdl文件引用。
2)在工具箱中找到S-Function模块,并拖入模型中。
双击打开,将S-Function name设置为motor,S-Function parameter设置为A、b、C。
3)点击Edit,即可打开mo文件,进行电机模型设计,修改部分代码,如下面注释。
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag,A,b,C) %%增加参变量 switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; case 1, sys=mdlDerivatives(t,x,u,A,b); %%增加参变量 case 2, sys=mdlUpdate(t,x,u); case 3, sys=mdlOutputs(t,x,u,C); %%增加参变量 case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); case 9, sys=mdlTerminate(t,x,u); otherwise DAS('Simulink:blocks:unhandledFlag', num2str(flag)); end function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; = 2; %%2个状态变量 = 0; = 1; %%单输入 = 1; %%单输出 = 1; = 1; sys = simsizes(sizes); x0 = [0 0]; %%初始状态为0 str = []; ts = [0 0]; simStateCompliance = 'UnknownSimState'; function sys=mdlDerivatives(t,x,u,A,b) %%增加参变量 sys = A*x + b*u; %%计算状态变量的导数 function sys=mdlUpdate(t,x,u) sys = []; function sys=mdlOutputs(t,x,u,C) %%增加参变量 sys = C*x; %%计算输出 function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];
4)在mdl模型中添加对应的输入,并与状态空间的建模方式对比,如下图。
仿真结果如下图所示,可以看出,两种方法的电机转速曲线完全一致,S-Function的电机建模正确。
以上,以电机模型为例,介绍了利用S-Function的方式来描述系统动态过程的方法。