Back to Documentation Overview

In-Depth Delivery with Dispatch

Today we'll be walking through a delivery example that highlights the Dispatch API's inventory, automatic reassignment, and capacity capabilities. In this example, we'll walk through a delivery use case that supports both mobile warehouses as well as on-demand delivery. For simplicity's sake, our example will only include one vehicle and two tasks, but this approach scales for a larger fleet and customer base.

This is the scenario we'll walk through today:

  1. Initialize fleet and vehicles.
  2. A driver comes online and adds their vehicle to a fleet. The driver has already loaded their car with common items from grocery stores (apples in this case) to act as a mobile warehouse.
  3. A customer orders a dozen apples for home delivery.
  4. rideOS assigns the driver to said delivery task. Since the driver's vehicle already contains apples the driver is automatically routed straight to the customer's home for dropoff.
  5. A different customer orders sushi for delivery to their office. The driver must go pick up the sushi from the restaurant.
  6. rideOS' optimization algorithm calculates the ideal route that minimizes travel time, rerouting the driver to pick up the sushi before completing the first customer's delivery.
  7. After completing steps along their path, the driver marks said steps as completed.

Building a system that is able to dynamically handle this amount of complexity for a delivery service is a non-trivial task, but with Dispatch all it takes is a few API calls.

Note: Generic vs. Unique Resources The example fleet we'll be using today handles both mobile warehouse and on-demand delivery. The discrepancy between mobile warehouse and on-demand items highlights the difference between "generic resources" and "unique resources". For more information on resources and types of resources, please refer to this guide on generic and unique resources.

Prerequisite: Get the API Key

To run this example, you will need a rideOS API Key. You can sign up for one here and view it on your profile page.

Once you have the API Key, you can set the environment variable with export RIDEOS_API_KEY="YOUR_API_KEY" and use RIDEOS_API_KEY in the cURL commands given below.

Initializing the Fleet/Vehicle/Resources

We'll begin by initalizing our fleet for this example.

curl --request POST https://api.rideos.ai/dispatch-fleets/v3/CreateFleet \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "fleet": {
    "fleetId": "exampleFleet",
    "displayName": "delivery_fleet",
    "optimizationSettings": {
        "enableVehicleReassignment": true,
        "optimizationProfile": {
          "value": "GOODS"
        }
    }
  }
}'

After initializing our fleet, we'll create the generic resources our vehicle can carry - in this case it'll be apples that take up a smallItem capacity.

curl --request POST https://api.rideos.ai/dispatch-resources/v3/CreateGenericResource \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "resource": {
    "resourceId": "apple",
    "requiredCapacities": [
      {
        "capacityType": "smallItem",
        "value": 1
      }
    ]
  }
}'

Once our fleet and resources have been created, we'll initialize our vehicle, making sure to include it's starting position, capacity, initial state, and inventory of generic resources.

curl --request POST https://api.rideos.ai/dispatch-vehicles/v3/CreateVehicle \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "vehicle": {
    "vehicleId": "exampleVehicle",
    "fleetId": "exampleFleet",
    "vehicleCapacities": [
      {
        "capacityType": "smallItem",
        "value": 72
      },
      {
        "capacityType": "meal",
        "value": 36
      }
    ],
    "inventory": {
      "resources": [
        {
          "resourceId": "apple",
          "count": 36
        }
      ]
    }
  },
  "initialPosition": {
    "position": {
      "position": {
        "latitude": 37.788897,
        "longitude": -122.389669
      },
      "heading": 0
    },
    "enforceMatch": true
  },
  "initialVehicleState": {
    "acceptingAssignments": true
  }
}'

Note: Capacity The dispatch API allows you to assign certain capacities to each vehicle. These capacities could range from things like seats to the number of meals a vehicle can hold. In this example, the vehicle will have two capacities, one for the number of non-perishable small items, and one for the number of fresh meals the vehicle can hold.

Requesting a Task

Next we'll request a task, in this case a customer will request a delivery of a dozen apples. Since the delivery vehicle already has apples stocked as a mobile warehouse, there is no pickup necessary and the vehicle can go straight to delivery.

curl --request POST https://api.rideos.ai/dispatch-tasks/v3/CreateTask \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
    "taskId": "exampleTask1",
    "fleetId": "exampleFleet",
    "taskDefinition": {
      "pickupDropoffTask": {
        "genericResourcePickup": {
          "genericResourceGroup": {
            "genericResources": [{
                "resourceId": "apple",
                "count": 12
              }
            ]
          }
        },
        "dropoff": {
          "position": {
            "latitude": 37.792386,
            "longitude": -122.412877
          }
        }
      },
      "dispatchParameters": {
        "poolingSetting": "POOLED"
      },
      "requestorId": "exampleRequestor1"
    }
  }'

We'll then request another task, this time the customer is requesting a unique resource (sushi) from a restaurant so there will have to be a pickup before the resource is dropped off.

curl --request POST https://api.rideos.ai/dispatch-tasks/v3/CreateTask \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
    "taskId": "exampleTask2",
    "fleetId": "exampleFleet",
    "taskDefinition": {
      "pickupDropoffTask": {
        "uniqueResourcePickup": {
          "pickupLocation": {
            "position": {
              "latitude": 37.789100,
              "longitude": -122.407130
            }
          },
          "uniqueResource": {
            "requiredCapacities": [
              {
                "capacityType": "meal",
                "value": 1
              }
            ]
          }
        },
        "dropoff": {
          "position": {
            "latitude": 37.79290,
            "longitude": -122.412880
          }
        }
      },
      "dispatchParameters": {
        "poolingSetting": "POOLED"
      },
      "requestorId": "exampleRequestor2"
    }
  }'

Note: Automatic Fleet Reassignment With the Dispatch API, anytime a new event occurs (a driver/vehicle comes online, a task is created/finished), your fleet is automatically updated to most optimally handle the state of the world. In this example, this means that when the sushi delivery task is added, the driver's plan is updated accordingly with steps to pickup and dropoff.

Getting Driver Plan and ETAs

Along the way, it might be necessary to get the steps that the driver needs to take in order to complete their assigned task. It could also be helpful to pull ETAs for each of these steps in order to estimate completion times.

curl --request POST https://api.rideos.ai/dispatch-vehicle-eta/v3/GetVehicleStepEtas \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
    "vehicleId": "exampleVehicle"
}'

There are also a host of other endpoints that allow you to access different aspects of a vehicle's state, capacity, and inventory as well as info about the current state of your fleet. More information about the availabile endpoints can be found in the Dispatch API reference.

Completing a Task

All that's left now is for the driver to proceed along the path they were assigned to. Every time a step has been completed (driving to pick-up/drop-off locations, loading/unloading resources), the step must be marked as completed in order to update the state of the fleet.

curl --request POST https://api.rideos.ai/dispatch-tasks/v3/CompleteSteps \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "taskId": "exampleTask1",
  "stepToComplete": [
    {
      "stepId": "EXAMPLE_TASK_ID",
      "timeOfCompletion": "2020-08-06T17:04:57Z"
    }
  ]
}'

That's about it! We have successfully created a delivery service that works both with mobile warehouse and on-demand delivery usecases at the same time with just a few API calls. You may also want to: