私は調整可能なパラメーターに取り組んでおり、手動の 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';