How to use my agent to enter a process flow of a specific agent (ex: Depot[0]) from a population of agent (ex: Depots)? - anylogic

So, I have a case in anylogic where a drone needs to be transported via a bike from a certain place (namely, Depot) to a certain place (namely, Stopover Point). After that, the drone will be released from the bike and will do some mapping to a set of designated locations of Mapping Points. For this case, I used a process flow to make the bike (that I treat as a resource unit) to seize the agent (drone) at the Depot before the bike move to the Stopover Point and releasing the drone there.
At first, I used to make some kind of sandbox model where I only use one Depot and one Stopover Point
so that it is easier when I want to use my agent (drone) in a process flow via enter block (ex: I only have to write main.depot.enter.take(this); at my agent (drone) statechart to enter it to the process flow at Depot bacause the Depot is a single agent).
The problem occurs when I tried to use more than one Depot and make it as a population of agent. This makes me unable to use main.depot.enter.take(this); because of the property of the Depot for it is now a population of agent and not a single agent anymore.
The question is how should I do if I want my agent (drone) to enter the process flow of a certain/specific Depot (ex: only Depot[0])? I have used a paramater such as "name" with the value consists of texts like "Depot 1, Depot 2, and so on" and modify the commmand to filter(main.depots, a -> a.name == "Depot 1").enter.take(this); or main.depot[0].enter.take(this); but I think that's not the right way to code it because it didn't works. So, how is exactly the correct way to code or to do it if I want my agent to enter a process flow of a specific agent (ex: Depot[0]) from a population of agent (ex: Depots)? Thank you.

You should use () instead of [] to select one depot from the population.
So to select the one with index 0, you write: main.depot(0).enter.take(this).
To select a depot based on the name parameter, I would use the findFirst function which selects one of the depots. In your exitblock, you could write:
main.depot(findFirst(main.depot, a->a.name.equals("Depot1")).getIndex()).enter.take(this)
The getIndex()method returns the index of the selected agent.

Related

Can a transporter follow an 'material' agent into another agent?

I have an material agent that is moved from the Main agent to inside another agent (simulating a room). I can send the material agent using the Exit and Enter blocks. The 'room' agent contains a network that the material agent is being sent to.
The material agent is initially being moved in Main using a Transporter. However I'm not able to get this Transporter to follow the material agent into the room agent. The main questions is - is it possible to send a Transporter into another agent? Or does it need to remain in the agent that the Transporter Fleet is located?
Thank you.
I will correct benjamin by saying that with setEnvironment you can't do it since that's a function that is called on the agent initialization.
Instead of setEnvironment,something you do normally is to send the agent to a new population (which is the way you dynamically change environment), but it doesn't work with transporters
My answer would be that you can't do it since transporters who follow paths are defined as strict AGVs and can only move on their initial network and you can't change the network, unlike other agents.
But i'm always a bit suspicious of myself when i say something is not possible...
This should be possible with some setEnvironment() calls.
However, it is not a good setup. Think of reality: your rooms are spatially all part of the same environment: your flat (or factory or whatever). Moving from 1 room to the next does not mean you change your flat. You stay in the same environment.
You should setup your room agents like that as well: their spatial representation should reside in Main (or whatever agent they are embedded in).
Use a parameter of type ShapeRectangle or similar in your Room agent to define which rectangle (or else) represents the spatial aspect of the room.
Then, the flow chart blocks in the Room agent simply refer to that parameter for their spatial needs.

In Anylogic How can I model truck that deliver orders to multiple clients

