2

私は調整可能なパラメーターに取り組んでおり、手動の s-function を使用すると非常に簡単です。しかし、変数を調整可能 (s-function パラメーター ブロック からパラメーターとして取得) し、レガシ コード ツールを使用して s-function を自動的に生成したい場合はどうすればよいでしょうか。それは可能ですか?

たとえば、単純な単線モデルを作成しました。これは single_track.h ファイルです

#ifndef _SINGLE_TRACK_FUNC_
#define _SINGLE_TRACK_FUNC_

typedef struct retvale
{
double a_y;
double psi_dot;
double beta;
} retvale;

extern struct retvale singletrack(double a,double b,double m,double cv,double ch,double lv,double lh,double theta,double I_s, double dt);
extern void initialization();
#endif

これは single_track.c ファイルです

#include "single_track_func.h"

float a_1_1,a_1_2,a_2_1,a_2_2,b_1_1,b_2_1,psi_dot_prev,beta_prev;
int count;

retvale singletrack(double a,double b,double m,double cv,double ch,double lv,double lh,double theta,double I_s, double dt)
{
    retvale my_obj;



    static float beta_dot=0; 
    static float psi_double_dot=0; 
    static float beta_previous=0; 
    static float psi_dot_previous=0;


    beta_previous       = beta_prev;
    psi_dot_previous    = psi_dot_prev;
    a_1_1               = ((-cv-ch)/((m)*(a)));
    a_1_2               = ((m*(a)*(a))-((ch*lh)-(cv*lv)))/(m*(a)*(a));    
    a_2_1               = (-(ch*lh)+(cv*lv))/theta;
    a_2_2               = ((-ch*lh*lh)-(cv*lv*lv))/(theta*(a));
    b_1_1               = -cv/(m*(a));
    b_2_1               = (cv*lv)/(theta);

    beta_dot            = a_1_1 * beta_previous + a_1_2 * psi_dot_previous - b_1_1*((b)/I_s);
    psi_double_dot      = a_2_1 * beta_previous + a_2_2 * psi_dot_previous + b_2_1*((b)/I_s);                             
    my_obj.beta             = beta_dot          * dt + beta_previous;
    my_obj.psi_dot          = psi_double_dot    * dt + psi_dot_previous;
    my_obj.a_y              = (a*((my_obj.psi_dot)-(beta_dot)));
    beta_prev=my_obj.beta;
    psi_dot_prev=my_obj.psi_dot; 
    return my_obj;

}
void initialization()
{
    psi_dot_prev=0;
    beta_prev=0;
}

double m から double dt までの引数は、s-function ブロックからのパラメーターとして期待される入力であり、「double a」および「double b」の値は入力から取得されるため、それらについて心配する必要はありません。

手動で、mdlInitializeSize ssSetNumSFcnParams(S, 8); の S 関数にいくつかのグローバル変数を導入しました。

m_s=mxGetPr(ssGetSFcnParam(S,0));
cv_s=(real_T*) mxGetPr(ssGetSFcnParam(S,1));
ch_s=(real_T*) mxGetPr(ssGetSFcnParam(S,2));
lv_s=(real_T*)mxGetPr(ssGetSFcnParam(S,3));
lh_s=(real_T*)mxGetPr(ssGetSFcnParam(S,4));
theta_s=(real_T*)mxGetPr(ssGetSFcnParam(S,5));
I_s_s=(real_T*)mxGetPr(ssGetSFcnParam(S,6));
dt_s=(real_T*)mxGetPr(ssGetSFcnParam(S,7));
 ssSetSFcnParamTunable(S,0,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,1,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,2,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,3,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,4,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,5,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,6,SS_PRM_SIM_ONLY_TUNABLE);
 ssSetSFcnParamTunable(S,7,SS_PRM_SIM_ONLY_TUNABLE);

これは手動で機能しますが、自動的に機能するようにレガシーコードに入れる方法

私は以前に定義済みの値を使用していたレガシーコードを書きましたが、うまくいきました:

run('CreateBusObject_retvale');


def = legacy_code('initialize');


def.SourceFiles = {'single_track_func.c'};
def.HeaderFiles = {'single_track_func.h'};
def.SFunctionName = 'single_track_1';
def.StartFcnSpec ='void initialization()';
def.OutputFcnSpec ='retvale y1=singletrack(double u1,double u2, double u3,)';
def.SampleTime = [-1,0];


legacy_code('sfcn_cmex_generate', def);



legacy_code('compile', def);

legacy_code('sfcn_tlc_generate', def);

そしてCreateBusObject_retvale.mは

a_y=Simulink.BusElement;
a_y.Name='a_y';
a_y.DataType='double';

psi_dot=Simulink.BusElement;
psi_dot.Name='psi_dot';
psi_dot.DataType='double';

beta=Simulink.BusElement;
beta.Name='beta';
beta.DataType='double';


retvale               = Simulink.Bus;
retvale.HeaderFile    = 'single_track_func.h';
retvale.Elements      = [a_y,psi_dot,beta];


outputBus           = Simulink.BusElement;
outputBus.Name      = 'outputBus';
outputBus.DataType  = 'Bus: retvale';
4

0 に答える 0