Commit 0c72b263 authored by Sebastian Hörl's avatar Sebastian Hörl
Browse files

Merge branch 'shared' into 'master'

Document & test shared AVs

See merge request ivt-vpl/astra_2018_002!8
parents c9981bbd 580ea0b8
......@@ -3,7 +3,7 @@
Private AVs can be activated via the `private_av` config group:
<module name="private_av">
<module name="private_avs">
<param name="usePrivateAVs" value="true" />
......@@ -14,6 +14,50 @@ Likewise, this option can be set via the command line:
java [...] --config:private_av.usePrivateAVs true
# How to run a simulation with shared AVs
Shared AVs can be activated via the `shared_av` config group:
<module name="shared_avs">
<!-- Defines whather shared AVs are active or not -->
<param name="useSharedAVs" value="true" />
<!-- Defines the fleet sizes of both services -->
<param name="taxiFleetSize" value="100" />
<param name="pooledFleetSize" value="100" />
<!-- Define a shape file for the operating area and zones for waiting time measurement therein -->
<param name="serviceAreaShapefile" value="path/to/service_areas.shp" />
<param name="waitingTimeZoneShapefile" value="path/to/waiting_time_zones.shp" />
<!-- Defines the relevant attribute names of the shapes in these shape files -->
<param name="serviceAreaAttribute" value="SAREA" />
<param name="waitingTimeZoneAttribute" value="WZONE" />
<!-- Defines which operating area is active -->
<param name="activeServiceArea" value="true" />
To run such a simulation, two shape files must be provided. The first is a file containing all the service areas for the scenarios (probably there will be exactly one per scenario). The path to that file must be given as the `serviceAreaShapefile` option. The shapes for these service areas must contain an attribute that can be configured via the `serviceAreaAttribute`. Finally, via config one can choose which of these areas is used in the next run by setting `activeServiceArea` to one of the possible values of that attribute, i.e. one selects one service area from this service area file.
Second, a file containing a segmentation of space for waiting time calculation must be given as `waitingTimeZoneShapefile`. Waiting times for the AV services are measured and predicted, for instance, in a grid. If the whole service area is one of these "waiting time zones", all waiting times in the service area will be averaged when predicting waiting times. The format of the shape file is again that each shape should contain an attribute that corresponds to `serviceAreaAttribute`. Only those shapes that correspond to the `selectedServiceArea` will be considered for estimation. The number of shapes for each service area is arbitrary. In any case, each of these waiting time zones gets a unique identifier. The attribute for that identifier is specified in the `waitingTimeZoneAttribute` option.
For the waiting time zones we usually just want some grid-like structure that is covering the service area. For that there is a script in `gis/`. It takes a number of command line arguments:
- A path to the shape file containing the actual service areas
- An output path for the new shape file with the waiting time zones
- The name of the attribute that distinguishes between service areas
- The new name of the attribute that distinguishes between waiting time zones
- The horizontal width of the hexagon grid
python3 path/to/service_areas.shp path/to/waiting_time_zones.shp SAREA WZONE 1000
# How to create the partial scenarios
This repository only contains code to run the requested scenarios in the ASTRA 2018/002 project. For the sake of avoiding code duplication, the scenario cutting code is still located in the [baseline_scenario]( repository, specifically in the (synpop)[] branch.
......@@ -14,7 +14,7 @@ public class ASTRAConfigurator {
Set<String> allowedModes = new HashSet<>(link.getAllowedModes());
if (allowedModes.contains("car")) {
allowedModes.addAll(Arrays.asList("prav3", "prav4", "prav5"));
allowedModes.addAll(Arrays.asList("av", "prav3", "prav4", "prav5"));
......@@ -18,7 +18,6 @@ import;
import ch.ethz.matsim.av.framework.AVQSimPlugin;
import ch.ethz.matsim.baseline_scenario.transit.simulation.BaselineTransitPlugin;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.dynamics.AVModesQSimPlugin;
public class ASTRAQSimModule extends AbstractModule {
......@@ -45,7 +44,6 @@ public class ASTRAQSimModule extends AbstractModule {
plugins.add(new TeleportationPlugin(config));
plugins.add(new PopulationPlugin(config));
plugins.add(new AVQSimPlugin(config));
plugins.add(new AVModesQSimPlugin(config));
return plugins;
......@@ -28,17 +28,9 @@ public class RunASTRA2018002 {
.allowPrefixes(SwissDiscreteModeChoiceModule.COMMAND_LINE_PREFIX) //
// ASTRAConfigGroup astraConfig = new ASTRAConfigGroup();
// astraConfig.setActiveServiceArea("zurich");
// astraConfig.setPooledFleetSize(0);
// astraConfig.setTaxiFleetSize(100);
// astraConfig.setServiceAreaShapefile("gis/operating_areas.shp");
// astraConfig.setServiceAreaAttribute("OAREA");
// astraConfig.setWaitingTimeZoneShapefile("gis/waiting_time_areas.shp");
// astraConfig.setWaitingTimeZoneIdentifierAttribute("WZONE");
// Load config
Config config = ConfigUtils.loadConfig(cmd.getOptionStrict("config-path"));
// Adjust config (they need to stay in the correct order!)
......@@ -15,6 +15,7 @@ import org.matsim.core.utils.misc.Time;
import org.matsim.facilities.ActivityFacilities;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.baseline_scenario.transit.routing.EnrichedTransitRoute;
import ch.ethz.matsim.discrete_mode_choice.components.estimators.AbstractTripRouterEstimator;
import ch.ethz.matsim.discrete_mode_choice.model.DiscreteModeChoiceTrip;
......@@ -143,8 +144,7 @@ public abstract class BaseUtilityEstimator extends AbstractTripRouterEstimator {
tripVariables.accessEgressTime_min += leg.getTravelTime() / 60.0;
travelDistance_km += leg.getRoute().getDistance() / 1000.0;
case SharedAVModule.AV_POOL:
case SharedAVModule.AV_TAXI:
case AVModule.AV_MODE:
ExtendedAVRoute route = (ExtendedAVRoute) leg.getRoute();
tripVariables.inVehicleTime_min += route.getTravelTime() / 60.0;
tripVariables.waitingTime_min += route.getWaitingTime() / 60.0;
......@@ -8,23 +8,25 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
private final static String USE_SHARED_AVS = "useSharedAVs";
private final static String TAXI_FLEET_SIZE = "taxiFleetSize";
private final static String POOLED_FLEET_SIZE = "pooledFleetSize";
private final static String SERVICE_AREA_ATTRIBUTE = "serviceAreaAttribute";
private final static String ACTIVE_SERVICE_AREA = "activeServiceArea";
private final static String SERVICE_AREA_SHAPEFILE = "serviceAreaShapefile";
private final static String WAITING_TIME_ZONE_SHAPEFILE = "waitingTimeZoneShapefile";
private final static String WAITING_TIME_ZONE_IDENTIFIER_ATTRIBUTE = "waitingTimeZoneIdentifierAttribute";
private final static String WAITING_TIME_ZONE_ATTRIBUTE = "waitingTimeZoneAttribute";
private boolean useSharedAVs = false;
private int taxiFleetSize = 100;
private int pooledFleetSize = 0;
private String serviceAreaAttribute = "OAREA";
private String activeServiceArea = "ZH";
private String serviceAreaShapefile = "service_area.shp";
private String serviceAreaAttribute = "SAREA";
private String activeServiceArea = "Active service area not set";
private String serviceAreaShapefile = "service_areas.shp";
private String waitingTimeZoneIdentifierAttribute = "WZONE";
private String waitingTimeZoneShapefile = "waiting_time_areas.shp";
private String waitingTimeZoneAttribute = "WZONE";
private String waitingTimeZoneShapefile = "waiting_time_zones.shp";
public SharedAVConfigGroup() {
......@@ -100,13 +102,13 @@ public class SharedAVConfigGroup extends ReflectiveConfigGroup {
this.waitingTimeZoneShapefile = waitingTimeZoneShapefile;
public String getWaitingTimeZoneIdentifierAttribute() {
return waitingTimeZoneIdentifierAttribute;
public String getWaitingTimeZoneAttribute() {
return waitingTimeZoneAttribute;
public void setWaitingTimeZoneIdentifierAttribute(String waitingTimeZoneIdentifierAttribute) {
this.waitingTimeZoneIdentifierAttribute = waitingTimeZoneIdentifierAttribute;
public void setWaitingTimeZoneAttribute(String waitingTimeZoneAttribute) {
this.waitingTimeZoneAttribute = waitingTimeZoneAttribute;
......@@ -44,12 +44,6 @@ public class SharedAVConfigurator {
ModeParams avParams = new ModeParams(AVModule.AV_MODE);
ModeParams poolParams = new ModeParams(SharedAVModule.AV_POOL);
ModeParams taxiParams = new ModeParams(SharedAVModule.AV_TAXI);
DiscreteModeChoiceConfigGroup dmcConfig = (DiscreteModeChoiceConfigGroup) config.getModules()
......@@ -136,7 +136,7 @@ public class SharedAVModule extends AbstractDiscreteModeChoiceExtension {
public List<WaitingTimeZone> provideWaitingTimeZones(@Named(AVModule.AV_MODE) Network network,
SharedAVConfigGroup astraConfig) {
WaitingTimeZoneReader reader = new WaitingTimeZoneReader(astraConfig.getWaitingTimeZoneIdentifierAttribute(),
WaitingTimeZoneReader reader = new WaitingTimeZoneReader(astraConfig.getWaitingTimeZoneAttribute(),
astraConfig.getServiceAreaAttribute(), network);
URL url = ConfigGroup.getInputFileURL(getConfig().getContext(), astraConfig.getWaitingTimeZoneShapefile());
return, url);
package ch.ethz.matsim.projects.astra_2018_002.shared_av.dynamics;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.dvrp.passenger.PassengerEngine;
import org.matsim.core.config.Config;
import org.matsim.core.mobsim.framework.MobsimAgent;
import org.matsim.core.mobsim.qsim.AbstractQSimPlugin;
import org.matsim.core.mobsim.qsim.interfaces.DepartureHandler;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.SharedAVModule;
public class AVModesQSimPlugin extends AbstractQSimPlugin {
public AVModesQSimPlugin(Config config) {
public Collection<? extends Module> modules() {
return Collections.singleton(new AbstractModule() {
protected void configure() {
public AVDepartureHandler provideAVDepartureHandler(PassengerEngine passengerEngine) {
return new AVDepartureHandler(passengerEngine);
public Collection<Class<? extends DepartureHandler>> departureHandlers() {
return Arrays.asList(AVDepartureHandler.class);
static private class AVDepartureHandler implements DepartureHandler {
private final PassengerEngine delegate;
public AVDepartureHandler(PassengerEngine delegate) {
this.delegate = delegate;
public boolean handleDeparture(double now, MobsimAgent agent, Id<Link> linkId) {
if (agent.getMode().equals(SharedAVModule.AV_POOL) || agent.getMode().equals(SharedAVModule.AV_TAXI)) {
return delegate.handleDeparture(now, agent, linkId);
return false;
......@@ -23,6 +23,7 @@ import org.matsim.core.router.util.TravelTime;
import org.matsim.facilities.Facility;
import ch.ethz.matsim.av.framework.AVModule;
import ch.ethz.matsim.av.routing.AVRoute;
import ch.ethz.matsim.av.routing.AVRouteFactory;
import ch.ethz.matsim.projects.astra_2018_002.shared_av.waiting_time.AVWaitingTime;
......@@ -101,7 +102,7 @@ public class ASTRAAVRoutingModule implements RoutingModule {
ExtendedAVRoute extendedAvRoute = new ExtendedAVRoute(avRoute);
Leg avLeg = populationFactory.createLeg(mode);
Leg avLeg = populationFactory.createLeg(AVModule.AV_MODE);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment