Simulink code generation: set tunable parameters programmatically - matlab

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.

Related

Subsystem Parameters Always Mapped to Global Variables in Code Generated by Matlab/Simulink Embedded Coder

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?

modify model's parameters in dymola's script file

I am trying to use a .mos file in Dymola to do multiple simulations, here is an example from claytex's blog:
openModel("C:/Dymola/Testing/Test1.mo")
translateModel ("Test1");
for i in 1:10 loop
a=i;
simulate();
system("copy dsres.mat results"+String(i) +".mat");
end for;
It seems when I translate a model in the script file, I could modify the model's parameters again, which is different when I use Dymola's GUI. In Dymola's GUI, if I try to modify the parameter after I translate the model, I have to re-translate the model. My question is:
In Dymola's script file, when I modify the parameter, how does Dymola deal with it?
The above comment by "user2024223" is correct, but I think "variable browser" is not stressed enough and some more explanation could help:
When changing the model's parameters after translation, make sure you are not using the model editing (either "Graphical" or "Text"-Ribbon), because this will change the model's code and therefore (usually) force re-translation. The same is true for the "Model View" in the "Simulation" Ribbon.
The code will not be changed if you use the "Variable Browser" in the "Simulation"-Ribbon. An alternative (which actually does the same) is typing the parameter value in the "Commands"-line. E.g. this could be J1.J=5 for the CoupledClutches example. Both of the variants in the paragraph should behave similarly to the script.
Dymola deals with parameter changes after translation by modifying the dsin.txt file.
Some/many parameters have been evaluated and cannot be changed in this way - these variables are not editable in the Variable Browser.
You will get a warning if you try to change non-editable variables in a script.
Note: You should in most cases not have to deal with re-translating the model even after modifying the editable parameters of that model in the GUI. Just simulate the model again - hopefully it does not need re-translation.

How to programmatically configure the tunability of model parameters?

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.

Using model arguments for a referenced model with inline parameters

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.

Doing Integration Testing on Simulink Models

Say, I've UNITs 1,2,3,4 ( either as Model reference or Subsystem) for which I've units tests ready using matlab.unittest.TestCase framework.
What could be the easiest way to write integration test fro entire system ?
I need some way to set Global_Inputx ( x = 1,2,3 ) and verify Global_Outy ( y =1,2 ) in easiest possible way (may be utilizing the Unit tests) ?
I can use Matlab 14a
PS: I've already gone through this but it didn't help.
I think the question of integration testing in Simulink is a complex one that may involve formal methods like code and coverage analysis of the dynamic system under test, automatic test generation e.t.c. If you haven't already, you may want to check out "Verification, Validation and Test" section of the MathWorks product line up: http://www.mathworks.com/products/?s_tid=gn_ps.
However to answer your specific question of how you would set the global input and verify global output in your test:
Depending on where your global input data that feeds the inport blocks resides (MATLAB base workspace, model workspace, e.t.c), do you think you could set the external input of the model to that data. For example:
set_param(, 'ExternalInput', )
This could be defined in your test class setup, test method setup or in the test depending on when the data is available and where defining it is appropriate. The data could also be passed in directly to the sim() command. Parameterized testing (http://www.mathworks.com/help/matlab/matlab_prog/create-basic-parameterized-test.html) is an option to consider if you want to test the system with different sets of inputs. The external input value becomes the parameter in this context.
If you have your model set up for output logging, then once the simulation is done, you would get the logged outputs, which you could then compare against a baseline.
Does that help? or am I way off the base here. If you can add more details, I can try again.