I am trying to change the simulation settings(startTime,stopTime,Interval) for an experiment based on the size of the external file that is presented to the model.
Experiment annotation allows one to set these simulation settings like this,
annotation(Experiment(startTime=0,stopTime=10,Interval=500));
Now I am trying to set these values based on a parameter declared in the same model. This parameter basically scans the external file to find its size. Modelica doesn't recognize the following declaration of the same annotation?
model ExperimentAnnotation
parameter Integer start = 0;
parameter Integer stop = 10;
parameter Integer size = 100;
equation
annotation(Experiment(startTime=start,stopTime=stop,Interval=size));
end ExperimentAnnotation;
Is there a work around for this? Kindly advise.
Thanks.
Using non-literal values for the startTime-annotation etc is not legal Modelica - according to section 18.4; and not supported in Dymola.
As I understand it the parameter doesn't have a literal value in the model, but the parameter-value is based on reading some file.
In Dymola you could use "Add Command" to add a script-command that reads the external file and then calls simulateModel with the correct values.
Related
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 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.
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.
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 am using Behavior Search to calibrate my NetLogo model for 20 different hospital units. I am using global variables to set the min and max for several sliders in my model, but I think this is causing an error in Behavior Search when I attempt to load the parameter values from the model. However, I don't want to manually enter these parameter ranges manually each time I use Behavior Search.
Is there a way to get around this error? Is there a way to set the min and max for a specific slider to a constant, rather than using global variables?
Thanks for your help!
BehaviorSearch developer here -- if I'm understanding your question correctly, your NetLogo model has a slider which has a min/max constraint that is not set to a constant, but is instead set to a global variable (in the slider settings, accessed from the NetLogo interface).
When I choose such a model using the BehaviorSearch GUI, and then click the "Load parameter ranges from model interface" button, then I get the value of 0 for that constraint. (I don't see any error message -- just the value 0 (if you're getting an error message instead, then I may not be understanding your situation correctly, and perhaps you could post exactly what error message you're seeing?)
This will be true even if you are setting the slider min/max to a global value in the special STARTUP procedure (see: http://ccl.northwestern.edu/netlogo/docs/dict/startup.html), because STARTUP is only run when a model loads in the NetLogo GUI, and not when a model is loaded in headless NetLogo.
Thus, unfortunately, I think the answer to your question is: "no, there isn't a way to get BehaviorSearch to load the parameter ranges from global variables within the model".
Some possible work-arounds:
BehaviorSearch is open-source -- some changes could be made to it -- i.e., maybe adding in a call to "startup" whenever BehaviorSearch GUI loads the parameter ranges would be sufficient for you.
If you're only doing a few searches, I don't see why manually editing the parameter ranges would be particularly onerous. However, if you're generating a lot of different searches with this model, then I can see how it might be an issue. The .bsearch files are just XML text files, so you might consider generating them without the BehaviorSearch GUI, e.g. using a scripting language.