1

我编写了一个简单的 s 函数,它在 ac 代码中调用一个函数,该函数对单轨模型进行建模。我正在使用常量变量来存储质量、偏航惯性矩、转向比等。我想知道如何使这些变量可调。我想从我的 s-function 中创建一个子系统,然后使用 realtime Workshop->generate s-function 并从列表中选择可调参数。但现在我找不到任何可调参数,因为我没有将任何东西指定为可调参数

这是我的 s-function 代码

#define S_FUNCTION_NAME  single_track
#define S_FUNCTION_LEVEL 2

#include "simstruc.h"


#include "single_track_func.c"


#define MDL_START  /* Change to #undef to remove function */ 
#if defined(MDL_START) 

static void mdlStart(SimStruct *S) 
  { 

    initialization();

  } 
#endif


static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);


    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
        return; /* Parameter mismatch will be reported by Simulink */
    }

    if (!ssSetNumInputPorts(S, 2)) return;
    ssSetInputPortWidth(S, 0, 1);
    ssSetInputPortDirectFeedThrough(S, 0, 1);
    ssSetInputPortWidth(S, 1, 1);
    ssSetInputPortDirectFeedThrough(S, 1, 1);


    if (!ssSetNumOutputPorts(S,3)) return;
    ssSetOutputPortWidth(S, 0, 1);
    ssSetOutputPortWidth(S, 1, 1);
    ssSetOutputPortWidth(S, 2, 1);
   ssSetNumSampleTimes(S, 1);


    ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);


    ssSetOptions(S,
                 SS_OPTION_WORKS_WITH_CODE_REUSE |
                 SS_OPTION_EXCEPTION_FREE_CODE |
                 SS_OPTION_USE_TLC_WITH_ACCELERATOR);
}

static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
    ssSetModelReferenceSampleTimeDefaultInheritance(S); 
}


static void mdlOutputs(SimStruct *S, int_T tid)
{
    retvale obj_b;

    InputRealPtrsType v_1 = ssGetInputPortRealSignalPtrs(S,0);               //velocity
    InputRealPtrsType delta_1 = ssGetInputPortRealSignalPtrs(S,1);         //steering angle

    real_T            *a_y_1    = ssGetOutputPortRealSignal(S,0);          //lateral acceleration           
    real_T            *psi_dot_1    = ssGetOutputPortRealSignal(S,1);      //yaw velocity   
    real_T            *beta_1    = ssGetOutputPortRealSignal(S,2);         //attitude angle   



                obj_b=singletrack((double)*(*v_1),(double)*(*delta_1));
                *a_y_1    = obj_b.a_y;          //lateral acceleration           
                *psi_dot_1 =obj_b.psi_dot;       //yaw velocity   
                *beta_1    =obj_b.beta;

}

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

这是具有功能 singletrack() 的逻辑文件

#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;

const int cv=75000;                  //cornering stiffness front      
const int ch=150000;                //cornering stiffness rear axle          
const int m=1550;                                    //mass of the vehicle kg
const int lv=1.344;                 //distance from center of gravity to front wheel
const int lh=1.456;                 //distance from center of gravity to rear wheel  
const int theta=2800;                //yaw moment of inertia      
const int I_s=16;                    //overall steering ratio      
const float dt=0.001;

retvale singletrack(double a,double b)
{
    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;
}

和相应的 .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);
extern void initialization();
#endif

我知道我必须使用 ssSetSFcnParamTunable() 但即使在查看示例之后也不知道该怎么做!

更新:

我将变量声明为 global real_T real_T *m_s,*cv_s,*ch_s,*lv_s,*lh_s,*theta_s,*I_s_s,*dt_s;

并在我的 mdlInitializeSizes() 中添加了这些代码行。我把它混合起来,一切都很好。但是当我使用 s-function 块并将 s-function 的名称更改为 mex 文件时,matlab 崩溃了。我也将这些参数作为指向我的 single_track () 函数的指针传递

ssSetNumSFcnParams(S, 8);
 m_s=mxGetPr(ssGetSFcnParam(S,0));
 cv_s=mxGetPr(ssGetSFcnParam(S,1));
 ch_s=mxGetPr(ssGetSFcnParam(S,2));
 lv_s=mxGetPr(ssGetSFcnParam(S,3));
 lh_s=mxGetPr(ssGetSFcnParam(S,4));
 theta_s=mxGetPr(ssGetSFcnParam(S,5));
 I_s_s=mxGetPr(ssGetSFcnParam(S,6));
 dt_s=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);

知道为什么会发生崩溃吗?

4

1 回答 1

0

要使参数可调,它必须作为输入从 Simulink 传递到您的 S-Function。

这是通过在 S-Function 块对话框的参数部分中指定它们(作为逗号分隔的列表)来完成的,并使用ssSetNumSFcnParamsS-Function 本身中的方法告诉 S-Function 需要多少参数(您当前有设置为 0)。

此外,在 S-Function 中,您需要

然后您需要重写您的singletrack函数,以便将所有参数作为输入传递给它,而不是硬编码到文件中。

但是,查看您提供的代码,将这一切作为 MATLAB 函数执行要比作为 S-Function 容易得多。

于 2014-12-11T05:38:49.677 回答