2020-02-16-Level 2 M S函数模板

官方模板写的比较啰嗦,找起来比较费力,重新做一个中文的模板。

function msfunCassie(block)
% smileland作品,免费使用,但请不要删除此句话
% 以下设定参数并不一定全部需要,不需要的注释掉就好
setup(block);

%endfunction

function setup(block)
  %block.CurrentTime 只读对象,调用当前时间

  % 初始化对话框参数,即对话框内给定的初始化参数.
  block.NumDialogPrms     = 2;%给定2个参数
  %block.DialogPrmsTunable = {'Tunable','Nontunable','SimOnlyTunable'};%参数是否可变(此句话可选是否需要,默认不可变)

  %%%%%%%%初始化输入输出端口的属性%%%%%%%
  
  % 初始化输入输出端口个数.
  block.NumInputPorts  = 1;%输入端口个数
  block.NumOutputPorts = 1;%输出端口个数
  
  % 设定输入输出端口时继承还是动态,以指示输入和输出端口从模型继承其已编译属性(尺寸、数据类型、复杂度和采样模式).
  block.SetPreCompInpPortInfoToDynamic;%设定输入端口为动态
  block.SetPreCompOutPortInfoToDynamic;%设定输出端口为动态

  % 设定输入端口属性.(也可以再Dwork中设定,在PostPropagationSetup子方法中)
  block.InputPort(1).DatatypeID  = 0;  % (-1 inherited;0 double;1 single;2 int8;3 uint8;4 int16;5 uint16;6 int32;7 uint12;8 boolean)
  block.InputPort(1).Complexity  = 'Real';%是否为复数
  
  % 设定输出端口属性.(也可以再Dwork中设定,在PostPropagationSetup子方法中)
  block.OutputPort(1).DatatypeID  = 0; % double
  block.OutputPort(1).Complexity  = 'Real';
  
  block.InputPort(1).Dimensions = 1;%输入口1的维数是1,最高支持到2维
  % block.InputPort(1).DimensionsMode = 'Fixed';%Fixed表示端口维数固定,Variable表示端口维数可变
  block.OutputPort(1).Dimensions = 1;%输出口1的维数是1,最高支持到2维
  % block.OutputPort(1).DimensionsMode = 'Fixed';%Fixed表示端口维数固定,Variable表示端口维数可变
  
  block.InputPort(1).DirectFeedthrough = true;%输入口有无直接馈通(true/false)
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  
  % 设定有多少连续状态变量.
  block.NumContStates = 1;
  
  % 设定有多少离散状态变量.
  % block.NumDworkDiscStates = 1;

  % 设定采样时间.
  %  [0 0.5]            : 从0.5s开始连续采样
  %  [0.1 0.5]          : 从0.5s开始,每0.1s采样一次
  %  [-1, 0]            : 继承采样频率
  %  [-2, 0]            : 动态变化的采样频率
  block.SampleTimes = [0 0];%连续采样率
  
  %设定离散工作向量个数
  % block.NumDworks = 1;
  
  % -----------------------------------------------------------------
  % Options,若使用TLC则需要以下语句,否则注释掉即可
  % -----------------------------------------------------------------

  % block.SetAccelRunOnTLC(false);
  
  % block.OperatingPointCompliance = 'Default';
  
  % -----------------------------------------------------------------
  % 引用使用的子方法,主要有PostPropagationSetup;InitializeConditions;
  % Start;Outputs;Updates;Derivatives;Terminate.以下子方法仅保留着几个。
  % -----------------------------------------------------------------
  
  %{
  %包含PostPropagationSetup子方法,用于初始化DWork工作向量
  block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
  %}
  
  %包含InitializeConditions子方法,用于初始化状态变量或DWork工作向量的值
  block.RegBlockMethod('InitializeConditions', @InitializeConditions);
  
  %与InitializeConditions子方法功能一致,但只初始化一次,Ini方法每次调用子方法时均会初始化
  % block.RegBlockMethod('Start', @Start);

  %包含输出模块
  block.RegBlockMethod('Outputs', @Outputs);

  %包含离散状态更新模块
  %block.RegBlockMethod('Update', @Update);

  %包含连续状态微分模块
  block.RegBlockMethod('Derivatives', @Derivatives);
  
  %包含终止模块
  %block.RegBlockMethod('Terminate', @Terminate);

  %还有其他模块,仅将最主要的列出,若需要则使用S函数自带模板。
%endfunction

% -------------------------------------------------------------------
% 以下为子方法模块,同样主要有DoPostPropSetup;InitializeConditions;
  % Start;Outputs;Updates;Derivatives;Terminate.以下子方法仅保留这几个。
% -------------------------------------------------------------------
%{
function DoPostPropSetup(block)
  block.NumDworks = 4;
  
  block.Dwork(1).Name            = 'tau';
  block.Dwork(1).Dimensions      = 1;
  block.Dwork(1).DatatypeID      = 0;      % double
  block.Dwork(1).Complexity      = 'Real'; % real
  block.Dwork(1).UsedAsDiscState = false;
  
  block.Dwork(2).Name            = 'Uc';
  block.Dwork(2).Dimensions      = 1;
  block.Dwork(2).DatatypeID      = 0;      % double
  block.Dwork(2).Complexity      = 'Real'; % real
  block.Dwork(2).UsedAsDiscState = false;
  
  block.Dwork(3).Name            = 'step';
  block.Dwork(3).Dimensions      = 1;
  block.Dwork(3).DatatypeID      = 0;      % double
  block.Dwork(3).Complexity      = 'Real'; % real
  block.Dwork(3).UsedAsDiscState = false;
  
  block.Dwork(4).Name            = 'u';
  block.Dwork(4).Dimensions      = 1;
  block.Dwork(4).DatatypeID      = 0;      % double
  block.Dwork(4).Complexity      = 'Real'; % real
  block.Dwork(4).UsedAsDiscState = false;
  
  % Register all tunable parameters as runtime parameters.
  block.AutoRegRuntimePrms;

%endfunction
%}
%

function InitializeConditions(block)

block.ContStates.Data = log(1e-6);
    
%{
function Start(block)

  tau = block.DialogPrm(1).Data;
  Uc = block.DialogPrm(2).Data; 

%}

%{
  function Update(block)
  block.Dwork(1).Data = [];
%}

function Outputs(block)
  
  block.OutputPort(1).Data = block.InputPort(1).data * exp(block.ContStates.Data);
  
  
function Derivatives(block)

tau = block.DialogPrm(1).Data;
Uc = block.DialogPrm(2).Data; 
  
if block.CurrentTime <= 0.02
    step = 0;
else
    step = 1;
end
    
block.Derivatives.Data = step * 1/tau * (block.InputPort(1).data^2 / Uc^2 - 1);
%endfunction

%endfunction
  
%function Terminate(block)

%disp(['Terminating the block with handle ' num2str(block.BlockHandle) '.']);

%endfunction