I am having issues with passing model arguments through referenced models which contain inline parameters.
My Simulink model consists of three ModelReference blocks which refer to the same referenced model (let's call this subModel). This subModel contains dozens of parameters which should be the same in each instance and a few which I want different for each instance. Currently, within model explorer, the subModel workspace is populated using a Matlab script. If I add model arguments within model explorer and then again at the ModelReference block level I get the error:
'Model arguments can not be used in non-tunable expressions. The
expression '(acc.vRef)^2' in parameter field 'Gain' of
'subModel/Force transducer/Gain1' can not be tuned but it
refers to variables (acc (model argument))'
So the next logical step is to disable inline parameters, now I get the error:
'Model 'subModel' is referenced in Normal Mode and does not
have 'Inline parameters' enabled. Go to the Optimization > Signals and
Parameters pane of the Configuration Parameters dialog for model
'subModel' and enable 'Inline parameters''
So I re-enabled inline parameters and tried creating global tunable parameters from the 'Inline parameters configure' window. This works and I can read in arguments into the subModel this way (as a global tunable parameter), the problem here is I read in the same global arguments into all three referenced subModel instances.
The question in short is, how do I read in model arguments with inline parameters enabled? On another note, this model must also be auto coder compatible.
Related
For a simple test setup, we want to generate C code from a Simulink subsystem, which has several configuration parameters defined in its block mask. The environment shall be able to modify these parameters and the input signals, and to evaluate the output signals for several instances of the subsystem's code representation.
Expected Outcome
The code generation is expected to provide structure declarations for model, parameters, inputs, and outputs in the generated code, which can be instantiated and initialized (parameters, inputs) by the environment, and passed to the generated functions as pointers. Functions should only depend on these passed arguments.
However, even after several hours of investigation, the generator still puts the configuration parameters into one global variable, which is directly accessed by the generated functions, what makes instance-specific configuration impossible.
Attempts
Only the following Model Settings turned out as useful on the newest release R2022a:
Optimization.Default parameter behavior = Tunable
Code Generation:
Code Interface.Code Interface Packaging = Reusable function
Pass root level I/O as = Structure reference
Result
After generating code for subsystem X, declarations for all structures are available; model M, inputs U and outputs Y are passed by reference to the functions, for example:
void X_step (RT_MODEL_X_T *const X_M, ExtU_X_T *X_U, ExtY_X_T *X_Y) {
...
... X_P.X_someParam ...
}
However, the parameter structure is still accessed as a global variable X_P. Instead, the parameter structure should be also passed as a pointer either explicitly or as part of the model structure, so that it can be used as X_P->someParam.
Is there any way to achieve this behavior?
History
Years ago, in Release 2013b, this already worked smoothly:
The model structure contained a substructure called ModelData which in turn contained
the field P_X_T defaultParam. These parameters were passed to the functions as part of the model structure and thus could be made instance-specific. This worked out of the box with a few standard settings (no storage classes or other sophisticated configurations). Is this feature removed or just hidden?
I use Simulink Coder to generate code from a huge model. I use a rsim target with tunable parameters to be able to give the executable variable inputs via a parameter file.
I can specify which model parameters should be tunable (by default all parameters will be in-lined in generated code on compile time) via the code generation settings:
code generation options > optimization > signals and parameters > configure default parameter behavior
Here I can manually choose from all workspace variables the ones I want to be globally tunable:
Q: Is there a way to add a variable (given its name) to this list programmatically?
For example if a have list of 50 variables i would want to add them to the tunables list, via a MATLAB script without having to add every single one manually. Or loop over the list and set the tunable setting on each one.
I can generate a parameter struct which contains a list of tunable parameters using rsimgetrtp('model_name'). But I was not able to find a function to actually set the parameters in the first place.
I use Matlab 2015b for this, since its legacy code.
I'm porting a large Simulink model from Simulink R2010a → R2017b.
The main model is basically a glue-layer for many interwoven reference models. My objective is to generate a standalone executable out of this main model using Coder.
Parameter tunability in this context is not done via the Signals and Parameters section on the Optimization tab in the Model Configuration Parameters dialog (as is the case in stand-alone models), but rather, via constructing Simulink.Parameter objects in the base workspace, and referencing those in the respective referenced models, or in their respective model workspaces.
Now, AFAIK, in R2010a it was enough to set
new_parameter.RTWInfo.StorageClass = 'Auto';
new_parameter.RTWInfo.CustomStorageClass = 'Define';
to make the parameter non-tunable and convert it into a #define in the generated code. In R2017b, this is no longer allowed; the StorageClass must be 'Custom' if you set a non-empty CustomStorageClass:
new_parameter.CoderInfo.StorageClass = 'Custom'; % <- can't be 'Auto'
new_parameter.CoderInfo.CustomStorageClass = 'Define';
But apparently, this does not make the parameter non-tunable:
Warning: Parameter 'OutPortSampleTime' of '[...]/Rate Transition1' is non-tunable but refers to tunable variables (Simulation_compiletimeConstant (base workspace))
I can't find anything in the R2017b documentation on making parameters non-tunable, programatically; I can only find how to do it in stand-alone models via the dialog, but that's not what I want here.
Can anyone point me in the right direction?
NOTE: Back in the day, Simulink Coder was called Real-Time Workshop (well, Real-time Workshop split into Coder and several other things), hence the difference RTWInfo vs. CoderInfo. Note that RTWInfo still works in R2017b, but issues a warning and gets converted into Coderinfo automatically.
In generated code it should appear as #define, the way you specified it.
https://www.mathworks.com/help/rtw/ug/choose-a-built-in-storage-class-for-controlling-data-representation-in-the-generated-code.html
Btw, yes, it's a bit confusing, because in m-file you specify CustomStorageClass = 'Define';, in GUI you specify Storage class as Define (custom), but in documentation they say Storage Class as Defined.
I am not sure why warning about tunability shows up.
I have a problem. I have an embedded function in my simulink model which has a structure (struct) as parameter. It contains only numerical values and I generate an S-Function of the embedded function by right clicking on the block and C/C++ code --> Generate S-function.
I then have the compiled block, if I try to change some values of my struct nothing changes (the fields of my struct stay the same as when I first compiled my embedded function).
When I compiled the embedded function block I selected the parameter to be tunable. I selected the parameter to be tunable in the Model Explorer. I tried to follow this video tutorial by mathworks: http://fr.mathworks.com/videos/tunable-structure-parameters-68947.html (The video is for r2010a while I am at r2015b) It is a bit different the interface in r2015b (from the one in the video) but when I click on Configure , like the guy does in the video, nothing happens.
Could you help me please?
Thanks a lot.
Once I had also decided to reduce the number of tunable parameters by checking the 'inline parameters' checkbox and then specifying the exception variables (variable that have the permission to be tunable even when 'inline parameters' is turned on. It did not work.
In case you aim does not heavily rely on optimization, it would be better if you simply turn off 'inline parameters'.
After that, the constant blocks (i suppose you are giving the input to your s-function from constant blocks) will become tunable.
Another advice: add mex in the init function of your model callbacks. It will save you from getting weird output (usually due to uncleared/un-reset variables from previous runs).
Hope it helps!
EDIT: I decided to add screenshots of the important parts of the model, hopefully that will help clear things up.
I launch a model from a GUI, and depending on what options are selected in the GUI, some model references should change. Currently, the model reference is set up as follows:
I then define the following workspace variables in the model launch script:
Despite that, I get the following error:
According to MATLAB documentation for Simulink.Variant(), the variant condition must be:
a boolean expression that references at least one base workspace
variable or parameter (Reference)
Your error message is telling you that you are failing to define an appropriate variant condition. You define cs_Version in your callback, but it does not exist in the base workspace. You must assign cs_Version to the base workspace, using the assignin method:
assignin ( 'base' , 'cs_Version' , cs_Version );
This piece of MATLAB documentation describes a model that uses variant controls mode and version, which must be assigned to the base workspace using the command line.