示例:
dx1/dt=-0.5572x1-0.7814x2+u1-u2;
dx2/dt=0.7814x1+2u2;
y=1.9691x1+6.4493x2;
simulink模型的建立
s函數程序
A=[-0.5572,-0.7814;0.7814,0]; B=[1,-1;0,2]; C=[1.9691,6.4493];
程序與之前修改的部分使用紅色標出
function [sys,x0,str,ts,simStateCompliance] = sfun_state01(t,x,u,flag,A,B,C) switch flag, case 0, [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes; case 1, sys=mdlDerivatives(t,x,u); case 2, sys=mdlUpdate(t,x,u,A,B); case 3, sys=mdlOutputs(t,x,u,C); 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,x0,str,ts,simStateCompliance]=mdlInitializeSizes sizes = simsizes; sizes.NumContStates = 0; sizes.NumDiscStates = 2; sizes.NumOutputs = 1; sizes.NumInputs = 2; sizes.DirFeedthrough = 0; sizes.NumSampleTimes = 1; sys = simsizes(sizes); x0 = [0 0]';
str = []; ts = [0.02,0]; simStateCompliance = 'UnknownSimState'; function sys=mdlDerivatives(t,x,u) sys = []; function sys=mdlUpdate(t,x,u,A,B) % update state variable Ts = 0.02; sys = x + (A * x + B * u) *Ts; function sys=mdlOutputs(t,x,u,C) % update output sys = C * x; function sys=mdlGetTimeOfNextVarHit(t,x,u) sampleTime = 1; sys = t + sampleTime; function sys=mdlTerminate(t,x,u) sys = [];
圖像結果
function sys = mlupdate(t, x, u)的功能是對離散狀態量的跟新,即更新下一采樣時刻的狀態變量,並在之后的mdloutputs中處理;這是s函數文章中程序錯誤的原因,但為什么會寫成上面的形式呢?離散變量的跟新是什么意思,在這里給大家推導一遍幫助大家的理解
這個式子就是malupdate中需要編寫的式子,離散變量的更新就是更新下一個采樣時刻的狀態變量,在outputs函數中對下一采樣時刻處理得到下一采樣時刻的輸出結果。
有同學會問程序中寫的式sys = x + (A * x + B * u) * Ts呢?x代表的x(k)應該好理解,但是左邊為什么是sys而不是x(k + 1),首先malupdate函數的輸出只有一個sys,其次sys會通過中間變量x傳輸到Output的x里面,所以這里的sys可以代表x(k + 1)。
到這里小伙伴們應該都清楚了,但是我是怎么驗證我寫的s-function函數是對s函數這一文章中寫的式錯的呢?很好辦直接對狀態方程建立simulink模型看圖像和自己寫的s-function模型的圖像是否一致不就完了。
simulink中的模型
為了便於觀看左邊是狀態變量x建立的模型,右邊是表示輸出y的模型,它們之間是使用goto和from模塊結合的和直接連線是一樣的
圖像結果是
為了便於對比這里將s-function中模型的圖像也放在這里左邊的是狀態方程搭建模型的圖像,右邊是s-function模型的圖像,是不是一模一樣,顯然s函數這篇文章中的圖像是有問題的。