Skip to content

Important concepts

The plan state

The Plotwise API plan has states. This means the plan has states and flows. It is really important the client is aware of it to make sure the requests sent are the ones allowed in a certain state.

You can find more state-related information in the flow section of the documentation and each entity state diagram in its reference page. E.g: Buckets state.

Tentative plan

A tentative plan is a valid plan available at every given time. It can be used to drive on, estimate the number of Routes for the final planning and makes it possible to check if specific deliveries can be delivered within a specific time slot.

It is however strongly recommended to take a look at the sequence diagram and the examples.

Non-Finalized Buckets

A regular cleanup task automatically cancels any non-finalized buckets (buckets in the open planning phase) whose due date is older than 2 days and newer than 7 days from the time of the cleanup.

Intermediate depots

Intermediate Depots are introduced in v2. The aim is to ensure that the maximum shift time is utilised and that resources are more efficiently used.

An intermediate depot is a dynamically inserted depot visit in the middle of a route. This additional depot visit breaks a single route down into multiple trips. A trip is a sequence of events where the first and last events are depot-like events (departure depot, arrival depot or intermediate depot), while all events between the first and last are deliveries. A route is therefore comprised of one or more trips (the number of trips in a route equals to 1 + the number of intermediate depots scheduled in it).

Trips exist so that the vehicle can reload and perform more deliveries within a given shift length. The following diagram illustrates the concept of Intermediate Depots:

To govern the addition of intermediary depots the following configuration parameters are set up at route creation.

  • intermediate_depot_duration: The work time expended at that intermediate depot, i.e., its "stop time".
  • capacity_threshold: This parameter is partially deprecated. It used to refer to the minimum used capacity ratio (used versus total) in a route for it to be considered for splitting (intermediary depot insertion). Currently, this value only needs to be filled with a value != 1.0 for the route to be considered for splitting.
  • time_threshold: This parameter is partially deprecated. It used to refer to the maximum used capacity ratio (used versus total) of work time for a route to be considered for splitting (intermediary depot insertion). Currently, this value only needs to be filled with a value != 0.0 for the route to be considered for splitting.
  • minimum_trip_length: This parameter is deprecated. It used to refer to the minimum work time duration a trip must have (in seconds) for it to be created (during an intermediate depot insertion) and continue to exist.

Intermediate depots are scheduled as needed in order to fit events into routes. If adding a certain event to a route will cause its vehicle's capacity to be exceeded, an intermediate depot (reload) stop will be planned in order to fit the event, assuming that the route still has time to perform the intermediate depot (including the additional required drive time to/from the depot, and the extra intermediate_depot_duration), and assuming the driver_capacity of the resource is not exceeded by the addition of the event.

Enable Intermediate Depots

To enable Intermediate Depots, it is mandatory to set intermediate_depot_duration, capacity_threshold and time_threshold upon Route creation and vehicle_capacity upon Resource creation.

Find more information about these entities in the Route, Resource and Event reference pages.

Intermediate depots examples

You can also find intermediate depots examples in here

Specifying Locations for Breaks

Routes can contain breaks to provide drivers with mandatory periods of rest at a defined interval. By default, the driver is assumed to be taking the breaks in their vehicle. This means that the location of the break will be the same as the location of the event preceding or succeeding the break. However, it is possible to specify a location for the break to be taken at. In this case, the planning will also take the time of travel to and from the break location into consideration when planning the break. To define a break, pass a geolocation when creating a route. You can read more about routes here.

Multiple Capacities

Originally only a single metric could be used to specify the capacity of an event and limit the capacity per trip (vehicle_capacity) and route (driver_capacity). With multiple capacities, it is possible to specify up to 5 different metrics. The interpretation of each metric is up to the customer but must be the same for every usage of capacities. Examples of used interpretations are weight (in kilograms) and volume (in liters).

Assignment of resources to routes and prioritization of routes

Resources are assigned to routes based on vehicle_capacity - bigger vehicles are assigned to longer routes (based on the time between the first and last timeslot_windows of the route).

