Matlab中S-函数的编写
S-函數(shù)使Simulink的功能大大擴(kuò)充,除Mmatlab外,用戶還可以用其他語言(C/C++/FORTRAN/Ada)編寫實(shí)現(xiàn)算法,很強(qiáng)大的同時(shí)也對(duì)使用者提出了較高的要求。下面是編寫S-函數(shù)的整個(gè)流程:
0 基礎(chǔ)知識(shí)
(1)Simulink仿真過程Simulnk仿真分為兩步:初始化、仿真循環(huán)。仿真是由求解器控制的,求解器主要作用是:計(jì)算模塊輸出、更新模塊離散狀態(tài)、計(jì)算連續(xù)狀態(tài)。求解器傳遞給系統(tǒng)的信息包括:時(shí)間、輸入和當(dāng)前狀態(tài)。系統(tǒng)的作用:計(jì)算模塊的輸出、更新狀態(tài)、計(jì)算狀態(tài)導(dǎo)數(shù),然后將這些信息傳遞給求解器。求解器和系統(tǒng)之間的信息傳遞是通過不同標(biāo)志來控制的。
、
(2)S-函數(shù)控制流
(3)S-函數(shù)的幾個(gè)概念
?
1)? 直接饋通
在編寫S-函數(shù)時(shí),初始化函數(shù)中需要對(duì)sizes.DirFeedthrough 進(jìn)行設(shè)置,如果輸出函數(shù)mdlOutputs或者對(duì)于變采樣時(shí)間的mdlGetTimeOfNextVarHit是輸入u的函數(shù),則模塊具有直接饋通的特性sizes.DirFeedthrough=1;否則為0。
?
2)? 采樣時(shí)間
仿真步長就是整個(gè)模型的基礎(chǔ)采樣時(shí)間,各個(gè)子系統(tǒng)或模塊的采樣時(shí)間,必須以這個(gè)步長為整數(shù)倍。
連續(xù)信號(hào)和離散信號(hào)對(duì)計(jì)算機(jī)而言其實(shí)都是采樣而來的,只是采樣時(shí)間不同,連續(xù)信號(hào)采樣時(shí)間可認(rèn)為趨于0且基于微分方程,離散信號(hào)采樣時(shí)間比較長基于差分方程。離散信號(hào)當(dāng)前狀態(tài)由前一個(gè)時(shí)刻的狀態(tài)決定,連續(xù)信號(hào)可以通過微分方程計(jì)算得到。如果要將連續(xù)信號(hào)離散化還要考慮下信號(hào)能否恢復(fù)的問題,即香農(nóng)定理。
?
采樣時(shí)間點(diǎn)的確定:下一個(gè)采樣時(shí)間=(n*采樣間隔)+ 偏移量,n表示當(dāng)前的仿真步,從0開始。
對(duì)于連續(xù)采樣時(shí)間,ts可以設(shè)置為[0 0],其中偏移量為0;
對(duì)于離散采樣時(shí)間,ts假設(shè)為[0.25 0.1],表示在S-函數(shù)仿真開始后0.1s開始每隔0.25s運(yùn)行一次,當(dāng)然每個(gè)采樣時(shí)刻都會(huì)調(diào)用mdlOutPuts和mdlUpdate函數(shù);
對(duì)于變采樣時(shí)間,即離散采樣時(shí)間的兩次采樣時(shí)間間隔是可變的,每次仿真步開始時(shí)都需要用mdlGetTimeNextVarHit計(jì)算下一個(gè)采樣時(shí)間的時(shí)刻值。ts可以設(shè)置為[-2 0]。
對(duì)于多個(gè)任務(wù),每個(gè)任務(wù)都可以以不同的采樣速率執(zhí)行S-函數(shù),假設(shè)任務(wù)A在仿真開始每隔0.25s執(zhí)行一次,任務(wù)B在仿真后0.1s每隔1s執(zhí)行一次,那么ts設(shè)置為[0.25 0.1;1.0 0.1],具體到S-函數(shù)的執(zhí)行時(shí)間為[0 0.1 0.25 0.5 0.75 1.0 1.1…]。
如果用戶想繼承被連接模塊的采樣時(shí)間,ts只要設(shè)置為[-1 0]。
1 S-函數(shù)的編寫
1.1 S函數(shù)的輸入輸出參數(shù)含義
首先打開M-文件的模版函數(shù):function[sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)
這個(gè)是無參的,如果有參數(shù)格式為:function[sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag,p1,p2,...)
1.2 子函數(shù)的作用
(1)
function[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates = 0; %連續(xù)狀態(tài)個(gè)數(shù) sizes.NumDiscStates = 0; %離散狀態(tài)個(gè)數(shù) sizes.NumOutputs = 0; %輸出個(gè)數(shù) sizes.NumInputs = 0; %輸入個(gè)數(shù) sizes.DirFeedthrough = 1; %是否直接饋通 sizes.NumSampleTimes = 1; %采樣時(shí)間個(gè)數(shù),至少一個(gè) sys = simsizes(sizes); %將size結(jié)構(gòu)傳到sys中 x0 = []; %初始狀態(tài)向量,由傳入的參數(shù)決定,沒有為空 str = []; ts = [0 0]; %設(shè)置采樣時(shí)間,這里是連續(xù)采樣,偏移量為0 % Specify the blocksimStateCompliance. The allowed values are: % 'UnknownSimState', < The defaultsetting; warn and assume DefaultSimState % 'DefaultSimState', < Same sim state as abuilt-in block % 'HasNoSimState', < No sim state % 'DisallowSimState' < Error out whensaving or restoring the model sim state simStateCompliance = 'UnknownSimState';(2)
functionsys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; % Example, set the next hit to be one secondlater. sys = t + sampleTime;?
(3)
functionsys=mdlOutputs(t,x,u) sys = [];?
(4)
function sys=mdlUpdate(t,x,u) sys = [];?
(5)
functionsys=mdlDerivatives(t,x,u) sys = [];?
(6)
functionsys=mdlTerminate(t,x,u) sys = [];?
2 實(shí)例解析
在編寫S-函數(shù)之前要確定系統(tǒng)是否有狀態(tài)變量、是連續(xù)還是離散狀態(tài)以及輸入輸出個(gè)數(shù)、是否傳入?yún)?shù)、采樣時(shí)間等因素,針對(duì)不同的系統(tǒng)進(jìn)行初始化、編寫不同的子函數(shù)。
以matlab自帶的限制積分函數(shù)程序limintm為例,講解S-函數(shù)的編寫。
Simulink系統(tǒng):
S-函數(shù)設(shè)置:其中傳入的參數(shù)2,3,2.5分別表示為積分上限、積分下限和初始積分條件。
輸出圖形:
S-函數(shù)分析:
function [sys,x0,str,ts,simStateCompliance]=limintm(t,x,u,flag,lb,ub,xi) %傳入的三個(gè)參數(shù)放在后面lb,ub,xi的位置 %LIMINTM Limited integrator implementation. % Example MATLAB file S-function implementing a continuous limited integrator % where the output is bounded by lower bound (LB) and upper bound (UB) % with initial conditions (XI). % % See sfuntmpl.m for a general S-function template. % % See also SFUNTMPL.% Copyright 1990-2009 The MathWorks, Inc. % $Revision: 1.1.6.2 $switch flag%%%%%%%%%%%%%%%%%%% Initialization %%%%%%%%%%%%%%%%%%%case 0 [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes(lb,ub,xi);%%%%%%%%%%%%%%%% Derivatives %%%%%%%%%%%%%%%%case 1sys = mdlDerivatives(t,x,u,lb,ub);%%%%%%%%%%%%%%%%%%%%%%%%% Update and Terminate %%%%%%%%%%%%%%%%%%%%%%%%%case {2,9}sys = []; % do nothing%%%%%%%%%%% Output %%%%%%%%%%%case 3sys = mdlOutputs(t,x,u); otherwiseDAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag)); end% end limintm% %============================================================================= % mdlInitializeSizes % Return the sizes, initial conditions, and sample times for the S-function. %============================================================================= % function [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes(lb,ub,xi)sizes = simsizes; sizes.NumContStates = 1;%1個(gè)連續(xù)狀態(tài),即積分狀態(tài) sizes.NumDiscStates = 0; sizes.NumOutputs = 1; sizes.NumInputs = 1; sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1;sys = simsizes(sizes); str = []; x0 = xi; %積分狀態(tài)初始條件‘ ts = [0 0]; % sample time: [period, offset]% speicfy that the simState for this s-function is same as the default simStateCompliance = 'DefaultSimState';% end mdlInitializeSizes% %============================================================================= % mdlDerivatives % Compute derivatives for continuous states. %============================================================================= % function sys = mdlDerivatives(t,x,u,lb,ub)if (x <= lb & u < 0) | (x>= ub & u>0 )sys = 0; elsesys = u; end% end mdlDerivatives% %============================================================================= % mdlOutputs % Return the output vector for the S-function %============================================================================= % function sys = mdlOutputs(t,x,u)sys = x;% end mdlOutputs?
參考:
《基于MATLAB/Simulink系統(tǒng)仿真權(quán)威指南》
總結(jié)
以上是生活随笔為你收集整理的Matlab中S-函数的编写的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows 运行库与dll文件
- 下一篇: 【原】基于Windows Media P