运行 Simulink 模块时出现错误,但单独运行相应的 M 文件时会成功

Posted

技术标签:

【中文标题】运行 Simulink 模块时出现错误,但单独运行相应的 M 文件时会成功【英文标题】:Get Errors when running Simulink block, but get Success when running respective M-file alone 【发布时间】:2014-09-29 09:08:40 【问题描述】:

我想使用 USRP 传输编码图像。第一步是使用 Matlab 加载图像并对其进行编码。各自的代码如下所示。

function msg = genMsg1
%#codegen
persistent msgStrSet count;
if isempty(msgStrSet)
  count = 0;
  msgStrSet = imread('cameraman.tif'); % Load the image of cameraman.tif
end
msgtemp = dec2bin(msgStrSet); % Covert msgStrSet into binary value
msg_1ine = msgtemp(count+1,:).'; % Take msgtemp line by line and tranpose it
msg = str2num(msg_1ine);  % Convert each line from string into column vector
count = mod(count+1,65536);
end

而这个M文件的运行结果是: 答案 =

 1
 0
 1
 0
 0
 0
 0
 0

由于我要使用SDRU发射器的模块,我必须将上述代码编码成一个matlab函数,如下图所示。

但是当我运行这个块时,会弹出错误窗口,如下图所示。

第一个错误是:

Subscripting into an mxArray is not supported.
Function 'MATLAB Function' (#46.311.329), line 11, column 12:
"msgtemp(count+1,:)"
Launch diagnostic report.

第二个错误是

Undefined function or variable 'msg_1ine'. The first assignment to a local variable determines its class.
Function 'MATLAB Function' (#46.391.399), line 12, column 15:
"msg_1ine"
Launch diagnostic report.

第三个错误和第四个错误是一样的。

Errors occurred during parsing of MATLAB function 'MATLAB Function'(#45) 

我认为第二、第三和第四个错误是由于第一个错误,

Subscripting into an mxArray is not supported.

我已经在互联网上搜索了一整天,但仍然找不到类似的问题。谁能告诉我到底什么是“不支持订阅 mxArray”以及如何解决?

提前感谢任何领导!

【问题讨论】:

【参考方案1】:

我不认为imread 支持代码生成,请参阅Functions and Objects Supported for C and C++ Code Generation,因此您需要将其声明为外部。我怀疑这是你在你的块中所做的,即使你没有在你的代码中提到它。问题是当一个函数被声明为外部函数时,它返回的数据类型是mxArray,请参阅Call MATLAB Functions,尤其是“使用 mxArrays”部分。

解决方法是将您的 msgStrSet 变量初始化为 0,以强制 MATLAB Coder 将变量数据类型设置为 double(或 mxArray 以外的任何类型):

function msg = genMsg1
%#codegen
coder.extrinsic('imread'); % declare imread as extrinsic
persistent msgStrSet count;
if isempty(msgStrSet)
  count = 0;
  msgStrSet = 0; % define msgStrSet as a double
  msgStrSet = imread('cameraman.tif'); % Load the image of cameraman.tif
end
msgtemp = dec2bin(msgStrSet); % Covert msgStrSet into binary value
msg_1ine = msgtemp(count+1,:).'; % Take msgtemp line by line and tranpose it
msg = str2num(msg_1ine);  % Convert each line from string into column vector
count = mod(count+1,65536);
end

【讨论】:

感谢您的回答。我忘了提及我已将 'imread' 和 'str2num' 声明为外在的。如您所说,将'msgStrSet'初始化为0后,运行结果显示“函数输出'msg'在这种情况下不能是mxArray。考虑使用已知类型预初始化输出变量。”然后我将'msg'初始化为msg = zeros(8,1),因为'msg'预期为8 * 1的矩阵,运行结果显示“变量'imread'的类不匹配。预期'double',实际'uint8 '. Block MATLAB Function (#55) While execution: State during Action ".这真的让我很困惑。有什么帮助吗? 错误是说应该是double。这是因为预初始化值zeros(8,1)doubleimread 正在返回一个 uint8 数组,因此使用 zeros(8,1,'uint8') 进行预初始化。用于预初始化的值需要与预期的大小、复杂性和类型相匹配(例如singledoubleint32 等)。 @Jinlong:见@lilbill39 的评论。初始化msg时将数据类型更改为uint8,一切都应该很好。 @lilbill39 我后来也注意到了,我添加了与您的命令具有相同功能的命令“msg = uint8(msg)”。然后运行后,弹出错误窗口,显示“变量'imread'的类不匹配。预期'double',实际'uint8'。Block MATLAB Function (#55) While execution: State during Action”。请问给我一些想法? @Jinlong:如果imread 将返回uint8 类型的变量,您可能还需要将msgStrSet 初始化为uint8【参考方案2】:

感谢您的帮助。正确的代码写法如下。

function msg = genmsg
persistent count msgStrSet;
coder.extrinsic('imread','str2num');
if isempty(msgStrSet)
    count = 0;
    msgStrSet = zeros(256,256,'uint8'); % Intialize msgStrSet as unsigned interger matrix of 256*256
    msgSet = imread('cameraman.tif'); % Load the image of cameraman.tif 
end
msgtemp = dec2bin(msgStrSet);  % Covert msgStrSet into binary value
msg_line = msgtemp(count+1,:).' % Take msgtemp line by line and tranpose it
msg = zeros(8,1,'double'); % Intialize msg as matrix of 8*1.
msg = str2num(msg_line); % Convert each line from string into column vector
count = mod(count+1,65536);
end

【讨论】:

下一次,接受给你的答案比创建你自己的答案然后接受它更好。 @am304 我已取消接受我的回答。但你的答案并不完全正确。 是,基于问题中不完整的信息。错误的原因是您的代码中有外部函数,为您提供mxArray 类型的数据。处理此类错误的正确方法是在调用函数之前将变量初始化为正确的数据类型。其余的是实现细节。

以上是关于运行 Simulink 模块时出现错误,但单独运行相应的 M 文件时会成功的主要内容,如果未能解决你的问题,请参考以下文章

在门户中运行 Azure 功能时出现内部服务器错误

运行时出现 Docker 错误:没有名为“pytz”的模块

运行 JavaFx 媒体应用程序时出现模块错误

MATLAB调用simulink时出现如下错误

在 Simulink 中单独运行子系统

尝试将 css 模块与 react 和 snowpack 一起使用时出现运行时错误