我正在研究可调参数,并且手动s函数非常简单。但是当我们想要使变量可调(从s函数参数块中获取它们作为参数)并使用遗留代码工具自动生成s函数时该怎么办。 它甚至可能吗?
例如,我编写了一个简单的单轨模型。这是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中的s-function中引入了一些全局变量 ssSetNumSFcnParams(S,8);
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';