In the case of multiple capacities with a vehicle_capacity_vector, the definition of "bigger" is based on the order capacity_1 -> capacity_2 -> ... -> capacity_5. For example, if a vehicle has a higher capacity_1 than another vehicle, it will be considered "bigger" regardless of the value of capacity_2.

This behavior is respected when events are added to the planning, and maintained throughout the continuous planning, except when events are cancelled in a way that empties a long route.

This can be utilized to prioritize longer shifts in the planning - if there are as many large vehicles as there are long routes, the longer routes will be prioritized over shorter routes.

Resource route pairing

By default, any resource can be assigned to any route as long as capacity restrictions are respected. It is possible to explicitly pair one or more resources with one or more routes. This can, among others, be used to assign vehicles to routes starting from a specific depot.

When a resource has a resource_route_tag, it is only assigned to a route with a matching resource_route_tag. Resources and routes without tags are matched to each other. The prioritization rules explained in the section above are applicable within the set of matching resources and routes.

Tags are case-sensitive strings that cannot be longer than 32 characters and that can only contain letters (a-z), numbers, underscores, and hyphens. The field is optional, but if it is included in the request body, it cannot be left blank.

Resource-event and Route-event pairing

By default, events can be paired up with any resource and any route in the bucket. Tags can be assigned to events, routes and resources to change that behavior. When tagged, events will only be assigned to routes and resources that contain all of the tags present on an event. For maximum flexibility, route pairing and resource pairing are separate lists of tags.

Resource-event and route-event pairing can be used to indicate if certain deliveries can only be made for a specific subset either, such as requiring a driver with installation skills or a vehicle with a tailgate. Events with no matching resource or route will be returned as no-fits.

Tags are case-sensitive strings that cannot be longer than 32 characters and that can only contain letters (a-z), numbers, underscores, and hyphens. The field is optional, but if it is included in the request body, it cannot be left blank. There can be no more than 5 tags in each set of tags.

Freezing ETAs

Freezing ETAs guarantees that events stay within a given delivery window, even as the planning continues to be optimized and other events are being added. This mechanism could allow the user to freeze the bucket at a certain time in the evening and send emails to the end-customers containing the expected delivery window, while still allowing additional changes to the buckets and the planning

In order to make use of this functionality, one needs an initialized bucket with some events planned in it. Such buckets can be transitioned into a frozen state by calling /buckets/{UUID}/action endpoint with freeze action along with two parameters seconds_before_eta and seconds_after_eta, see examples section for details. This call creates, separately for every event, a restriction for the possible placement of events ETAs - a restriction that behaves similarly to approved suggestion windows. This restriction is calculated to be [eta - seconds_before_eta, eta + seconds_before_eta] (where eta is the event ETA at the time of freezing the bucket), with some additional logic in edge cases where this window goes out of the range of the event min/max times or the selected timeslot. The calculated window is stored in the frozen_window field of events.

After triggering freeze the bucket is moved into a frozen state. Because of this new state, the initialized state is no longer the only bucket state in which adding events is possible. To make it easy to find buckets that can be modified, the bucket entity was extended with a new query param: mutable (see examples section for usage).

Suggestions approved after freezing take precedence over the frozen window: such events will behave as if they were never frozen.

Freezing can be performed only on an initialized bucket, a bucket that is already frozen cannot be frozen again.

Planning profiles

The planning profiles is one of the attributes responsible for defining the behaviour of the bucket when processing and building the planning. In particular, planning profiles can be used to define a transport modality and/or specific parameters for a given depot area.

For instance, there can be one profile for bike and another for truck, but there can also be several profiles for bikes depending on different areas of service.

Profiles are customised to your needs, when getting access to the Plotwise service, you will be asked for information about your daily operations. This information will be used to generate a set of profiles that will fit your needs and make sure the plan is optimal.

You can find examples for planning profiles in here.

Feature flags

Feature flags are definitions within the planning profile, used to alter the behaviour of the bucket. By default, they are always false.

The following feature flags are available for configuration:

allow_increased_reload_stops

