Same resource from resource pool for subsequent process - anylogic

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.

Related

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

How can I take the closest resources to specific stations from ResourcePool?

I'm simulating a manufacturing process. The stations need a variable number of ResourcePool "workers". Let's say there are 5 workers for 4 stations, and I want to simulate that those workers can work indifferently in any of the stations.
The problem is that they are not working in the closest station. Oppositely, even when a worker is next to the station, maybe the furthest worker goes until this station which needs the resource, and then the process starts. Obviously, this is inefficient and doesn't represent the reality.
I already have the workers defined, their shifts, their timetables, etc. I have tried to use the function getNeartestAgent() in 'Customize request choice', but it doesn't work. I also tried to calculate the distance of each agent with getDistance(), but I don't know how to manage it and I'm sure it must be a simpler solution even when I'm not working on GIS.
[31/08/22]
Recently I tried to develop a similar model, and I still have the same problem. The model consists of 3 stations which need 1 unit of ResourcePool. In this pool, there are 2 units. This units are agent type Operario. So, I need to choose the closest unit to the station. I tried several things, the following are just some...:
Service blocks -> Resource selection -> "Nearest to the agent". The agent is the material item, so the unit should go to the closest agent being treated in the station. However, it didn't work (units where to any station indeferently).
Service blocks -> Resource selection -> "Unit with top rating". The Unit rating field was 1/distanceTo(node1.getXYZ()). It didn't work either.
Stations (instead of Service blocks) -> Customize resource choice -> Resource choice condition. I can't stablish a boolean variable related to the unit position, as I can't compare among them.
Function. I can't compare units from ResourcePool, as they are detected as Agent and not as Operario.
ResourcePool. I tried to stablish the priority based on the distance to a certain node. But then I can't call these agents (Operario) from the station. It seems here I can only refer to material items, eventhough I write "unit.(...)".
Does anyone know how can I choose the closest resource to the station in which the task is performed? Should be through Customize resource choice -> Resource choice condition, but I don't know how!
when you use a service or seize block, in the advanced properties, there's an option called "Resource Selection"
You have to choose "Nearest to the agent"
If this doesn't work, it might mean that a resource that is close by and not selected, might be actually busy with something else... you have debug your model in order to be sure that it is not the case.

Considering differences in the same materials - Stations

I am trying to simulate a manufacturing assembly process, where material items are processed following an unique line. In the quality control stations, when a failure is detected, the object is sent to the repair area (by a truckpallet) and, when it is repaired, the same resource takes it and puts it at the start of the line. Until this point, I already programmed it.
The problem is the following: when it is a repaired object, is has to follow the same conveyor but with no stops in the stations. The object must enter a station and leave it, with no delays (as the works related with the stations have already been made).
I thought the best would be to consider the difference (repaired vs. not repaired) in the Agent, but then I can't work with it in the Main agent... I have also tried alternative solutions, for example defining variables in each station 1 and consider that in the stations delays and in the following station:
triangular( 109.1*delay_bec, delaytime_bec*delay_bec, 307.6*delay_bec)
Actions - in finished process:
if(delay_bec==0){
delay_headers=0;
delay_bec=1;}
But nothing worked... Any help?
I thought the best would be to consider the difference (repaired vs. not repaired) in the Agent, but then I can't work with it in the Main agent...
This is actually the correct approach. You need to create a custom agent type, give in a boolean variable isRepaired (or similar) and then in the delay you can dynamically adjust the duration using that characteristic:
agent.isRepaired ? 0. : 100
This will delay normal agents by 100 time units and repaired agents not at all.
Obviously, you must make sure that the agents flowing through the flow blocks are of your custom agent type (see the help how to do that)

Manually releasing a seized resource from an agent?

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 :)

Avoiding collisions with other objects while moving an Agent to a specific destination

I have in my model some free-moving agents, which travel to specific nodes. I use the function...
moveTo(node)
...to specify the node an agent should visit. Using this function, the agent travels the shortest path to the node. However, the model layout contains areas (i.e. image files), which the agent should not pass. Right now, the agents may travel through these areas to reach their destination. Now I'm wondering, whether there is an easy way to permit an agent to enter specific areas in the model, when traveling to a node.
I already took a look at the example model "Wandering Elephants" where the elephants are permitted to walk through areas with water. The solution there is, that if an elephant meets water in the direction it's currently heading, it randomly searches for another direction, until it finds one without water. However, this approach doesn't really fit to my problem, as the elephants in the model wander around without any specific destination. I'm searching for a method, which works for an agent that travels to a specific point. In the best case, the agent would search the shortest path around the obstacle to reach its destination.
Edit 1: The following figure shows my problem in a nutshell. On the left side is my model structure, while on the right side the state chart of my custom agent. What is happening in the model: The 3 sources are producing agents, which will be delayed for an uncertain time (delay stops with stopDelay()). Everytime an agent enters a delay, the delay is added to the collection request. My customagent check requests in a loop until the collection contains at least one request. Then, the customagent randomly selects a request (i.e. delay object) to serve. Each delay is associated with a node (the collection processNodes maps delays to nodes). Now, I want to cast my customagent to a Transporter and move it to the corresponding node. The agent should avoid collisions with the stripped walls in the model. I want to avoid any seizing and releasing of resources. I just want to adapt the behaviour of the Transport agent from the material handling library to my agent.
Edit 2:
In my current testbed, my custom agent does not consider node 1 or node 2. For testing, the agent should only try to reach node without any collisions.
I found a sufficient work-around. Not exactly what I wanted, but it works. Against my initial intention, I use now seize and release for transports. However, I added a hold-block in front of each seized-block and only a resource, which decides to serve the process, is able to unblock the corresponding hold. The on-enter control of the unblocked hold ensures that the hold is directly blocked again as soon as a single agent flows through. For the case that other users are also interested in the solution, I attached the flow-chart of the process and the state-chart of the Transporter-Agent. The system structure is quite the same as in my initial question.
There is no build-in way unless you use transporters from the Material handling library (or pedestrians). These can do what you need.
So easiest might be to convert you agents to transporters temporarily.
Otherwise, you will have to code something yourself...