I am working on a university project with Anylogic version 8.1. We have to use this version because the university license covers Anylogic only up to this version.
In this project our task is to model a order picking system with 12 order picking stations. Four stations are connected with each other via a circuit so that three areas are formed. Those three areas are also connected via a circuit. A order gets injected and ejected at two different points in the main circle. It then can move into the smaller circles to visit stations.
Therefore each instance of (agent) type Order has the following properties:
A Station can take up to 3 orders: one being processed on a delay block and two on the conveyor.
A Station is entered from the circle, which connects four stations. This circle is named SubArea:
This sub area has also a limit of orders it can take. Orders are guided by the selectOutput Blocks: the first four are calling the select_output_branch function and the last one is calling the select_output_exit function.
if(!order.stations_to_visit.isEmpty() && order.next_station == station && station.number_of_orders < station.max_number_of_orders) {
return false;
} else {
return true;
}
if(order.stations_to_visit.isEmpty() || order.next_station.subArea != sub_area) {
return true;
} else {
return false;
}
The big circle is called Area and looks like that:
As in the SubArea, the order is routed by selectOutput blocks. The first three again use the select_output_branch function and the last uses the select_output_exit function.
if(!order.stations_to_visit.isEmpty() && order.next_station.subArea == sub_area && order.next_station.subArea.number_of_orders < order.next_station.subArea.max_number_of_orders) {
return false;
} else {
return true;
}
if(order.stations_to_visit.isEmpty()) {
return true;
} else {
return false;
}
In every enter and delay block forced pushing is disabled.
The Main includes an instance of the Area agent and an instance of the Flow Controller:
The FLowController is where the creation, injection and next_station selection happens.
The creation process of the Orders is as follows: A source creates based on a schedule (order_load) at discrete time moments (e.g. 10:00) a specified number of orders. Those get added to the default population and onExit the generate_new_stations_to_visit function is called. This functions takes a random number of all stations and sets them as stations_to_visit by the order and sets the orders next station to the first element of stations_to_visit. After that the order exits on on that moment it moves to the population orders_to_inject.
The injection of orders in the area happens via the injection_event. This calls the inject_order function.
// Check if there is a order to inject available && if area has capacities left
if(!orders_to_inject.isEmpty() && injected_orders.size() < max_injected_orders) {
// Select order to inject
Order order_to_inject = orders_to_inject.random();
// Move to injected orders
order_to_inject.goToPopulation(injected_orders);
// Select first station to visit
select_next_station_to_visit(order_to_inject);
// Inject to area entry
main.area.enter_flow_controller.take(order_to_inject);
}
The function visited_station gets called by the delay block in the station:
// Check if the correct station was visited
if(order.next_station == station) {
// Move station to visited stations
order.visited_stations.add(station);
order.stations_to_visit.remove(station);
// Select next station
select_next_station_to_visit(order);
} else {
System.out.println("Visited wrong station");
}
And the selcet_next_station to visit does the following:
// If any stations to visit are left
if(!order.stations_to_visit.isEmpty()) {
// Set next station
order.next_station = order.stations_to_visit.get(0);
}
After a order leaves the area it gets moved to the population finished orders.
Thats it for the model so far:
During runtime a NullPointerException occurs:
Exception during discrete event execution:
NullPointerException
at com.anylogic.libraries.processmodeling.Conveyor.e(Unknown Source)
at com.anylogic.libraries.processmodeling.Conveyor.b(Unknown Source)
at com.anylogic.libraries.processmodeling.Conveyor$5.onExit(Unknown Source)
at com.anylogic.libraries.processmodeling.Delay.d(Unknown Source)
at com.anylogic.libraries.processmodeling.Delay.b(Unknown Source)
at com.anylogic.libraries.processmodeling.Delay$6.onExit(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.e(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBuffer$1.onExit(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.d(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$1.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.a(Unknown Source)
at com.anylogic.libraries.processmodeling.InPort.receiveImmediately(Unknown Source)
at com.anylogic.libraries.processmodeling.InputBlock$1.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutPort.b(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.c(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$2.a(Unknown Source)
at com.anylogic.libraries.processmodeling.OutputBlock$2.action(Unknown Source)
at com.anylogic.libraries.processmodeling.AsynchronousExecutor_xjal.executeActionOf(Unknown Source)
at com.anylogic.engine.EventTimeout.execute(Unknown Source)
at com.anylogic.engine.Engine.d(Unknown Source)
at com.anylogic.engine.Engine.nd(Unknown Source)
at com.anylogic.engine.Engine.f(Unknown Source)
at com.anylogic.engine.Engine$e.run(Unknown Source)
Here is what i have done so far to solve this:
Anyways, all this narrowed the problem down to: When i remove the routing logic from the select Output Blocks the problem does not occur. When i put it back in the error occurs again.
EDIT: When i remove the routing logic (select_ouput_branch and select_output_exit) only from the subarea and change it to random(0.5) the error doesn't occur.
Thank you for your time and effort. I am glad if someone could help.
EDIT: I build a third model, with no logic at all, just anylogic blocks and default agents in the main:
The NullPointer still occurs. Might this be an Anylogic bug?
I finally found the solution.
It seems like anylogic cant handle to many agents / orders on one conveyor. E.g. when a conveyor has a length of 1.5 meters and it can take up to two agents, which is kinda confusing and causes the NullPointer.
So i wrapped each conveyor in a restricted area and it works :)