【问题标题】:How can I create an s-function in Simulink with an input port that is a 2d array?如何在 Simulink 中使用二维数组的输入端口创建 s-function?
【发布时间】:2012-07-17 15:22:33
【问题描述】:

我正在尝试使用将接受二维数组作为输入的 s-function builder 在 Simulink 中创建一个 s-function。在输入端口中,我指定了维度:2d,行:4,列:4。当我尝试使用 f[x][y] 访问输入端口时,它会给出错误:“错误 C2109:下标需要数组或指针type”,用于输入端口所在的行。

如何在 Simulink 中使用二维数组的输入端口创建 s-function?

相关代码:

static void mdlInitializeSizes(SimStruct *S)
{
  DECL_AND_INIT_DIMSINFO(inputDimsInfo);
  DECL_AND_INIT_DIMSINFO(outputDimsInfo);
  ssSetNumSFcnParams(S, NPARAMS);
  if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) {
  return; /* Parameter mismatch will be reported by Simulink */
  }

  ssSetNumContStates(S, NUM_CONT_STATES);
  ssSetNumDiscStates(S, NUM_DISC_STATES);

  if (!ssSetNumInputPorts(S, NUM_INPUTS)) return;
  /*Input Port 0 */
  inputDimsInfo.width = INPUT_0_WIDTH;
  ssSetInputPortDimensionInfo(S, 0, &inputDimsInfo);
  ssSetInputPortMatrixDimensions( S ,0, INPUT_0_WIDTH, INPUT_DIMS_0_COL);
  ssSetInputPortFrameData(S, 0, IN_0_FRAME_BASED);
  ssSetInputPortDataType(S, 0, SS_DOUBLE);
  ssSetInputPortComplexSignal(S, 0, INPUT_0_COMPLEX);
  ssSetInputPortDirectFeedThrough(S, 0, INPUT_0_FEEDTHROUGH);
  ssSetInputPortRequiredContiguous(S, 0, 1); /*direct input signal access*/

  if (!ssSetNumOutputPorts(S, NUM_OUTPUTS)) return;

  ssSetNumSampleTimes(S, 1);
  ssSetNumRWork(S, 0);
  ssSetNumIWork(S, 0);
  ssSetNumPWork(S, 0);
  ssSetNumModes(S, 0);
  ssSetNumNonsampledZCs(S, 0);

  /* Take care when specifying exception free code – see sfuntmpl_doc.c */
  ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE |
  SS_OPTION_USE_TLC_WITH_ACCELERATOR |
  SS_OPTION_WORKS_WITH_CODE_REUSE));
}

mdlOuputs 中,我尝试将f(端口)视为普通数组。 示例:

x=f[0][0];

这会引发错误。

编辑: 嗯,有点想通了。

您根据输入参数设置端口尺寸,然后您可以使用 f[x*xw+y] 寻址值,其中 x 和 y 是 x 和 y 位置(从 0 开始),xw 是数字列数。

还没有找到更好的方法,但是这个方法可行。

【问题讨论】:

  • 你能复制粘贴S-Function builder为mdlInitializeSizesmdlSetInputPortDimensionInfomdlOutputs(你访问端口的部分)生成的代码吗?
  • Stackoverflow 不允许我在这里发布,所以这里是 mdlInitializeSizes: textsave.de/?p=128363 。没有 mdlSetInputPortDimensionInfo。在 mdlOuputs 中,我尝试将 f(端口)视为普通数组。示例:x=f[0][0]。这给出了一个错误。

标签: c matlab simulink


【解决方案1】:

我猜 S-Function 构建器正在生成类似于 mdlOutputs 中的代码:

real_T *y0 = (real_T *)ssGetOutputPortSignal(S, 0);
// OR 
real_T *y0 = ssGetOutputPortRealSignal(S, 0);

y0 中的任何一行都是指向一维数组的指针,因此当您尝试使用 2 个下标访问它时,编译器会报错。

您可以通过将二维索引更改为线性索引来修复它,就像您在编辑中发布的那样。这工作得很好,事实上,当您使用 2 个下标对二维数组进行索引时,编译器无论如何都必须在幕后执行此操作。

另一种选择是将ssGetInputPortSignal(或ssGetInputPortRealSignal)的返回值转换为指向指针类型的指针

real_T **y0 = (real_T **)ssGetOutputPortSignal(S, 0);

y0[1][1] = 0;

【讨论】:

    【解决方案2】:

    正如您在编辑中提到的,使用线性索引实际上是访问 C MEX s 函数中的矩阵的正确方法。查看 sfun_matadd.c s-function 示例中的 mdlOutputs:http://www.ligo.caltech.edu/~rana/mat/Jenne/sfun_matadd.c。示例代码中的注释解释得很清楚:

     /* 
     * Note1: Matrix signals are stored in column major order.
     * Note2: Access each matrix element by one index not two indices.
     *        For example, if the output signal is a [2x2] matrix signal,
     *        -          - 
     *       | y[0]  y[2] |
     *       | y[1]  y[3] |
     *       -           -
     *       Output elements are stored as follows:
     *           y[0] --> row = 0, col = 0
     *           y[1] --> row = 1, col = 0
     *           y[2] --> row = 0, col = 1
     *           y[3] --> row = 1, col = 1
     */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      • 2016-04-24
      • 1970-01-01
      • 2022-01-10
      • 2022-11-09
      • 1970-01-01
      • 2016-12-20
      相关资源
      最近更新 更多