RSS

C-MEX Tutorial By Control Lab – DTE FTUI

04 May

C-Mex merupakan pemrograman bahasa C yang terintegrasi dengan MATLAB. Dengan menggunakan C-Mex, kita dapat membuat blok diagram Simulink dengan algoritma yang kita inginkan. Kelebihan pemrograman dengan C-Mex dibandingkan dengan bahasa m-file adalah waktu pemrosesan yang lebih cepat.

  1. INSTALASI

Program yang dibutuhkan:

  • MATLAB
  • compiler bahasa C à Microsoft visual C/C++ atau LCC
  • Simulink

Untuk menentukan compiler yang digunakan, pada command window lakukan langkah – langkah berikut:

  • ketik mex –setup
  • pilih compiler
  • ketik yes
  1. PROSEDUR

Seperti bahasa C pada umumnya, terdapat beberapa void pada pemrograman dengan C-Mex. Void – void dasar yang selalu ada:

  1. static void mdlInitializeSizes

    Void ini berfungsi untuk menginisialisasi karakteristik blok Simulink, seperti menentukan banyaknya variable global yang tersusun dalam suatu array xD, banyaknya input, banykanya output, banyaknya jumlah sample time dalam blok tersebut.

  2. static void mdlInitializeSampleTimes

    Void ini berfungsi untuk menentukan sample time dan offset time. Offset time adalah waktu awal yang digunakan untuk memulai simulasi.

  3. static void mdlInitializeConditions

    Void ini berfungsi untuk membuat semua nilai awal xD0 menjadi 0.

  4. static void mdlOutputs

    Void ini berfungsi untuk menentukan variable global (array xD) yang menjadi keluaran.

  5. static void mdlUpdate

Void ini berfungsi untuk menerapkan algoritma yang kita inginkan

  1. static void mdlTerminate

    Void ini berfungsi untuk mengakhiri pemrograman C-Mex ini. Isinya berupa void kosong.

 

Secara umum, bentuk pemrogramannya adalah sebagai berikut:

 

#define S_FUNCTION_LEVEL 2

#define S_FUNCTION_NAME integral

 

#include <math.h>

#include “simstruc.h”

 

#define U(element) (*uPtrs[element])

#define ZERO    1.0E-20

 

static void mdlInitializeSizes(SimStruct *S)

{

}

static void mdlInitializeSampleTimes(SimStruct *S)

{

}

#define MDL_INITIALIZE_CONDITIONS

static void mdlInitializeConditions(SimStruct *S)

{

}

static void mdlOutputs(SimStruct *S, int_T tid)

{

}

#define MDL_UPDATE

static void mdlUpdate(SimStruct *S, int_T tid)

{

}

static void mdlTerminate(SimStruct *S)

{}

#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

 

Dari contoh di atas, secara umum pembuatan S-function terdiri dari:

  1. define level S-function
  2. define nama S-function
  3. define input dengan menggunakan U(element)
  4. define MDL_INITIALIZE_CONDITIONS
  5. define MDL_UPDATE
  6. diakhiri dengan beberapa perintah untuk menentukan bahwa file tersebut adalah mex-file dan di-compile secara mex-file, mekanisme interface mex-file, dan menentukan fungsi registrasi untuk menerjemahkan kode.

 

  1. SYNTAX

Untuk mempelajari syntax yang ada, mari kita buat suatu blok simulink dengan algoritma integrasi dengan menggunakan bahasa C-Mex. Contoh program:

#define S_FUNCTION_LEVEL 2

#define S_FUNCTION_NAME integral

 

#include <math.h>

#include “simstruc.h”

 

#define U(element) (*uPtrs[element])

#define ZERO    1.0E-20

 

void kali(double o,double *xD, int i)

{

 

xD[i]= xD[i]+o*0.15;

}

 

static void mdlInitializeSizes(SimStruct *S)

{

ssSetNumDiscStates(S,1);

 

if(!ssSetNumInputPorts(S, 1)) return;

ssSetInputPortWidth(S, 0, 1);

ssSetInputPortDirectFeedThrough(S, 0, 1);

ssSetInputPortOverWritable(S, 0, 1);

 

if(!ssSetNumOutputPorts(S, 1)) return;

ssSetOutputPortWidth(S, 0, 1);

 

ssSetNumSampleTimes(S, 1);

 

/* Take care when specifying exception free code – see sfuntmpl.doc */

ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_DISCRETE_VALUED_OUTPUT));

}

static void mdlInitializeSampleTimes(SimStruct *S)

{

ssSetSampleTime(S, 0, 0.15);

ssSetOffsetTime(S, 0, 0);

}

#define MDL_INITIALIZE_CONDITIONS

static void mdlInitializeConditions(SimStruct *S)

{

real_T            *xD0     = ssGetRealDiscStates(S);

int_T                nDStates     = ssGetNumDiscStates(S);

int_T                i;

 

/* Initialize the discrete states to 0.0 */

for(i=0; i <=nDStates-1; i++) {

     xD0[i] = 0.0;

}

}

static void mdlOutputs(SimStruct *S, int_T tid)

{

InputRealPtrsType    uPtrs     = ssGetInputPortRealSignalPtrs(S,0);

real_T    *y     = ssGetOutputPortRealSignal(S,0);

real_T    *xD     = ssGetRealDiscStates(S);

int_T    nDStates     = ssGetNumDiscStates(S);

 

y[0] = xD[0];

}

 

 

#define MDL_UPDATE

static void mdlUpdate(SimStruct *S, int_T tid)

{

real_T            *xD     = ssGetRealDiscStates(S);

int_T                nDStates    = ssGetNumDiscStates(S);

InputRealPtrsType    uPtrs = ssGetInputPortRealSignalPtrs(S,0);

real_T x,z;

int_T i=0;

 

x=U(i);

kali(x,xD,i);

}

 

