S-Function 使用及应用举例
对用simulink做仿真的有用: <BR><BR>S-Function 使用及应用举例 <BR><BR>【发信人: hii_yzf (叶子), 信区: MathTools <BR>标 题: S-FUNCTIONS的书写之一 <BR>发信站: 交通大学思源BBS站 (Mon Apr 16 16:35:09 2001) , 站内信件 <BR><BR>S-FUNCTIONS的书写之一 <BR><BR>s-function也就是system-function的缩写。说得简单,s-function就是用MATLAB所提供的模型不能完全满足用户,而提供给用户自己编写程序来满足自己要求模型的接口。要了解 s-function,必须了解以下知识: <BR>(1)direct feedthrough <BR>(2)dynamically sized inputs <BR>(3)setting sample times and offsets <BR>[由于我也不知道怎么把上面三句话精确的翻译成中文,因此在此不加翻译,大家自己理解,也许更好]由于上面三部分的重要性,在此详细进行分析。 <BR><BR>一.direct feedthrough <BR>direct feedthrough意思是说系统的输出或可变采样时间是否受到输入的控制。大家清楚有的系统是受到输入控制如: <BR>y=k*u (u是输入,k是放大因子,y是输出) <BR>而有的系统输出是不受到输入影响,如: <BR>输出:y=x <BR>dx=u <BR>x表示状态 <BR><BR>二.dynamically sized inputs <BR>主要是给出:输入连续状态数目(size.NumContStates),离散状态数目(size.NumDiscStates) <BR>,输出数目(size.NumOutputs),输入数目(size.NumInputs),Direct Feedthrough(size.Dir Feedthrough)。 <BR>三.setting sample times and offsets <BR><BR>setting smaple times and offsets主要设置采样时间 MATLAB为了用户方便,已经书写了S-FUNCTIONS模板函数sfuntmpl.m。为了更好的写S-FUNCTIONS,大家来看一下,该函数sfuntmpl.m内容如下:(我通过在该内容加注释来说明,以$开头) <BR><BR>function = sfuntmpl(t,x,u,flag) <BR>$输出变量就此四个,大家必须注意它的顺序。$输入变量可以为t,x,u,flag,p1,...,pn等,但是前面的四个变量不能变,特此说明。 <BR><BR>%SFUNTMPL General M-file S-function template <BR>% With M-file S-functions, you can define you own ordinary differential <BR>% equations (ODEs), discrete system equations, and/or just about <BR>% any type of algorithm to be used within a Simulink block diagram. <BR>% <BR>$上面是其功能 <BR>% The general form of an M-File S-function syntax is: <BR>% = SFUNC(T,X,U,FLAG,P1,...,Pn) <BR>% <BR>$调用格式 <BR>% What is returned by SFUNC at a given point in time, T, depends on the <BR>% value of the FLAG, the current state vector, X, and the current <BR>% input vector, U. <BR>% <BR>% FLAG RESULT DESCRIPTION <BR>% ----- ------ -------------------------------------------- <BR>% 0 Initialization, return system sizes in SYS, <BR>% initial state in X0, state ordering strings <BR>% in STR, and sample times in TS. <BR>$具体怎样实现,大家参看后面的函数mdlInitializeSizes <BR>% 1 DX Return continuous state derivatives in SYS. <BR>% 2 DS Update discrete states SYS = X(n+1) <BR>% 3 Y Return outputs in SYS. <BR>% 4 TNEXT Return next time hit for variable step sample <BR>% time in SYS. <BR>% 5 Reserved for future (root finding). <BR>% 9 [] Termination, perform any cleanup SYS=[]. <BR>% <BR>$参看后面相应函数 <BR>% <BR>% The state vectors, X and X0 consists of continuous states followed <BR>% by discrete states. <BR>% <BR>% Optional parameters, P1,...,Pn can be provided to the S-function and <BR>% used during any FLAG operation. <BR>% <BR>% When SFUNC is called with FLAG = 0, the following information <BR>% should be returned: <BR>% <BR>% SYS(1) = Number of continuous states. <BR>% SYS(2) = Number of discrete states. <BR>% SYS(3) = Number of outputs. <BR>% SYS(4) = Number of inputs. <BR>% Any of the first four elements in SYS can be specified <BR>% as -1 indicating that they are dynamically sized. The <BR>% actual length for all other flags will be equal to the <BR>% length of the input, U. <BR>% SYS(5) = Reserved for root finding. Must be zero. <BR>% SYS(6) = Direct feedthrough flag (1=yes, 0=no). The s-function <BR>% has direct feedthrough if U is used during the FLAG=3 <BR>% call. Setting this to 0 is akin to making a promise that <BR>% U will not be used during FLAG=3. If you break the promise <BR>% then unpredictable results will occur. <BR>% SYS(7) = Number of sample times. This is the number of rows in TS. <BR>% <BR>$需要说明的是sys的顺序不能乱 <BR>% <BR>% X0 = Initial state conditions or [] if no states. <BR>% <BR>% STR = State ordering strings which is generally specified as []. <BR>% <BR>% TS = An m-by-2 matrix containing the sample time <BR>% (period, offset) information. Where m = number of sample <BR>% times. The ordering of the sample times must be: <BR>% <BR>% TS = ; : Variable step discrete sample time <BR>% where FLAG=4 is used to get time of <BR>% next hit. <BR>% <BR>% There can be more than one sample time providing <BR>% they are ordered such that they are monotonically <BR>% increasing. Only the needed sample times should be <BR>% specified in TS. When specifying than one <BR>% sample time, you must check for sample hits explicitly by <BR>% seeing if <BR>% abs(round((T-OFFSET)/PERIOD) - (T-OFFSET)/PERIOD) <BR>% is within a specified tolerance, generally 1e-8. This <BR>% tolerance is dependent upon your model's sampling times <BR>% and simulation time. <BR>% <BR>% You can also specify that the sample time of the S-function <BR>% is inherited from the driving block. For functions which <BR>% change during minor steps, this is done by <BR>% specifying SYS(7) = 1 and TS = [-1 0]. For functions which <BR>% are held during minor steps, this is done by specifying <BR>% SYS(7) = 1 and TS = [-1 -1]. <BR><BR>% Copyright (c) 1990-1998 by The MathWorks, Inc. All Rights Reserved. <BR>% $Revision: 1.12 $ <BR><BR>% <BR>% The following outlines the general structure of an S-function. <BR>% <BR>switch flag, <BR>%%%%%%%%%%%%%%%%%% <BR>% Initialization % <BR>%%%%%%%%%%%%%%%%%% <BR>case 0,=mdlInitializeSizes; <BR>$大家是不是觉得此函数名太长,当然可以根据自己的爱好加以改变,不过后面的相应改。 <BR>%%%%%%%%%%%%%%% <BR>% Derivatives % <BR>%%%%%%%%%%%%%%% <BR>case 1,sys=mdlDerivatives(t,x,u); <BR>%%%%%%%%%% <BR>% Update % <BR>%%%%%%%%%% <BR>case 2,sys=mdlUpdate(t,x,u); <BR>%%%%%%%%%%% <BR>% Outputs % <BR>%%%%%%%%%%% <BR>case 3,sys=mdlOutputs(t,x,u); <BR>%%%%%%%%%%%%%%%%%%%%%%% <BR>% GetTimeOfNextVarHit % <BR>%%%%%%%%%%%%%%%%%%%%%%% <BR>case 4,sys=mdlGetTimeOfNextVarHit(t,x,u); <BR>%%%%%%%%%%%%% <BR>% Terminate % <BR>%%%%%%%%%%%%% <BR>case 9,sys=mdlTerminate(t,x,u); <BR>%%%%%%%%%%%%%%%%%%%% <BR>% Unexpected flags % <BR>%%%%%%%%%%%%%%%%%%%% <BR>otherwise, error(['Unhandled flag = ',num2str(flag)]); <BR>end <BR>% end sfuntmpl <BR><BR>% <BR>%============================================================================= <BR>% mdlInitializeSizes <BR>% Return the sizes, initial conditions, and sample times for the S-function. <BR>%============================================================================= <BR>% <BR>function =mdlInitializeSizes <BR>% <BR>% call simsizes for a sizes structure, fill it in and convert it to a <BR>% sizes array. <BR>% <BR>% Note that in this example, the values are hard coded. This is not a <BR>% recommended practice as the characteristics of the block are typically <BR>% defined by the S-function parameters. <BR>% <BR>$关于函数simsizes大家必须遵循,因为把是内部函数,不得随便改变,其作用是返回未初始化的size结构。 <BR>sizes = simsizes; <BR>$number of continuous states <BR>sizes.NumContStates = 0; <BR>$number of discrete states <BR>sizes.NumDiscStates = 0; <BR>$number of outputs <BR>sizes.NumOutputs = 0; <BR>$ number of inputs <BR>sizes.NumInputs = 0; <BR>$Flag for direct feedthrough <BR>sizes.DirFeedthrough = 1; <BR>$number of sample times <BR>sizes.NumSampleTimes = 1; <BR>% at least one sample time is needed <BR>$ <BR>sys = simsizes(sizes); <BR>% <BR>% initialize the initial conditions <BR>% <BR>x0 = []; <BR>% <BR>% str is always an empty matrix <BR>% <BR>str = []; <BR>% <BR>% initialize the array of sample times <BR>% <BR>ts = ; <BR>% end mdlInitializeSizes <BR>% <BR>%============================================================================= <BR>% mdlDerivatives <BR>% Return the derivatives for the continuous states. <BR>%============================================================================= <BR>% <BR>function sys=mdlDerivatives(t,x,u) <BR>sys = []; % end mdlDerivatives <BR>% <BR>%============================================================================= <BR>% mdlUpdate <BR>% Handle discrete state updates, sample time hits, and major time step <BR>% requirements. <BR>%============================================================================= <BR>% <BR>function sys=mdlUpdate(t,x,u) <BR>sys = []; % end mdlUpdate <BR>% <BR>%============================================================================= <BR>% mdlOutputs <BR>% Return the block outputs. <BR>%============================================================================= <BR>% <BR>function sys=mdlOutputs(t,x,u) <BR>sys = []; % end mdlOutputs <BR>% <BR>%============================================================================= <BR>% mdlGetTimeOfNextVarHit <BR>% Return the time of the next hit for this block. Note that the result is <BR>% absolute time. Note that this function is only used when you specify a <BR>% variable discrete-time sample time [-2 0] in the sample time array in <BR>% mdlInitializeSizes. <BR>%============================================================================= <BR>% <BR>function sys=mdlGetTimeOfNextVarHit(t,x,u) <BR>sampleTime = 1; % Example, set the next hit to be one second later. <BR>sys = t + sampleTime; % end mdlGetTimeOfNextVarHit <BR>% <BR>%============================================================================= <BR>% mdlTerminate <BR>% Perform any end of simulation tasks. <BR>%============================================================================= <BR>% <BR>function sys=mdlTerminate(t,x,u) <BR>sys = []; % end mdlTerminate <BR><BR>在下面我将写几个具体的实例。 <BR><BR>之二、连续系统例子: <BR><BR>function = csfunc(t,x,u,flag) <BR>%CSFUNC An example M-file S-function for defining a continuous system. <BR>% Example M-file S-function implementing continuous equations: <BR>% x' = Ax + Bu <BR>% y = Cx + Du <BR>% <BR>% See sfuntmpl.m for a general S-function template. <BR>% <BR>% See also SFUNTMPL. <BR> <BR>% Copyright (c) 1990-1998 by The MathWorks, Inc. All Rights Reserved. <BR>% $Revision: 1.5 $ <BR>A=[-0.09 -0.01; 1 0]; <BR>B=[ 1 -7; 0 -2]; <BR>C=[ 0 2; 1 -5]; <BR>D=[-3 0; 1 0]; <BR>switch flag, <BR>%%%%%%%%%%%%%%%%%% <BR>% Initialization % <BR>%%%%%%%%%%%%%%%%%% <BR>case 0,=mdlInitializeSizes(A,B,C,D); <BR>%%%%%%%%%%%%%%% <BR>% Derivatives % <BR>%%%%%%%%%%%%%%% <BR>case 1,sys=mdlDerivatives(t,x,u,A,B,C,D); <BR>%%%%%%%%%%% <BR>% Outputs % <BR>%%%%%%%%%%% <BR>case 3,sys=mdlOutputs(t,x,u,A,B,C,D); <BR>%%%%%%%%%%%%%%%%%%% <BR>% Unhandled flags % <BR>%%%%%%%%%%%%%%%%%%% <BR>case { 2, 4, 9 },sys = []; <BR>%%%%%%%%%%%%%%%%%%%% <BR>% Unexpected flags % <BR>%%%%%%%%%%%%%%%%%%%% <BR>otherwise, error(['Unhandled flag = ',num2str(flag)]); <BR>end <BR>% end csfunc <BR>% <BR>%============================================================================= <BR>% mdlInitializeSizes <BR>% Return the sizes, initial conditions, and sample times for the S-function. <BR>%============================================================================= <BR>% <BR>function =mdlInitializeSizes(A,B,C,D) <BR>sizes = simsizes; <BR>sizes.NumContStates = 2; sizes.NumDiscStates = 0; sizes.NumOutputs = 2; <BR>sizes.NumInputs = 2; sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; <BR>sys = simsizes(sizes); x0 = zeros(2,1); str = []; ts = ; <BR>% end mdlInitializeSizes <BR>% <BR>%============================================================================= <BR>% mdlDerivatives <BR>% Return the derivatives for the continuous states. <BR>%============================================================================= <BR>% <BR>function sys=mdlDerivatives(t,x,u,A,B,C,D) <BR>sys = A*x + B*u; % end mdlDerivatives <BR>% <BR>%============================================================================= <BR>% mdlOutputs <BR>% Return the block outputs. <BR>%============================================================================= <BR>% <BR>function sys=mdlOutputs(t,x,u,A,B,C,D) <BR>sys = C*x + D*u; % end mdlOutputs <BR> 之三、有关离散系统 <BR><BR>关于离散系统定义的书写在此举一例: <BR><BR>function = dsfunc(t,x,u,flag) <BR>%DSFUNC An example M-file S-function for defining a discrete system. <BR>% Example M-file S-function implementing discrete equations: <BR>% x(n+1) = Ax(n) + Bu(n) <BR>% y(n) = Cx(n) + Du(n) <BR>% <BR>% See sfuntmpl.m for a general S-function template. <BR>% <BR>% See also SFUNTMPL. % Copyright (c) 1990-1998 by The MathWorks, Inc. All Rights Reserved. <BR>% $Revision: 1.13 $ <BR>% Generate a discrete linear system: <BR>A=[-1.3839 -0.5097 1.0000 0]; B=[-2.5559 0 0 4.2382]; <BR>C=[ 0 2.0761 0 7.7891]; D=[ -0.8141 -2.9334 1.2426 0]; <BR>switch flag, <BR>% Initialization <BR>case 0, = mdlInitializeSizes(A,B,C,D); <BR>% Update % %%%%%%%%%% <BR>case 2, sys = mdlUpdate(t,x,u,A,B,C,D); %%%%%%%%%% <BR>% Output % %%%%%%%%%% <BR>case 3, sys = mdlOutputs(t,x,u,A,C,D); %%%%%%%%%%%%% <BR>% Terminate % %%%%%%%%%%%%% <BR>case 9, sys = []; % do nothing %%%%%%%%%%%%%%%%%%%% <BR>% Unexpected flags % %%%%%%%%%%%%%%%%%%%% <BR>otherwise, error(['unhandled flag = ',num2str(flag)]); <BR>end %end dsfunc <BR>% <BR>%======================================================================= <BR>% mdlInitializeSizes <BR>% Return the sizes, initial conditions, and sample times for the S-function. <BR>%======================================================================= <BR>% <BR>function = mdlInitializeSizes(A,B,C,D) <BR>sizes = simsizes; <BR>sizes.NumContStates = 0; sizes.NumDiscStates = size(A,1); sizes.NumOutputs = size(D,1); <BR>sizes.NumInputs = size(D,2); sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; <BR>sys = simsizes(sizes); x0 = ones(sizes.NumDiscStates,1); str = []; ts = ; <BR>% end mdlInitializeSizes <BR>% <BR>%======================================================================= <BR>% mdlUpdate <BR>% Handle discrete state updates, sample time hits, and major time step <BR>% requirements. <BR>%======================================================================= <BR>% function sys = mdlUpdate(t,x,u,A,B,C,D) <BR>sys = A*x+B*u; %end mdlUpdate <BR>% <BR>%======================================================================= <BR>% mdlOutputs <BR>% Return Return the output vector for the S-function <BR>%======================================================================= <BR>% <BR>function sys = mdlOutputs(t,x,u,A,C,D) <BR>sys = C*x+D*u; %end mdlUpdate <BR><BR>S-FUNCTIONS的书写之四(离散和连续的混合型) <BR><BR> <BR><BR>function = mixedm(t,x,u,flag) <BR>%MIXEDM An example integrator followed by unit delay M-file S-function <BR>% Example M-file S-function implementing a hybrid system consisting <BR>% of a continuous integrator (1/s) in series with a unit delay (1/z). <BR>% Sampling period and offset for unit delay. <BR>dperiod = 1; doffset = 0; <BR>switch flag <BR>%%%%%%%%%%%%%%%%%% <BR>% Initialization % <BR>%%%%%%%%%%%%%%%%%% <BR>case 0, =mdlInitializeSizes(dperiod,doffset); <BR>%%%%%%%%%%%%%%% <BR>% Derivatives % <BR>%%%%%%%%%%%%%%% <BR>case 1, sys=mdlDerivatives(t,x,u); <BR>%%%%%%%%%% <BR>% Update % <BR>%%%%%%%%%% <BR>case 2, sys=mdlUpdate(t,x,u,dperiod,doffset); <BR>%%%%%%%%%% <BR>% Output % <BR>%%%%%%%%%% <BR>case 3, sys=mdlOutputs(t,x,u,doffset,dperiod); <BR>%%%%%%%%%%%%% <BR>% Terminate % <BR>%%%%%%%%%%%%% <BR>case 9, sys = []; <BR>% do nothing <BR>otherwise, error(['unhandled flag = ',num2str(flag)]); <BR>end % end mixedm % <BR>%============================================================================= <BR>% mdlInitializeSizes <BR>% Return the sizes, initial conditions, and sample times for the S-function. <BR>%============================================================================= <BR>% <BR>function =mdlInitializeSizes(dperiod,doffset) <BR>sizes = simsizes; sizes.NumContStates = 1; sizes.NumDiscStates = 1; <BR>sizes.NumOutputs = 1; sizes.NumInputs = 1; sizes.DirFeedthrough = 0; <BR>sizes.NumSampleTimes = 2; sys = simsizes(sizes); x0 = ones(2,1); str = []; <BR>ts = ; <BR>% end mdlInitializeSizes <BR>% <BR>%============================================================================= <BR>% mdlDerivatives % Compute derivatives for continuous states. <BR>%============================================================================= <BR>% <BR>function sys=mdlDerivatives(t,x,u) <BR>sys = u; % end mdlDerivatives <BR>% <BR>%============================================================================= <BR>% mdlUpdate <BR>% Handle discrete state updates, sample time hits, and major time step % requirements. <BR>%============================================================================= <BR>% <BR>function sys=mdlUpdate(t,x,u,dperiod,doffset) <BR>% next discrete state is output of the integrator <BR>if abs(round((t - doffset)/dperiod) - (t - doffset)/dperiod) < 1e-8, sys = x(1); <BR>else sys = []; end % end mdlUpdate <BR>% <BR>%============================================================================= <BR>% mdlOutputs % Return the output vector for the S-function <BR>%============================================================================= <BR>% <BR>function sys=mdlOutputs(t,x,u,doffset,dperiod) <BR>% Return output of the unit delay if we have a <BR>% sample hit within a tolerance of 1e-8. If we <BR>% don't have a sample hit then return [] indicating <BR>% that the output shouldn't change. <BR>if abs(round((t - doffset)/dperiod) - (t - doffset)/dperiod) < 1e-8, sys = x(2); else sys = []; end % end mdlOutputs 关于这些程序的说明,我将在后面讲解。 <BR><BR>S-Function书写之五 <BR><BR>在本帖中我对前面列举的关于系统是连续,离散,连续与离散混合的三个例子加以说明,以至于大家在看下面的例子时能更好的理解。 <BR><BR>一.函数mdlInitializeSizes <BR><BR>对于描述连续型的函数csfunc.m <BR><BR>sizes.NumContStates = 2; sizes.NumDiscStates = 0; <BR><BR>$表明本函数是描述连续型的 <BR><BR>sizes.NumOutputs = 2; sizes.NumInputs = 2; <BR>sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; <BR><BR>对于描述离散型的函数dsfunc.m <BR><BR>sizes.NumContStates = 0; sizes.NumDiscStates = size(A,1); <BR><BR>$表明本函数是描述离散型的 <BR><BR>sizes.NumOutputs = size(D,1); sizes.NumInputs = size(D,2); <BR>sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; <BR><BR>对于描述混合型的函数mixedm.m <BR><BR>sizes.NumContStates = 1; sizes.NumDiscStates = 1; <BR><BR>$表明本函数是描述混合型的 <BR><BR>sizes.NumOutputs = 1; sizes.NumInputs = 1; <BR>sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 2; <BR><BR>关于变量sizes.numoutputs和sizes.numinputs则由描述的系统的输出,输入而定。 <BR>关于变量sizes.DirFeedthrough,则可以查看矩阵D,如果D是非空,则为1,否则为0 <BR>关于变量sizes.NumSampleTimes,即是ts这个矩阵的行数。 <BR><BR>二.函数mdlDerivatives <BR><BR>仅仅出现在含有连续型的系统中;这部分应该根据系统状态来决定。 <BR><BR>三.函数mdlUpdate 仅仅出现在含有离散型的系统中;该函数应该根据系统状态来决定 <BR><BR>四.函数mdlOutputs 该函数在各种类型中都有,应该根据描述系统的输出来决定; <BR><BR>五.关于书写s-functions函数的注意之点 <BR><BR>(1)我想大家都会觉得上述三个函数都不利于维护,因此在写s-functions函数时不妨把矩阵 A,B,C,D也考虑成变量,作为输入参数; <BR>(2)关于在csfuncs.m中的型如case(2,4,9)这种形式,大家最好不要采用,不利于维护,可以分 开来写 <BR>(3)关于结构sizes中的各个变量的值,最好从输入参量中得到,而不是通过人为判断来输入 <BR>(4)因此,其实上述三种形式,可以变化成一种形式. <BR>(5)可以通过对相应于你所要求的系统对上述三个函数加以相应的改进来到达自己的要求,因此可以把上述函数当成模板函数. <BR> 这是个好东西<BR>我是新手,正想学这个,我先copy下来<BR> <P>最好上传一个这方面的电子书籍</P> 顶 :@) 标记下,回头学习! 连续系统的例子运行时有错误,case 1,sys=mdlDerivatives(t,x,u,A,B,C,D);出错了,是怎么回事啊?还有switch 后只能跟常数,要把flag换成常数吗? 多谢分享 顶一下,多谢多谢:lol 谢谢楼主,正在学习中……:@) 关于mdlDerivatives我觉得应该是计算当前输入量的积分的,
比如写 sys = u; 在这个函数里,在输出 mdloutputs 函数中写 sys = x,那么S函数输出应该是当前输入信号 U 的积分才对。
若有不对的请批评指正。 学习了,谢谢分享 楼主这个有详细的操作步骤没有啊,举一个例子来做一下啊。看了还是不怎么明白 向楼主学习了!!~~ 这个是个好东西!!!!!!!
页:
[1]
2