Manually releasing a seized resource from an agent? - anylogic

I have a fairly straightforward process:
batch-seize-delay process
Order agent types are batched into a Batch agent type, then a third agent type is seized as a Resource for that Batch. On seize, a message is sent to the Resource agent's statechart for some actions to be taken. However, if a certain condition is met upon receipt of the message, then the Batch agent needs to release the Resource agent and seize a different one so the process can be completed. I've written code in the Resource agent that adds the rejected Batch agent into the collection shown above when it's rejected (rejectionsCollection.add(Batch)). Then, the Batch agent is reinserted at the second source block using an injection call and I've coded the 'New agent' option with rejectionsCollection.get(0). But, I have to also call remove() in the seize and delay blocks otherwise I get flowchart errors (same agent in two blocks at the same time).
When I use seize.remove(batch) as an action to take if the condition is met, but the problem is that the resource agent doesn't get released. I've also set the seize advanced option 'Canceled units' equal to 'go to release' and set 'Release for canceled units' as my release block, but this doesn't work. The third agent remains seized and eventually I run out of Resource agents (which shouldn't happen).
I've also tried copying it into a NewBatch agent Batch newBatch = batch; but it still gives a flowchart error. I've also tried using clone() but I haven't figured out the right syntax (I'm not the most experienced java programmer). I get error messages that say 'cannot convert from Object to Batch'. Not sure if it's relevant but the Batch agent has two collections within it as well.
My next thought was that I could manually release the Resource agent but the help file says that even though a seized resource is publicly accessible, users shouldn't do it. What else could I try?
Sorry for the wall of text but any ideas are appreciated!

You do not manually release resources. The setup is agent-centric, so you must tell the agent to let go of the resource. This is done by making the agent "move" to the release block.
In your case, you could make the delay duration conditional: if the agent has met your condition, the delay time should be 0, else the normal delay time.
Use this notation: agent.condition == true ? 0. : normalDelayTime
You could also use a "Split" element after "Seize" and bypass the "delay" object altogether for your special agents.
Many options, but remember to thing agent-centric :)

Related

Access to agents that grouped using Batch block

By Batch block I group together a certain amount of agents, They get a new agent identity.
I defined a temporary batch permanent batch = false.
How I can access to the agents that are 'inside' the new agent?
I tried to search in which population he keeps the original agents, without success.
you can access through agent.contents()
Beware though, that you need to use unbatch if you want to use those agents for anything at all... i would say it's good practice to take these batched agents as read_only otherwise unpredictable things might happen

Trasporters are jammed at a specific location in AnyLogic

I hope you are having a great day.
Recently, I tried to build an AnyLogic model with free-space transporters, but I encountered an unexpected situation as shown below.
I thought that there is no logical reason why all the transporters are jammed in a specific position. Is there any solution or possible reason for this situation? I have attached my model for your information.
Thank you for reading this question.
The problem with the traffic jam appears to be due to the fact that there are two few attractors available for the transporters to place the items and then they get stuck waiting for an attractor to become available...
When running your model as-is I get a jam in the stage one area
And in the logic blocks, I can see that the transports are stuck in the "Move By Transporter" block.
If I assume the attractors are set to 4 for a reason I would suggest the following logic - similar to what is described here
You create a list of all the attractors available. See the neat trick in AnyLogic where if you select a bunch of objects and then right-click on them you can automatically create a collection.
You can call it something like attractorsAvailabeStage1
And create a new map to store the WIP agents that will be occupying the attractors
And have a function that will provide the available attractors.
Change the move by transporter option to move to an attractor
And also return the attractor as available once it gets moved from its location
Now you only need to prevent mew agents from entering the area if there is no more attractors left or agents on their way to the attractors
I tested it and it works great for stage 1 you need to do it for all the stages.
On second thought....
seeing that you do have resource pools and service blocks. You can achieve the same logic I described by having resources first size the locations, then go to the transport block, and then be delayed
You first seize the space in the stage, then you move to the space, then you delay it.... then you wait, then seize the space in stage 2, then move there, then release stage 1.
I would go for the latter option

Same resource from resource pool for subsequent process

There is a process, box enters station (i) and operator and machine are used for SETUP, then box moves to (ii) where only machine is used.
there is 1 - operator, but 2- machines.
there are 2 conveyer systems.
How to ensure that box uses same Machine resource in station (ii) as station (i)
**Or
Ensure the Machine is continually seized from station (i) to (ii)
To re-seize the same resource - When the box seizes a resource, set a variable equal to the resource that was seized. In the resource pool, you can see "on seize" and there is self, unit, agent. Agent is the one doing the seizing and unit is the one that got seized. For the second station, in the resources section, check "customize resource condition". Try something like agent.unitSeized == unit; where unitSeized is the variable you set up. See the help menu for this. You might have to play around a little on where this occurs, exact syntax.
To keep the resource seized, I would not use a station. There is no option to seize a resource with the built in station resource & release it later. I would use a position on conveyor and just handle everything manually. That is, convey to that POC, and then next block in your flowchart can be a seize. You can then delay for processing, add a convey for getting to the next POC on conveyor 2, delay for processing, release resource. This approach would work for your first case too. You can have much more control if you route to various positions, and then send to delays or other regular process blocks to get the behavior you want. If you take this approach, you could add decide blocks, so that it covers both of your cases via an input parameter.

Forklifts stop moving and freeze in place

I am facing an interesting problem with this warehouse model of mine. I have forklifts that move shipments around a network- the warehouse, and the model seems to be running fine until st some point forklifts start getting stuck at random location in the network for no reason. The longer I run the model the more forklifts are stuck. The are like completely frozen in place. At first I was defining the number of forklifts- resource pool capacity, using a schedule and I thought that might be the problem, so I went a head and changed it to constant capacity, and the problem still arises as you can see in this image.
As far the resource pool, the seize, and release blocks concerned; I kept the default settings and didn't change anything.
Here's a screenshot of the resource pool properties. I defined forklift as an agent and inside that agent is nothing but the image of a forklift and at the "use in flowchart as" box I set it to resource unit. I don't quite understand the 100 at the end of shift priority box, but I left it at the default value.
Here's a screenshot of one of seize blocks but all the block are similar
Similarly, this is screenshot of one of release blocks where the forklifts return to their home location after each task. Here I tried all the options from return to home every time to release from a given pool and choose the forklift pool or just releases the correspondent seize block, and that all didn't resolve the issue
Again, the model runs fine and only after 10% of the running time period this starts to happen. Any help would be appreciated.

How do I seize a subset of seized resources?

I have a pool of 25 agents (Operators). When an Order is generated, I seize a few Operators and move them to one of many different ProductionSuites as determined by a parameter in the Order.
Within the ProductionSuite, I have a variable of type ResourcePool that I would like to use to have these Operators perform tasks.
In the main window, I put this code in the "On seize unit:" code box:
agent.assignedSuite.suiteOperatorPool.addAgentToContents(unit);
but this triggers a NullPointerException error. Am I using the addAgentToContents method incorrectly?
You have not initialized your suiteOperatorPool variable, it's "initial value" field is empty. Hence, this is just an empty shell of type ResourcePool that cannot do anything, including adding agents to it.
You would need to initialize it properly using the ResourcePool API, but I don't think that is possible.
Also, you cannot have resources be part of 2 resource pools, as you are trying to do. You should think of a different way to solve your problem. Maybe rephrase the issue so we can think of alternatives. You might not need a RP at all but just use pure agent functionality...?