static void mdlTerminate(SimStruct *S)

{}

#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

 

Beberapa syntax – syntax yang digunakan:

  • Pada prosedur mdlInitializeSizes(Simstruct *S)
    • ssSetNumDiscStates(S,3)

      Syntax ini berfungsi untuk menentukan banyaknya state (variable global) dalam S-function. Angka 3 menunjukkan bahwa banyaknya state pada S-function adalah 3 state.

    • ssSetNumInputPorts(S, 1)

      syntax ini berfungsi untuk menentukan banyaknya port input blok suatu S-function. Syntax di atas menunjukkan bahwa ada 1 port input pada S-function yang dibuat.

    • ssSetInputPortWidth(S, 0, 2)

      syntax ini berfungsi untuk menentukan lebar input pada blok diagram suatu S-function. Angka 0 menunjukkan lebar input port ke-0. Sedangkan angka 2 menunjukkan terdapat 2 input pada port tersebut.

    • ssSetInputPortDirectFeedThrough(S, 0, 1)

      Syntax ini berfungsi untuk menentukan status direct feedthrough suatu port blok diagram. Angka 0 menunjukkan port input ke-0 yang akan diset. Angka 1 menunjukkan bahwa port tersebut diset dalam status direct feedthrough. Jika angka 1 pada syntax diganti dengan angka 0, maka sinyal port input yang berhubungan tidak digunakan dalam mdlOutputs.

    • ssSetInputPortOverWritable(S, 0, 1)

      Syntax ini berfungsi untuk menentukan apakah port input blok diagram ini dapat di-overwrite oleh port output blok diagram tersebut atau tidak. Angka 0 menunjukkan port input ke-0 yang akan diset. Dan angka 1 menunjukkan bahwa simulink akan mengalokasikan lokasi memori yang sama untu suatu port input dan suatu untuk port output. Hal ini berfungsi untuk mengurangi penggunaan memori.

    • ssSetNumOutputPorts(S, 1)

      Syntax ini berfungsi untuk menentukan banyaknya port output pada blok diagram suatu S-function

    • ssSetOutputPortWidth(S, 0, 1)

      Syntax ini berfungsi untuk menentukan lebar output pada port output ke-0 blok diagram suatu S-function.

    • ssSetNumSampleTimes(S, 1)

      Syntax ini berfungsi untuk menentukan banyaknya sample time pada blok diagram suatu S-function

    • ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_DISCRETE_VALUED_OUTPUT))

      Syntax SS_OPTION_EXCEPTION_FREE_CODE menunjukkan bahwa S-function yang kita buat tidak menggunakan mexErrMsgTxt, mxCalloc, atau routine lainnya yang dapat menghasilkan pengecualian saat dipanggil. Sedangkan SS_OPTION_DISCRETE_VALUED_OUTPUT menunjukkan bahwa S-function yang kita buat mempunyai nilai output diskrit. Tanda “|” manandakan bahwa kita menggunakan kedua option tersebut.

  • Pada prosedur mdlInitializeSampleTimes(Simstruct *S)
    • ssSetSampleTime(S, 0, 0.15)

      Syntax ini berfungsi untuk menentukan besarnya sample time yang digunakan pada blok diagram Simulink. Tujuan syntax tersebut adalah menentukan sample time ke-0 bernilai 0.15.

    • ssSetOffsetTime(S, 0, 0)

      Syntax ini berfungsi untuk menentukan waktu mulai suatu simulasi pada blok diagram suatu S-function. Syntax di atas bertujuan untuk menentukan waktu offset sample time ke-0 adalah 0.

     

  • Pada prosedur mdlInitializeConditions(Simstruct *S)
    • ssGetRealDiscStates(S)

      Syntax ssGetRealDiscStates(S) berfungsi untuk menentukan ukuran array real yang dibutuhkan, yaitu sebanyak jumlah state-nya.

    • ssGetNumDiscStates(S)

      Syntax ssGetNumDiscStates(S) berfungsi untuk mendapatkan banyaknya global state dan memasukkannya ke variable nDStates yang dideklarasikan sebagai variable integer.

     

  • Pada prosedur mdlOutputs(Simstruct *S)
    • ssGetInputPortRealSignalPtrs(S,0)

      Syntax
      di atas berfungsi untuk menentukan banyaknya pointer yang diperlukan oleh port input yang bersangkutan (port input ke-0 untuk syntax di atas). Banyaknya pointer yang dibutuhkan sama dengan lebar port input tersebut.

    • ssGetOutputPortRealSignal(S,0)

      Syntax ini mempunyai fungsi yang sama seperti syntax di atas. Hanya saja syntax ini berkaitan dengan ouput.

     

  • #define S_FUNCTION_LEVEL 2

    Syntax ini menunjukkan bahwa S-function yang kita buat adalah S-function level 2. S-function level 1 digunakan pada Simulink versi 1.3 sampai 2.1. S-function level 2 digunakan pada Simulink versi 3 ke atas.

  • #define S_FUNCTION_NAME integral

    Syntax ini menunjukkan bahwa nama blok S-function yang kita buat adalah integral.

NB: Hal yang perlu diperhatikan dalam pembuatan S_function adalah index yang selalu dimulai dari 0.

 

 

  1. SIMULASI

Setelah membuat S-function, lakukan hal- hal berikut ini:

  • save S-function yang kita buat dengan nama file yang sama dengan nama blok yang kita set
  • compile S-function yang kita buat pada command window

    pada command window MATLAB, gunakan syntax mex nama_file.c

  • buat model pada Simulink seperti gambar di bawah ini

  • simulasikan, dan pada scope akan terlihat seperti gambar berikut

     

    Sumber : http://www.controllabui.org

 
 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: