All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opentcs.strategies.basic.dispatching.rerouting.AbstractDriveOrderMerger Maven / Gradle / Ivy

/**
 * Copyright (c) The openTCS Authors.
 *
 * This program is free software and subject to the MIT license. (For details,
 * see the licensing information (LICENSE.txt) you should have received with
 * this copy of the software.)
 */
package org.opentcs.strategies.basic.dispatching.rerouting;

import static java.util.Objects.requireNonNull;

import jakarta.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.opentcs.components.kernel.Router;
import org.opentcs.data.model.Path;
import org.opentcs.data.model.Vehicle;
import org.opentcs.data.order.DriveOrder;
import org.opentcs.data.order.Route;
import org.opentcs.data.order.TransportOrder;
import org.opentcs.strategies.basic.routing.ResourceAvoidanceExtractor;

/**
 * An abstract implementation of {@link DriveOrderMerger} defining the basic merging algorithm.
 */
public abstract class AbstractDriveOrderMerger
    implements
      DriveOrderMerger {

  private final Router router;
  private final ResourceAvoidanceExtractor resourceAvoidanceExtractor;

  /**
   * Creates a new instance.
   *
   * @param router The router to use.
   * @param resourceAvoidanceExtractor Extracts resources to be avoided from transport orders.
   */
  protected AbstractDriveOrderMerger(
      Router router,
      ResourceAvoidanceExtractor resourceAvoidanceExtractor
  ) {
    this.router = requireNonNull(router, "router");
    this.resourceAvoidanceExtractor
        = requireNonNull(resourceAvoidanceExtractor, "resourceAvoidanceExtractor");
  }

  @Override
  public DriveOrder mergeDriveOrders(
      @Nonnull
      DriveOrder orderA,
      @Nonnull
      DriveOrder orderB,
      @Nonnull
      TransportOrder originalOrder,
      int currentRouteStepIndex,
      Vehicle vehicle
  ) {
    requireNonNull(orderA, "orderA");
    requireNonNull(orderB, "orderB");
    requireNonNull(originalOrder, "originalOrder");

    return new DriveOrder(orderA.getDestination())
        .withState(orderA.getState())
        .withTransportOrder(orderA.getTransportOrder())
        .withRoute(
            mergeRoutes(
                orderA.getRoute(),
                orderB.getRoute(),
                originalOrder,
                currentRouteStepIndex,
                vehicle
            )
        );
  }

  /**
   * Merges the two given {@link Route}s.
   *
   * @param routeA A route.
   * @param routeB A route to be merged with {@code routeA}.
   * @param originalOrder The transport order to merge the drive orders for.
   * @param currentRouteStepIndex The index of the last route step travelled for {@code routeA}.
   * @param vehicle The {@link Vehicle} to merge the routes for.
   * @return The (new) merged route.
   */
  protected Route mergeRoutes(
      Route routeA,
      Route routeB,
      TransportOrder originalOrder,
      int currentRouteStepIndex,
      Vehicle vehicle
  ) {
    // Merge the route steps
    List mergedSteps = mergeSteps(
        routeA.getSteps(),
        routeB.getSteps(),
        currentRouteStepIndex
    );

    // Calculate the costs for merged route
    return new Route(
        mergedSteps,
        router.getCosts(
            vehicle,
            mergedSteps.get(0).getSourcePoint(),
            mergedSteps.get(mergedSteps.size() - 1).getDestinationPoint(),
            resourceAvoidanceExtractor
                .extractResourcesToAvoid(originalOrder)
                .toResourceReferenceSet()
        )
    );
  }

  /**
   * Merges the two given lists of {@link Route.Step}s.
   *
   * @param stepsA A list of steps.
   * @param stepsB A list of steps to be merged with {@code stepsA}.
   * @param currentRouteStepIndex The index of the last route step travelled for {@code stepsA}.
   * @return The (new) merged list of steps.
   */
  protected abstract List mergeSteps(
      List stepsA,
      List stepsB,
      int currentRouteStepIndex
  );

  protected List updateRouteIndices(List steps) {
    List updatedSteps = new ArrayList<>();
    for (int i = 0; i < steps.size(); i++) {
      Route.Step currStep = steps.get(i);
      updatedSteps.add(
          new Route.Step(
              currStep.getPath(),
              currStep.getSourcePoint(),
              currStep.getDestinationPoint(),
              currStep.getVehicleOrientation(),
              i,
              currStep.isExecutionAllowed(),
              currStep.getReroutingType()
          )
      );
    }
    return updatedSteps;
  }

  protected List stepsToPaths(List steps) {
    return steps.stream()
        .map(step -> step.getPath())
        .collect(Collectors.toList());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy