Anylogic: How can I open/close a valve on an agent frame from the main/rootframe? - anylogic

I am building a DES-ABM hybrid model in AnyLogic. The agents go through the DES blocks on the main frame. From these blocks on the main/root frame, I want to open a valve on the agent frame.
When I use agent.xxx and it finds the proper agent with all elements on the agent frame.
I used
'''agent.valve_trafficsignIN.open(); ''' (in a DES block on main/rootframe)
to open the valve on the agent frame. It does not give me any errors when I run it. Also, when I print the information using traceln, it gives me the correct specs of the valve in question and it states that it is open.
However, when I open the agent frame, the valve is still closed. Also, the changes that should happen in the model when the valve opens do not happen.
What should I change/how do I open the valve on the agent frame from the main/root frame?

I found out that a DES source block generates agents in a DeafaultPopulation, which is why I could not find the correct agent during the simulation run. I changed the source setting to 'add agents to: custom population' and I can now find, and refer to, the right agent.

Related

In Anylogic, is it possible to send an agent from one storage to another directly?

I have 2 storages (called storageA & storageB) and I want to move an agent (pallet) from one to the other via forklifts. I have set up the following.
A pallet is created at a node and is moved to storageA via 'store'. This part works fine. The pallet is then moved to storageB via 'store1' after a delay. This is when the following error occurs:
Exception during discrete event execution:
root.store1.seizeTrans.freeSpaceSendTo:
Path not found! {agent=2, source={level=level, pos=(1673.3333333333333, 3245.0, 0.0)}, target={level=level, pos=(1857.25, 3160.4845, 0.0)}}
It works if I replace 'store1' with a retrieve block and send it to a node first. However I would like to send the pallet directly to another storage rather than via another location. Is this possible?
Please let me know if I have not provided enough information.
Thanks
yeah unfortunately you can't do that as far as I know, the solution I use is the following, which is actually not a super robust solution... but has been ok in applications so far
Place a retrieve block between your delay and your store1
Use the agent you pick up as destination:
on the on seize action of the retrieve block do:agent.transporter=unit;
4.On the store1 block put the highest priority for the task
5. ON the store1 block use resource custom transporter choice: agent.transporter.equals(unit)
6. The dispatching policy should be nearest to the agent in store1, but doing all the above ensures that the resource continues doing the task no matter what... by only using the dispatch policy your model will work 99.999999% of the time... the problem occurs only if another task with higher priority occurs at the exact same time as the transporter is released in the retrieve block, which is rare, but can happen.
I had the same question today so I landed here. But luckily, only after the second step written above, the whole process needed did already work for my case. We can move an agent from one storage to another by simply set the destination of the 'retrieve' block to the coordinate of the agent and the move to independently instead of by fleets or resources. after that we put the 'store' block.
Destination is: (x,y,z)
X: agent.getX()
Y: agent.getY()
Z: agent.getZ()
after agents being retrieved to a specified coordinate, it seems that fleets do not comply paths in the network anymore

Anylogic Message Animation

I am trying to force agents of a population to exchange messages in AnyLogic. I would like each time agent A sends a message to B the icon of the message to move from A to B. How can I implement this?
The code Emile sent you works to move an agent from one place to another one. I understand you don't want to move your two agents, but instead you want to move only a "message icon" from one to the other. For that you can create an agent (let's call it agent "Message"), create it and locate it in the agentA, and tell it (as Emile said) to move to agentB: messageAB.moveTo(agentB.getPosition()); this way you'll get the effect you want.
You could also:
use a timer to move from one place to another, or
use an event and change the position of the icon dinamically depending on how much time you have remaining on that event
use a source/delay/sink for the same as in point 2
There are basically two ways to move an agent:
Jump to agent B: Instantly appears near agent B
Move to agent A at a certain speed
For each one the code is respectively as follows:
agentA.jumpTo( agentB.getXYZ() );
agentA.moveTo( agentB );
Where agentA and agentB refer to the agents which you might call differently depending where you are in the model.

AnyLogic: How to refer to an agent in a delay block in anylogic

I am building a DES-ABM hybrid model in AnyLogic.
The agents go through the DES blocks, among which multiple Delay blocks.
How do I
access an agent which is in a Delay block
or peferrably
acces the specific agent which triggered the 'on enter' action of the delay block?
My ultimate goal is to open or close a valve object on the agent frame
So can I/ how do I
A. open or close the valve on the agent frame directly form the main/root frame (on which the Delay block is located)
or if that is not possible
B. send a message or trigger a statechart within the specific agent which will then open or close the valve from the agent's own frame?
I have tried to use the 'DelayBlockName'.agents() function, but this does not work and returns [] when I check it using traceln.
access an agent which is in a Delay block or peferrably
use the keyword agent. These keywords differ for different library blocks so best start learning about the lightbulb and how it can help, see here.
acces the specific agent which triggered the 'on enter' action of the delay block?
When you write agent. in the "On enter" block, every agent coming through will execute that code, so by definition, it is always the specific agent :)
My ultimate goal is to open or close a valve object on the agent frame So can I/ how do I A. open or close the valve on the agent frame directly form the main/root frame (on which the Delay block is located) or if that is not possible B. send a message or trigger a statechart within the specific agent which will then open or close the valve from the agent's own frame?
this is something completely different to your original question and just... messy. Please limit questions to 1 topic so it is easy for us to answer :) (see this guide for more)

difficult to find the current location of agents in Anylogic simulation

i built a simple model for pedestrian movement from start line towards target line, I want to find the number of moving agents in some area using the XY-coordinates (from X=150 to X=350, Y is the same )
The action for the event is to get the count of agents in that area and set the value for the variable crowd1:
crowd1=count(agents(), p-> p.getX()>150 && p.getX()<350)
the problem is that it's always 0 , even though the gents are moving in the simulation.
There are no agents in your environment because you haven't created any agent type... For your code to work you need to have a population of pedestrians registered in your environment (meaning that you have to create the agent type and add it to main as a populatin), and then you have to add to a custom population the agents created in pedSource...
Otherwise, you can use this code:
count(pedGoTo.getPeds(),p->p.getX()>150 && p.getX()<350)

How to add to agent to presentation

I am trying to simulate self-sustaining population of cows, but when i dinamicly add new agents to main agent's population newly created agent does not appear. How to fix it? I create agents from mother agent with
this.main.add_cows();
first generation population
pupulation without presentation
First go to the agent where the animation will exist (which is also where your agent is defined). In most cases this is the main agent, so you probably want to go to "main" and click on the cow agent to see the "initial location" in the properties of the cow agent.
When a new agent is created, the default position is at the agent animation location, which is probably somewhere out of the visible area since we generally position our defined agents out of the canvas, and in your case it's the same position for all cows.
Now you have other options: you can select for instance a random coordinate in the space (assuming you have a 600x600 pixels square):
Or you can select a node (as long as a node is defined in your animation canvas:
So, to summarize, when you create a new agent in your population, you have to tell AnyLogic where you want to locate it... Otherwise, how can the software know what you want?
ensure to set the initial location correct, otherwise it might appear at a default location you do not expect. Something like:
Cow myNewCow = this.main.add_cows();
myNewCow.setXY(uniform(0,600), uniform(0,400));