Matlab中s函数的使用
目錄
0. 寫在前面
1. s函數的編寫
2. 連續系統模型
3. 中文注釋的sfuntmpl
?
0. 寫在前面
??????? 最近做畢設用到了matlab的s函數,在這里分享一下我的收獲,歡迎大家指正
????????關于s函數的一些概念就不在敘述了,網上一查一大堆。本文主要分享s函數編寫的步驟和自己對代碼的一些理解
????????(第一篇文章,多多關照)
?
1. s函數的編寫
???????? ① 首先,打開模板函數,復制sfuntmpl中的代碼到自己的m文件中
>> edit sfuntmpl????????
????????② 然后,修改函數名字(名字得和文件名一樣,這里我用的是systemP.m)
??????? sfuntmpl代碼:
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)??????? 修改后代碼:(無模塊參數)
function [sys,x0,str,ts,simStateCompliance] = systemP(t,x,u,flag)??????? 修改后代碼:(帶三個模塊參數)
function [sys,x0,str,ts,simStateCompliance] = systemP(t,x,u,flag,name1,name2,name3)??????? 使用帶模塊參數時需要在simulink中傳參進來。例如下圖,傳參1,2,3,對應name1,name2,name3
?
????????參數意義:
| 輸出 | 輸入 |
| sys:通用返回值 | t:時間 |
| x0:狀態初始值 | x:狀態 |
| str:保留項(目前沒用)? | u:輸入 |
| ts:采樣時間設置 | flag:標志位 |
| simStateCompliance:仿真狀態設置 | 可以添加任意個simulink模塊參數的輸入 |
????????
??????? ③ 修改初始化參數(也就是flag等于0)
%case 0:初始化 function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes; %用于設置模塊參數的結構體sizes.NumContStates = 0; %連續變量個數 sizes.NumDiscStates = 0; %離散變量個數 sizes.NumOutputs = 0; %輸出個數 sizes.NumInputs = 0; %輸入個數 sizes.DirFeedthrough = 1; %輸入是否直接影響輸出 sizes.NumSampleTimes = 1; %至少一個采樣時間sys = simsizes(sizes);%初始化初始條件 x0 = [];%保留項 str = [];% 初始化采樣時間 ts = [0 0]; %[0 0] 連續采樣%[0 1] 小步長的連續采樣%[PERIOD OFFSET] 離散采用時間 [采樣時間 步長]%[-2 0] 變步長的采樣時間 FLAG=4時獲取下一次采樣時間%指定simStateCompliance塊值 simStateCompliance = 'UnknownSimState'; %'UnknownSimState' 默認設置%'DefaultSimState' 與內置塊的模擬狀態相同%'HasNoSimState' 沒有模擬狀態%'DisallowSimState' 保存或恢復模型模擬狀態時出錯??????? 在這一步主要分三種情況闡述:
- 連續系統
? ????? 連續系統修改:連續變量個數、輸入個數、輸出個數、x0初始條件
- 離散系統
??????? 離散系統修改:離散變量個數、輸入個數、輸出個數、x0初始條件、采樣時間
- 純數學計算
??????? 由輸入計算輸出的函數修改:輸入個數、輸出個數
????????simStateCompliance的選擇:這里一般情況使用‘默認設置’是沒有問題的。我在做畢設時,僅一次遇到matlab跑simulink仿真程序時出現狀態的問題,我把默認設置改成‘與內置塊的模擬狀態相同’也就好了。
?
????????④ 根據‘步驟③’中提到的三種情況對應修改‘case 1+case 3’、‘case 2+case 3’、‘case 3’
??????? 大多數情況的傳參就是在這里使用的
????????(如果你想在初始化中使用傳參也不是不可以,注意事項一樣)
??????? 傳參除了在‘步驟②’中提到的位置修改外,還應該修改兩個地方
第一,switch-case的函數中,如果調用該函數需要傳參,則需要在對應函數后面加上參數
switch flagcase 0 [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;case 1 sys=mdlDerivatives(t,x,u,name1,name2,name3);case 2 sys=mdlUpdate(t,x,u);case 3 sys=mdlOutputs(t,x,u,name1,name3);case 4 sys=mdlGetTimeOfNextVarHit(t,x,u);case 9 sys=mdlTerminate(t,x,u);otherwise DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end第二,參數定義的時候
function sys=mdlDerivatives(t,x,u,name1,name2,name3) sys = [];function sys=mdlUpdate(t,x,u) sys = [];function sys=mdlOutputs(t,x,u,name1,name3) sys = [];以上兩個地方必須配套使用
?
??????? ⑤ 創建simulink模塊
????????s函數寫完后,保存,打開simulink,搜索s-function
????????
?????????將s-function模塊拖入工作區,雙擊模塊,在s-function名稱中添加剛剛保存的s函數,在s-function參數中輸入傳參,沒有傳參可以不輸入。
?
2. 連續系統模型案例
??????? 由于我主要使用的是連續模型,所以在這里我分享一下連續的系統模型和代碼
連續模型主要是狀態空間方程:
??????? x為連續變量,u為輸入
??????? 在s-function模塊中是單輸入、單輸出,我們可以使用Mux和Dmux增加輸入輸出
????????輸入n個信號分別用u(1)、u(2)....u(n)來區分,輸出m個信號在‘case 3’時,sys=[輸出1;輸出2;...;輸出m]
?
連續系統模型:
代碼:
function [sys,x0,str,ts,simStateCompliance] = systemP(t,x,u,flag)switch flagcase 0 %初始化[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;case 1 %計算連續狀態的微分sys=mdlDerivatives(t,x,u);case 2 %計算下一個離散狀態 sys=mdlUpdate(t,x,u);case 3 %計算輸出sys=mdlOutputs(t,x,u);case 4 %計算下一次采樣的時間sys=mdlGetTimeOfNextVarHit(t,x,u);case 9 %系統結束sys=mdlTerminate(t,x,u);otherwise %其他情況DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end%case 0:初始化 function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes; %用于設置模塊參數的結構體sizes.NumContStates = 2; %連續變量個數 sizes.NumDiscStates = 0; %離散變量個數 sizes.NumOutputs = 1; %輸出個數 sizes.NumInputs = 2; %輸入個數 sizes.DirFeedthrough = 0; %輸入是否直接影響輸出 sizes.NumSampleTimes = 1; %至少一個采樣時間sys = simsizes(sizes);%初始化初始條件 x0 = [0;0];%保留項 str = [];% 初始化采樣時間 ts = [0 0]; %[0 0] 連續采樣%[0 1] 小步長的連續采樣%[PERIOD OFFSET] 離散采用時間 [采樣時間 步長]%[-2 0] 變步長的采樣時間 FLAG=4時獲取下一次采樣時間%指定simStateCompliance塊值 simStateCompliance = 'UnknownSimState'; %'UnknownSimState' 默認設置%'DefaultSimState' 與內置塊的模擬狀態相同%'HasNoSimState' 沒有模擬狀態%'DisallowSimState' 保存或恢復模型模擬狀態時出錯%case 1:計算連續狀態的微分 function sys=mdlDerivatives(~,x,u) ut = u(2); Ml = u(1); sys = [0 1;0 1]*x+[1;0]*ut-[0;1]*Ml;%case 2:計算下一個離散狀態 %sys=AX+BU function sys=mdlUpdate(~,~,~) sys = [];%case 3:計算輸出 function sys=mdlOutputs(~,x,~) sys = [1 0]*x;%case 4:計算下一次采樣的時間[-2 0]時使用該函數 function sys=mdlGetTimeOfNextVarHit(t,~,~) sampleTime = 1; %例如設置下一次的采樣時間是1s后 sys = t + sampleTime;%case 9:系統結束 function sys=mdlTerminate(~,~,~) sys = [];?
3. 中文注釋的sfuntmpl
? 最后,在這里放一份完整的做了中文注釋的sfuntmpl版本
function [sys,x0,str,ts,simStateCompliance] = sfuntmpl(t,x,u,flag)switch flagcase 0 %初始化[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;case 1 %計算連續狀態的微分sys=mdlDerivatives(t,x,u);case 2 %計算下一個離散狀態 sys=mdlUpdate(t,x,u);case 3 %計算輸出sys=mdlOutputs(t,x,u);case 4 %計算下一次采樣的時間sys=mdlGetTimeOfNextVarHit(t,x,u);case 9 %系統結束sys=mdlTerminate(t,x,u);otherwise %其他情況DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));end%case 0:初始化 function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes = simsizes; %用于設置模塊參數的結構體sizes.NumContStates = 0; %連續變量個數 sizes.NumDiscStates = 0; %離散變量個數 sizes.NumOutputs = 0; %輸出個數 sizes.NumInputs = 0; %輸入個數 sizes.DirFeedthrough = 1; %輸入是否直接影響輸出 sizes.NumSampleTimes = 1; %至少一個采樣時間sys = simsizes(sizes);%初始化初始條件 x0 = [];%保留項 str = [];% 初始化采樣時間 ts = [0 0]; %[0 0] 連續采樣%[0 1] 小步長的連續采樣%[PERIOD OFFSET] 離散采用時間 [采樣時間 步長]%[-2 0] 變步長的采樣時間 FLAG=4時獲取下一次采樣時間%指定simStateCompliance塊值 simStateCompliance = 'UnknownSimState'; %'UnknownSimState' 默認設置%'DefaultSimState' 與內置塊的模擬狀態相同%'HasNoSimState' 沒有模擬狀態%'DisallowSimState' 保存或恢復模型模擬狀態時出錯%case 1:計算連續狀態的微分 %sys=AX+BU function sys=mdlDerivatives(t,x,u) sys = [];%case 2:計算下一個離散狀態 %sys=AX+BU function sys=mdlUpdate(t,x,u) sys = [];%case 3:計算輸出 %sys = CX+DU function sys=mdlOutputs(t,x,u) sys = [];%case 4:計算下一次采樣的時間[-2 0]時使用該函數 function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; %例如設置下一次的采樣時間是1s后 sys = t + sampleTime;%case 9:系統結束 function sys=mdlTerminate(t,x,u) sys = [];?
?
總結
以上是生活随笔為你收集整理的Matlab中s函数的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开发指南篇 5:Vue API 盲点解析
- 下一篇: 相册管理系统