- サンプル
- ブロック置き換え
- Fromブロックの追加・接続
model = 'test'
open_system(model);
blockName = 'NormalTimeReception'
add_line(model, [blockName,'/1'], [SwitchBlock,'/2'])
% Simulink モデル内の特定ブロックを Inport ブロックに置換するスクリプト
% MATLAB 2018b で動作確認
% ユーザーからモデル名を入力してもらう
function replaceBlock(modelName)
load_system(modelName);
% 置換対象の条件設定
constantName = 'c_False'; % Constantブロックのデータ
unitDelayInitial = 'c_True'; % UnitDelayブロックの初期データ
% 置換する Inport ブロックの詳細設定
inportBaseName = 'NormalTimeReception'; % Inportブロック名の基本文字列
inportDataType = 'Inherit: auto'; % Inportのデータ型
inportWidth = 30; % Inportブロックの幅
inportHeight = 14; % Inportブロックの高さ
% 変更があったサブシステムを記録するリスト
modifiedSubsystems = {};
% モデル内のすべてのサブシステムを取得
subsystems = find_system(modelName, 'BlockType', 'SubSystem');
for i = 1:length(subsystems)
currentSubsystem = subsystems{i};
% サブシステム直下の Constant ブロックを取得
constantBlocks = find_system(currentSubsystem, 'SearchDepth', 1, 'BlockType', 'Constant');
for j = 1:length(constantBlocks)
constantBlock = constantBlocks{j};
% Constant ブロックの値が c_False か確認
if strcmp(get_param(constantBlock, 'Value'), constantName)
% Constant ブロックの出力ポートを取得し、接続先(Line)を確認
constPorts = get_param(constantBlock, 'PortHandles');
outLine = get_param(constPorts.Outport, 'Line');
if outLine ~= -1
dstBlocks = get_param(outLine, 'DstBlockHandle');
if ~isempty(dstBlocks) && dstBlocks ~= -1
for k = 1:length(dstBlocks)
% 接続先ブロックが UnitDelay であるかチェック
if strcmp(get_param(dstBlocks(k), 'BlockType'), 'UnitDelay')
% UnitDelay の初期条件が c_True なら置換対象とする
if strcmp(get_param(dstBlocks(k), 'InitialCondition'), unitDelayInitial)
% UnitDelay ブロックの出力接続先情報を取得(削除前に記録)
unitDelayPorts = get_param(dstBlocks(k), 'PortHandles');
unitDelayOutLine = get_param(unitDelayPorts.Outport, 'Line');
if unitDelayOutLine ~= -1
unitDelayDstBlocks = get_param(unitDelayOutLine, 'DstBlockHandle');
unitDelayDstPorts = get_param(unitDelayOutLine, 'DstPortHandle');
else
unitDelayDstBlocks = [];
unitDelayDstPorts = [];
end
% 基準位置は Constant ブロックの位置を取得
pos = get_param(constantBlock, 'Position');
% 新規 Inport ブロック用の位置を再設定(幅30, 高さ14)
newPos = [ pos(1), pos(2), pos(1)+inportWidth, pos(2)+inportHeight ];
% 既存の接続ラインの削除
delete_line(outLine);
if unitDelayOutLine ~= -1
delete_line(unitDelayOutLine);
end
% 対象ブロック(Constant, UnitDelay)の削除
delete_block(constantBlock);
delete_block(dstBlocks(k));
% サブシステム内の既存 Inport ブロック数を取得し,
% 新規ブロックのポート番号を(既存数+1)とする
existingInports = find_system(currentSubsystem, 'SearchDepth', 1, 'BlockType', 'Inport');
newPortNumber = length(existingInports) + 1;
% サブシステム内の Inport ブロック名は "NormalTimeReception" とする
newInportName = inportBaseName;
newInportPath = [currentSubsystem, '/', newInportName];
add_block('simulink/Sources/In1', newInportPath, ...
'Position', newPos, ...
'Port', num2str(newPortNumber), ...
'OutDataTypeStr', inportDataType);
% 元の接続先へ新 Inport ブロックからの接続を再設定
if ~isempty(unitDelayDstBlocks) && unitDelayDstBlocks ~= -1
for m = 1:length(unitDelayDstBlocks)
% 接続先のブロック名とポート番号を取得し接続
destBlockName = get_param(unitDelayDstBlocks(m), 'Name');
destPortNum = num2str(get_param(unitDelayDstPorts(m), 'PortNumber'));
try
add_line(currentSubsystem, [newInportName, '/1'], ...
[destBlockName, '/2'], 'autorouting', 'on');
catch
warning('接続先の端子が既に使用されています: %s', destBlockName);
end
end
end
% 変更があったサブシステムを記録
if ~ismember(currentSubsystem, modifiedSubsystems)
modifiedSubsystems{end+1} = currentSubsystem;
end
end
end
end
end
end
end
end
end
% 変更があったサブシステムのみ背景色を設定 (状態:未適応)※下記3行のコメントアウトを外すことで色付け適応
% for i = 1:length(modifiedSubsystems)
% set_param(modifiedSubsystems{i}, 'BackgroundColor', 'cyan');
% end
% 変更内容を保存しシステムを閉じる (状態:処理完了後保村せず開く)
open_system(modelName);
% save_system(modelName);
% close_system(modelName);
end
使い方👇
上記コードをコピーし、関数名称で保存(.mファイル)し、下記コマンドを実行
<関数名(ファイル名も同名)>('<モデルファイル名(拡張子なし)>')
例: replaceBlock('ForGesInfoCalcFunc_Calc')
function add_blocks_for_inputs(modelName)
% Simulink モデルを開く
load_system(modelName);
% モデルのトップレベルのシステム名を取得
topLevel = bdroot(modelName);
% サブシステムを検索
subsystems = find_system(modelName, 'BlockType', 'SubSystem');
% 設定
fromTag = 'NormalTimeReception'; % Fromブロックのタグ名
fromBlockWidth = 175; % Fromブロックの幅
fromBlockHeight = 16; % Fromブロックの高さ
offsetX = -300; % From ブロックの配置オフセット(左側)
offsetY = 120; % From ブロックの配置オフセット(下側)
% 未接続ポートを格納するリスト
unconnected_ports = {};
% 各サブシステムを処理
for i = 1:length(subsystems)
subSys = subsystems{i};
% サブシステムの入力ポートハンドルを取得
inportHandles = get_param(subSys, 'PortHandles');
if isfield(inportHandles, 'Inport')
for j = 1:length(inportHandles.Inport)
portHandle = inportHandles.Inport(j);
% 接続状態を取得
lineHandle = get_param(portHandle, 'Line');
% 未接続のポートを検出
if lineHandle == -1
% サブシステムの親階層(外部)を取得
parentSystem = get_param(subSys, 'Parent');
if isempty(parentSystem)
parentSystem = topLevel;
end
% Fromブロックの一意な名前を生成
existingFromBlocks = find_system(parentSystem, 'SearchDepth', 1, 'BlockType', 'From');
fromBlockName = sprintf('From_%d', length(existingFromBlocks) + 1);
% ポートの位置を取得
pos = get_param(subSys, 'Position');
y = pos(2) + (j - 1) * 40 + offsetY; % 位置を調整
% Fromブロックを追加(外部に作成)
fromBlockPath = sprintf('%s/%s', parentSystem, fromBlockName);
if isempty(find_system(parentSystem, 'SearchDepth', 1, 'Name', fromBlockName))
add_block('simulink/Signal Routing/From', ...
fromBlockPath, ...
'Position', [pos(1) + offsetX, y - fromBlockHeight/2, pos(1) + offsetX + fromBlockWidth, y + fromBlockHeight/2], ...
'GotoTag', fromTag, ...
'ShowName', 'off'); % ブロック名を非表示
end
% From ブロックをサブシステムの Inport に接続
fromPortHandle = get_param(fromBlockPath, 'PortHandles');
add_line(parentSystem, fromPortHandle.Outport, portHandle, 'autorouting', 'on');
% ログ出力
unconnected_ports{end+1} = sprintf('Added From block for: %s (Port %d)', subSys, j);
end
end
end
end
% 結果を出力
if isempty(unconnected_ports)
fprintf('No unconnected input ports found.\n');
else
fprintf('From blocks added for the following unconnected input ports:\n');
for k = 1:length(unconnected_ports)
fprintf('%s\n', unconnected_ports{k});
end
end
% 変更内容を保存しシステムを閉じる (状態:処理完了後保村せず開く)
open_system(modelName);
% save_system(modelName);
% close_system(modelName);
end
使い方👇
上記コードをコピーし、関数名称で保存(.mファイル)し、下記コマンドを実行
<関数名(ファイル名も同名)>('<モデルファイル名(拡張子なし)>')
例: add_blocks_for_inputs('ForGesInfoCalcFunc_Calc')