主要内容

创建和更新S-Function运行时参数

关于运行时参数

可以创建内部表示的外部s函数对话框参数调用运行时参数.每个运行时参数对应一个或多个对话框参数,可以具有与其对应的外部参数相同的值和数据类型,也可以具有不同的值或数据类型。如果运行时参数的值或数据类型与外部对应参数不同,则可以说对话框参数已被转换为创建运行时参数。对应于多个对话框参数的运行时参数的值通常是对话框参数值的函数。的仿真软金宝app件®engine为运行时参数分配和释放存储空间,并提供用于更新和访问它们的函数,因此不需要s -function来执行这些任务。运行时参数促进了以下类型的s函数操作:

  • 计算参数

    通常情况下,块的输出是几个对话框参数值的函数。例如,假设一个块有两个参数,一个物体的体积和密度,块的输出是输入信号和物体质量的函数。在这种情况下,质量可以看作是由体积和密度这两个外部参数计算出来的第三个内部参数。s函数可以创建一个与计算权重对应的运行时参数,从而消除了在输出计算中为权重提供特殊情况处理的需要。看到从多个S-Function参数创建运行时参数更多信息。

  • 数据类型转换

    通常,块需要更改对话框参数的数据类型以促进内部处理。例如,假设块的输出是输入和对话框参数的函数,并且输入和对话框参数是不同的数据类型。在这种情况下,s函数可以创建一个运行时参数,该参数具有与对话框参数相同的值,但具有输入信号的数据类型,并在输出计算中使用该运行时参数。

  • 代码生成

    在代码生成期间,金宝app仿真软件编码器™产品将所有运行时参数自动写入模型.rtw文件,从而不需要s函数通过mdlRTW方法。

sfcndemo_runtime金宝appSimulink模型包含四个创建运行时参数的s函数示例。

创建运行时参数

以C开头函数中,您可以以多种方式创建运行时参数。下面几节描述在C S-function中创建运行时参数的不同方法。

一次性创建所有运行时参数

使用SimStruct函数ssRegAllTunableParamsAsRunTimeParamsmdlSetWorkWidths创建与所有可调参数对应的运行时参数。此函数要求您向它传递一个名称数组,每个运行时参数对应一个名称数组。的金宝app仿真软件编码器Product在代码生成期间使用这些名称作为参数名称。的功能sfun_runtime1.c演示如何一次性创建所有运行时参数。

这种创建运行时参数的方法假设s函数运行时参数与其可调对话框参数之间存在一一对应关系。事实可能并非如此。例如,s函数可能希望使用计算参数,其值是几个对话框参数的函数。在这种情况下,s函数可能需要单独创建运行时参数。

单独创建运行时参数

要单独创建运行时参数,使用s函数mdlSetWorkWidths方法应该

  1. 指定它打算使用的运行时参数的数量,使用ssSetNumRunTimeParams

  2. 使用ssRegDlgParamAsRunTimeParam注册与单个对话框参数对应的运行时参数,即使存在数据类型转换,也可以ssSetRunTimeParamInfo设置与多个对话框参数对应的运行时参数的属性。

下面的示例使用ssRegDlgParamAsRunTimeParam它来自于s函数sfun_runtime3.c.这个例子直接从对话框参数创建一个运行时参数,其数据类型与第一个输入端口的信号相同。

static void mdlSetWorkWidths(SimStruct *S){/*获取运行时参数的输入数据类型*/ DTypeId dtId = ssGetInputPortDataType(S, 0);/*定义运行时参数的名称*/ const char_T *rtParamName = "增益";ssSetNumRunTimeParams (S, 1);/*一个运行时参数*/ if (ssGetErrorStatus(S) != NULL)返回;ssRegDlgParamAsRunTimeParam(S, GAIN_IDX, 0, rtParamName, dtId);} #endif /* MDL_SET_WORK_WIDTHS */

下一个示例使用ssSetRunTimeParamInfo它来自于s函数sfun_runtime2.c

