Modelica MSL CombiTimeTable - how to only set size of table at time of compilation? - modelica

I have stated to use MSL CombiTimeTable and replace my own code for a similar function. Is there a way to specify only the size of the table at time of compilation and later give the table values?
The following declaration code works
CombiTimeTable pump(
smoothness=Modelica.Blocks.Types.Smoothness.ConstantSegments,
extrapolation = Modelica.Blocks.Types.Extrapolation.HoldLastPoint,
table=[0,0; 1001,1; 1002,2; 1003,3; 1004,4; 1005,5]);
But I want to avoid giving table dummy values. The documentation of MSL for this block does not indicate that it is possible, but here is perhaps some way to do it?
https://doc.modelica.org/Modelica%203.2.3/Resources/helpMapleSim/Blocks/Sources/index.html#CombiTimeTable
I usually compile the Modelica code to FMUs and set parameters in a Python script. There is a possibility to read the CombiTimeTable information from a file, but I want to have all parameters for the FMU in the Python script, for simplicity.

It depends. You could try:
CombiTimeTable pump(
nout=1,
smoothness=Modelica.Blocks.Types.Smoothness.ConstantSegments,
extrapolation = Modelica.Blocks.Types.Extrapolation.HoldLastPoint,
table=table);
parameter Real table[6,2];
which uses an unspecified table of the right-size.
However, tools may require special settings (Dymola seems to require Advanced.IssueErrorForUnassignedParameter=false)- and/or generate default values like 0 regardless.

Would it be an option to specify the table data from file, i.e., tableFromFile=true? This way you do not need to care for the number of table rows in an explicit way as it all is handled within the Modelica external function code.

Related

How to extract an MSL model, modify the code, and use locally?

I am interested to replace my own PID-regulator models with MSL/Blocks/Continuous/LimPID. The problem is that this model restricts limitations of output signals to be parameters and thus do not allow time-varying limits, which I need to have.
Studying the code I understand that the output limitation is created by a block MSL/Blocks/Nonlinear/Limiter and I just want to change this to the block VariableLimiter.
I can imagine that you need to ensure that changes of output-limitations vary in a time-scale slower than the regulator in order to not excite unwanted behaviour of the controller. Still here is a class of problems where it would be very useful to allow this limits to vary slowly.
Thanks for the good input to my question and below a very simple example to refine my question. (The LimPID is more complicated and I come back to that).
Let us instead just modify the block Add to a local block in MyModel.
I copy the code from Modelica.Blocks.Math.Add and call it Addb in MyModel. Since here is a dependence of Interfaces.SI2SO I need to make an import before the extends-clause. This import I take from the ordinary general MSL package, instead of copying also that in to MyModel. Then I introduce a new parameter "bias" and modify the equation. The annotation may need some update as well but we do not bother with that now.
MyModel
...
block Addb "Output the sum of the two inputs"
import Modelica.Blocks.Interfaces;
extends Interfaces.SI2SO;
parameter Real k1=+1 "Gain of input signal 1";
parameter Real k2=+1 "Gain of input signal 2";
parameter Real bias=0 "Bias term";
equation
y = k1*u1 + k2*u2 + bias;
annotation (...);
end Addb;
MyModel;
This code seems to work.
My added new question is whether it is enough to look up "extends-clauses" and other references to MSL and make the proper imports since the code is now local, or here are more aspects to think of? The LimPID code is rather complex with procedures for initialization etc so I just wonder if here is more to do than just bring in a number of import-clauses?
The models in Modelica Standard Library (MSL) should only be seen as exemplary models, not covering all possible applications. MSL is write protected and it is not possible to replace the limiter block in LimPID (and add max/min input connectors). Also, it wouldn't work out if you shared your simulation model with others, expecting their MSL to work like your modified MSL.
Personally, I have my own libraries of components where MSL models are inadequate. For example, I have PID controllers with variable limits, manual/automatic functions and many more functions which are needed in my applications.
Often, I create a copy of an MSL model, place it in the same package in my own library and make the necessary modifications and additions, e.g. MyLibrary.Blocks.Continuous.PID.

How to import a header file to load constant values in Simulink? (for generable code)

I'm developing a Simulink model with many constants.
I'm trying to:
Avoid hardcoding every constant in the model and have something unreadable.
Be able to know what that 9.73288483... constant in the middle of my model stands for.
I wanted to add all my constants to a header file to have them as global constants (/including the header file everywhere) so that I could directly refer to their name instead of the value and it would also simplify my model.
Another reason for me to use a header file is that I will then generate my model in C using Simulink coder, and I really want to have that header file to have a clean generated code
I've seen people in here referring to the existence of such function.
So I've been wondering if anyone here could help me out?
Then I could also apply it to replace my functions parameters by global constants in another header file which would let me simply load a different "parameters_values.h" file when I want to change the conditions of my simulation easily.
You can specify under "file->model properties" callback functions

Anylogic: can you type a probability distribution into an edit box?

In the simulation window, before the run, I'd like to change some probability distributions (e.g. delay time) by typing, for example, "triangular(5, 20, 15)" into a specific editbox linked to a variable.
I know how to do this with static values, but I couldn't figure out how to do the same with probability distributions.
AnyLogic offers a built-in functionality for that with com.anylogic.engine.database.CodeValue.
It is originally meant that a distribution function stored as text in the internal database can be parsed to java code and executed, but it actually also works without the database and for any kind of code. It is the same idea as in Benjamin's answer, just that you do not need to add any external java library.
Use it like this:
CodeValue myCode = new CodeValue(this,"....java code to be executed");
myCode.execute();
And in your specific case, assuming you have a variable named variableA and an editbox named editbox, use the following to evaluate the expression, get a value and set it for the variable:
CodeValue myCode = new CodeValue(this,"variableA = "+editbox.getText());
myCode.execute();
Obviously, allowing the user to type any command there and running it without a check or error treatment is a bad idea, be aware of that.
This is a Java issue. You need to convert a String (your editbox content) to executable code. Not straight-forward but also not impossible, see Convert String to Code and similar posts.

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.

Why can't I tune tunable parameter "L" for block "Series RLC branch"?

I made exe file from Simulink model (I used rsim, tunable parameter on). Before this i made a standalone application with exe file that had block "constant" and everything worked great. I used "rsimgetrtp" and followed mr.Phil advices. But now when I need to make a more complex exe simulation with GUI i get warning that says some parameters can't be tunable.
"Warning: Reducing expression 'Lk' in parameter field
'Inductance' of 'sestpulsni/Lk3' to its numerical equivalent because
this field is marked not tunable. This expression resolves to tunable
variables (Lk (base workspace)). You will be unable to tune this
expression during model execution"
Is there anyway I can make it tunable? or if I can't what should i do to make a standalone GUI with exe and tunable parameters?
It sounds like you are using a block from the SimPowerSystems library.
Unfortunately, many (most? all?) of the blocks in that library take all the parameters, throw them into a large pot, mix them together, and then use the resulting Mung to perform the simulation. There is no way to use the block and avoid that problem.
The only thing you can do is implement your own block, with the required functionality, which keeps the variables individual and hence tunable.