Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: properly take into account non-zero dropoff durations in prebooking #3080

Merged
merged 5 commits into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()) {
Expand All @@ -98,6 +98,8 @@ private void processDropoffRequests(double now) {
iterator.remove();
}
}

return leaveTimes.size() == 0;
}

private boolean updatePickupRequests(double now) {
Expand Down Expand Up @@ -154,12 +156,9 @@ public void notifyPassengersAreReadyForDeparture(List<MobsimPassengerAgent> pass
queuePickup(request, now);
}


private AcceptedDrtRequest getRequestForPassengers(List<Id<Person>> 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!"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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)
}
}
Loading