Search code examples
simulationanylogic

AnyLogic: How to make AGV wait/sleep separately using event


I have 10 AGVs(TransporterFleet) moving on a guided path. I created functions to return random time and duration for AGV's error. All functions and event were created in AGV, not main() because I want each AGV to have their own random error and error duration.

Problem: The AGV does move as if nothing happens, same speed, no sleep.

Expect: Each AGV should stop when model time = nextTimeToFailure and stop for nextFailureDuration seconds. When an AGV stops, sleep function should not stop other AGVs.

Current set up:

timeToFailure()

double timeToFailure = exponential(0, 60, 0, 10);
return timeToFailure;

failureDuration()

double duration = exponential(0, 15, 0, 3);
return duration;

Then I have an event to trigger on condition: time() == nextTimeToFailure

if(nextTimeToFailure == 0){
System.out.println("nextFailureDuration is 0 ");
    nextTimeToFailure = time() + timeToFailure();
    nextFailureDuration = failureDuration();    
}

setSpeed(reducedSpeed()); //reduceSpeed() function return 0
rectangle.setFillColor(red);
try {
    Thread.sleep((long)nextFailureDuration);
} catch(InterruptedException e) {
    System.out.println("got interrupted!");
}

nextTimeToFailure = Double.NaN;
nextFailureDuration = Double.NaN;

nextTimeToFailure = time() + timeToFailure();
nextFailureDuration = failureDuration();
    
rectangle.setFillColor(lime);

Solution

  • NEVER use condition-based events at all, they work differently than you think (fairly advanced concepts under the hood).

    Instead, simply setup a statechart or Dynamic Event to regularly trigger every timeToFailure.

    For Dynamic Event:

    1. drag it into your AGV agent type, name it myDE
    2. on startup code of the AGV, call create_myDE(timeToFailure(), MINUTE); (or whatever time unit timeToFailure() returns in)
    3. in the DE, write your usual code and compute the nextTimeToFailure
    4. at the end of the DE code, make it re-call itself using create_myDE(nextTimeToFailure, MINUTE);`

    This will recreate failure events again and again, and they will trigger 100% "on time"

    However, the state-chart approach is a more visual and elegant way, check the example models, there are tons that show how to use it for failures.

    Or use the "Downtime" block