Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adaptions in bicycle code for routing, scoring, and other vehicle interaction #325

Merged
merged 88 commits into from
Aug 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
eef666d
first design for leg scoring that uses the travel disutility object d…
kainagel Nov 1, 2017
6275a03
resource files
Jan 28, 2018
7a9f188
update and reorganize tests and example classes
Jan 28, 2018
81634b2
reactived code that is not yet revised
Jan 28, 2018
c61bc42
Merge remote-tracking branch 'origin/master' into bicycleScoring
Jan 28, 2018
655437b
get tests running by using other evetns compare
Jan 28, 2018
ce8a452
some revision
Jan 31, 2018
6bc8286
correct disutility-based scoring
Jan 31, 2018
cdf6f32
set iterations correctly
Jan 31, 2018
72b694b
simplify new scoring function factory
Jan 31, 2018
955a03a
update and clarify tests
Feb 7, 2018
4380c62
reduce number of largely redundant files for tests
Feb 7, 2018
2732740
finalize simplification of tests (incl. speeds in km/h)
Feb 7, 2018
6a6091e
comment in travel time
Feb 7, 2018
a03460f
simplify bicycle module
Feb 7, 2018
addf042
first version of bicycle leg scoring
Feb 7, 2018
4fc4fa7
Merge remote-tracking branch 'origin/master' into bicycleScoring
Feb 7, 2018
12e95ca
solve minor compile error after merging
Feb 7, 2018
5646d46
correct sign
Feb 9, 2018
204c608
files for tests
Feb 9, 2018
1ab8c88
change to bicycle leg scoring
Feb 9, 2018
aa54e9a
update tests
Feb 9, 2018
7be43c2
Merge remote-tracking branch 'origin/master' into bicycleScoring
Feb 9, 2018
06c2edb
rearragen packages and two working versions of disutility
Feb 14, 2018
c3b9809
finalize package rearrangement
Feb 14, 2018
0fac553
new class combining utility utils
Feb 14, 2018
9b0b61e
config now created out of the code
Feb 14, 2018
a70e226
delete redundant input file
Feb 14, 2018
fa539c5
bicycle disutilities with logNormalRandom based on attributables
Feb 19, 2018
25db4ca
update tests
Feb 19, 2018
262356e
update example
Feb 19, 2018
9b5e676
update package structure
Feb 19, 2018
5852ee9
adapt randomizing disutility to be used in delegation
Feb 19, 2018
c26d0ed
Merge remote-tracking branch 'origin/master' into bicycleScoring
Feb 19, 2018
6fd69bd
put network back that was apparently deleted by mistake
Feb 19, 2018
638d7e2
Merge remote-tracking branch 'origin/master' into bicycleScoring
Mar 3, 2018
e30d1bb
Merge remote-tracking branch 'origin/master' into bicycleScoring
Mar 17, 2018
1b34c59
adjust path
Apr 2, 2018
7461771
found error that prevented correct speed reduction and fix it
Apr 2, 2018
f6e6f59
simpler approach for disutility does not work yet, b/c of attributables
Apr 2, 2018
c7369a9
revise example class
Apr 2, 2018
70e3ecb
Merge remote-tracking branch 'origin/master' into bicycleScoring
Apr 2, 2018
518a698
separate random terms for different utility components
Apr 2, 2018
e4b02c8
create getter for keys so that you can copy attributes without knowin…
gabrielthunig Apr 4, 2018
ef715fe
Copy attributes for nodes and links. Not for the network because it i…
gabrielthunig Apr 4, 2018
f7c4dee
Merge remote-tracking branch 'origin/getAttributeKeys' into bicycleSc…
Apr 7, 2018
8bf5626
Merge remote-tracking branch 'origin/master' into bicycleScoring
Apr 7, 2018
fbec5d7
simplify bicycle disutility after link attribute workaround not required
Apr 7, 2018
5f67354
update cobblestone test results
Apr 7, 2018
46e7af1
revise tests and example
Apr 7, 2018
104bd0e
revise other tests
Apr 7, 2018
6bb5dd8
allowing run example with and without config file
Apr 11, 2018
59d7088
Merge remote-tracking branch 'origin/master' into bicycleScoring
Jun 12, 2018
86e1146
clean up after partly flawed merge
Jun 12, 2018
5f65907
update output plans for test (now with vehicle id)
Jun 13, 2018
1c9236d
update speeds in networks to more realisitc values
Jun 13, 2018
e3d92c3
minor
Jun 13, 2018
f0bed14
adjust locations
Jun 13, 2018
405b08b
minor
Jun 13, 2018
a102c09
minor
Jun 13, 2018
693840a
correct bicycle speeds
Jun 14, 2018
855f3c7
correct console information
Jun 14, 2018
341c5a9
remove intermediately tested disutility-based scoring
Jun 14, 2018
21464e1
renaming
Jun 14, 2018
735fdb2
revise link-based bicycle scoring
Jun 14, 2018
dac2848
clean up leg-based bicycle scoring, make it extension of CN leg scoring
Jun 14, 2018
5c58713
simplify leg-based bicycle scoring, stronger use of inherited method
Jun 14, 2018
8604aa8
clean up class, revise reference files (last decimal position changed)
Jun 14, 2018
140e6a6
remove obsolete alternative option
Jun 14, 2018
8c6565b
small simplification
Jun 14, 2018
f2be18e
improve comment
Jun 14, 2018
14b58f9
Get both leg- and link-based scoring runnable with (nearly) same results
Jun 14, 2018
1e8443e
smaller revision
Jun 14, 2018
2631b0d
make type of bicycle scoring adjustable
Jun 14, 2018
7d5a594
bicycle scoring type in config group
Jun 14, 2018
2a90b8c
changed motorized interaction test to link-based scoring
Jun 14, 2018
ed2600f
comment some logs
Jun 14, 2018
2d0ec5c
reactivate car counter
Jun 14, 2018
b16cd17
update test reference for motorized interaction test
Jun 14, 2018
e6711da
remove unnecessary inject
Jun 19, 2018
305d263
add alternative network
Jun 20, 2018
a3189ba
remove redundant test
Jun 21, 2018
7cadf94
undo some unnecessary changes
Jun 21, 2018
9483716
Merge branch 'master' into bicycleScoring
Jul 24, 2018
ffd3904
Merge branch 'master' into bicycleScoring
Aug 17, 2018
da7f6af
Merge branch 'master' into bicycleScoring
neuma Aug 22, 2018
62ff569
Merge branch 'master' into bicycleScoring
neuma Aug 24, 2018
9525184
delete obsolete bicycle qsim factory
Aug 26, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.bicycle.run;
package org.matsim.contrib.bicycle;

