Skip to content

Commit

Permalink
Merge branch 'master' into small-scale-traffic-impro
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow authored Jan 2, 2024
2 parents e50cd45 + 90e5f29 commit 13acdcd
Show file tree
Hide file tree
Showing 272 changed files with 1,641 additions and 1,743 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -88,6 +87,7 @@ private void installSampler(DrtWithExtensionsConfigGroup drtWithExtensionsConfig
}

void addCompanionAgents() {
int identifier = 0;
HashMap<String, Integer> drtCompanionAgents = new HashMap<>();
Collection<Person> companions = new ArrayList<>();
for (Person person : this.scenario.getPopulation().getPersons().values()) {
Expand All @@ -105,7 +105,8 @@ void addCompanionAgents() {
int groupPart = i;

companions.add(createCompanionAgent(mainMode, person, trip, trip.getOriginActivity(),
trip.getDestinationActivity(), groupPart, groupSize));
trip.getDestinationActivity(), groupPart, groupSize, identifier));
identifier++;
}
}
}
Expand All @@ -121,9 +122,9 @@ void addCompanionAgents() {
}

private Person createCompanionAgent(String drtMode, Person originalPerson, TripStructureUtils.Trip trip,
Activity fromActivity, Activity toActivity, int groupPart, int groupSize) {
Activity fromActivity, Activity toActivity, int groupPart, int groupSize, int identifier) {
String prefix = getCompanionPrefix(drtMode);
String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + UUID.randomUUID();
String companionId = prefix + "_" + originalPerson.getId().toString() + "_" + identifier;
Person person = PopulationUtils.getFactory().createPerson(Id.createPersonId(companionId));
DrtCompanionUtils.setDRTCompanionType(person, DRT_COMPANION_TYPE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.matsim.core.config.ConfigGroup;

import java.net.URL;
import java.util.Map;

/**
* @author nkuehnel / MOIA
Expand All @@ -30,6 +29,10 @@ public class ShiftsParams extends ReflectiveConfigGroupWithConfigurableParameter
@Comment("changeover duration in [seconds]")
public double changeoverDuration = 900;

@Parameter
@Comment("maximum delay of shift assignment after start time has passed in [seconds]. If a shift can not be assigned to a vehicle until the planned start of the shift plus the defined max delay, the shift is discarded. Defaults to 0")
public double maxUnscheduledShiftDelay = 0;

@Parameter
@Comment("Time of shift assignment (i.e. which vehicle carries out a specific shift) before start of shift in [seconds]")
public double shiftScheduleLookAhead = 1800;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,13 @@ private void startShifts(double timeStep) {

private void assignShifts(double timeStep) {
// Remove elapsed shifts
unscheduledShifts.removeIf(shift -> shift.getStartTime() < 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 false;
});

// Assign shifts
Set<DrtShift> assignableShifts = new LinkedHashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,44 @@
package org.matsim.contrib.drt.extension.edrt.run;

import java.net.URL;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.population.Plan;
import org.matsim.api.core.v01.population.Population;
import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory;
import org.matsim.contrib.drt.prebooking.PrebookingParams;
import org.matsim.contrib.drt.prebooking.logic.ProbabilityBasedPrebookingLogic;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.drt.run.DrtConfigs;
import org.matsim.contrib.drt.run.DrtControlerCreator;
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEvent;
import org.matsim.contrib.dvrp.passenger.PassengerRequestRejectedEventHandler;
import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEvent;
import org.matsim.contrib.dvrp.passenger.PassengerRequestScheduledEventHandler;
import org.matsim.contrib.dvrp.passenger.*;
import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
import org.matsim.contrib.dvrp.run.DvrpModule;
import org.matsim.contrib.dvrp.run.DvrpQSimComponents;
import org.matsim.contrib.ev.EvConfigGroup;
import org.matsim.contrib.ev.EvModule;
import org.matsim.contrib.ev.charging.*;
import org.matsim.contrib.ev.discharging.IdleDischargingHandler;
import org.matsim.contrib.ev.temperature.TemperatureService;
import org.matsim.contrib.evrp.EvDvrpFleetQSimModule;
import org.matsim.contrib.evrp.OperatingVehicleProvider;
import org.matsim.contrib.otfvis.OTFVisLiveModule;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.controler.Controler;
import org.matsim.core.mobsim.qsim.AbstractQSimModule;
import org.matsim.core.population.io.PopulationReader;
import org.matsim.core.population.io.PopulationWriter;
import org.matsim.core.router.TripStructureUtils;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.vis.otfvis.OTFVisConfigGroup;
Expand All @@ -51,36 +71,82 @@ void test() {
RunEDrtScenario.run(configUrl, false);
}

@Test
void testMultiModeDrtDeterminism() {
URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_multiModeEdrt_config.xml");

Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(),
new OTFVisConfigGroup(), new EvConfigGroup());


Controler controller = RunEDrtScenario.createControler(config, false);
config.controller().setLastIteration(2);

PassengerPickUpTracker tracker = new PassengerPickUpTracker();
tracker.install(controller);

controller.run();

assertEquals(2011, tracker.passengerPickupEvents);
}


@Test
void testWithPrebooking() {
URL configUrl = IOUtils.extendUrl(ExamplesUtils.getTestScenarioURL("mielec"), "mielec_edrt_config.xml");

Config config = ConfigUtils.loadConfig(configUrl, new MultiModeDrtConfigGroup(), new DvrpConfigGroup(),
new OTFVisConfigGroup(), new EvConfigGroup());

DrtConfigGroup drtConfig = DrtConfigGroup.getSingleModeDrtConfig(config);
drtConfig.addParameterSet(new PrebookingParams());

Controler controller = RunEDrtScenario.createControler(config, false);
ProbabilityBasedPrebookingLogic.install(controller, drtConfig, 0.5, 4.0 * 3600.0);

PrebookingTracker tracker = new PrebookingTracker();
tracker.install(controller);

controller.run();

assertEquals(74, tracker.immediateScheduled);
assertEquals(198, tracker.prebookedScheduled);
assertEquals(116, tracker.immediateRejected);
assertEquals(7, tracker.prebookedRejected);
}


static private class PassengerPickUpTracker implements PassengerPickedUpEventHandler {
int passengerPickupEvents = 0;

void install(Controler controller) {
PassengerPickUpTracker thisTracker = this;

controller.addOverridingModule(new AbstractModule() {
@Override
public void install() {
addEventHandlerBinding().toInstance(thisTracker);
}
});
}

@Override
public void handleEvent(PassengerPickedUpEvent event) {
passengerPickupEvents++;
}

@Override
public void reset(int iteration) {
passengerPickupEvents=0;
}

}

static private class PrebookingTracker implements PassengerRequestRejectedEventHandler, PassengerRequestScheduledEventHandler {
int immediateScheduled = 0;
int prebookedScheduled = 0;
int immediateRejected = 0;
int prebookedRejected = 0;

@Override
public void handleEvent(PassengerRequestScheduledEvent event) {
if (event.getRequestId().toString().contains("prebooked")) {
Expand All @@ -98,10 +164,10 @@ public void handleEvent(PassengerRequestRejectedEvent event) {
immediateRejected++;
}
}

void install(Controler controller) {
PrebookingTracker thisTracker = this;

controller.addOverridingModule(new AbstractModule() {
@Override
public void install() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ public int getOutgoingOccupancy() {
}

public int getOccupancyChange() {
return task.getPickupRequests().size() - task.getDropoffRequests().size();
return task.getPickupRequests().values().stream().mapToInt(AcceptedDrtRequest::getPassengerCount).sum() -
task.getDropoffRequests().values().stream().mapToInt(AcceptedDrtRequest::getPassengerCount).sum();
}

private double calcLatestArrivalTime() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ public static boolean isSwitchingFromStopToStay(DvrpVehicle vehicle) {
if (!STAY.isBaseTypeOf(currentTask)) {
return false;
}

// only if stay task is last task: with prebooking we may also idle during the day, but
// currently all the downstream relocation/charging logic assumes that we only stay at
// currently all the downstream relocation/charging logic assumes that we only stay at
// the end of the schedule
if (currentTask.getTaskIdx() < schedule.getTaskCount() - 1) {
return false;
Expand All @@ -64,13 +64,15 @@ public static boolean isSwitchingFromStopToStay(DvrpVehicle vehicle) {
}

public static Link findStraightLineNearestDepot(DvrpVehicle vehicle, Set<Link> links) {
Link currentLink = ((DrtStayTask)vehicle.getSchedule().getCurrentTask()).getLink();
Link currentLink = ((DrtStayTask) vehicle.getSchedule().getCurrentTask()).getLink();
return links.contains(currentLink) ?
null /* already at a depot*/ :
links.stream()
.min(Comparator.comparing(
l -> DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(),
l.getFromNode().getCoord())))
.get();
null /* already at a depot*/ :
links.stream().map(l -> new DepotCandidates(l, DistanceUtils.calculateSquaredDistance(currentLink.getToNode().getCoord(),
l.getFromNode().getCoord())))
.min(Comparator.comparing(DepotCandidates::distance)
.thenComparing(h -> h.link.getId()))
.get().link();
}