By default, the maximum number of intermediate depots in a route is limited to be 2. This number can be increased to 3 by setting the allow_increased_reload_stops feature flag to true.

  • When changing a profile's false into a true (i.e. to change a limit of 2 reload stops to 3 reload stops), all routes in the bucket will be able to use 3 reload stops.
  • When changing a profile's true into a false (i.e. to change a limit of 3 reload stops to 2 reload stops), only newly-added routes will have a limit of 2 reload stops. Older routes will still have a limit of 3.

special_ev_add_event

With the inclusion of the maximum_route_distance_meters for resources, resources with an unlimited maximum route distance might get filled before ones that have a limited maximum route distance. In that case, events that are far away from the depot might often become no-fits, as they cannot be reached by a resource with a limited driving distance.

This behavior can be altered by setting the special_ev_add_event feature flag to true. When set to true, before declaring a new event to be a no-fit, the planning will try to move some events from an unlimited-distance resource to a limited-distance resource in an attempt to provide enough room for the new event to fit in the planning. If the new event still does not fit in the planning, it will be declared a no-fit.

Timeslots, min/max times, and suggestion timeslots

Tip

In this section, and in general in this documentation, "timeslot" and "window" mean the same thing, a min_time and a max_time. A time respects a timeslot/window if min_time <= time <= max_time.

The eta of an event determines when the event is expected to start. There are several data fields that limit the eta of events, especially deliveries and depots. The following behavior is guaranteed:

Depot etas will always be respect:

  • The min_time and max_time from the departure_stop (for the first depot) and the arrival_stop (for the last depot) in the route's algorithm_fields.
  • The min_time and max_time from the route's first timeslot_window (for the first depot) and the route's last timeslot_window (for the last depot).

Delivery etas will always respect:

  • The event min_time and max_time from the event itself.
  • The min_time and max_time from the selected_timeslot within the algorithm_fields (if any). This field is filled when a suggestion has been picked and approved, based on the timeslot of that suggestion.
  • The min_time and max_time from the frozen_window within the algorithm_fields (if any). This field is filled when the bucket has been frozen.
  • In addition, when an event is assigned to a specific route, the etas will never be within the min_time and max_time of the first or the last timeslot_windows of that route. This is because these two timeslots are reserved for vehicle loading/unloading and for driving.

There are several gotcha's that related to these limitations: * The time limitations only apply to the eta itself. The end of the event (which is eta + stop_time) does not have to adhere to any of the rules described above. * The middle timeslots within the route's timeslot_windows are values that do not impact anything, they are validated for correctness and then ignored. (They used to have meaning, and an impact on performance, but do not anymore). * If there is a gap between the max_time of the departure_stop and the min_time of the arrival_stop, this translates to "the driver is not allowed back at the depot until the arrival_stop's min_time, even if that driver is done with deliveries and waiting at the parking lot". Effectively, this means that optimization will struggle with finding better solutions, because there is no advantage to letting the driver arrive at the depot earlier in the day. * To avoid confusion, timeslots whose min_time and max_time do not fully fit within the event's min_time and max_time are not considered to be valid for suggestions, and will never be given in the return values of the suggestion request.

That last gotcha deserves a practical example:

In theory, when an event has min/max_times and a selected timeslot, the eta of that event will adhere to the most restrictive limitation. For example, an event with business hours limitations (min_time = 9:00, max_time = 17:00) and an afternoon selected timeslot (12:00-18:00) will be guaranteed by the code to have an eta between 12:00 and 17:00.

However, in reality, allowing such suggestions could create a lot of confusion - If a customer has the limitation of business hours and then gets a timeslot of 12:00-18:00, they might worry that they'll get their delivery at 17:30 (when the office is closed). To avoid this confusion, any timeslot that does not fit fully within the event's min/max_times is not considered valid and will not be returned as a possible suggestion.

This means that the afternoon timeslot of 12:00-18:00 will never be possible to be selected for a business-hour event. To work around this limitation, any timeslot sent in the suggestion request should be changed so that it's completely contained within the event's min/max_times. Namely, in this case, the morning timeslot should be 9:00-12:00 (instead of 7:30-12:00), and the afternoon timeslot should be 12:00-17:00 (instead of 12:00-18:00).