import java.util.Map;
import java.util.TreeMap;
Expand All @@ -34,11 +34,14 @@ public class BicycleConfigGroup extends ConfigGroup {
private static final String INPUT_COMFORT = "marginalUtilityOfComfort_m";
private static final String INPUT_INFRASTRUCTURE = "marginalUtilityOfInfrastructure_m";
private static final String INPUT_GRADIENT = "marginalUtilityOfGradient_m_100m";

public static enum BicycleScoringType {legBased, linkBased};

private String networkAttFile = null;
private double marginalUtilityOfComfort;
private double marginalUtilityOfInfrastructure;
private double marginalUtilityOfGradient;
private BicycleScoringType bicycleScoringType = BicycleScoringType.legBased;

public BicycleConfigGroup() {
super(GROUP_NAME);
Expand Down Expand Up @@ -127,4 +130,12 @@ public void setMarginalUtilityOfGradient_m_100m(final double value) {
public double getMarginalUtilityOfGradient_m_100m() {
return this.marginalUtilityOfGradient;
}

public void setBicycleScoringType(final BicycleScoringType value) {
this.bicycleScoringType = value;
}

public BicycleScoringType getBicycleScoringType() {
return this.bicycleScoringType;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ public final class BicycleLabels {
private BicycleLabels() {
// Don't allow to create instances of this class
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* *********************************************************************** *
* project: org.matsim.* *
* BicycleLegScoring.java *
* *
* *********************************************************************** *
* *
* copyright : (C) 2007 by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
* *********************************************************************** *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */

package org.matsim.contrib.bicycle;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.core.population.routes.NetworkRoute;
import org.matsim.core.scoring.functions.CharyparNagelLegScoring;
import org.matsim.core.scoring.functions.ScoringParameters;

/**
* @author dziemke
*/
public class BicycleLegScoring extends CharyparNagelLegScoring {
// private static final Logger LOG = Logger.getLogger(BicycleLegScoring.class);

private final double marginalUtilityOfInfrastructure_m;
private final double marginalUtilityOfComfort_m;
private final double marginalUtilityOfGradient_m_100m;

public BicycleLegScoring(final ScoringParameters params, Network network, BicycleConfigGroup bicycleConfigGroup) {
super(params, network);

this.marginalUtilityOfInfrastructure_m = bicycleConfigGroup.getMarginalUtilityOfInfrastructure_m();
this.marginalUtilityOfComfort_m = bicycleConfigGroup.getMarginalUtilityOfComfort_m();
this.marginalUtilityOfGradient_m_100m = bicycleConfigGroup.getMarginalUtilityOfGradient_m_100m();
}

protected double calcLegScore(final double departureTime, final double arrivalTime, final Leg leg) {
// Get leg score from regular CharyparNagelLegScoring
double legScore = super.calcLegScore(departureTime, arrivalTime, leg);
// LOG.warn("----- legScore = " + legScore);

NetworkRoute networkRoute = (NetworkRoute) leg.getRoute();

List<Id<Link>> linkIds = new ArrayList<>();
linkIds.addAll(networkRoute.getLinkIds());
linkIds.add(networkRoute.getEndLinkId());

// Iterate over all links of the route
for (Id<Link> linkId : linkIds) {
double scoreOnLink = BicycleUtilityUtils.computeLinkBasedScore(network.getLinks().get(linkId),
marginalUtilityOfComfort_m, marginalUtilityOfInfrastructure_m, marginalUtilityOfGradient_m_100m);
// LOG.warn("----- link = " + linkId + " -- scoreOnLink = " + scoreOnLink);
legScore += scoreOnLink;
}
return legScore;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.bicycle.run;
package org.matsim.contrib.bicycle;

import org.apache.log4j.Logger;
import org.matsim.api.core.v01.Id;
Expand All @@ -26,31 +26,46 @@
import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.bicycle.MotorizedInteractionEvent;
import org.matsim.contrib.bicycle.MotorizedInteractionEventHandler;
import org.matsim.core.events.algorithms.Vehicle2DriverEventHandler;
import org.matsim.core.gbl.Gbl;
import org.matsim.core.scoring.SumScoringFunction;
import org.matsim.core.scoring.functions.ModeUtilityParameters;
import org.matsim.core.scoring.functions.ScoringParameters;
import org.matsim.vehicles.Vehicle;

/**
* @author dziemke
*
* This is an alternative to BicycleLegScoring. Currently yields slightly different scores than BicyleLegScoring.
* This link-based scoring should be used when true times spent on an individual link are relevant
* and for the scoring of the interaction with motorized traffic.
*/
public class BicycleScoring implements SumScoringFunction.ArbitraryEventScoring, MotorizedInteractionEventHandler {
private static final Logger LOG = Logger.getLogger(BicycleScoring.class);
public class BicycleLinkScoring implements SumScoringFunction.ArbitraryEventScoring, MotorizedInteractionEventHandler {
private static final Logger LOG = Logger.getLogger(BicycleLinkScoring.class);

protected final ScoringParameters params;

private Scenario scenario;
private BicycleTravelDisutility bicycleTravelDisutility;
private Vehicle2DriverEventHandler delegate = new Vehicle2DriverEventHandler();
private Vehicle2DriverEventHandler vehicle2Driver = new Vehicle2DriverEventHandler();
private Id<Link> previousLink;
private double previousLinkRelativePosition;
private double previousLinkEnterTime;
private double score;
private int carCountOnLink;

public BicycleScoring(Scenario scenario, BicycleTravelTime bicycleTravelTime, BicycleTravelDisutilityFactory bicycleTravelDisutilityFactory) {
this.scenario = scenario;
this.bicycleTravelDisutility = (BicycleTravelDisutility) bicycleTravelDisutilityFactory.createTravelDisutility(bicycleTravelTime);
private final double marginalUtilityOfInfrastructure_m;
private final double marginalUtilityOfComfort_m;
private final double marginalUtilityOfGradient_m_100m;

private static int ccc=0 ;

public BicycleLinkScoring(final ScoringParameters params, Scenario scenario, BicycleConfigGroup bicycleConfigGroup) {
this.params = params;
this.scenario = scenario;

this.marginalUtilityOfInfrastructure_m = bicycleConfigGroup.getMarginalUtilityOfInfrastructure_m();
this.marginalUtilityOfComfort_m = bicycleConfigGroup.getMarginalUtilityOfComfort_m();
this.marginalUtilityOfGradient_m_100m = bicycleConfigGroup.getMarginalUtilityOfGradient_m_100m();
}

@Override public void finish() {}
Expand All @@ -63,11 +78,10 @@ public double getScore() {
@Override
public void handleEvent(Event event) {
if (event instanceof VehicleEntersTrafficEvent) {
// LOG.warn(event.toString());
VehicleEntersTrafficEvent vehEvent = (VehicleEntersTrafficEvent) event;

// Establish connection between driver and vehicle
delegate.handleEvent(vehEvent);
vehicle2Driver.handleEvent(vehEvent);

// No LinkEnterEvent on first link of a leg
previousLink = vehEvent.getLinkId();
Expand All @@ -77,7 +91,6 @@ public void handleEvent(Event event) {

}
if (event instanceof VehicleLeavesTrafficEvent) {
// LOG.warn(event.toString());
VehicleLeavesTrafficEvent vehEvent = (VehicleLeavesTrafficEvent) event;

Id<Vehicle> vehId = vehEvent.getVehicleId();
Expand All @@ -86,12 +99,11 @@ public void handleEvent(Event event) {
calculateScoreForPreviousLink(vehEvent.getLinkId(), enterTime, vehId, travelTime, previousLinkRelativePosition);

// End connection between driver and vehicle
delegate.handleEvent(vehEvent);
vehicle2Driver.handleEvent(vehEvent);
}
if (event instanceof LinkEnterEvent) {
// This only works because setPassLinkEventsToPerson is activated (via ScoringFunctionsForPopulation)
// This only works since ScoringFunctionsForPopulation passes link events to persons; quite new; dz, june'18
// Otherwise ArbitraryEventScoring only handles events that are instance of HasPersonId, which is not the case for LinkEnterEvents
// LOG.warn(event.toString());
LinkEnterEvent linkEnterEvent = (LinkEnterEvent) event;

Id<Vehicle> vehId = linkEnterEvent.getVehicleId();
Expand All @@ -103,34 +115,66 @@ public void handleEvent(Event event) {
carCountOnLink = 0;
previousLinkRelativePosition = 0.;
previousLinkEnterTime = linkEnterEvent.getTime();

}
}
}

private void calculateScoreForPreviousLink(Id<Link> linkId, Double enterTime, Id<Vehicle> vehId, double travelTime, double relativeLinkEnterPosition) {
if (relativeLinkEnterPosition != 1.0) {
Link link = scenario.getNetwork().getLinks().get(linkId);
Person person = scenario.getPopulation().getPersons().get(delegate.getDriverOfVehicle(vehId));
Vehicle vehicle = scenario.getVehicles().getVehicles().get(vehId);
// Link link = scenario.getNetwork().getLinks().get(linkId);
// Person person = scenario.getPopulation().getPersons().get(vehicle2Driver.getDriverOfVehicle(vehId));
// Vehicle vehicle = scenario.getVehicles().getVehicles().get(vehId);

double carScoreOffset = -(this.carCountOnLink * 0.04);
this.score += carScoreOffset;
LOG.warn("----- link = " + linkId + " -- car score offset = " + carScoreOffset);
// LOG.warn("----- link = " + linkId + " -- car score offset = " + carScoreOffset);

double scoreOnLink = BicycleUtilityUtils.computeLinkBasedScore(scenario.getNetwork().getLinks().get(linkId),
marginalUtilityOfComfort_m, marginalUtilityOfInfrastructure_m, marginalUtilityOfGradient_m_100m);
// LOG.warn("----- link = " + linkId + " -- scoreOnLink = " + scoreOnLink);
this.score += scoreOnLink;

this.score += bicycleTravelDisutility.getTravelDisutilityBasedOnTTime(link, enterTime, person, vehicle, travelTime);
// LOG.warn("score = " + score + " -- linkId = " + link.getId() + " -- enterTime = " + enterTime + " -- personId = " + person.getId() + " -- travelTime = " + travelTime);
double timeDistanceBasedScoreComponent = computeTimeDistanceBasedScoreComponent(travelTime, scenario.getNetwork().getLinks().get(linkId).getLength());
// LOG.warn("----- link = " + linkId + " -- timeDistanceBasedScoreComponent = " + timeDistanceBasedScoreComponent);
this.score += timeDistanceBasedScoreComponent;
}
else {
// If agent was already at the end of the link and thus did not travel on it, do nothing
double timeDistanceBasedScoreComponent = computeTimeDistanceBasedScoreComponent(travelTime, 0.);
this.score += timeDistanceBasedScoreComponent;
}
// TODO Use relative position in a more sophisticated way.
}


// Copied and adapted from CharyparNagelLegScoring
protected double computeTimeDistanceBasedScoreComponent(double travelTime, double dist) {
double tmpScore = 0.0;
ModeUtilityParameters modeParams = this.params.modeParams.get("bicycle");
if (modeParams == null) {
throw new RuntimeException("no scoring parameters are defined for bicycle") ;
}
tmpScore += travelTime * modeParams.marginalUtilityOfTraveling_s;
if (modeParams.marginalUtilityOfDistance_m != 0.0 || modeParams.monetaryDistanceCostRate != 0.0) {
if ( Double.isNaN(dist) ) {
if ( ccc<10 ) {
ccc++ ;
Logger.getLogger(this.getClass()).warn("distance is NaN. Will make score of this plan NaN. Possible reason: Simulation does not report " +
"a distance for this trip. Possible reason for that: mode is teleported and router does not " +
"write distance into plan. Needs to be fixed or these plans will die out.") ;
if ( ccc==10 ) {
Logger.getLogger(this.getClass()).warn(Gbl.FUTURE_SUPPRESSED) ;
}
}
}
tmpScore += modeParams.marginalUtilityOfDistance_m * dist;
tmpScore += modeParams.monetaryDistanceCostRate * this.params.marginalUtilityOfMoney * dist;
}
tmpScore += modeParams.constant;
return tmpScore;
}


@Override
public void handleEvent(MotorizedInteractionEvent event) {
// LOG.info("event received from link " + event.getLinkId());
if (event.getLinkId().equals(previousLink)) {
// LOG.warn("USED: Event from link " + event.getLinkId());
this.carCountOnLink++;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,9 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.bicycle.run;
package org.matsim.contrib.bicycle;

import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Link;
import org.matsim.contrib.bicycle.BicycleUtils;
import org.matsim.contrib.bicycle.MotorizedInteractionEngine;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.controler.AbstractModule;
import org.matsim.core.mobsim.qsim.qnetsimengine.ConfigurableQNetworkFactory;
import org.matsim.core.mobsim.qsim.qnetsimengine.QNetworkFactory;
import org.matsim.core.mobsim.qsim.qnetsimengine.QVehicle;
import org.matsim.core.mobsim.qsim.qnetsimengine.linkspeedcalculator.DefaultLinkSpeedCalculator;
import org.matsim.core.mobsim.qsim.qnetsimengine.linkspeedcalculator.LinkSpeedCalculator;
import org.matsim.vehicles.VehicleType;

import com.google.inject.Provides;
import com.google.inject.Singleton;

/**
* @author smetzler, dziemke
Expand All @@ -46,32 +31,16 @@ public void install() {
bind(BicycleTravelTime.class).asEagerSingleton();
addTravelTimeBinding("bicycle").to(BicycleTravelTime.class);
bind(BicycleTravelDisutilityFactory.class).asEagerSingleton();
addTravelDisutilityFactoryBinding("bicycle").to(BicycleTravelDisutilityFactory.class);
this.bindScoringFunctionFactory().toInstance(new BicycleScoringFunctionFactory());
addTravelDisutilityFactoryBinding("bicycle").to(BicycleTravelDisutilityFactory.class);
bindScoringFunctionFactory().toInstance(new BicycleScoringFunctionFactory());
// The following leads to "Tried proxying org.matsim.core.scoring.ScoringFunctionsForPopulation to support a circular dependency, but it is not an interface."
// bindScoringFunctionFactory().to(BicycleScoringFunctionFactory.class);

if (considerMotorizedInteraction) {
addMobsimListenerBinding().to(MotorizedInteractionEngine.class);
}
}

@Singleton @Provides
QNetworkFactory provideQNetworkFactory(Scenario scenario, EventsManager eventsManager) {
ConfigurableQNetworkFactory qNetworkFactory = new ConfigurableQNetworkFactory(eventsManager, scenario) ;
qNetworkFactory.setLinkSpeedCalculator(new LinkSpeedCalculator(){
LinkSpeedCalculator delegate = new DefaultLinkSpeedCalculator() ;
@Override public double getMaximumVelocity(QVehicle vehicle, Link link, double time) {
if ( vehicle.getVehicle().getType().getId().equals( Id.create("bicycle", VehicleType.class) ) ) {
// return vehicle.getMaximumVelocity(); // return the same as vehicleType.getMaximumVelocity()
// return vehicle.getVehicle().getType().getMaximumVelocity();
return BicycleUtils.getSpeed("bicycle");
} else {
return delegate.getMaximumVelocity(vehicle, link, time) ;
}
}
});
return qNetworkFactory;
}

public void setConsiderMotorizedInteraction(boolean considerMotorizedInteraction) {
this.considerMotorizedInteraction = considerMotorizedInteraction;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* See also COPYING, LICENSE and WARRANTY file *
* *
* *********************************************************************** */
package org.matsim.contrib.bicycle.run;
package org.matsim.contrib.bicycle;

import java.util.HashSet;
import java.util.Set;
Expand Down
Loading