Commit 367c8de9 authored by clivings's avatar clivings
Browse files
parents 11ff522e c21dbde7
# How to run a simulaton with private AVs
# How to run a simulation with private AVs
Private AVs can be activated via the `private_av` config group:
......
......@@ -9,12 +9,11 @@ import org.matsim.api.core.v01.network.Link;
public class ASTRAConfigurator {
static public void adjustNetwork(Scenario scenario) {
// TODO: only until we actually assign allowed modes via the pipeline
for (Link link : scenario.getNetwork().getLinks().values()) {
Set<String> allowedModes = new HashSet<>(link.getAllowedModes());
if (allowedModes.contains("car")) {
allowedModes.addAll(Arrays.asList("av", "prav3", "prav4", "prav5"));
allowedModes.addAll(Arrays.asList("av", "prav3", "prav4", "prav5", "car_passenger"));
}
link.setAllowedModes(allowedModes);
......
......@@ -12,6 +12,7 @@ import ch.ethz.matsim.baseline_scenario.traffic.BaselineTrafficModule;
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.discrete_mode_choice.modules.DiscreteModeChoiceModule;
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.SwissModeChoiceConfigurator;
......@@ -62,6 +63,7 @@ public class RunASTRA2018002 {
UtilitySet utilitySet = Enum.valueOf(UtilitySet.class, cmd.getOption("model").orElse("ZERO"));
boolean useRouteChoice = cmd.getOption("use-route-choice").map(Boolean::parseBoolean).orElse(true);
boolean useOnlySignificant = cmd.getOption("use-only-significant").map(Boolean::parseBoolean).orElse(false);
controller.addOverridingModule(new DiscreteModeChoiceModule());
controller.addOverridingModule(
new SwissDiscreteModeChoiceModule(utilitySet, useRouteChoice, useOnlySignificant, cmd));
......
package ch.ethz.matsim.projects.astra_2018_002.analysis.flow;
public class AnalysisVehicle {
public boolean isShared = false;
public boolean isPooled = false;
public int automationLevel = 0;
}
......@@ -16,6 +16,7 @@ import org.matsim.vehicles.Vehicles;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyCalculator;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVModule;
public class FlowListener implements LinkEnterEventHandler {
private final double startTime;
......@@ -24,8 +25,8 @@ public class FlowListener implements LinkEnterEventHandler {
private final int numberOfLinks;
private final int numberOfBins;
private final Item[][] timeItems;
private final Item[] totalItems;
private final CountItem[][] timeItems;
private final CountItem[] totalItems;
private final Map<Id<Link>, Integer> linkMap = new HashMap<>();
private final List<Link> links;
......@@ -33,12 +34,13 @@ public class FlowListener implements LinkEnterEventHandler {
private final FlowEfficiencyCalculator flowEfficiencyCalculator;
private final Vehicle CONVENTIONAL_VEHICLE;
private final Vehicle PRIVATE_AV;
private final Vehicle SHARED_AV;
private final Vehicle CONVENTIONAL;
private final Vehicle PRAV3;
private final Vehicle PRAV4;
private final Vehicle PRAV5;
public FlowListener(Vehicles vehicles, Collection<Link> links, double startTime, double endTime, double interval,
FlowEfficiencyCalculator flowEfficiencyCalculator) {
public FlowListener(Collection<Link> links, double startTime, double endTime, double interval,
FlowEfficiencyCalculator flowEfficiencyCalculator, Vehicles vehicles) {
this.startTime = startTime;
this.interval = interval;
......@@ -52,32 +54,105 @@ public class FlowListener implements LinkEnterEventHandler {
linkMap.put(this.links.get(index).getId(), index);
}
this.CONVENTIONAL_VEHICLE = vehicles.getFactory().createVehicle(Id.createVehicleId("conventional"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.CONVENTIONAL_VEHICLE_TYPE_ID));
this.PRIVATE_AV = vehicles.getFactory().createVehicle(Id.createVehicleId("private_av"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.PRIVATE_AV_VEHICLE_TYPE_ID));
this.SHARED_AV = vehicles.getFactory().createVehicle(Id.createVehicleId("shared_av"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.SHARED_AV_VEHICLE_TYPE_ID));
this.totalItems = new Item[numberOfLinks];
this.timeItems = new Item[numberOfLinks][numberOfBins];
this.totalItems = new CountItem[numberOfLinks];
this.timeItems = new CountItem[numberOfLinks][numberOfBins];
this.flowEfficiencyCalculator = flowEfficiencyCalculator;
for (int linkIndex = 0; linkIndex < numberOfLinks; linkIndex++) {
totalItems[linkIndex] = new Item();
totalItems[linkIndex] = new CountItem();
for (int timeIndex = 0; timeIndex < numberOfBins; timeIndex++) {
timeItems[linkIndex][timeIndex] = new Item();
timeItems[linkIndex][timeIndex] = new CountItem();
}
}
this.CONVENTIONAL = vehicles.getFactory().createVehicle(Id.createVehicleId("conventional"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.CONVENTIONAL_VEHICLE_TYPE_ID));
this.PRAV3 = vehicles.getFactory().createVehicle(Id.createVehicleId("prav3"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.PRAV3_ID));
this.PRAV4 = vehicles.getFactory().createVehicle(Id.createVehicleId("prav4"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.PRAV4_ID));
this.PRAV5 = vehicles.getFactory().createVehicle(Id.createVehicleId("prav5"),
vehicles.getVehicleTypes().get(FlowEfficiencyConfigurator.PRAV5_ID));
}
public class Item {
public int numberOfConventionalVehicles;
public int numberOfPrivateAutomatedVehicles;
public int numberOfSharedAutomatedVehicles;
public class CountItem {
// By function
public int privateVehicles;
public int pooledVehicles;
public int taxiVehicles;
public double numberOfPCUs;
// By automation
public int conventionalVehicles;
public int level5Vehicles;
public int level4Vehicles;
public int level3Vehicles;
public double pcus;
}
private AnalysisVehicle getAnaysisVehicle(Id<Vehicle> vehicleId) {
String rawVehicleId = vehicleId.toString();
AnalysisVehicle vehicle = new AnalysisVehicle();
if (rawVehicleId.contains("prav3")) {
vehicle.automationLevel = 3;
} else if (rawVehicleId.contains("prav4")) {
vehicle.automationLevel = 4;
} else if (rawVehicleId.contains("prav5")) {
vehicle.automationLevel = 5;
} else if (rawVehicleId.contains(SharedAVModule.AV_TAXI)) {
vehicle.automationLevel = 5;
vehicle.isShared = true;
} else if (rawVehicleId.contains(SharedAVModule.AV_POOL)) {
vehicle.automationLevel = 5;
vehicle.isShared = true;
vehicle.isPooled = true;
}
return vehicle;
}
private Vehicle getAutomationLevelVehicle(int automationLevel) {
switch (automationLevel) {
case 3:
return PRAV3;
case 4:
return PRAV4;
case 5:
return PRAV5;
default:
return CONVENTIONAL;
}
}
private void modifyCountItem(CountItem item, AnalysisVehicle analysisVehicle, Vehicle vehicle, Link link) {
switch (analysisVehicle.automationLevel) {
case 3:
item.level3Vehicles++;
break;
case 4:
item.level4Vehicles++;
break;
case 5:
item.level5Vehicles++;
break;
default:
item.conventionalVehicles++;
break;
}
if (analysisVehicle.isShared) {
if (analysisVehicle.isPooled) {
item.pooledVehicles++;
} else {
item.taxiVehicles++;
}
} else {
item.privateVehicles++;
}
item.pcus += flowEfficiencyCalculator.calculateFlowEfficiency(vehicle, link);
}
@Override
......@@ -86,39 +161,17 @@ public class FlowListener implements LinkEnterEventHandler {
int linkIndex = linkMap.get(event.getLinkId());
Link link = links.get(linkIndex);
Vehicle vehicle = CONVENTIONAL_VEHICLE;
String plainVehicleId = event.getVehicleId().toString();
if (plainVehicleId.startsWith("av_")) {
vehicle = SHARED_AV;
} else if (plainVehicleId.startsWith("prav_")) {
vehicle = PRIVATE_AV;
}
Item totalItem = totalItems[linkIndex];
totalItem.numberOfPCUs += flowEfficiencyCalculator.calculateFlowEfficiency(vehicle, link);
AnalysisVehicle analysisVehicle = getAnaysisVehicle(event.getVehicleId());
Vehicle vehicle = getAutomationLevelVehicle(analysisVehicle.automationLevel);
if (vehicle == CONVENTIONAL_VEHICLE) {
totalItem.numberOfConventionalVehicles++;
} else if (vehicle == SHARED_AV) {
totalItem.numberOfPrivateAutomatedVehicles++;
} else {
totalItem.numberOfSharedAutomatedVehicles++;
}
CountItem totalItem = totalItems[linkIndex];
modifyCountItem(totalItem, analysisVehicle, vehicle, link);
int timeIndex = (int) Math.floor((event.getTime() - startTime) / interval);
if (timeIndex > -1 && timeIndex < numberOfBins) {
Item timeItem = timeItems[linkIndex][timeIndex];
timeItem.numberOfPCUs += flowEfficiencyCalculator.calculateFlowEfficiency(vehicle, link);
if (vehicle == CONVENTIONAL_VEHICLE) {
timeItem.numberOfConventionalVehicles++;
} else if (vehicle == SHARED_AV) {
timeItem.numberOfPrivateAutomatedVehicles++;
} else {
timeItem.numberOfSharedAutomatedVehicles++;
}
CountItem timeItem = timeItems[linkIndex][timeIndex];
modifyCountItem(timeItem, analysisVehicle, vehicle, link);
}
}
}
......@@ -131,7 +184,7 @@ public class FlowListener implements LinkEnterEventHandler {
return numberOfBins;
}
public Item getTotalItem(Id<Link> linkId) {
public CountItem getTotalItem(Id<Link> linkId) {
int linkIndex = linkMap.get(linkId);
if (linkIndex == -1) {
......@@ -141,7 +194,7 @@ public class FlowListener implements LinkEnterEventHandler {
return totalItems[linkIndex];
}
public Item[] getTimeItems(Id<Link> linkId) {
public CountItem[] getTimeItems(Id<Link> linkId) {
int linkIndex = linkMap.get(linkId);
if (linkIndex == -1) {
......
......@@ -28,7 +28,7 @@ import com.vividsolutions.jts.geom.Coordinate;
import ch.ethz.matsim.baseline_scenario.config.CommandLine;
import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationException;
import ch.ethz.matsim.projects.astra_2018_002.analysis.flow.FlowListener.Item;
import ch.ethz.matsim.projects.astra_2018_002.analysis.flow.FlowListener.CountItem;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyCalculator;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.FlowEfficiencyConfigurator;
import ch.ethz.matsim.projects.astra_2018_002.flow_efficiency.StaticFlowEfficiencyCalculator;
......@@ -62,8 +62,8 @@ public class RunFlowAnalysis {
}
}
FlowListener flowListener = new FlowListener(scenario.getVehicles(), links, startTime, endTime, interval,
flowEfficiencyCalculator);
FlowListener flowListener = new FlowListener(links, startTime, endTime, interval, flowEfficiencyCalculator,
scenario.getVehicles());
EventsManager eventsManager = EventsUtils.createEventsManager();
eventsManager.addHandler(flowListener);
......@@ -79,28 +79,44 @@ public class RunFlowAnalysis {
.setCrs(crs) //
.setName("links") //
.addAttribute("link_id", String.class) //
.addAttribute("day_cv", Integer.class) //
.addAttribute("day_prav", Integer.class) //
.addAttribute("day_sav", Integer.class) //
.addAttribute("day_pcu", Double.class) //
.addAttribute("am_cv", Integer.class) //
.addAttribute("am_prav", Integer.class) //
.addAttribute("am_sav", Integer.class) //
.addAttribute("am_pcu", Double.class) //
.addAttribute("pm_cv", Integer.class) //
.addAttribute("pm_prav", Integer.class) //
.addAttribute("pm_sav", Integer.class) //
.addAttribute("pm_pcu", Double.class) //
.addAttribute("capacity", Double.class) //
.addAttribute("freespeed", Double.class) //
.addAttribute("lanes", Double.class) //
.addAttribute("osm_type", String.class) //
//
.addAttribute("day_private", Integer.class) //
.addAttribute("day_pooled", Integer.class) //
.addAttribute("day_taxi", Integer.class) //
.addAttribute("day_conventional", Integer.class) //
.addAttribute("day_level5", Integer.class) //
.addAttribute("day_level4", Integer.class) //
.addAttribute("day_level3", Integer.class) //
.addAttribute("day_pcu", Double.class) //
//
.addAttribute("am_private", Integer.class) //
.addAttribute("am_pooled", Integer.class) //
.addAttribute("am_taxi", Integer.class) //
.addAttribute("am_conventional", Integer.class) //
.addAttribute("am_level5", Integer.class) //
.addAttribute("am_level4", Integer.class) //
.addAttribute("am_level3", Integer.class) //
.addAttribute("am_pcu", Double.class) //
//
.addAttribute("pm_private", Integer.class) //
.addAttribute("pm_pooled", Integer.class) //
.addAttribute("pm_taxi", Integer.class) //
.addAttribute("pm_conventional", Integer.class) //
.addAttribute("pm_level5", Integer.class) //
.addAttribute("pm_level4", Integer.class) //
.addAttribute("pm_level3", Integer.class) //
.addAttribute("pm_pcu", Double.class) //
//
.create();
for (Link link : links) {
Item totalItem = flowListener.getTotalItem(link.getId());
Item morningItem = flowListener.getTimeItems(link.getId())[morningPeakIndex];
Item eveningItem = flowListener.getTimeItems(link.getId())[eveningPeakIndex];
CountItem totalItem = flowListener.getTotalItem(link.getId());
CountItem morningItem = flowListener.getTimeItems(link.getId())[morningPeakIndex];
CountItem eveningItem = flowListener.getTimeItems(link.getId())[eveningPeakIndex];
Coordinate fromCoord = new Coordinate(link.getFromNode().getCoord().getX(),
link.getFromNode().getCoord().getY());
......@@ -113,24 +129,42 @@ public class RunFlowAnalysis {
}
SimpleFeature feature = featureFactory.createPolyline(new Coordinate[] { fromCoord, toCoord },
new Object[] { link.getId().toString(), //
totalItem.numberOfConventionalVehicles, totalItem.numberOfPrivateAutomatedVehicles,
totalItem.numberOfSharedAutomatedVehicles, totalItem.numberOfPCUs, //
morningItem.numberOfConventionalVehicles, morningItem.numberOfPrivateAutomatedVehicles,
morningItem.numberOfSharedAutomatedVehicles, morningItem.numberOfPCUs, //
eveningItem.numberOfConventionalVehicles, eveningItem.numberOfPrivateAutomatedVehicles,
eveningItem.numberOfSharedAutomatedVehicles, eveningItem.numberOfPCUs, //
link.getCapacity(), link.getFreespeed(), link.getNumberOfLanes(), osmType //
new Object[] { //
link.getId().toString(), //
link.getCapacity(), //
link.getFreespeed(), //
link.getNumberOfLanes(), //
osmType, //
//
totalItem.privateVehicles, //
totalItem.pooledVehicles, //
totalItem.taxiVehicles, //
totalItem.conventionalVehicles, //
totalItem.level5Vehicles, //
totalItem.level4Vehicles, //
totalItem.level3Vehicles, //
totalItem.pcus, //
//
morningItem.privateVehicles, //
morningItem.pooledVehicles, //
morningItem.taxiVehicles, //
morningItem.conventionalVehicles, //
morningItem.level5Vehicles, //
morningItem.level4Vehicles, //
morningItem.level3Vehicles, //
morningItem.pcus, //
//
eveningItem.privateVehicles, //
eveningItem.pooledVehicles, //
eveningItem.taxiVehicles, //
eveningItem.conventionalVehicles, //
eveningItem.level5Vehicles, //
eveningItem.level4Vehicles, //
eveningItem.level3Vehicles, //
eveningItem.pcus, //
//
}, null);
features.add(feature);
List<String> row = new LinkedList<>();
row.add(link.getId().toString());
row.add(String.valueOf(totalItem.numberOfConventionalVehicles));
row.add(String.valueOf(totalItem.numberOfPrivateAutomatedVehicles));
row.add(String.valueOf(totalItem.numberOfSharedAutomatedVehicles));
row.add(String.valueOf(totalItem.numberOfPCUs));
}
ShapeFileWriter.writeGeometries(features, cmd.getOptionStrict("output-path"));
......
......@@ -2,8 +2,10 @@ 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.api.core.v01.population.Person;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.QSimConfigGroup.VehiclesSource;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.VehicleType;
import org.matsim.vehicles.VehicleUtils;
......@@ -17,6 +19,7 @@ public class FlowEfficiencyConfigurator {
static final public Id<VehicleType> PRAV3_ID = Id.create("prav3", VehicleType.class);
static final public Id<VehicleType> PRAV4_ID = Id.create("prav4", VehicleType.class);
static final public Id<VehicleType> PRAV5_ID = Id.create("prav5", VehicleType.class);
static final public Id<VehicleType> PASSENGER_VEHICLE_TYPE_ID = Id.create("car_passenger", VehicleType.class);
static public void configure(Config config) {
// Load vehicles by vehicle type
......@@ -44,6 +47,10 @@ public class FlowEfficiencyConfigurator {
.createVehicleType(CONVENTIONAL_VEHICLE_TYPE_ID);
scenario.getVehicles().addVehicleType(carVehicleType);
VehicleType passengerVehicleType = VehicleUtils.getFactory() //
.createVehicleType(PASSENGER_VEHICLE_TYPE_ID);
scenario.getVehicles().addVehicleType(passengerVehicleType);
VehicleType privateAvVehicleType = VehicleUtils.getFactory() //
.createVehicleType(PRIVATE_AV_VEHICLE_TYPE_ID);
scenario.getVehicles().addVehicleType(privateAvVehicleType);
......@@ -63,5 +70,11 @@ public class FlowEfficiencyConfigurator {
VehicleType prav5VehicleType = VehicleUtils.getFactory() //
.createVehicleType(PRAV5_ID);
scenario.getVehicles().addVehicleType(prav5VehicleType);
for (Person person : scenario.getPopulation().getPersons().values()) {
Id<Vehicle> vehicleId = Id.createVehicleId(person.getId().toString() + "_car_passenger");
Vehicle vehicle = scenario.getVehicles().getFactory().createVehicle(vehicleId, passengerVehicleType);
scenario.getVehicles().addVehicle(vehicle);
}
}
}
package ch.ethz.matsim.projects.astra_2018_002.mode_choice;
import java.util.Collection;
import java.util.List;
import org.matsim.api.core.v01.population.Person;
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 PassengerConstraint extends AbstractTripConstraint {
public static final String PASSENGER_MODE = "car_passenger";
@Override
public boolean validateBeforeEstimation(DiscreteModeChoiceTrip trip, String mode, List<String> previousModes) {
if (trip.getInitialMode().equals(PASSENGER_MODE)) {
if (!mode.equals(PASSENGER_MODE)) {
return false;
}
}
if (mode.equals(PASSENGER_MODE)) {
if (!trip.getInitialMode().equals(PASSENGER_MODE)) {
return false;
}
}
return true;
}
static public class Factory implements TripConstraintFactory {
@Override
public TripConstraint createConstraint(Person person, List<DiscreteModeChoiceTrip> planTrips,
Collection<String> availableModes) {
return new PassengerConstraint();
}
}
}
......@@ -10,17 +10,19 @@ import org.matsim.pt.transitSchedule.api.TransitSchedule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import ch.ethz.matsim.baseline_scenario.config.CommandLine;
import ch.ethz.matsim.baseline_scenario.config.CommandLine.ConfigurationException;
import ch.ethz.matsim.discrete_mode_choice.components.utils.home_finder.HomeFinder;
import ch.ethz.matsim.discrete_mode_choice.modules.AbstractDiscreteModeChoiceExtension;
import ch.ethz.matsim.discrete_mode_choice.modules.DiscreteModeChoiceModule;
import ch.ethz.matsim.discrete_mode_choice.modules.config.DiscreteModeChoiceConfigGroup;
import ch.ethz.matsim.discrete_mode_choice.modules.config.ModeAvailabilityConfigGroup;
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;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.outside.OutsideConstraint;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.outside.SwissHomeFinder;
import ch.ethz.matsim.projects.astra_2018_002.mode_choice.outside.SwissTourFinder;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing.DefaultSharedAVTravelCost;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.pricing.SharedAVTravelCost;
......@@ -31,6 +33,7 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
public static final String SWISS_MODE_AVAILABILITY_NAME = "SwissModeAvailability";
public static final String SWISS_TOUR_FINDER_NAME = "SwissTourFinder";
public static final String OUTSIDE_CONSTRAINT_NAME = "OutsideConstraint";
public static final String PASSENGER_CONSTRAINT_NAME = "PassengerConstraint";
private final UtilitySet utilitySet;
private final boolean useRouteChoice;
......@@ -48,11 +51,11 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
@Override
protected void installExtension() {
install(new DiscreteModeChoiceModule());
bindTripEstimator(SWISS_ESTIMATOR_NAME).to(SwissUtilityEstimator.class);
bindModeAvailability(SWISS_MODE_AVAILABILITY_NAME).to(SwissModeAvailability.class);
bindTourFinder(SWISS_TOUR_FINDER_NAME).to(SwissTourFinder.class);
bindTripConstraintFactory(OUTSIDE_CONSTRAINT_NAME).to(OutsideConstraint.Factory.class);
bindTripConstraintFactory(PASSENGER_CONSTRAINT_NAME).to(PassengerConstraint.Factory.class);
}
@Provides
......@@ -114,4 +117,17 @@ public class SwissDiscreteModeChoiceModule extends AbstractDiscreteModeChoiceExt
public OutsideConstraint.Factory provideOutsideConstraintFactory() {
return new OutsideConstraint.Factory();
}
@Provides
@Singleton
@Named("tour")
public HomeFinder provideHomeFinder() {
return new SwissHomeFinder();
}
@Provides
@Singleton
public PassengerConstraint.Factory providePassengerConstraintFactory() {
return new PassengerConstraint.Factory();
}
}
......@@ -44,6 +44,12 @@ public class SwissModeAvailability extends CarModeAvailability {
modes.add("outside");
}
Boolean isCarPassenger = (Boolean) person.getAttributes().getAttribute("isCarPassenger");
if (isCarPassenger != null && isCarPassenger) {
modes.add("car_passenger");
}