Level1-S函数(system-functions)
S函数是通过按照MATLAB提供的特定的API进行编程,可以与simulink引擎进行交互。这种交互同内建的block与simulink引擎的交互很相同。因此了解了S函数的工作原理就了解了simulink其他模块的原理。
对于任一一个simulink模块,其包含输入u,状态量x,输出y,及时间t(由simulink引擎驱动,解算器的时间单位)
相关的数学表达式见上方,derivatives针对的是连续系统,update针对的是离散系统。
S函数或其他block的运作方式是按如下步骤:
1、初始化阶段,Simulink引擎将库模块整合到模型中,定义传播信号维度(标量?向量?矩阵?)、数据类型(unit8?或其他)和采样时间,计算模块的参数,确定块执行顺序,并分配内存
2、然后进入循环阶段,其中的每一步叫做仿真步(simulation step)。在每一个仿真步内,引擎按照初始化期间确定的顺序执行模型中的每个模块。针对于每个模块,该引擎调用计算当前采样时间模块的状态、导数和输出。直到仿真完成
怎么编辑S函数呢,这是从S函数模板导出的。
1、首先更改函数名sfuntmpl为你自己的函数名称(simulink会在仿真过程中的每个步长内多次调用该函数;
t表示当前时刻的仿真时间,u表示输入的向量,x表示状态,Pn表示自定义参数;
sys为通用输出参数,根据flag的值来确定返回的值,比如flag=3是返回S函数的输出信号,x0位状态变量的初始值,仅在flag=0时有效。str为保留变量,ts为S函数的采样时间,由一个两维数组表示)
2、模板switch函数通过判断flag的值确定当前处于什么步骤(flag值随着仿真过程自动变化):
mdlInitializeSizes为初始化,定义该模块的输入输出维数、连续/离散状态变量个数、采样时间,以及输入是否为直接反馈等
mdlDerivatives为连续系统的微分函数,通过给定的微分计算表达式,通过积分计算得到状态变量的值。
mdlUpdate为离散系统状态量更新
mdlOutputs为计算S函数的输出
mdlGetTimeOfNextVarHit为离散系统时使用,计算下一个采样时刻的绝对值,若模块不是变步长,不执行该函数
mdlTerminate仿真结束时执行一些必要的动作,如清除临时变量,显示提示信息等。
3、下一步就是主要定义各的函数
mdlInitializeSizes函数中,定义了一个结构体sizes,sizes中定义了NumContStates(连续状态的数目)、NumDiscStates(离散状态的数目)、NumOutputs(输出端口数)、NumInputs(输入端口数)、DirFeedthrough(是否为直接馈入)、NumSampleTimes(采样时间或者说仿真步骤的个数)
mdlDerivatives和mdlUpdate,可以根据是连续系统还是离散系统选择一个进行每一个仿真步骤的计算
mdlOutputs将计算结果输出
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag) %SFUNTMPL General MATLAB S-Function Template % With MATLAB S-functions, you can define you own ordinary differential % equations (ODEs), discrete system equations, and/or just about % any type of algorithm to be used within a Simulink block diagram. % % The general form of an MATLAB S-function syntax is: % [SYS,X0,STR,TS,SIMSTATECOMPLIANCE] = SFUNC(T,X,U,FLAG,P1,...,Pn) % % What is returned by SFUNC at a given point in time, T, depends on the % value of the FLAG, the current state vector, X, and the current % input vector, U. % % FLAG RESULT DESCRIPTION % ----- ------ -------------------------------------------- % 0 [SIZES,X0,STR,TS] Initialization, return system sizes in SYS, % initial state in X0, state ordering strings % in STR, and sample times in TS. % 1 DX Return continuous state derivatives in SYS. % 2 DS Update discrete states SYS = X(n+1) % 3 Y Return outputs in SYS. % 4 TNEXT Return next time hit for variable step sample % time in SYS. % 5 Reserved for future (root finding). % 9 [] Termination, perform any cleanup SYS=[]. % % % The state vectors, X and X0 consists of continuous states followed % by discrete states. % % Optional parameters, P1,...,Pn can be provided to the S-function and % used during any FLAG operation. % % When SFUNC is called with FLAG = 0, the following information % should be returned: % % SYS(1) = Number of continuous states. % SYS(2) = Number of discrete states. % SYS(3) = Number of outputs. % SYS(4) = Number of inputs. % Any of the first four elements in SYS can be specified % as -1 indicating that they are dynamically sized. The % actual length for all other flags will be equal to the % length of the input, U. % SYS(5) = Reserved for root finding. Must be zero. % SYS(6) = Direct feedthrough flag (1=yes, 0=no). The s-function % has direct feedthrough if U is used during the FLAG=3 % call. Setting this to 0 is akin to making a promise that % U will not be used during FLAG=3. If you break the promise % then unpredictable results will occur. % SYS(7) = Number of sample times. This is the number of rows in TS. % % % X0 = Initial state conditions or [] if no states. % % STR = State ordering strings which is generally specified as []. % % TS = An m-by-2 matrix containing the sample time % (period, offset) information. Where m = number of sample % times. The ordering of the sample times must be: % % TS = [0 0, : Continuous sample time. % 0 1, : Continuous, but fixed in minor step % sample time. % PERIOD OFFSET, : Discrete sample time where % PERIOD > 0 & OFFSET < PERIOD. % -2 0]; : Variable step discrete sample time % where FLAG=4 is used to get time of % next hit. % % There can be more than one sample time providing % they are ordered such that they are monotonically % increasing. Only the needed sample times should be % specified in TS. When specifying more than one % sample time, you must check for sample hits explicitly by % seeing if % abs(round((T-OFFSET)/PERIOD) - (T-OFFSET)/PERIOD) % is within a specified tolerance, generally 1e-8. This % tolerance is dependent upon your model's sampling times % and simulation time. % % You can also specify that the sample time of the S-function % is inherited from the driving block. For functions which % change during minor steps, this is done by % specifying SYS(7) = 1 and TS = [-1 0]. For functions which % are held during minor steps, this is done by specifying % SYS(7) = 1 and TS = [-1 1]. % % SIMSTATECOMPLIANCE = Specifices how to handle this block when saving and % restoring the complete simulation state of the % model. The allowed values are: 'DefaultSimState', % 'HasNoSimState' or 'DisallowSimState'. If this value % is not speficified, then the block's compliance with % simState feature is set to 'UknownSimState'. % Copyright 1990-2010 The MathWorks, Inc. % % The following outlines the general structure of an S-function. % switch flag, %%%%%%%%%%%%%%%%%% % Initialization % %%%%%%%%%%%%%%%%%% case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; %%%%%%%%%%%%%%% % Derivatives % %%%%%%%%%%%%%%% case 1, sys=mdlDerivatives(t,x,u); %%%%%%%%%% % Update % %%%%%%%%%% case 2, sys=mdlUpdate(t,x,u); %%%%%%%%%%% % Outputs % %%%%%%%%%%% case 3, sys=mdlOutputs(t,x,u); %%%%%%%%%%%%%%%%%%%%%%% % GetTimeOfNextVarHit % %%%%%%%%%%%%%%%%%%%%%%% case 4, sys=mdlGetTimeOfNextVarHit(t,x,u); %%%%%%%%%%%%% % Terminate % %%%%%%%%%%%%% case 9, sys=mdlTerminate(t,x,u); %%%%%%%%%%%%%%%%%%%% % Unexpected flags % %%%%%%%%%%%%%%%%%%%% otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end % end sfuntmpl % %============================================================================= % mdlInitializeSizes % Return the sizes, initial conditions, and sample times for the S-function. %============================================================================= % function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes % % call simsizes for a sizes structure, fill it in and convert it to a % sizes array. % % Note that in this example, the values are hard coded. This is not a % recommended practice as the characteristics of the block are typically % defined by the S-function parameters. % sizes = simsizes; sizes.NumContStates = 0; sizes.NumDiscStates = 0; sizes.NumOutputs = 0; sizes.NumInputs = 0; sizes.DirFeedthrough = 1; sizes.NumSampleTimes = 1; % at least one sample time is needed sys = simsizes(sizes); % % initialize the initial conditions % x0 = []; % % str is always an empty matrix % str = []; % % initialize the array of sample times % ts = [0 0]; % Specify the block simStateCompliance. The allowed values are: % 'UnknownSimState', < The default setting; warn and assume DefaultSimState % 'DefaultSimState', < Same sim state as a built-in block % 'HasNoSimState', < No sim state % 'DisallowSimState' < Error out when saving or restoring the model sim state simStateCompliance = 'UnknownSimState'; % end mdlInitializeSizes % %============================================================================= % mdlDerivatives % Return the derivatives for the continuous states. %============================================================================= % function sys=mdlDerivatives(t,x,u) sys = []; % end mdlDerivatives % %============================================================================= % mdlUpdate % Handle discrete state updates, sample time hits, and major time step % requirements. %============================================================================= % function sys=mdlUpdate(t,x,u) sys = []; % end mdlUpdate % %============================================================================= % mdlOutputs % Return the block outputs. %============================================================================= % function sys=mdlOutputs(t,x,u) sys = []; % end mdlOutputs % %============================================================================= % mdlGetTimeOfNextVarHit % Return the time of the next hit for this block. Note that the result is % absolute time. Note that this function is only used when you specify a % variable discrete-time sample time [-2 0] in the sample time array in % mdlInitializeSizes. %============================================================================= % function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; % Example, set the next hit to be one second later. sys = t + sampleTime; % end mdlGetTimeOfNextVarHit % %============================================================================= % mdlTerminate % Perform any end of simulation tasks. %============================================================================= % function sys=mdlTerminate(t,x,u) sys = []; % end mdlTerminate