如何在s-functions中将常量变量用作matlab中的可调参数

时间:2014-12-10 11:02:47

标签: matlab variables simulink s-function

我编写了一个简单的s函数,它调用c代码中的函数来模拟单轨模型。我使用常数变量来存储质量,偏航惯性矩,转向比等。我想知道如何使这些变量可调。我想从我的s函数创建一个子系统,然后使用实时研讨会 - >生成s函数并从列表中选择可调参数。但是现在我无法找到任何可调参数,因为我没有指定任何可调参数

这是我的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(),但即使看了例子也不知道怎么做!!

更新

我将变量声明为全局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);

知道崩溃的原因吗?

1 个答案:

答案 0 :(得分:0)

要使参数可调,必须将其作为Simulink的输入传递给S函数。

这是通过在S-Function块的对话框的参数部分中指定它们(以逗号分隔的列表),并使用S-Function本身内的ssSetNumSFcnParams方法来告诉S函数预期有多少参数(您当前将其设置为0)。

此外,在S-Function中你需要

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

但是,看一下你已经给出的代码,作为一个MAT函数,它将比作为一个S函数更容易完成。