Product ID in agent-ANYLOGIC - anylogic

I have created an agent ("Handsfree") in the agent I introduced parameter "WIRE". How do i make that parameter vary as simulation goes on so that it should automatically be set to either true or false so that i could assign the delay a specific time according to the parameter "WIRE".

When does WIRE switch between true and false values? Is it based on time? If so, you can write a simple function to switch the initial value from true to false (or vice-versa). That function could also set the delay time in another parameter, "pDelayTime". Then, you'd call that function with an event at specified or random times (whatever is needed). The delay time in your block would need to be set to "pDelayTime".

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 - Assembler should stop working for 2 hours after 10 assemblies done

The "Assembler" should stop working for 2 hours after 10 assemblies are done.
How can I achieve that?
There are so many ways to do this depending on what it means to stop working and what the implications are for the incoming parts.. but here's one option
create a resourcePool called Machine, this will be used along with the technicians:
on the "on exit" action of the assembler do this (I use 9 instead of 10 because the out.count() doesn't count until the agent is completely out, so when it counts 9, it means that you have produced 10)
if(self.out.count()==9){
machine.set_capacity(0);
create_MyDynamicEvent(2, HOUR);
}
In your dynamice event (that you have to create) you will add the following code:
machine.set_capacity(1);
A second option is to have a variable countAssembler count the number of items produced... then
on exit you write countAssembler++;
on enter delay you write the following:
if(countAssembler==10){
self.suspend(agent);
create_MyDynamicEvent(2, HOUR,agent);
}
on the dynamic event you write:
assembler.resume(agent);
Don't forget to add the parameter needed in the dynamic event:
Create a variable called countAssembler of type int. Increment this as agents pass through the assembler. Also create a variable called assemblerStopTime. You also record the assembler stop time with assemblerStopTime=time()
Place a selectOutputOut block before the and let them in if countAssembler value is less than 10. Otherwise send to a Wait block.
Now, to maintain the FIFO rule, in the first selectOutputOut condition, you need to check also if there is any agent in the wait block and if the current time - assemblerStopTime is greater than 2. If there is, you free it and send to the assembler with wait.free(0) function. And send the current agent to wait. You also need to reset the countAssembler to zero.

How can I change a signal only if a condition is met, and otherwise return the signal's old value without having the signal as an input?

I am working on converting code into simulink blocks, and this issue is coming up repeatedly in this task.
Take this pseudocode:
int number = 0; // Global variable
updateNumber()
{
if(externalCondition)
then number++; // The number is edited based on an external condition.
// else do nothing;
}
main
{
for(true)
{
updateNumber();
}
}
We have a global variable, with a default value of 0.
Then, when we call a function updateNumber that variable is changed based on an external condition.
I have to create a Simulink model for the updateNumber function, with no inputs, but with number as its output.
number should only change its value if the condition is met, else it shall keep its previous value. Just like in the pseudocode.
I suspect I can use enabled subsystems to achieve this, but I just can't see how this can be done in Simulink.
The main problem is: how can I not change the value of the number when the condition is not met? Can I have an if block that outputs "something or nothing" based on the condition?
This is what I've tried, but even when the enabled subsystem's signal is set to false the subsystem runs and sets the value to 15.
Here's another illustration of what I'm trying to achieve.
Stateflow should solve it. Just increment number everytime condition is met

In Celery tasks, do retry_backoff and retry_backoff_max affect the manual self.retry() calls?

So according to the docs, default_retry_delayspecifies the time in seconds before a retry of the task should be executed. I just want to be sure that this only affects the manually called self.retry()calls and not the autoretries triggered by Celery when the task encounters predefined exceptions.
Likewise, I want to know if retry_backoff and retry_backoff_maxonly affect the autoretries and not the manual self.retry().
Finally, what happens when all of these are set?
That answer may change depending on the version of Celery that is used. However, as far as I have checked with the source code of versions v4.3.1, v4.4.7 and v5.0.0, retry_backoff and retry_backoff_max only affect the auto-retry. If autoretry_for is not set as True (or a True value such as positive integers), then the backoff parameters is not used.
As it can be seen from the implementation, when a True value is set to autoretry_for, Celery uses retry_backoff, retry_backoff_max, and retry_jitter arguments in order to compute the countdown of the next retry, before calling .retry method. Thus, these retry_xx arguments are not directly used by the .retry method; however, they affect the value of countdown. Thus, they are only used in the auto_retry.
When the countdown is explicity defined or computed via autoretry, then the value of default_retry_delay is ignored, as it can be seen in the implementation of v5.0.0. The same is valid when eta is set. Thus, to be able to use default_retry_delay, countdown, and eta should not be set. Additionally, autoretry_for should not be set or it should be set with a False value.
Another approach to use default_retry_delay and autoretry at the same time would be to define autoretry and retry variables; but for manual retry calls, set the eta and countdown to None explicitly. One example:
#app.task(bind=True, default_retry_delay=360, autoretry_for=[ExternalApiError], max_retries=5, retry_backoff=1800, retry_backoff_max=8 * 3600, retry_jitter=False)
def my_task(self, data):
try:
... # some code here that may raise ExternalApiError
except SomeOtherError:
try:
self.retry(countdown=None, eta=None)
except self.MaxRetriesExceededError:
... # when maximum number of retries has been exceeded.
If you want to use backoff parameters with manual retry calls, it can be implemented by using the method get_exponential_backoff_interval of Celery. One example could be this:
from celery.utils.time import get_exponential_backoff_interval
#app.task(bind=True, max_retries=5)
def my_task(self, data):
try:
... # some code here that may raise ExternalApiError
except SomeOtherError:
try:
retry_backoff = True
retry_backoff_max = 5
retry_jitter = True
countdown = get_exponential_backoff_interval(
factor=retry_backoff,
retries=self.request.retries,
maximum=retry_backoff_max,
full_jitter=retry_jitter)
)
self.retry(countdown=countdown)
except self.MaxRetriesExceededError:
... # when maximum number of retries has been exceeded.

Using pstimer to run an event

I want to execute a function or a procedure or a block in regular intervals of 60seconds.
Do i have to use PS timer for that?
let this be my block
MyString = myEditor.Screen-Value.
Message MyString.
//myEditor is my Editor widget in the frame.
//My String is a string which i will use to display
I want to repeat this in each 60 seconds.. So that everytime it should display whatever I typed
inside the editor.? How can I do this with using PSTimer or without using it?
You must generate a Tick trigger block.
In this block can you write your code.
PSTimer has a property "Interval", which means interval for Tick event in miliseconds.
It has also other property "Enabled", witch starts and stopts timer.
When you run some longer code from your Tick event, schould be better switch that property "Enabled" on FALSE and on end of the trigger over on TRUE. Otherwise you can become a conflict with your code and new Tick event resp. your program will making never other, only showing runing your trigger script.