Anylogic from "release block" change variable integer - anylogic

I have an Agent Cart created with 4 variables inside. Each variable is an integer and one of them is called red and has an initial value of 4.
When I use seize/release statement I want change the integer by -1.
In the action section ive tried "On release" saying (Cart)unit.red in hope of changing the variable from 4 to 3. It gives an error back. "red cannot be resolved or is not a field" along with an syntax error on ")", assignment operator expected in (Cart)unit.red. Writing (Cart)unit.variable doesnt work either. Another sub-question : Is it possible to change two of the variables in the class from the "on release" block?
EDIT
Classpicture
Overview
Seize
Release

You need to assign Cart to your resource pool in order to be able to use it.
Check this image:
After that you need to be very careful on making the distinction between Cart, cart and carts
Cart being the class
cart being the agent if there is only 1 cart and you defined it as a single agent
carts being the population of agents
in your case, only the class is needed if you created a resource type called Cart... check out the capital letters compared to the non-capitalized ones.
Ok, now in your seize block you can use the cart ONLY in the action called on seize unit or on prepare unit.
if you do ((Cart)unit).red=3; it WILL work, as long as you understood all the previous explanation.
It it doesn't, you will need to give A LOT more information about your model, including very precise images of everything you are doing.

Related

Anylogic how create new agent and assign properties?

Anylogic: This should be simple but I just cannot find it in the help files..
On creating a new agent instance, we know there are four parameters and what they are, but not in what order they were defined. Lets say parameters are "type_of_car" (String), "number_of_pax" (Integer), "automatic" (boolean), "fuel_capacity" (double). Now when calling: new myagenttype("ford", 5, false, 55) the agent gets created as a ford with 55 pax, manual and 5 liter fuel capacity - which is all wrong. (it seems the definition order of the parameters in the agent definition are in a different order)
How do we include the parameter name (or definition) when we call new agenttype() to avoid this problem, ensuring the right value gets assigned to the right parameter?
The problem originates because of a bug in Anylogic's logic in triggering functions. We have a Split which creates a new agent and assigns the agent properties on the "On exit copy" - event, however what Anylogic does is it creates the agent, forward it to the next logical block (a decision node), then execute the code of the decision - all wrong now for the agent's properties are undefined - and only then executes the "On exit copy" event which assigns the agent's properties. Very frustrating.
This is actually not a bug, this is defined in the simulation experiment properties, in the randomness section, with the "selection mode for simultaneous events" property. The default is LIFO, but if you want the opposite behavior in your case you should use FIFO... I always use LIFO too, and in these cases, sometimes I might use a 1milisecond auxiliary delay between the split and the next block in order to control the order manually... if you do that, you will solver your problem in fact... just use a 0.001 miliseconds delay after your split
Now from your Agent Type problem, the arguments for your class constructor should be written in order, and the only way to know the correct order is by using the autocomplete feature when you write new agenttype()... the autocomplete will tell you the order in which you should write your constructor arguments.

What is the right way to allot a distinct value to an agent's parameter in Anylogic?

