S-函数

S-函数

一、简介

S函数用于自定义实现特定的算法,然后嵌入到simulink模块“S-Function”中用于仿真。

二、主函数

1、函数头

function [sys,x0,str,ts]=functionname(t,x,u,flag,p1,p2,p3...)

① sys,x0,str,ts为系统默认输出变量;
② t,x,u,flag为系统默认输入参数;
③ p1,p2,p3…为用户可选输入变量;
(如果定义函数时列表中有可选输入参数,在S-Function模块中要设置参数的值)
④ s函数文件名要与函数名一致。

2、函数体

switch flag
case 0
[sys,x0,str,ts]=mdlInitializeSizes;
case 1
sys = mdlDerivatives(t,x,u);
case 2
sys = mdlUpdates(t,x,u);
case 3
sys = mdlOutputs(t,x,u);
case 4
sys = mdlGetTimeOfNextVarHit(t,x,u);
case 9
sys=mdlGetTimeOfNextVarHit(t,x,u);

3、说明
对于特定的算法可能只用到某些flag状态的操作,对于不需要操作的flag状态,有两种处理方式,一种是在主函数中处理,另一种是在定义子函数时处理。以不需要进行flag为1、4和9状态时的操作为例分别进行说明。
① 在主函数中处理
在主函数中编写为:
case {1,2,9}
sys = [];
这样处理就不需要再编写对应状态的子函数。
② 在子函数中处理
在主函数中编写为:

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

在子函数中编写为:

function sys = mdlUpdates(t,x,u)
sys = [];
function sys = mdlGetTimeOfNextVarHit(t,x,u)
sys = [];
function sys=mdlTerminate(t,x,u)
 sys = [];

三、子函数

算法的设计可能会用到状态变量x,那么根据x的性质可以将算法分为三大类:基于连续状态变量的算法、基于离散状态变量的算法和不基于状态变量的算法。接下来分别介绍这三种类型的算法设计。

1、基于连续状态变量的算法
算法的整体设计思想是:ẋ=f1(t,x,u) y=f2(t,x,u)
① 初始化(flag=0)
设置使用的连续状态变量的个数:size.NumContStates = □
设置不使用离散状态变量:size.NumDiscStates = 0
设置输出变量的个数:size.NumOutputs = □
设置输入变量的个数:size.NumInputs = □
设置输出变量与输入变量是否相关:size.DirFeedthrough = 1或0
设置采样时间的个数:size.NumSampleTimes = □
用系统变量sys记录并返回上述设置:sys=simsize(sizes)
设置状态变量的初始值:x0 = [□ □ □…]
设置保留变量str为空:str = []
设置采样时间类型:ts = [□ □…]
示例:

/***************************************************/
function [sys,x0,str,ts] = mdlInitializeSizes

sizes = simsizes;
sizes.NumContStates = 2;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 2;
sizes.NumInputs = 2;
sizes.DirFeedthrough = 1; 
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);

x0 = zeros(2,1);
str = [];
ts = [0 0];
/***************************************************/

② 状态变量求导(flag=1)
子函数mdlDerivatives实现连续状态变量x导数的表达式:f1(t,x,u),用系统变量sys记录并传递给ẋ。在函数体中也可以编写其它操作,但是sys只返回给ẋ。
示例:

/***************************************************/
function sys = mdlDerivatives(t,x,u,A,B,C,D)

sys = A*x + B*u;
/***************************************************/

③ 状态变量更新(flag=2)
子函数mdlUpdates实现离散状态变量x的更新,因此在基于连续状态变量的算法中不需要这一步运算。
④ 输出变量计算(flag=3)
子函数mdlOutputs实现输出变量y的表达式:f2(t,x,u),用系统变量sys记录并传递给y。在函数体中也可以编写其它操作,但是sys只返回给y。
示例:

/***************************************************/
function sys = mdlOutputs( t,x,u,A,B,C,D )

sys = A*x + B*u;
/***************************************************/

⑤ 采样时刻计算(flag=4)
子函数mdlGetTimeOfNextVarHit计算下一次采样时刻,只在离散采样系统中有用(即mdlInitializeSizes中的ts设置ts(1)不为0)。
示例:

/***************************************************/
function sys = mdlGetTimeOfNextVarHit( t,x,u )

sys = t + u(2)/***************************************************/

⑥ Simulink仿真结束时的操作(flag=9)
编写simulink仿真结束时刻进行的操作,用sys记录返回值,但是返回值传递给哪个变量不详,一般置sys=[]。
示例:

/***************************************************/
function sys=mdlTerminate(t,x,u)
 
sys = [];
/***************************************************/

2、基于离散状态变量的算法
算法的整体设计思想是:x(n+1)=f1(t,x,u) y(n)=f2(t,x,u)
① 初始化(flag=0)
设置不使用连续状态变量:size.NumContStates = 0
设置使用的离散状态变量的个数:size.NumDiscStates = □
设置输出变量的个数:size.NumOutputs = □
设置输入变量的个数:size.NumInputs = □
设置输出变量与输入变量是否相关:size.DirFeedthrough = 1或0
设置采样时间的个数:size.NumSampleTimes = □
用系统变量sys记录并返回上述设置:sys=simsize(sizes)
设置状态变量的初始值:x0 = [□ □ □…]
设置保留变量str为空:str = []
设置采样时间类型:ts = [□ □…]
示例:

/***************************************************/
function [sys,x0,str,ts] = mdlInitializeSizes

sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 2;
sizes.NumOutputs = 2;
sizes.NumInputs = 2;
sizes.DirFeedthrough = 1; 
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);

x0 = zeros(2,1);
str = [];
ts = [0 0];
/***************************************************/

② 状态变量求导(flag=1)
子函数mdlDerivatives实现连续状态变量x的更新,计算f1(t,x,u),用系统变量sys记录并传递给ẋ。因此在基于离散状态变量的算法中不需要这一步运算。
③ 状态变量更新(flag=2)
子函数mdlUpdates实现离散状态变量x导数的表达式:f1(t,x,u),用系统变量sys记录并传递给x(n+1)。在函数体中也可以编写其它操作,但是sys只返回给x(n+1)。
示例:

/***************************************************/
function sys = mdlUpdates(t,x,u,A,B,C,D)

sys = A*x + B*u;
/***************************************************/

④ 输出变量计算(flag=3)
子函数mdlOutputs实现输出变量y的表达式:f2(t,x,u),用系统变量sys记录并传递给y。在函数体中也可以编写其它操作,但是sys只返回给y。
示例:

/***************************************************/
function sys = mdlUpdates( t,x,u,A,B,C,D )

sys = A*x + B*u;
/***************************************************/

⑤ 采样时刻计算(flag=4)
子函数mdlGetTimeOfNextVarHit计算下一次采样时刻,只在离散采样系统中有用(即mdlInitializeSizes中的ts设置ts(1)不为0)。
示例:

/***************************************************/
function sys = mdlGetTimeOfNextVarHit( t,x,u )

sys = t + u(2)/***************************************************/

⑥ Simulink仿真结束时的操作(flag=9)
编写simulink仿真结束时刻进行的操作,用sys记录返回值,但是返回值传递给哪个变量不详,一般置sys=[]。
示例:

/***************************************************/
function sys=mdlTerminate(t,x,u)
 
sys = [];
/***************************************************/

3、不基于状态变量的算法
这种算法非常简单,对照以上两种算法做适当修改即可。

你可能感兴趣的:(自动化嵌入式)