小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

MATLAB中的S-Function的用法(C語(yǔ)言)

 好景宜人 2015-03-23

1. S-Function簡(jiǎn)介  

S-Function是system-function的縮寫。說(shuō)得簡(jiǎn)單,S-Function就是用MATLAB所提供的模型不能完全滿足用戶,而提供給用戶自己編寫程序來(lái)滿足自己要求模型的接口。

 

2. MEX函數(shù)與M文件的區(qū)別

第一,  MEX 函數(shù)能實(shí)現(xiàn)的回調(diào)函數(shù)比M-文件能實(shí)現(xiàn)的回調(diào)函數(shù)要多得多;

第二,  MEX 函數(shù)直接訪問(wèn)內(nèi)部數(shù)據(jù)結(jié)構(gòu)SimStruct,SimStruct 是Simulink 用來(lái)保存關(guān)于S-function 信息的一個(gè)數(shù)據(jù)結(jié)構(gòu);

第三,  MEX 函數(shù)也可使用MATLAB MEX 文件API 直接來(lái)訪問(wèn)MATLAB 的工作空間。

如果一個(gè)C MEX文件與一個(gè)M文件具有相同的名字,則C MEX文件被優(yōu)先使用,即在S-Function塊中使用的是C MEX文件。

 

3. 基礎(chǔ)知識(shí)

3.1 直接饋通(direct feedthrough)

 直接饋通表示系統(tǒng)的輸出或可變采樣時(shí)間是否受到輸入的控制。

a.  輸出函數(shù)(mdlOutputs或flag==3)是輸入u的函數(shù)。即,如果輸入u在mdlOutputs中被訪問(wèn),則存在直接饋通。

b.  對(duì)于一個(gè)變步長(zhǎng)S-Function的“下一個(gè)采樣時(shí)間”函數(shù)(mdlGetTimeOfNextVarHit或flag==4)中可以訪問(wèn)輸入u。

例如,一個(gè)需要其輸入的系統(tǒng)(也就是具有直接饋通)是運(yùn)算y=kXu,其中,u是輸入,k是增益,y是輸出。

又如,一個(gè)不需要其輸入的系統(tǒng)(也就是沒(méi)有直饋通)是一種簡(jiǎn)單的積分運(yùn)算:

輸出:y=x;

導(dǎo)數(shù):dx/dt=u

其中,x是狀態(tài),dx/dt是狀態(tài)對(duì)時(shí)間的導(dǎo)數(shù),u是輸入,y是輸出。

正確設(shè)置直接饋通標(biāo)志是十分重要的,因?yàn)樗绊懩P椭袎K的執(zhí)行順序,并可用檢測(cè)代數(shù)環(huán)。

3.2 dynamically sized inputs 

主要是給出:輸入連續(xù)狀態(tài)數(shù)目(size.NumContStates),離散狀態(tài)數(shù)目(size.NumDiscStates) ,輸出數(shù)目(size.NumOutputs),輸入數(shù)目(size.NumInputs),Direct Feedthrough(size.Dir Feedthrough)。 

3.3 setting sample times and offsets

setting smaple times and offsets主要設(shè)置采樣時(shí)間.

3.4 Level-1 和Level-2

Level 1 提供一個(gè)簡(jiǎn)單的接口,可與少部分的S函數(shù)API交互。Matlab對(duì)于這種方式的支持更多的是為了保持與以前版本的兼容,現(xiàn)在推薦采用的是Level 2 S函數(shù)。

 

4. S-Function實(shí)例

S-Function的仿真流程

例如要?jiǎng)?chuàng)建一個(gè)有1輸入(2維),2輸出(1維),3個(gè)參數(shù),還有全局變量的S-Function。 過(guò)程如下:

a. 新建sfunction的C語(yǔ)言文件

打開(kāi)simulink,點(diǎn)擊User-Defined Functions里面的S-Function Examples。這個(gè)里面有多個(gè)語(yǔ)言版本的模板,有C,C++,Ada,F(xiàn)ortran和M語(yǔ)言的版本,其實(shí)都大同小異,只要了解幾個(gè)函數(shù)就很容易使用了。 選擇C語(yǔ)言的版本:從S-function模塊中選擇C-file S-functions里面的Basic C-MEX template。打開(kāi)后,另存為自己的模塊名字,如test.c 。下面我們來(lái)分析代碼: 

