Matlab提供的学习资料
在Matlab命令行中输入>> edit sfuntmpl
可获取详细的资料
你觉得S-Function很难学,但是一旦学会,你发现Simulink更加好用了!!
如果有以下需求可以用S-Fuction
(1)被模块化的Simulink搞得晕头转向,想要通过一个函数写出复杂的被控系统
(2)想要保存在时域的变量
(3)控制系统输出较为复杂,难以用function m-function描述
(4)控制系统具有复杂的时变特性
S-Function界面介绍
S-function name:自己定义的名字,一般和.m文件名相同;
S-function parameters:参数,不填
S-function modules :模块,不填
**点击“Edit”,即可进入代码编辑界面**
S-Function 函数结构
[sys,x0,str,ts] = functionName(t,x,u,flag)
%主函数,接收信号后,首先进入这个函数。函数包含一个switch语句,依据case的不同,调用不同的函数。
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
%初始化函数,对被控方程S-Function进行参数设置,类比构造类。
sys=mdlDerivatives(t,x,u)
%仅在连续系统中调用,用于产生系统状态的导数
sys=mdlUpdate(t,x,u)
%仅在离散系统中被调用,顾名思义,产生下一个状态
sys=mdlOutputs(t,x,u)
%产生(传递)系统输出
sys=mdlGetTimeOfNextVarHit(t,x,u)
%获得下一次系统执行(next hit)的时间,该时间为绝对时间。请注意,仅当在采样时间数组中以mdlInitializeSizes指定变量离散时间采样时间[-2 0]时,才使用此函数。
sys=mdlTerminate(t,x,u)
%相当于构析函数(~Class),结束该仿真模块时被调用
S-Function执行顺序
(1)在仿真开始时,执行mdlInitializeSizes;
(2)若系统包含连续部分,则调用mdlDerivatives;若系统包含离散部分,则调用mdlUpdate
(3)调用mdlOutputs,产生输出
(4)若满足条件,则执行mdlGetTimeOfNextVarHit
(5)循环执行1--3,直至仿真停止
(6)执行mdlTerminate,仿真停止
S-Function输入输出参数的含义
1. 输入参数t,x,u,flag介绍
t: 系统时间
x:系统状态
u:系统输入,即为Simulink中输入给S-Function的数据
flag:系统状态,自动生成,返回的flag决定系统当前执行到哪个S-Function子函数
2. 输出参数sys,x0,str,ts,simStateCompliance介绍
sys : 系统本身,可以理解为下一时刻的系统;同时sys的前几个数值(sys[1]等)是系统的输出,即在simulink中S-function伸出线上的数据
x0 : 系统初始状态
str : 状态排序字符串,通常指定为[]。
ts : 可认为是采样时间
simStateCompliance: 指定在保存和恢复模型的完整模拟状态时如何处理此块。允许的值为:“DefaultSimState”、“HasNoSimState”或“DisallowSimState”。
如果未指定该值,则模拟特征的块符合性设置为“UknownSimState”。
mdlInitializeSizes例程与介绍
sizes = simsizes; %调用构造函数,生成一个默认类
sizes.NumContStates = 0; %设置系统连续状态的数量
sizes.NumDiscStates = 0; % 设置系统离散状态的数量
sizes.NumOutputs = 0; % 设置系统输出的数量
sizes.NumInputs = 0; % 设置系统输入的数量
sizes.DirFeedthrough = 1; % 设置系统直接通过量的数量,一般为1
sizes.NumSampleTimes = 1; % 需要的样本时间,一般为1.
% NumSampleTimes : 0 表示没有,即用户在编写 mdlOutputs 子函数时确保子函数的 sys 不出现输入变量u;1 表示有直接联系,即在输出的 sys 中与 u 有直接的联系。
sys = simsizes(sizes); % 创建类对象sys
x0 = []; % 系统初始状态
str = []; % 保留变量,保持为空
ts = [0 0]; % 采样时间
simStateCompliance = 'UnknownSimState';
给个小例子,让你更清楚
该例子是用S-Function构建PID控制器Gc和被控对象Gg.
采用初始化、微分函数和输出函数,即mdlInitializeSizes函数、mdlDerivatives函数、mdlOutputs函数。
==========================================================================
在初始化中采用sizes的结构,选择2个输出,3个输入,3个输入实现了P、I、D三项的输入。
其中初始条件x(0)=0,dx(0)=0
Kp,Ki,Kd = 60,1,3;
另一个S-Function用于生成一个状态空间,转成传递函数和Simulink中133/(s^2+25s)等价,这里不过是状态空间的写法
dx = Ax + Bu
y = Cx + Du
==>
A = [0 1; 0 -25]; B = [0; 133]; C = [1 0]; D = 0;
%%chap3s.m
% u系统输入,即为Simulink中输入给S-Function的数据,这里指控制器提供给函数的三个信号,所以很明显,sizes.NumInputs = 3
function [sys, x0, str, ts] = s_function(t, x, u, flag)
switch flag
case 0
[sys, x0, str, ts] = mdlInitializeSizes;
case 3
sys = mdlOutputs(t,x,u);
case {2, 4, 9}
sys = [];
% Unexpected flags
otherwise
error(['UNhandled flag = ', num2str(flag)]);
end
% 这里说明,因为在前面已经给定控制器的模型,该S-Function的作用只是将Kp,Ki,Kd的值给系统加上
function [sys, x0, str, ts] = mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 0; % 设置连续信号个数
sizes.NumDiscStates = 0; % 设置离散信号个数
sizes.NumOutputs = 1; % 输出信号个数,这里指正弦跟踪误差信号
sizes.NumInputs = 3; % 输入信号个数,这里指PID三个环节的输入
sizes.DirFeedthrough = 1; % 设置系统直接通过量的数量,一般为1
sizes.NumSampleTimes = 0; % 需要的样本时间,一般为1.
sys = simsizes(sizes);
x0 = [];
str = [];
ts = [];
% 产生输出
function sys = mdlOutputs(t,x,u)
error = u(1);
derror = u(2);
errori = u(3);
kp = 60;
ki = 1;
kd = 3;
ut = kp*error + kd*derror + ki*errori;
sys(1) = ut; % 同时sys的前几个数值(sys[1]等)是系统的输出,即在simulink中S-function伸出线上的数据
%%chap1_3plant.m
% S-Function for continuous state equation
function [sys, x0, str, ts] = s_function(t, x, u, flag)
switch flag
%Initialization
case 0
[sys, x0, str, ts] = mdlInitializeSizes; % 初始化构造函数
case 1
sys = mdlDerivatives(t,x,u);
%Outputs
case 3
sys = mdlOutputs(t, x, u);
%Unhandled flags
case {2, 4, 9}
sys =[];
%Unexpected flags
otherwise
error(['UNhandled flag = ', num2str(flag)]);
end
function [sys, x0, str, ts] = mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 2; % 连续状态的个数为两个,分别为dx(t)、y(t)
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1; % 输出为一个
sizes.NumInputs = 1; % 输入为一个,即经过控制器校正的信号
sizes.DirFeedthrough = 0; % 无关系则为0
sizes.NumSampleTimes = 0;
sys = simsizes(sizes);
x0 = [0, 0];
str = [];
ts = [];
function sys = mdlDerivatives(t,x,u)
sys(1) = x(2);
% sys(2) = -(25+10*rands(1))*x(2)+(133+30*rands(1))*u;
sys(2) = -(25+10*sin(t))*x(2)+(133+30*sin(t))*u;
function sys = mdlOutputs(t,x,u)
sys(1) = x(1);