Commit 338db17b authored by Sebastian Hörl's avatar Sebastian Hörl
Browse files

changes + new walk and bike parameters

parent 8a932db2
package ch.ethz.matsim.projects.astra_2018_002;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.ControlerConfigGroup.RoutingAlgorithmType;
import org.matsim.core.controler.Controler;
import org.matsim.core.scenario.ScenarioUtils;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.baseline_scenario.config.CommandLine;
import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationException;
import ch.ethz.matsim.baseline_scenario.transit.BaselineTransitModule;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRoute;
import ch.ethz.matsim.baseline_scenario.transit.routing.DefaultEnrichedTransitRouteFactory;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissDiscreteModeChoiceModule;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissModeChoiceUtilities;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissModeChoiceConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissUtilityParameters.UtilitySet;
import ch.sbb.matsim.routing.pt.raptor.SwissRailRaptorModule;
......@@ -28,9 +31,8 @@ public class RunASTRA2018002 {
Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"));
// Adjust config
SwissDiscreteModeChoiceModule.configure(config);
config.controler().setRoutingAlgorithmType(RoutingAlgorithmType.FastAStarLandmarks);
SwissModeChoiceConfigurator.configure(config);
//FlowEfficiencyConfigurator.configure(config);
cmd.applyConfiguration(config);
......@@ -41,12 +43,14 @@ public class RunASTRA2018002 {
ScenarioUtils.loadScenario(scenario);
// Adjust scenario
SwissModeChoiceUtilities.copyHousholdAttributes(scenario);
SwissModeChoiceConfigurator.copyHousholdAttributes(scenario);
//FlowEfficiencyConfigurator.defineVehicleTypes(scenario);
// Set up controller
Controler controler = new Controler(scenario);
controler.addOverridingModule(new SwissRailRaptorModule());
controler.addOverridingModule(new BaselineTransitModule());
//controler.addOverridingModule(new AVModule());
UtilitySet utilitySet = Enum.valueOf(UtilitySet.class, cmd.getOptionStrict("model"));
boolean useRouteChoice = cmd.getOption("use-route-choice").map(Boolean::parseBoolean).orElse(true);
......@@ -56,14 +60,5 @@ public class RunASTRA2018002 {
// Run
controler.run();
// PCU
//
// config.qsim().setVehiclesSource(VehiclesSource.modeVehicleTypesFromVehiclesData);
// config.travelTimeCalculator().setAnalyzedModes("car,private_av");
// config.travelTimeCalculator().setSeparateModes(true);
// Set up scenario
// PCUUtils.defineVehicleTypes(scenario);
}
}
package ch.ethz.matsim.projects.astra_2018_002.av.operating_area;
import java.util.Collection;
import java.util.List;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import ch.ethz.matsim.discrete_mode_choice.model.constraints.AbstractTripConstraint;
import ch.ethz.matsim.discrete_mode_choice.model.trip_based.TripConstraint;
import ch.ethz.matsim.discrete_mode_choice.model.trip_based.TripConstraintFactory;
public class OperatingAreaConstraint extends AbstractTripConstraint {
private final OperatingAreaRegistry registry;
public OperatingAreaConstraint(OperatingAreaRegistry registry) {
this.registry = registry;
}
@Override
public boolean validateBeforeEstimation(DiscreteModeChoiceTrip trip, String mode, List<String> previousModes) {
if (mode.equals(AVModule.AV_MODE)) {
Id<Link> originLinkId = trip.getOriginActivity().getLinkId();
Id<Link> destinationLinkId = trip.getDestinationActivity().getLinkId();
return registry.areLinksCoveredAndConnected(originLinkId, destinationLinkId);
}
return true;
}
public static class Factory implements TripConstraintFactory {
private final OperatingAreaRegistry registry;
public Factory(OperatingAreaRegistry registry) {
this.registry = registry;
}
@Override
public TripConstraint createConstraint(Person person, List<DiscreteModeChoiceTrip> planTrips,
Collection<String> availableModes) {
return new OperatingAreaConstraint(registry);
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.av.operating_area;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.dvrp.data.Vehicle;
import com.google.inject.Inject;
import ch.ethz.matsim.av.config.AVGeneratorConfig;
import ch.ethz.matsim.av.data.AVVehicle;
import ch.ethz.matsim.av.generator.AVGenerator;
public class OperatingAreaGenerator implements AVGenerator {
private final String prefix;
private final List<Link> links;
private final int numberOfVehicles;
private final Random random = new Random();
private int numberOfGeneratedVehicles = 0;
public OperatingAreaGenerator(String prefix, int numberOfVehicles, List<Link> links) {
this.links = links;
this.numberOfVehicles = numberOfVehicles;
this.prefix = prefix;
}
@Override
public boolean hasNext() {
return numberOfGeneratedVehicles < numberOfVehicles;
}
@Override
public AVVehicle next() {
numberOfGeneratedVehicles++;
// TODO: Here we create vehicles at random. Usually we also estimate the
// population density at a certain link to get a better initial positioning. We
// can add this here later (see the standard implementations in the AV package).
Id<Vehicle> vehicleId = Id.create(prefix + "_" + String.valueOf(numberOfGeneratedVehicles), Vehicle.class);
Link startLink = links.get(random.nextInt(links.size()));
return new AVVehicle(vehicleId, startLink, 4.0, 0.0, Double.POSITIVE_INFINITY);
}
public static class Factory implements AVGeneratorFactory {
@Inject
OperatingAreaRegistry registry;
@Override
public AVGenerator createGenerator(AVGeneratorConfig generatorConfig) {
String operator = generatorConfig.getParent().getId().toString();
String prefix = "av_" + operator;
int numberOfVehicles = (int) generatorConfig.getNumberOfVehicles();
List<Link> links = new ArrayList<>(registry.getLinks(operator));
return new OperatingAreaGenerator(prefix, numberOfVehicles, links);
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.av.operating_area;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import ch.ethz.matsim.av.framework.AVUtils;
import ch.ethz.matsim.discrete_mode_choice.modules.AbstractDiscreteModeChoiceExtension;
public class OperatingAreaModule extends AbstractDiscreteModeChoiceExtension {
public static final String CONSTRAINT_NAME = "OperatingArea";
public static final String GENERATOR_NAME = "OperatingArea";
@Override
protected void installExtension() {
bindTripConstraintFactory(CONSTRAINT_NAME).to(OperatingAreaConstraint.Factory.class);
AVUtils.registerGeneratorFactory(binder(), GENERATOR_NAME, OperatingAreaGenerator.Factory.class);
}
@Provides
@Singleton
public OperatingAreaConstraint.Factory provideOperatingAreaConstraintFactory(OperatingAreaRegistry registry) {
return new OperatingAreaConstraint.Factory(registry);
}
@Provides
@Singleton
public OperatingAreaRegistry provideOperatingAreaRegistry() {
return new OperatingAreaRegistry();
}
}
package ch.ethz.matsim.projects.astra_2018_002.av.operating_area;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
public class OperatingAreaRegistry {
private final List<String> areaNames = new LinkedList<>();
private final List<Collection<Link>> linksForAreas = new LinkedList<>();
private final Map<Id<Link>, Set<Integer>> areasForLinks = new HashMap<>();
public void addOperatingArea(String operatingArea, Collection<Link> links) {
areaNames.add(operatingArea);
linksForAreas.add(links);
for (Link link : links) {
Id<Link> linkId = link.getId();
if (!areasForLinks.containsKey(linkId)) {
areasForLinks.put(linkId, new HashSet<>());
}
areasForLinks.get(linkId).add(areaNames.size() - 1);
}
}
public boolean areLinksCoveredAndConnected(Id<Link> originId, Id<Link> destinationId) {
Set<Integer> originIndices = areasForLinks.get(originId);
Set<Integer> destinationIndices = areasForLinks.get(destinationId);
if (originIndices == null || destinationIndices == null) {
// One of the links does not have an operating area -> it is not covered by AVs
return false;
}
originIndices.retainAll(destinationIndices);
// There was an overlap, so AV can be used for this OD pair
return originIndices.size() > 0;
}
public String getOperatingArea(Id<Link> originId, Id<Link> destinationId) {
Set<Integer> originIndices = areasForLinks.get(originId);
Set<Integer> destinationIndices = areasForLinks.get(destinationId);
if (originIndices == null || destinationIndices == null) {
// One of the links does not have an operating area -> it is not covered by AVs
throw new IllegalStateException("Trip not covered by AVs");
}
originIndices.retainAll(destinationIndices);
if (originIndices.size() > 0) {
// There was an overlap, so AV can be used for this OD pair
return areaNames.get(originIndices.iterator().next());
} else {
throw new IllegalStateException("OD is not covered by one operator");
}
}
public Collection<Link> getLinks(String operatingArea) {
int index = areaNames.indexOf(operatingArea);
if (index == -1) {
throw new IllegalStateException("Operating area " + operatingArea + " does not exist.");
}
return linksForAreas.get(index);
}
}
package ch.ethz.matsim.projects.astra_2018_002.flow_efficiency;
import org.matsim.api.core.v01.network.Link;
import org.matsim.vehicles.Vehicle;
public interface FlowEfficiencyCalculator {
double calculateFlowEfficiency(Vehicle vehicle, Link link);
class Instance implements FlowEfficiencyCalculator {
private FlowEfficiencyCalculator delegate;
public void set(FlowEfficiencyCalculator delegate) {
this.delegate = delegate;
}
@Override
public double calculateFlowEfficiency(Vehicle vehicle, Link link) {
if (delegate == null) {
return 1.0;
} else {
return delegate.calculateFlowEfficiency(vehicle, link);
}
}
}
final static Instance INSTANCE = new Instance();
}
package ch.ethz.matsim.projects.astra_2018_002.flow_efficiency;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.QSimConfigGroup.VehiclesSource;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
public class FlowEfficiencyConfigurator {
static public void configure(Config config) {
// Load vehicles by vehicle type
config.qsim().setVehiclesSource(VehiclesSource.modeVehicleTypesFromVehiclesData);
// TODO: Do we need those?
// config.travelTimeCalculator().setAnalyzedModes("car,private_av");
// config.travelTimeCalculator().setSeparateModes(true);
// Set the calculator instance (not the best design, but works)
FlowEfficiencyCalculator calculator = new StaticFlowEfficiencyCalculator();
FlowEfficiencyCalculator.INSTANCE.set(calculator);
}
static public void defineVehicleTypes(Scenario scenario) {
VehicleType carVehicleType = VehicleUtils.getDefaultVehicleType();
scenario.getVehicles().addVehicleType(carVehicleType);
VehicleType privateAvVehicleType = VehicleUtils.getFactory()
.createVehicleType(Id.create("private_av", VehicleType.class));
scenario.getVehicles().addVehicleType(privateAvVehicleType);
}
}
package ch.ethz.matsim.projects.astra_2018_002.flow_efficiency;
import org.matsim.api.core.v01.network.Link;
import org.matsim.vehicles.Vehicle;
public class StaticFlowEfficiencyCalculator implements FlowEfficiencyCalculator {
private final double flowEfficiency;
public StaticFlowEfficiencyCalculator(double flowEfficiency) {
this.flowEfficiency = flowEfficiency;
}
public StaticFlowEfficiencyCalculator() {
this(1.0);
}
@Override
public double calculateFlowEfficiency(Vehicle vehicle, Link link) {
return flowEfficiency;
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
import java.util.Arrays;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.PlanCalcScoreConfigGroup;
import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams;
import org.matsim.core.router.TripRouter;
import org.matsim.facilities.ActivityFacilities;
import org.matsim.pt.transitSchedule.api.TransitSchedule;
......@@ -15,16 +9,7 @@ import com.google.inject.Provides;
import com.google.inject.Singleton;
import ch.ethz.matsim.discrete_mode_choice.modules.AbstractDiscreteModeChoiceExtension;
import ch.ethz.matsim.discrete_mode_choice.modules.ConstraintModule;
import ch.ethz.matsim.discrete_mode_choice.modules.DiscreteModeChoiceConfigurator;
import ch.ethz.matsim.discrete_mode_choice.modules.DiscreteModeChoiceModule;
import ch.ethz.matsim.discrete_mode_choice.modules.EstimatorModule;
import ch.ethz.matsim.discrete_mode_choice.modules.ModeAvailabilityModule;
import ch.ethz.matsim.discrete_mode_choice.modules.ModelModule.ModelType;
import ch.ethz.matsim.discrete_mode_choice.modules.SelectorModule;
import ch.ethz.matsim.discrete_mode_choice.modules.TourFinderModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup.HomeType;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.SwissUtilityParameters.UtilitySet;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostModel;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.cost.CostParameters;
......@@ -80,47 +65,4 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
return new CostParameters();
}
static public void configure(Config config) {
// Set up discrete choice
DiscreteModeChoiceConfigurator.configureAsModeChoiceInTheLoop(config);
DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules()
.get(DiscreteModeChoiceConfigGroup.GROUP_NAME);
dmcConfig.setModelType(ModelType.Tour);
dmcConfig.setPerformReroute(false);
dmcConfig.setSelector(SelectorModule.MULTINOMIAL_LOGIT);
dmcConfig.setTripEstimator(SwissDiscreteModeChoiceModule.SWISS_ESTIMATOR_NAME);
dmcConfig.setTourEstimator(EstimatorModule.CUMULATIVE);
dmcConfig.setCachedModes(Arrays.asList("car", "bike", "pt", "walk"));
dmcConfig.setTourFinder(TourFinderModule.ACTIVITY_BASED);
dmcConfig.getActivityTourFinderConfigGroup().setActivityType("home");
dmcConfig.setModeAvailability(ModeAvailabilityModule.CAR);
dmcConfig.getCarModeAvailabilityConfig().setAvailableModes(Arrays.asList("car", "bike", "pt", "walk"));
dmcConfig.setTourConstraints(
Arrays.asList(ConstraintModule.VEHICLE_CONTINUITY, ConstraintModule.FROM_TRIP_BASED));
dmcConfig.setTripConstraints(Arrays.asList(ConstraintModule.TRANSIT_WALK));
dmcConfig.getVehicleTourConstraintConfig().setHomeType(HomeType.USE_ACTIVITY_TYPE);
dmcConfig.getVehicleTourConstraintConfig().setRestrictedModes(Arrays.asList("car", "bike"));
// These parameters are only used by SwissRailRaptor. We configure the
// parameters here in a way that SRR searches for the route with the shortest
// travel time.
PlanCalcScoreConfigGroup scoringConfig = config.planCalcScore();
ModeParams ptParams = scoringConfig.getModes().get(TransportMode.pt);
ptParams.setConstant(0.0);
ptParams.setMarginalUtilityOfDistance(0.0);
ptParams.setMarginalUtilityOfTraveling(1.0);
ptParams.setMonetaryDistanceRate(0.0);
scoringConfig.setMarginalUtilityOfMoney(0.0);
scoringConfig.setMarginalUtlOfWaitingPt_utils_hr(0.0);
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
import java.util.Arrays;
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.population.Person;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.ControlerConfigGroup.RoutingAlgorithmType;
import org.matsim.core.config.groups.PlanCalcScoreConfigGroup;
import org.matsim.core.config.groups.PlanCalcScoreConfigGroup.ModeParams;
import org.matsim.core.config.groups.PlansCalcRouteConfigGroup.ModeRoutingParams;
import org.matsim.households.Household;
import ch.ethz.matsim.discrete_mode_choice.modules.ConstraintModule;
import ch.ethz.matsim.discrete_mode_choice.modules.DiscreteModeChoiceConfigurator;
import ch.ethz.matsim.discrete_mode_choice.modules.EstimatorModule;
import ch.ethz.matsim.discrete_mode_choice.modules.ModeAvailabilityModule;
import ch.ethz.matsim.discrete_mode_choice.modules.ModelModule.ModelType;
import ch.ethz.matsim.discrete_mode_choice.modules.SelectorModule;
import ch.ethz.matsim.discrete_mode_choice.modules.TourFinderModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.discrete_mode_choice.modules.config.VehicleTourConstraintConfigGroup.HomeType;
public class SwissModeChoiceConfigurator {
static public void configure(Config config) {
// Set up discrete choice
DiscreteModeChoiceConfigurator.configureAsModeChoiceInTheLoop(config);
DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules()
.get(DiscreteModeChoiceConfigGroup.GROUP_NAME);
dmcConfig.setModelType(ModelType.Tour);
dmcConfig.setPerformReroute(false);
dmcConfig.setSelector(SelectorModule.MULTINOMIAL_LOGIT);
dmcConfig.setTripEstimator(SwissDiscreteModeChoiceModule.SWISS_ESTIMATOR_NAME);
dmcConfig.setTourEstimator(EstimatorModule.CUMULATIVE);
dmcConfig.setCachedModes(Arrays.asList("car", "bike", "pt", "walk"));
dmcConfig.setTourFinder(TourFinderModule.ACTIVITY_BASED);
dmcConfig.getActivityTourFinderConfigGroup().setActivityType("home");
dmcConfig.setModeAvailability(ModeAvailabilityModule.CAR);
dmcConfig.getCarModeAvailabilityConfig().setAvailableModes(Arrays.asList("car", "bike", "pt", "walk"));
dmcConfig.setTourConstraints(
Arrays.asList(ConstraintModule.VEHICLE_CONTINUITY, ConstraintModule.FROM_TRIP_BASED));
dmcConfig.setTripConstraints(Arrays.asList(ConstraintModule.TRANSIT_WALK)); // ,
// OperatingAreaModule.CONSTRAINT_NAME));
dmcConfig.getVehicleTourConstraintConfig().setHomeType(HomeType.USE_ACTIVITY_TYPE);
dmcConfig.getVehicleTourConstraintConfig().setRestrictedModes(Arrays.asList("car", "bike"));
// These parameters are only used by SwissRailRaptor. We configure the
// parameters here in a way that SRR searches for the route with the shortest
// travel time.
PlanCalcScoreConfigGroup scoringConfig = config.planCalcScore();
ModeParams ptParams = scoringConfig.getModes().get(TransportMode.pt);
ptParams.setConstant(0.0);
ptParams.setMarginalUtilityOfDistance(0.0);
ptParams.setMarginalUtilityOfTraveling(1.0);
ptParams.setMonetaryDistanceRate(0.0);
scoringConfig.setMarginalUtilityOfMoney(0.0);
scoringConfig.setMarginalUtlOfWaitingPt_utils_hr(0.0);
// Some additional settings
config.controler().setRoutingAlgorithmType(RoutingAlgorithmType.FastAStarLandmarks);
ModeRoutingParams bikeParams = config.plansCalcRoute().getModeRoutingParams().get(TransportMode.bike);
bikeParams.setBeelineDistanceFactor(1.4);
bikeParams.setTeleportedModeSpeed(3.1); // 11.6 km/h
ModeRoutingParams walkParams = config.plansCalcRoute().getModeRoutingParams().get(TransportMode.walk);
walkParams.setBeelineDistanceFactor(1.3);
walkParams.setTeleportedModeSpeed(1.2); // 4.32 km/h
}
static public void copyHousholdAttributes(Scenario scenario) {
for (Household household : scenario.getHouseholds().getHouseholds().values()) {
for (Id<Person> memberId : household.getMemberIds()) {
Person person = scenario.getPopulation().getPersons().get(memberId);
person.getAttributes().putAttribute("householdIncome", household.getIncome().getIncome());
person.getAttributes().putAttribute("spRegion", household.getAttributes().getAttribute("spRegion"));
person.getAttributes().putAttribute("municipalityType",
household.getAttributes().getAttribute("municipalityType"));
}
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.population.Person;
import org.matsim.households.Household;
public class SwissModeChoiceUtilities {
static public void copyHousholdAttributes(Scenario scenario) {
for (Household household : scenario.getHouseholds().getHouseholds().values()) {