我正在尝试使用s-function builder在Simulink中创建一个s函数,它将接受一个二维数组作为输入。在输入端口我指定尺寸:2d,rows:4,columns:4。当我尝试使用f [x] [y]访问输入端口时,它给出一个错误:“错误C2109:下标需要数组或指针输入“,表示输入端口所在的行。
如何在Simulink中使用二维数组的输入端口创建一个s函数?
相关代码:
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是数字列。
还没有找到更好的方法,但这很有效。
答案 0 :(得分:1)
我猜测S-Function构建器在mdlOutputs
中生成的代码如下所示:
real_T *y0 = (real_T *)ssGetOutputPortSignal(S, 0);
// OR
real_T *y0 = ssGetOutputPortRealSignal(S, 0);
任何一行y0
都是指向一维数组的指针,所以当你尝试使用2个下标来访问它时,就像它是一个二维数组一样,编译器会抱怨。
您可以通过将2-D索引更改为在编辑中发布的线性索引来修复它。这非常合适,事实上,当您使用2个下标索引到2-D数组时,编译器必须在幕后进行操作。
另一个选项是将ssGetInputPortSignal
(或ssGetInputPortRealSignal
)的返回值强制转换为指向指针类型的指针。
real_T **y0 = (real_T **)ssGetOutputPortSignal(S, 0);
y0[1][1] = 0;
答案 1 :(得分:0)
正如您在编辑中提到的,使用线性索引实际上是在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
*/