record DepotCandidates(Link link, double distance) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ public List<Id<Person>> getPassengerIds() {
return request.getPassengerIds();
}

public int getPassengerCount() {
return request.getPassengerCount();
}

public String getMode() {
return request.getMode();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package org.matsim.contrib.drt.prebooking;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.events.GenericEvent;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.dvrp.optimizer.Request;
import org.matsim.contrib.dvrp.passenger.AbstractPassengerRequestEvent;

import java.util.*;

/**
* @author Sebastian Hörl (sebhoerl), IRT SystemX
*/
public class PassengerRequestBookedEvent extends AbstractPassengerRequestEvent {
public static final String EVENT_TYPE = "PassengerRequest booked";

public PassengerRequestBookedEvent(double time, String mode, Id<Request> requestId, Id<Person> personId) {
super(time, mode, requestId, List.of(personId));
public PassengerRequestBookedEvent(double time, String mode, Id<Request> requestId, List<Id<Person>> personIds) {
super(time, mode, requestId, personIds);
}

@Override
Expand All @@ -30,7 +28,8 @@ public static PassengerRequestBookedEvent convert(GenericEvent event) {
double time = Double.parseDouble(attributes.get(ATTRIBUTE_TIME));
String mode = Objects.requireNonNull(attributes.get(ATTRIBUTE_MODE));
Id<Request> requestId = Id.create(attributes.get(ATTRIBUTE_REQUEST), Request.class);
Id<Person> personId = Id.createPersonId(attributes.get(ATTRIBUTE_PERSON));
return new PassengerRequestBookedEvent(time, mode, requestId, personId);
String[] personIdsAttribute = attributes.get(ATTRIBUTE_PERSON).split(",");
List<Id<Person>> personIds = Arrays.stream(personIdsAttribute).map(Id::createPersonId).toList();
return new PassengerRequestBookedEvent(time, mode, requestId, personIds);
}
}
Loading

0 comments on commit 13acdcd

Please sign in to comment.