Step 13: Avoiding obstacles. Recalculate routes on the fly.
So, how can we "convince" our forklifts to dynamically circumvent the pallets that appear in their way?
Let’s try to recalculate the routes of all moving forklifts every time a pallet place becomes occupied.
1. Recalculation of forklifts' routes
Let’s add the following method:
...
public void rerouteAgents() {
getAgents().stream()
.filter(a -> a.hasPath())
.forEach(a -> a.moveTo(a.getGraphPath().getLastNode(), a.getVelocity()));
}
...
2. Running the recalculation
In order to invoke this method, we need the ability to access the EnvironmentWithPallets
instance.
So, let’s store it in Node
objects:
...
private final EnvironmentWithPallets graphEnvironment;
public EnvironmentWithPallets getGraphEnvironment() {
return graphEnvironment;
}
...
public Node(Point point, EnvironmentWithPallets graphEnvironment, String id) {
super(point);
this.graphEnvironment = graphEnvironment;
this.id = id;
}
...
Now we can update the placePallet()
method of the PalletPosition
class (we add the rerouteAgents()
call here):
...
public void placePallet(boolean loading) {
if (busy == loading) {
throw new RuntimeException("Can't " + (busy ? "put to a busy" : "take from a free") + " position");
}
busy = loading;
reserved = false;
node.getGraphEnvironment().rerouteAgents();
onBusyCallbacks.get(busy).ifPresent(callback -> callback.accept(this));
}
...
We see that the Model.java
class is not compiling anymore.
To fix it, add the graphEnvironment
parameter to the Node
class constructor call:
...
public Node addNode(Point point, String id) {
Node node = new Node(point, graphEnvironment, id);
graphEnvironment.addNode(node);
return node;
}
...
3. Final result
Let’s run the simulation now… Forklifts have now become aware of all pallets appearing in their way. Now we can be confident that the precious cargo in our pallets is safe.
4. Side note
The "dynamic routing" we implemented in this step works perfectly for our scenario. However, we should keep in mind that the computational complexity of this algorithm is:
agents_count * graph_size * frequency_of_pallets_placement
This can be too high in bigger scenarios. Thus, for bigger scenarios, we might need a more sophisticated solution. However, such a solution goes far beyond the scope of this tutorial.