MATLABS函数编写示范(MATLAB2010a)2010-05-0521:22:47|分类:MATLAB之控制系统|标签:matlabs-function编写教程sbuilder|字号大中小订阅1.M语言S函数在命令行输入命令“editsfuntmpl”即可打开M语言s函数模板。M语言S函数是以flag为标志进行运算的。flag==0时,初始化参数;flag==1时,计算微分;flag==2时,状态更新;flag==3时,计算输出;flag==4时适用于变步长结算;其他参数不常用。(1)flag==0时,调用mdlInitializeSizes函数,sizes结构及解释如下:sizes.NumContStates=0;//连续变量个数sizes.NumDiscStates=0;//离散变量个数sizes.NumOutputs=0;//输出个数sizes.NumInputs=0;//输入个数sizes.DirFeedthrough=1;//是否直通,当在输出里包含了输入时,为直通sizes.NumSampleTimes=1;//采样时间对状态变量进行初始化,如果初始条件是0初始条件,则x0=[00](2)flag==1时,调用mdlDerivatives(t,x,u)函数计算微分,如有一系统为状态方程为x'=2x+u,y=5x+u时,编写如下:sys=2*x+u;(3)flag==3时,计算输出,如上例系统,则编写如下:sys=5*x+u;ok,下面只需要将编写好的s函数名称写入s-function模块。例子:对如下系统(零初始条件)x1'=-3x1-x2+u;x2'=2x1;y=x2;编写s函数如下:function[sys,x0,str,ts,simStateCompliance]=sfun_m_hyj(t,x,u,flag)switchflag,case0,[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;case1,sys=mdlDerivatives(t,x,u);case2,sys=mdlUpdate(t,x,u);case3,sys=mdlOutputs(t,x,u);case4,sys=mdlGetTimeOfNextVarHit(t,x,u);case9,sys=mdlTerminate(t,x,u);otherwiseDAStudio.error('Simulink:blocks:unhandledFlag',num2str(flag));endfunction[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizessizes=simsizes;sizes.NumContStates=2;sizes.NumDiscStates=0;sizes.NumOutputs=1;sizes.NumInputs=1;sizes.DirFeedthrough=1;sizes.NumSampleTimes=1;%atleastonesampletimeisneededsys=simsizes(sizes);x0=[00];str=[];ts=[00];simStateCompliance='UnknownSimState';functionsys=mdlDerivatives(t,x,u)sys=[-3*x(1)-x(2)+u;2*x(1)];//注意此处传递的是x向量,包含了x1和x2,引用时使用x(1),x(2),下标从1开始functionsys=mdlUpdate(t,x,u)sys=[];functionsys=mdlOutputs(t,x,u)sys=[x(2)];//x向量functionsys=mdlGetTimeOfNextVarHit(t,x,u)sampleTime=1;%Example,setthenexthittobeonesecondlater.sys=t+sampleTime;functionsys=mdlTerminate(t,x,u)sys=[];2.C语言S函数让我们做一个两个输入,两个输出,两个参数的例子。在MATLAB命令行输入editsfuntmpl_basic.c即可打开C语言S函数模板。#defineS_FUNCTION_NAMEtest//更改名字#defineS_FUNCTION_LEVEL2#defineINPUT_NUM2//输入输出个数#defineOUTPUT_NUM2#includesimstruc.h////////////////////////////////用到的头文件#includemath.h#includestdio.hstaticvoidmdlInitializeSizes(SimStruct*S){/*Seesfuntmpl_doc.cformoredetailsonthemacrosbelow*/ssSetNumSFcnParams(S,2);/*Numberofexpectedparameters*///输入参数个数if(ssGetNumSFcnParams(S)!=ssGetSFcnParamsCount(S)){/*Returnifnumberofexpected!=numberofactualparameters*/return;}ssSetNumContStates(S,0);//连续、离散状态个数ssSetNumDiscStates(S,0);if(!ssSetNumInputPorts(S,INPUT_NUM))return;ssSetInputPortWidth(S,0,3);//设置端口维数,更改为3x1ssSetInputPortRequiredContiguous(S,0,true);/*directinputsignalaccess*///第二个输入端口ssSetInputPortWidth(S,1,3);ssSetInputPortRequiredContiguous(S,1,true);sSetInputPortDirectFeedThrough(S,0,1);ssSetInputPortDirectFeedThrough(S,1,1);if(!ssSetNumOutputPorts(S,OUTPUT_NUM))return;ssSetOutputPortWidth(S,0,3);//输出端口维数3x1ssSetOutputPortWidth(S,1,3);//第二个输出ssSetNumSampleTimes(S,0.001);//采样时间0.001sssSetNumRWork(S,0);//设置浮点向量大小,0表示继承信号大小ssSetNumIWork(S,0);ssSetNumPWork(S,0);ssSetNumModes(S,0);ssSetNumNonsampledZCs(S,0);//设置采样点之间的zerocrossing的模块的状态个数/*Specifythesimstatecompliancetobesameasabuilt-inblock*/ssSetSimStateCompliance(S,USE_DEFAULT_SIM_STATE);ssSetOptions(S,0);对于输出函数mdlOutputs,先获得变量,再进行编程staticvoidmdlOutputs(SimStruct*S,int_Ttid){//获得参数指针real_T*para1=mxGetPr(ssGetSFcnParam(S,0));real_T*para2=mxGetPr(ssGetSFcnParam(S,1));constreal_T*u1=(constreal_T*)ssGetInputPortSignal(S,0);constreal_T*u2=(constreal_T*)ssGetInputPortSignal(S,1);real_T*y1=ssGetOutputPortSignal(S,0);real_T*y2=ssGetOutputPortSignal(S,1);//将输入乘以参数1或者参数2,然后赋值给输出y1[0]=para1[0]*u1[0];y1[1]=para1[0]*u1[1];y1[2]=para1[0]*u1[2];y2[0]=para2[0]*u2[0];y2[1]=para2[0]*u2[1];y2[2]=para2[0]*u2[2];}ok,使用mex编译并加入s-function模块,就可以。3.s-functionbuildersfunctionbuilder可以很方便的自动生成c语言s函数。填写s函数名,并确定连续状态个数及初始化,采样模式为连续;编写连续状态程序,注意此处即使只有一个u0也要加上u0[0],且此处的下标是从0开始。编写输出程序,此处的输入输出定义取默认值。完成后点击build按钮生成s函数。最后,总结以上的例子,可得以下仿真结果,从图中看,结果符合逻辑。