I want my agent to be of a single type. Where type contains a list of 3 options. And the allotment should be based on probability. E.g. let's say I want to allot 1: 30%, 2: 50% and 3: 20% to each of the agents generated in the source of my main tab.
I tried with one of the ways by declaring th parameter as int and then writing randomTrue(0.3)?1:randomTrue(0.7)?2:3 in the default value. But every time the agent comes with the same value of 2.
Please can anyone help me with this??
And if I try to allot the parameters in the main window at any of the blocks, do they get attached to the specific agent that passes through that block or its value just gets updated for that time until the other agent passes? Actually I have to check each and every agent for the parameter and then send it through a specific output path from the selectoutput block.
Your code does not actually change anything in the created agent.
Create a parameter `myType´ of type Integer.
In your source code write:
agent.myType = randomTrue(0.3) ? 0 : randomTrue(0.7) ? 1 : 2
Make sure your Source block actually creates agents of the Agent type that holds the myType parameter.
Study some of the example models and tutorials, it is covered in many places :-)

How to get around using Enter and Exit blocks in "Prepare" flowchart (Execution error "0 isn't supported for building resource behavior flowcharts")

I have an airlock (small room called AL_2216) between 2 areas. The airlock has many different agent types passing through it (cart, product, operator, etc). There are queuing areas on either side of the airlock.
Because the space is small, I built a short flowchart that has a queue and restricted area blocks that all agents must pass through when going through this space. If the restricted area's capacity is full, the agents wait in either the InsideQueueArea or OutsideQueueArea depending on the direction they're going.
I send agents via Exit and Enter blocks to this flowchart and it works great on the top portion of the flowchart.
BUT if I try to use an Enter or Exit block in the prepare flowchart, I get this error:
I tried using a custom block instead of Enter and Exit blocks, but that creates a new instance of the code each time and the restrictions don't work together across the multiple custom blocks.
This airlock is just one of many in my model. Without referring to the same code, I'll have multiple copies that need to refer to each other's restricted areas and the flowcharts become huge and complicated. Is there a way to get around this?
EDIT:
I'm not sure what to do with these ports. They have no properties that do anything:
EDIT2:
Here's a file to see the behavior - Model2.zip
The Prepared flowchart portion is set to "ignore" so the code will run. You can see the operators and the carts passing through AL_2216 with only 2 being allowed at a time. If you uncheck "ignore" for the prepare flowchart, the error will trigger.
AnyLogic sent the right answer!!
So I was asking Anylogic a different question and they recognized my name from this post! They sent a fix to me and it works exactly the way it should! The exception error message I was getting "out: 0 isn't supported for..." made me think the exit/enter blocks were not supported in perparation flowcharts.
But actually, the seizeCart block didn't know where to start the prep flowchart because it wasn't directly connected to the resource task start block. A quick setting change under the Advanced section of the seizeCart block defining which resource task start block to start at did the trick! Here's the email from AnyLogic:
-The error text and documentation are not sufficient for understanding this (the error text is confusing), I suppose it is obsolete error text. We will rectify the description;
-Under the question there is a more generic discussion which seems to be unrelated to the initial problem. Please let me know if I miss something or if your model does not work as you expect even after adjustment of seizeCart block property.
I think you should replace the Enter and Exit blocks that lead to the bottom input of your seizeCart Seize block with simple Port objects (from the Agent palette).
As per the help for Seize:
So it wants a direct link to a ResourceTaskStart flow and your Enter/Exit combinations might be ... not "direct" enough... Try it.
So here's what I ended up doing. It's the best I could come up with that could be easily replicated for lots of airlocks.
I've added a wait block (dummyThruAL_2216) to my Product flowchart prior to seizing the cart. This wait block injects a new Agent into sourceDummy at the cartHome node. The dummy then seizes a cart and moves through the airlock and it's restriction. Upon exiting the restriction, I check what type of agent and direct the agent to the correct exit block. The dummy agent and cart move to the Product where the dummy agent releases the cart and sinks. The sink frees the wait block and the Product seizes the cart that is right next to it and continues on it's journey.
It's an easy copy/paste to add more airlocks. Not as nice as my original, but what are you going to do... Thanks for everyone's help and suggestions.
As others have said, there are (not really documented) restrictions on what blocks you can use in preparation and wrap-up flowcharts, which mean what you're attempting won't work.
As you say, it's important to keep a single 'instance' of the airlock flow so that the restrictions (queue and restricted area) are 'global' when this represents the same physical airlock. (Otherwise a repeated custom block is precisely what you should use for each different physical airlock.)
Your best option (and assuming you needed to attach the Cart resource to the Product) is probably to
Add dummy agents (via Source block inject calls) to a separate mini-process that represents your resource preparation requirement (but now not attached to the Seize block).
Replace the Seize in your main process with a Seize-Wait-Release-Seize combination:
The Seize block seizes the cart as normal (without moving or attaching it; no 'Send seized resources' or 'Attach seized resources' options) and then injects an agent into your mini-process (which can use Exit and Enter blocks to use the airlock sub-process). This agent represents the seized resource agent (Cart) and thus should start where it starts and be animated so it looks like it. (You can make the actual Cart temporarily non-visible during this mini-process.)
When the agent reaches the end of the mini-process (at a Sink block), instantly move the related Cart to your node (use jumpTo), make it visible again and free the Product agent from the Wait block
Release the seized Cart and then immediately re-Seize it, but now attaching it (so the animation looks correct). If you use the Resource selection 'Nearest to the agent' option you should be guaranteed to seize the correct cart. (You can also use the 'Customise resource choice' option with some code to ensure that you absolutely always choose the same Cart.)
(It is simpler than the above if you don't care about having a correct animation, and you can use custom blocks to make this block combination reusable and thus not too clunky.)
Edit: A very similar alternative which also works (and is the basis for your own answer) is to have a dummy agent representing your Product in the sub-flow which seizes (and attaches) the actual Cart agent, leaving it at the Product's location to be immediately seized as above. This is slightly better since you don't have to worry about the visibility and 'jumping' of the real resource agent, plus you can move a Seize and a Release from the main flow (which now just has Wait-Seize) to the sub-flow (thus 'hiding them away').

Using agent parameters from main to different agent?

For a project I'm trying to select the right output if a parameter of the created agent is true. The agent is created in the main but goes into a different agent for the selection of the output. If I use a select in the main and use the statement for the parameter as condition it works fine. Whenever it enters the agent and I use the same statement it gives an error (Description: product1 cannot be resolved or is not a field. Location: testCase5/Transport/selectOutput - SelectOutput).
I tried using different conditions like main.agent.product1 . Can't seem to solve the issue. I know that it has to do something with declaration probably but I'm clueless at the moment.
//for the condition that works if I put the selectOutput in the main
agent.product1
//for the condition in the agent I tried the same but didn't work. also tried
main.agent.product1 // Gives the same error but for (Description: agentcannot be resolved or is not a field.)
(Main)agent.product1
//And a few more
In AnyLogic each block of a project flow (regardless if from the process modeling library, the pedestrian library or another) has the type of Agent that is flowing through it defined in its properties. You can find this setting as Agent type in the block's properties under Advanced.
If you fail to set this correctly (meaning this setting equals the type of Agents you let flow through it), it will still flow through, BUT: you cannot access the specific properties of the Agent type.
That said, usually you do not even have to think about, because AnyLogic has an automatism there: The first block of your process flow, typically a Source-block or a Enter-block is the only block where you have to make the correct setting, all attached blocks get it then automatically!
However this does not work when:
You have separate flows (eg. you leave one flow through an Exit-block and enter another by an Enter). You'll manually have to put the correct setting also for the first block of the second process flow.
Your process flow is continued inside of another Agent/Custom Block, as in your example. AnyLogic doesnt realize the process flow inside your custom block is logically connected to the outside process flow in main. You have to specifiy manually again the Agent type flowing through in the first block of your process inside your Custom Block.

Anylogic - New Beginner: Action charts How to return visable the variables?

I am new to anylogic and need to create an actionchart for my master thesis. I know how to set it up and all but I don't know how I can see if the algorithm worked. I tried to use statistics where I choose my used variables but this shows me always the initial value.
This is what I tried to do: Just a first easy algorithm. I have a variable "test" with initial value 0. I have created an action chart with a "for loop" (for i=0;i<10;i++). And in the loop I have placed a code-block with test=test+1;.
And I have placed outside of the loop a return-block where I return "test".
So this action chart should just add 1 for every loop to my variable test. At a result the value should be 10.
When I am running this there are no errors but also no results. The Statistic block only shows the value 0. And now I don't know what I am doing wrong. Is the error in the action chart or at the statistics?
I have searched in Google and read "anylogic in three days" and was searching at the anylogic help.pages... I havn't found a solution so I thought that maybe someone knows what I am doing wrong.
I rebuilt the example you describe, and I am getting an action chart that returns the value 10. I also added a statistics block and associated it with the value of test, and it shows a value of 10. Is it possible that you are just never calling the action chart (analogous to calling a function), therefore it never executes?
In general, I would avoid action charts, as I have found it is just easier to write and maintain code in the AnyLogic functions or Advanced Java area.