How can I handle different materials in one flowchart in Anylogic?

Siilas :

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.

Florian :

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.


Flowchart Agent type definition

Each flowchart block has an Agent type defined, that this block is expecting:

Flowchart Agent type definition

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.

Source Agent type

Make sure that in your Sources you have New Agent and Agent Type set to your specific agent type:

Source Agent Type Definition

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).

Input parameter of function

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):

Function Input Definition

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);
}

Do I really need several different Agent type in one flowchart?

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.

What if I really need several Agent types in one flowchart?

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:

Inherit Agent

Now you will see, that things defined in your base Agent will also appear (grey) in your inherited Agents:

Base Agent and Inherited Agent

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.

Conclusion

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:

  • Sources: New Agent
  • Sources: Agent type
  • Flowchart blocks: Agent type
  • Functions working with the flowing agent: Input parameter

If 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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=121273&siteId=1