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