Cannot change the dimensions of run-time parameter in Model block - matlab

I have a Simulink model with a Model block I am using to avoid duplication of some functionality.
When I try and run the parent model, I get the following errors:
Cannot change the dimensions of run-time parameter 'Gain' in
'TranslationChannel/First-Order Filter1/Model/Continuous/A' from
[1x1] to [0x0] while model is executing
Invalid setting in
'TranslationChannel/Second-Order Filter/Model/Continuous/A*x/A11' for
parameter 'Gain'
Error evaluating parameter 'Gain' in
'TranslationChannel/Second-Order Filter/Model/Continuous/A*x/A11'
Reference to non-existent field 'A11'.
Invalid setting in
'TranslationChannel/Tilt/Model/Continuous/A*x/A11' for parameter
'Gain'
Error evaluating parameter 'Gain' in
'TranslationChannel/Tilt/Model/Continuous/A*x/A11'
Reference to
non-existent field 'A11'.
The sub-model is below:
The block the error refers to is First Order Fliter 1, the parameters are which are:
How do I resolve this error, or, is there a better way of calling the same series of blocks multiple times in a model?
The parent model is below:
EDIT:
After my discussion with Ander, I tried connecting a step source directly to the model block to eliminated any possibility of a null signal and got the same error, suggesting the problem is due to calling the second model. If anyone can assist further, that would be great.
EDIT 2: I have confirmed that data is being passed into the model. Removing the filters from the sub-model makes it work fine. The error occurs in the masked portion of the filters.

I have resolved this my using a library instead of a model, and putting the filter blocks into a subsystem inside the library that I then drag to my main model.
This allows me to tune the parameters once and have it change all the blocks at once.

Related

How to generate code for Simulink model which contains an export-function submodel?

I'm using matlab 2019b to build this Simulink model: A function call generator calls an export-fuction submodel.
An export-function model is a model with function call inputs.
I can generate code for the submodel using embedded coder, as well as run simulation of the top model. But generating code for the top model gives this error message:
Model 'main' contains a reference model 'main/Model' that is set up as a multi-instance export-function, but model 'main' does not follow export-function rules.
where 'main' is the top model name.
The export-function model document https://www.mathworks.com/help/simulink/ug/export-function-models.html writes:
For function-call Model blocks, Periodic sample time constraint for the referenced model set to Ensure sample time independent
Following this rule throws another errors. If the top model's periodic sample time constraint is changed, the error is:
This model will not inherit a sample time because the block 'main/Model' disallows it from doing so. If this model does not need to inherit a sample time, change the "Periodic sample time constraint" to something other than "Ensure sample time independent" on the Solver tab of the Configuration Parameters dialog.
And if the submodel's periodic sample time constraint is changed, the error is:
The current diagnostic settings for model 'instance' are not valid because the model contains root-level Inport block 'instance/f' that outputs a function-call signal. See errors reported below for details.
Caused by:
In the export-function model 'instance', the parameter 'Periodic sample time constraint' in 'Configuration Parameters' > 'Solver' > 'Tasking and sample time options' must be set to 'Unconstrained'.
Suggested Actions
Set the 'Periodic sample time constraint' to 'Unconstrained' in 'instance'.
How can I generate code for the top model?

Get the handle of a block calling an Interpreted Matlab Function

