Font size

Custom routing

Transporters with path-guided navigation move from one point to another by following the chosen route. The routing information is stored in the RouteData object. It contains a series of movement tasks. Each task describes transporter's movement along a single segment of the route. The segment ends when the type of movement changes. There are three types of movement:

This type of object is returned by the findShortestPath() function used to specify the transporter's route, and by the getRouteData() function used to obtain the details of the previously specified route.

Example of custom routing

Demo model: Custom Routing for Transporters Open the model page in AnyLogic Cloud. There you can run the model or download it (by clicking Model source files).

In this example, we will demonstrate how to specify a custom route for a transporter (AGV).

We have simulated the transfer of material items between two nodes, which are connected by three paths of noticeably different lengths. In the process diagram this transfer is defined by the MoveByTransporter block from the Material Handling Library.

The items are transferred from node1 to node2 by a single AGV which is defined by the TransporterFleet block. We use the TransporterControl block to specify the rules of movement for the AGV. The Navigation parameter in its properties is set to Custom: this way we can specify our own routing algorithm for the AGV.

This algorithm is described in the custom setRoute(source, target, unit) function. We switch the Find path parameter of the TransporterControl block to the dynamic value editor and place the call of the custom function there.

The function must return the RouteData object, therefore in the function's properties we have selected the Returns value option and specified the RouteData in the Type field. In the Arguments section we have set the following arguments:

The function is used for routing and is called each time the AGV starts its movement.

Here is the routing algorithm we have created for this example:

//check the AGV's current state
  if (agv.getState() == TransporterState.DELIVERING)
    switch (radio.value)
      case 0:
        //use the default routing
        return transporterControl.findShortestPath(source, target, null, null);
      case 1:
        //use the default routing with the specified path(s) excluded
        Path[] avPaths = {path1};
        //avPaths list passes the excluded paths to the routing algorithm
        return transporterControl.findShortestPath(source, target, null, avPaths);
      case 2:
        //create data structure to store the custom route
        RouteData route = new RouteData();

        //define the 1st movement task, from node1 center to node1 border
        Point source1 = new Point(100.0, 100.0, 0.0);
        Point target1 = new Point(100.0, 110.0, 0.0);
        route.addPlainMovement(node1, source1, target1);

        //the 2nd movement task along path2
        route.addPathMovement(path2, 0.0, 78.0, METER);

        //the 3rd task, inside node2
        Point source2 = new Point(700.0, 110.0, 0.0);
        Point target2 = new Point(700.0, 100.0, 0.0);
        route.addPlainMovement(node2, source2, target2);

        return route;
        return null;
  //use the shortest path to return to home location
  else return transporterControl.findShortestPath(source, target, null, null);

In this example, you can choose one of three routing policies using the radio buttons control. We utilize the switch statement in the algorithm to specify one delivery route per button. The integer value used for each case is the index of the corresponding radio button.

The index is zero-based, so the index of the first button is 0.

The statement contains three cases.

Using the default route

By default, the transporters in AnyLogic select the shortest route to target. In this example, the AGV uses the shortest path as the delivery route if the Default routing (shortest route) radio button is selected.

We set this route by calling the findShortestPath() function of the TransporterControl block and passing the following arguments:

Excluding paths / nodes from the default route

You may need to create a custom route for the transporter where it will avoid certain paths or nodes, but still select the shortest way to the destination. In this example, when the Exclude path1 radio button is selected, we tell the AGV to find the shortest delivery route which must exclude path1.

First, we create a local variable avPaths (an array of Path elements). In our example it stores just one path, path1. To specify several paths, list them comma-separated inside the curly brackets.

Path[] avPaths = {path1};

Then we call the findShortestPath() function again, but this time we pass our local variable avPaths as the last argument to exclude from the route.

return transporterControl.findShortestPath(source, target, null, avPaths);

AnyLogic also provides an option to include certain paths in the custom route with the help of the findShortestPath(ILocation source, ILocation target, Node[] nodesToAvoid, Path[] pathsToAvoid, Path[] pathsToInclude) function.

Creating the custom route with RouteData

You can create the transporter's route from scratch by manually defining all the necessary movement tasks that will be stored in the RouteData object. This approach gives you the most control over the transporter's movement.

In this example we use this approach to define the AGV's delivery route along path2. This delivery route is used when we select the Custom route radio button.

First, we declare the new RouteData object:

RouteData route = new RouteData();

Next, we define the first movement task: PLAIN type of movement from the center of node1 to the point of connection between node1 and path2.

We define two local variables to store the movement start point (source1) and end point (target1). The arguments pass X-, Y-, Z- coordinates of the point. We set source1 to store the node1 center point, and target1 — the connection point of the node1 and path2.

Point source1 = new Point(100.0, 100.0, 0.0);
Point target1 = new Point(100.0, 110.0, 0.0);

We use the addPlainMovement() function of the RouteData to define the movement task and add it to the route.

route.addPlainMovement(node1, source1, target1);

The function has the following arguments:

  • The network element where the movement takes place;
  • The start point of the movement;
  • The end point of the movement.

The second movement task describes the PATH type of movement along path2:

route.addPathMovement(path2, 0.0, 78.0, METER);

To add the PATH movement task to the route, we use the addPathMovement() function of the RouteData.

The function has the following arguments:

  • The path where the movement takes place;
  • The distance between the point on the path where the movement begins to the starting point of the path. In this case the movement begins in the starting point, therefore we pass the 0.0 value.
  • The distance between the point on the path where the movement ends to the starting point of the path. The length of the path must be specified in the given length units. In this example we calculate the length of the path in meters. At the default scale of 1 meter to 10 pixels, the length of path2 is 78 meters.
  • The length unit constant.

The third movement task describes the PLAIN type of movement from the point of connection between path2 and node2 to the center of node2.

Setting up the return route

The algorithm tells the AGV to select the shortest route every time it returns to its home location. This is executed by using the if statement and checking the current state of the AGV: if the AGV is delivering the material item, it follows the chosen routing policy described above. In any other state it uses the shortest route set up with the help of findShortestPath() function.

//check the AGV’s current state
  if (agv.getState() == TransporterState.DELIVERING)

  { //the section of code that describes the delivery routing policy }

  else return transporterControl.findShortestPath(source, target, null, null);
How can we improve this article?