How to set agents hight in delay block? - anylogic

By seizeTransporter block my AGV seizes an agent called "Sitz" and transports it via Move by Transporter block to a Delay Block.
When AGV enters the delay block the transported agent "Sitz" is changing its cargo location to 0.
I tried to fix that issue with creating an parameter on main called p_assemblyHight with default value 1.0 and the following code in Actions section of the delay Block: agent.setHight(p_assemblyHight, METER);
Anyway this action will not execute.
What can I do so that my transported product (called "Sitz") stays on the agv and not dropping in delay block?
Check the two screenshots for better understanding.
Thank you a lot!

The setHeight method does not change the z-component, but the height of an agent presentation. Irrelevant for you.
You need to access your Sitz in the delay block and change its z-component.
In the Delay block call:
agent.setXYZ(agent.getX(), agent.getY(), 10);
The last argument is the Z component, adjust as needed. The first 2 just make sure the XY components are not changed

Related

Having problem with "moveTo" Block in AnyLogic

I am using "moveto" to reach at destination caller Dryer. Dryer have "queue" and "delay".
Now when agent come it first go to Dryer and then go to "queue" and then wait for its turn to go to Dryer for "delay".
What should happen is agent move to the "queue", wait for its turn to go to Dryer. How I can achieve that?
My approach
1. MoveTo
2. Queue
3. Delay
what you should do is use a conveyor block instead of a moveTo + queue blocks like this:
The conveyor will act as a queue and everything will be ok
You will have to define the path for the conveyor and set the delay with capacity 1 and the location of the delay on the dryer
What I would do is put a Node with a radius 0 very close to the Node associated with the dryer and send the agents there.
See below each block where I associate it:
Good luck!

Anylogic - Assembler should stop working for 2 hours after 10 assemblies done

The "Assembler" should stop working for 2 hours after 10 assemblies are done.
How can I achieve that?
There are so many ways to do this depending on what it means to stop working and what the implications are for the incoming parts.. but here's one option
create a resourcePool called Machine, this will be used along with the technicians:
on the "on exit" action of the assembler do this (I use 9 instead of 10 because the out.count() doesn't count until the agent is completely out, so when it counts 9, it means that you have produced 10)
if(self.out.count()==9){
machine.set_capacity(0);
create_MyDynamicEvent(2, HOUR);
}
In your dynamice event (that you have to create) you will add the following code:
machine.set_capacity(1);
A second option is to have a variable countAssembler count the number of items produced... then
on exit you write countAssembler++;
on enter delay you write the following:
if(countAssembler==10){
self.suspend(agent);
create_MyDynamicEvent(2, HOUR,agent);
}
on the dynamic event you write:
assembler.resume(agent);
Don't forget to add the parameter needed in the dynamic event:
Create a variable called countAssembler of type int. Increment this as agents pass through the assembler. Also create a variable called assemblerStopTime. You also record the assembler stop time with assemblerStopTime=time()
Place a selectOutputOut block before the and let them in if countAssembler value is less than 10. Otherwise send to a Wait block.
Now, to maintain the FIFO rule, in the first selectOutputOut condition, you need to check also if there is any agent in the wait block and if the current time - assemblerStopTime is greater than 2. If there is, you free it and send to the assembler with wait.free(0) function. And send the current agent to wait. You also need to reset the countAssembler to zero.

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)

Anylogic: How to conditionally close/open a valve

I am very new at Anylogic. I have a simple model, using the Fluid dynamics library: two tanks and a valve between them. The valve have to open at a rate, say X, only when the amount in the first tank, say tank_1, were twice of the amount of the second tank, say tank_2
Could you please help me with that?
Regards
You probably have more conditions on what to use with the valve depending on different things. But it's a bad idea to make something occur when then tank_1 is exactly 2 times larger than tank_2... Instead, create a boolean variable that tells you if the current situation is that tank_1 is over or below 2*tank_2. Let's call it "belowTank2". I will assume tank_1 is below 2*tank_2 in the beginning of the simulation. so belowTank2 is true.
Then you create an event that runs cyclically every second or even more often if you want and you use the following code:
if(belowTank2){
if(tank_1.amount()>2*tank_2.amount()){
valve.set_openRate(0.1);
belowTank2=false;
}
}else{
if(tank_1.amount()<2*tank_2.amount()){
valve.set_openRate(0.3);
belowTank2=true;
}
}
So this means that whenever tank_1 surpases 2*tank_2, it will trigger the rate change on the valve. And it will trigger again a change when it's below 2*tank_2