diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java index 3fef9b0c932..b2abd66b16f 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/prebooking/PrebookingStopActivity.java @@ -68,7 +68,7 @@ public PrebookingStopActivity(PassengerHandler passengerHandler, DynAgent driver @Override protected boolean isLastStep(double now) { - return updatePickupRequests(now) && leaveTimes.size() == 0 && now >= endTime.get(); + return updatePickupRequests(now) && processDropoffRequests(now) && now >= endTime.get(); } @Override @@ -86,7 +86,7 @@ private void initDropoffRequests(double now) { processDropoffRequests(now); } - private void processDropoffRequests(double now) { + private boolean processDropoffRequests(double now) { var iterator = leaveTimes.entrySet().iterator(); while (iterator.hasNext()) { @@ -98,6 +98,8 @@ private void processDropoffRequests(double now) { iterator.remove(); } } + + return leaveTimes.size() == 0; } private boolean updatePickupRequests(double now) { @@ -154,12 +156,9 @@ public void notifyPassengersAreReadyForDeparture(List pass queuePickup(request, now); } - private AcceptedDrtRequest getRequestForPassengers(List> passengerIds) { - return pickupRequests.values() - .stream() - .filter(r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) - .findAny() - .orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); + return pickupRequests.values().stream().filter( + r -> r.getPassengerIds().size() == passengerIds.size() && r.getPassengerIds().containsAll(passengerIds)) + .findAny().orElseThrow(() -> new IllegalArgumentException("I am waiting for different passengers!")); } } diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/stops/PrebookingStopTimeCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/stops/PrebookingStopTimeCalculator.java index 1eee457066d..f4dad777fed 100644 --- a/contribs/drt/src/main/java/org/matsim/contrib/drt/stops/PrebookingStopTimeCalculator.java +++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/stops/PrebookingStopTimeCalculator.java @@ -50,17 +50,14 @@ public double initEndTimeForDropoff(DvrpVehicle vehicle, double beginTime, DrtRe @Override public double updateEndTimeForDropoff(DvrpVehicle vehicle, DrtStopTask stop, double insertionTime, DrtRequest request) { - final double stopDuration = provider.calcDropoffDuration(vehicle, request); - - // we need to take into account the general shift of the task and adding the new - // stop - - // first, we apply shiftEndTime, TODO: can we do this without the complex - // calculation? - double shiftedEndTime = shiftEndTime(vehicle, stop, insertionTime); + double stopDuration = provider.calcDropoffDuration(vehicle, request); + // first, check when we can start with the dropoff + double earliestStartTime = stop.getBeginTime(); + earliestStartTime = Math.max(earliestStartTime, insertionTime); + // second, we add the dropoff - return Math.max(stop.getEndTime(), Math.max(shiftedEndTime, insertionTime + stopDuration)); + return Math.max(stop.getEndTime(), earliestStartTime + stopDuration); } /** diff --git a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java index cb149fc1f3b..0bf2f375f6e 100644 --- a/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java +++ b/contribs/drt/src/test/java/org/matsim/contrib/drt/prebooking/PrebookingTest.java @@ -7,6 +7,9 @@ import org.matsim.contrib.drt.prebooking.PrebookingTestEnvironment.RequestInfo; import org.matsim.contrib.drt.prebooking.logic.AttributeBasedPrebookingLogic; import org.matsim.contrib.drt.run.DrtConfigGroup; +import org.matsim.contrib.drt.stops.PassengerStopDurationProvider; +import org.matsim.contrib.drt.stops.StaticPassengerStopDurationProvider; +import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule; import org.matsim.core.controler.Controler; import org.matsim.testcases.MatsimTestUtils; @@ -479,4 +482,50 @@ void sameTrip_inverseSubmission_splitPickup() { // Three stops, 2x pickup, 1x dropoff assertEquals(3, environment.getTaskInfo().get("vehicleA").stream().filter(t -> t.type.equals("STOP")).count()); } + + @Test + void interactionTimes() { + /*- + * Here we test prebookings in combination with non-zero interaction times for pickup and dropoff + */ + + PrebookingTestEnvironment environment = new PrebookingTestEnvironment(utils) // + .addVehicle("vehicleA", 1, 1) // + // 1800 indicated but only departing 2000 + .addRequest("personA", 0, 0, 5, 5, 2000.0, 0.0, 2000.0 - 200.0) // + .configure(600.0, 1.3, 600.0, 60.0) // + .endTime(10.0 * 3600.0); + + Controler controller = environment.build(); + installPrebooking(controller); + + controller.addOverridingModule(new AbstractDvrpModeModule("drt") { + @Override + public void install() { + bindModal(PassengerStopDurationProvider.class) + .toInstance(StaticPassengerStopDurationProvider.of(60.0, 30.0)); + } + }); + + controller.run(); + + RequestInfo requestInfo = environment.getRequestInfo().get("personA"); + assertEquals(0.0, requestInfo.submissionTime, 1e-3); + assertEquals(2060.0, requestInfo.pickupTime, 1e-3); + assertEquals(2301.0, requestInfo.dropoffTime, 1e-3); + + var taskInfo = environment.getTaskInfo().get("vehicleA"); + assertEquals("STAY", taskInfo.get(0).type); + assertEquals("DRIVE", taskInfo.get(1).type); + assertEquals("STAY", taskInfo.get(2).type); + assertEquals("STOP", taskInfo.get(3).type); + assertEquals("DRIVE", taskInfo.get(4).type); + assertEquals("STOP", taskInfo.get(5).type); + + assertEquals(1.0, taskInfo.get(1).startTime, 1e-3); // Pickup drive + assertEquals(86.0, taskInfo.get(2).startTime, 1e-3); // Starting to wait + assertEquals(1800.0, taskInfo.get(3).startTime, 1e-3); // Starting stop + assertEquals(2060.0, taskInfo.get(3).endTime, 1e-3); // Ending stop (260s duration) + assertEquals(2060.0, taskInfo.get(4).startTime, 1e-3); // Starting drive (ending stop) + } }