Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1f64172
fix(emissions): update detailed vs average lookup behavior based on c…
Nitnelav May 19, 2025
f7e632d
Merge branch 'develop' into develop
Nitnelav May 19, 2025
803bbdf
Merge branch 'develop' into develop
Nitnelav Jun 16, 2025
9012a23
Merge branch 'eqasim-org:develop' into develop
Nitnelav Jun 16, 2025
2c45875
Merge branch 'eqasim-org:develop' into develop
Nitnelav Jun 21, 2025
73134d9
Merge branch 'eqasim-org:develop' into develop
Nitnelav Sep 4, 2025
7016a9e
add motorcycle mode
Nitnelav Sep 20, 2025
4d15a09
run adjustScenario from configurator on population routing
Nitnelav Sep 21, 2025
7643584
move motorcycle stuff to core
Nitnelav Sep 24, 2025
7cd1250
small change
Nitnelav Sep 24, 2025
5ab541c
put everything but motorcycle activation outside
Nitnelav Oct 2, 2025
8d6dc6b
add core/melun_test to .gitignore
Nitnelav Oct 2, 2025
42cf93d
add motorcycle mode
Nitnelav Sep 20, 2025
79a08eb
run adjustScenario from configurator on population routing
Nitnelav Sep 21, 2025
4b2b5bb
move motorcycle stuff to core
Nitnelav Sep 24, 2025
90fa63f
small change
Nitnelav Sep 24, 2025
da3d0a1
put everything but motorcycle activation outside
Nitnelav Oct 2, 2025
c06f936
add core/melun_test to .gitignore
Nitnelav Oct 2, 2025
b14622a
Merge branch 'handle_motorcycles_2025' of https://github.com/Symexpo/…
Nitnelav Oct 2, 2025
b854f95
Merge branch 'develop' into handle_motorcycles_2025
Nitnelav Oct 2, 2025
98eeed3
Merge branch 'develop' into handle_motorcycles_2025
Nitnelav Oct 6, 2025
5070dc7
cleanup
Nitnelav Oct 6, 2025
c97023f
add TestMotorcycles
Nitnelav Oct 8, 2025
35113b8
Merge branch 'develop' into handle_motorcycles_2025
Nitnelav Oct 8, 2025
88960b6
update config to latest version
Nitnelav Oct 10, 2025
35127b1
fix config
Nitnelav Oct 10, 2025
161ca50
fix config and update test assertion
Nitnelav Oct 10, 2025
687cb49
isolate motorcycle tests
Nitnelav Oct 10, 2025
f6546bd
fix config and update the test withAbstractAsccess
Nitnelav Oct 10, 2025
0ea5449
fix TestEmissions
Nitnelav Oct 10, 2025
79a66f9
Merge branch 'develop' into handle_motorcycles_2025
Nitnelav Oct 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ dependency-reduced-pom.xml
*.iml
*.idea
simulation_output
core/melun_test
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ public class GenerateConfig {
protected final List<String> ACTIVITY_TYPES = Arrays.asList("home", "work", "education", "shop", "leisure", "other",
"freight_loading", "freight_unloading", "outside");

protected final List<String> MODES = Arrays.asList("walk", "bike", "pt", "car", "car_passenger", "truck",
"outside");
protected final List<String> MODES = Arrays.asList("walk", "bike", "pt", "car", "car_passenger", "motorcycle",
"truck", "outside");

private final List<String> NETWORK_MODES = Arrays.asList("car", "car_passenger", "truck");
private final List<String> NETWORK_MODES = Arrays.asList("car", "car_passenger", "truck", "motorcycle");

private final CommandLine cmd;
private final String prefix;
Expand Down Expand Up @@ -158,7 +158,7 @@ protected void adaptConfiguration(Config config) {

dmcConfig.setTripEstimator(EqasimModeChoiceModule.UTILITY_ESTIMATOR_NAME);
dmcConfig.setTourEstimator(EstimatorModule.CUMULATIVE);
dmcConfig.setCachedModes(Arrays.asList("car", "bike", "pt", "walk", "car_passenger", "truck"));
dmcConfig.setCachedModes(Arrays.asList("car", "bike", "pt", "walk", "car_passenger", "truck", "motorcycle"));

dmcConfig.setTourFinder(TourFinderModule.ACTIVITY_BASED);
dmcConfig.getActivityTourFinderConfigGroup().setActivityTypes(Arrays.asList("home", "outside"));
Expand All @@ -170,14 +170,15 @@ protected void adaptConfiguration(Config config) {
EqasimModeChoiceModule.PASSENGER_CONSTRAINT_NAME, EqasimModeChoiceModule.OUTSIDE_CONSTRAINT_NAME));

dmcConfig.setHomeFinder(EqasimModeChoiceModule.HOME_FINDER);
dmcConfig.getVehicleTourConstraintConfig().setRestrictedModes(Arrays.asList("car", "bike"));
dmcConfig.getVehicleTourConstraintConfig().setRestrictedModes(Arrays.asList("car", "bike", "motorcycle"));

dmcConfig.setTourFilters(Arrays.asList(EqasimModeChoiceModule.OUTSIDE_FILTER_NAME,
EqasimModeChoiceModule.TOUR_LENGTH_FILTER_NAME));

// Set up modes

eqasimConfig.setEstimator(TransportMode.car, EqasimModeChoiceModule.CAR_ESTIMATOR_NAME);
eqasimConfig.setEstimator(TransportMode.motorcycle, EqasimModeChoiceModule.MOTORCYCLE_ESTIMATOR_NAME);
eqasimConfig.setEstimator(TransportMode.pt, EqasimModeChoiceModule.PT_ESTIMATOR_NAME);
eqasimConfig.setEstimator(TransportMode.bike, EqasimModeChoiceModule.BIKE_ESTIMATOR_NAME);
eqasimConfig.setEstimator(TransportMode.walk, EqasimModeChoiceModule.WALK_ESTIMATOR_NAME);
Expand All @@ -187,6 +188,7 @@ protected void adaptConfiguration(Config config) {
}

eqasimConfig.setCostModel(TransportMode.car, EqasimModeChoiceModule.ZERO_COST_MODEL_NAME);
eqasimConfig.setCostModel(TransportMode.motorcycle, EqasimModeChoiceModule.ZERO_COST_MODEL_NAME);
eqasimConfig.setCostModel(TransportMode.pt, EqasimModeChoiceModule.ZERO_COST_MODEL_NAME);

// To make sure trips arriving later than the next activity end time are taken into account when routing the next trip during mode choice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.eqasim.core.scenario.cutter.network.RoadNetwork;
import org.eqasim.core.scenario.preparation.FacilityPlacement.OSMFacilityPlacementVoter;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.core.config.CommandLine;
import org.matsim.core.config.CommandLine.ConfigurationException;
import org.matsim.core.config.ConfigUtils;
Expand All @@ -14,6 +16,9 @@
import org.matsim.facilities.FacilitiesWriter;
import org.matsim.facilities.MatsimFacilitiesReader;

import java.util.HashSet;
import java.util.Set;

public class RunPreparation {
static public void main(String[] args) throws ConfigurationException, InterruptedException {
CommandLine cmd = new CommandLine.Builder(args) //
Expand All @@ -38,6 +43,15 @@ static public void main(String[] args) throws ConfigurationException, Interrupte
FacilityPlacement facilityPlacement = new FacilityPlacement(numberOfThreads, batchSize, roadNetwork, voter);
facilityPlacement.run(scenario.getActivityFacilities());

// add motorcycle mode
for (Link link : scenario.getNetwork().getLinks().values()) {
Set<String> modes = new HashSet<>(link.getAllowedModes());
if (modes.contains("car")) {
modes.add("motorcycle");
link.setAllowedModes(modes);
}
}

// Fix freight activities (TODO: should go to the pipeline)
FreightAssignment freightAssignment = new FreightAssignment(scenario.getNetwork(),
scenario.getActivityFacilities());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,8 @@
import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters;
import org.eqasim.core.simulation.mode_choice.utilities.EqasimUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.BikeUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.CarUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.PtUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.WalkUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.ZeroUtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.BikePredictor;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.CarPredictor;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.PersonPredictor;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.PtPredictor;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.WalkPredictor;
import org.eqasim.core.simulation.mode_choice.utilities.estimators.*;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.*;
import org.eqasim.core.simulation.modes.drt.mode_choice.constraints.DrtServiceAreaConstraint;
import org.eqasim.core.simulation.modes.drt.mode_choice.constraints.DrtWalkConstraint;
import org.eqasim.core.simulation.modes.drt.mode_choice.predictors.DefaultDrtPredictor;
Expand Down Expand Up @@ -59,6 +51,7 @@ public class EqasimModeChoiceModule extends AbstractEqasimExtension {
public static final String UTILITY_ESTIMATOR_NAME = "EqasimUtilityEstimator";

public static final String CAR_ESTIMATOR_NAME = "CarUtilityEstimator";
public static final String MOTORCYCLE_ESTIMATOR_NAME = "MotorcycleUtilityEstimator";
public static final String PT_ESTIMATOR_NAME = "PtUtilityEstimator";
public static final String BIKE_ESTIMATOR_NAME = "BikeUtilityEstimator";
public static final String WALK_ESTIMATOR_NAME = "WalkUtilityEstimator";
Expand All @@ -83,6 +76,7 @@ protected void installEqasimExtension() {
bindTripEstimator(UTILITY_ESTIMATOR_NAME).to(EqasimUtilityEstimator.class);

bind(CarPredictor.class);
bind(MotorcyclePredictor.class);
bind(PtPredictor.class);
bind(BikePredictor.class);
bind(WalkPredictor.class);
Expand All @@ -91,6 +85,7 @@ protected void installEqasimExtension() {

bindUtilityEstimator(ZERO_ESTIMATOR_NAME).to(ZeroUtilityEstimator.class);
bindUtilityEstimator(CAR_ESTIMATOR_NAME).to(CarUtilityEstimator.class);
bindUtilityEstimator(MOTORCYCLE_ESTIMATOR_NAME).to(MotorcycleUtilityEstimator.class);
bindUtilityEstimator(PT_ESTIMATOR_NAME).to(PtUtilityEstimator.class);
bindUtilityEstimator(BIKE_ESTIMATOR_NAME).to(BikeUtilityEstimator.class);
bindUtilityEstimator(WALK_ESTIMATOR_NAME).to(WalkUtilityEstimator.class);
Expand Down Expand Up @@ -136,6 +131,12 @@ public CostModel provideCarCostModel(Map<String, Provider<CostModel>> factory, E
return getCostModel(factory, config, "car");
}

@Provides
@Named("motorcycle")
public CostModel provideMotorcycleCostModel(Map<String, Provider<CostModel>> factory, EqasimConfigGroup config) {
return getCostModel(factory, config, "motorcycle");
}

@Provides
@Named("pt")
public CostModel providePtCostModel(Map<String, Provider<CostModel>> factory, EqasimConfigGroup config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ public class CarParameters {
public double constantParkingSearchPenalty_min = 0.0;
}

public class MotorcycleParameters {
public double alpha_u = 0.0;
public double betaTravelTime_u_min = 0.0;

public double additionalAccessEgressWalkTime_min = 0.0;
public double constantParkingSearchPenalty_min = 0.0;
}

public class PtParameters {
public double alpha_u = 0.0;
public double betaLineSwitch_u = 0.0;
Expand Down Expand Up @@ -44,6 +52,7 @@ public class DrtParameters {
public double betaCost_u_MU = 0.0;

public final CarParameters car = new CarParameters();
public final MotorcycleParameters motorcycle = new MotorcycleParameters();
public final PtParameters pt = new PtParameters();
public final BikeParameters bike = new BikeParameters();
public final WalkParameters walk = new WalkParameters();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.eqasim.core.simulation.mode_choice.utilities.estimators;

import com.google.inject.Inject;
import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters;
import org.eqasim.core.simulation.mode_choice.utilities.UtilityEstimator;
import org.eqasim.core.simulation.mode_choice.utilities.predictors.MotorcyclePredictor;
import org.eqasim.core.simulation.mode_choice.utilities.variables.MotorcycleVariables;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip;

import java.util.List;

public class MotorcycleUtilityEstimator implements UtilityEstimator {
private final ModeParameters parameters;
private final MotorcyclePredictor predictor;

@Inject
public MotorcycleUtilityEstimator(ModeParameters parameters, MotorcyclePredictor predictor) {
this.parameters = parameters;
this.predictor = predictor;
}

protected double estimateConstantUtility() {
return parameters.motorcycle.alpha_u;
}

protected double estimateTravelTimeUtility(MotorcycleVariables variables) {
return parameters.motorcycle.betaTravelTime_u_min * variables.travelTime_min;
}

protected double estimateAccessEgressTimeUtility(MotorcycleVariables variables) {
return parameters.walk.betaTravelTime_u_min * variables.accessEgressTime_min;
}

protected double estimateMonetaryCostUtility(MotorcycleVariables variables) {
return parameters.betaCost_u_MU * EstimatorUtils.interaction(variables.euclideanDistance_km,
parameters.referenceEuclideanDistance_km, parameters.lambdaCostEuclideanDistance) * variables.cost_MU;
}

@Override
public double estimateUtility(Person person, DiscreteModeChoiceTrip trip, List<? extends PlanElement> elements) {
MotorcycleVariables variables = predictor.predictVariables(person, trip, elements);

double utility = 0.0;

utility += estimateConstantUtility();
utility += estimateTravelTimeUtility(variables);
utility += estimateAccessEgressTimeUtility(variables);
utility += estimateMonetaryCostUtility(variables);

return utility;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.eqasim.core.simulation.mode_choice.utilities.predictors;

import com.google.common.base.Verify;
import com.google.inject.Inject;
import com.google.inject.name.Named;
import org.eqasim.core.simulation.mode_choice.cost.CostModel;
import org.eqasim.core.simulation.mode_choice.parameters.ModeParameters;
import org.eqasim.core.simulation.mode_choice.utilities.variables.MotorcycleVariables;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.Person;
import org.matsim.api.core.v01.population.PlanElement;
import org.matsim.contribs.discrete_mode_choice.model.DiscreteModeChoiceTrip;
import org.matsim.core.router.TripStructureUtils;

import java.util.List;

public class MotorcyclePredictor extends CachedVariablePredictor<MotorcycleVariables> {
private final CostModel costModel;
private final ModeParameters parameters;

@Inject
public MotorcyclePredictor(ModeParameters parameters, @Named("motorcycle") CostModel costModel) {
this.costModel = costModel;
this.parameters = parameters;
}

@Override
public MotorcycleVariables predict(Person person, DiscreteModeChoiceTrip trip, List<? extends PlanElement> elements) {
double motorcycleTravelTime_min = parameters.motorcycle.constantParkingSearchPenalty_min;
double accessEgressTime_min = parameters.motorcycle.additionalAccessEgressWalkTime_min;

boolean foundCar = false;

for (Leg leg : TripStructureUtils.getLegs(elements)) {
if (leg.getMode().equals(TransportMode.motorcycle)) {
Verify.verify(!foundCar);
motorcycleTravelTime_min += leg.getTravelTime().seconds() / 60.0;
} else if (leg.getMode().equals(TransportMode.walk)) {
accessEgressTime_min += leg.getTravelTime().seconds() / 60.0;
} else {
throw new IllegalStateException("Unexpected mode in car chain: " + leg.getMode());
}
}

double cost_MU = costModel.calculateCost_MU(person, trip, elements);
double euclideanDistance_km = PredictorUtils.calculateEuclideanDistance_km(trip);

return new MotorcycleVariables(motorcycleTravelTime_min, cost_MU, euclideanDistance_km, accessEgressTime_min);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.eqasim.core.simulation.mode_choice.utilities.variables;

public class MotorcycleVariables implements BaseVariables {
final public double travelTime_min;
final public double cost_MU;
final public double euclideanDistance_km;
final public double accessEgressTime_min;

public MotorcycleVariables(double travelTime_min, double cost_MU, double euclideanDistance_km,
double accessEgressTime_min) {
this.travelTime_min = travelTime_min;
this.cost_MU = cost_MU;
this.euclideanDistance_km = euclideanDistance_km;
this.accessEgressTime_min = accessEgressTime_min;
}
}
Loading