S函数L1使用方法介绍
1. 流程解释
S函数分为L1和L2两级,其中L1的模块只能单输入单输出,而L2是可以多输入多输出的。这里仅涉及L1的Matlab语言S函数使用,应用于机器人仿真控制设计。
首先是官方流程(翻译),如下图:
然后是一与代码相关的参考流程图(有修改):
2. 伪代码流程解释
main
{
初始化模型; //0;mdlInitializeSizes
//计算下一个采样时间点(大步长); //4;mdlGetTimeOfNextVarHit
while(未到达仿真终止时间)
{
计算下一个采样时间点(大步长); //4;mdlGeTimeOfNextVarHit 根据官网流程修改
计算模块的输出; //3;mdlOutputs
更新离散状态量; //2;mdlUpdate
if(此模型带有连续状态模块)
{
here:计算模块的输出; //3;mdloutputs
计算微分; //1;mdlDerivatives
if(精度未达标)
goto here;
过零检测;
计算写一个采样时间点(大步长);
}
}
执行仿真终止动作; //9;mdlTerminate
}
3. L1模板代码及其解释
%% S-Funtion Usage Template and Comprehention
%% sfun总函数
function [sys, x0, str, ts, simStateCompliance] = learnSFunction(t, x, u, flag, p1, p2)
%==============================================================================
% sys sfun调用的系统模型,有sys(1~7)种状态属性
% x0 sys的初始状态
% str 状态排序字符串,一般为空
% ts 采样时间
% 详细使用见initialize
%
% t 系统时间,与u和x有关
% x 系统状态变量
% u 系统输入变量(simulink中给u的,用u(index)表示)
%==============================================================================
switch flag % 状态机,通过系统自动计算和改变
case 0 % 初始化
[sys, x0, str, ts, simStateCompliance] = mdlInitializeSizes;
case 1 % 返回定义的连续型状态导数模型
sys = mdlDerivatives(t, x, u);
case 2 % 更新离散状态X0,sys=X(n+1)
sys = mdlUpdate(t, x, u);
case 3 % 通过u将参数从模块传出
sys = mdlOutputs(t, x, u);
case 4 % 离散时使用,抓取下一个采样的T给sys
sys = mdlGetTimeOfNextVarHit(t, x, u);
case 9 % sys结束时定义功能,默认清除sys使得sys=[]
sys = mdlTerminate(t, x, u);
otherwise % 报错
DAStudio.error('Simulation: blocks : unhandledFlag: ', num2str(flag));
end
%% 初始化函数
function [sys, x0, str, ts, simStateCompliance] = mdlInitializeSizes
size = simsizes;
size.NumInputs = 0; % 输入的数量
size.NumOutputs = 0; % 输出的数量
size.NumContStates = 0; % 连续状态的数量
size.NunDiscStates = 0; % 离散状态的数量
size.DirFeedThrough = 1; % 是否直通(直通可以在flag3-output中使用变量u中的内容)
size.NumSampleTimes = 1; % ts的采样时间数量,代表其行数(row)
sys = simsizes(size);
x0 = [];
str=[];
simStateCompliance = 'UnknownSimState';
%=============================================================================
% ts是一个 NumSampleTimes*2 的矩阵,每行代表一个采样点,
% 每行代表[period offset],几种写法含义如下:
% [0 0] : 系统为连续时间
% [0 1] : 系统时间连续,但以很小的步长采样
% [-2 0]: 变步长时间采样,通过flag4-mdlGetTimeOfNextVarHit抓取
% [x y] : 其余的写法代表period为采样总时间,offset为采样间隔
% 其中 period>0, offset<period
%=============================================================================
ts = [0 0];
%% mdlUpdate
%=============================================================================
% 状态更新、timehit、时间步长时的具体要求
%=============================================================================
function sys=mdlUpdate(t,x,u)
sys = [];
%% 其它功能函数
function sys=mdlDerivatives(t,x,u)
sys = [];
function sys=mdlOutputs(t,x,u)
sys = [];
function sys=mdlGetTimeOfNextVarHit(t,x,u)
% 例子,设置下一抓取(hit)时间点为1s后
sampleTime = 1;
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];