I was faced with a problem in AnyLogic.
I created a function with an argument. The argument is agent Message. However, the function doesn't get the current agent. It seems that the argument is empty. Why?
this is one of the most confusing things in anylogic that things get calculated in reverse order compared to what you expect.
First the condition is calculated in order for the agent to decide where to go, and after that the agent exits the source...
Based on what we see here, the volume is probably calculated on the "on exit" action of your source and you should calculate it on the "on at exit" or you can also put a delay of 1 milisecond after the source and everything will be ok
Related
I have a model as shown below with two situations, I am running it for two situations.
In the first run (for situation1), I write traceln function as "traceln(productDemand)" in the "event-generateDemand" placed in "Main". At the end of simulation, I get the values in the first column below.
2)In the second run (for situation2), for once I write traceln function as "traceln(main.productDemand)" in the "event" placed in "Producer" agent.At the end of the second simulation, I get the values in the second column below.
Normally, these two values are always same , it expected that at the every simulation time they have to be same, but they are not same as shown in the Fig.1. what's the problem? Why the "productDemand" variable is different when we try to access from another agent at the same time?
I hope I was able to explain my problem.
Fig.1- The obtained results as table format
Fig.2- The screenshot of Event placed in Main
Fig.3- The screenshot of Event placed in Producer agent
Fig.4- The obtained results for both traceln functions on the running
Fig.5- Simulation experiment screenshot.
fig.1
fig.2
fig.3
fig.4
fig.5
There is no bug in the model it is just a simple case of timing. Not all events occur at exactly the same "time" although they all occur at the same timestep. One will always execute before the other.
See the simple example below:
I have eventA that increases the variable value and then traces the value (similar to your event on main)
Then I have another event that traces the variable as well, similar to yours in the agent.
Yet when I run the model at the same time the variable appears to be different from the different locations of tracing
If you click on the Events tab in the console you will see that event B is scheduled to run before event A
Even though both will run at the same timestep in the model they don't run "at the same time"
If you want to be in total control of what happens on a specific time step, it is advised to have one event that runs at the time interval you want, e.g daily, and have it sit on main and then call all the functions in the order you want them executed.
If you don't do this then AnyLogic will schedule the events as they get created, which most of the time is the order in which you placed them on the canvas.
I'm modelling a manufacturing line in anylogic. Two agents are being processed and transported via the same conveyor. Both Agents need to spend diffent delay times in a service station. Because of that i added two parallel services and now i want to sort the agents arriving on the conveyor to their corrosponding service stations.
flowchart
Agent1 needs to go to service and Agent2 to serviceT.
I assigned parameters to both Agents, Agent1 has the boolean parameter "S" set to true and Agent2 the same parameter set to false.
To sort the Agents in the selectOutput block i typed in the if condition agent.S == true as seen in the next screenshot.
selectOutput
Anylogic prompts following error: "Unresolved compilation problem: S cannot be resolved or is not a field"
What can i do about this?
Thank you!
I would like to answer this question in two parts:
Instead of using a selectOutput to model different delay times for the SAME station, it would be more reasonable to have only ONE service representing that ONE station. To model different times, set the delay time equal to agent.S where S is the delay time for each agent.
Regardless of whether you choose what I suggested or what you are already using, you will still get the same error. The reason for this error is most likely that you haven't specified the agent type going through the select output properly. In fact, if you look at the image of the select output properties you shared, under the "Advanced" tab, the agent type is set as the default type Agent. Make sure to replace that by the agent type that contains the parameter S.
I've been trying to model a scenario but still cannot find the best way to do it. The scenario is as follows:
Agents arrive at a point where they need to choose one of three paths. Each path is a delay with capacity 1. If the first path already has an agent in it (in the delay block), then the 1st condition is not met and the agent tries the second port. In the second port, if the delay block is available it can proceed, otherwise it checks the third. If all are busy, then the agent should wait in a queue before the select output.
To model this process, I used the following sequence:
Queue > Hold > Select Output 5 > 1 Delay element of capacity 1 after each of the three first output ports of the select output
The condition for the select output is for example "Delay1.size() == 0" then for the second port "Delay2.size() == 0", etc.
Then, I created a function that checks if all delay.size() == 1, then the hold element is set to blocked to avoid having agents going through the select output's default port. The function is tested at every "On Enter" and "On Exit" fields of all the blocks.
Despite the above, agents are still going through the default port which means that the hold element is not working properly.
Is there a more efficient way to model the described scenario? Thank you!
Well, you are not actually blocking your Hold element at all, hence agents will walk through anytime :-)
There are many ways for such a situation.
You could replace the Delay with a Wait element instead. Whenever an agent leaves one of your Delay blocks, you unblock the Hold.
Whenever an agent passes the Hold, you block it, but only if all 3 pathes are currently busy.
Should do the trick
I build a model in dymola. Even though there are some errors during the initialization process, but the calculation succeeded at last.
After the model converged successfully, I tried to use the "Save start values in the model" option to get the right iteration variable strat values stored into the model so that the model would NOT get errors in the next calculation. But after I did this and tried to do calculation once more, I still got the same errors.
So, my question is:
Could I use the "Save start values in the model" to help convergence?
If so, how should I do it?
Are you certain that there are error messages?
The simulation log indicates that you have enabled
Simulation Setup>Debug>Nonlinear iterations
That gives debug messages in the simulation log for every iteration of the non-linear solver, regardless of whether there is a problem or not. (Which can be good for analyzing errors, but should not be on as default as it generates large log-file.)
If disabling that flag doesn't remove all messages, it would be necessary to see the remaining messages and the model to understand the problem; as the previously indicated procedures should work.
The reason is I set the fixed attribute of some parameter as false, the fixed attribute of some variable as true, so I could use the variable's value to initialize the system, and the corresponding parameter would be calculated. when using "save start values in the model" option, it would store the result into the parameter's start attribute, but its value attribute would keep unchanged. When I do simulation again, Dymola would NOT use the parameter's start attribute, it would still use the parameter's value attribute. After I change the value attribute manually, there would be no error anymore.
I have a pool of 25 agents (Operators). When an Order is generated, I seize a few Operators and move them to one of many different ProductionSuites as determined by a parameter in the Order.
Within the ProductionSuite, I have a variable of type ResourcePool that I would like to use to have these Operators perform tasks.
In the main window, I put this code in the "On seize unit:" code box:
agent.assignedSuite.suiteOperatorPool.addAgentToContents(unit);
but this triggers a NullPointerException error. Am I using the addAgentToContents method incorrectly?
You have not initialized your suiteOperatorPool variable, it's "initial value" field is empty. Hence, this is just an empty shell of type ResourcePool that cannot do anything, including adding agents to it.
You would need to initialize it properly using the ResourcePool API, but I don't think that is possible.
Also, you cannot have resources be part of 2 resource pools, as you are trying to do. You should think of a different way to solve your problem. Maybe rephrase the issue so we can think of alternatives. You might not need a RP at all but just use pure agent functionality...?