I'm creating a model based on the product delivery example provided by AnyLogic. In my own model, I want a truck to deliver multiple orders in one trip instead of one. My process diagram is shown below. Here, an order enters via the enter block and several orders are accumulated in the batch block. Every order has a specified destination. How do I model the truck such that it combines two orders and move to the nearest delivery location first and then the second etc?
The main problem is that I don't know the code that accesses the parameter "Delivery location" in each order.
enter image description here
enter image description here
Additional information:
The orders agents are generated and the delivery location is stored in a parameter called "client"
The batch block combines (lets say 2) orders into a batch of the type Order ( advanced settings set to population of agents)
The service block pulls a truck from the resource poule and send the batch of orders to the truck agent using send(batch.unit)
The truck agent stores the order/orders(?) in a variable called "order"
Then, a moveTo function should deliver the order to the first destination
What would be the code to move to the first, second etc., destination?
Here is the conceptual piece you are probably not aware of, and that should help you move in the right direction:
you can have "for loops" as part of your process flows. Below, you see an example where an agent keeps driving to places until it has no more parcels.
Obviously, the details of the blocks depend on your model but in each, you can access the truck's orders if you have them in your Truck agent type (which is needed, obviously).

AnyLogic if condition selectOutput

I'm modelling a manufacturing line in anylogic. Two agents are being processed and transported via the same conveyor. Both Agents need to spend diffent delay times in a service station. Because of that i added two parallel services and now i want to sort the agents arriving on the conveyor to their corrosponding service stations.
flowchart
Agent1 needs to go to service and Agent2 to serviceT.
I assigned parameters to both Agents, Agent1 has the boolean parameter "S" set to true and Agent2 the same parameter set to false.
To sort the Agents in the selectOutput block i typed in the if condition agent.S == true as seen in the next screenshot.
selectOutput
Anylogic prompts following error: "Unresolved compilation problem: S cannot be resolved or is not a field"
What can i do about this?
Thank you!
I would like to answer this question in two parts:
Instead of using a selectOutput to model different delay times for the SAME station, it would be more reasonable to have only ONE service representing that ONE station. To model different times, set the delay time equal to agent.S where S is the delay time for each agent.
Regardless of whether you choose what I suggested or what you are already using, you will still get the same error. The reason for this error is most likely that you haven't specified the agent type going through the select output properly. In fact, if you look at the image of the select output properties you shared, under the "Advanced" tab, the agent type is set as the default type Agent. Make sure to replace that by the agent type that contains the parameter S.

Anylogic: How can you link a population with a source

how is it possible that the sourceof a process model only creates the agents out of a population and in best case at once? In my model the source is creating more agents than the size of the population.
thx in advance
Using a Source it is not possible to output already existing Agents of a population from it, as the source is always creating them at the time of output.
You have two possibilities:
Instead of a Source, use the Process Modelling element Enter at
the start of your process flow. Using the function
enter.take(myPopulation.get(index)) you can input your already
existing population members. This way you can also input them "at once".
In the Source properties under Advanced - Population select your
custom population. Whenever the source creates a new Agent, it will
get added to this population. Note: The Agent type of the population
must be the same as the Agent type defined in the Source.

How to use "wait" in anylogic?

I have a stock agent which is created in the end of my production line. My products are characterized by their model. I'm trying to create a logic to take out the products from this stock agent when they are to be delivered to the client. This delivery is controlled by an excel sheet and I'm taking the information through a SQL code. However, I was not able to find the right code to take out the products which are to be delivered. My agent population is called ProdutoStock and it's located in my main screen.
I have tried: Main.remove_ProdutoStock() but i couldn't figure out the arguments that i need for this function, since i have to take out of the agent a specific number of agents and also of a specific model.
So, I decided to create a wait block and use the free function to free the specific agents i wanted main.waiting_delivery.free() but i also can't figure out the necessary arguments for this function.
Would someone have any idea how I can take out of my agent/line the products that I need to deliver for my client (considering quality and also model)? This code is not being typed into my main screen.
the argument of the free method is the agent itself.
So you have to do main.waiting_delivery.free(yourAgent);
If you want to free the last agent that entered the wait block:
if(main.waiting_delivery.size()>0)
main.waiting_delivery.free(main.waiting_delivery.get(0));
If you want to free agents following a certain condition
List <YourAgent> theAgents=findAll(main.yourAgentPopulation,a->a.condition==true);
for(YourAgent a : theAgents){
main.waiting_delivery.free(a);
}