AnyLogic: Change source "Arrivals defined by" at runtime - anylogic

Topic is related to Process Modeling Library, Source. Objective is to change between "Rate" and "Interarrival time" for Source during the simulation.
Switching to "Rate" during the simulation works fine. When switching to "Interarrival time" I face problems - I cannot seem to control the interarrival time with the set_rate function. I've even tried to hardcode the arrival rate (commented in code) - but that did not work either. Any suggestions?
if (comboArrival.getValueIndex()==0)
{
source.set_arrivalType(sourceRate.INTERARRIVAL_TIME);
source.set_rate(arrivalRate/60, PER_MINUTE);
//source.set_rate(1.0, PER_MINUTE);
}
else
{
source.set_arrivalType(sourceRate.RATE);
source.set_rate(arrivalRate/60/60);
}

The interarrival time is dynamic. You can simply put a variable in its field and change the variable.
Now all you need to do is change variable e.g.
variable = arrivalRate/60, PER_MINUTE;
Of course you would still need to change the arrival type to interarrival time as you are already doing before changing the variable value.

When setting up the Properties for Source - I had to make sure that the "Interarrival Time" was selected first. Switching from Interarrival time to Rate dynamically worked. When I tried to set up the Properties for Source as Rate and then switch dynamically to Interarrival time, I kept facing problems.

Related

Anylogic: Dynamically change source rate using variable/slider

I am trying to dynamically change the source Arrival rate using a variable "arrivalRate" linked to a slider (see image).
However, during the simulation the initial rate remains the same, even when I change the arrivalRate. I know that the arrivalRate variable is changing successfully (it is an int) - but this has no effect on the source rate during the simulation.
Anyone have an idea what the issue is - or how to fix it?
Whenever you see the = sign before a field, it means it's not dynamic, it is only evaluated at the start of the model or at the element creation and will not change throughout the simulation run unless you force it. In other words, the variable arrivalRate is checked only once to assign the source's arrival rate and that's it.
Now if you want to change it dynamically, in the slider's Action field, write the following:
source.set_rate( arrivalRate );

Anylogic, using different time unit

I'm having an issue configuring passing time on an Anylogic model: I would like to configure every tick of the model time to be 5 minutes at 1x.
To be clearer, all the things I did were done on the project components shown on the "Projects" tab.
Reading guides and manuals I saw that by clicking on the project root I could configure the time unit in minutes, and this allows me to run it with 1 minute per tick.
I tried to modify the Simulation options setting the "Real-time with scale" at 5, but when I run the experiment it automatically starts at 5x.
Is there any way to achieve my needing?
Thanks a lot.
P
No matter what, the best option to control this, is by doing it programmatically.
getEngine().setRealTimeMode(true); // to be sure you are not using virtual mode
getEngine().setRealTimeScale(5); // 5 would be the 5x, otherwise put a different number
For instance, you can run this at 1x when your model starts (on your "on startup" action on your main properties) and with a button, or after some time, you can change it to whatever you want.

Anylogic: How to conditionally close/open a valve

I am very new at Anylogic. I have a simple model, using the Fluid dynamics library: two tanks and a valve between them. The valve have to open at a rate, say X, only when the amount in the first tank, say tank_1, were twice of the amount of the second tank, say tank_2
Could you please help me with that?
Regards
You probably have more conditions on what to use with the valve depending on different things. But it's a bad idea to make something occur when then tank_1 is exactly 2 times larger than tank_2... Instead, create a boolean variable that tells you if the current situation is that tank_1 is over or below 2*tank_2. Let's call it "belowTank2". I will assume tank_1 is below 2*tank_2 in the beginning of the simulation. so belowTank2 is true.
Then you create an event that runs cyclically every second or even more often if you want and you use the following code:
if(belowTank2){
if(tank_1.amount()>2*tank_2.amount()){
valve.set_openRate(0.1);
belowTank2=false;
}
}else{
if(tank_1.amount()<2*tank_2.amount()){
valve.set_openRate(0.3);
belowTank2=true;
}
}
So this means that whenever tank_1 surpases 2*tank_2, it will trigger the rate change on the valve. And it will trigger again a change when it's below 2*tank_2

How can I save output from Simulink?

I'm a student learning to use MATLAB. For an assignment, I have to create a simple state machine and collect some results. I'm used to using Verilog/Modelsim, and I'd like to collect data only when the state machine's output changes, which is not necessarily every time/sample period.
Right now I have a model that looks like this:
RequestChart ----> ResponseChart ----> Unit Delay Block --> (Back to RequestChart)
| |
------------------------> Mux --> "To Workspace" Sink Block
I've tried setting the sink block to save as "Array" format, but it only saves 51 values. I've tried setting it to "Timeseries", but it saves tons of zero values.
Can someone give me some suggestions? Like I said, MATLAB is new to me, please let me know if I need to clarify my question or provide more information.
Edit: Here's a screen capture of my model:
Generally Simulink will output a sample at every integration step. If you want to only output data when a particular event occurs -- in this case only when some data changes -- then do the following,
run the output of the state machine into a Detect Change block (from the Logic and Bit Operations library)
run that signal into the trigger port of a Triggered Subsystem.
run the output of the state machine into the data port of the Triggered Subsystem.
inside the triggered subsystem, run the data signal into a To Workspace block.
Data will only be saved at time point that the trigger occurs, i.e. when your data changes.
In your Simulink window, make sure the Relative Tolerance is small so that you can generate many more points in between your start and ending time. Click on the Simulation option at the top of the window, then click on Model Configuration Parameters.
From there, change the Relative Tolerance to something small... like 1e-10. After that, try running your simulation again. You should have a lot more points in your output array that you can now save.

Qt: Preferences not restored through signal and slot mechanism

In my Text Editor application, I save the users font format selection as a preference.
Signals and slots are first set up in the constructor, and then the preferences are read as in the code below:
Constructor:
boldAction->setCheckable(true);
italicAction->setCheckable(true);
underlineAction->setCheckable(true);
fontSizeSelector->setCheckable(false);
connect(boldAction,SIGNAL(changed()),this,SLOT(bold()));
connect(italicAction,SIGNAL(triggered()),this,SLOT(italic()));
connect(underlineAction,SIGNAL(triggered()),this,SLOT(underline()));
ReadUserPreferences():
void TextEditor::readUserPreferences()
{
QSettings userPreferences(QSettings::NativeFormat,QSettings::UserScope,ORGANIZATION_TITLE,APPLICATION_TITLE);
this->boldAction->setChecked( userPreferences.value("appearance/bold").toBool() );
this->italicAction->setChecked( userPreferences.value("appearance/italic").toBool() );
this->underlineAction->setChecked( userPreferences.value("appearance/underline").toBool());
//other code.
}
Now, in the readPreferences function, when boldAction->setChecked(true);, shouldn't the text become bold because the signal and slot mechanism has already been defined? If so, then why isn't it working on my application? The bold function itself works perfectly fine.
Is there a better way of doing this than what I'm doing? Thanks for your help
There appear to be two things wrong here.
Firstly, you are connecting to the wrong signals. The changed signal does not pass a value indicating the action's checked state, and triggered is not emitted at all when setChecked is called. You need to connect to the toggled signal.
Secondly, the signal will only be emitted if the checked state has changed. So if the action is already checked and the user preference evaluates to true, nothing will happen. You probably need to take steps to ensure the appropriate default state is set before connecting the signals.