【问题标题】:Error due to variable size data in Matlab function block由于 Matlab 功能块中的可变大小数据而导致的错误
【发布时间】:2013-06-17 08:47:23
【问题描述】:

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

我在 Simulink 中有一个 Matlab 功能块,它想成为一个调制器。它以[nx1] 数据帧作为输入,并应返回一个[lx1] 帧,其中l=nl = n/K,对于某些K,除以n

但是,代码(非常简单的摘录)

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 构造函数来初始化它。

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

【问题讨论】:

  • 您是否尝试过使用coder.varsize 中的dims-选项?
  • 是的,我做了,但显然放置或不放置 coder.varsize 命令没有任何区别..

标签: matlab simulink matlab-coder


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回复。我的情况是第一个,即数组的大小是在编译时确定的。所以,首先我将 dataType 设置为 Tunable,并且我已经解决了这个问题。但这确实是不够的。那么,我应该在哪里放置 set_param 命令?我不能把它放在功能块中,因为我得到“set_param”与代码生成不兼容,如果我把它放在块上方的掩码中,同样适用..
  • 您的 set_param 应该在您的模型代码之外。在运行模型之前,您必须从 MATLAB 命令行调用它。
  • 我找到了问题的真正原因。很抱歉,因为我提供的示例代码过于简化。感谢您的关注。我接受你的回答,因为你说的都是正确的。只是,这里没有必要使用调用 set_param 的技巧。我不能给你+1,因为我是新人,对不起!最美好的祝愿
【解决方案2】:

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

  • 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 只分配了一次,但编译器不接受它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多