静态无效mdlSetWorkWidths(SimStruct *S) {ssParamRec p;/*初始化ssParamRec结构*/ int dlgP = GAIN_IDX;/* s函数参数索引*/ /*配置运行时参数信息*/ p.name = "增益";p.nDimensions = 2;p.dimensions = (int_T *) mxGetDimensions(GAIN_PARAM(S));. datatypeid = SS_DOUBLE;p.complexSignal = COMPLEX_NO;p.data = (void *)mxGetPr(GAIN_PARAM(S));p.dataAttributes = NULL;p.nDlgParamIndices = 1; p.dlgParamIndices = &dlgP; p.transformed = false; p.outputAsMatrix = false; /* Set number of run-time parameters */ if (!ssSetNumRunTimeParams(S, 1)) return; /* Set run-time parameter information */ if (!ssSetRunTimeParamInfo(S, 0, &p)) return; }

的功能sfun_runtime2.c定义参数GAIN_IDX而且GAIN_PARAM如下所示,在使用这些参数之前mdlSetWorkWidths

#定义GAIN_IDX参数ssgetfcnparam (S,GAIN_IDX)

从多个S-Function参数创建运行时参数

使用ssSetRunTimeParamInfo函数mdlSetWorkWidths创建运行时参数作为多个s函数参数的函数。例如,考虑一个具有两个s函数参数(密度和体积)的s函数。s函数输入一个力(F)并输出一个加速度(一个).的mdlOutputs方法使用该方程计算力F = m *,其中质量()是密度与体积的乘积。

的功能sfun_runtime4.c使用单个运行时参数来存储质量,实现此示例。s函数首先定义运行时参数数据类型,以及与体积和密度相关的变量。

#if RUN_TIME_DATA_TYPE == SS_DOUBLE typedef true;#endif #define VOL_IDX 0 #define VOL_PARAM(S) ssGetSFcnParam(S,VOL_IDX) #define DEN_IDX 1 #define DEN_PARAM(S) ssGetSFcnParam(S,DEN_IDX)

mdlSetWorkWidths方法然后初始化运行时参数,如下所示。

静态无效mdlSetWorkWidths(SimStruct *S) {ssParamRec p;/*初始化ssParamRec结构*/ int dlg[2];/*存储对话框索引*/ real_T vol = *mxGetPr(VOL_PARAM(S));real_T den = *mxGetPr(DEN_PARAM(S));RunTimeDataType *质量;/*将运行时参数的维度初始化为*局部变量。Simu金宝applink引擎将此*信息复制到运行时参数中。*/ int_T massDims[2] = {1,1};/*为运行时参数数据分配内存。s函数*拥有这个内存位置。 The Simulink engine does not copy the data.*/ if ((mass=(RunTimeDataType*)malloc(1)) == NULL) { ssSetErrorStatus(S,"Memory allocation error"); return; } /* Store the pointer to the memory location in the S-function * userdata. Since the S-function owns this data, it needs to * free the memory during mdlTerminate */ ssSetUserData(S, (void*)mass); /* Call a local function to initialize the run-time * parameter data. The Simulink engine checks that the data is not * empty so an initial value must be stored. */ calcMass(mass, vol, den); /* Specify mass as a function of two S-function dialog parameters */ dlg[0] = VOL_IDX; dlg[1] = DEN_IDX; /* Configure run-time parameter information. */ p.name = "Mass"; p.nDimensions = 2; p.dimensions = massDims; p.dataTypeId = RUN_TIME_DATA_TYPE; p.complexSignal = COMPLEX_NO; p.data = mass; p.dataAttributes = NULL; p.nDlgParamIndices = 2; p.dlgParamIndices = &dlg p.transformed = RTPARAM_TRANSFORMED; p.outputAsMatrix = false; /* Set number of run-time parameters */ if (!ssSetNumRunTimeParams(S, 1)) return; /* Set run-time parameter information */ if (!ssSetRunTimeParamInfo(S,0,&p)) return; }

局部函数calcMass中的运行时参数值mdlSetWorkWidths而在mdlProcessParameters,当调整密度或体积的值时。

/ *功能:calcMass  ============================================== * 文摘:*本地函数计算质量与体积和密度的函数。*/ static void calcMass(RunTimeDataType *mass, real_T vol, real_T den) {*mass = vol * den;}

mdlOutputs方法使用所存储的质量来计算力。

