Skip to content

Commit

Permalink
Merge pull request #3001 from moia-oss/shiftEntryRecord
Browse files Browse the repository at this point in the history
DRT: fix initialization of shift dispatcher
  • Loading branch information
nkuehnel authored Dec 18, 2023
2 parents c45c60e + bd1a4bb commit adbaf7d
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public EDrtShiftDispatcherImpl(EShiftTaskScheduler shiftTaskScheduler, ChargingI
this.fleet = fleet;
}

@Override
public void initialize() {
delegate.initialize();
}

@Override
public void dispatch(double timeStep) {
delegate.dispatch(timeStep);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public EDrtShiftStartLogic(ShiftStartLogic delegate) {

@Override
public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry shiftEntry) {
Schedule schedule = shiftEntry.vehicle.getSchedule();
Schedule schedule = shiftEntry.vehicle().getSchedule();
Task currentTask = schedule.getCurrentTask();
if (currentTask instanceof EDrtWaitForShiftStayTask) {
//check whether vehicle still needs to complete charging task
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ public class DefaultShiftStartLogic implements ShiftStartLogic {
@Override
public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry peek) {
// old shift hasn't ended yet
if (!peek.shift.equals(peek.vehicle.getShifts().peek())) {
if (!peek.shift().equals(peek.vehicle().getShifts().peek())) {
return false;
}
Schedule schedule = peek.vehicle.getSchedule();
Schedule schedule = peek.vehicle().getSchedule();

// only active vehicles
if (schedule.getStatus() != Schedule.ScheduleStatus.STARTED) {
Expand All @@ -36,8 +36,8 @@ public boolean shiftStarts(DrtShiftDispatcher.ShiftEntry peek) {
Task currentTask = schedule.getCurrentTask();
if(currentTask instanceof WaitForShiftStayTask) {
//check if optional location requirement is met
if(peek.shift.getOperationFacilityId().isPresent()) {
Id<OperationFacility> operationFacilityId = peek.shift.getOperationFacilityId().get();
if(peek.shift().getOperationFacilityId().isPresent()) {
Id<OperationFacility> operationFacilityId = peek.shift().getOperationFacilityId().get();
Verify.verify((operationFacilityId.equals(((WaitForShiftStayTask) currentTask).getFacility().getId())),
"Vehicle and shift start locations do not match.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,9 @@
*/
public interface DrtShiftDispatcher {

final class ShiftEntry {
public final DrtShift shift;
public final ShiftDvrpVehicle vehicle;

public ShiftEntry(DrtShift shift, ShiftDvrpVehicle vehicle) {
this.shift = shift;
this.vehicle = vehicle;
}
}
void initialize();

record ShiftEntry(DrtShift shift, ShiftDvrpVehicle vehicle){}

void dispatch(double timeStep);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,15 @@ public DrtShiftDispatcherImpl(DrtShifts shifts, Fleet fleet, MobsimTimer timer,
this.drtShiftParams = drtShiftParams;
this.shiftStartLogic = shiftStartLogic;
this.assignShiftToVehicleLogic = assignShiftToVehicleLogic;

createQueues();
}

@Override
public void initialize() {

private void createQueues() {
unscheduledShifts = new PriorityQueue<>(Comparator.comparingDouble(DrtShift::getStartTime));
unscheduledShifts.addAll(shifts.getShifts().values());

assignedShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getStartTime()));
assignedShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getStartTime()));

idleVehiclesQueues = new LinkedHashMap<>();
for(OperationFacility facility: operationFacilities.getDrtOperationFacilities().values()) {
Expand All @@ -112,11 +111,11 @@ private void createQueues() {
queue
);
}
activeShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getEndTime()));
endingShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift.getEndTime()));
activeShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime()));
endingShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime()));
}

@Override
@Override
public void dispatch(double timeStep) {
if(timeStep % drtShiftParams.loggingInterval == 0) {
logger.info(String.format("Active shifts: %s | Assigned shifts: %s | Unscheduled shifts: %s",
Expand All @@ -136,13 +135,13 @@ public void dispatch(double timeStep) {

private void checkBreaks() {
for (ShiftEntry activeShift : activeShifts) {
final DrtShift shift = activeShift.shift;
final DrtShift shift = activeShift.shift();
if (shift != null && shift.isStarted()) {
OperationFacility breakFacility = decideOnBreak(activeShift);
if (breakFacility != null) {
shiftTaskScheduler.relocateForBreak(activeShift.vehicle, breakFacility, shift);
shiftTaskScheduler.relocateForBreak(activeShift.vehicle(), breakFacility, shift);
eventsManager.processEvent(new DrtShiftBreakScheduledEvent(timer.getTimeOfDay(), shift.getId(),
activeShift.vehicle.getId(), breakFacility.getLinkId(),
activeShift.vehicle().getId(), breakFacility.getLinkId(),
shift.getBreak().orElseThrow().getScheduledLatestArrival()));
}
}
Expand All @@ -154,23 +153,23 @@ private void startShifts(double timeStep) {
final Iterator<ShiftEntry> iterator = this.assignedShifts.iterator();
while (iterator.hasNext()) {
final ShiftEntry next = iterator.next();
if (next.shift.getStartTime() > timeStep) {
if (next.shift().getStartTime() > timeStep) {
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 (next.shift().getEndTime() < timeStep) {
logger.warn("Too late to start shift " + next.shift().getId());
next.vehicle().getShifts().remove(next.shift());
iterator.remove();
continue;
}

if (shiftStartLogic.shiftStarts(next)) {
next.shift.start();
shiftTaskScheduler.startShift(next.vehicle, timeStep, next.shift);
next.shift().start();
shiftTaskScheduler.startShift(next.vehicle(), timeStep, next.shift());
activeShifts.add(next);
iterator.remove();
logger.debug("Started shift " + next.shift);
StayTask currentTask = (StayTask) next.vehicle.getSchedule().getCurrentTask();
eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, next.shift.getId(), next.vehicle.getId(),
logger.debug("Started shift " + next.shift());
StayTask currentTask = (StayTask) next.vehicle().getSchedule().getCurrentTask();
eventsManager.processEvent(new DrtShiftStartedEvent(timeStep, next.shift().getId(), next.vehicle().getId(),
currentTask.getLink().getId()));
}
}
Expand All @@ -190,29 +189,29 @@ private void assignShifts(double timeStep) {
ShiftDvrpVehicle vehicle = null;

for (ShiftEntry active : activeShifts) {
if (active.shift.getEndTime() > shift.getStartTime()) {
if (active.shift().getEndTime() > shift.getStartTime()) {
break;
}
if(shift.getOperationFacilityId().isPresent()) {
//we have to check that the vehicle ends the previous shift at the same facility where
//the new shift is to start.
if(active.shift.getOperationFacilityId().isPresent()) {
if(!active.shift.getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) {
if(active.shift().getOperationFacilityId().isPresent()) {
if(!active.shift().getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) {
continue;
}
} else {
Optional<ShiftChangeOverTask> nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle.getSchedule());
Optional<ShiftChangeOverTask> nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle().getSchedule());
if(nextShiftChangeover.isPresent()) {
Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift));
Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift()));
if(!nextShiftChangeover.get().getFacility().getId().equals(shift.getOperationFacilityId().get())) {
// there is already a shift changeover scheduled elsewhere
continue;
}
}
}
}
if (assignShiftToVehicleLogic.canAssignVehicleToShift(active.vehicle, shift)) {
vehicle = active.vehicle;
if (assignShiftToVehicleLogic.canAssignVehicleToShift(active.vehicle(), shift)) {
vehicle = active.vehicle();
break;
}
}
Expand Down Expand Up @@ -266,17 +265,17 @@ private void endShifts(double timeStep) {
while (iterator.hasNext()) {
final ShiftEntry next = iterator.next();

if (timeStep + drtShiftParams.shiftEndLookAhead < next.shift.getEndTime()) {
if (timeStep + drtShiftParams.shiftEndLookAhead < next.shift().getEndTime()) {
continue;
}

final DrtShift active = next.shift;
final DrtShift active = next.shift();

if (active != next.vehicle.getShifts().peek()) {
if (active != next.vehicle().getShifts().peek()) {
throw new IllegalStateException("Shifts don't match!");
}

logger.debug("Scheduling shift end for shift " + next.shift.getId() + " of vehicle " + next.vehicle.getId());
logger.debug("Scheduling shift end for shift " + next.shift().getId() + " of vehicle " + next.vehicle().getId());
scheduleShiftEnd(next);
endingShifts.add(next);
iterator.remove();
Expand All @@ -287,12 +286,12 @@ private void updateShiftEnds(double timeStep) {
final Iterator<ShiftEntry> endingShiftsIterator = this.endingShifts.iterator();
while (endingShiftsIterator.hasNext()) {
final ShiftEntry next = endingShiftsIterator.next();
if (next.shift.isEnded()) {
if (next.shift().isEnded()) {
endingShiftsIterator.remove();
continue;
}
if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift.getEndTime()) {
if (next.vehicle.getShifts().size() > 1) {
if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift().getEndTime()) {
if (next.vehicle().getShifts().size() > 1) {
updateShiftEnd(next);
}
} else {
Expand All @@ -303,17 +302,17 @@ private void updateShiftEnds(double timeStep) {

private void updateShiftEnd(ShiftEntry next) {

if(next.shift.getOperationFacilityId().isPresent()) {
if(next.shift().getOperationFacilityId().isPresent()) {
//start and end facility are fixed
return;
}

final List<? extends Task> tasks = next.vehicle.getSchedule().getTasks();
final List<? extends Task> tasks = next.vehicle().getSchedule().getTasks();

Task lastTask = null;
LinkTimePair start = null;
ShiftChangeOverTask changeOverTask = null;
final Task currentTask = next.vehicle.getSchedule().getCurrentTask();
final Task currentTask = next.vehicle().getSchedule().getCurrentTask();
for (Task task : tasks.subList(currentTask.getTaskIdx(), tasks.size())) {
if (task instanceof ShiftChangeOverTask) {
changeOverTask = (ShiftChangeOverTask) task;
Expand Down Expand Up @@ -359,21 +358,21 @@ private void updateShiftEnd(ShiftEntry next) {
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,
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());
shiftChangeFacility.register(next.vehicle().getId());
changeOverTask.getFacility().deregisterVehicle(next.vehicle().getId());
eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(),
next.vehicle.getId(), shiftChangeFacility.getId()));
next.vehicle().getId(), shiftChangeFacility.getId()));
}
}
}
}

private void scheduleShiftEnd(ShiftEntry endingShift) {
// hub return
final Schedule schedule = endingShift.vehicle.getSchedule();
final Schedule schedule = endingShift.vehicle().getSchedule();

Task currentTask = schedule.getCurrentTask();
Link lastLink;
Expand All @@ -395,14 +394,14 @@ private void scheduleShiftEnd(ShiftEntry endingShift) {
OperationFacility shiftChangeoverFacility = null;

//check whether current shift has to end at specific facility
if(endingShift.shift.getOperationFacilityId().isPresent()) {
if(endingShift.shift().getOperationFacilityId().isPresent()) {
shiftChangeoverFacility = operationFacilities
.getDrtOperationFacilities()
.get(endingShift.shift.getOperationFacilityId().get());
.get(endingShift.shift().getOperationFacilityId().get());
} else {
//check whether next shift has to start at specific facility
for (DrtShift shift : endingShift.vehicle.getShifts()) {
if (shift != endingShift.shift) {
for (DrtShift shift : endingShift.vehicle().getShifts()) {
if (shift != endingShift.shift()) {
if (shift.getOperationFacilityId().isPresent()) {
shiftChangeoverFacility = operationFacilities
.getDrtOperationFacilities()
Expand All @@ -418,20 +417,20 @@ private void scheduleShiftEnd(ShiftEntry endingShift) {
OperationFacilityType.hub);
}

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(), endingShift.vehicle.getId(),
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(), endingShift.vehicle().getId(),
shiftChangeoverFacility.getId()));
} else {
throw new RuntimeException("Could not find shift end location!");
}
}

private OperationFacility decideOnBreak(ShiftEntry activeShift) {
if (activeShift.shift != null) {
if (shiftNeedsBreak(activeShift.shift, timer.getTimeOfDay())) {
final Schedule schedule = activeShift.vehicle.getSchedule();
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
Expand All @@ -451,9 +450,9 @@ private OperationFacility decideOnBreak(ShiftEntry activeShift) {
if (shiftBreakFacility == null) {
throw new RuntimeException("Could not schedule break!");
}
if (shiftBreakFacility.register(activeShift.vehicle.getId())) {
if (shiftBreakFacility.register(activeShift.vehicle().getId())) {
eventsManager.processEvent(new ShiftFacilityRegistrationEvent(timer.getTimeOfDay(),
activeShift.vehicle.getId(), shiftBreakFacility.getId()));
activeShift.vehicle().getId(), shiftBreakFacility.getId()));
return shiftBreakFacility;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater;
import org.matsim.contrib.dvrp.schedule.Task;
import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent;
import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent;
import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener;

/**
* @author nkuehnel, fzwick / MOIA
*/
public class ShiftDrtOptimizer implements DrtOptimizer {
public class ShiftDrtOptimizer implements DrtOptimizer, MobsimInitializedListener {

private final DrtOptimizer optimizer;

Expand Down Expand Up @@ -67,4 +69,8 @@ public void requestSubmitted(Request request) {
this.optimizer.requestSubmitted(request);
}

@Override
public void notifyMobsimInitialized(MobsimInitializedEvent e) {
dispatcher.initialize();
}
}

0 comments on commit adbaf7d

Please sign in to comment.