本文最后更新于 2026年5月11日。
simulink模型要在normal模式下运行编译
findAndCheckRelationalOperators('AlgoSim_251111');
function findAndCheckRelationalOperators(modelName)
% 查找模型中所有关系运算符(Relational Operator)模块,并检查输入类型是否一致。
% 确保模型已加载
if ~bdIsLoaded(modelName)
load_system(modelName);
end
disp(['--- 正在检查模型: ', modelName, ' 中的关系运算符 ---']);
% 1. 查找模型中所有的 Relational Operator 块
relationalBlocks = find_system(modelName, ...
'BlockType', 'RelationalOperator');
if isempty(relationalBlocks)
disp('模型中未找到 Relational Operator 块。');
return;
end
% 清理所有块路径中的不可见字符(换行、回车、空格等)
relationalBlocks = cleanBlockPaths(relationalBlocks); % 新增函数:清理路径
blocksFound = 0;
heterogeneousBlocks = {}; % 存储需要修复的块路径
% 🚨 关键步骤 1: 尝试进入编译状态
try
feval(modelName, [], [], [], 'compile');
catch ME
fprintf(2, '警告:模型编译失败。无法获取编译后的数据类型。错误: %s\n', ME.message);
return;
end
% 🚨 关键步骤 2: 遍历块,并在 finally 块中终止编译
try
for i = 1:length(relationalBlocks)
blockPath = relationalBlocks{i};
% 获取两个输入信号的端口句柄
ports = get_param(blockPath, 'PortHandles');
inputPorts = ports.Inport;
if length(inputPorts) ~= 2
warning('Simulink大师:SkipBlock', '跳过块 %s,因为它不是双输入关系运算符。', blockPath);
continue;
end
% 获取输入信号的数据类型
try
dataType1 = get_param(inputPorts(1), 'CompiledPortDataType');
dataType2 = get_param(inputPorts(2), 'CompiledPortDataType');
% 比较数据类型
if ~strcmp(dataType1, dataType2)
blocksFound = blocksFound + 1;
% 🚨 修正 1: 清理模块路径后再用于超链接
safeBlockPath = escapeSingleQuotes(blockPath); % 转义单引号(避免 MATLAB 语法错误)
% 🚨 修正 2: 使用 fprintf 和超链接语法(已清理路径)
fprintf('\n🚨 发现异构比较模块 (%d): <a href="matlab:open_system(''%s'');">打开模块</a>\n', blocksFound, safeBlockPath);
fprintf(' - 模块路径: %s\n', strrep(blockPath, newline, ' ')); % 显示时替换换行为空格
fprintf(' - 输入 1 类型: %s\n', dataType1);
fprintf(' - 输入 2 类型: %s\n', dataType2);
heterogeneousBlocks{end+1} = blockPath; % 保存原始路径用于后续修复
end
catch ME_inner
warning('Simulink大师:TypeError', '无法检查块 %s 的编译类型: %s', strrep(blockPath, newline, ' '), ME_inner.message);
end
end
finally
% 确保无论是否发生错误,编译状态都会被终止
feval(modelName, [], [], [], 'term');
end
disp('--- 检查完成 ---');
disp(['总共发现 ', num2str(blocksFound), ' 个异构类型比较模块。']);
if ~isempty(heterogeneousBlocks)
disp(' ');
disp('** 建议立即在这些模块的输入端添加 Data Type Conversion 块进行统一。**');
disp('以下模块需手动检查或修复:');
for i = 1:length(heterogeneousBlocks)
fprintf(' (%d) %s\n', i, strrep(heterogeneousBlocks{i}, newline, ' '));
end
end
end % 结束 function
%% ================================
% 辅助函数 1:清理块路径中的多余空白字符(包括换行、回车、制表符)
% ================================
function cleaned = cleanBlockPaths(blockPaths)
cleaned = cell(size(blockPaths));
for i = 1:length(blockPaths)
path = blockPaths{i};
% 去除首尾空白 + 替换中间换行、回车、制表符为空格(防止路径解析失败)
cleaned{i} = regexprep(strtrim(path), '[\n\r\t]+', ' ');
end
end
%% ================================
% 辅助函数 2:转义单引号,防止在 MATLAB 超链接中出错
% ================================
function out = escapeSingleQuotes(str)
% 将 ' 替换为 '',以便在 matlab:open_system('...') 中安全使用
out = strrep(str, '''', '''''');
end