From d4a2962d3217da15a6265f77604800e4471c1584 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Sun, 4 Aug 2024 22:00:37 +0200 Subject: [PATCH 01/11] add test which includes tolling. One test is failing, because it is not possible to create different schemes for the different types. --- .../NetworkBasedTransportCostsTest.java | 174 ++++++++++++++++-- 1 file changed, 163 insertions(+), 11 deletions(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index ccdb7095162..63870ca8ed3 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -30,9 +30,13 @@ import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.roadpricing.RoadPricingScheme; +import org.matsim.contrib.roadpricing.RoadPricingSchemeImpl; +import org.matsim.contrib.roadpricing.RoadPricingUtils; import org.matsim.core.config.Config; import org.matsim.core.network.io.MatsimNetworkReader; import org.matsim.core.scenario.ScenarioUtils; +import org.matsim.core.utils.misc.Time; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.CostInformation; import org.matsim.vehicles.VehicleType; @@ -47,6 +51,8 @@ public class NetworkBasedTransportCostsTest { + private static final String TYPE_1 = "type1"; + private static final String TYPE_2 = "type2"; @RegisterExtension public final MatsimTestUtils utils = new MatsimTestUtils(); @@ -60,21 +66,21 @@ void test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem(){ Network network = scenario.getNetwork(); NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(network); - builder.addVehicleTypeSpecificCosts("type1", 10.0, 0.0, 2.0); - builder.addVehicleTypeSpecificCosts("type2", 20.0, 0.0, 4.0); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); when(type1.getMaxVelocity()).thenReturn(5.0); - when(type1.getTypeId()).thenReturn("type1"); + when(type1.getTypeId()).thenReturn(TYPE_1); when(vehicle1.getType()).thenReturn(type1); when(vehicle1.getId()).thenReturn("vehicle1"); Vehicle vehicle2 = mock(Vehicle.class); com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); when(type2.getMaxVelocity()).thenReturn(5.0); - when(type2.getTypeId()).thenReturn("type2"); + when(type2.getTypeId()).thenReturn(TYPE_2); when(vehicle2.getType()).thenReturn(type2); when(vehicle2.getId()).thenReturn("vehicle2"); @@ -94,8 +100,8 @@ void test_whenVehicleTypeNotKnow_throwException(){ Network network = scenario.getNetwork(); NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(network); - builder.addVehicleTypeSpecificCosts("type1", 10.0, 0.0, 2.0); - builder.addVehicleTypeSpecificCosts("type2", 20.0, 0.0, 4.0); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle2 = mock(Vehicle.class); @@ -120,14 +126,14 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ String NETWORK_FILENAME = utils.getClassInputDirectory() + "network.xml"; new MatsimNetworkReader(scenario.getNetwork()).readFile(NETWORK_FILENAME); - VehicleType vehType1 = VehicleUtils.getFactory().createVehicleType(Id.create( "type1", VehicleType.class )); + VehicleType vehType1 = VehicleUtils.getFactory().createVehicleType(Id.create(TYPE_1, VehicleType.class )); CostInformation costInformation1 = vehType1.getCostInformation() ; costInformation1.setFixedCost( 0.0 ); costInformation1.setCostsPerMeter( 2.0 ); costInformation1.setCostsPerSecond( 0.0 ); - VehicleType vehType2 = VehicleUtils.getFactory().createVehicleType(Id.create( "type2", VehicleType.class )); + VehicleType vehType2 = VehicleUtils.getFactory().createVehicleType(Id.create(TYPE_2, VehicleType.class )); CostInformation costInformation = vehType2.getCostInformation() ; costInformation.setFixedCost( 0.0 ); @@ -136,20 +142,20 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ Network network = scenario.getNetwork(); NetworkBasedTransportCosts.Builder builder = - NetworkBasedTransportCosts.Builder.newInstance(network,Arrays.asList(vehType1,vehType2)); + NetworkBasedTransportCosts.Builder.newInstance(network,Arrays.asList(vehType1,vehType2)); NetworkBasedTransportCosts networkBasedTransportCosts = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); when(type1.getMaxVelocity()).thenReturn(5.0); - when(type1.getTypeId()).thenReturn("type1"); + when(type1.getTypeId()).thenReturn(TYPE_1); when(vehicle1.getType()).thenReturn(type1); when(vehicle1.getId()).thenReturn("vehicle1"); Vehicle vehicle2 = mock(Vehicle.class); com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); when(type2.getMaxVelocity()).thenReturn(5.0); - when(type2.getTypeId()).thenReturn("type2"); + when(type2.getTypeId()).thenReturn(TYPE_2); when(vehicle2.getType()).thenReturn(type2); when(vehicle2.getId()).thenReturn("vehicle2"); @@ -159,4 +165,150 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ Assertions.assertEquals(20000.0, networkBasedTransportCosts.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } + /** + * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} + * In addition, there is added a road pricing scheme. + * The scheme is only set for one vehicle type: type1. + * So, only the vehicle using that type (vehicle1) should be tolled, the other (vehicle2) not. + * + */ + @Test + void test_whenAddingTwoDifferentVehicleTypes_tollOneType(){ + Config config = new Config(); + config.addCoreModules(); + Scenario scenario = ScenarioUtils.createScenario(config); + new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); + + //Create Rp Scheme from code. + RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme, "DemoToll4Test"); + RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme, "Tolling scheme for test."); + + /* Add general link based toll for one link */ + RoadPricingUtils.addLink(scheme, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); + + /* Create the rpCalculator based on the scheme. + * Here, only for one type, the see the vehicleType dependent work of it + * */ + VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); + roadPricingCalculator.addPricingScheme(TYPE_1, scheme); + ///___ End creating from Code + + NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); + builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activite the tolling. + NetworkBasedTransportCosts c = builder.build(); + + Vehicle vehicle1 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type1.getMaxVelocity()).thenReturn(5.0); + when(type1.getTypeId()).thenReturn(TYPE_1); + when(vehicle1.getType()).thenReturn(type1); + when(vehicle1.getId()).thenReturn("vehicle1"); + + Vehicle vehicle2 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type2.getMaxVelocity()).thenReturn(5.0); + when(type2.getTypeId()).thenReturn(TYPE_2); + when(vehicle2.getType()).thenReturn(type2); + when(vehicle2.getId()).thenReturn("vehicle2"); + + //vehicle1: includes toll + Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); + + //vehicle 2: no toll + Assertions.assertEquals(40000.0, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); + } + + /** + * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} + * In addition, there is added a road pricing scheme. + * Two different schemes are created to toll the two different vehicle types differently. + */ + @Test + void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ + Config config = new Config(); + config.addCoreModules(); + Scenario scenario = ScenarioUtils.createScenario(config); + new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); + + //Create Rp Scheme from code. + RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); + RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); + + /* Add general link based toll for one link */ + RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); + + //Create Rp Scheme from code. + //Fixme: The following does not work as one may expect: In the end, both schemes are the same object. + // --> It is just added a second entry to the costs, which is not taken into account anyways... + // Questions: + // 1.) How to build ab a second scheme, that is "independently" settable? Currently no new RoadPricingSchemeImpl() can be created without + // the addOrGet methods provided in {@link RoadPricingUtils}. + // 2.) Why does not both costs are summede up in the current behavior, so, the toll is 99.99 + 42.42 = 142.41? + // --> Which one is choose? The first? The higher one?...??? + // One solution might be to use the "withTollFactor" approach. --> Todo write an additional test for it. + // Nevertheless, the current approach leads IMO (KMT) easily to unintentional mistakes. + //kmt, Aug'24 + RoadPricingSchemeImpl scheme2 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme2, "DemoToll4TestType1"); + RoadPricingUtils.setType(scheme2, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme2, "Tolling scheme for test."); + + /* Add general link based toll for one link */ + RoadPricingUtils.addLink(scheme2, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme2, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 42.42); + + + /* Create the rpCalculator based on the scheme. + * Each vehicle type gets affected by a different tolling scheme. + * */ + //FIXME: See above/below: schem1 and scheme2 are the same object.... + VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); + roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); + roadPricingCalculator.addPricingScheme(TYPE_2, scheme2); + + ///___ End creating from Code + + NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); + builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activate the tolling. + NetworkBasedTransportCosts c = builder.build(); + + Vehicle vehicle1 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type1.getMaxVelocity()).thenReturn(5.0); + when(type1.getTypeId()).thenReturn(TYPE_1); + when(vehicle1.getType()).thenReturn(type1); + when(vehicle1.getId()).thenReturn("vehicle1"); + + Vehicle vehicle2 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type2.getMaxVelocity()).thenReturn(5.0); + when(type2.getTypeId()).thenReturn(TYPE_2); + when(vehicle2.getType()).thenReturn(type2); + when(vehicle2.getId()).thenReturn("vehicle2"); + + //vehicle1: includes toll of 99.99 for entering the final link + Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); + + //vehicle 2: includes toll of 42.42 for entering the final link + //Fixme: This currently fails... see comments above. + Assertions.assertEquals(40042.42, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); + } + } From 3b7896d47256e7fc05cbf7550c6113608d45961e Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Sun, 4 Aug 2024 22:06:31 +0200 Subject: [PATCH 02/11] WIP: Prepare test for tolling with factor. Not implemented to the end now -> Disabled. --- .../NetworkBasedTransportCostsTest.java | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index 63870ca8ed3..1b7ce8fe5e3 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -25,6 +25,7 @@ import com.graphhopper.jsprit.core.problem.driver.Driver; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Id; @@ -270,7 +271,6 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ RoadPricingUtils.addLink(scheme2, Id.createLinkId("21")); RoadPricingUtils.createAndAddGeneralCost(scheme2, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 42.42); - /* Create the rpCalculator based on the scheme. * Each vehicle type gets affected by a different tolling scheme. * */ @@ -311,4 +311,68 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } + /** + * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} + * In addition, there is added a road pricing scheme. + * Two different schemes are created to toll the two different vehicle types differently. + * Here the approach using a factor is used to take into account the different types. + * //TODO: Write it completely + */ + @Test + @Disabled + void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor(){ + Config config = new Config(); + config.addCoreModules(); + Scenario scenario = ScenarioUtils.createScenario(config); + new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); + + //Create Rp Scheme from code. + RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); + RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); + + /* Add general link based toll for one link */ + RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); + + //Use a factor to take into account the differnt types. type2 gehts tolled with 50% of the toll of type1 + //TODO: Include factor + + VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); + roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); + + ///___ End creating from Code + + NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); + builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activate the tolling. + NetworkBasedTransportCosts c = builder.build(); + + Vehicle vehicle1 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type1.getMaxVelocity()).thenReturn(5.0); + when(type1.getTypeId()).thenReturn(TYPE_1); + when(vehicle1.getType()).thenReturn(type1); + when(vehicle1.getId()).thenReturn("vehicle1"); + + Vehicle vehicle2 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type2.getMaxVelocity()).thenReturn(5.0); + when(type2.getTypeId()).thenReturn(TYPE_2); + when(vehicle2.getType()).thenReturn(type2); + when(vehicle2.getId()).thenReturn("vehicle2"); + + //vehicle1: includes toll of 99.99 for entering the final link + Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); + + //vehicle 2: includes toll of 49.995 (50% of 99.99) for entering the final link + //Fixme: This currently fails... see comments above. + Assertions.assertEquals(40049.995, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); + } + } From 40240461c419d161c9b1850602bd9d8af2ea0acb Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Sun, 4 Aug 2024 23:30:50 +0200 Subject: [PATCH 03/11] replace self-build RoadPricingCalculator with official RoadPricingScheme --- .../controler/CarrierVehicleReRouter.java | 7 ++-- .../jsprit/NetworkBasedTransportCosts.java | 37 +++++++++++-------- ...cleTypeDependentRoadPricingCalculator.java | 1 + .../NetworkBasedTransportCostsTest.java | 33 +++++++++++++---- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java index 4a75e5c607d..cd03cb5fd94 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierVehicleReRouter.java @@ -36,6 +36,7 @@ import com.graphhopper.jsprit.io.algorithm.AlgorithmConfigXmlReader; import com.graphhopper.jsprit.io.algorithm.VehicleRoutingAlgorithms; import org.matsim.api.core.v01.network.Network; +import org.matsim.contrib.roadpricing.RoadPricingScheme; import org.matsim.core.replanning.ReplanningContext; import org.matsim.core.replanning.modules.GenericPlanStrategyModule; import org.matsim.core.router.util.TravelTime; @@ -58,7 +59,7 @@ class CarrierVehicleReRouter implements GenericPlanStrategyModule{ private final VehicleRoutingActivityCosts vehicleRoutingActivityCosts; - public CarrierVehicleReRouter( Network network, CarrierVehicleTypes vehicleTypes, TravelTime travelTimes, String vrpAlgoConfigFile, VehicleTypeDependentRoadPricingCalculator roadPricing ) { + public CarrierVehicleReRouter( Network network, CarrierVehicleTypes vehicleTypes, TravelTime travelTimes, String vrpAlgoConfigFile, RoadPricingScheme roadPricing ) { this.network = network; vehicleRoutingTransportCosts = getNetworkBasedTransportCosts(network,vehicleTypes,travelTimes,roadPricing); vehicleRoutingActivityCosts = new VehicleRoutingActivityCosts() { @@ -146,7 +147,7 @@ public void handlePlan(CarrierPlan carrierPlan) { } - private NetworkBasedTransportCosts getNetworkBasedTransportCosts(Network network, CarrierVehicleTypes vehicleTypes, TravelTime travelTimes, VehicleTypeDependentRoadPricingCalculator roadPricing) { + private NetworkBasedTransportCosts getNetworkBasedTransportCosts(Network network, CarrierVehicleTypes vehicleTypes, TravelTime travelTimes, RoadPricingScheme roadPricing ) { //****** //Define transport-costs //****** @@ -157,7 +158,7 @@ private NetworkBasedTransportCosts getNetworkBasedTransportCosts(Network network //sets time-dependent travelTimes tpcostsBuilder.setTravelTime(travelTimes); - if(roadPricing != null) tpcostsBuilder.setRoadPricingCalculator(roadPricing); + if(roadPricing != null) tpcostsBuilder.setRoadPricingScheme(roadPricing ); //sets time-slice to build time-dependent tpcosts and travelTime matrices tpcostsBuilder.setTimeSliceWidth(900); diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java index f332b84cb0b..6ad51d3f5bc 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java @@ -30,6 +30,8 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.roadpricing.RoadPricingScheme; +import org.matsim.contrib.roadpricing.RoadPricingSchemeImpl; import org.matsim.core.router.speedy.SpeedyALTFactory; import org.matsim.core.router.util.LeastCostPathCalculator; import org.matsim.core.router.util.LeastCostPathCalculator.Path; @@ -83,6 +85,8 @@ */ public class NetworkBasedTransportCosts implements VRPTransportCosts { + private final RoadPricingScheme roadPricingScheme; + public interface InternalLeastCostPathCalculatorListener { void startCalculation(long routerId); @@ -320,13 +324,13 @@ static class VehicleTransportCostsIncludingToll implements TravelDisutility { private final TravelDisutility baseTransportDisutility; - private final VehicleTypeDependentRoadPricingCalculator vehicleTypeDependentPricingCalculator; + private final RoadPricingScheme roadPricingScheme; - public VehicleTransportCostsIncludingToll(TravelDisutility baseTransportDisutility, - VehicleTypeDependentRoadPricingCalculator vehicleTypeDependentPricingCalculator) { + public VehicleTransportCostsIncludingToll( TravelDisutility baseTransportDisutility, + RoadPricingScheme roadPricingScheme ) { super(); this.baseTransportDisutility = baseTransportDisutility; - this.vehicleTypeDependentPricingCalculator = vehicleTypeDependentPricingCalculator; + this.roadPricingScheme = roadPricingScheme; // System.out.println("huuuuuuuuuuuuuuuuuuuu - initialize transport costs with toll"); } @@ -334,8 +338,10 @@ public VehicleTransportCostsIncludingToll(TravelDisutility baseTransportDisutili public double getLinkTravelDisutility(Link link, double time, Person person, org.matsim.vehicles.Vehicle vehicle) { double costs = baseTransportDisutility.getLinkTravelDisutility(link, time, person, vehicle); - Id typeId = vehicle.getType().getId(); - double toll = vehicleTypeDependentPricingCalculator.getTollAmount(typeId, link, time); +// Id typeId = vehicle.getType().getId(); +// double toll = roadPricingScheme.getTollAmount(typeId, link, time ); + RoadPricingSchemeImpl.Cost costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, person.getId(), vehicle.getId() ); + double toll = costInfo.amount; // System.out.println("huuuuuuuuuuuuuuuuuuuu - paid toll"); return costs + toll; } @@ -377,7 +383,8 @@ public static Builder newInstance(Network network) { private LeastCostPathCalculatorFactory leastCostPathCalculatorFactory = (network, travelCosts, travelTimes) -> new SpeedyALTFactory().createPathCalculator(network, travelCosts, travelTime); - private VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); +// private VehicleTypeDependentRoadPricingCalculator roadPricingScheme = new VehicleTypeDependentRoadPricingCalculator(); + private RoadPricingScheme roadPricingScheme; private boolean withToll = false; @@ -472,9 +479,9 @@ public Builder setThreadSafeLeastCostPathCalculatorFactory( return this; } - public Builder setRoadPricingCalculator(VehicleTypeDependentRoadPricingCalculator calculator) { + public Builder setRoadPricingScheme( RoadPricingScheme roadPricingScheme) { withToll = true; - this.roadPricingCalculator = calculator; + this.roadPricingScheme = roadPricingScheme; return this; } @@ -501,7 +508,7 @@ public NetworkBasedTransportCosts build() { baseDisutility = new BaseVehicleTransportCosts(typeSpecificCosts, travelTime); } if (withToll) { - finalDisutility = new VehicleTransportCostsIncludingToll(baseDisutility, roadPricingCalculator); + finalDisutility = new VehicleTransportCostsIncludingToll(baseDisutility, roadPricingScheme ); } else finalDisutility = baseDisutility; return new NetworkBasedTransportCosts(this); @@ -551,8 +558,6 @@ public void addVehicleTypeSpecificCosts(String typeId, double fix, double perSec private final Map matsimVehicles = new HashMap<>(); - private final VehicleTypeDependentRoadPricingCalculator roadPricingCalc; - /** * by default sets the {@link SpeedyALTFactory} */ @@ -568,7 +573,7 @@ private NetworkBasedTransportCosts(Builder builder) { this.travelTime = builder.travelTime; this.network = builder.network; this.leastCostPathCalculatorFactory = builder.leastCostPathCalculatorFactory; - this.roadPricingCalc = builder.roadPricingCalculator; + this.roadPricingScheme = builder.roadPricingScheme; this.timeSliceWidth = builder.timeSliceWidth; this.defaultTypeId = builder.defaultTypeId; this.ttMemorizedCounter = new Counter("#TransportCostValues cached "); @@ -882,8 +887,8 @@ public TravelTime getTravelTime() { * * @return {@link VehicleTypeDependentRoadPricingCalculator} */ - public VehicleTypeDependentRoadPricingCalculator getRoadPricingCalculator() { - return roadPricingCalc; - } +// public VehicleTypeDependentRoadPricingCalculator getRoadPricingCalculator() { +// return roadPricingCalc; +// } } diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java index ed5d3694720..6175780ab9a 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/VehicleTypeDependentRoadPricingCalculator.java @@ -35,6 +35,7 @@ * @author stefan schröder * */ +@Deprecated // use RoadPricingScheme public class VehicleTypeDependentRoadPricingCalculator { interface TollCalculator { diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index 1b7ce8fe5e3..cb90a059a6e 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -30,10 +30,10 @@ import org.junit.jupiter.api.extension.RegisterExtension; 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.api.core.v01.network.Network; -import org.matsim.contrib.roadpricing.RoadPricingScheme; -import org.matsim.contrib.roadpricing.RoadPricingSchemeImpl; -import org.matsim.contrib.roadpricing.RoadPricingUtils; +import org.matsim.api.core.v01.population.Person; +import org.matsim.contrib.roadpricing.*; import org.matsim.core.config.Config; import org.matsim.core.network.io.MatsimNetworkReader; import org.matsim.core.scenario.ScenarioUtils; @@ -44,6 +44,9 @@ import org.matsim.vehicles.VehicleUtils; import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -194,14 +197,28 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneType(){ /* Create the rpCalculator based on the scheme. * Here, only for one type, the see the vehicleType dependent work of it * */ - VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); - roadPricingCalculator.addPricingScheme(TYPE_1, scheme); +// VehicleTypeDependentRoadPricingCalculator roadPricingScheme = new VehicleTypeDependentRoadPricingCalculator(); +// roadPricingScheme.addPricingScheme(TYPE_1, scheme); ///___ End creating from Code + TollFactor tollFactor = new TollFactor(){ + @Override public double getTollFactor( Id personId, Id vehicleId, Id linkId, double time ){ + double tollFactor = 1.; + // find vehicle: + org.matsim.vehicles.Vehicle vehicle = scenario.getVehicles().getVehicles().get( vehicleId ); // das ist schlussendlich ziemlich dumm, aber so ist die Schnittstelle im Moment + VehicleType type = vehicle.getType(); + if ( type......) { + tollFactor = 2.; + } + return tollFactor; + } + }; + RoadPricingScheme schemeUsingTollFactor = new RoadPricingSchemeUsingTollFactor( scheme , tollFactor ); + NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activite the tolling. + builder.setRoadPricingScheme(schemeUsingTollFactor ); NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); @@ -284,7 +301,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activate the tolling. + builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); @@ -348,7 +365,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor( NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingCalculator(roadPricingCalculator); //add the rpCalculator to activate the tolling. + builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); From ae8aa5ab28408b6343cac852f528f38e08902495 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Mon, 5 Aug 2024 23:09:03 +0200 Subject: [PATCH 04/11] adapt test: use tollFactor --- .../NetworkBasedTransportCostsTest.java | 203 +++++++++--------- 1 file changed, 106 insertions(+), 97 deletions(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index cb90a059a6e..58681271e6a 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -203,12 +203,16 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneType(){ TollFactor tollFactor = new TollFactor(){ @Override public double getTollFactor( Id personId, Id vehicleId, Id linkId, double time ){ - double tollFactor = 1.; - // find vehicle: - org.matsim.vehicles.Vehicle vehicle = scenario.getVehicles().getVehicles().get( vehicleId ); // das ist schlussendlich ziemlich dumm, aber so ist die Schnittstelle im Moment - VehicleType type = vehicle.getType(); - if ( type......) { - tollFactor = 2.; + double tollFactor = 0.; + + var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); + +// // find vehicle: +// org.matsim.vehicles.Vehicle vehicle = scenario.getVehicles().getVehicles().get( vehicleId ); // das ist schlussendlich ziemlich dumm, aber so ist die Schnittstelle im Moment +// VehicleType type = vehicle.getType(); +// if (TYPE_1.equals(type.getId().toString())) { + if (TYPE_1.equals(vehTypeIdString)) { + tollFactor = 1.; } return tollFactor; } @@ -244,89 +248,89 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneType(){ Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } - /** - * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} - * In addition, there is added a road pricing scheme. - * Two different schemes are created to toll the two different vehicle types differently. - */ - @Test - void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ - Config config = new Config(); - config.addCoreModules(); - Scenario scenario = ScenarioUtils.createScenario(config); - new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); - - //Create Rp Scheme from code. - RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); - /* Configure roadpricing scheme. */ - RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); - RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); - RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); - - /* Add general link based toll for one link */ - RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); - RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); - - //Create Rp Scheme from code. - //Fixme: The following does not work as one may expect: In the end, both schemes are the same object. - // --> It is just added a second entry to the costs, which is not taken into account anyways... - // Questions: - // 1.) How to build ab a second scheme, that is "independently" settable? Currently no new RoadPricingSchemeImpl() can be created without - // the addOrGet methods provided in {@link RoadPricingUtils}. - // 2.) Why does not both costs are summede up in the current behavior, so, the toll is 99.99 + 42.42 = 142.41? - // --> Which one is choose? The first? The higher one?...??? - // One solution might be to use the "withTollFactor" approach. --> Todo write an additional test for it. - // Nevertheless, the current approach leads IMO (KMT) easily to unintentional mistakes. - //kmt, Aug'24 - RoadPricingSchemeImpl scheme2 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); - /* Configure roadpricing scheme. */ - RoadPricingUtils.setName(scheme2, "DemoToll4TestType1"); - RoadPricingUtils.setType(scheme2, RoadPricingScheme.TOLL_TYPE_LINK); - RoadPricingUtils.setDescription(scheme2, "Tolling scheme for test."); - - /* Add general link based toll for one link */ - RoadPricingUtils.addLink(scheme2, Id.createLinkId("21")); - RoadPricingUtils.createAndAddGeneralCost(scheme2, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 42.42); - - /* Create the rpCalculator based on the scheme. - * Each vehicle type gets affected by a different tolling scheme. - * */ - //FIXME: See above/below: schem1 and scheme2 are the same object.... - VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); - roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); - roadPricingCalculator.addPricingScheme(TYPE_2, scheme2); - - ///___ End creating from Code - - NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); - builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); - builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. - NetworkBasedTransportCosts c = builder.build(); - - Vehicle vehicle1 = mock(Vehicle.class); - com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); - when(type1.getMaxVelocity()).thenReturn(5.0); - when(type1.getTypeId()).thenReturn(TYPE_1); - when(vehicle1.getType()).thenReturn(type1); - when(vehicle1.getId()).thenReturn("vehicle1"); - - Vehicle vehicle2 = mock(Vehicle.class); - com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); - when(type2.getMaxVelocity()).thenReturn(5.0); - when(type2.getTypeId()).thenReturn(TYPE_2); - when(vehicle2.getType()).thenReturn(type2); - when(vehicle2.getId()).thenReturn("vehicle2"); - - //vehicle1: includes toll of 99.99 for entering the final link - Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); - Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); - - //vehicle 2: includes toll of 42.42 for entering the final link - //Fixme: This currently fails... see comments above. - Assertions.assertEquals(40042.42, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); - Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); - } +// /** +// * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} +// * In addition, there is added a road pricing scheme. +// * Two different schemes are created to toll the two different vehicle types differently. +// */ +// @Test +// void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ +// Config config = new Config(); +// config.addCoreModules(); +// Scenario scenario = ScenarioUtils.createScenario(config); +// new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); +// +// //Create Rp Scheme from code. +// RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); +// /* Configure roadpricing scheme. */ +// RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); +// RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); +// RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); +// +// /* Add general link based toll for one link */ +// RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); +// RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); +// +// //Create Rp Scheme from code. +// //Fixme: The following does not work as one may expect: In the end, both schemes are the same object. +// // --> It is just added a second entry to the costs, which is not taken into account anyways... +// // Questions: +// // 1.) How to build ab a second scheme, that is "independently" settable? Currently no new RoadPricingSchemeImpl() can be created without +// // the addOrGet methods provided in {@link RoadPricingUtils}. +// // 2.) Why does not both costs are summede up in the current behavior, so, the toll is 99.99 + 42.42 = 142.41? +// // --> Which one is choose? The first? The higher one?...??? +// // One solution might be to use the "withTollFactor" approach. --> Todo write an additional test for it. +// // Nevertheless, the current approach leads IMO (KMT) easily to unintentional mistakes. +// //kmt, Aug'24 +// RoadPricingSchemeImpl scheme2 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); +// /* Configure roadpricing scheme. */ +// RoadPricingUtils.setName(scheme2, "DemoToll4TestType1"); +// RoadPricingUtils.setType(scheme2, RoadPricingScheme.TOLL_TYPE_LINK); +// RoadPricingUtils.setDescription(scheme2, "Tolling scheme for test."); +// +// /* Add general link based toll for one link */ +// RoadPricingUtils.addLink(scheme2, Id.createLinkId("21")); +// RoadPricingUtils.createAndAddGeneralCost(scheme2, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 42.42); +// +// /* Create the rpCalculator based on the scheme. +// * Each vehicle type gets affected by a different tolling scheme. +// * */ +// //FIXME: See above/below: schem1 and scheme2 are the same object.... +// VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); +// roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); +// roadPricingCalculator.addPricingScheme(TYPE_2, scheme2); +// +// ///___ End creating from Code +// +// NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); +// builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); +// builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); +// builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. +// NetworkBasedTransportCosts c = builder.build(); +// +// Vehicle vehicle1 = mock(Vehicle.class); +// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); +// when(type1.getMaxVelocity()).thenReturn(5.0); +// when(type1.getTypeId()).thenReturn(TYPE_1); +// when(vehicle1.getType()).thenReturn(type1); +// when(vehicle1.getId()).thenReturn("vehicle1"); +// +// Vehicle vehicle2 = mock(Vehicle.class); +// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); +// when(type2.getMaxVelocity()).thenReturn(5.0); +// when(type2.getTypeId()).thenReturn(TYPE_2); +// when(vehicle2.getType()).thenReturn(type2); +// when(vehicle2.getId()).thenReturn("vehicle2"); +// +// //vehicle1: includes toll of 99.99 for entering the final link +// Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); +// Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); +// +// //vehicle 2: includes toll of 42.42 for entering the final link +// //Fixme: This currently fails... see comments above. +// Assertions.assertEquals(40042.42, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); +// Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); +// } /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} @@ -336,7 +340,6 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ * //TODO: Write it completely */ @Test - @Disabled void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor(){ Config config = new Config(); config.addCoreModules(); @@ -355,17 +358,24 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor( RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); //Use a factor to take into account the differnt types. type2 gehts tolled with 50% of the toll of type1 - //TODO: Include factor - - VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); - roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); + TollFactor tollFactor = (personId, vehicleId, linkId, time) -> { + var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); + if (TYPE_1.equals(vehTypeIdString)) { + return 1; + } else if (TYPE_2.equals(vehTypeIdString)) { + return 0.5; + } else { + return 0; + } + }; + RoadPricingSchemeUsingTollFactor rpSchemeWTollFactor = new RoadPricingSchemeUsingTollFactor( scheme1 , tollFactor ); - ///___ End creating from Code + ///___ End creating toll scheme from code NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. + builder.setRoadPricingScheme(rpSchemeWTollFactor); //add the rpCalculator to activate the tolling. NetworkBasedTransportCosts c = builder.build(); Vehicle vehicle1 = mock(Vehicle.class); @@ -387,7 +397,6 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor( Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); //vehicle 2: includes toll of 49.995 (50% of 99.99) for entering the final link - //Fixme: This currently fails... see comments above. Assertions.assertEquals(40049.995, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } From 3bc9b188fb6d1e61d49291545ccaa486ddc09916 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Mon, 5 Aug 2024 23:09:32 +0200 Subject: [PATCH 05/11] add option if person==null --- .../carriers/jsprit/NetworkBasedTransportCosts.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java index 6ad51d3f5bc..df48a3e6451 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java @@ -340,7 +340,12 @@ public double getLinkTravelDisutility(Link link, double time, Person person, double costs = baseTransportDisutility.getLinkTravelDisutility(link, time, person, vehicle); // Id typeId = vehicle.getType().getId(); // double toll = roadPricingScheme.getTollAmount(typeId, link, time ); - RoadPricingSchemeImpl.Cost costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, person.getId(), vehicle.getId() ); + RoadPricingSchemeImpl.Cost costInfo; + if (person == null) { + costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, null, vehicle.getId() ); + } else { + costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, person.getId(), vehicle.getId() ); + } double toll = costInfo.amount; // System.out.println("huuuuuuuuuuuuuuuuuuuu - paid toll"); return costs + toll; From f051660abb897ac0b5bebf44db93066405e030ca Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 6 Aug 2024 09:14:53 +0200 Subject: [PATCH 06/11] more tests --- .../NetworkBasedTransportCostsTest.java | 56 ++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index 58681271e6a..7de43a75c87 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -169,6 +169,60 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ Assertions.assertEquals(20000.0, networkBasedTransportCosts.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } + + /** + * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} + * In addition, there is added a road pricing scheme. + * The scheme is only set for one vehicle type: type1. + * So, only the vehicle using that type (vehicle1) should be tolled, the other (vehicle2) not. + * + */ + @Test + void test_whenAddingTwoDifferentVehicleTypes_tollAllTypes(){ + Config config = new Config(); + config.addCoreModules(); + Scenario scenario = ScenarioUtils.createScenario(config); + new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); + + //Create Rp Scheme from code. + RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + /* Configure roadpricing scheme. */ + RoadPricingUtils.setName(scheme, "DemoToll4Test"); + RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme, "Tolling scheme for test."); + + /* Add general link based toll for one link */ + RoadPricingUtils.addLink(scheme, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); + + NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); + builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); + builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); + builder.setRoadPricingScheme(scheme); + NetworkBasedTransportCosts c = builder.build(); + + Vehicle vehicle1 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type1.getMaxVelocity()).thenReturn(5.0); + when(type1.getTypeId()).thenReturn(TYPE_1); + when(vehicle1.getType()).thenReturn(type1); + when(vehicle1.getId()).thenReturn("vehicle1"); + + Vehicle vehicle2 = mock(Vehicle.class); + com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); + when(type2.getMaxVelocity()).thenReturn(5.0); + when(type2.getTypeId()).thenReturn(TYPE_2); + when(vehicle2.getType()).thenReturn(type2); + when(vehicle2.getId()).thenReturn("vehicle2"); + + //vehicle1: includes toll + Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); + + //vehicle 2: no toll + Assertions.assertEquals(40099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); + Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); + } /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} * In addition, there is added a road pricing scheme. @@ -177,7 +231,7 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ * */ @Test - void test_whenAddingTwoDifferentVehicleTypes_tollOneType(){ + void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ Config config = new Config(); config.addCoreModules(); Scenario scenario = ScenarioUtils.createScenario(config); From 99f008a937b17517515066f7826b66b474123272 Mon Sep 17 00:00:00 2001 From: Kai Nagel Date: Tue, 6 Aug 2024 09:54:59 +0200 Subject: [PATCH 07/11] more steps forward --- .../jsprit/NetworkBasedTransportCosts.java | 5 +- .../NetworkBasedTransportCostsTest.java | 46 ++++++++++++++----- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java index df48a3e6451..e12b8b1b1e3 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java @@ -346,7 +346,10 @@ public double getLinkTravelDisutility(Link link, double time, Person person, } else { costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, person.getId(), vehicle.getId() ); } - double toll = costInfo.amount; + double toll=0.; + if ( costInfo != null ){ + toll = costInfo.amount; + } // System.out.println("huuuuuuuuuuuuuuuuuuuu - paid toll"); return costs + toll; } diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index 7de43a75c87..f4049d554a1 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -28,6 +28,7 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.matsim.api.core.v01.Coord; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; import org.matsim.api.core.v01.network.Link; @@ -38,10 +39,12 @@ import org.matsim.core.network.io.MatsimNetworkReader; import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.misc.Time; +import org.matsim.freight.carriers.CarrierVehicle; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.CostInformation; import org.matsim.vehicles.VehicleType; import org.matsim.vehicles.VehicleUtils; +import org.matsim.vehicles.VehiclesFactory; import java.util.Arrays; import java.util.List; @@ -279,19 +282,38 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ builder.setRoadPricingScheme(schemeUsingTollFactor ); NetworkBasedTransportCosts c = builder.build(); - Vehicle vehicle1 = mock(Vehicle.class); - com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); - when(type1.getMaxVelocity()).thenReturn(5.0); - when(type1.getTypeId()).thenReturn(TYPE_1); - when(vehicle1.getType()).thenReturn(type1); - when(vehicle1.getId()).thenReturn("vehicle1"); + VehiclesFactory vf = scenario.getVehicles().getFactory(); + final Vehicle vehicle1; + { + VehicleType vehType1 = vf.createVehicleType( Id.create( TYPE_1, VehicleType.class ) ); + scenario.getVehicles().addVehicleType( vehType1 ); +// org.matsim.vehicles.Vehicle matsimVehicle1 = vf.createVehicle( Id.createVehicleId( "vehicle1" ), vehType1 ); + CarrierVehicle matsimVehicle1 = CarrierVehicle.newInstance( Id.createVehicleId( "vehicle1" ), null, vehType1 ); + scenario.getVehicles().addVehicle( matsimVehicle1 ); + vehicle1 = MatsimJspritFactory.createJspritVehicle( matsimVehicle1, new Coord() ); + } + VehicleType vehType2 = vf.createVehicleType( Id.create( TYPE_2, VehicleType.class ) ); + scenario.getVehicles().addVehicleType( vehType2 ); +// org.matsim.vehicles.Vehicle matsimVehicle2 = vf.createVehicle( Id.createVehicleId( "vehicle2" ), vehType2 ); + CarrierVehicle matsimVehicle2 = CarrierVehicle.newInstance( Id.createVehicleId( "vehicle2" ), null, vehType2 ); + scenario.getVehicles().addVehicle( matsimVehicle2 ); - Vehicle vehicle2 = mock(Vehicle.class); - com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); - when(type2.getMaxVelocity()).thenReturn(5.0); - when(type2.getTypeId()).thenReturn(TYPE_2); - when(vehicle2.getType()).thenReturn(type2); - when(vehicle2.getId()).thenReturn("vehicle2"); + Vehicle vehicle2 = MatsimJspritFactory.createJspritVehicle( matsimVehicle2, new Coord() ); + +// // for the following rather use the MatsimJspritFactory#createCarrierVehicle +// Vehicle vehicle1 = mock(Vehicle.class); +// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); +// when(type1.getMaxVelocity()).thenReturn(5.0); +// when(type1.getTypeId()).thenReturn(TYPE_1); +// when(vehicle1.getType()).thenReturn(type1); +// when(vehicle1.getId()).thenReturn("vehicle1"); +// +// Vehicle vehicle2 = mock(Vehicle.class); +// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); +// when(type2.getMaxVelocity()).thenReturn(5.0); +// when(type2.getTypeId()).thenReturn(TYPE_2); +// when(vehicle2.getType()).thenReturn(type2); +// when(vehicle2.getId()).thenReturn("vehicle2"); //vehicle1: includes toll Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); From 9b3f81881594988eedbd5082889e820c70b345c4 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 6 Aug 2024 11:12:29 +0200 Subject: [PATCH 08/11] fix one test: Use MATSim's vehicles --- .../NetworkBasedTransportCostsTest.java | 168 ++++-------------- 1 file changed, 34 insertions(+), 134 deletions(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index f4049d554a1..d1a8a5107bc 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -40,6 +40,7 @@ import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.misc.Time; import org.matsim.freight.carriers.CarrierVehicle; +import org.matsim.freight.carriers.CarriersUtils; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.CostInformation; import org.matsim.vehicles.VehicleType; @@ -240,7 +241,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ Scenario scenario = ScenarioUtils.createScenario(config); new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); - //Create Rp Scheme from code. + //Create RoadPricing Scheme from code. RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); /* Configure roadpricing scheme. */ RoadPricingUtils.setName(scheme, "DemoToll4Test"); @@ -251,69 +252,51 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ RoadPricingUtils.addLink(scheme, Id.createLinkId("21")); RoadPricingUtils.createAndAddGeneralCost(scheme, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); - /* Create the rpCalculator based on the scheme. - * Here, only for one type, the see the vehicleType dependent work of it - * */ -// VehicleTypeDependentRoadPricingCalculator roadPricingScheme = new VehicleTypeDependentRoadPricingCalculator(); -// roadPricingScheme.addPricingScheme(TYPE_1, scheme); - ///___ End creating from Code - - TollFactor tollFactor = new TollFactor(){ - @Override public double getTollFactor( Id personId, Id vehicleId, Id linkId, double time ){ - double tollFactor = 0.; - - var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); - -// // find vehicle: -// org.matsim.vehicles.Vehicle vehicle = scenario.getVehicles().getVehicles().get( vehicleId ); // das ist schlussendlich ziemlich dumm, aber so ist die Schnittstelle im Moment -// VehicleType type = vehicle.getType(); -// if (TYPE_1.equals(type.getId().toString())) { - if (TYPE_1.equals(vehTypeIdString)) { - tollFactor = 1.; - } - return tollFactor; + //Use toll factor to only toll vehicles of type1. + TollFactor tollFactor = (personId, vehicleId, linkId, time) -> { + double tollFactor1 = 0.; + var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); + if (TYPE_1.equals(vehTypeIdString)) { + tollFactor1 = 1.; } + return tollFactor1; }; RoadPricingScheme schemeUsingTollFactor = new RoadPricingSchemeUsingTollFactor( scheme , tollFactor ); - NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); - builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); - builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); - builder.setRoadPricingScheme(schemeUsingTollFactor ); - NetworkBasedTransportCosts c = builder.build(); + /// End creating roadPricing scheme from Code + //Build MATSim vehicles and convert them to jsprit Vehicles ... just to see, that this works across the whole chain and + //that we can filter/search by (MATSim) vehicle types in Toll Factor usage VehiclesFactory vf = scenario.getVehicles().getFactory(); final Vehicle vehicle1; { VehicleType vehType1 = vf.createVehicleType( Id.create( TYPE_1, VehicleType.class ) ); + vehType1.getCostInformation().setFixedCost(10.0); + vehType1.getCostInformation().setCostsPerSecond(0.0); + vehType1.getCostInformation().setCostsPerMeter(2.0); scenario.getVehicles().addVehicleType( vehType1 ); -// org.matsim.vehicles.Vehicle matsimVehicle1 = vf.createVehicle( Id.createVehicleId( "vehicle1" ), vehType1 ); - CarrierVehicle matsimVehicle1 = CarrierVehicle.newInstance( Id.createVehicleId( "vehicle1" ), null, vehType1 ); + CarrierVehicle matsimVehicle1 = CarrierVehicle.newInstance( Id.createVehicleId( "vehicle1" ), Id.createLinkId("20"), vehType1 ); scenario.getVehicles().addVehicle( matsimVehicle1 ); vehicle1 = MatsimJspritFactory.createJspritVehicle( matsimVehicle1, new Coord() ); } - VehicleType vehType2 = vf.createVehicleType( Id.create( TYPE_2, VehicleType.class ) ); - scenario.getVehicles().addVehicleType( vehType2 ); -// org.matsim.vehicles.Vehicle matsimVehicle2 = vf.createVehicle( Id.createVehicleId( "vehicle2" ), vehType2 ); - CarrierVehicle matsimVehicle2 = CarrierVehicle.newInstance( Id.createVehicleId( "vehicle2" ), null, vehType2 ); - scenario.getVehicles().addVehicle( matsimVehicle2 ); - - Vehicle vehicle2 = MatsimJspritFactory.createJspritVehicle( matsimVehicle2, new Coord() ); - -// // for the following rather use the MatsimJspritFactory#createCarrierVehicle -// Vehicle vehicle1 = mock(Vehicle.class); -// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); -// when(type1.getMaxVelocity()).thenReturn(5.0); -// when(type1.getTypeId()).thenReturn(TYPE_1); -// when(vehicle1.getType()).thenReturn(type1); -// when(vehicle1.getId()).thenReturn("vehicle1"); -// -// Vehicle vehicle2 = mock(Vehicle.class); -// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); -// when(type2.getMaxVelocity()).thenReturn(5.0); -// when(type2.getTypeId()).thenReturn(TYPE_2); -// when(vehicle2.getType()).thenReturn(type2); -// when(vehicle2.getId()).thenReturn("vehicle2"); + + final Vehicle vehicle2; + { + VehicleType vehType2 = vf.createVehicleType(Id.create(TYPE_2, VehicleType.class)); + vehType2.getCostInformation().setFixedCost(20.0); + vehType2.getCostInformation().setCostsPerSecond(0.0); + vehType2.getCostInformation().setCostsPerMeter(4.0); + scenario.getVehicles().addVehicleType(vehType2); + + CarrierVehicle matsimVehicle2 = CarrierVehicle.newInstance(Id.createVehicleId("vehicle2"), Id.createLinkId("20"), vehType2); + scenario.getVehicles().addVehicle(matsimVehicle2); + vehicle2 = MatsimJspritFactory.createJspritVehicle(matsimVehicle2, new Coord()); + } + + //Build the NetbasedTransportCosts opbejct with the roadpricing scheme. + NetworkBasedTransportCosts c = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork(), scenario.getVehicles().getVehicleTypes().values() ) + .setRoadPricingScheme(schemeUsingTollFactor) + .build() ; //vehicle1: includes toll Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); @@ -324,89 +307,6 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } -// /** -// * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} -// * In addition, there is added a road pricing scheme. -// * Two different schemes are created to toll the two different vehicle types differently. -// */ -// @Test -// void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferently(){ -// Config config = new Config(); -// config.addCoreModules(); -// Scenario scenario = ScenarioUtils.createScenario(config); -// new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); -// -// //Create Rp Scheme from code. -// RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); -// /* Configure roadpricing scheme. */ -// RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); -// RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); -// RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); -// -// /* Add general link based toll for one link */ -// RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); -// RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); -// -// //Create Rp Scheme from code. -// //Fixme: The following does not work as one may expect: In the end, both schemes are the same object. -// // --> It is just added a second entry to the costs, which is not taken into account anyways... -// // Questions: -// // 1.) How to build ab a second scheme, that is "independently" settable? Currently no new RoadPricingSchemeImpl() can be created without -// // the addOrGet methods provided in {@link RoadPricingUtils}. -// // 2.) Why does not both costs are summede up in the current behavior, so, the toll is 99.99 + 42.42 = 142.41? -// // --> Which one is choose? The first? The higher one?...??? -// // One solution might be to use the "withTollFactor" approach. --> Todo write an additional test for it. -// // Nevertheless, the current approach leads IMO (KMT) easily to unintentional mistakes. -// //kmt, Aug'24 -// RoadPricingSchemeImpl scheme2 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); -// /* Configure roadpricing scheme. */ -// RoadPricingUtils.setName(scheme2, "DemoToll4TestType1"); -// RoadPricingUtils.setType(scheme2, RoadPricingScheme.TOLL_TYPE_LINK); -// RoadPricingUtils.setDescription(scheme2, "Tolling scheme for test."); -// -// /* Add general link based toll for one link */ -// RoadPricingUtils.addLink(scheme2, Id.createLinkId("21")); -// RoadPricingUtils.createAndAddGeneralCost(scheme2, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 42.42); -// -// /* Create the rpCalculator based on the scheme. -// * Each vehicle type gets affected by a different tolling scheme. -// * */ -// //FIXME: See above/below: schem1 and scheme2 are the same object.... -// VehicleTypeDependentRoadPricingCalculator roadPricingCalculator = new VehicleTypeDependentRoadPricingCalculator(); -// roadPricingCalculator.addPricingScheme(TYPE_1, scheme1); -// roadPricingCalculator.addPricingScheme(TYPE_2, scheme2); -// -// ///___ End creating from Code -// -// NetworkBasedTransportCosts.Builder builder = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork()); -// builder.addVehicleTypeSpecificCosts(TYPE_1, 10.0, 0.0, 2.0); -// builder.addVehicleTypeSpecificCosts(TYPE_2, 20.0, 0.0, 4.0); -// builder.setRoadPricingScheme(roadPricingCalculator ); //add the rpCalculator to activate the tolling. -// NetworkBasedTransportCosts c = builder.build(); -// -// Vehicle vehicle1 = mock(Vehicle.class); -// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type1 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); -// when(type1.getMaxVelocity()).thenReturn(5.0); -// when(type1.getTypeId()).thenReturn(TYPE_1); -// when(vehicle1.getType()).thenReturn(type1); -// when(vehicle1.getId()).thenReturn("vehicle1"); -// -// Vehicle vehicle2 = mock(Vehicle.class); -// com.graphhopper.jsprit.core.problem.vehicle.VehicleType type2 = mock( com.graphhopper.jsprit.core.problem.vehicle.VehicleType.class ); -// when(type2.getMaxVelocity()).thenReturn(5.0); -// when(type2.getTypeId()).thenReturn(TYPE_2); -// when(vehicle2.getType()).thenReturn(type2); -// when(vehicle2.getId()).thenReturn("vehicle2"); -// -// //vehicle1: includes toll of 99.99 for entering the final link -// Assertions.assertEquals(20099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle1), 0.01); -// Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle1), 0.01); -// -// //vehicle 2: includes toll of 42.42 for entering the final link -// //Fixme: This currently fails... see comments above. -// Assertions.assertEquals(40042.42, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); -// Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); -// } /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} From 8a3cd452528f9da7486fff38613d09e9fa2da517 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 6 Aug 2024 11:27:02 +0200 Subject: [PATCH 09/11] fix the last test: Building the netbased costs without MATSim's vehicle types --- .../NetworkBasedTransportCostsTest.java | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index d1a8a5107bc..65b691b5737 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -25,7 +25,6 @@ import com.graphhopper.jsprit.core.problem.driver.Driver; import com.graphhopper.jsprit.core.problem.vehicle.Vehicle; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.matsim.api.core.v01.Coord; @@ -40,7 +39,6 @@ import org.matsim.core.scenario.ScenarioUtils; import org.matsim.core.utils.misc.Time; import org.matsim.freight.carriers.CarrierVehicle; -import org.matsim.freight.carriers.CarriersUtils; import org.matsim.testcases.MatsimTestUtils; import org.matsim.vehicles.CostInformation; import org.matsim.vehicles.VehicleType; @@ -48,9 +46,6 @@ import org.matsim.vehicles.VehiclesFactory; import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -176,10 +171,7 @@ void test_whenAddingTwoVehicleTypesViaConstructor_itMustAccountForThat(){ /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} - * In addition, there is added a road pricing scheme. - * The scheme is only set for one vehicle type: type1. - * So, only the vehicle using that type (vehicle1) should be tolled, the other (vehicle2) not. - * + * In addition, there is added a road pricing scheme to toll all vehicles */ @Test void test_whenAddingTwoDifferentVehicleTypes_tollAllTypes(){ @@ -227,12 +219,14 @@ void test_whenAddingTwoDifferentVehicleTypes_tollAllTypes(){ Assertions.assertEquals(40099.99, c.getTransportCost(Location.newInstance("20"), Location.newInstance("21"), 0.0, mock(Driver.class), vehicle2), 0.01); Assertions.assertEquals(20000.0, c.getDistance(Location.newInstance("6"), Location.newInstance("21"), 0.0, vehicle2), 0.01); } + /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} * In addition, there is added a road pricing scheme. * The scheme is only set for one vehicle type: type1. * So, only the vehicle using that type (vehicle1) should be tolled, the other (vehicle2) not. - * + * This test is build, in a way, that it uses the MATSim infrastructure for filtering the vehicles in the toll factor. + * To see it just on jsprit setting, please refer to {@link #test_whenAddingTwoDifferentVehicleTypes_tollBasedOnVehicleId} */ @Test void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ @@ -255,7 +249,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ //Use toll factor to only toll vehicles of type1. TollFactor tollFactor = (personId, vehicleId, linkId, time) -> { double tollFactor1 = 0.; - var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); + var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); //This needs, the vehicles registered in the scenario. if (TYPE_1.equals(vehTypeIdString)) { tollFactor1 = 1.; } @@ -266,7 +260,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ /// End creating roadPricing scheme from Code //Build MATSim vehicles and convert them to jsprit Vehicles ... just to see, that this works across the whole chain and - //that we can filter/search by (MATSim) vehicle types in Toll Factor usage + //that we can filter/search by (MATSim) vehicle types in TollFactor usage VehiclesFactory vf = scenario.getVehicles().getFactory(); final Vehicle vehicle1; { @@ -294,7 +288,9 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ } //Build the NetbasedTransportCosts opbejct with the roadpricing scheme. - NetworkBasedTransportCosts c = NetworkBasedTransportCosts.Builder.newInstance(scenario.getNetwork(), scenario.getVehicles().getVehicleTypes().values() ) + NetworkBasedTransportCosts c = NetworkBasedTransportCosts.Builder.newInstance( + scenario.getNetwork(), + scenario.getVehicles().getVehicleTypes().values() ) .setRoadPricingScheme(schemeUsingTollFactor) .build() ; @@ -311,12 +307,12 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ /** * This test is a modified version of {@link #test_whenAddingTwoDifferentVehicleTypes_itMustAccountForThem} * In addition, there is added a road pricing scheme. - * Two different schemes are created to toll the two different vehicle types differently. - * Here the approach using a factor is used to take into account the different types. - * //TODO: Write it completely + * With using a toll factor, the tolling can be set differently for the two vehicles. + * This test is build, in a way, that it uses the JSPRIT vehicle directly. + * To see it with the MATSim settings, please refer to {@link #test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor()} */ @Test - void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor(){ + void test_whenAddingTwoDifferentVehicleTypes_tollBasedOnVehicleId(){ Config config = new Config(); config.addCoreModules(); Scenario scenario = ScenarioUtils.createScenario(config); @@ -334,14 +330,19 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBothTypesDifferentlyWithFactor( RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); //Use a factor to take into account the differnt types. type2 gehts tolled with 50% of the toll of type1 - TollFactor tollFactor = (personId, vehicleId, linkId, time) -> { - var vehTypeIdString = VehicleUtils.findVehicle(vehicleId, scenario).getType().getId().toString(); - if (TYPE_1.equals(vehTypeIdString)) { - return 1; - } else if (TYPE_2.equals(vehTypeIdString)) { - return 0.5; - } else { - return 0; + TollFactor tollFactor = new TollFactor() { + @Override + public double getTollFactor(Id personId, Id vehicleId, Id linkId, double time) { + //No information about the vehicleType available anywhere, because is is nowhere registered centrally, + // -> Use the vehicleId to distinguish the types. + var vehTypeIdString = vehicleId.toString(); + if (vehTypeIdString.equals("vehicle1")) { + return 1; + } else if (vehTypeIdString.equals("vehicle2")) { + return 0.5; + } else { + return 0; + } } }; RoadPricingSchemeUsingTollFactor rpSchemeWTollFactor = new RoadPricingSchemeUsingTollFactor( scheme1 , tollFactor ); From 883f2d34fbfa617038acefd8a51a02e3a4207a62 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 6 Aug 2024 11:37:37 +0200 Subject: [PATCH 10/11] some cleanup and javadoc --- .../jsprit/NetworkBasedTransportCosts.java | 44 +++++++------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java index e12b8b1b1e3..e6d8e1a0e45 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCosts.java @@ -320,7 +320,6 @@ private static class VehicleTypeVarCosts { */ static class VehicleTransportCostsIncludingToll implements TravelDisutility { -// private static Logger logger = LogManager.getLogger(VehicleTransportCostsIncludingToll.class); private final TravelDisutility baseTransportDisutility; @@ -331,26 +330,24 @@ public VehicleTransportCostsIncludingToll( TravelDisutility baseTransportDisutil super(); this.baseTransportDisutility = baseTransportDisutility; this.roadPricingScheme = roadPricingScheme; -// System.out.println("huuuuuuuuuuuuuuuuuuuu - initialize transport costs with toll"); } @Override public double getLinkTravelDisutility(Link link, double time, Person person, org.matsim.vehicles.Vehicle vehicle) { double costs = baseTransportDisutility.getLinkTravelDisutility(link, time, person, vehicle); -// Id typeId = vehicle.getType().getId(); -// double toll = roadPricingScheme.getTollAmount(typeId, link, time ); + RoadPricingSchemeImpl.Cost costInfo; if (person == null) { costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, null, vehicle.getId() ); } else { costInfo = roadPricingScheme.getLinkCostInfo( link.getId(), time, person.getId(), vehicle.getId() ); } - double toll=0.; + + double toll = 0.; if ( costInfo != null ){ toll = costInfo.amount; } -// System.out.println("huuuuuuuuuuuuuuuuuuuu - paid toll"); return costs + toll; } @@ -408,7 +405,7 @@ public static Builder newInstance(Network network) { * Creates the builder requiring {@link Network} and a collection of * {@link VehicleType}. * - * @param network + * @param network the MATSim network * @param vehicleTypes must be all vehicleTypes and their assigned * costInformation in the system. */ @@ -429,7 +426,7 @@ private void retrieveTypeSpecificCosts(Collection vehicleTypes) { * Sets the travelTime. By default, travelTime is based on * link.getFreespeed();. * - * @param travelTime + * @param travelTime the travelTime to set * @return this builder */ public Builder setTravelTime(TravelTime travelTime) { @@ -478,7 +475,7 @@ public Builder setFIFO(boolean isFIFO) { *