I am using Simulink to model a waste recycling plant out of a number of masked blocks that I created, representing sorting steps, buffers etc. Each module (that is, a masked block) has a failure probability, modeled using Discrete Events. If a failure event occurs, a triggered subsystem calls an Interpreted Matlab Function ("outside" of simulink). This function is supposed to set a parameter status of the masked block representing the module that failed as well as the upstream modules' status to 0 (because obviously, everything upstream has to stop as well or the material will just pile up).
`set_param(gcb, 'status', num2str(status));
PortConnectivity = get_param(gcb,'PortConnectivity');
sources = PortConnectivity.SrcBlock;`
Basically, this will be looped until I reach a block with no own Source Block.
This all works quite well, except for one problem: The gcb command gives me the block path to the last block I highlighted manually, and not to the block that called the Interpreted Matlab function. Is there any way to get the calling block's handle (which I would use with it's Parents parameter to access the Mask's status)? (A similar question has been asked here, with no results...)
I hope you get my problem - I'll be happy to elaborate if anything's unclear; I am not claiming to be a Simulink expert, so sorry for maybe using wrong terminology.
Ok, for everyone stumbling upon this:
For the mask that contains the caller of the Matlab Interpreted Function, in the mask editor I define a parameter 'this_block' (turn visibility off), that I initialize in the Initialisation pane using
parent = get_param(gcb,'Parent');
set_param(gcb, 'this_block','Parent')
Since this masked block (responsible for modelling the failure and its upstream communication) is itself used in another masked block also present in the library (responsible for modeling the module's behaviour), I also had to check "Allow library blocks to modify it's contents" in the mask editor Inititlization pane of the parent's mask. The parameter 'this_block' is then handed over as one of the input arguments of the called function (in my case, status_communication(u, this_block)).

Why does MATLAB give a "class has no property" error when running but not debugging?

I have a script that performs a bunch of experiments on different datasets, below is part of the logic to determine whether a dataset needs to be loaded. Basically we load the dataset if there is none already loaded, or if the currently loaded one doesn't match the one we need by name.
This example crashes with the error The class dataset has no property or method named 'name' at the if statement (the class does in fact have this property):
if(~exist('dataset','var')||~strcmp(dataset.name,datasets{datai}.id))
loaded=load(datasets{datai}.filename);
dataset=loaded.dataset;
end
If I debug and stop at the line, I can access dataset.name in the debugger without performing any further actions. I don't think the reason is the dataset object not existing. In the loop I ran, the first dataset was correctly loaded, but the second one (where the name check comes into play) wasn't.
This rewriting works:
if(~exist('dataset','var')||~strcmp(nom,datasets{datai}.id))
loaded=load(datasets{datai}.filename);
dataset=loaded.dataset;
nom=dataset.name;
end
Why was I able to access dataset.name in the debugger, and why does the rewriting fix the issue?

Set Filename of ToFile Block after Model has Finished

I have a series of ToFile blocks in my Simulink model that each have a unique filename (e.g. "Pulse.mat". I want to store the results of my simulation in timestamped folders based roughly on when I hit the run button / use the sim command.
My solution was to write two scripts, one called during the InitFcn callback and one for the StopFcn/CloseFcn callback (and PreSaveFcn callback).
The InitFcn callback would find all ToFile blocks and change the filename from "Pulse.mat" to something like "../runs//Pulse.mat", and the StopFcn/CloseFcn/PreSaveFcn to revert them to their original ".mat" names. This worked on my small test model, however when I attempted to integrate it into my actual model I receive the following error:
Error evaluating 'StopFcn' callback of block_diagram '<model_name>'.
Caused by:
Cannot change parameter 'Filename' of '<ToFile Block>' while simulation is running. The block was made virtual as it was optimized for simulation
From my research I discovered that the StopFcn actually executes before the simulation is "done" (for whatever reason), but why did it work in my initial test model? Do my ToFile blocks in my actual model have some property set that causes this error to occur?
The block has been virtualised in your larger model; which seems to be changing the execution point. One option might be to untick 'Block Reduction' in the 'Optimisation' pane of the model configuration parameters dialogue.
Alternatively, there might be another approach that you could try -
Setting the model properties 'StartFcn' to something like :
evalin('base','resultTimTag = datestr(clock, ''yyyymmdd_HHhMM'');')
and setting the model properties 'StopFcn' to :
targetDir = evalin('base','resultTimTag');
mkdir(targetDir);
outputs = dir('*.mat');
for i=1:length(outputs)
movefile(outputs(i).name,targetDir);
end
evalin('base','clear resultTimeTag');
It's possibly a little more brute-force than your approach, but seems to work quite nicely...

SIMULINK - Ignoring Scope Block when using Embedded Code Generation

I have got some inputs in my model that are passed through the environment controller block. In this way, I can use test inputs (fixed or configurable parameters) in simulation and the top-level input ports for Embedded Code Generation. However, I need to check the outputs of my model (after simulation) on a scope.
I was hoping that there is way I can use something similar to environment controller block in order to ignore scope blocks when I generate code. In this way, I can still view my outputs but not worry about any unnecessary blocks getting error-flagged during code generation checking. Is there any way to do it or is it "Automatically" ignored when generating code. Has anyone come across this?
KR,