由于Matlab功能块中的可变大小数据导致的错误

时间:2013-06-17 08:47:23

标签: matlab simulink matlab-coder

我遇到了许多其他人之前遇到过的问题,所以在询问以下问题之前,我先阅读了一些讨论和参考资料:

我在Simulink中有一个Matlab功能块,它想成为一个调制器。它将[nx1]数据框作为输入,并且应该返回一个[lx1]框架,l=nl = n/K,其中K除以n 1}}。

然而,(非常简单的提取)代码

function ak = Modulator(dataFrame,dataType)

      coder.varsize('ak',length(dataFrame));

      M = 4; % this is for simplicity in this extract

      if dataType == 1 %input is a binary stream, bit mapping required
              ak = zeros(round(length(dataFrame)/log2(M)),1);
      else % input data is a stream of integer
              ak = zeros(length(dataFrame),1);
      end  

  end

因为

而无法编译
"Data 'ak' is inferred as a variable size matrix,
 while its specified type is something else."

现在,在line 2我指定它是一个可变大小的矩阵,我还使用if/else构造函数来初始化它。

为了使编译器满意,可以在数据和端口管理器中检查"Variable number of columns"的{​​{1}}复选框,但这会出现一个新错误,因为级联中的块不会接受可变数据,至少是我需要的数据,如数字滤波器。

2 个答案:

答案 0 :(得分:1)

首先,您应该看看您是否希望数据是可变大小的。根据示例代码,您希望基于dataType的大小不同。 dataType感觉就像编译时(不是运行时)变量。如果是这种情况,您应该在MATLAB功能块中将其作为参数,并确保它不可调。然后,您可以使用set_param函数设置此参数的值。如果你这样做,那么dataType的值在编译时是已知的,并且只分析了一个“if”分支,这将导致固定大小的“ak”。

如果不是这种情况,并且您希望在运行时切换dataType,则必须检查数据和端口管理器中的“变量大小”选项。在这种情况下,您的ak是可变大小的数据。此输出只能与可支持可变大小输入的其他块一起使用。

答案 1 :(得分:1)

由于两个问题,我上面给出的代码没有编译:

  • ak的初始化取决于dataType的值,它不是输入,而是在MATLAB功能块上方的掩码中定义的参数。但是,它被标记为“可调”,因此在运行时选择if / else的两个分支之一。这使得ak在运行时变成了一个可变大小的数组,因此也就是错误。

  • 要理解第二个错误,请考虑我提供的示例代码的更完整版本,这太简单了(我为此道歉)

    function ak = Modulator(dataFrame,modscheme,dataType)

    persistent constellation
    persistent M
    if isempty(constellation) || isempty(M)
        switch modcode
            case 1
                constellation = get_it_from_some_function;
                M = xx;
            case n
                ...
        end
    
    if dataType == 1 %input is a binary stream, bit mapping required
              ak = zeros(round(length(dataFrame)/log2(M)),1); % <- ERROR!!
    else % input data is a stream of integer
              ak = zeros(length(dataFrame),1);
    end      
    end
    

此代码无法编译,因为编译器看到它,M可能会在运行时更改,因此可能会更改ak的大小。实际上这绝不会发生,因为M只分配了一次,但编译器不接受它