Level-1 Matlab S-Function编写入门
# Level-1 Matlab S-Function编写入门
S-function包括主函数和6个功能子函数,包括mdlInitializeSizes
(初始化)、mdlDerivatives
(连续状态微分)、mdlUpdate
(离散状态更新)、mdlOutputs
(模块输出)、mdlGetTimeOfNextVarHit
(计算下次采样时刻)和mdlTerminate
(仿真结束)。
在S-function仿真过程中,利用switch-case
语句,根据不同阶段对应的flag值来调用不同子函数,以完成对S-function模块仿真流程的控制。
Level-1 Matlab S-function仿真流程如下:
# Level-1 Matlab S-Function函数的代码编写
可以利用命令打开一个示例代码:
edit sfuntmpl
# 函数原型及输入输出含义
函数原型如下:
[sys,x0,str,ts,simStateCompliance] = SFUNC(t,x,u,flag,p1,...pn)
SFUNC
在给定时间点t
返回的内容取决于flag
的值、当前状态x
、当前输入量u
和可选输入参数p1,...pn
,可选参数可以提供给S-Function,并且在任何FLAG操作期间使用。下面对flag
的定义进行解释:
FLAG | 结果 | 描述 |
---|---|---|
0 | [sizes, x0, str, Ts] | 初始化,在sys返回系统大小,在x0初始化状态,在str中返回状态排序信息,在Ts中返回采样时间 |
1 | dx | 返回在sys中的连续状态的微分 |
2 | ds | 更新离散状态 sys = x(n+1) |
3 | y | 返回sys输出 |
4 | t_next | 返回sys中下一采样时间点 |
5 | 保留字 | |
9 | [] | 仿真结束,进行清理sys操作 |
输出量:
sys
: 一个通用的返回参数,返回值取决于flag的值;x0
:状态初始值;str
:默认为空,无需设置;ts
:采样时间,包含采样时间和偏移量;simStateComplicance
:附加变量。
# 如何使用可选参数?
需要在使用可选参数的函数参数列表后加上定义即可。
function [sys,x0,str,ts,simStateCompliance] = delay_and_gain_level1(t,x,u,flag,Ts,gain)
switch flag,
case 0,
% 在需要使用可选参数的函数处加上参数即可
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(Ts);
case 1,
sys=mdlDerivatives(t,x,u);
case 2,
sys=mdlUpdate(t,x,u);
case 3,
sys=mdlOutputs(t,x,u,gain);
case 4,
sys=mdlGetTimeOfNextVarHit(t,x,u,Ts);
case 9,
sys=mdlTerminate(t,x,u);
otherwise
DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
end
# Flag 0: mdlInitializeSizes函数
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
% 示例中参数使用硬编码设置,推荐利用可选参数进行设置
sizes = simsizes;
% 以下四个参数可以被指定为-1,表示大小动态调整
sizes.NumContStates = 0; % 连续状态的数量
sizes.NumDiscStates = 0; % 离散状态的数量
sizes.NumOutputs = 0; % 输出的数量
sizes.NumInputs = 0; % 输入的数量
% 如果在FLAG=3调用期间使用u,则具有直接馈入
% 将其设置为0类似于承诺在FLAG=3期间不会使用u;
% 如果违反承诺,则会出现不可预测的结果。
sizes.DirFeedthrough = 1; % 输入端口是否具有直接馈入
% 采样次数,应与下述ts的行数一致,一般为1
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
x0 = [];
str = [];
ts = [0 0]; % [采样时间,时间偏移]
simStateCompliance = 'UnknownSimState';
% end mdlInitializeSizes
# Flag 1: mdlDerivatives函数
function sys=mdlDerivatives(t,x,u)
% 设置对状态x的微分
sys = [];
% end mdlDerivatives
# Flag 2: mdlUpdate函数
function sys=mdlUpdate(t,x,u)
% 设置对离散状态x(n)的更新x(n+1)
sys = [];
% end mdlUpdate
# Flag 3: mdlOutputs函数
function sys=mdlOutputs(t,x,u)
% 设置系统输出y,该函数的x实则为x(n)
sys = [];
% end mdlOutputs
# Flag 4: mdlGetTimeOfNextVarHit函数
function sys=mdlGetTimeOfNextVarHit(t,x,u)
% 例如,如下设置则下一次执行该模块为1秒后
sampleTime = 1;
sys = t + sampleTime;
% end mdlGetTimeOfNextVarHit
# Flag 9: mdlTerminate函数
function sys=mdlTerminate(t,x,u)
% 执行任何结束仿真后需要处理的任务
sys = [];
% end mdlTerminate
# 一些值得注意的点
- 初始化函数中的参数尽可能使用可选参数设置的方式进行,尽量避免使用硬编码的手段;
- 参数列表中的x表示当前时刻的x(k);
- 注意根据Flag=3: mdlOutputs函数中是否使用u,正确设置DirFeedthrough的值。
# 对S-Function模块进行封装
在S-Function中如需设置可选参数,利用模块的封装可以更加清楚地展示所需参数并设置,本节将介绍封装的基本操作。
- 右击待封装的模块:
Mask(封装)
->Create Mask(创建封装)
; - 在
Parameters & Dialog(参数和对话框)
中选择Edit(编辑)
; - 设置
Prompt(提示)
和Name(名称)
并保存,其中Prompt为面板中的提示词,Name为可选参数变量名; - 右击被封装系统:选择
Block Parameters(模块参数)
,在S-Function参数
字段中设置相应的可选参数。
编辑 (opens new window)
上次更新: 2023/08/14, 19:51:00