diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java
index 1db60059c37..3d54738d88e 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtControlerCreator.java
@@ -41,11 +41,13 @@
public class EDrtControlerCreator {
public static Controler createControler(Config config, boolean otfvis) {
- MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
- DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing());
-
Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config);
ScenarioUtils.loadScenario(scenario);
+ return createControler(config, scenario, otfvis);
+ }
+ public static Controler createControler(Config config, Scenario scenario, boolean otfvis) {
+ MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
+ DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing());
Controler controler = new Controler(scenario);
controler.addOverridingModule(new MultiModeEDrtModule());
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsControlerCreator.java
index 835cc77e9e2..ccc1576a348 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsControlerCreator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/DrtOperationsControlerCreator.java
@@ -1,5 +1,6 @@
package org.matsim.contrib.drt.extension.operations;
+import org.matsim.api.core.v01.Scenario;
import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup;
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesModeModule;
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilitiesQSimModule;
@@ -27,10 +28,25 @@ public class DrtOperationsControlerCreator {
* @return
*/
public static Controler createControler(Config config, boolean otfvis) {
- MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
-
Controler controler = DrtControlerCreator.createControler(config, otfvis);
+ return prepareController(config, controler);
+ }
+
+ /**
+ * Creates a controller in one step.
+ *
+ * @param config
+ * @param scenario
+ * @param otfvis
+ * @return
+ */
+ public static Controler createControler(Config config, Scenario scenario, boolean otfvis) {
+ Controler controler = DrtControlerCreator.createControler(config, scenario, otfvis);
+ return prepareController(config, controler);
+ }
+ private static Controler prepareController(Config config, Controler controler) {
+ MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
for (DrtConfigGroup drtCfg : multiModeDrtConfig.getModalElements()) {
controler.addOverridingModule(new ShiftDrtModeModule(drtCfg));
controler.addOverridingQSimModule(new DrtModeQSimModule(drtCfg, new ShiftDrtModeOptimizerQSimModule(drtCfg)));
@@ -40,7 +56,6 @@ public static Controler createControler(Config config, boolean otfvis) {
}
controler.configureQSimComponents(DvrpQSimComponents.activateAllModes(multiModeDrtConfig));
-
return controler;
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/EDrtOperationsControlerCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/EDrtOperationsControlerCreator.java
index da76f73772d..855cba7f143 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/EDrtOperationsControlerCreator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/EDrtOperationsControlerCreator.java
@@ -1,5 +1,6 @@
package org.matsim.contrib.drt.extension.operations;
+import org.matsim.api.core.v01.Scenario;
import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup;
import org.matsim.contrib.drt.extension.edrt.run.EDrtControlerCreator;
import org.matsim.contrib.drt.extension.operations.eshifts.charging.ShiftOperatingVehicleProvider;
@@ -24,11 +25,19 @@
public class EDrtOperationsControlerCreator {
public static Controler createControler(Config config, boolean otfvis) {
-
- MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
-
Controler controler = EDrtControlerCreator.createControler(config, otfvis);
+ prepareController(config, controler);
+ return controler;
+ }
+
+ public static Controler createControler(Config config, Scenario scenario, boolean otfvis) {
+ Controler controler = EDrtControlerCreator.createControler(config, scenario, otfvis);
+ prepareController(config, controler);
+ return controler;
+ }
+ private static void prepareController(Config config, Controler controler) {
+ MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
for (DrtConfigGroup drtCfg : multiModeDrtConfig.getModalElements()) {
controler.addOverridingModule(new ShiftDrtModeModule(drtCfg));
controler.addOverridingQSimModule(new DrtModeQSimModule(drtCfg, new ShiftDrtModeOptimizerQSimModule(drtCfg)));
@@ -39,14 +48,11 @@ public static Controler createControler(Config config, boolean otfvis) {
controler.addOverridingModule(new DrtShiftEfficiencyModeModule(drtCfg));
}
-
controler.addOverridingQSimModule(new AbstractQSimModule() {
@Override
protected void configureQSim() {
this.bind(IdleDischargingHandler.VehicleProvider.class).to(ShiftOperatingVehicleProvider.class);
}
});
-
- return controler;
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/README.md b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/README.md
new file mode 100644
index 00000000000..9f7200cc257
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/README.md
@@ -0,0 +1,72 @@
+# DRT Operations
+
+Provides functionality to realistically simulate operational aspects,
+designed for, bot not limited to, non-autonomous services.
+
+Initially developed for MOIA GmbH
+
+If used, please cite:
+
+Felix Zwick, Nico Kuehnel, Sebastian Hörl.
+Shifts in perspective: Operational aspects in (non-)autonomous
+ride-pooling simulations.
+Transportation Research Part A: Policy and Practice,
+Volume 165, 2022, Pages 300-320.
+https://doi.org/10.1016/j.tra.2022.09.001.
+
+
+## Core features:
+
+- Operation facilities
+- (Driver) shifts
+
+
+The entry point for setting up a simulation are the specific control(l)er creators:
+- DrtOperationsControlerCreator
+ - or
+- EDrtOperationsControlerCreator
+ - in the electric vehicles case
+
+## Operation Facilities
+Operation facilities are meant to represent hubs and in-field break locations.
+The facilities have a capacity that cannot be exceeded and may be linked to
+existing chargers via the id.
+
+(Driver) shifts may only start or end at operation facilities in the default setup.
+Vehicles will route to operation facilities to end a shift or for scheduling a break.
+
+Operational facilities may be described with an xml file like this:
+```
+
+
+
+
+
+
+
+
+```
+
+## Shifts
+Shifts define periods in which vehicles may be active serving passengers.
+Shifts are dynamically assigned to vehicles.
+
+In autonomous settings, shifts may be used to model up- and down-time and/or cleaning
+cycles.
+
+Shifts have a start and end time and can optionally have a break which is defined
+by earliest start and latest end as well as a duration. Optionally, as operation
+facility id may be defined to control the location of the start/end of the shift.
+
+Shifts may be described in an xml file likes this:
+```
+
+
+
+
+
+
+
+
+```
+
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtAssignShiftToVehicleLogic.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtAssignShiftToVehicleLogic.java
index 32f74d1196c..0c2d4fd79c8 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtAssignShiftToVehicleLogic.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtAssignShiftToVehicleLogic.java
@@ -9,7 +9,7 @@
package org.matsim.contrib.drt.extension.operations.eshifts.dispatcher;
import org.matsim.contrib.drt.extension.operations.eshifts.fleet.EvShiftDvrpVehicle;
-import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams;
import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.AssignShiftToVehicleLogic;
import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle;
@@ -37,8 +37,8 @@ public boolean canAssignVehicleToShift(ShiftDvrpVehicle vehicle, DrtShift shift)
// no, if charging
if(vehicle.getSchedule().getStatus() == Schedule.ScheduleStatus.STARTED) {
final Task currentTask = vehicle.getSchedule().getCurrentTask();
- if (currentTask instanceof EDrtWaitForShiftStayTask) {
- if (((EDrtWaitForShiftStayTask) currentTask).getChargingTask() != null) {
+ if (currentTask instanceof EDrtWaitForShiftTask) {
+ if (((EDrtWaitForShiftTask) currentTask).getChargingTask() != null) {
if (currentTask.getEndTime() > shift.getStartTime()) {
return false;
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java
index e18008e4ce5..ace6e8d66e0 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftDispatcherImpl.java
@@ -3,7 +3,7 @@
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.drt.extension.operations.eshifts.fleet.EvShiftDvrpVehicle;
-import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.eshifts.scheduler.EShiftTaskScheduler;
import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams;
import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.DrtShiftDispatcher;
@@ -11,7 +11,7 @@
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilities;
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.dvrp.fleet.DvrpVehicle;
import org.matsim.contrib.dvrp.fleet.Fleet;
import org.matsim.contrib.dvrp.schedule.Schedule;
@@ -96,8 +96,8 @@ private void checkChargingAtHub(double timeStep) {
final ElectricVehicle electricVehicle = eShiftVehicle.getElectricVehicle();
if (electricVehicle.getBattery().getCharge() / electricVehicle.getBattery().getCapacity() < drtShiftParams.chargeAtHubThreshold) {
final Task currentTask = eShiftVehicle.getSchedule().getCurrentTask();
- if (currentTask instanceof EDrtWaitForShiftStayTask
- && ((EDrtWaitForShiftStayTask) currentTask).getChargingTask() == null) {
+ if (currentTask instanceof EDrtWaitForShiftTask
+ && ((EDrtWaitForShiftTask) currentTask).getChargingTask() == null) {
Optional selectedCharger = chargerIds
.stream()
.map(id -> chargingInfrastructure.getChargers().get(id))
@@ -122,7 +122,7 @@ private void checkChargingAtHub(double timeStep) {
.calcRemainingEnergyToCharge(electricVehicle);
final double endTime = timeStep + waitTime + chargingTime;
if (endTime < currentTask.getEndTime()) {
- shiftTaskScheduler.chargeAtHub((WaitForShiftStayTask) currentTask, eShiftVehicle,
+ shiftTaskScheduler.chargeAtHub((WaitForShiftTask) currentTask, eShiftVehicle,
electricVehicle, selectedChargerImpl, timeStep, endTime, energy);
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java
index ad3c83ca0f7..97ceadbb433 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/dispatcher/EDrtShiftStartLogic.java
@@ -8,7 +8,7 @@
*/
package org.matsim.contrib.drt.extension.operations.eshifts.dispatcher;
-import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.DrtShiftDispatcher;
import org.matsim.contrib.drt.extension.operations.shifts.dispatcher.ShiftStartLogic;
import org.matsim.contrib.dvrp.schedule.Schedule;
@@ -29,9 +29,9 @@ public EDrtShiftStartLogic(ShiftStartLogic delegate) {
public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry shiftEntry) {
Schedule schedule = shiftEntry.vehicle().getSchedule();
Task currentTask = schedule.getCurrentTask();
- if (currentTask instanceof EDrtWaitForShiftStayTask) {
+ if (currentTask instanceof EDrtWaitForShiftTask) {
//check whether vehicle still needs to complete charging task
- if(((EDrtWaitForShiftStayTask) currentTask).getChargingTask() == null) {
+ if(((EDrtWaitForShiftTask) currentTask).getChargingTask() == null) {
return delegate.shiftStarts(shiftEntry);
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java
index ab4bf41c938..aefdfeb5e6c 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/run/ShiftEDrtModeOptimizerQSimModule.java
@@ -76,7 +76,9 @@ drtShiftParams, new EDrtShiftStartLogic(new DefaultShiftStartLogic()),
new EDrtAssignShiftToVehicleLogic(new DefaultAssignShiftToVehicleLogic(drtShiftParams), drtShiftParams)),
getter.getModal(Fleet.class)))).asEagerSingleton();
- bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter -> new ShiftVehicleDataEntryFactory(new EDrtVehicleDataEntryFactory(0)))).asEagerSingleton();
+ bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter ->
+ new ShiftVehicleDataEntryFactory(new EDrtVehicleDataEntryFactory(0),
+ drtShiftParams.considerUpcomingShiftsForInsertion))).asEagerSingleton();
bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> new ShiftEDrtTaskFactoryImpl(new EDrtTaskFactoryImpl(), getter.getModal(OperationFacilities.class)))).in(Singleton.class);
bindModal(ShiftDrtTaskFactory.class).toProvider(modalProvider(getter -> ((ShiftDrtTaskFactory) getter.getModal(DrtTaskFactory.class))));
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftStayTask.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftTask.java
similarity index 69%
rename from contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftStayTask.java
rename to contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftTask.java
index c60e0214f1d..546b4e6b770 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftStayTask.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/EDrtWaitForShiftTask.java
@@ -1,23 +1,23 @@
package org.matsim.contrib.drt.extension.operations.eshifts.schedule;
import org.matsim.api.core.v01.network.Link;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.evrp.ChargingTask;
import org.matsim.contrib.evrp.ETask;
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
/**
* @author nkuehnel / MOIA
*/
-public class EDrtWaitForShiftStayTask extends WaitForShiftStayTask implements ETask {
+public class EDrtWaitForShiftTask extends WaitForShiftTask implements ETask {
private final double consumedEnergy;
private final ChargingTask chargingTask;
- public EDrtWaitForShiftStayTask(double beginTime, double endTime, Link link,
- double consumedEnergy, OperationFacility facility,
- ChargingTask chargingTask) {
+ public EDrtWaitForShiftTask(double beginTime, double endTime, Link link,
+ double consumedEnergy, OperationFacility facility,
+ ChargingTask chargingTask) {
super(beginTime, endTime, link, facility);
this.consumedEnergy = consumedEnergy;
this.chargingTask = chargingTask;
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java
index 4604771bed9..6092021974c 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtActionCreator.java
@@ -42,9 +42,9 @@ public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now
task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle) vehicle, timer));
DrtStopTask t = (DrtStopTask) task;
return new ChargingChangeoverActivity(((EDrtShiftChangeoverTaskImpl) task).getChargingTask(), passengerHandler, dynAgent, t, t.getDropoffRequests(), t.getPickupRequests());
- } else if (task instanceof EDrtWaitForShiftStayTask && ((EDrtWaitForShiftStayTask) task).getChargingTask() != null) {
+ } else if (task instanceof EDrtWaitForShiftTask && ((EDrtWaitForShiftTask) task).getChargingTask() != null) {
task.initTaskTracker(new OfflineETaskTracker((EvDvrpVehicle) vehicle, timer));
- return new ChargingWaitForShiftActivity(((EDrtWaitForShiftStayTask) task).getChargingTask());
+ return new ChargingWaitForShiftActivity(((EDrtWaitForShiftTask) task).getChargingTask());
}
DynAction dynAction = delegate.createAction(dynAgent, vehicle, now);
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java
index 5e0c085c1bb..b7c2657f1bf 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/schedule/ShiftEDrtTaskFactoryImpl.java
@@ -9,7 +9,7 @@
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeOverTask;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftDrtTaskFactory;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak;
import org.matsim.contrib.drt.schedule.DrtDriveTask;
@@ -69,14 +69,14 @@ public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime,
} catch (Throwable e) {
throw new RuntimeException(e);
}
- WaitForShiftStayTask waitForShiftStayTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(),
+ WaitForShiftTask waitForShiftTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(),
vehicle.getStartLink(), operationFacility);
boolean success = operationFacility.register(vehicle.getId());
if (!success) {
throw new RuntimeException(String.format("Cannot register vehicle %s at facility %s at start-up. Please check" +
"facility capacity and initial fleet distribution.", vehicle.getId().toString(), operationFacility.getId().toString()));
}
- return waitForShiftStayTask;
+ return waitForShiftTask;
}
@Override
@@ -92,16 +92,16 @@ public ShiftChangeOverTask createShiftChangeoverTask(DvrpVehicle vehicle, double
}
@Override
- public WaitForShiftStayTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link,
- OperationFacility facility) {
- return new EDrtWaitForShiftStayTask(beginTime, endTime, link, 0, facility, null);
+ public WaitForShiftTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link,
+ OperationFacility facility) {
+ return new EDrtWaitForShiftTask(beginTime, endTime, link, 0, facility, null);
}
- public WaitForShiftStayTask createChargingWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime,
- double endTime, Link link, OperationFacility facility,
- double totalEnergy, Charger charger) {
+ public WaitForShiftTask createChargingWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime,
+ double endTime, Link link, OperationFacility facility,
+ double totalEnergy, Charger charger) {
ChargingTask chargingTask = new ChargingTaskImpl(EDrtChargingTask.TYPE, beginTime, endTime, charger, ((EvDvrpVehicle)vehicle).getElectricVehicle(), totalEnergy);
- return new EDrtWaitForShiftStayTask(beginTime, endTime, link, totalEnergy, facility, chargingTask);
+ return new EDrtWaitForShiftTask(beginTime, endTime, link, totalEnergy, facility, chargingTask);
}
public EDrtShiftBreakTaskImpl createChargingShiftBreakTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link,
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java
index 7352f32c261..dc053728a40 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java
@@ -351,8 +351,8 @@ private void appendShiftChange(DvrpVehicle vehicle, DrtShift shift, OperationFac
public void startShift(ShiftDvrpVehicle vehicle, double now, DrtShift shift) {
Schedule schedule = vehicle.getSchedule();
StayTask stayTask = (StayTask) schedule.getCurrentTask();
- if (stayTask instanceof WaitForShiftStayTask) {
- ((WaitForShiftStayTask) stayTask).getFacility().deregisterVehicle(vehicle.getId());
+ if (stayTask instanceof WaitForShiftTask) {
+ ((WaitForShiftTask) stayTask).getFacility().deregisterVehicle(vehicle.getId());
stayTask.setEndTime(now);
schedule.addTask(taskFactory.createStayTask(vehicle, now, shift.getEndTime(), stayTask.getLink()));
} else {
@@ -375,6 +375,24 @@ public boolean updateShiftChange(ShiftDvrpVehicle vehicle, Link link, DrtShift s
return false;
}
+ @Override
+ public void planAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) {
+ Schedule schedule = vehicle.getSchedule();
+ StayTask stayTask = (StayTask) schedule.getCurrentTask();
+ if (stayTask instanceof WaitForShiftTask) {
+ stayTask.setEndTime(Math.max(timeStep, shift.getStartTime()));
+ }
+ }
+
+ @Override
+ public void cancelAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) {
+ Schedule schedule = vehicle.getSchedule();
+ StayTask stayTask = (StayTask) schedule.getCurrentTask();
+ if (stayTask instanceof WaitForShiftTask) {
+ stayTask.setEndTime(vehicle.getServiceEndTime());
+ }
+ }
+
private void updateShiftChangeImpl(DvrpVehicle vehicle, VrpPathWithTravelData vrpPath,
DrtShift shift, OperationFacility facility, Task lastTask) {
Schedule schedule = vehicle.getSchedule();
@@ -413,19 +431,19 @@ private void updateShiftChangeImpl(DvrpVehicle vehicle, VrpPathWithTravelData vr
vrpPath.getToLink(), facility));
}
- public void chargeAtHub(WaitForShiftStayTask currentTask, ShiftDvrpVehicle vehicle,
+ public void chargeAtHub(WaitForShiftTask currentTask, ShiftDvrpVehicle vehicle,
ElectricVehicle electricVehicle, Charger charger, double beginTime,
double endTime, double energy) {
final double initialEndTime = currentTask.getEndTime();
currentTask.setEndTime(beginTime);
((ChargingWithAssignmentLogic) charger.getLogic()).assignVehicle(electricVehicle);
- final WaitForShiftStayTask chargingWaitForShiftStayTask = ((ShiftEDrtTaskFactoryImpl) taskFactory).createChargingWaitForShiftStayTask(vehicle,
+ final WaitForShiftTask chargingWaitForShiftTask = ((ShiftEDrtTaskFactoryImpl) taskFactory).createChargingWaitForShiftStayTask(vehicle,
beginTime, endTime, currentTask.getLink(), currentTask.getFacility(), energy, charger);
- final WaitForShiftStayTask waitForShiftStayTask = taskFactory.createWaitForShiftStayTask(vehicle, endTime,
+ final WaitForShiftTask waitForShiftTask = taskFactory.createWaitForShiftStayTask(vehicle, endTime,
initialEndTime, currentTask.getLink(), currentTask.getFacility());
- vehicle.getSchedule().addTask(currentTask.getTaskIdx() + 1, chargingWaitForShiftStayTask);
- vehicle.getSchedule().addTask(currentTask.getTaskIdx() + 2, waitForShiftStayTask);
+ vehicle.getSchedule().addTask(currentTask.getTaskIdx() + 1, chargingWaitForShiftTask);
+ vehicle.getSchedule().addTask(currentTask.getTaskIdx() + 2, waitForShiftTask);
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/NearestOperationFacilityWithCapacityFinder.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/NearestOperationFacilityWithCapacityFinder.java
index 1df98354824..7d41752548e 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/NearestOperationFacilityWithCapacityFinder.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/NearestOperationFacilityWithCapacityFinder.java
@@ -4,6 +4,7 @@
import org.matsim.contrib.common.util.DistanceUtils;
import java.util.Comparator;
+import java.util.Optional;
import java.util.function.Predicate;
/**
@@ -21,7 +22,7 @@ public NearestOperationFacilityWithCapacityFinder(OperationFacilities operationF
}
@Override
- public OperationFacility findFacilityOfType(Coord coord, OperationFacilityType type) {
+ public Optional findFacilityOfType(Coord coord, OperationFacilityType type) {
Predicate super OperationFacility> filter;
switch (type) {
case hub:
@@ -37,15 +38,15 @@ public OperationFacility findFacilityOfType(Coord coord, OperationFacilityType t
.filter(filter)
.filter(OperationFacility::hasCapacity)
.min(Comparator.comparing(
- f -> DistanceUtils.calculateSquaredDistance(coord, f.getCoord()))).orElse(null);
+ f -> DistanceUtils.calculateSquaredDistance(coord, f.getCoord())));
}
@Override
- public OperationFacility findFacility(Coord coord) {
+ public Optional findFacility(Coord coord) {
return operationFacilities.getDrtOperationFacilities().values().stream()
.filter(OperationFacility::hasCapacity)
.min(Comparator.comparing(
- f -> DistanceUtils.calculateSquaredDistance(coord, f.getCoord()))).orElse(null);
+ f -> DistanceUtils.calculateSquaredDistance(coord, f.getCoord())));
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilityFinder.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilityFinder.java
index 8262f5938f5..469f7f3703b 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilityFinder.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/operationFacilities/OperationFacilityFinder.java
@@ -2,12 +2,14 @@
import org.matsim.api.core.v01.Coord;
+import java.util.Optional;
+
/**
* @author nkuehnel / MOIA
*/
public interface OperationFacilityFinder {
- OperationFacility findFacilityOfType(Coord coord, OperationFacilityType type);
+ Optional findFacilityOfType(Coord coord, OperationFacilityType type);
- OperationFacility findFacility(Coord coord);
+ Optional findFacility(Coord coord);
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java
index 4d76cbddfc0..e61e5541896 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/config/ShiftsParams.java
@@ -8,8 +8,8 @@
*/
package org.matsim.contrib.drt.extension.operations.shifts.config;
-import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
import org.matsim.contrib.common.util.ReflectiveConfigGroupWithConfigurableParameterSets;
+import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
import org.matsim.core.config.ConfigGroup;
import java.net.URL;
@@ -43,7 +43,7 @@ public class ShiftsParams extends ReflectiveConfigGroupWithConfigurableParameter
@Parameter
@Comment("Time of shift end rescheduling (i.e. check whether shift should end" +
- " at a different facillity) before end of shift in [seconds]")
+ " at a different facility) before end of shift in [seconds]")
public double shiftEndRescheduleLookAhead = 1800;
@Parameter
@@ -53,7 +53,7 @@ public class ShiftsParams extends ReflectiveConfigGroupWithConfigurableParameter
@Parameter
@Comment("set to true if shifts can start and end at in field operational facilities," +
- " false if changerover is only allowed at hubs")
+ " false if changeover is only allowed at hubs")
public boolean allowInFieldChangeover = true;
//electric shifts
@@ -91,7 +91,13 @@ public class ShiftsParams extends ReflectiveConfigGroupWithConfigurableParameter
@Comment("defines the logging interval in [seconds]")
public double loggingInterval = 600;
- public ShiftsParams() {
+ @Parameter
+ @Comment("Defines whether vehicles should be eligible for insertion when they have a shift assigned which has not yet started. " +
+ "Defaults to false. Should be set to true if used together with prebookings that are inserted before shift starts. " +
+ "In this case, make sure that 'shiftScheduleLookAhead' is larger than the prebboking slack.")
+ public boolean considerUpcomingShiftsForInsertion = false;
+
+ public ShiftsParams() {
super(SET_NAME);
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java
index cb9e5d76a9f..f2b006cbae7 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DefaultShiftStartLogic.java
@@ -11,7 +11,7 @@
import com.google.common.base.Verify;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.dvrp.schedule.Schedule;
import org.matsim.contrib.dvrp.schedule.Task;
@@ -34,11 +34,11 @@ public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry peek) {
// current task is WaitForShiftTask
Task currentTask = schedule.getCurrentTask();
- if(currentTask instanceof WaitForShiftStayTask) {
+ if(currentTask instanceof WaitForShiftTask) {
//check if optional location requirement is met
if(peek.shift().getOperationFacilityId().isPresent()) {
Id operationFacilityId = peek.shift().getOperationFacilityId().get();
- Verify.verify((operationFacilityId.equals(((WaitForShiftStayTask) currentTask).getFacility().getId())),
+ Verify.verify((operationFacilityId.equals(((WaitForShiftTask) currentTask).getFacility().getId())),
"Vehicle and shift start locations do not match.");
}
return true;
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java
index c32b5d1b12b..5d983e81f05 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java
@@ -140,40 +140,52 @@ private void checkBreaks() {
for (ShiftEntry activeShift : activeShifts) {
final DrtShift shift = activeShift.shift();
if (shift != null && shift.isStarted()) {
- OperationFacility breakFacility = decideOnBreak(activeShift);
- if (breakFacility != null) {
- shiftTaskScheduler.relocateForBreak(activeShift.vehicle(), breakFacility, shift);
- eventsManager.processEvent(new DrtShiftBreakScheduledEvent(timer.getTimeOfDay(), mode, shift.getId(),
- activeShift.vehicle().getId(), breakFacility.getLinkId(),
- shift.getBreak().orElseThrow().getScheduledLatestArrival()));
+ if (hasSchedulableBreak(shift, timer.getTimeOfDay())) {
+ Optional breakFacility = findBreakFacility(activeShift);
+ if (breakFacility.isPresent()) {
+ OperationFacility facility = breakFacility.get();
+ if (facility.register(activeShift.vehicle().getId())) {
+ eventsManager.processEvent(new ShiftFacilityRegistrationEvent(
+ timer.getTimeOfDay(), mode, activeShift.vehicle().getId(), facility.getId()));
+ shiftTaskScheduler.relocateForBreak(activeShift.vehicle(), facility, shift);
+ eventsManager.processEvent(new DrtShiftBreakScheduledEvent(timer.getTimeOfDay(), mode, shift.getId(),
+ activeShift.vehicle().getId(), facility.getLinkId(),
+ shift.getBreak().orElseThrow().getScheduledLatestArrival()));
+ return;
+ }
+ }
+ throw new RuntimeException("Could not schedule break!");
}
}
}
}
private void startShifts(double timeStep) {
- // Start shifts
final Iterator iterator = this.assignedShifts.iterator();
while (iterator.hasNext()) {
- final ShiftEntry next = iterator.next();
- if (next.shift().getStartTime() > timeStep) {
+ final ShiftEntry assignedShiftEntry = iterator.next();
+ if (assignedShiftEntry.shift().getStartTime() > timeStep) {
+ shiftTaskScheduler.planAssignedShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift());
break;
- } else if (next.shift().getEndTime() < timeStep) {
- logger.warn("Too late to start shift " + next.shift().getId());
- next.vehicle().getShifts().remove(next.shift());
+ } else if (assignedShiftEntry.shift().getEndTime() < timeStep) {
+ logger.warn("Too late to start shift " + assignedShiftEntry.shift().getId());
+ shiftTaskScheduler.cancelAssignedShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift());
+ assignedShiftEntry.vehicle().getShifts().remove(assignedShiftEntry.shift());
iterator.remove();
continue;
}
- if (shiftStartLogic.shiftStarts(next)) {
- next.shift().start();
- shiftTaskScheduler.startShift(next.vehicle(), timeStep, next.shift());
- activeShifts.add(next);
+ if (shiftStartLogic.shiftStarts(assignedShiftEntry)) {
+ assignedShiftEntry.shift().start();
+ shiftTaskScheduler.startShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift());
+ activeShifts.add(assignedShiftEntry);
iterator.remove();
- logger.debug("Started shift " + next.shift());
- StayTask currentTask = (StayTask) next.vehicle().getSchedule().getCurrentTask();
- eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, mode, next.shift().getId(), next.vehicle().getId(),
+ logger.debug("Started shift " + assignedShiftEntry.shift());
+ StayTask currentTask = (StayTask) assignedShiftEntry.vehicle().getSchedule().getCurrentTask();
+ eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, mode, assignedShiftEntry.shift().getId(), assignedShiftEntry.vehicle().getId(),
currentTask.getLink().getId()));
+ } else {
+ shiftTaskScheduler.planAssignedShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift());
}
}
}
@@ -183,9 +195,9 @@ private void assignShifts(double timeStep) {
unscheduledShifts.removeIf(shift -> {
if (shift.getStartTime() + drtShiftParams.maxUnscheduledShiftDelay < timeStep ) {
logger.warn("Shift with ID " + shift.getId() + " could not be assigned and is being removed as start time is longer in the past than defined by maxUnscheduledShiftDelay.");
- return true;
+ return true;
}
- return false;
+ return false;
});
// Assign shifts
@@ -264,6 +276,7 @@ private void assignShifts(double timeStep) {
private void assignShiftToVehicle(DrtShift shift, ShiftDvrpVehicle vehicle) {
Gbl.assertNotNull(vehicle);
vehicle.addShift(shift);
+ shiftTaskScheduler.planAssignedShift(vehicle, timer.getTimeOfDay(), shift);
assignedShifts.add(new ShiftEntry(shift, vehicle));
eventsManager.processEvent(new DrtShiftAssignedEvent(timer.getTimeOfDay(), mode, shift.getId(), vehicle.getId()));
}
@@ -357,23 +370,25 @@ private void updateShiftEnd(ShiftEntry next) {
}
}
- final OperationFacility shiftChangeFacility;
+ final Optional maybeFacility;
if (drtShiftParams.allowInFieldChangeover) {
- shiftChangeFacility = breakFacilityFinder.findFacility(start.link.getCoord());
+ maybeFacility = breakFacilityFinder.findFacility(start.link.getCoord());
} else {
- shiftChangeFacility = breakFacilityFinder.findFacilityOfType(start.link.getCoord(),
+ maybeFacility = breakFacilityFinder.findFacilityOfType(start.link.getCoord(),
OperationFacilityType.hub);
}
- if (shiftChangeFacility != null && changeOverTask != null
- && !(shiftChangeFacility.getId().equals(changeOverTask.getFacility().getId()))) {
- if (shiftChangeFacility.hasCapacity()) {
- if (shiftTaskScheduler.updateShiftChange(next.vehicle(),
- network.getLinks().get(shiftChangeFacility.getLinkId()), next.shift(), start,
- shiftChangeFacility, lastTask)) {
- shiftChangeFacility.register(next.vehicle().getId());
- changeOverTask.getFacility().deregisterVehicle(next.vehicle().getId());
- eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(),
- mode, next.vehicle().getId(), shiftChangeFacility.getId()));
+ if (maybeFacility.isPresent()) {
+ OperationFacility shiftChangeFacility = maybeFacility.get();
+ if(changeOverTask != null && !(shiftChangeFacility.getId().equals(changeOverTask.getFacility().getId()))) {
+ if (shiftChangeFacility.hasCapacity()) {
+ if (shiftTaskScheduler.updateShiftChange(next.vehicle(),
+ network.getLinks().get(shiftChangeFacility.getLinkId()), next.shift(), start,
+ shiftChangeFacility, lastTask)) {
+ shiftChangeFacility.register(next.vehicle().getId());
+ changeOverTask.getFacility().deregisterVehicle(next.vehicle().getId());
+ eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(),
+ mode, next.vehicle().getId(), shiftChangeFacility.getId()));
+ }
}
}
}
@@ -423,50 +438,35 @@ private void scheduleShiftEnd(ShiftEntry endingShift) {
if(shiftChangeoverFacility == null) {
shiftChangeoverFacility = breakFacilityFinder.findFacilityOfType(coord,
- OperationFacilityType.hub);
+ OperationFacilityType.hub).orElseThrow(() -> new RuntimeException("Could not find shift end location!"));
}
- if (shiftChangeoverFacility != null && shiftChangeoverFacility.register(endingShift.vehicle().getId())) {
- shiftTaskScheduler.relocateForShiftChange(endingShift.vehicle(),
- network.getLinks().get(shiftChangeoverFacility.getLinkId()), endingShift.shift(), shiftChangeoverFacility);
- eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), mode, endingShift.vehicle().getId(),
- shiftChangeoverFacility.getId()));
- } else {
- throw new RuntimeException("Could not find shift end location!");
- }
+ Verify.verify(shiftChangeoverFacility.register(endingShift.vehicle().getId()), "Could not register vehicle at facility.");
+
+ shiftTaskScheduler.relocateForShiftChange(endingShift.vehicle(),
+ network.getLinks().get(shiftChangeoverFacility.getLinkId()), endingShift.shift(), shiftChangeoverFacility);
+ eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(), mode, endingShift.vehicle().getId(),
+ shiftChangeoverFacility.getId()));
}
- private OperationFacility decideOnBreak(ShiftEntry activeShift) {
- if (activeShift.shift() != null) {
- if (shiftNeedsBreak(activeShift.shift(), timer.getTimeOfDay())) {
- final Schedule schedule = activeShift.vehicle().getSchedule();
- Task currentTask = schedule.getCurrentTask();
- Link lastLink;
- if (currentTask instanceof DriveTask
- && currentTask.getTaskType().equals(EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE)
- && currentTask.equals(schedule.getTasks().get(schedule.getTaskCount()-2))) {
- LinkTimePair start = ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).getDiversionPoint();
- if(start != null) {
- lastLink = start.link;
- } else {
- lastLink = ((DriveTask) currentTask).getPath().getToLink();
- }
- } else {
- lastLink = ((DrtStayTask) schedule.getTasks()
- .get(schedule.getTaskCount() - 1)).getLink();
- }
- final OperationFacility shiftBreakFacility = breakFacilityFinder.findFacility(lastLink.getCoord());
- if (shiftBreakFacility == null) {
- throw new RuntimeException("Could not schedule break!");
- }
- if (shiftBreakFacility.register(activeShift.vehicle().getId())) {
- eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(),
- mode, activeShift.vehicle().getId(), shiftBreakFacility.getId()));
- return shiftBreakFacility;
- }
+ private Optional findBreakFacility(ShiftEntry activeShift) {
+ final Schedule schedule = activeShift.vehicle().getSchedule();
+ Task currentTask = schedule.getCurrentTask();
+ Link lastLink;
+ if (currentTask instanceof DriveTask
+ && currentTask.getTaskType().equals(EmptyVehicleRelocator.RELOCATE_VEHICLE_TASK_TYPE)
+ && currentTask.equals(schedule.getTasks().get(schedule.getTaskCount()-2))) {
+ LinkTimePair start = ((OnlineDriveTaskTracker) currentTask.getTaskTracker()).getDiversionPoint();
+ if(start != null) {
+ lastLink = start.link;
+ } else {
+ lastLink = ((DriveTask) currentTask).getPath().getToLink();
}
+ } else {
+ lastLink = ((DrtStayTask) schedule.getTasks()
+ .get(schedule.getTaskCount() - 1)).getLink();
}
- return null;
+ return breakFacilityFinder.findFacility(lastLink.getCoord());
}
@Override
@@ -500,12 +500,10 @@ public void startBreak(ShiftDvrpVehicle vehicle, Id linkId) {
}
private boolean isSchedulable(DrtShift shift, double timeStep) {
- return shift.getStartTime() <= timeStep + drtShiftParams.shiftScheduleLookAhead; // && shift.getEndTime() > timeStep;
+ return shift.getStartTime() <= timeStep + drtShiftParams.shiftScheduleLookAhead;
}
-
-
- private boolean shiftNeedsBreak(DrtShift shift, double timeStep) {
+ private boolean hasSchedulableBreak(DrtShift shift, double timeStep) {
return shift.getBreak().isPresent() && shift.getBreak().get().getEarliestBreakStartTime() == timeStep
&& !shift.getBreak().get().isScheduled();
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftVehicleDataEntryFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftVehicleDataEntryFactory.java
index 3262fe787fc..66a3470ddbe 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftVehicleDataEntryFactory.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/ShiftVehicleDataEntryFactory.java
@@ -1,16 +1,11 @@
package org.matsim.contrib.drt.extension.operations.shifts.optimizer;
-import com.google.inject.Provider;
import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle;
-import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.OperationalStop;
-import org.matsim.contrib.drt.optimizer.VehicleDataEntryFactoryImpl;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
+import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift;
import org.matsim.contrib.drt.optimizer.VehicleEntry;
-import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.dvrp.fleet.DvrpVehicle;
-import org.matsim.core.config.Config;
-
-import jakarta.inject.Inject;
/**
* @author nkuehnel / MOIA
@@ -19,10 +14,13 @@ public class ShiftVehicleDataEntryFactory implements VehicleEntry.EntryFactory {
private final VehicleEntry.EntryFactory entryFactory;
+ private final boolean considerUpcomingShifts;
+
- public ShiftVehicleDataEntryFactory(VehicleEntry.EntryFactory delegate) {
+ public ShiftVehicleDataEntryFactory(VehicleEntry.EntryFactory delegate, boolean considerUpcomingShifts) {
entryFactory = delegate;
- }
+ this.considerUpcomingShifts = considerUpcomingShifts;
+ }
@Override
public VehicleEntry create(DvrpVehicle vehicle, double currentTime) {
@@ -36,12 +34,21 @@ public VehicleEntry create(DvrpVehicle vehicle, double currentTime) {
public boolean isEligibleForRequestInsertion(DvrpVehicle dvrpVehicle, double currentTime) {
final DrtShift currentShift = ((ShiftDvrpVehicle) dvrpVehicle).getShifts().peek();
- if(currentShift == null ||
- currentTime > currentShift.getEndTime() ||
- !currentShift.isStarted() ||
- currentShift.isEnded()) {
- return false;
+
+ // no shift assigned
+ if (currentShift == null) {
+ return false;
+ }
+
+ if(currentShift.isStarted()) {
+ if(currentTime > currentShift.getEndTime()) {
+ return false;
+ }
+ // do not insert into operational stops such as breaks
+ return !(dvrpVehicle.getSchedule().getCurrentTask() instanceof OperationalStop);
+ } else {
+ // upcoming shift assigned but not started yet. Only consider vehicles already waiting for shift start
+ return considerUpcomingShifts && dvrpVehicle.getSchedule().getCurrentTask() instanceof WaitForShiftTask;
}
- return !(dvrpVehicle.getSchedule().getCurrentTask() instanceof OperationalStop);
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/insertion/ShiftInsertionCostCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/insertion/ShiftInsertionCostCalculator.java
index db74fcd4d85..d6b3c978146 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/insertion/ShiftInsertionCostCalculator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/optimizer/insertion/ShiftInsertionCostCalculator.java
@@ -1,7 +1,9 @@
package org.matsim.contrib.drt.extension.operations.shifts.optimizer.insertion;
+import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTask;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeOverTask;
+import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak;
import org.matsim.contrib.drt.optimizer.VehicleEntry;
import org.matsim.contrib.drt.optimizer.Waypoint;
@@ -32,19 +34,24 @@ public ShiftInsertionCostCalculator(MobsimTimer timer,
@Override
public double calculate(DrtRequest drtRequest, Insertion insertion, DetourTimeInfo detourTimeInfo) {
- if (!checkShiftTimeConstraintsForScheduledRequests(insertion,
- detourTimeInfo.pickupDetourInfo.pickupTimeLoss, detourTimeInfo.getTotalTimeLoss())) {
+ if (!checkShiftTimeConstraintsForScheduledRequests(insertion, detourTimeInfo)) {
return INFEASIBLE_SOLUTION_COST;
}
return delegate.calculate(drtRequest, insertion, detourTimeInfo);
}
- boolean checkShiftTimeConstraintsForScheduledRequests(Insertion insertion, double pickupDetourTimeLoss,
- double totalTimeLoss) {
+ boolean checkShiftTimeConstraintsForScheduledRequests(Insertion insertion, DetourTimeInfo detourTimeInfo) {
VehicleEntry vEntry = insertion.vehicleEntry;
final int pickupIdx = insertion.pickup.index;
final int dropoffIdx = insertion.dropoff.index;
+ DrtShift currentShift = ((ShiftDvrpVehicle) vEntry.vehicle).getShifts().peek();
+ double shiftEndTime = currentShift.getEndTime();
+ if(shiftEndTime < detourTimeInfo.dropoffDetourInfo.arrivalTime) {
+ // fast fail which also captures requests that are prebooked for times outside of the shift.
+ return false;
+ }
+
for (int s = 0; s < pickupIdx; s++) {
Waypoint.Stop stop = vEntry.stops.get(s);
if (stop.task instanceof ShiftChangeOverTask) {
@@ -53,6 +60,8 @@ boolean checkShiftTimeConstraintsForScheduledRequests(Insertion insertion, doubl
}
}
+ double pickupDetourTimeLoss = detourTimeInfo.pickupDetourInfo.pickupTimeLoss;
+
// each existing stop has 2 time constraints: latestArrivalTime and latestDepartureTime (see: Waypoint.Stop)
// we are looking only at the time constraints of the scheduled requests (the new request is checked separately)
@@ -73,6 +82,8 @@ boolean checkShiftTimeConstraintsForScheduledRequests(Insertion insertion, doubl
}
}
+ double totalTimeLoss = detourTimeInfo.getTotalTimeLoss();
+
// all stops after the new (potential) dropoff are delayed by totalTimeLoss
// check if this delay satisfies the time constraints at these stops
for (int s = dropoffIdx; s < vEntry.stops.size(); s++) {
@@ -109,6 +120,31 @@ boolean checkShiftTimeConstraintsForScheduledRequests(Insertion insertion, doubl
return false;
}
}
+
+
+ // avoid shrinking break corridor too much (rather coarse for now)
+ if(currentShift.getBreak().isPresent()) {
+ DrtShiftBreak drtShiftBreak = currentShift.getBreak().get();
+ if(!drtShiftBreak.isScheduled()) {
+
+
+ if(detourTimeInfo.dropoffDetourInfo.arrivalTime < drtShiftBreak.getEarliestBreakStartTime()) {
+ // insertion finished before break corridor
+ //ok
+ } else if(detourTimeInfo.pickupDetourInfo.departureTime > drtShiftBreak.getLatestBreakEndTime()) {
+ // insertion start after break corridor
+ //ok
+ } else {
+ double remainingTime = drtShiftBreak.getLatestBreakEndTime() - detourTimeInfo.dropoffDetourInfo.arrivalTime;
+ if (remainingTime < drtShiftBreak.getDuration()) {
+ // no meaningful break possible after insertion
+ // (there could still be enough time before a prebooking though)
+ return false;
+ }
+ }
+ }
+ }
+
return true; //all time constraints of all stops are satisfied
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeModule.java
index 7df2d885723..8b52ca88951 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeModule.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeModule.java
@@ -14,7 +14,7 @@
import org.matsim.contrib.drt.extension.operations.shifts.io.DrtShiftsReader;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftBreakTaskImpl;
import org.matsim.contrib.drt.extension.operations.shifts.schedule.ShiftChangeoverTaskImpl;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.shifts.scheduler.ShiftTaskScheduler;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftsSpecification;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftsSpecificationImpl;
@@ -57,7 +57,7 @@ public ShiftDrtModeModule(DrtConfigGroup drtCfg) {
private static final Comparator taskTypeComparator = Comparator.comparing((Task.TaskType type) -> {
//we want the following order on the plot: STAY, RELOCATE, other
- if (type.equals(WaitForShiftStayTask.TYPE)) {
+ if (type.equals(WaitForShiftTask.TYPE)) {
return "F";
} else if (type.equals(ShiftChangeoverTaskImpl.TYPE)) {
return "E";
@@ -73,7 +73,7 @@ public ShiftDrtModeModule(DrtConfigGroup drtCfg) {
}).reversed();
private static final Map taskTypePaints = ImmutableMap.of(
- WaitForShiftStayTask.TYPE, Color.WHITE,
+ WaitForShiftTask.TYPE, Color.WHITE,
ShiftChangeoverTaskImpl.TYPE, Color.GRAY,
ShiftBreakTaskImpl.TYPE, Color.DARK_GRAY,
DrtStayTask.TYPE, Color.LIGHT_GRAY);
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java
index a6398faf3b3..a65de06b2c4 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/run/ShiftDrtModeOptimizerQSimModule.java
@@ -124,7 +124,9 @@ shiftsParams, new DefaultShiftStartLogic(), new DefaultAssignShiftToVehicleLogic
new DefaultInsertionCostCalculator(getter.getModal(CostCalculationStrategy.class),
drtCfg.addOrGetDrtOptimizationConstraintsParams().addOrGetDefaultDrtOptimizationConstraintsSet()))));
- bindModal(VehicleEntry.EntryFactory.class).toInstance(new ShiftVehicleDataEntryFactory(new VehicleDataEntryFactoryImpl()));
+ bindModal(VehicleEntry.EntryFactory.class).toInstance(
+ new ShiftVehicleDataEntryFactory(new VehicleDataEntryFactoryImpl(), shiftsParams.considerUpcomingShiftsForInsertion)
+ );
bindModal(DrtTaskFactory.class).toProvider(modalProvider(getter -> new ShiftDrtTaskFactoryImpl(new DrtTaskFactoryImpl(), getter.getModal(OperationFacilities.class))));
bindModal(ShiftDrtTaskFactory.class).toProvider(modalProvider(getter -> ((ShiftDrtTaskFactory) getter.getModal(DrtTaskFactory.class))));
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtActionCreator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtActionCreator.java
index 0f65e1208f0..5deb47eba47 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtActionCreator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtActionCreator.java
@@ -38,7 +38,7 @@ public DynAction createAction(DynAgent dynAgent, DvrpVehicle vehicle, double now
DrtStopTask t = (DrtStopTask) task;
return new DrtStopActivity(passengerHandler, dynAgent, t::getEndTime, t.getDropoffRequests(), t.getPickupRequests(),
DRT_SHIFT_CHANGEOVER_NAME);
- } else if (task instanceof WaitForShiftStayTask) {
+ } else if (task instanceof WaitForShiftTask) {
return new IdleDynActivity(DRT_SHIFT_WAIT_FOR_SHIFT_NAME, task::getEndTime);
} else {
return dynActionCreator.createAction(dynAgent, vehicle, now);
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtStayTaskEndTimeCalculator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtStayTaskEndTimeCalculator.java
index ddeaf4ffb9e..546f0843673 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtStayTaskEndTimeCalculator.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtStayTaskEndTimeCalculator.java
@@ -1,8 +1,8 @@
package org.matsim.contrib.drt.extension.operations.shifts.schedule;
+import com.google.common.base.Verify;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.matsim.contrib.drt.extension.operations.DrtOperationsParams;
import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShiftBreak;
import org.matsim.contrib.drt.schedule.DrtStayTaskEndTimeCalculator;
@@ -31,17 +31,21 @@ public ShiftDrtStayTaskEndTimeCalculator(ShiftsParams drtShiftParams, DrtStayTas
@Override
public double calcNewEndTime(DvrpVehicle vehicle, StayTask task, double newBeginTime) {
- if(task instanceof ShiftBreakTask) {
+ if (task instanceof WaitForShiftTask) {
+ Verify.verify(newBeginTime <= task.getEndTime(), "WaitForShiftTasks should not be delayed");
+ return task.getEndTime();
+ }
+ if (task instanceof ShiftBreakTask) {
final DrtShiftBreak shiftBreak = ((ShiftBreakTask) task).getShiftBreak();
return newBeginTime + shiftBreak.getDuration();
- } else if(task instanceof ShiftChangeOverTask) {
+ } else if (task instanceof ShiftChangeOverTask) {
return Math.max(newBeginTime, ((ShiftChangeOverTask) task).getShift().getEndTime()) + drtShiftParams.changeoverDuration;
- } else if(DrtTaskBaseType.getBaseTypeOrElseThrow(task).equals(DrtTaskBaseType.STAY)) {
+ } else if (DrtTaskBaseType.getBaseTypeOrElseThrow(task).equals(DrtTaskBaseType.STAY)) {
final List extends Task> tasks = vehicle.getSchedule().getTasks();
final int taskIdx = tasks.indexOf(task);
- if(tasks.size() > taskIdx+1) {
- final Task nextTask = tasks.get(taskIdx +1);
- if(nextTask instanceof ShiftChangeOverTask) {
+ if (tasks.size() > taskIdx + 1) {
+ final Task nextTask = tasks.get(taskIdx + 1);
+ if (nextTask instanceof ShiftChangeOverTask) {
return Math.max(newBeginTime, ((ShiftChangeOverTask) nextTask).getShift().getEndTime());
}
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactory.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactory.java
index 9de610a8b84..eaaf5c371ef 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactory.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactory.java
@@ -18,6 +18,6 @@ ShiftBreakTask createShiftBreakTask(DvrpVehicle vehicle, double beginTime, doubl
ShiftChangeOverTask createShiftChangeoverTask(DvrpVehicle vehicle, double beginTime, double endTime,
Link link, DrtShift shift, OperationFacility facility);
- WaitForShiftStayTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link,
- OperationFacility facility);
+ WaitForShiftTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link,
+ OperationFacility facility);
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java
index 57460d2bee6..e59d40dbac6 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/ShiftDrtTaskFactoryImpl.java
@@ -58,9 +58,9 @@ public ShiftChangeOverTask createShiftChangeoverTask(DvrpVehicle vehicle, double
}
@Override
- public WaitForShiftStayTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime,
- Link link, OperationFacility facility) {
- return new WaitForShiftStayTask(beginTime, endTime, link, facility);
+ public WaitForShiftTask createWaitForShiftStayTask(DvrpVehicle vehicle, double beginTime, double endTime,
+ Link link, OperationFacility facility) {
+ return new WaitForShiftTask(beginTime, endTime, link, facility);
}
public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime, double endTime, Link link) {
@@ -71,7 +71,7 @@ public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime,
} catch (Throwable e) {
throw new RuntimeException(e);
}
- WaitForShiftStayTask waitForShiftStayTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(),
+ WaitForShiftTask waitForShiftStayTask = createWaitForShiftStayTask(vehicle, vehicle.getServiceBeginTime(), vehicle.getServiceEndTime(),
vehicle.getStartLink(), operationFacility);
boolean success = operationFacility.register(vehicle.getId());
if (!success) {
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftStayTask.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftStayTask.java
deleted file mode 100644
index 25556e16db7..00000000000
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftStayTask.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.matsim.contrib.drt.extension.operations.shifts.schedule;
-
-import org.matsim.api.core.v01.network.Link;
-import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility;
-import org.matsim.contrib.drt.schedule.DrtTaskType;
-import org.matsim.contrib.dvrp.schedule.DefaultStayTask;
-
-import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY;
-
-/**
- * @author nkuehnel / MOIA
- */
-public class WaitForShiftStayTask extends DefaultStayTask implements OperationalStop {
-
- public static final DrtTaskType TYPE = new DrtTaskType("WAIT_FOR_SHIFT", STAY);
-
- private final OperationFacility facility;
-
- public WaitForShiftStayTask(double beginTime, double endTime, Link link, OperationFacility facility) {
- super(TYPE, beginTime, endTime, link);
- this.facility = facility;
- }
-
- @Override
- public OperationFacility getFacility() {
- return facility;
- }
-
-}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftTask.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftTask.java
new file mode 100644
index 00000000000..dcb0e9a1927
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/schedule/WaitForShiftTask.java
@@ -0,0 +1,65 @@
+package org.matsim.contrib.drt.extension.operations.shifts.schedule;
+
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility;
+import org.matsim.contrib.drt.passenger.AcceptedDrtRequest;
+import org.matsim.contrib.drt.schedule.DrtStopTask;
+import org.matsim.contrib.drt.schedule.DrtTaskType;
+import org.matsim.contrib.dvrp.optimizer.Request;
+import org.matsim.contrib.dvrp.schedule.DefaultStayTask;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STOP;
+
+/**
+ * @author nkuehnel / MOIA
+ */
+public class WaitForShiftTask extends DefaultStayTask implements DrtStopTask, OperationalStop {
+
+ public static final DrtTaskType TYPE = new DrtTaskType("WAIT_FOR_SHIFT", STOP);
+
+ private final OperationFacility facility;
+
+ public WaitForShiftTask(double beginTime, double endTime, Link link, OperationFacility facility) {
+ super(TYPE, beginTime, endTime, link);
+ this.facility = facility;
+ }
+
+ @Override
+ public OperationFacility getFacility() {
+ return facility;
+ }
+
+ @Override
+ public Map, AcceptedDrtRequest> getDropoffRequests() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map, AcceptedDrtRequest> getPickupRequests() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public void addDropoffRequest(AcceptedDrtRequest request) {
+ throw new RuntimeException("Not supported");
+ }
+
+ @Override
+ public void addPickupRequest(AcceptedDrtRequest request) {
+ throw new RuntimeException("Not supported");
+ }
+
+ @Override
+ public void removePickupRequest(Id requestId) {
+ throw new RuntimeException("Not supported");
+ }
+
+ @Override
+ public void removeDropoffRequest(Id requestId) {
+ throw new RuntimeException("Not supported");
+ }
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftDrtScheduleInquiry.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftDrtScheduleInquiry.java
index 7fb582caea6..d598bb29b13 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftDrtScheduleInquiry.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftDrtScheduleInquiry.java
@@ -2,13 +2,13 @@
import com.google.inject.Inject;
import org.matsim.contrib.drt.extension.operations.shifts.fleet.ShiftDvrpVehicle;
+import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftTask;
import org.matsim.contrib.drt.extension.operations.shifts.shift.DrtShift;
import org.matsim.contrib.drt.scheduler.DrtScheduleInquiry;
import org.matsim.contrib.dvrp.fleet.DvrpVehicle;
import org.matsim.contrib.dvrp.schedule.Schedule;
import org.matsim.contrib.dvrp.schedule.ScheduleInquiry;
import org.matsim.contrib.dvrp.schedule.Task;
-import org.matsim.contrib.drt.extension.operations.shifts.schedule.WaitForShiftStayTask;
import org.matsim.core.mobsim.framework.MobsimTimer;
import static org.matsim.contrib.drt.schedule.DrtTaskBaseType.STAY;
@@ -42,7 +42,7 @@ public boolean isIdle(DvrpVehicle vehicle) {
}
}
Task currentTask = schedule.getCurrentTask();
- if(currentTask instanceof WaitForShiftStayTask) {
+ if(currentTask instanceof WaitForShiftTask) {
return false;
}
return currentTask.getTaskIdx() == schedule.getTaskCount() - 1
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskScheduler.java
index 2b9b3415d5c..dc8187c0fce 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskScheduler.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskScheduler.java
@@ -23,4 +23,8 @@ public interface ShiftTaskScheduler {
boolean updateShiftChange(ShiftDvrpVehicle vehicle, Link link, DrtShift shift,
LinkTimePair start, OperationFacility facility, Task lastTask);
+
+ void planAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift);
+
+ void cancelAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift);
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java
index d6d272371e9..94b5c3d0fed 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/scheduler/ShiftTaskSchedulerImpl.java
@@ -18,10 +18,7 @@
import org.matsim.contrib.dvrp.fleet.Fleet;
import org.matsim.contrib.dvrp.path.VrpPathWithTravelData;
import org.matsim.contrib.dvrp.path.VrpPaths;
-import org.matsim.contrib.dvrp.schedule.DriveTask;
-import org.matsim.contrib.dvrp.schedule.Schedule;
-import org.matsim.contrib.dvrp.schedule.StayTask;
-import org.matsim.contrib.dvrp.schedule.Task;
+import org.matsim.contrib.dvrp.schedule.*;
import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker;
import org.matsim.contrib.dvrp.util.LinkTimePair;
import org.matsim.core.mobsim.framework.MobsimTimer;
@@ -95,7 +92,7 @@ public void relocateForBreak(ShiftDvrpVehicle vehicle, OperationFacility breakFa
double startTime = path.getArrivalTime();
double endTime = startTime + shift.getBreak().orElseThrow().getDuration();
- double latestDetourArrival = path.getDepartureTime() + path.getTravelTime() + 1.5;
+ double latestDetourArrival = path.getDepartureTime() + path.getTravelTime() * 1.5;
relocateForBreakImpl(vehicle, startTime, endTime, latestDetourArrival, toLink, shift, breakFacility);
} else {
@@ -156,10 +153,10 @@ private void relocateForBreakImpl(ShiftDvrpVehicle vehicle, double startTime, do
// append SHIFT_BREAK task
DrtShiftBreak shiftBreak = shift.getBreak().orElseThrow();
- ShiftBreakTask dropoffStopTask = taskFactory.createShiftBreakTask(vehicle, startTime,
+ ShiftBreakTask shiftBreakTask = taskFactory.createShiftBreakTask(vehicle, startTime,
endTime, link, shiftBreak, breakFacility);
- schedule.addTask(dropoffStopTask);
+ schedule.addTask(shiftBreakTask);
schedule.addTask(taskFactory.createStayTask(vehicle, endTime, shift.getEndTime(),
link));
@@ -266,10 +263,13 @@ private void appendShiftChange(DvrpVehicle vehicle, DrtShift shift, OperationFac
public void startShift(ShiftDvrpVehicle vehicle, double now, DrtShift shift) {
Schedule schedule = vehicle.getSchedule();
StayTask stayTask = (StayTask) schedule.getCurrentTask();
- if (stayTask instanceof WaitForShiftStayTask) {
- ((WaitForShiftStayTask) stayTask).getFacility().deregisterVehicle(vehicle.getId());
+ if (stayTask instanceof WaitForShiftTask) {
+ ((WaitForShiftTask) stayTask).getFacility().deregisterVehicle(vehicle.getId());
stayTask.setEndTime(now);
- schedule.addTask(taskFactory.createStayTask(vehicle, now, shift.getEndTime(), stayTask.getLink()));
+ if(Schedules.getLastTask(schedule).equals(stayTask)) {
+ //nothing planned yet.
+ schedule.addTask(taskFactory.createStayTask(vehicle, now, shift.getEndTime(), stayTask.getLink()));
+ }
} else {
throw new IllegalStateException("Vehicle cannot start shift during task:" + stayTask.getTaskType().name());
}
@@ -291,6 +291,24 @@ public boolean updateShiftChange(ShiftDvrpVehicle vehicle, Link link, DrtShift s
return false;
}
+ @Override
+ public void planAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) {
+ Schedule schedule = vehicle.getSchedule();
+ StayTask stayTask = (StayTask) schedule.getCurrentTask();
+ if (stayTask instanceof WaitForShiftTask) {
+ stayTask.setEndTime(Math.max(timeStep, shift.getStartTime()));
+ }
+ }
+
+ @Override
+ public void cancelAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) {
+ Schedule schedule = vehicle.getSchedule();
+ StayTask stayTask = (StayTask) schedule.getCurrentTask();
+ if (stayTask instanceof WaitForShiftTask) {
+ stayTask.setEndTime(vehicle.getServiceEndTime());
+ }
+ }
+
private void updateShiftChangeImpl(DvrpVehicle vehicle, VrpPathWithTravelData vrpPath,
DrtShift shift, OperationFacility facility, Task lastTask) {
Schedule schedule = vehicle.getSchedule();
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DefaultShiftBreakImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DefaultShiftBreakImpl.java
index 07b094f3dc0..10f36a1d387 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DefaultShiftBreakImpl.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DefaultShiftBreakImpl.java
@@ -54,9 +54,4 @@ public boolean isScheduled() {
public double getScheduledLatestArrival() {
return latestArrivalTime;
}
-
- @Override
- public void reset() {
- this.latestArrivalTime = UNSCHEDULED_ARRIVAL_TIME;
- }
}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DrtShiftBreak.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DrtShiftBreak.java
index 2009dcd02f6..86e5500401a 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DrtShiftBreak.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/shift/DrtShiftBreak.java
@@ -16,6 +16,4 @@ public interface DrtShiftBreak {
boolean isScheduled();
double getScheduledLatestArrival();
-
- void reset();
}
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
index 2da1b30b225..fc58f3b3b63 100644
--- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java
@@ -135,7 +135,7 @@ void test() {
stratSets.setStrategyName("ChangeExpBeta");
config.replanning().addStrategySettings(stratSets);
- config.controller().setLastIteration(2);
+ config.controller().setLastIteration(1);
config.controller().setWriteEventsInterval(1);
config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
@@ -184,7 +184,7 @@ public void install() {
}
run.run();
- Assertions.assertEquals(23817, linkCounter.getLinkLeaveCount());
+ Assertions.assertEquals(20842, linkCounter.getLinkLeaveCount());
}
static class LinkCounter implements LinkLeaveEventHandler {
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java
new file mode 100644
index 00000000000..5babef611b3
--- /dev/null
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/operations/shifts/run/RunPrebookingShiftDrtScenarioIT.java
@@ -0,0 +1,329 @@
+package org.matsim.contrib.drt.extension.operations.shifts.run;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.matsim.api.core.v01.Coord;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.api.core.v01.network.Node;
+import org.matsim.api.core.v01.population.*;
+import org.matsim.contrib.common.zones.systems.grid.square.SquareGridZoneSystemParams;
+import org.matsim.contrib.drt.analysis.zonal.DrtZoneSystemParams;
+import org.matsim.contrib.drt.extension.DrtWithExtensionsConfigGroup;
+import org.matsim.contrib.drt.extension.operations.DrtOperationsControlerCreator;
+import org.matsim.contrib.drt.extension.operations.DrtOperationsParams;
+import org.matsim.contrib.drt.extension.operations.operationFacilities.*;
+import org.matsim.contrib.drt.extension.operations.shifts.config.ShiftsParams;
+import org.matsim.contrib.drt.extension.operations.shifts.shift.*;
+import org.matsim.contrib.drt.optimizer.constraints.DefaultDrtOptimizationConstraintsSet;
+import org.matsim.contrib.drt.optimizer.insertion.extensive.ExtensiveInsertionSearchParams;
+import org.matsim.contrib.drt.optimizer.rebalancing.RebalancingParams;
+import org.matsim.contrib.drt.optimizer.rebalancing.mincostflow.MinCostFlowRebalancingStrategyParams;
+import org.matsim.contrib.drt.prebooking.PrebookingModeQSimModule;
+import org.matsim.contrib.drt.prebooking.PrebookingParams;
+import org.matsim.contrib.drt.prebooking.logic.AttributeBasedPrebookingLogic;
+import org.matsim.contrib.drt.run.DrtConfigGroup;
+import org.matsim.contrib.drt.run.DrtControlerCreator;
+import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
+import org.matsim.contrib.dvrp.fleet.DvrpVehicle;
+import org.matsim.contrib.dvrp.fleet.FleetSpecification;
+import org.matsim.contrib.dvrp.fleet.FleetSpecificationImpl;
+import org.matsim.contrib.dvrp.fleet.ImmutableDvrpVehicleSpecification;
+import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler;
+import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
+import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
+import org.matsim.contrib.zone.skims.DvrpTravelTimeMatrixParams;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigGroup;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.config.groups.QSimConfigGroup;
+import org.matsim.core.config.groups.ReplanningConfigGroup;
+import org.matsim.core.config.groups.ScoringConfigGroup;
+import org.matsim.core.controler.AbstractModule;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.network.NetworkUtils;
+import org.matsim.core.population.PopulationUtils;
+import org.matsim.core.utils.geometry.CoordUtils;
+
+import java.util.HashSet;
+import java.util.Set;
+
+
+
+/**
+ * @author nkuehnel / MOIA
+ */
+public class RunPrebookingShiftDrtScenarioIT {
+
+
+ @Test
+ void test() {
+
+ MultiModeDrtConfigGroup multiModeDrtConfigGroup = new MultiModeDrtConfigGroup(DrtWithExtensionsConfigGroup::new);
+
+ DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup = (DrtWithExtensionsConfigGroup) multiModeDrtConfigGroup.createParameterSet("drt");
+ drtWithShiftsConfigGroup.mode = TransportMode.drt;
+ DefaultDrtOptimizationConstraintsSet defaultConstraintsSet =
+ (DefaultDrtOptimizationConstraintsSet) drtWithShiftsConfigGroup.addOrGetDrtOptimizationConstraintsParams()
+ .addOrGetDefaultDrtOptimizationConstraintsSet();
+ drtWithShiftsConfigGroup.stopDuration = 30.;
+ defaultConstraintsSet.maxTravelTimeAlpha = 1.5;
+ defaultConstraintsSet.maxTravelTimeBeta = 10. * 60.;
+ defaultConstraintsSet.maxWaitTime = 600.;
+ defaultConstraintsSet.rejectRequestIfMaxWaitOrTravelTimeViolated = true;
+ defaultConstraintsSet.maxWalkDistance = 1000.;
+ drtWithShiftsConfigGroup.operationalScheme = DrtConfigGroup.OperationalScheme.door2door;
+
+ drtWithShiftsConfigGroup.addParameterSet(new ExtensiveInsertionSearchParams());
+
+ ConfigGroup rebalancing = drtWithShiftsConfigGroup.createParameterSet("rebalancing");
+ drtWithShiftsConfigGroup.addParameterSet(rebalancing);
+ ((RebalancingParams) rebalancing).interval = 600;
+
+ MinCostFlowRebalancingStrategyParams strategyParams = new MinCostFlowRebalancingStrategyParams();
+ strategyParams.targetAlpha = 0.3;
+ strategyParams.targetBeta = 0.3;
+
+ drtWithShiftsConfigGroup.getRebalancingParams().get().addParameterSet(strategyParams);
+
+ SquareGridZoneSystemParams zoneParams = new SquareGridZoneSystemParams();
+ zoneParams.cellSize = 500.;
+
+ DrtZoneSystemParams drtZoneSystemParams = new DrtZoneSystemParams();
+ drtZoneSystemParams.addParameterSet(zoneParams);
+ drtWithShiftsConfigGroup.addParameterSet(drtZoneSystemParams);
+
+ DvrpConfigGroup dvrpConfigGroup = new DvrpConfigGroup();
+ DvrpTravelTimeMatrixParams matrixParams = dvrpConfigGroup.getTravelTimeMatrixParams();
+ matrixParams.addParameterSet(zoneParams);
+
+ multiModeDrtConfigGroup.addParameterSet(drtWithShiftsConfigGroup);
+
+ final Config config = ConfigUtils.createConfig(multiModeDrtConfigGroup,
+ dvrpConfigGroup);
+
+ Set modes = new HashSet<>();
+ modes.add("drt");
+ config.travelTimeCalculator().setAnalyzedModes(modes);
+
+ ScoringConfigGroup.ModeParams scoreParams = new ScoringConfigGroup.ModeParams("drt");
+ config.scoring().addModeParams(scoreParams);
+ ScoringConfigGroup.ModeParams scoreParams2 = new ScoringConfigGroup.ModeParams("walk");
+ config.scoring().addModeParams(scoreParams2);
+
+ final ScoringConfigGroup.ActivityParams start = new ScoringConfigGroup.ActivityParams("start");
+ start.setScoringThisActivityAtAll(false);
+ final ScoringConfigGroup.ActivityParams end = new ScoringConfigGroup.ActivityParams("end");
+ end.setScoringThisActivityAtAll(false);
+
+ config.scoring().addActivityParams(start);
+ config.scoring().addActivityParams(end);
+
+ config.qsim().setSimStarttimeInterpretation(QSimConfigGroup.StarttimeInterpretation.onlyUseStarttime);
+ config.qsim().setSimEndtimeInterpretation(QSimConfigGroup.EndtimeInterpretation.minOfEndtimeAndMobsimFinished);
+
+ final ReplanningConfigGroup.StrategySettings stratSets = new ReplanningConfigGroup.StrategySettings();
+ stratSets.setWeight(1);
+ stratSets.setStrategyName("ChangeExpBeta");
+ config.replanning().addStrategySettings(stratSets);
+
+ config.controller().setLastIteration(0);
+ config.controller().setWriteEventsInterval(1);
+
+ config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
+ config.controller().setOutputDirectory("test/output/prebooking_shifts");
+
+ DrtOperationsParams operationsParams = (DrtOperationsParams) drtWithShiftsConfigGroup.createParameterSet(DrtOperationsParams.SET_NAME);
+ ShiftsParams shiftsParams = (ShiftsParams) operationsParams.createParameterSet(ShiftsParams.SET_NAME);
+ OperationFacilitiesParams operationFacilitiesParams = (OperationFacilitiesParams) operationsParams.createParameterSet(OperationFacilitiesParams.SET_NAME);
+ operationsParams.addParameterSet(shiftsParams);
+ operationsParams.addParameterSet(operationFacilitiesParams);
+
+ shiftsParams.considerUpcomingShiftsForInsertion = true;
+ shiftsParams.shiftEndLookAhead = 900.;
+ drtWithShiftsConfigGroup.addParameterSet(operationsParams);
+
+ PrebookingParams prebookingParams = new PrebookingParams();
+ prebookingParams.maximumPassengerDelay = 600;
+ prebookingParams.unschedulingMode = PrebookingParams.UnschedulingMode.Routing;
+ prebookingParams.scheduleWaitBeforeDrive = true;
+ drtWithShiftsConfigGroup.addParameterSet(prebookingParams);
+
+ Scenario scenario = DrtControlerCreator.createScenarioWithDrtRouteFactory(config);
+ prepareNetwork(scenario);
+ preparePopulation(scenario);
+
+ final Controler run = DrtOperationsControlerCreator.createControler(config, scenario, false);
+ prepareOperations(run, drtWithShiftsConfigGroup);
+
+ run.addOverridingQSimModule(new PrebookingModeQSimModule(drtWithShiftsConfigGroup.getMode(),
+ prebookingParams));
+ AttributeBasedPrebookingLogic.install(run, drtWithShiftsConfigGroup);
+
+ Set> rejectedPersons = new HashSet<>();
+ run.addOverridingModule(new AbstractModule() {
+ @Override
+ public void install() {
+ addEventHandlerBinding().toInstance((PassengerRequestRejectedEventHandler) event -> rejectedPersons.addAll(event.getPersonIds()));
+ }
+ });
+
+ run.run();
+
+
+ Assertions.assertFalse(rejectedPersons.contains(Id.createPersonId(1)));
+ Assertions.assertTrue(rejectedPersons.contains(Id.createPersonId(2)));
+ Assertions.assertFalse(rejectedPersons.contains(Id.createPersonId(3)));
+ Assertions.assertTrue(rejectedPersons.contains(Id.createPersonId(4)));
+ Assertions.assertFalse(rejectedPersons.contains(Id.createPersonId(5)));
+ Assertions.assertTrue(rejectedPersons.contains(Id.createPersonId(6)));
+ }
+
+ private void preparePopulation(Scenario scenario) {
+ Population population = scenario.getPopulation();
+ PopulationFactory factory = PopulationUtils.getFactory();
+
+ //person 1 - prebooking submitted once shift is assigned (but not started) for time when shift should be active - ok
+ {
+ Person person = factory.createPerson(Id.createPersonId(1));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(5000);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 1800.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5000.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+
+ //person 2 - prebooking submitted before shift is assigned for time when shift should be active - rejected
+ {
+ Person person = factory.createPerson(Id.createPersonId(2));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(5000);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 900.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5000.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+
+ //person 3 - prebooking submitted during shift for time when shift should be active - ok
+ {
+ Person person = factory.createPerson(Id.createPersonId(3));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(5000);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 5000.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+
+ //person 4 - prebooking submitted during shift for time when shift should be ended - rejected
+ {
+ Person person = factory.createPerson(Id.createPersonId(4));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(8000);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 11000.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+
+ //person 5 - prebooking submitted during shift for time which falls into break beginning of break corridor with enough remaining time - ok
+ {
+ Person person = factory.createPerson(Id.createPersonId(5));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(6000.);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 6000.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+
+ //person 6 - prebooking submitted during shift for time which would preclude meaningful break - rejected
+ {
+ Person person = factory.createPerson(Id.createPersonId(6));
+ Plan plan = factory.createPlan();
+ Activity start = factory.createActivityFromLinkId("start", Id.createLinkId(1));
+ start.setEndTime(6500.);
+ start.getAttributes().putAttribute("prebooking:submissionTime" + "drt", 4000.);
+ start.getAttributes().putAttribute("prebooking:plannedDepartureTime" + "drt", 6500.);
+ plan.addActivity(start);
+ plan.addLeg(factory.createLeg("drt"));
+ plan.addActivity(factory.createActivityFromLinkId("end", Id.createLinkId(2)));
+ person.addPlan(plan);
+ population.addPerson(person);
+ }
+ }
+
+ private static void prepareOperations(Controler run, DrtWithExtensionsConfigGroup drtWithShiftsConfigGroup) {
+ FleetSpecification fleetSpecification = new FleetSpecificationImpl();
+ fleetSpecification.addVehicleSpecification(ImmutableDvrpVehicleSpecification.newBuilder() //
+ .id(Id.create("v1", DvrpVehicle.class)) //
+ .capacity(1) //
+ .serviceBeginTime(0.0) //
+ .serviceEndTime(24 * 3600) //
+ .startLinkId(Id.createLinkId(1)) //
+ .build());
+
+ OperationFacilitiesSpecification opFasSpecification = new OperationFacilitiesSpecificationImpl();
+ opFasSpecification.addOperationFacilitySpecification(OperationFacilitySpecificationImpl
+ .newBuilder()
+ .capacity(1)
+ .type(OperationFacilityType.hub)
+ .coord(new Coord(1000, 1000))
+ .linkId(Id.createLinkId(1))
+ .id(Id.create(1, OperationFacility.class))
+ .build());
+
+ DrtShiftsSpecification shiftsSpecification = new DrtShiftsSpecificationImpl();
+ shiftsSpecification.addShiftSpecification(DrtShiftSpecificationImpl.newBuilder()
+ .start(3600)
+ .end(10800)
+ .id(Id.create(1, DrtShift.class))
+ .shiftBreak(DrtShiftBreakSpecificationImpl.newBuilder().duration(600.).earliestStart(6000.).latestEnd(7000.).build())
+ .operationFacility(Id.create(1, OperationFacility.class))
+ .build()
+ );
+ run.addOverridingModule(new AbstractDvrpModeModule(drtWithShiftsConfigGroup.getMode()) {
+ @Override
+ public void install() {
+ bindModal(FleetSpecification.class).toInstance(fleetSpecification);
+ bindModal(OperationFacilitiesSpecification.class).toInstance(opFasSpecification);
+ bindModal(DrtShiftsSpecification.class).toInstance(shiftsSpecification);
+ }
+ });
+
+ }
+
+ private void prepareNetwork(Scenario scenario) {
+ Network network = scenario.getNetwork();
+ Node node1 = NetworkUtils.createAndAddNode(network, Id.createNodeId(1), new Coord(0, 0));
+ Node node2 = NetworkUtils.createAndAddNode(network, Id.createNodeId(2), new Coord(1000, 1000));
+
+ NetworkUtils.createAndAddLink(network, Id.createLinkId(1), node1, node2, CoordUtils.length(node2.getCoord()), 50 / 3.6, 100, 1, null, null);
+ NetworkUtils.createAndAddLink(network, Id.createLinkId(2), node2, node1, CoordUtils.length(node2.getCoord()), 50 / 3.6, 100, 1, null, null);
+ }
+
+}
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java
index ab438acc805..1b4435829f1 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/run/DrtControlerCreator.java
@@ -60,11 +60,22 @@ public static Scenario createScenarioWithDrtRouteFactory(Config config) {
* @return
*/
public static Controler createControler(Config config, boolean otfvis) {
- MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
- DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing());
-
Scenario scenario = createScenarioWithDrtRouteFactory(config);
ScenarioUtils.loadScenario(scenario);
+ return createControler(config, scenario, otfvis);
+ }
+
+ /**
+ * Creates a controller in one step.
+ *
+ * @param config
+ * @param scenario
+ * @param otfvis
+ * @return
+ */
+ public static Controler createControler(Config config, Scenario scenario, boolean otfvis) {
+ MultiModeDrtConfigGroup multiModeDrtConfig = MultiModeDrtConfigGroup.get(config);
+ DrtConfigs.adjustMultiModeDrtConfig(multiModeDrtConfig, config.scoring(), config.routing());
Controler controler = new Controler(scenario);
controler.addOverridingModule(new DvrpModule());