我编写了一个简单的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);
知道崩溃的原因吗?
答案 0 :(得分:0)
要使参数可调,必须将其作为Simulink的输入传递给S函数。
这是通过在S-Function块的对话框的参数部分中指定它们(以逗号分隔的列表),并使用S-Function本身内的ssSetNumSFcnParams
方法来告诉S函数预期有多少参数(您当前将其设置为0)。
此外,在S-Function中你需要
然后,您需要重写singletrack
函数,以便将所有参数作为输入传递给它,而不是硬编码到文件中。
但是,看一下你已经给出的代码,作为一个MAT函数,它将比作为一个S函数更容易完成。