For my flow chart I generate three different agents via different sources. Now I want to handle them differently in diverse blocks in the flow chart. For instance, I want to have a different delay time for the agents. Since I am new to AnyLogic and not that good with Java, I have problems to understand how to handle the agents in my model.
I gave the agents a string-parameter with a name and tried to use a function with an if-else-statement to differentiate the agents in the delay. My approach is summarized in the following image (I hope I did it right):
The code in the function is:
if (agent.TypeComponent == "blade" || agent.TypeComponent == "narcelle")
return uniform(3.5, 6);
else return uniform(1, 3);
I get the error report (translated from german):
agent cannot be solved to a variable.
the method delayPrepFeeder() in type Main is not applicable for the arguments (Agent)
Thank you and kind regards.
The short and simplifiwed answer: You can only have one Agent type flowing through your flowchart and working with it properly. So either use only one Source or make sure that all your Sources create the same Agent type, eg. Component. More details on the different aspects below.
Each flowchart block has an Agent type defined, that this block is expecting:
You can still send Agents through the flowchart that are not matching this defined Agent type, but you won't be able to access any of its variables, parameters and functions! If you still try to access a field of a type that is not the defined type, you will get this error: MyField cannot be resolved or is not a field
. Why? Because when you access the flowing Agent via agent.
then the Java type you are working with will be the defined Agent type, or in other words, your Agent has been casted to the defined type, whatever his real type was before.
Make sure that in your Sources you have New Agent and Agent Type set to your specific agent type:
The New Agent setting defines the actual type of the created flowing object. The Agent Type is available in all flowchart blocks, it defines as which type you can handle the flowing object (or in Java speek: to which type it is casted when you access agent
).
In your delayPrepFeeder()
function check that you defined an input parameter and that you defined it as the right type. Do it like this (of course use your own custom type name):
The code will have to use the name you just defined for your input parameter (here: myAgent). Inside this function you cannot access the Agent directly by using agent
, this works only directly in the flowchart block. Therefore we defined the input parameter myAgent
and call the function with the reference to the agent
. Again, the process flow module will hand you with the calling of agent
an object reference of the type defined in this flowchart block, which has to match both the type defined in the Source and the type you work with in the input parameters and the function.
if (myAgent.TypeComponent.equalsIgnoreCase("blade") || myAgent.TypeComponent.equalsIgnoreCase("narcelle")){
return uniform(3.5, 6);
}
else {
return uniform(1, 3);
}
You probably don't.
If your types differ by only attributes, use fields (variables and parameters) to differentiate between them. For example always use the Agent type Component
and then differentiate with a parameter called type
. This type
parameter can be a String (eg: "Rotorblade"), or even better an entry from a AnyLogic Option List, where you defined all possible types beforehand.
The only case when you really need different types is when you have completely different (complex) statecharts, action charts, visualisation or other customized AnyLogic elements inside your Agent types.
You can do so with the use of inheritance. Create a "base" Agent (which is so far just a normal Agent), for example Component. This base Agent will be the one that you set as type flowing through in all Flowchart blocks. Inside this base Agent you add all the variables, parameters, functions, etc. that are common to all your types and that you want to access in the flowchart.
Next, you create your inherited Agents. Again, create them as normal Agent Types. You make them inherit from the base Agent with this simple setting:
Now you will see, that things defined in your base Agent will also appear (grey) in your inherited Agents:
One more thing: You can actually access the fields and functions of the inherited agents, by casting it from the base type to its correct type with: (MyInheritedAgent)agent
. However you will have to be sure beforehand that this object is really of this type, otherwise you will get a casting error.
You can (without using inherited Agents) only use one single Agent type per AnyLogic flowchart. Make therefore sure that the Agent type is always set to this same one Agent type in the following positions:
agent
: Input parameterIf one is not enough, use Agent inheritance.
As a side note, please use equals()
or equalsIgnoreCase()
instead of ==
for String comparison, the reasons being explained here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With