/ *功能:mdlOutputs  ========================================== * 文摘:* *输出加速度作为输入力除以质量计算。*/ static void mdlOutputs(SimStruct *S, int_T tid) {real_T *y1 = ssGetOutputPortRealSignal(S,0);InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);RunTimeDataType *mass = (RunTimeDataType *)((ssGetRunTimeParamInfo(S,0))->data);/* *输出加速度=力/质量*/ y1[0] = (*uPtrs[0]) /*质量;}

最后,mdlTerminate方法释放为中运行时参数分配的内存mdlSetWorkWidths

/ *功能:mdlTerminate  ========================================== * 文摘:*免费用户数据。*/ static void mdlTerminate(SimStruct *S){/*用于存储运行时参数数据的空闲内存*/ RunTimeDataType *mass = ssGetUserData(S);if(质量!= NULL) {free(质量);}}

要运行这个例子,打开Simulink模型:金宝app

更新运行时参数

每当您在模拟过程中更改S-function对话框参数的值时,Simulink引擎将调用S-function金宝appmdlCheckParameters方法来验证更改。如果更改有效,则引擎调用s函数mdlProcessParameters方法在下一个时间步骤的开始。这个方法应该更新s函数的运行时参数,以反映对话框参数的更改。

在C s函数中,使用与创建运行时参数的方式相适应的方法更新运行时参数,如下面的部分所述。

一次性更新所有参数

在C MEX s -函数中,如果s -函数可调对话框参数和运行时参数之间存在一一对应关系,即运行时参数是使用ssRegAllTunableParamsAsRunTimeParams, s函数可以使用SimStruct函数ssUpdateAllTunableParamsAsRunTimeParams完成这个任务。这个函数更新每个运行时参数,使其具有与相应对话框参数相同的值。看到sfun_runtime1.c举个例子。

单独更新参数

如果S-function对话框和运行时参数之间没有一对一的对应关系,或者运行时参数是对话框参数的转换版本mdlProcessParameters方法必须分别更新每个参数。根据运行时参数的注册方式选择用于更新该运行时参数的方法。

如果使用注册运行时参数ssSetRunTimeParamInfo,mdlProcessParameters方法使用ssUpdateRunTimeParamData更新运行时参数,如sfun_runtime2.c.这个函数更新参数的属性记录中的数据字段,ssParamRec,用一个新的值。不能直接修改ssParamRec的指针,尽管您可以获得指向ssParamRec使用ssGetRunTimeParamInfo

如果使用注册运行时参数ssRegDlgParamAsRunTimeParam,mdlProcessParameters方法使用ssUpdateDlgParamAsRunTimeParam更新运行时参数,如中所示sfun_runtime3.c

将参数更新为多个S-Function参数的函数

如果将运行时参数注册为多个s函数参数的函数,则mdlProcessParameters方法使用ssUpdateRunTimeParamData更新运行时参数。

的功能sfun_runtime4.c提供示例。在本例中,mdlProcessParameters方法计算运行时参数的新值,并将该值传递给运行时参数的内存位置的指针,该位置是在调用时分配的mdlSetWorkWidths.的mdlProcessParameters方法将更新后的运行时参数的指针传递给ssUpdateRunTimeParamData

调优运行时参数

调优对话框参数将在模拟过程中调优相应的运行时参数,并且只有当对话框参数满足以下条件时才会在生成的代码中调优:

  • s函数将对话框参数标记为可调,使用ssSetSFcnParamTunable

  • 对话框的参数是一个MATLAB®具有Simulink产品支持的数据类型的值数组。金宝app金宝app

注意,不能调优值为单元格数组或结构的运行时参数。

访问运行时参数

您可以轻松地从s函数代码访问运行时参数。要访问运行时参数数据,请根据数据类型选择以下方法之一。

  • 如果数据是类型

    real_T *dataPtr = (real_T *) ssGetRunTimeParamInfo(S, #)->data;
  • 如果参数是复杂的,则数据的实部和虚部是交错的。例如,用户输入如下信息:

    K = [1+2i, 3+4i;5 + 6, 7 + 8我)

    生成的矩阵是

    K = 1+ 2i3 + 4i5 + 6i7 +8i

    这个矩阵的内存布局为

    [1,2,5,6,3,4,7,8]

    要从s函数代码中访问复杂的运行时参数:

    For (i = 0;我<宽度;i++) {real_T realData = dataPtr[(2*i)];real_T imagData = dataPtr[(2*i)+1];}

请注意

矩阵元素以列主格式写出来。实值和虚值交错在一起。

另请参阅

相关的话题