How to programmatically reference a parameter value in a masked subsystem reference?

Hello,
I'm working on a large project that uses hundreds of masked subsystem references. To reduce the visual complexity of the subsystem references, I'm trying to write a script that programmatically finds all constant blocks in a model and if any constant block connects to two or more destinations, delete the extra lines and add copies of the constant block next to the destination blocks.
The problem I'm encountering arises when I try to copy a constant block who's value is the name of a parameter in the subsystem mask. The relevant bit of code is:
name = get_param(constantBlock, 'Name');
value = get_param(constantBlock, 'Value');
connectedPorts = get_param(constantBlock, 'PortConnectivity');
% If there are more than 1 destination block, copy the constant block
for i = 2:length(connectedPorts.DstBlock)
newBlock = add_block('simulink/Sources/Constant', [modelName, '/' name], 'MakeNameUnique', 'on');
set_param(newBlock, 'Value', value);
% <additional code for calculating and setting the position of the new block and drawing new lines>
% ...
end
This code works nominally, but when it is passed a constant block that takes a mask parameter as value, the following error is produced:
Invalid setting in 'My_Model/MyConstant' for parameter 'Value'.
Suppose that the parameter in question is named 'myParam'. When dropping a breakpoint at the line producing the error, I noticed that I can manually assign the value of the constant to 'myParam1', 'myParam2', etc. without issue. The problem only arises when I try to assign the value to 'myParam', which is a parameter in the subsystem's mask.
So far, I have tried to assign the value of myParam programmatically, i.e.
assignin('base', 'MyParam', 42);
assignin('caller', 'MyParam', 42);
and to wrap the parameter name in extra quotes
set_param(newBlock, 'Value', ['''' value '''']);
But neither method helped.
I understand that I can programmatically remove the parameter from the mask, set the value of the constant block and then add the parameter back into the mask, but I wonder if there is no better way of solving the issue?
Thankful for any assistance.
// Viktor

댓글 수: 3

Update
Temporarily removing and adding a parameter to the mask is not trivial either, the following code should in theory accomplish the task
function SetBlockParameterToMaskedVariable(modelName, block, blockParam, varName)
% Assumes the model is a loaded subsystem, block belongs to the subsystem and has a parameter blockParam.
maskObj = Simulink.Mask.get(modelName);
% If there is no mask or the mask does not have the parameter, just set the block parameter
if isempty(maskObj) || isempty({maskObj.getParameter(varName).Name})
set_param(block, blockParam, varName);
return;
end
% Copy the mask parameter settings and remove the parameter from the mask
maskParameter = maskObj.getParameter(varName);
maskParameterCopy = GetMaskParamCopy(maskParameter);
maskObj.removeParameter(varName);
% Set the block parameter to reference the mask variable
set_param(block, blockParam, varName);
% Re-add the mask parameter to the mask
maskObj.addParameter('Type', maskParameterCopy.Type, ...
'Name', maskParameterCopy.Name, ...
'Prompt', maskParameterCopy.Prompt, ...
'Value', maskParameterCopy.Value, ...
'Evaluate', maskParameterCopy.Evaluate, ...
'Tunable', maskParameterCopy.Tunable);
end
function paramCopy = GetMaskParamCopy(maskParameter)
% Returns a struct with the properties of the mask parameter
paramCopy = struct();
paramCopy.Type = maskParameter.Type;
paramCopy.Name = maskParameter.Name;
paramCopy.Prompt = maskParameter.Prompt;
paramCopy.Value = maskParameter.Value;
paramCopy.Evaluate = maskParameter.Evaluate;
paramCopy.Tunable = maskParameter.Tunable;
end
However, the exact same error is encountered despite the mask parameter having been removed. The only way I could make this work was by saving the model just before set_param, closing it and then loading it again. I was then able to set the block parameter. This is not a viable solution though, first because it is slow, and second because it requires reinitialization of all model references that were invalidated when we closed the model.
My assumption is that the mask workspace is only evaluated when loading the model, and thus it tries to infer the value of 'MyParam' even though it has been removed from the model's mask.
-> Is there any way to make matlab re-evaluate the mask workspace without closing and loading the model?
Hi Viktor,
I understand that the issue is that even after removing a mask parameter, Simulink still raises an Invalid setting for parameter 'Value' error because the mask workspace is only refreshed when the model is reloaded or updated. This explains why closing and reopening the model temporarily solves the problem.
While closing and reopening the model forces a refresh, a lighter workaround is to trigger re-evaluation programmatically using:
maskObj = Simulink.Mask.get(modelName);
maskObj.refresh;
For broader compatibility across versions:
set_param(modelName, 'SimulationCommand', 'update');
These approaches prompt Simulink to reprocess the mask workspace without requiring a full reload.
Alternatively, cloning the original Constant block using add_block with the source block path preserves the reference to the mask parameter, avoiding the need for re-evaluation altogether.
Hope this solves your query!
Some useful documentation:
Directly copying the old block works! Thank you!
For future readers finding this thread, I used:
newBlock = add_block(oldBlock, [modelName, '/' name], 'MakeNameUnique', 'on');

댓글을 달려면 로그인하십시오.

답변 (0개)

카테고리

도움말 센터File Exchange에서 Programmatic Model Editing에 대해 자세히 알아보기

제품

릴리스

R2024b

질문:

2025년 9월 4일

댓글:

2025년 9월 11일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by