Skip to content

Commit

Permalink
Merge branch 'master' into scenario-cutout
Browse files Browse the repository at this point in the history
  • Loading branch information
rakow authored Dec 11, 2024
2 parents 8bec2c4 + 5f58a97 commit daa0907
Show file tree
Hide file tree
Showing 55 changed files with 1,303 additions and 343 deletions.
2 changes: 1 addition & 1 deletion contribs/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
<dependency>
<groupId>com.github.matsim-org</groupId>
<artifactId>gtfs2matsim</artifactId>
<version>47b0802a29</version>
<version>19f1676fc6</version>
<exclusions>
<!-- Exclude unneeded dependencies and these with known CVE -->
<exclusion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.matsim.core.utils.io.IOUtils;
import org.matsim.pt.transitSchedule.api.*;
import org.matsim.pt.utils.CreatePseudoNetwork;
import org.matsim.pt.utils.CreatePseudoNetworkWithLoopLinks;
import org.matsim.pt.utils.TransitScheduleValidator;
import org.matsim.vehicles.*;
import picocli.CommandLine;
Expand Down Expand Up @@ -85,8 +86,8 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand {
@CommandLine.Option(names = "--transform-schedule", description = "Fully qualified class name to a Consumer<TransitSchedule> to be executed after the schedule was created", arity = "0..*", split = ",")
private List<Class<?>> transformSchedule;

@CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate")
private boolean mergeStops;
@CommandLine.Option(names = "--merge-stops", description = "Whether stops should be merged by coordinate", defaultValue = "doNotMerge")
private GtfsConverter.MergeGtfsStops mergeStops;

@CommandLine.Option(names = "--prefix", description = "Prefixes to add to the gtfs ids. Required if multiple inputs are used and ids are not unique.", split = ",")
private List<String> prefixes = new ArrayList<>();
Expand All @@ -100,10 +101,29 @@ public class CreateTransitScheduleFromGtfs implements MATSimAppCommand {
@CommandLine.Option(names = "--shp-crs", description = "Overwrite coordinate system of the shape file")
private String shpCrs;

@CommandLine.Option(names = "--pseudo-network", description = "Define how the pseudo network should be created", defaultValue = "singleLinkBetweenStops")
private PseudoNetwork pseudoNetwork;


public static void main(String[] args) {
System.exit(new CommandLine(new CreateTransitScheduleFromGtfs()).execute(args));
}

private static void addHbefaMapping(VehicleType vehicleType, HbefaVehicleCategory category) {
EngineInformation carEngineInformation = vehicleType.getEngineInformation();
VehicleUtils.setHbefaVehicleCategory(carEngineInformation, String.valueOf(category));
VehicleUtils.setHbefaTechnology(carEngineInformation, "average");
VehicleUtils.setHbefaSizeClass(carEngineInformation, "average");
VehicleUtils.setHbefaEmissionsConcept(carEngineInformation, "average");
vehicleType.setNetworkMode(TransportMode.pt);
}

private static void increaseLinkFreespeedIfLower(Link link, double newFreespeed) {
if (link.getFreespeed() < newFreespeed) {
link.setFreespeed(newFreespeed);
}
}

@Override
public Integer call() throws Exception {

Expand Down Expand Up @@ -183,6 +203,13 @@ public Integer call() throws Exception {

Scenario ptScenario = getScenarioWithPseudoPtNetworkAndTransitVehicles(network, scenario.getTransitSchedule(), "pt_");

for (TransitLine line : new ArrayList<>(scenario.getTransitSchedule().getTransitLines().values())) {
if (line.getRoutes().isEmpty()) {
log.warn("Line {} with no routes removed.", line.getId());
scenario.getTransitSchedule().removeTransitLine(line);
}
}

if (validate) {
//Check schedule and network
TransitScheduleValidator.ValidationResult checkResult = TransitScheduleValidator.validateAll(ptScenario.getTransitSchedule(), ptScenario.getNetwork());
Expand Down Expand Up @@ -237,14 +264,19 @@ private Predicate<Stop> createFilter(int i) throws Exception {
/**
* Creates the pt scenario and network.
*/
private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network network, TransitSchedule schedule, String ptNetworkIdentifier) {
private Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network network, TransitSchedule schedule, String ptNetworkIdentifier) {
ScenarioUtils.ScenarioBuilder builder = new ScenarioUtils.ScenarioBuilder(ConfigUtils.createConfig());
builder.setNetwork(network);
builder.setTransitSchedule(schedule);
Scenario scenario = builder.build();

// add pseudo network for pt
new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork();
switch (pseudoNetwork) {
case singleLinkBetweenStops ->
new CreatePseudoNetwork(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork();
case withLoopLinks ->
new CreatePseudoNetworkWithLoopLinks(scenario.getTransitSchedule(), scenario.getNetwork(), ptNetworkIdentifier, 0.1, 100000.0).createNetwork();
}

// create TransitVehicle types
// see https://svn.vsp.tu-berlin.de/repos/public-svn/publications/vspwp/2014/14-24/ for veh capacities
Expand Down Expand Up @@ -449,8 +481,12 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
// so we need to add time for passengers to board and alight
double minStopTime = 30.0;

List<Id<Link>> routeIds = new LinkedList<>();
routeIds.add(route.getRoute().getStartLinkId());
routeIds.addAll(route.getRoute().getLinkIds());
routeIds.add(route.getRoute().getEndLinkId());

for (int i = 1; i < routeStops.size(); i++) {
// TODO cater for loop link at first stop? Seems to just work without.
TransitRouteStop routeStop = routeStops.get(i);
// if there is no departure offset set (or infinity), it is the last stop of the line,
// so we don't need to care about the stop duration
Expand All @@ -462,8 +498,23 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
// Math.max to avoid negative values of travelTime
double travelTime = Math.max(1, routeStop.getArrivalOffset().seconds() - lastDepartureOffset - 1.0 -
(stopDuration >= minStopTime ? 0 : (minStopTime - stopDuration)));
Link link = network.getLinks().get(routeStop.getStopFacility().getLinkId());
increaseLinkFreespeedIfLower(link, link.getLength() / travelTime);


Id<Link> stopLink = routeStop.getStopFacility().getLinkId();
List<Id<Link>> subRoute = new LinkedList<>();
do {
Id<Link> linkId = routeIds.removeFirst();
subRoute.add(linkId);
} while (!subRoute.contains(stopLink));

List<? extends Link> links = subRoute.stream().map(scenario.getNetwork().getLinks()::get)
.toList();

double length = links.stream().mapToDouble(Link::getLength).sum();

for (Link link : links) {
increaseLinkFreespeedIfLower(link, length / travelTime);
}
lastDepartureOffset = routeStop.getDepartureOffset().seconds();
}

Expand All @@ -481,20 +532,15 @@ private static Scenario getScenarioWithPseudoPtNetworkAndTransitVehicles(Network
return scenario;
}

private static void addHbefaMapping(VehicleType vehicleType, HbefaVehicleCategory category) {
EngineInformation carEngineInformation = vehicleType.getEngineInformation();
VehicleUtils.setHbefaVehicleCategory(carEngineInformation, String.valueOf(category));
VehicleUtils.setHbefaTechnology(carEngineInformation, "average");
VehicleUtils.setHbefaSizeClass(carEngineInformation, "average");
VehicleUtils.setHbefaEmissionsConcept(carEngineInformation, "average");
vehicleType.setNetworkMode(TransportMode.pt);
}

private static void increaseLinkFreespeedIfLower(Link link, double newFreespeed) {
if (link.getFreespeed() < newFreespeed) {
link.setFreespeed(newFreespeed);
}
public enum PseudoNetwork {
/**
* Create links between all stops and possibly duplicate stops.
*/
singleLinkBetweenStops,
/**
* Create a pseudo network with loop links at each stop.
*/
withLoopLinks,
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater;
import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic;
import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory;
import org.matsim.contrib.ev.charging.ChargingStrategy;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils;
import org.matsim.core.api.experimental.events.EventsManager;
Expand Down Expand Up @@ -116,7 +117,8 @@ protected void configureQSim() {
public EmptyVehicleChargingScheduler get() {
var taskFactory = getModalInstance(DrtTaskFactory.class);
var chargingInfrastructure = getModalInstance(ChargingInfrastructure.class);
return new EmptyVehicleChargingScheduler(timer, taskFactory, chargingInfrastructure);
ChargingStrategy.Factory chargingStrategyFactory = getModalInstance(ChargingStrategy.Factory.class);
return new EmptyVehicleChargingScheduler(timer, taskFactory, chargingInfrastructure, chargingStrategyFactory);
}
}).asEagerSingleton();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@

import java.net.URL;

import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider;
import org.matsim.contrib.drt.run.DrtConfigGroup;
import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
import org.matsim.contrib.drt.extension.edrt.optimizer.EDrtVehicleDataEntryFactory.EDrtVehicleDataEntryFactoryProvider;
import org.matsim.contrib.dvrp.run.DvrpModes;
import org.matsim.contrib.ev.EvConfigGroup;
import org.matsim.contrib.ev.charging.ChargeUpToMaxSocStrategy;
import org.matsim.contrib.ev.charging.ChargingLogic;
import org.matsim.contrib.ev.charging.ChargingPower;
import org.matsim.contrib.ev.charging.ChargingStrategy;
import org.matsim.contrib.ev.charging.ChargingWithQueueingAndAssignmentLogic;
import org.matsim.contrib.ev.charging.FixedSpeedCharging;
import org.matsim.contrib.ev.temperature.TemperatureService;
Expand All @@ -40,6 +42,8 @@
import org.matsim.core.controler.Controler;
import org.matsim.vis.otfvis.OTFVisConfigGroup;

import com.google.inject.Key;

/**
* @author Michal Maciejewski (michalm)
*/
Expand Down Expand Up @@ -69,10 +73,13 @@ public void install() {
controler.addOverridingModule(new AbstractModule() {
@Override
public void install() {
bind(ChargingLogic.Factory.class).toProvider(new ChargingWithQueueingAndAssignmentLogic.FactoryProvider(
charger -> new ChargeUpToMaxSocStrategy(charger, MAX_RELATIVE_SOC)));
bind(ChargingLogic.Factory.class).to(ChargingWithQueueingAndAssignmentLogic.Factory.class);
bind(ChargingPower.Factory.class).toInstance(ev -> new FixedSpeedCharging(ev, CHARGING_SPEED_FACTOR));
bind(TemperatureService.class).toInstance(linkId -> TEMPERATURE);

for (DrtConfigGroup drtCfg : MultiModeDrtConfigGroup.get(config).getModalElements()) {
bind(Key.get(ChargingStrategy.Factory.class, DvrpModes.mode(drtCfg.mode))).toInstance(new ChargeUpToMaxSocStrategy.Factory(MAX_RELATIVE_SOC));
}
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@
package org.matsim.contrib.drt.extension.edrt.schedule;

import org.matsim.contrib.drt.schedule.DrtTaskType;
import org.matsim.contrib.ev.charging.ChargingStrategy;
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.contrib.ev.infrastructure.Charger;
import org.matsim.contrib.evrp.ChargingTaskImpl;

public class EDrtChargingTask extends ChargingTaskImpl {
public static final DrtTaskType TYPE = new DrtTaskType("CHARGING");

public EDrtChargingTask(double beginTime, double endTime, Charger charger, ElectricVehicle ev, double totalEnergy) {
super(TYPE, beginTime, endTime, charger, ev, totalEnergy);
public EDrtChargingTask(double beginTime, double endTime, Charger charger, ElectricVehicle ev, double totalEnergy, ChargingStrategy chargingStrategy) {
super(TYPE, beginTime, endTime, charger, ev, totalEnergy, chargingStrategy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.matsim.contrib.dvrp.schedule.DefaultStayTask;
import org.matsim.contrib.evrp.EvDvrpVehicle;
import org.matsim.contrib.evrp.VrpPathEnergyConsumptions;
import org.matsim.contrib.ev.charging.ChargingStrategy;
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.contrib.ev.infrastructure.Charger;

Expand Down Expand Up @@ -59,8 +60,8 @@ public DefaultStayTask createInitialTask(DvrpVehicle vehicle, double beginTime,
}

public EDrtChargingTask createChargingTask(DvrpVehicle vehicle, double beginTime, double endTime, Charger charger,
double totalEnergy) {
double totalEnergy, ChargingStrategy chargingStrategy) {
return new EDrtChargingTask(beginTime, endTime, charger, ((EvDvrpVehicle)vehicle).getElectricVehicle(),
totalEnergy);
totalEnergy, chargingStrategy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ public class EmptyVehicleChargingScheduler {
private final MobsimTimer timer;
private final EDrtTaskFactoryImpl taskFactory;
private final Map<Id<Link>, List<Charger>> linkToChargersMap;
private final ChargingStrategy.Factory chargingStrategyFactory;

public EmptyVehicleChargingScheduler(MobsimTimer timer, DrtTaskFactory taskFactory,
ChargingInfrastructure chargingInfrastructure) {
ChargingInfrastructure chargingInfrastructure, ChargingStrategy.Factory chargingStrategyFactory) {
this.timer = timer;
this.chargingStrategyFactory = chargingStrategyFactory;
this.taskFactory = (EDrtTaskFactoryImpl)taskFactory;
linkToChargersMap = chargingInfrastructure.getChargers()
.values()
Expand All @@ -68,15 +70,16 @@ public void chargeVehicle(DvrpVehicle vehicle) {
// Empty charger or at least smallest queue charger
Charger charger = freeCharger.orElseGet(() -> chargers.stream().min(Comparator.comparingInt(e -> e.getLogic().getQueuedVehicles().size())).orElseThrow());
ElectricVehicle ev = ((EvDvrpVehicle)vehicle).getElectricVehicle();
if (!charger.getLogic().getChargingStrategy().isChargingCompleted(ev)) {
chargeVehicleImpl(vehicle, charger);
ChargingStrategy strategy = chargingStrategyFactory.createStrategy(charger.getSpecification(), ev);
if (!strategy.isChargingCompleted()) {
chargeVehicleImpl(vehicle, ev, charger, strategy);
}
}
}



private void chargeVehicleImpl(DvrpVehicle vehicle, Charger charger) {
private void chargeVehicleImpl(DvrpVehicle vehicle, ElectricVehicle ev, Charger charger, ChargingStrategy strategy) {
Schedule schedule = vehicle.getSchedule();
DrtStayTask stayTask = (DrtStayTask)schedule.getCurrentTask();
if (stayTask.getTaskIdx() != schedule.getTaskCount() - 1) {
Expand All @@ -86,19 +89,17 @@ private void chargeVehicleImpl(DvrpVehicle vehicle, Charger charger) {

// add CHARGING TASK
double beginTime = stayTask.getEndTime();
ChargingStrategy strategy = charger.getLogic().getChargingStrategy();
ElectricVehicle ev = ((EvDvrpVehicle)vehicle).getElectricVehicle();
double totalEnergy = -strategy.calcRemainingEnergyToCharge(ev);
double totalEnergy = -strategy.calcRemainingEnergyToCharge();

double chargingDuration = Math.min(strategy.calcRemainingTimeToCharge(ev),
double chargingDuration = Math.min(strategy.calcRemainingTimeToCharge(),
vehicle.getServiceEndTime() - beginTime);
if (chargingDuration <= 0) {
return;// no charging
}
double endTime = beginTime + chargingDuration;

schedule.addTask(taskFactory.createChargingTask(vehicle, beginTime, endTime, charger, totalEnergy));
((ChargingWithAssignmentLogic)charger.getLogic()).assignVehicle(ev);
schedule.addTask(taskFactory.createChargingTask(vehicle, beginTime, endTime, charger, totalEnergy, strategy));
((ChargingWithAssignmentLogic)charger.getLogic()).assignVehicle(ev, strategy);

// append STAY
schedule.addTask(taskFactory.createStayTask(vehicle, endTime, vehicle.getServiceEndTime(), charger.getLink()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ public class EDrtShiftDispatcherImpl implements DrtShiftDispatcher {

private final Fleet fleet;

private final ChargingStrategy.Factory chargingStrategyFactory;

public EDrtShiftDispatcherImpl(EShiftTaskScheduler shiftTaskScheduler, ChargingInfrastructure chargingInfrastructure,
ShiftsParams drtShiftParams, OperationFacilities operationFacilities,
DrtShiftDispatcher delegate, Fleet fleet) {
DrtShiftDispatcher delegate, Fleet fleet, ChargingStrategy.Factory chargingStrategyFactory) {
this.shiftTaskScheduler = shiftTaskScheduler;
this.chargingInfrastructure = chargingInfrastructure;
this.drtShiftParams = drtShiftParams;
this.operationFacilities = operationFacilities;
this.delegate = delegate;
this.fleet = fleet;
this.chargingStrategyFactory = chargingStrategyFactory;
}

@Override
Expand Down Expand Up @@ -112,18 +115,18 @@ private void checkChargingAtHub(double timeStep) {

if (selectedCharger.isPresent()) {
Charger selectedChargerImpl = selectedCharger.get();
ChargingStrategy chargingStrategy = selectedChargerImpl.getLogic().getChargingStrategy();
if (!chargingStrategy.isChargingCompleted(electricVehicle)) {
ChargingStrategy chargingStrategy = chargingStrategyFactory.createStrategy(selectedChargerImpl.getSpecification(), electricVehicle);
if (!chargingStrategy.isChargingCompleted()) {
final double waitTime = ChargingEstimations
.estimateMaxWaitTimeForNextVehicle(selectedChargerImpl);
final double chargingTime = chargingStrategy
.calcRemainingTimeToCharge(electricVehicle);
.calcRemainingTimeToCharge();
double energy = -chargingStrategy
.calcRemainingEnergyToCharge(electricVehicle);
.calcRemainingEnergyToCharge();
final double endTime = timeStep + waitTime + chargingTime;
if (endTime < currentTask.getEndTime()) {
shiftTaskScheduler.chargeAtHub((WaitForShiftTask) currentTask, eShiftVehicle,
electricVehicle, selectedChargerImpl, timeStep, endTime, energy);
electricVehicle, selectedChargerImpl, timeStep, endTime, energy, chargingStrategy);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.matsim.contrib.dvrp.run.DvrpConfigGroup;
import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic;
import org.matsim.contrib.dvrp.vrpagent.VrpLegFactory;
import org.matsim.contrib.ev.charging.ChargingStrategy;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.mobsim.framework.MobsimTimer;
Expand Down Expand Up @@ -72,7 +73,7 @@ protected void configureQSim() {
drtShiftParams, new EDrtShiftStartLogic(new DefaultShiftStartLogic()),
new EDrtAssignShiftToVehicleLogic(new DefaultAssignShiftToVehicleLogic(drtShiftParams), drtShiftParams),
getter.getModal(ShiftScheduler.class)),
getter.getModal(Fleet.class)))
getter.getModal(Fleet.class), getter.getModal(ChargingStrategy.Factory.class)))
).asEagerSingleton();

bindModal(VehicleEntry.EntryFactory.class).toProvider(modalProvider(getter ->
Expand All @@ -87,7 +88,8 @@ drtShiftParams, new EDrtShiftStartLogic(new DefaultShiftStartLogic()),
getter -> new EShiftTaskScheduler(getter.getModal(Network.class), getter.getModal(TravelTime.class),
getter.getModal(TravelDisutilityFactory.class).createTravelDisutility(getter.getModal(TravelTime.class)),
getter.get(MobsimTimer.class), getter.getModal(ShiftDrtTaskFactory.class), drtShiftParams, getter.getModal(ChargingInfrastructure.class),
getter.getModal(OperationFacilities.class), getter.getModal(Fleet.class))
getter.getModal(OperationFacilities.class), getter.getModal(Fleet.class),
getter.getModal(ChargingStrategy.Factory.class))
)).asEagerSingleton();

// See EDrtModeOptimizerQSimModule
Expand Down
Loading

0 comments on commit daa0907

Please sign in to comment.