復(fù)制代碼
#define S_FUNCTION_NAME  test//這里把文件名sfuntmpl_basic修改為test
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
//程序里面要用到的頭文件在這里引用,如“math.h”等。
float global_var; //定義全局變量
static void mdlInitializeSizes(SimStruct *S)
{
 //這個(gè)函數(shù)用來(lái)設(shè)置輸入、輸出和參數(shù)的。
    ssSetNumSFcnParams(S, 3);  /*設(shè)置參數(shù)個(gè)數(shù),這里為3 */
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return;
    }
    ssSetNumContStates(S, 0);//設(shè)置連續(xù)狀態(tài)的個(gè)數(shù),缺省為0;
    ssSetNumDiscStates(S, 0);//設(shè)置離散狀態(tài)的個(gè)數(shù),缺省為0;
    if (!ssSetNumInputPorts(S, 1)) return;//設(shè)置輸入變量的個(gè)數(shù),這里為1
    ssSetInputPortWidth(S, 0, 2); //設(shè)置輸入變量0的維數(shù)為2
ssSetInputPortRequiredContiguous(S, 0, true); //設(shè)置input0的訪問(wèn)方式,true就是臨近訪問(wèn),這樣指針的增量后就可以直接訪問(wèn)下個(gè)input端口了。
ssSetInputPortDirectFeedThrough(S, 0, 1);// 設(shè)置輸入端口的信號(hào)是否mdlOutputs函數(shù)中使用,這兒設(shè)置為true。
    if (!ssSetNumOutputPorts(S, 2)) return;//設(shè)置輸出變量的個(gè)數(shù)
ssSetOutputPortWidth(S, 0, 1);//設(shè)置輸出變量0的維數(shù)為1維
    ssSetOutputPortWidth(S, 1, 1);//設(shè)置輸出變量1的維數(shù)為1維
ssSetNumSampleTimes(S, 1); //設(shè)置采樣時(shí)間,此處為1s。
    ssSetNumRWork(S, 0);//不管
    ssSetNumIWork(S, 0);
    ssSetNumPWork(S, 0);
    ssSetNumModes(S, 0);
    ssSetNumNonsampledZCs(S, 0);
ssSetOptions(S, 0);
//下面可以寫全局變量的初始化程序
global_var=1;
}
static void mdlInitializeSampleTimes(SimStruct *S)//暫時(shí)不管
{
    ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
 
}
#define MDL_INITIALIZE_CONDITIONS   /* Change to #undef to remove function */
#if defined(MDL_INITIALIZE_CONDITIONS)
 
  static void mdlInitializeConditions(SimStruct *S)//暫時(shí)不管
  {
  }
#endif /* MDL_INITIALIZE_CONDITIONS */
#define MDL_START  /* Change to #undef to remove function */
#if defined(MDL_START) 
  static void mdlStart(SimStruct *S)//暫時(shí)不管
  {
  }
#endif /*  MDL_START */
static void mdlOutputs(SimStruct *S, int_T tid)//這里填入相關(guān)的運(yùn)算、算法等
{
real_T *para1 = mxGetPr(ssGetSFcnParam(S,0));
real_T *para2 = mxGetPr(ssGetSFcnParam(S,1));
real_T *para3 = mxGetPr(ssGetSFcnParam(S,2));
const real_T *u = (const real_T*) ssGetInputPortSignal(S,0);
real_T       *y1 = ssGetOutputPortSignal(S,0);
real_T       *y2 = ssGetOutputPortSignal(S,1);
y1[0]=u[0]*para1[0]+u[1]*para2[0];
y2[0]=u[1]*para3[0]+u[0]*para1[0];
}
#define MDL_UPDATE  /* Change to #undef to remove function */
#if defined(MDL_UPDATE)
 
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
  }
#endif /* MDL_UPDATE */
#define MDL_DERIVATIVES  /* Change to #undef to remove function */
#if defined(MDL_DERIVATIVES)
  static void mdlDerivatives(SimStruct *S)
  {
  }
#endif /* MDL_DERIVATIVES */
static void mdlTerminate(SimStruct *S)//這里需要把global變量全部初始化,否則下次運(yùn)行程序時(shí),全局變量還是之前的值。
{
}
 
#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
#include "simulink.c"      /* MEX-file interface mechanism */
#else
#include "cg_sfun.h"       /* Code generation registration function */
#endif
復(fù)制代碼

 b. 編譯

在matlab的command window 里面輸入“mex test.c”,即可將test.c編譯為mex文件。

c.調(diào)用sfunction

在simulink空間里面拉入sfunction,在s-function name里面填入test,參數(shù)里面填入要設(shè)定的參數(shù),然后仿真即可。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多