* By default, it use {@link SpeedyALTFactory} * - * @param {@link {@link LeastCostPathCalculatorFactory} + * @param leastCostPathCalcFactory {@link LeastCostPathCalculatorFactory} * @return this builder */ public Builder setThreadSafeLeastCostPathCalculatorFactory( @@ -526,10 +523,10 @@ public NetworkBasedTransportCosts build() { * Adds type-specific costs. If typeId already exists, existing entry is * overwritten. * - * @param typeId - * @param fix - * @param perSecond - * @param perMeter + * @param typeId the vehicleType-id as String + * @param fix fix costs for the vehicle + * @param perSecond variable costs per second + * @param perMeter variable costs per meter */ public void addVehicleTypeSpecificCosts(String typeId, double fix, double perSecond, double perMeter) { typeSpecificCosts.put(typeId, new VehicleTypeVarCosts(perMeter, perSecond)); @@ -598,7 +595,7 @@ private NetworkBasedTransportCosts(Builder builder) { * cached travel-time. If not, it computes and caches new values with the * leastCostPathCalc defined in here. * - * @Throws {@link IllegalStateException} if vehicle is null + * @exception IllegalStateException if vehicle is null */ @Override public double getTransportTime(Location fromId, Location toId, double departureTime, Driver driver, @@ -679,7 +676,7 @@ private void informStartCalc() { * cached travel-cost value. If not, it computes and caches new values with the * leastCostPathCalc defined in here. * - * @Throws {@link IllegalStateException} if vehicle is null + * @exception IllegalStateException if vehicle is null */ @Override public double getTransportCost(Location fromId, Location toId, double departureTime, Driver driver, @@ -747,7 +744,7 @@ public double getTransportCost(Location fromId, Location toId, double departureT * cached distance. If not, it computes and caches new values with the * leastCostPathCalc defined in here. * - * @Throws {@link IllegalStateException} if vehicle is null + * @exception IllegalStateException if vehicle is null */ @Override public double getDistance(Location fromId, Location toId, double departureTime, Vehicle vehicle) { @@ -812,7 +809,7 @@ public Collection getInternalListeners( * This is a rather bad approximation. If you require this, you should implement * another {@link VehicleRoutingTransportCosts} * - * @Throws {@link IllegalStateException} if vehicle is null + * @exception IllegalStateException if vehicle is null */ @Override public double getBackwardTransportCost(Location fromId, Location toId, double arrivalTime, Driver driver, @@ -828,7 +825,7 @@ public double getBackwardTransportCost(Location fromId, Location toId, double ar * This is a rather bad approximation. If you require this, you should implement * another {@link VehicleRoutingTransportCosts}. * - * @Throws {@link IllegalStateException} if vehicle is null + * @exception IllegalStateException if vehicle is null */ @Override public double getBackwardTransportTime(Location fromId, Location toId, double arrivalTime, Driver driver, @@ -875,7 +872,7 @@ private int getTimeSlice(double time) { /** * Gets the network the calculation is based on. * - * @return + * @return the network */ public Network getNetwork() { return network; @@ -890,13 +887,4 @@ public TravelTime getTravelTime() { return travelTime; } - /** - * Gets the {@link VehicleTypeDependentRoadPricingCalculator} - * - * @return {@link VehicleTypeDependentRoadPricingCalculator} - */ -// public VehicleTypeDependentRoadPricingCalculator getRoadPricingCalculator() { -// return roadPricingCalc; -// } - } From 307c602ab7577fd5bcebb7fc7d9c285b8de70b67 Mon Sep 17 00:00:00 2001 From: Kai Martins-Turner Date: Tue, 6 Aug 2024 11:42:33 +0200 Subject: [PATCH 11/11] fix typos, internal renaming --- .../NetworkBasedTransportCostsTest.java | 49 +++++++++---------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java index 65b691b5737..64e7eeba641 100644 --- a/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java +++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/jsprit/NetworkBasedTransportCostsTest.java @@ -30,9 +30,7 @@ import org.matsim.api.core.v01.Coord; 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.api.core.v01.network.Network; -import org.matsim.api.core.v01.population.Person; import org.matsim.contrib.roadpricing.*; import org.matsim.core.config.Config; import org.matsim.core.network.io.MatsimNetworkReader; @@ -255,7 +253,7 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ } return tollFactor1; }; - RoadPricingScheme schemeUsingTollFactor = new RoadPricingSchemeUsingTollFactor( scheme , tollFactor ); + RoadPricingScheme rpSchemeWTollFactor = new RoadPricingSchemeUsingTollFactor( scheme , tollFactor ); /// End creating roadPricing scheme from Code @@ -287,11 +285,11 @@ void test_whenAddingTwoDifferentVehicleTypes_tollOneTypeTollFactor(){ vehicle2 = MatsimJspritFactory.createJspritVehicle(matsimVehicle2, new Coord()); } - //Build the NetbasedTransportCosts opbejct with the roadpricing scheme. + //Build the NetbasedTransportCosts object with the roadpricing scheme. NetworkBasedTransportCosts c = NetworkBasedTransportCosts.Builder.newInstance( scenario.getNetwork(), scenario.getVehicles().getVehicleTypes().values() ) - .setRoadPricingScheme(schemeUsingTollFactor) + .setRoadPricingScheme(rpSchemeWTollFactor) .build() ; //vehicle1: includes toll @@ -319,33 +317,30 @@ void test_whenAddingTwoDifferentVehicleTypes_tollBasedOnVehicleId(){ new MatsimNetworkReader(scenario.getNetwork()).readFile(utils.getClassInputDirectory() + "network.xml"); //Create Rp Scheme from code. - RoadPricingSchemeImpl scheme1 = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); + RoadPricingSchemeImpl scheme = RoadPricingUtils.addOrGetMutableRoadPricingScheme(scenario ); /* Configure roadpricing scheme. */ - RoadPricingUtils.setName(scheme1, "DemoToll4TestType1"); - RoadPricingUtils.setType(scheme1, RoadPricingScheme.TOLL_TYPE_LINK); - RoadPricingUtils.setDescription(scheme1, "Tolling scheme for test."); + RoadPricingUtils.setName(scheme, "DemoToll4TestType1"); + RoadPricingUtils.setType(scheme, RoadPricingScheme.TOLL_TYPE_LINK); + RoadPricingUtils.setDescription(scheme, "Tolling scheme for test."); /* Add general link based toll for one link */ - RoadPricingUtils.addLink(scheme1, Id.createLinkId("21")); - RoadPricingUtils.createAndAddGeneralCost(scheme1, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); - - //Use a factor to take into account the differnt types. type2 gehts tolled with 50% of the toll of type1 - TollFactor tollFactor = new TollFactor() { - @Override - public double getTollFactor(Id personId, Id vehicleId, Id linkId, double time) { - //No information about the vehicleType available anywhere, because is is nowhere registered centrally, - // -> Use the vehicleId to distinguish the types. - var vehTypeIdString = vehicleId.toString(); - if (vehTypeIdString.equals("vehicle1")) { - return 1; - } else if (vehTypeIdString.equals("vehicle2")) { - return 0.5; - } else { - return 0; - } + RoadPricingUtils.addLink(scheme, Id.createLinkId("21")); + RoadPricingUtils.createAndAddGeneralCost(scheme, Time.parseTime("00:00:00"), Time.parseTime("72:00:00"), 99.99); + + //Use a factor to take into account the different types. type2 gehts tolled with 50% of the toll of type1 + TollFactor tollFactor = (personId, vehicleId, linkId, time) -> { + //No information about the vehicleType available anywhere, because it is not registered centrally. + // -> Use the vehicleId to distinguish the types. + var vehTypeIdString = vehicleId.toString(); + if (vehTypeIdString.equals("vehicle1")) { + return 1; + } else if (vehTypeIdString.equals("vehicle2")) { + return 0.5; + } else { + return 0; } }; - RoadPricingSchemeUsingTollFactor rpSchemeWTollFactor = new RoadPricingSchemeUsingTollFactor( scheme1 , tollFactor ); + RoadPricingSchemeUsingTollFactor rpSchemeWTollFactor = new RoadPricingSchemeUsingTollFactor( scheme , tollFactor ); ///___ End creating toll scheme from code