Skip to content

Commit

Permalink
integration test pickup/dropoff on adjacent links
Browse files Browse the repository at this point in the history
  • Loading branch information
markusstraub committed Dec 2, 2024
1 parent b804742 commit 3e10d85
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 6 deletions.
40 changes: 40 additions & 0 deletions data/floridsdorf/population_drs_adjacentMatch.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE population SYSTEM "http://www.matsim.org/files/dtd/population_v6.dtd">

<population>
<attributes>
<attribute name="coordinateReferenceSystem" class="java.lang.String">epsg:31256</attribute>
</attributes>

<!-- Exactly one driver and one rider that should match -->
<!-- full subtours starting and ending at home so that SubtourModeChoice works properly -->
<person id="carPerson">
<attributes>
<attribute class="java.lang.String" name="carAvail">always</attribute>
<attribute class="java.lang.String" name="drsAffinity">driverOnly</attribute>
<attribute class="java.lang.String" name="hasLicense">yes</attribute>
</attributes>
<plan selected="yes">
<activity type="home" link="112" x="5826.522" y="345633.182" start_time="07:20:00" end_time="07:20:00" />
<leg mode="bike" />
<activity type="work" link="152" x="3360.657" y="344813.230" start_time="07:40:00" end_time="17:30:00" />
<leg mode="bike" />
<activity type="home" link="112" x="5826.522" y="345633.182" start_time="18:00:00" />
</plan>
</person>
<person id="ridePerson">
<attributes>
<attribute class="java.lang.String" name="carAvail">never</attribute>
<attribute class="java.lang.String" name="drsAffinity">riderOnly</attribute>
<attribute class="java.lang.String" name="hasLicense">no</attribute>
</attributes>
<plan selected="yes">
<activity type="home" link="28" x="5991.161" y="345598.0287" end_time="07:20:00" />
<leg mode="bike" />
<activity type="work" link="1655" x="3400.587" y="344774.199" start_time="07:40:00" end_time="17:30:00" />
<leg mode="bike" />
<activity type="home" link="28" x="5991.161" y="345598.0287" start_time="18:00:00" />
</plan>
</person>

</population>
3 changes: 1 addition & 2 deletions data/floridsdorf/population_drs_trivialMatch.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</attributes>

<!-- Exactly one driver and one rider that should match -->
<!-- full subtour starting and ending at home so that SubtourModeChoice works properly -->
<!-- full subtours starting and ending at home so that SubtourModeChoice works properly -->
<person id="carPerson">
<attributes>
<attribute class="java.lang.String" name="carAvail">always</attribute>
Expand All @@ -29,7 +29,6 @@
<attribute class="java.lang.String" name="hasLicense">no</attribute>
</attributes>
<plan selected="yes">
<!-- full subtour starting and ending at home so that SubtourModeChoice works properly -->
<activity type="home" link="112" x="5826.522" y="345633.182" start_time="07:20:00" end_time="07:20:00" />
<leg mode="bike" />
<activity type="work" link="152" x="3360.657" y="344813.230" start_time="07:40:00" end_time="17:30:00" />
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/at/ac/ait/matsim/drs/engine/DrsData.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.uber.h3core.H3Core;
import com.uber.h3core.LengthUnit;
Expand All @@ -34,6 +35,8 @@ public DrsData(Scenario scenario, DrsConfigGroup drsConfig) {
ImmutableSet.of(Drs.DRIVER_MODE));
LOGGER.info("Filtered {} drs driver links from network with {} links", drsNetwork.getLinks().size(),
scenario.getNetwork().getLinks().size());
LOGGER.debug("Removed links: {}",
Sets.difference(scenario.getNetwork().getLinks().keySet(), drsNetwork.getLinks().keySet()));

