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