diff --git a/contribs/accessibility/pom.xml b/contribs/accessibility/pom.xml
index 45d1f56723b..4b3a78553b5 100644
--- a/contribs/accessibility/pom.xml
+++ b/contribs/accessibility/pom.xml
@@ -83,5 +83,11 @@
gt-jdbc-postgis
${geotools.version}
+
+ org.matsim.contrib
+ drt
+ 16.0-SNAPSHOT
+ compile
+
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
index c4677dd3fd3..86afb7ad1eb 100644
--- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/AccessibilityModule.java
@@ -158,6 +158,10 @@ public ControlerListener get() {
calculator = new NetworkModeAccessibilityExpContributionCalculator(mode, nwModeTravelTime, nwModeTravelDisutility, scenario);
} else if ( TransportMode.pt.equals( mode ) ){
calculator = new SwissRailRaptorAccessibilityContributionCalculator( mode, config.scoring(), scenario );
+ } else if ( Modes4Accessibility.estimatedDrt.name().equals( mode )) {
+ final TravelTime travelTime = travelTimes.get(TransportMode.car); // TODO: replace with drt
+ final TravelDisutilityFactory travelDisutilityFactory = travelDisutilityFactories.get(TransportMode.car); //TODO: replace with DRT
+ calculator = new EstimatedDrtAccessibilityContributionCalculator(mode, travelTime, travelDisutilityFactory, scenario);
} else if ( Modes4Accessibility.matrixBasedPt.name().equals( mode ) ) {
throw new RuntimeException("currently not supported because implementation not consistent with guice grapher. kai, sep'19") ;
// calculator = new LeastCostPathCalculatorAccessibilityContributionCalculator(
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java
new file mode 100644
index 00000000000..6848a36a185
--- /dev/null
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/EstimatedDrtAccessibilityContributionCalculator.java
@@ -0,0 +1,178 @@
+package org.matsim.contrib.accessibility;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.BasicLocation;
+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.network.Link;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.api.core.v01.network.Node;
+import org.matsim.contrib.accessibility.utils.*;
+import org.matsim.contrib.drt.estimator.DrtEstimator;
+import org.matsim.contrib.drt.estimator.impl.EuclideanDistanceBasedDrtEstimator;
+import org.matsim.contrib.roadpricing.RoadPricingScheme;
+import org.matsim.core.config.groups.NetworkConfigGroup;
+import org.matsim.core.config.groups.ScoringConfigGroup;
+import org.matsim.core.gbl.Gbl;
+import org.matsim.core.network.NetworkUtils;
+import org.matsim.core.network.algorithms.TransportModeNetworkFilter;
+import org.matsim.core.router.costcalculators.TravelDisutilityFactory;
+import org.matsim.core.router.util.TravelDisutility;
+import org.matsim.core.router.util.TravelTime;
+import org.matsim.core.utils.misc.OptionalTime;
+import org.matsim.facilities.ActivityFacilities;
+import org.matsim.facilities.ActivityFacility;
+import org.matsim.utils.leastcostpathtree.LeastCostPathTree;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author thibautd, dziemke
+ */
+final class EstimatedDrtAccessibilityContributionCalculator implements AccessibilityContributionCalculator {
+ private static final Logger LOG = LogManager.getLogger( NetworkModeAccessibilityExpContributionCalculator.class );
+
+ private final String mode;
+ private final TravelDisutilityFactory travelDisutilityFactory;
+ private final TravelTime travelTime;
+ private final Scenario scenario;
+
+ private final TravelDisutility travelDisutility;
+ private final ScoringConfigGroup scoringConfigGroup;
+ private final NetworkConfigGroup networkConfigGroup;
+
+ private Network subNetwork;
+
+ private final EuclideanDistanceBasedDrtEstimator drtEstimator;
+
+ private final double betaWalkTT;
+
+ private final double betaDrtTT;
+ private final double walkSpeed_m_s;
+
+ private Node fromNode = null;
+ private final LeastCostPathTree lcpt;
+
+ private Map, ArrayList> aggregatedMeasurePoints;
+ private Map, AggregationObject> aggregatedOpportunities;
+
+
+
+ public EstimatedDrtAccessibilityContributionCalculator(String mode, final TravelTime travelTime, final TravelDisutilityFactory travelDisutilityFactory, Scenario scenario) {
+ this.mode = mode;
+ this.travelTime = travelTime;
+ this.travelDisutilityFactory = travelDisutilityFactory;
+ this.scenario = scenario;
+ this.scoringConfigGroup = scenario.getConfig().scoring();
+ this.networkConfigGroup = scenario.getConfig().network();
+
+ Gbl.assertNotNull(travelDisutilityFactory);
+ this.travelDisutility = travelDisutilityFactory.createTravelDisutility(travelTime);
+
+
+ this.lcpt = new LeastCostPathTree(travelTime, travelDisutility);
+
+ // TODO: should the marginal utility of traveling for drt be same as for car?
+ betaWalkTT = scoringConfigGroup.getModes().get(TransportMode.walk).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
+ betaDrtTT = scoringConfigGroup.getModes().get(TransportMode.car).getMarginalUtilityOfTraveling() - scoringConfigGroup.getPerforming_utils_hr();
+
+ this.walkSpeed_m_s = scenario.getConfig().routing().getTeleportedModeSpeeds().get(TransportMode.walk);
+
+ //TODO: realistic parameters?
+ this.drtEstimator = new EuclideanDistanceBasedDrtEstimator(scenario.getNetwork(), 1.2, 1.0, 0, 5 * 3600, 0, 1, 0);
+
+ }
+
+
+ @Override
+ public void initialize(ActivityFacilities measuringPoints, ActivityFacilities opportunities) {
+ LOG.warn("Initializing calculator for mode " + mode + "...");
+ LOG.warn("Full network has " + scenario.getNetwork().getNodes().size() + " nodes.");
+ subNetwork = NetworkUtils.createNetwork(networkConfigGroup);
+ Set modeSet = new HashSet<>();
+ modeSet.add(TransportMode.car);
+ TransportModeNetworkFilter filter = new TransportModeNetworkFilter(scenario.getNetwork());
+ filter.filter(subNetwork, modeSet);
+ if (subNetwork.getNodes().size() == 0) {
+ throw new RuntimeException("Network has 0 nodes for mode " + mode + ". Something is wrong.");
+ }
+ LOG.warn("sub-network for mode " + modeSet + " now has " + subNetwork.getNodes().size() + " nodes.");
+
+ this.aggregatedMeasurePoints = AccessibilityUtils.aggregateMeasurePointsWithSameNearestNode(measuringPoints, subNetwork);
+ this.aggregatedOpportunities = AccessibilityUtils.aggregateOpportunitiesWithSameNearestNode(opportunities, subNetwork, scenario.getConfig());
+
+
+ }
+
+
+ @Override
+ public void notifyNewOriginNode(Id extends BasicLocation> fromNodeId, Double departureTime) {
+ this.fromNode = subNetwork.getNodes().get(fromNodeId);
+ this.lcpt.calculate(subNetwork, fromNode, departureTime);
+
+ }
+
+
+ @Override
+ public double computeContributionOfOpportunity(ActivityFacility origin,
+ Map, AggregationObject> aggregatedOpportunities, Double departureTime) {
+ double expSum = 0.;
+
+ Link nearestLink = NetworkUtils.getNearestLinkExactly(subNetwork, origin.getCoord());
+ Distances distance = NetworkUtil.getDistances2NodeViaGivenLink(origin.getCoord(), nearestLink, fromNode);
+ double walkTravelTimeMeasuringPoint2Road_h = distance.getDistancePoint2Intersection() / (this.walkSpeed_m_s * 3600);
+ // Orthogonal walk to nearest link
+ double walkUtilityMeasuringPoint2Road = (walkTravelTimeMeasuringPoint2Road_h * betaWalkTT);
+ // Travel on section of first link to first node
+ double distanceFraction = distance.getDistanceIntersection2Node() / nearestLink.getLength();
+ double congestedCarUtilityRoad2Node = -travelDisutility.getLinkTravelDisutility(nearestLink, departureTime, null, null) * distanceFraction;
+
+ // Combine all utility components (using the identity: exp(a+b) = exp(a) * exp(b))
+ double modeSpecificConstant = AccessibilityUtils.getModeSpecificConstantForAccessibilities(TransportMode.car, scoringConfigGroup); // TODO: update from car to drt
+
+ for (final AggregationObject destination : aggregatedOpportunities.values()) {
+
+ // utility during DRT ride
+ DrtEstimator.Estimate estimate = drtEstimator.estimate(origin.getCoord(), destination.getNearestBasicLocation().getCoord(), OptionalTime.defined(departureTime));
+
+ double totalTime = (estimate.waitingTime() + estimate.rideTime()) / 3600;
+ double utilityDrt = betaDrtTT * totalTime;
+
+ // Pre-computed effect of all opportunities reachable from destination network node
+ double sumExpVjkWalk = destination.getSum();
+
+ expSum += Math.exp(this.scoringConfigGroup.getBrainExpBeta() * (walkUtilityMeasuringPoint2Road + modeSpecificConstant
+ + congestedCarUtilityRoad2Node + utilityDrt)) * sumExpVjkWalk;
+ }
+ return expSum;
+ }
+
+
+ @Override
+ public EstimatedDrtAccessibilityContributionCalculator duplicate() {
+ LOG.info("Creating another EstimatedDrtAccessibilityContributionCalculator object.");
+ EstimatedDrtAccessibilityContributionCalculator estimatedDrtAccessibilityContributionCalculator =
+ new EstimatedDrtAccessibilityContributionCalculator(this.mode, this.travelTime, this.travelDisutilityFactory, this.scenario);
+ estimatedDrtAccessibilityContributionCalculator.subNetwork = this.subNetwork;
+ estimatedDrtAccessibilityContributionCalculator.aggregatedMeasurePoints = this.aggregatedMeasurePoints;
+ estimatedDrtAccessibilityContributionCalculator.aggregatedOpportunities = this.aggregatedOpportunities;
+ return estimatedDrtAccessibilityContributionCalculator;
+ }
+
+
+ @Override
+ public Map, ArrayList> getAggregatedMeasurePoints() {
+ return aggregatedMeasurePoints;
+ }
+
+
+ @Override
+ public Map, AggregationObject> getAgregatedOpportunities() {
+ return aggregatedOpportunities;
+ }
+}
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/Modes4Accessibility.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/Modes4Accessibility.java
index 1aed991d7e4..901340ba5d2 100644
--- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/Modes4Accessibility.java
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/Modes4Accessibility.java
@@ -1,5 +1,5 @@
package org.matsim.contrib.accessibility;
-public enum Modes4Accessibility {freespeed, car, walk, bike, pt, matrixBasedPt}
+public enum Modes4Accessibility {freespeed, car, walk, bike, pt, estimatedDrt, matrixBasedPt}
// yy might make sense to replace this by a String (as for the normal matsim router), but configurability right now is not sufficient at the level here, and may never be.
-// kai/dominik, feb'17
\ No newline at end of file
+// kai/dominik, feb'17
diff --git a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java
index 6fcd4466276..61ac67d7bc3 100644
--- a/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java
+++ b/contribs/accessibility/src/main/java/org/matsim/contrib/accessibility/SwissRailRaptorAccessibilityContributionCalculator.java
@@ -41,7 +41,7 @@
* @author dziemke
*/
class SwissRailRaptorAccessibilityContributionCalculator implements AccessibilityContributionCalculator {
- private static final Logger LOG = LogManager.getLogger( SwissRailRaptorAccessibilityContributionCalculator.class );
+ private static final Logger LOG = LogManager.getLogger( EstimatedDrtAccessibilityContributionCalculator.class );
private SwissRailRaptor raptor;
private String mode;
private ScoringConfigGroup scoringConfigGroup;
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/estimator/impl/EuclideanDistanceBasedDrtEstimator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/estimator/impl/EuclideanDistanceBasedDrtEstimator.java
index dd3a2492ce9..760594e2798 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/estimator/impl/EuclideanDistanceBasedDrtEstimator.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/estimator/impl/EuclideanDistanceBasedDrtEstimator.java
@@ -59,6 +59,11 @@ public EuclideanDistanceBasedDrtEstimator(Network network, double networkDistanc
public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
Coord fromCoord = network.getLinks().get(route.getStartLinkId()).getToNode().getCoord();
Coord toCoord = network.getLinks().get(route.getEndLinkId()).getToNode().getCoord();
+
+ return estimate(fromCoord, toCoord, departureTime);
+ }
+
+ public Estimate estimate(Coord fromCoord, Coord toCoord , OptionalTime departureTime) {
double euclideanDistance = CoordUtils.calcEuclideanDistance(fromCoord, toCoord);
double typicalRideDuration = euclideanDistance * slope + intercept;
double typicalRideDistance = networkDistanceFactor * euclideanDistance;