int resolution = findH3ResolutionForDistance(drsConfig.getMaxMatchingDistanceMeters());
this.zoneSystem = new H3ZoneSystem(scenario.getConfig().global().getCoordinateSystem(), resolution,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package at.ac.ait.matsim.drs.run;

import org.matsim.api.core.v01.TransportMode;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.ReplanningConfigGroup.StrategySettings;

/**
* Minimal example demonstrating a single match found in the replanning phase
* where driver and rider have start destination not on the same link but close
* enough for them to match
*/
public class RunAdjacentMatchExample extends RunSimpleDrsExample {

public static void main(String[] args) {
new RunAdjacentMatchExample().run(false, null);
}

@Override
public void adjustConfig(Config config) {
config.controller().setLastIteration(1);
config.controller().setOutputDirectory("output-floridsdorf-adjacentMatch");
config.plans().setInputFile("population_drs_adjacentMatch.xml");

// configure replanning so that in iteration 1 SubtourModeChoice will be used,
// and drsRider + drsDriver mode is tried out
// (so that we can demonstrate the match)
config.replanning().clearStrategySettings();
config.replanning()
.addStrategySettings(new StrategySettings().setStrategyName("SubtourModeChoiceForDrs").setWeight(1));

DrsConfigGroup drs = (DrsConfigGroup) config.getModules().get("drs");
drs.setSubtourModeChoiceModes(new String[] { Drs.DRIVER_MODE, Drs.RIDER_MODE, TransportMode.bike });
drs.setSubtourModeChoiceChainBasedModes(new String[] { Drs.DRIVER_MODE, TransportMode.bike });
}

}
1 change: 0 additions & 1 deletion src/main/java/at/ac/ait/matsim/drs/util/DrsUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.matsim.api.core.v01.population.Route;
import org.matsim.core.config.Config;
import org.matsim.core.config.groups.ControllerConfigGroup;
import org.matsim.core.controler.events.AfterMobsimEvent;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.GenericRouteImpl;
import org.matsim.core.router.DefaultRoutingRequest;
Expand Down
64 changes: 61 additions & 3 deletions src/test/java/at/ac/ait/matsim/drs/run/IntegrationTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.matsim.api.core.v01.population.Route;
import org.matsim.core.population.PopulationUtils;
import org.matsim.core.router.TripStructureUtils;
import org.matsim.core.router.TripStructureUtils.Trip;

import com.opencsv.CSVParserBuilder;
import com.opencsv.CSVReaderHeaderAware;
Expand Down Expand Up @@ -250,8 +251,8 @@ public void testNoDriver(@TempDir(cleanup = CleanupMode.NEVER, factory = TDFacto
}

/**
* SubtourModeChoice + matching logic test: test that a trival match works
* (rider + driver with same locations and times)
* SubtourModeChoice + matching logic test for a trivial match:
* rider + driver with same locations and times
*/
@Test
@Tag("IntegrationTest")
Expand All @@ -265,14 +266,69 @@ public void testTrivialMatch(@TempDir(cleanup = CleanupMode.NEVER, factory = TDF
CSV replanningStats = readCsv(tempDir.resolve(DrsReplanningStats.FILENAME + ".csv"));
assertEquals(2, replanningStats.size());
assertEquals("2", replanningStats.get(1, CsvField.matchedRiders));
assertEquals("2", replanningStats.get(1, CsvField.matchedDrivers));
assertEquals("0", replanningStats.get(1, CsvField.unmatchedRiders));
assertEquals("0", replanningStats.get(1, CsvField.unmatchedDrivers));

// driver and rider must use drs mode
CSV trips = readCsv(tempDir.resolve("output_trips.csv.gz"));
assertEquals(Drs.DRIVER_MODE, trips.filter("person", "carPerson").filter("trip_number", "1").get("main_mode"));
assertEquals(Drs.RIDER_MODE, trips.filter("person", "ridePerson").filter("trip_number", "1").get("main_mode"));
}

/**
* SubtourModeChoice + matching logic test for:
* rider + driver with similar locations (and same times)
*
* Also check if the network routes (access egress) are OK
*/
@Test
@Tag("IntegrationTest")
public void testAdjacentMatch(@TempDir(cleanup = CleanupMode.NEVER, factory = TDFactory.class) Path tempDir)
throws Exception {
new RunAdjacentMatchExample().run(false, tempDir);

// In iteration 1 (after replanning)

// driver and rider are matched
CSV replanningStats = readCsv(tempDir.resolve(DrsReplanningStats.FILENAME + ".csv"));
assertEquals(2, replanningStats.size());
assertEquals("2", replanningStats.get(1, CsvField.matchedRiders));
assertEquals("2", replanningStats.get(1, CsvField.matchedDrivers));
assertEquals("0", replanningStats.get(1, CsvField.unmatchedRiders));
assertEquals("0", replanningStats.get(1, CsvField.unmatchedDrivers));

// driver and rider must use drs mode
CSV trips = readCsv(tempDir.resolve("output_trips.csv.gz"));
assertEquals(Drs.DRIVER_MODE, trips.filter("person", "carPerson").filter("trip_number", "1").get("main_mode"));
assertEquals(Drs.RIDER_MODE, trips.filter("person", "ridePerson").filter("trip_number", "1").get("main_mode"));

Population outputPlans = PopulationUtils
.readPopulation(tempDir.resolve("output_plans.xml.gz").toFile().toString());

// rider route with a single leg
Plan riderPlan = outputPlans.getPersons().get(Id.createPersonId("ridePerson")).getSelectedPlan();
Trip riderTrip = TripStructureUtils.getTrips(riderPlan).get(0);
assertEquals(1, riderTrip.getLegsOnly().size());
Route riderRoute = riderTrip.getLegsOnly().get(0).getRoute();
assertEquals("28", riderRoute.getStartLinkId().toString());
assertEquals("1655", riderRoute.getEndLinkId().toString());

// driver route with three legs (detour for pickup / dropoff)
Plan driverPlan = outputPlans.getPersons().get(Id.createPersonId("carPerson")).getSelectedPlan();
Trip driverTrip = TripStructureUtils.getTrips(driverPlan).get(0);
assertEquals(3, driverTrip.getLegsOnly().size());
Route driverPickupRoute = driverTrip.getLegsOnly().get(0).getRoute();
assertEquals("112", driverPickupRoute.getStartLinkId().toString());
assertEquals("28", driverPickupRoute.getEndLinkId().toString());
Route driverWithRiderRoute = driverTrip.getLegsOnly().get(1).getRoute();
assertEquals("28", driverWithRiderRoute.getStartLinkId().toString());
assertEquals("1655", driverWithRiderRoute.getEndLinkId().toString());
Route driverFinalRoute = driverTrip.getLegsOnly().get(2).getRoute();
assertEquals("1655", driverFinalRoute.getStartLinkId().toString());
assertEquals("152", driverFinalRoute.getEndLinkId().toString());
}

/**
* SubtourModeChoice + matching logic test: test that a trival match works -
* even if the ReRoute strategy runs a few times
Expand All @@ -291,7 +347,9 @@ public void testTrivialMatchWithReRoute(
CSV replanningStats = readCsv(tempDir.resolve(DrsReplanningStats.FILENAME + ".csv"));
assertEquals(11, replanningStats.size());
assertEquals("2", replanningStats.get(10, CsvField.matchedRiders));
assertEquals("2", replanningStats.get(10, CsvField.matchedDrivers));
assertEquals("0", replanningStats.get(10, CsvField.unmatchedRiders));
assertEquals("0", replanningStats.get(10, CsvField.unmatchedDrivers));

// driver and rider must use drs mode
CSV trips = readCsv(tempDir.resolve("output_trips.csv.gz"));
Expand Down Expand Up @@ -327,7 +385,7 @@ public void testRiderPlansGetNetworkRoute(
}

/**
* Test dRS engine behavior: riders must be able to adjust their departure time
* Test drs engine behavior: riders must be able to adjust their departure time
*/
@Test
@Tag("IntegrationTest")
Expand Down

0 comments on commit 3e10d85

Please sign in to comment.