diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
index 9ff85eb7b67..35f11ab09d6 100644
--- a/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
+++ b/contribs/application/src/main/java/org/matsim/application/analysis/population/TripAnalysis.java
@@ -92,6 +92,7 @@ public Integer call() throws Exception {
Table persons = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("persons.csv")))
.columnTypesPartial(Map.of("person", ColumnType.TEXT))
+ .sample(false)
.separator(';').build());
int total = persons.rowCount();
@@ -132,6 +133,7 @@ public Integer call() throws Exception {
Table trips = Table.read().csv(CsvReadOptions.builder(IOUtils.getBufferedReader(input.getPath("trips.csv")))
.columnTypesPartial(columnTypes)
+ .sample(false)
.separator(';').build());
diff --git a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java
index 59e3cf6d1a4..7b71a32670e 100644
--- a/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java
+++ b/contribs/discrete_mode_choice/src/test/java/org/matsim/contrib/discrete_mode_choice/examples/TestSiouxFalls.java
@@ -61,9 +61,9 @@ public void install() {
System.out.println((int) listener.counts.get("car"));
System.out.println(listener.counts.get("walk"));
- assertEquals(44195, (int) listener.counts.get("pt"));
- assertEquals(132316, (int) listener.counts.get("car"));
- assertEquals(82139, (int) listener.counts.get("walk"));
+ assertEquals(44195, listener.counts.get("pt"), 2);
+ assertEquals(132316, listener.counts.get("car"), 2);
+ assertEquals(82139, listener.counts.get("walk"), 2);
}
diff --git a/contribs/drt-extensions/pom.xml b/contribs/drt-extensions/pom.xml
index b56ab569782..2217f9ebdc7 100644
--- a/contribs/drt-extensions/pom.xml
+++ b/contribs/drt-extensions/pom.xml
@@ -24,6 +24,12 @@
16.0-SNAPSHOT
+
+ org.matsim.contrib
+ informed-mode-choice
+ 16.0-SNAPSHOT
+
+
org.matsim.contrib
simwrapper
@@ -33,6 +39,7 @@
org.assertj
assertj-core
+ test
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java
index 6239ca5a240..d84aa00e156 100644
--- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/edrt/run/EDrtModeOptimizerQSimModule.java
@@ -60,7 +60,7 @@
import org.matsim.contrib.dvrp.schedule.ScheduleTimingUpdater;
import org.matsim.contrib.dvrp.vrpagent.VrpAgentLogic;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
-import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures;
+import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.mobsim.framework.MobsimTimer;
import org.matsim.core.modal.ModalProviders;
@@ -95,8 +95,8 @@ protected void configureQSim() {
getter.getModal(DrtRequestInsertionRetryQueue.class)))).asEagerSingleton();
bindModal(ChargingInfrastructure.class).toProvider(modalProvider(
- getter -> ChargingInfrastructures.createModalNetworkChargers(getter.get(ChargingInfrastructure.class),
- getter.getModal(Network.class), getMode()))).asEagerSingleton();
+ getter -> ChargingInfrastructureUtils.createModalNetworkChargers(getter.get(ChargingInfrastructure.class ),
+ getter.getModal(Network.class), getMode() ))).asEagerSingleton();
// XXX if overridden to something else, make sure that the depots are equipped with chargers
// otherwise vehicles will not re-charge
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/BasicDrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/BasicDrtEstimator.java
new file mode 100644
index 00000000000..3d7555020e1
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/BasicDrtEstimator.java
@@ -0,0 +1,172 @@
+package org.matsim.contrib.drt.extension.estimator;
+
+import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
+import org.apache.commons.math3.stat.regression.RegressionResults;
+import org.apache.commons.math3.stat.regression.SimpleRegression;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.events.PersonMoneyEvent;
+import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
+import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup;
+import org.matsim.contrib.drt.fare.DrtFareParams;
+import org.matsim.contrib.drt.routing.DrtRoute;
+import org.matsim.contrib.drt.run.DrtConfigGroup;
+import org.matsim.contrib.drt.speedup.DrtSpeedUp;
+import org.matsim.core.controler.events.IterationEndsEvent;
+import org.matsim.core.controler.listener.IterationEndsListener;
+import org.matsim.core.utils.misc.OptionalTime;
+
+import java.util.SplittableRandom;
+
+/**
+ * Estimates drt trips based only daily averages. No spatial or temporal differentiation is taken into account for the estimate.
+ * This estimator is suited for small scenarios with few vehicles and trips and consequently few data points.
+ */
+public class BasicDrtEstimator implements DrtEstimator, IterationEndsListener {
+
+ private static final Logger log = LogManager.getLogger(BasicDrtEstimator.class);
+
+ private final DrtEventSequenceCollector collector;
+ private final DrtEstimatorConfigGroup config;
+ private final DrtConfigGroup drtConfig;
+
+ private final SplittableRandom rnd = new SplittableRandom();
+ /**
+ * Currently valid estimates.
+ */
+ private GlobalEstimate currentEst;
+ private RegressionResults fare;
+
+ public BasicDrtEstimator(DrtEventSequenceCollector collector, DrtEstimatorConfigGroup config,
+ DrtConfigGroup drtConfig) {
+ //zones = injector.getModal(DrtZonalSystem.class);
+ this.collector = collector;
+ this.config = config;
+ this.drtConfig = drtConfig;
+ }
+
+ @Override
+ public void notifyIterationEnds(IterationEndsEvent event) {
+
+ // Speed-up iteration need to be ignored for the estimates
+ if (drtConfig.getDrtSpeedUpParams().isPresent() &&
+ DrtSpeedUp.isTeleportDrtUsers(drtConfig.getDrtSpeedUpParams().get(),
+ event.getServices().getConfig().controller(), event.getIteration())) {
+ return;
+ }
+
+ GlobalEstimate est = new GlobalEstimate();
+
+ int n = 0;
+
+ int nRejections = collector.getRejectedRequestSequences().size();
+ int nSubmitted = collector.getRequestSubmissions().size();
+
+ for (DrtEventSequenceCollector.EventSequence seq : collector.getPerformedRequestSequences().values()) {
+
+ if (seq.getPickedUp().isPresent() && seq.getDroppedOff().isPresent()) {
+
+ double waitTime = seq.getPickedUp().get().getTime() - seq.getSubmitted().getTime();
+ est.waitTime.addValue(waitTime);
+
+ double unsharedTime = seq.getSubmitted().getUnsharedRideTime();
+ double travelTime = seq.getDroppedOff().get().getTime() - seq.getPickedUp().get().getTime();
+
+ est.detour.addValue(travelTime / unsharedTime);
+
+ double fare = seq.getDrtFares().stream().mapToDouble(PersonMoneyEvent::getAmount).sum();
+ est.fare.addData(seq.getSubmitted().getUnsharedRideDistance(), fare);
+ n++;
+ }
+ }
+
+ // At least some data points are required
+ if (n <= 3)
+ return;
+
+ fare = est.fare.regress();
+
+ double rejectionRate = (double) nRejections / nSubmitted;
+
+ if (currentEst == null) {
+ est.meanWait = est.waitTime.getMean();
+ est.stdWait = est.waitTime.getStandardDeviation();
+ est.meanDetour = est.detour.getMean();
+ est.stdDetour = est.detour.getStandardDeviation();
+ est.rejectionRate = rejectionRate;
+ } else {
+ est.meanWait = config.decayFactor * est.waitTime.getMean() + (1 - config.decayFactor) * currentEst.waitTime.getMean();
+ est.stdWait = config.decayFactor * est.waitTime.getStandardDeviation() + (1 - config.decayFactor) * currentEst.waitTime.getStandardDeviation();
+ est.meanDetour = config.decayFactor * est.detour.getMean() + (1 - config.decayFactor) * currentEst.detour.getMean();
+ est.stdDetour = config.decayFactor * est.detour.getStandardDeviation() + (1 - config.decayFactor) * currentEst.detour.getStandardDeviation();
+ est.rejectionRate = config.decayFactor * rejectionRate + (1 - config.decayFactor) * currentEst.rejectionRate;
+ }
+
+ log.info("Calculated {}", est);
+ currentEst = est;
+ }
+
+ @Override
+ public Estimate estimate(DrtRoute route, OptionalTime departureTime) {
+
+ if (currentEst == null) {
+ // If not estimates are present, use travel time alpha as detour
+ // beta is not used, because estimates are supposed to be minimums and not worst cases
+ double travelTime = Math.min(route.getDirectRideTime() + drtConfig.maxAbsoluteDetour,
+ route.getDirectRideTime() * drtConfig.maxTravelTimeAlpha);
+
+ double fare = 0;
+ if (drtConfig.getDrtFareParams().isPresent()) {
+ DrtFareParams fareParams = drtConfig.getDrtFareParams().get();
+ fare = fareParams.distanceFare_m * route.getDistance()
+ + fareParams.timeFare_h * route.getDirectRideTime() / 3600.0
+ + fareParams.baseFare;
+
+ fare = Math.max(fare, fareParams.minFarePerTrip);
+ }
+
+ // for distance, also use the max travel time alpha
+ return new Estimate(route.getDistance() * drtConfig.maxTravelTimeAlpha, travelTime, drtConfig.maxWaitTime, fare, 0);
+ }
+
+ double fare = 0;
+ if (this.fare != null)
+ fare = this.fare.getParameterEstimate(0) + this.fare.getParameterEstimate(1) * route.getDistance();
+
+ if (drtConfig.getDrtFareParams().isPresent()) {
+ fare = Math.max(fare, drtConfig.getDrtFareParams().get().minFarePerTrip);
+ }
+
+ double detour = Math.max(1, rnd.nextGaussian(currentEst.meanDetour, config.randomization * currentEst.stdDetour));
+ double waitTime = Math.max(0, rnd.nextGaussian(currentEst.meanWait, config.randomization * currentEst.stdWait));
+
+ return new Estimate(route.getDistance() * detour, route.getDirectRideTime() * detour, waitTime, fare, currentEst.rejectionRate);
+ }
+
+ /**
+ * Helper class to hold statistics.
+ */
+ private static final class GlobalEstimate {
+
+ private final SummaryStatistics waitTime = new SummaryStatistics();
+ private final SummaryStatistics detour = new SummaryStatistics();
+ private final SimpleRegression fare = new SimpleRegression(true);
+
+ private double meanWait;
+ private double stdWait;
+ private double meanDetour;
+ private double stdDetour;
+ private double rejectionRate;
+
+ @Override
+ public String toString() {
+ return "GlobalEstimate{" +
+ "meanWait=" + meanWait +
+ ", stdWait=" + stdWait +
+ ", meanDetour=" + meanDetour +
+ ", stdDetour=" + stdDetour +
+ ", rejectionRate=" + rejectionRate +
+ '}';
+ }
+ }
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java
new file mode 100644
index 00000000000..2d87f7ea7b8
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimateAnalyzer.java
@@ -0,0 +1,126 @@
+package org.matsim.contrib.drt.extension.estimator;
+
+import org.apache.commons.csv.CSVFormat;
+import org.apache.commons.csv.CSVPrinter;
+import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.events.PersonMoneyEvent;
+import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
+import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup;
+import org.matsim.contrib.drt.routing.DrtRoute;
+import org.matsim.core.controler.events.AfterMobsimEvent;
+import org.matsim.core.controler.events.ShutdownEvent;
+import org.matsim.core.controler.events.StartupEvent;
+import org.matsim.core.controler.listener.AfterMobsimListener;
+import org.matsim.core.controler.listener.ShutdownListener;
+import org.matsim.core.controler.listener.StartupListener;
+import org.matsim.core.utils.misc.OptionalTime;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+
+/**
+ * Analyzes and outputs drt estimates errors metrics based on daily requests.
+ */
+public final class DrtEstimateAnalyzer implements StartupListener, ShutdownListener, AfterMobsimListener {
+
+ private static final Logger log = LogManager.getLogger(DrtEstimateAnalyzer.class);
+
+ // Might be useful but not needed currently
+ //private final DefaultMainLegRouter.RouteCreator creator;
+ private final DrtEstimator estimator;
+ private final DrtEventSequenceCollector collector;
+ private final DrtEstimatorConfigGroup config;
+
+ private CSVPrinter csv;
+
+ public DrtEstimateAnalyzer(DrtEstimator estimator, DrtEventSequenceCollector collector, DrtEstimatorConfigGroup config) {
+ this.estimator = estimator;
+ this.collector = collector;
+ this.config = config;
+ }
+
+ @Override
+ public void notifyStartup(StartupEvent event) {
+
+ String filename = event.getServices().getControlerIO().getOutputFilename("drt_estimates_" + config.getMode() + ".csv");
+
+ try {
+ csv = new CSVPrinter(Files.newBufferedWriter(Path.of(filename), StandardCharsets.UTF_8), CSVFormat.DEFAULT);
+ csv.printRecord("iteration",
+ "wait_time_mae", "wait_time_err_q5", "wait_time_err_q50", "wait_time_err_q95",
+ "travel_time_mae", "travel_time_err_q5", "travel_time_err_q50", "travel_time_err_q95",
+ "fare_mae", "fare_err_q5", "fare_err_q50", "fare_err_q95"
+ );
+
+ } catch (IOException e) {
+ throw new UncheckedIOException("Could not open output file for estimates.", e);
+ }
+ }
+
+ @Override
+ public void notifyShutdown(ShutdownEvent event) {
+ try {
+ csv.close();
+ } catch (IOException e) {
+ log.warn("Could not close drt estimate file", e);
+ }
+ }
+
+ /**
+ * Needs to run before any estimators updates.
+ */
+ @Override
+ public void notifyAfterMobsim(AfterMobsimEvent event) {
+
+ try {
+ csv.printRecord(calcMetrics(event.getIteration()));
+ csv.flush();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Return row of metrics for the csv file.
+ */
+ private Iterable calcMetrics(int iteration) {
+
+ DescriptiveStatistics waitTime = new DescriptiveStatistics();
+ DescriptiveStatistics travelTime = new DescriptiveStatistics();
+ DescriptiveStatistics fare = new DescriptiveStatistics();
+
+ for (DrtEventSequenceCollector.EventSequence seq : collector.getPerformedRequestSequences().values()) {
+ if (seq.getPickedUp().isPresent() && seq.getDroppedOff().isPresent()) {
+
+ // many attributes are not filled, when using the constructor
+ DrtRoute route = new DrtRoute(seq.getSubmitted().getFromLinkId(), seq.getSubmitted().getToLinkId());
+ route.setDirectRideTime(seq.getSubmitted().getUnsharedRideTime());
+ route.setDistance(seq.getSubmitted().getUnsharedRideDistance());
+
+ double valWaitTime = seq.getPickedUp().get().getTime() - seq.getSubmitted().getTime();
+ double valTravelTime = seq.getDroppedOff().get().getTime() - seq.getPickedUp().get().getTime();
+ double valFare = seq.getDrtFares().stream().mapToDouble(PersonMoneyEvent::getAmount).sum();
+
+ DrtEstimator.Estimate estimate = estimator.estimate(route, OptionalTime.defined(seq.getSubmitted().getTime()));
+
+ waitTime.addValue(Math.abs(estimate.waitingTime() - valWaitTime));
+ travelTime.addValue(Math.abs(estimate.travelTime() - valTravelTime));
+ fare.addValue(Math.abs(estimate.fare() - valFare));
+ }
+ }
+
+ return List.of(
+ iteration,
+ waitTime.getMean(), waitTime.getPercentile(5), waitTime.getPercentile(50), waitTime.getPercentile(95),
+ travelTime.getMean(), travelTime.getPercentile(5), travelTime.getPercentile(50), travelTime.getPercentile(95),
+ fare.getMean(), fare.getPercentile(5), fare.getPercentile(50), fare.getPercentile(95)
+ );
+ }
+
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java
new file mode 100644
index 00000000000..fef209ed211
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/DrtEstimator.java
@@ -0,0 +1,35 @@
+package org.matsim.contrib.drt.extension.estimator;
+
+import org.matsim.contrib.drt.routing.DrtRoute;
+import org.matsim.core.controler.listener.ControlerListener;
+import org.matsim.core.utils.misc.OptionalTime;
+
+/**
+ * Interface to estimate a DRT service's detour, waiting time and costs.
+ */
+public interface DrtEstimator extends ControlerListener {
+
+ /**
+ * Provide an estimate for a drt route with specific pickup and dropoff point.
+ *
+ * @param route drt route
+ * @param departureTime estimated departure time
+ * @return An {@link Estimate} instance
+ */
+ Estimate estimate(DrtRoute route, OptionalTime departureTime);
+
+
+ /**
+ * Estimate for various attributes for a drt trip.
+ *
+ * @param distance travel distance in meter
+ * @param travelTime travel time in seconds
+ * @param waitingTime waiting time in seconds
+ * @param fare money, which is negative if the customer needs to pay it
+ * @param rejectionRate probability of a trip being rejected
+ */
+ record Estimate(double distance, double travelTime, double waitingTime, double fare, double rejectionRate) {
+
+ }
+
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java
new file mode 100644
index 00000000000..ed1771ae34f
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimator.java
@@ -0,0 +1,58 @@
+package org.matsim.contrib.drt.extension.estimator;
+
+import com.google.inject.Inject;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.population.Leg;
+import org.matsim.contrib.drt.routing.DrtRoute;
+import org.matsim.contrib.dvrp.run.DvrpMode;
+import org.matsim.core.scoring.functions.ModeUtilityParameters;
+import org.matsim.core.utils.misc.OptionalTime;
+import org.matsim.modechoice.EstimatorContext;
+import org.matsim.modechoice.ModeAvailability;
+import org.matsim.modechoice.estimators.LegEstimator;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * Aggregate class for informed-mode-choice that makes sure to invoke the correct estimator for each drt mode.
+ */
+public class MultiModalDrtLegEstimator implements LegEstimator {
+
+ private static final Logger log = LogManager.getLogger(MultiModalDrtLegEstimator.class);
+
+ protected final Map estimators = new HashMap<>();
+
+ @Inject
+ public MultiModalDrtLegEstimator(Map estimators) {
+ for (Map.Entry e : estimators.entrySet()) {
+ this.estimators.put(e.getKey().value(), e.getValue());
+ }
+ }
+
+ @Override
+ public double estimate(EstimatorContext context, String mode, Leg leg, ModeAvailability option) {
+
+ if (!(leg.getRoute() instanceof DrtRoute route))
+ throw new IllegalStateException("Drt leg routes must be of type DrtRoute.");
+
+ OptionalTime departureTime = leg.getDepartureTime();
+
+ DrtEstimator estimator = Objects.requireNonNull(estimators.get(mode), String.format("No drt estimator found for mode %s. Check warnings for errors.", mode));
+
+ DrtEstimator.Estimate est = estimator.estimate(route, departureTime);
+ ModeUtilityParameters params = context.scoring.modeParams.get(mode);
+
+ // By default, waiting time is scored as travel time
+ return params.constant +
+ params.marginalUtilityOfDistance_m * est.distance() +
+ params.marginalUtilityOfTraveling_s * est.travelTime() +
+ params.marginalUtilityOfTraveling_s * est.waitingTime() +
+ context.scoring.marginalUtilityOfMoney * params.monetaryDistanceCostRate * est.distance() +
+ context.scoring.marginalUtilityOfMoney * est.fare();
+
+ }
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java
new file mode 100644
index 00000000000..107aa2eb53a
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorConfigGroup.java
@@ -0,0 +1,61 @@
+package org.matsim.contrib.drt.extension.estimator.run;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import jakarta.validation.constraints.PositiveOrZero;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.contrib.dvrp.run.Modal;
+import org.matsim.contrib.util.ReflectiveConfigGroupWithConfigurableParameterSets;
+
+public class DrtEstimatorConfigGroup extends ReflectiveConfigGroupWithConfigurableParameterSets implements Modal {
+
+ /**
+ * Type of estimator, which will be installed in {@link DrtEstimatorModule}.
+ */
+ public enum EstimatorType {
+ BASIC,
+
+ /**
+ * Custom estimator, that needs to provided via binding.
+ */
+ CUSTOM
+ }
+
+ public static final String GROUP_NAME = "drtEstimator";
+
+ public DrtEstimatorConfigGroup() {
+ super(GROUP_NAME);
+ }
+
+ public DrtEstimatorConfigGroup(String mode) {
+ super(GROUP_NAME);
+ this.mode = mode;
+ }
+
+ @Parameter
+ @Comment("Mode of the drt service to estimate.")
+ @NotBlank
+ public String mode = TransportMode.drt;
+
+ @Parameter
+ @Comment("Estimator typed to be used. In case of 'CUSTOM', guice bindings needs to be provided.")
+ @NotNull
+ public EstimatorType estimator = EstimatorType.BASIC;
+
+ @Parameter
+ @Comment("Decay of the exponential moving average.")
+ @Positive
+ public double decayFactor = 0.7;
+
+ @Parameter
+ @Comment("Factor multiplied with standard deviation to randomize estimates.")
+ @PositiveOrZero
+ public double randomization = 0.1;
+
+ @Override
+ public String getMode() {
+ return mode;
+ }
+
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java
new file mode 100644
index 00000000000..14bc2ae330d
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/DrtEstimatorModule.java
@@ -0,0 +1,80 @@
+package org.matsim.contrib.drt.extension.estimator.run;
+
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.MapBinder;
+import org.matsim.contrib.drt.analysis.DrtEventSequenceCollector;
+import org.matsim.contrib.drt.extension.estimator.BasicDrtEstimator;
+import org.matsim.contrib.drt.extension.estimator.DrtEstimateAnalyzer;
+import org.matsim.contrib.drt.extension.estimator.DrtEstimator;
+import org.matsim.contrib.drt.run.DrtConfigGroup;
+import org.matsim.contrib.drt.run.MultiModeDrtConfigGroup;
+import org.matsim.contrib.dvrp.run.AbstractDvrpModeModule;
+import org.matsim.contrib.dvrp.run.DvrpMode;
+import org.matsim.contrib.dvrp.run.DvrpModes;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.controler.AbstractModule;
+
+import java.util.Optional;
+
+/**
+ * Main module that needs to be installed if any estimator is to be used.
+ */
+public class DrtEstimatorModule extends AbstractModule {
+
+ @Override
+ public void install() {
+
+ MultiModeDrtConfigGroup drtConfigs = MultiModeDrtConfigGroup.get(getConfig());
+ MultiModeDrtEstimatorConfigGroup configs = ConfigUtils.addOrGetModule(getConfig(), MultiModeDrtEstimatorConfigGroup.class);
+
+ for (DrtConfigGroup cfg : drtConfigs.getModalElements()) {
+
+ Optional estCfg = configs.getModalElement(cfg.mode);
+
+ estCfg.ifPresent(drtEstimatorConfigGroup -> install(new ModeModule(cfg, drtEstimatorConfigGroup)));
+ }
+ }
+
+ static final class ModeModule extends AbstractDvrpModeModule {
+
+ private final DrtConfigGroup cfg;
+ private final DrtEstimatorConfigGroup group;
+
+ public ModeModule(DrtConfigGroup cfg, DrtEstimatorConfigGroup group) {
+ super(group.mode);
+ this.cfg = cfg;
+ this.group = group;
+ }
+
+ @Override
+ public void install() {
+
+ // try with default injections and overwrite
+ if (group.estimator == DrtEstimatorConfigGroup.EstimatorType.BASIC) {
+ bindModal(DrtEstimator.class).toProvider(modalProvider(
+ getter -> new BasicDrtEstimator(getter.getModal(DrtEventSequenceCollector.class), group, cfg)
+ )).in(Singleton.class);
+ }
+
+ // DRT Estimators will be available as Map
+ MapBinder.newMapBinder(this.binder(), DvrpMode.class, DrtEstimator.class)
+ .addBinding(DvrpModes.mode(getMode()))
+ .to(modalKey(DrtEstimator.class));
+
+ addControlerListenerBinding().to(modalKey(DrtEstimator.class));
+
+ bindModal(DrtEstimatorConfigGroup.class).toInstance(group);
+
+ // Needs to run before estimators
+ bindModal(DrtEstimateAnalyzer.class)
+ .toProvider(
+ modalProvider(getter -> new DrtEstimateAnalyzer(getter.getModal(DrtEstimator.class), getter.getModal(DrtEventSequenceCollector.class), group))
+ )
+ .in(Singleton.class);
+
+ addControlerListenerBinding().to(modalKey(DrtEstimateAnalyzer.class));
+
+ }
+
+ }
+}
diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java
new file mode 100644
index 00000000000..b998bf78648
--- /dev/null
+++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/estimator/run/MultiModeDrtEstimatorConfigGroup.java
@@ -0,0 +1,103 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2018 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** *
+ */
+
+package org.matsim.contrib.drt.extension.estimator.run;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.Supplier;
+
+import org.matsim.contrib.dvrp.run.MultiModal;
+import org.matsim.contrib.dvrp.run.MultiModals;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigGroup;
+import org.matsim.core.config.ReflectiveConfigGroup;
+
+import com.google.common.base.Verify;
+
+/**
+ * @author Michal Maciejewski (michalm)
+ */
+public final class MultiModeDrtEstimatorConfigGroup extends ReflectiveConfigGroup implements MultiModal {
+ public static final String GROUP_NAME = "drtEstimators";
+
+ /**
+ * @param config
+ * @return MultiModeDrtConfigGroup if exists. Otherwise fails
+ */
+ public static MultiModeDrtEstimatorConfigGroup get(Config config) {
+ return (MultiModeDrtEstimatorConfigGroup)config.getModule(GROUP_NAME);
+ }
+
+ private final Supplier drtConfigSupplier;
+
+ public MultiModeDrtEstimatorConfigGroup() {
+ this(DrtEstimatorConfigGroup::new);
+ }
+
+ public MultiModeDrtEstimatorConfigGroup(Supplier drtConfigSupplier) {
+ super(GROUP_NAME);
+ this.drtConfigSupplier = drtConfigSupplier;
+ }
+
+ @Override
+ protected void checkConsistency(Config config) {
+ super.checkConsistency(config);
+ Verify.verify(config.getModule(DrtEstimatorConfigGroup.GROUP_NAME) == null,
+ "In the multi-mode DRT setup, DrtEstimatorConfigGroup must not be defined at the config top level");
+ MultiModals.requireAllModesUnique(this);
+ }
+
+ @Override
+ public ConfigGroup createParameterSet(String type) {
+ if (type.equals(DrtEstimatorConfigGroup.GROUP_NAME)) {
+ return drtConfigSupplier.get();
+ } else {
+ throw new IllegalArgumentException("Unsupported parameter set type: " + type);
+ }
+ }
+
+ @Override
+ public void addParameterSet(ConfigGroup set) {
+ if (set instanceof DrtEstimatorConfigGroup) {
+ super.addParameterSet(set);
+ } else {
+ throw new IllegalArgumentException("Unsupported parameter set class: " + set);
+ }
+ }
+
+ public void addParameterSet(DrtEstimatorConfigGroup set) {
+ addParameterSet((ConfigGroup) set);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Collection getModalElements() {
+ return (Collection)getParameterSets(DrtEstimatorConfigGroup.GROUP_NAME);
+ }
+
+ /**
+ * Find estimator config for specific mode.
+ */
+ public Optional getModalElement(String mode) {
+ return getModalElements().stream().filter(m -> m.getMode().equals(mode)).findFirst();
+ }
+
+}
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java
index db01301303c..7131c33a368 100644
--- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/DrtTestScenario.java
@@ -24,12 +24,14 @@
import org.matsim.core.utils.io.IOUtils;
import org.matsim.examples.ExamplesUtils;
import org.matsim.simwrapper.SimWrapperModule;
+import org.matsim.modechoice.InformedModeChoiceConfigGroup;
import org.matsim.testcases.MatsimTestUtils;
import org.matsim.vehicles.VehicleType;
import javax.annotation.Nullable;
import java.net.URL;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
@@ -82,6 +84,8 @@ protected Config prepareConfig(Config config) {
config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_start").setTypicalDuration(60 * 15));
config.scoring().addActivityParams(new ScoringConfigGroup.ActivityParams("freight_end").setTypicalDuration(60 * 15));
+ InformedModeChoiceConfigGroup imc = ConfigUtils.addOrGetModule(config, InformedModeChoiceConfigGroup.class);
+ imc.setModes(Set.of("drt", "av", "car", "pt", "bike", "walk"));
MultiModeDrtConfigGroup multiModeDrtConfig = ConfigUtils.addOrGetModule(config, MultiModeDrtConfigGroup.class);
ConfigUtils.addOrGetModule(config, DvrpConfigGroup.class);
diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java
new file mode 100644
index 00000000000..8d61ef68123
--- /dev/null
+++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/estimator/MultiModalDrtLegEstimatorTest.java
@@ -0,0 +1,90 @@
+package org.matsim.contrib.drt.extension.estimator;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.matsim.application.MATSimApplication;
+import org.matsim.contrib.drt.extension.DrtTestScenario;
+import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorConfigGroup;
+import org.matsim.contrib.drt.extension.estimator.run.DrtEstimatorModule;
+import org.matsim.contrib.drt.extension.estimator.run.MultiModeDrtEstimatorConfigGroup;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.config.groups.ReplanningConfigGroup;
+import org.matsim.core.controler.Controler;
+import org.matsim.modechoice.InformedModeChoiceModule;
+import org.matsim.modechoice.ModeOptions;
+import org.matsim.modechoice.estimators.DefaultLegScoreEstimator;
+import org.matsim.modechoice.estimators.FixedCostsEstimator;
+import org.matsim.testcases.MatsimTestUtils;
+
+import java.io.File;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MultiModalDrtLegEstimatorTest {
+
+ @Rule
+ public MatsimTestUtils utils = new MatsimTestUtils();
+
+ private Controler controler;
+
+ @Before
+ public void setUp() throws Exception {
+
+ Config config = DrtTestScenario.loadConfig(utils);
+
+ config.controller().setLastIteration(3);
+
+ controler = MATSimApplication.prepare(new DrtTestScenario(MultiModalDrtLegEstimatorTest::prepare, MultiModalDrtLegEstimatorTest::prepare), config);
+ }
+
+ private static void prepare(Controler controler) {
+ InformedModeChoiceModule.Builder builder = InformedModeChoiceModule.newBuilder()
+ .withFixedCosts(FixedCostsEstimator.DailyConstant.class, "car")
+ .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.AlwaysAvailable.class, "bike", "walk", "pt")
+ .withLegEstimator(DefaultLegScoreEstimator.class, ModeOptions.ConsiderYesAndNo.class, "car")
+ .withLegEstimator(MultiModalDrtLegEstimator.class, ModeOptions.AlwaysAvailable.class, "drt", "av");
+
+ controler.addOverridingModule(builder.build());
+ controler.addOverridingModule(new DrtEstimatorModule());
+ }
+
+ private static void prepare(Config config) {
+
+ MultiModeDrtEstimatorConfigGroup estimators = ConfigUtils.addOrGetModule(config, MultiModeDrtEstimatorConfigGroup.class);
+
+ estimators.addParameterSet(new DrtEstimatorConfigGroup("drt"));
+ estimators.addParameterSet(new DrtEstimatorConfigGroup("av"));
+
+ // Set subtour mode selection as strategy
+ List strategies = config.replanning().getStrategySettings().stream()
+ .filter(s -> !s.getStrategyName().toLowerCase().contains("mode")
+ ).collect(Collectors.toList());
+
+ strategies.add(new ReplanningConfigGroup.StrategySettings()
+ .setStrategyName(InformedModeChoiceModule.SELECT_SUBTOUR_MODE_STRATEGY)
+ .setSubpopulation("person")
+ .setWeight(0.2));
+
+ config.replanning().clearStrategySettings();
+ strategies.forEach(s -> config.replanning().addStrategySettings(s));
+
+ }
+
+ @Test
+ public void run() {
+
+ String out = utils.getOutputDirectory();
+
+ controler.run();
+
+ assertThat(new File(out, "kelheim-mini-drt.drt_estimates_drt.csv"))
+ .exists()
+ .isNotEmpty();
+
+
+ }
+}
diff --git a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java
index 7935a2403e8..eca53f0c0d7 100644
--- a/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java
+++ b/contribs/drt/src/main/java/org/matsim/contrib/drt/speedup/DrtTeleportedRouteCalculator.java
@@ -40,6 +40,12 @@ public class DrtTeleportedRouteCalculator implements TeleportedRouteCalculator {
this.averageInVehicleBeelineSpeed = averageInVehicleBeelineSpeed;
}
+ // TODO: from discussion from michal and rakow
+ // speedup is currently using very simple and not exchangeable estimators
+ // it could be possible to integrate the drt estimators used by the informed mode-choice
+ // this router should probably not use the beeline distance but the direct travel route
+ // speed-up would still be significant (oct'23)
+
@Override
public Route calculateRoute(PassengerRequest request) {
Link startLink = request.getFromLink();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java
index 81f6682c3ff..4a2655a5ccf 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/charging/VehicleChargingHandler.java
@@ -42,7 +42,7 @@
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.contrib.ev.infrastructure.Charger;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
-import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures;
+import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils;
import org.matsim.core.config.groups.ScoringConfigGroup;
import org.matsim.core.events.MobsimScopeEventHandler;
import org.matsim.vehicles.Vehicle;
@@ -73,7 +73,7 @@ public class VehicleChargingHandler
VehicleChargingHandler(ChargingInfrastructure chargingInfrastructure, ElectricFleet electricFleet) {
this.chargingInfrastructure = chargingInfrastructure;
this.electricFleet = electricFleet;
- chargersAtLinks = ChargingInfrastructures.getChargersAtLinks(chargingInfrastructure);
+ chargersAtLinks = ChargingInfrastructureUtils.getChargersAtLinks(chargingInfrastructure );
}
/**
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java
index c36f95635a9..96078d1eab1 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DischargingModule.java
@@ -29,7 +29,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class DischargingModule extends AbstractModule {
+public final class DischargingModule extends AbstractModule {
@Override
public void install() {
bind(DriveEnergyConsumption.Factory.class).toInstance(ev -> new OhdeSlaskiDriveEnergyConsumption());
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java
index eae4a115384..ca8508a0e74 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DriveDischargingHandler.java
@@ -44,7 +44,7 @@
* calculating the drive-related energy consumption. However, the time spent on the first link is used by the time-based
* idle discharge process (see {@link IdleDischargingHandler}).
*/
-public class DriveDischargingHandler
+public final class DriveDischargingHandler
implements LinkLeaveEventHandler, VehicleEntersTrafficEventHandler, VehicleLeavesTrafficEventHandler, MobsimScopeEventHandler {
private static class EvDrive {
private final Id vehicleId;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java
index f00009b3e7a..3289446a72e 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/DrivingEnergyConsumptionEvent.java
@@ -27,7 +27,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class DrivingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent {
+public final class DrivingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent {
public static final String EVENT_TYPE = "drivingEnergyConsumption";
public DrivingEnergyConsumptionEvent(double time, Id vehicleId, Id linkId, double energy, double endCharge) {
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java
index da6fab88948..20a90c08e13 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdleDischargingHandler.java
@@ -45,7 +45,7 @@
* VehicleProvider is responsible to decide if AUX discharging applies to a given vehicle based on information from
* ActivityStartEvent.
*/
-public class IdleDischargingHandler
+public final class IdleDischargingHandler
implements MobsimAfterSimStepListener, ActivityStartEventHandler, ActivityEndEventHandler, MobsimScopeEventHandler {
public interface VehicleProvider {
/**
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java
index d992dc363f5..fcb625ad7b6 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/IdlingEnergyConsumptionEvent.java
@@ -27,7 +27,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class IdlingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent {
+public final class IdlingEnergyConsumptionEvent extends AbstractEnergyConsumptionEvent {
public static final String EVENT_TYPE = "idlingEnergyConsumption";
public IdlingEnergyConsumptionEvent(double time, Id vehicleId, Id linkId, double energy, double endCharge) {
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java
index afc8d17d93a..ea20f84a484 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/LTHDriveEnergyConsumption.java
@@ -32,7 +32,7 @@
import com.google.common.primitives.Doubles;
-public class LTHDriveEnergyConsumption implements DriveEnergyConsumption {
+public final class LTHDriveEnergyConsumption implements DriveEnergyConsumption {
private final PiecewiseBicubicSplineInterpolatingFunction function;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java
index a85c043522d..ef120c09fa9 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/MissingEnergyEvent.java
@@ -26,7 +26,7 @@
import org.matsim.api.core.v01.network.Link;
import org.matsim.vehicles.Vehicle;
-public class MissingEnergyEvent extends Event {
+public final class MissingEnergyEvent extends Event {
public static final String EVENT_TYPE = "missing_energy";
public static final String ATTRIBUTE_VEHICLE = "vehicle";
public static final String ATTRIBUTE_ENERGY = "energy";
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java
index 39d93db41c0..b344474bf9d 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiAuxEnergyConsumption.java
@@ -27,7 +27,7 @@
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
-public class OhdeSlaskiAuxEnergyConsumption implements AuxEnergyConsumption {
+public final class OhdeSlaskiAuxEnergyConsumption implements AuxEnergyConsumption {
private static final double a = 1.3;// [W]
private static final double b = -63.4;// [W]
private static final double c = 1748.1;// [W]
@@ -46,7 +46,7 @@ private static double calcPower(double temp) {
private final TemperatureService temperatureService;
- public OhdeSlaskiAuxEnergyConsumption(TemperatureService temperatureService) {
+ OhdeSlaskiAuxEnergyConsumption(TemperatureService temperatureService) {
this.temperatureService = temperatureService;
}
@@ -59,7 +59,7 @@ public static class Factory implements AuxEnergyConsumption.Factory {
private final TemperatureService temperatureService;
@Inject
- public Factory(TemperatureService temperatureService) {
+ Factory(TemperatureService temperatureService) {
this.temperatureService = temperatureService;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java
index dafad6d76d1..44b62145719 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/OhdeSlaskiDriveEnergyConsumption.java
@@ -30,7 +30,7 @@
* https://www.researchgate.net/profile/Michal-Maciejewski-3/publication/312393169_Statistical_analysis_of_real-world_urban_driving_cycles_for_modelling_energy_consumption_of_electric_vehicles/links/59b7a17faca2722453a5fc7f/Statistical-analysis-of-real-world-urban-driving-cycles-for-modelling-energy-consumption-of-electric-vehicles.pdf
* TODO Add (dis-)charging efficiency relative to SOC, temperature, etc...
*/
-public class OhdeSlaskiDriveEnergyConsumption implements DriveEnergyConsumption {
+public final class OhdeSlaskiDriveEnergyConsumption implements DriveEnergyConsumption {
private static final double g = 9.81; // g [m/s^2]
private static final double m = 1525; // vehicle mass [kg]
private static final double m_s = m + 100; // vehicle mass + extra mass [kg]
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java
index b905a6f881e..4310d786b80 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/discharging/VehicleTypeSpecificDriveEnergyConsumptionFactory.java
@@ -29,7 +29,7 @@
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.vehicles.VehicleType;
-public class VehicleTypeSpecificDriveEnergyConsumptionFactory implements DriveEnergyConsumption.Factory {
+public final class VehicleTypeSpecificDriveEnergyConsumptionFactory implements DriveEnergyConsumption.Factory {
private final Map, DriveEnergyConsumption.Factory> consumptionMap = new HashMap<>();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java
index 406f0e647dc..e4980391db6 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExample.java
@@ -71,8 +71,11 @@ public void run( String[] args ) {
install( new EvModule() );
addRoutingModuleBinding( TransportMode.car ).toProvider(new EvNetworkRoutingProvider(TransportMode.car) );
- // a router that inserts charging activities when the battery is run empty. there may be some other way to insert
- // charging activities, based on the situation. kai, dec'22
+ // a router that inserts charging activities INTO THE ROUTE when the battery is run empty. This assumes that a full
+ // charge at the start of the route is not sufficient to drive the route. There are other settings where the
+ // situation is different, e.g. urban, where there may be a CHAIN of activities, and charging in general is done in
+ // parallel with some of these activities. That second situation is adressed by some "ev" code in the vsp contrib.
+ // kai, dec'22
}
} );
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java
index 15ed10c0627..024bc2e4c54 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithLTHConsumptionModel.java
@@ -89,7 +89,7 @@ public void run( String[] args ) {
VehicleTypeSpecificDriveEnergyConsumptionFactory driveEnergyConsumptionFactory = new VehicleTypeSpecificDriveEnergyConsumptionFactory();
var vehicleType = Id.create( "EV_65.0kWh", VehicleType.class );
driveEnergyConsumptionFactory.addEnergyConsumptionModelFactory( vehicleType,
- new LTHConsumptionModelReader( vehicleType ).readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) ) );
+ new LTHConsumptionModelReader().readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) ) );
controler.addOverridingModule( new EvModule() );
controler.addOverridingModule( new AbstractModule(){
@@ -106,6 +106,7 @@ public void install(){
} );
}
+
controler.run();
}
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java
new file mode 100644
index 00000000000..eacaba778ad
--- /dev/null
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/example/RunEvExampleWithOwnConsumptionModel.java
@@ -0,0 +1,137 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2016 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.ev.example;
+/*
+ * created by jbischoff, 19.03.2019
+ */
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.matsim.api.core.v01.Scenario;
+import org.matsim.api.core.v01.TransportMode;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.contrib.ev.EvConfigGroup;
+import org.matsim.contrib.ev.EvModule;
+import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
+import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
+import org.matsim.contrib.ev.discharging.LTHDriveEnergyConsumption;
+import org.matsim.contrib.ev.fleet.ElectricVehicle;
+import org.matsim.contrib.ev.infrastructure.LTHConsumptionModelReader;
+import org.matsim.contrib.ev.routing.EvNetworkRoutingProvider;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigGroup;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.controler.AbstractModule;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.controler.OutputDirectoryHierarchy;
+import org.matsim.core.scenario.ScenarioUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * Runs a sample EV run using a vehicle consumption model designed at LTH in Lund which takes the speed and the slope of a link into account.
+ * Link slopes may be added using a double array on the network.
+ * The consumption maps are based on Domingues, Gabriel. / Modeling, Optimization and Analysis of Electromobility Systems. Lund : Department of Biomedical Engineering, Lund university, 2018. 169 p., PhD thesis
+ */
+public class RunEvExampleWithOwnConsumptionModel{
+ static final String DEFAULT_CONFIG_FILE = "test/input/org/matsim/contrib/ev/example/RunEvExample/config.xml";
+ private static final Logger log = LogManager.getLogger( RunEvExampleWithOwnConsumptionModel.class );
+
+ public static void main(String[] args) throws IOException {
+ if (args.length > 0) {
+ log.info("Starting simulation run with the following arguments:");
+ log.info("args=" + Arrays.toString( args ) );
+ } else {
+ File localConfigFile = new File(DEFAULT_CONFIG_FILE);
+ if (localConfigFile.exists()) {
+ log.info("Starting simulation run with the local example config file");
+ args = new String[]{ DEFAULT_CONFIG_FILE };
+ } else {
+ log.info("Starting simulation run with the example config file from GitHub repository");
+ args = new String[]{"https://raw.githubusercontent.com/matsim-org/matsim/master/contribs/ev/"
+ + DEFAULT_CONFIG_FILE };
+ }
+ }
+ new RunEvExampleWithOwnConsumptionModel().run(args );
+ }
+
+ public void run( String[] args ) {
+ Config config = ConfigUtils.loadConfig(args, new EvConfigGroup());
+ config.controller().setOverwriteFileSetting(OutputDirectoryHierarchy.OverwriteFileSetting.deleteDirectoryIfExists);
+
+ // ===
+
+ Scenario scenario = ScenarioUtils.loadScenario(config);
+
+ // ===
+
+ Controler controler = new Controler(scenario);
+ {
+ DriveEnergyConsumption.Factory driveEnergyConsumptionFactory = new DriveEnergyConsumption.Factory(){
+ @Override public DriveEnergyConsumption create( ElectricVehicle electricVehicle ){
+ DriveEnergyConsumption.Factory factory = new LTHConsumptionModelReader().readURL( ConfigGroup.getInputFileURL( config.getContext(), "MidCarMap.csv" ) );
+ DriveEnergyConsumption delegate = factory.create( electricVehicle );
+
+ DriveEnergyConsumption consumption = new DriveEnergyConsumption(){
+ @Override public double calcEnergyConsumption( Link link, double travelTime, double linkEnterTime ){
+
+ // discharge because the link must be driven:
+ double delta = delegate.calcEnergyConsumption( link, travelTime, linkEnterTime );
+
+ double desiredSocAtEndOfLink = (double) electricVehicle.getVehicleSpecification().getMatsimVehicle().getAttributes().getAttribute( "whatever" );
+
+ return electricVehicle.getBattery().getSoc() - desiredSocAtEndOfLink;
+ // * above will often be negative; this is the purpose: discharging is negative i.e. we are
+ // charging on the link. ((This is why I am in general against hiding the sign in the method
+ // name. kai))
+
+ // * above is in SOC space, needs to be translated into kWh space
+
+ // * need to make sure that the above charging is physically possible
+
+ // * need to make sure that we are not discharging beyond what is needed to drive the link
+
+ }
+ };
+ return consumption;
+ }
+ };
+
+ controler.addOverridingModule( new EvModule() );
+ controler.addOverridingModule( new AbstractModule(){
+ @Override
+ public void install(){
+ bind( DriveEnergyConsumption.Factory.class ).toInstance( driveEnergyConsumptionFactory );
+ bind( AuxEnergyConsumption.Factory.class ).toInstance(
+ electricVehicle -> ( beginTime, duration, linkId ) -> 0 ); //a dummy factory, as aux consumption is part of the drive consumption in the model
+
+ addRoutingModuleBinding( TransportMode.car ).toProvider( new EvNetworkRoutingProvider( TransportMode.car ) );
+ // a router that inserts charging activities when the battery is run empty. there may be some other way to insert
+ // charging activities, based on the situation. kai, dec'22
+ }
+ } );
+ }
+
+
+ controler.run();
+ }
+}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java
similarity index 94%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java
index b3be0ab8a02..a9629018dfc 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/BatteryDefaultImpl.java
@@ -23,11 +23,11 @@
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
-public class BatteryImpl implements Battery {
+final class BatteryDefaultImpl implements Battery {
private final double capacity;
private double charge;
- public BatteryImpl(double capacity, double charge) {
+ BatteryDefaultImpl( double capacity, double charge ) {
this.capacity = capacity;
this.charge = charge;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java
deleted file mode 100644
index 2f1475f964e..00000000000
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ConvertInitialChargeToInitialSoc.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) 2022 by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * *********************************************************************** *
- */
-
-package org.matsim.contrib.ev.fleet;
-
-import static org.matsim.contrib.ev.fleet.ElectricVehicleSpecificationImpl.INITIAL_SOC;
-
-import org.matsim.vehicles.MatsimVehicleReader;
-import org.matsim.vehicles.MatsimVehicleWriter;
-import org.matsim.vehicles.VehicleUtils;
-
-/**
- * @author Michal Maciejewski (michalm)
- */
-public class ConvertInitialChargeToInitialSoc {
- private static final String INITIAL_ENERGY_kWh = "initialEnergyInKWh";
-
- public static void run(String file) {
- var vehicles = VehicleUtils.createVehiclesContainer();
- var reader = new MatsimVehicleReader(vehicles);
- reader.readFile(file);
-
- for (var v : vehicles.getVehicles().values()) {
- double battery_kWh = VehicleUtils.getEnergyCapacity(v.getType().getEngineInformation());
- double initial_kWh = (double)v.getAttributes().getAttribute(INITIAL_ENERGY_kWh);
- double initial_soc = initial_kWh / battery_kWh;
- v.getAttributes().removeAttribute(INITIAL_ENERGY_kWh);
- v.getAttributes().putAttribute(INITIAL_SOC, initial_soc);
- }
-
- var writer = new MatsimVehicleWriter(vehicles);
- writer.writeFile(file);
- }
-}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java
index fc6493ae3b8..179a6ec9116 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetModule.java
@@ -37,7 +37,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class ElectricFleetModule extends AbstractModule {
+public final class ElectricFleetModule extends AbstractModule {
@Inject
private EvConfigGroup evCfg;
@@ -46,9 +46,9 @@ public void install() {
bind(ElectricFleetSpecification.class).toProvider(new Provider<>() {
@Inject private Vehicles vehicles;
@Override public ElectricFleetSpecification get() {
- ElectricFleetSpecification fleetSpecification = new ElectricFleetSpecificationImpl();
- ElectricVehicleSpecificationImpl.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification,
- vehicles.getVehicles().values());
+ ElectricFleetSpecification fleetSpecification = new ElectricFleetSpecificationDefaultImpl();
+ ElectricFleetUtils.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification,
+ vehicles.getVehicles().values() );
return fleetSpecification;
}
}).asEagerSingleton();
@@ -64,8 +64,8 @@ protected void configureQSim() {
@Override
public ElectricFleet get() {
- return ElectricFleets.createDefaultFleet(fleetSpecification, driveConsumptionFactory, auxConsumptionFactory,
- chargingPowerFactory);
+ return ElectricFleetUtils.createDefaultFleet(fleetSpecification, driveConsumptionFactory, auxConsumptionFactory,
+ chargingPowerFactory );
}
}).asEagerSingleton();
@@ -77,7 +77,7 @@ public ElectricFleet get() {
for (var oldSpec : electricFleetSpecification.getVehicleSpecifications().values()) {
var matsimVehicle = oldSpec.getMatsimVehicle();
double socAtEndOfCurrentIteration = electricFleet.getElectricVehicles().get(oldSpec.getId()).getBattery().getSoc();
- ElectricVehicleSpecifications.setInitialSoc(matsimVehicle, socAtEndOfCurrentIteration);
+ ElectricFleetUtils.setInitialSoc(matsimVehicle, socAtEndOfCurrentIteration );
}
}
});
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java
similarity index 96%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java
index 14a70682741..b24583feb13 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetSpecificationDefaultImpl.java
@@ -30,7 +30,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public final class ElectricFleetSpecificationImpl implements ElectricFleetSpecification {
+final class ElectricFleetSpecificationDefaultImpl implements ElectricFleetSpecification {
private final Map, ElectricVehicleSpecification> specifications = new LinkedHashMap<>();
@Override
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java
new file mode 100644
index 00000000000..0e92b52759c
--- /dev/null
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleetUtils.java
@@ -0,0 +1,90 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2022 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** *
+ */
+
+package org.matsim.contrib.ev.fleet;
+
+import java.util.Collection;
+import java.util.Objects;
+
+import com.google.common.collect.ImmutableMap;
+import org.matsim.api.core.v01.Id;
+import org.matsim.contrib.ev.charging.ChargingPower;
+import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
+import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
+import org.matsim.vehicles.*;
+
+public final class ElectricFleetUtils {
+ public static final String EV_ENGINE_HBEFA_TECHNOLOGY = "electricity";
+ public static final String INITIAL_SOC = "initialSoc";// in [0, 1]
+ public static final String CHARGER_TYPES = "chargerTypes";
+ private static final String INITIAL_ENERGY_kWh = "initialEnergyInKWh";
+ private ElectricFleetUtils(){} // do not instantiate
+ public static void setInitialSoc(Vehicle vehicle, double initialSoc) {
+ vehicle.getAttributes().putAttribute( INITIAL_SOC, initialSoc );
+ }
+
+ public static void setChargerTypes(EngineInformation engineInformation, Collection chargerTypes) {
+ engineInformation.getAttributes().putAttribute( CHARGER_TYPES, chargerTypes );
+ }
+ public static void run(String file) {
+ var vehicles = VehicleUtils.createVehiclesContainer();
+ var reader = new MatsimVehicleReader(vehicles);
+ reader.readFile(file);
+
+ for (var v : vehicles.getVehicles().values()) {
+ double battery_kWh = VehicleUtils.getEnergyCapacity(v.getType().getEngineInformation());
+ double initial_kWh = (double)v.getAttributes().getAttribute(INITIAL_ENERGY_kWh);
+ double initial_soc = initial_kWh / battery_kWh;
+ v.getAttributes().removeAttribute(INITIAL_ENERGY_kWh);
+ v.getAttributes().putAttribute(INITIAL_SOC, initial_soc);
+ }
+
+ var writer = new MatsimVehicleWriter(vehicles);
+ writer.writeFile(file);
+ }
+ public static ElectricVehicle create( ElectricVehicleSpecification vehicleSpecification,
+ DriveEnergyConsumption.Factory driveFactory, AuxEnergyConsumption.Factory auxFactory,
+ ChargingPower.Factory chargingFactory ) {
+ ElectricVehicleDefaultImpl ev = new ElectricVehicleDefaultImpl(vehicleSpecification);
+ ev.driveEnergyConsumption = Objects.requireNonNull(driveFactory.create(ev ) );
+ ev.auxEnergyConsumption = Objects.requireNonNull(auxFactory.create(ev));
+ ev.chargingPower = Objects.requireNonNull(chargingFactory.create(ev));
+ return ev;
+ }
+ public static void createAndAddVehicleSpecificationsFromMatsimVehicles(ElectricFleetSpecification fleetSpecification, Collection vehicles) {
+ vehicles.stream()
+ .filter(vehicle -> EV_ENGINE_HBEFA_TECHNOLOGY.equals(VehicleUtils.getHbefaTechnology(vehicle.getType().getEngineInformation())))
+ .map( ElectricVehicleSpecificationDefaultImpl::new )
+ .forEach(fleetSpecification::addVehicleSpecification);
+ }
+ public static ElectricVehicleSpecification createElectricVehicleSpecificationDefaultImpl( Vehicle matsimVehicle ){
+ return new ElectricVehicleSpecificationDefaultImpl( matsimVehicle );
+ }
+ public static ElectricFleet createDefaultFleet(ElectricFleetSpecification fleetSpecification,
+ DriveEnergyConsumption.Factory driveConsumptionFactory, AuxEnergyConsumption.Factory auxConsumptionFactory,
+ ChargingPower.Factory chargingFactory) {
+ ImmutableMap, ElectricVehicle> vehicles = fleetSpecification.getVehicleSpecifications()
+ .values()
+ .stream()
+ .map(s -> create(s, driveConsumptionFactory, auxConsumptionFactory, chargingFactory ))
+ .collect(ImmutableMap.toImmutableMap(ElectricVehicle::getId, v -> v));
+ return () -> vehicles;
+ }
+}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java
deleted file mode 100644
index fbe29db0ab3..00000000000
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricFleets.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) 2019 by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * *********************************************************************** *
- */
-
-package org.matsim.contrib.ev.fleet;
-
-import org.matsim.api.core.v01.Id;
-import org.matsim.contrib.ev.charging.ChargingPower;
-import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
-import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
-import org.matsim.vehicles.Vehicle;
-
-import com.google.common.collect.ImmutableMap;
-
-public class ElectricFleets {
- public static ElectricFleet createDefaultFleet(ElectricFleetSpecification fleetSpecification,
- DriveEnergyConsumption.Factory driveConsumptionFactory, AuxEnergyConsumption.Factory auxConsumptionFactory,
- ChargingPower.Factory chargingFactory) {
- ImmutableMap, ElectricVehicle> vehicles = fleetSpecification.getVehicleSpecifications()
- .values()
- .stream()
- .map(s -> ElectricVehicleImpl.create(s, driveConsumptionFactory, auxConsumptionFactory,
- chargingFactory))
- .collect(ImmutableMap.toImmutableMap(ElectricVehicle::getId, v -> v));
- return () -> vehicles;
- }
-}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java
similarity index 74%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java
index 91125b6500d..c4da3c65565 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleDefaultImpl.java
@@ -20,8 +20,6 @@
package org.matsim.contrib.ev.fleet;
-import java.util.Objects;
-
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.ev.charging.ChargingPower;
import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
@@ -31,27 +29,18 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
-public class ElectricVehicleImpl implements ElectricVehicle {
- public static ElectricVehicle create(ElectricVehicleSpecification vehicleSpecification,
- DriveEnergyConsumption.Factory driveFactory, AuxEnergyConsumption.Factory auxFactory,
- ChargingPower.Factory chargingFactory) {
- ElectricVehicleImpl ev = new ElectricVehicleImpl(vehicleSpecification);
- ev.driveEnergyConsumption = Objects.requireNonNull(driveFactory.create(ev));
- ev.auxEnergyConsumption = Objects.requireNonNull(auxFactory.create(ev));
- ev.chargingPower = Objects.requireNonNull(chargingFactory.create(ev));
- return ev;
- }
+final class ElectricVehicleDefaultImpl implements ElectricVehicle {
private final ElectricVehicleSpecification vehicleSpecification;
private final Battery battery;
- private DriveEnergyConsumption driveEnergyConsumption;
- private AuxEnergyConsumption auxEnergyConsumption;
- private ChargingPower chargingPower;
+ DriveEnergyConsumption driveEnergyConsumption;
+ AuxEnergyConsumption auxEnergyConsumption;
+ ChargingPower chargingPower;
- private ElectricVehicleImpl(ElectricVehicleSpecification vehicleSpecification) {
+ ElectricVehicleDefaultImpl( ElectricVehicleSpecification vehicleSpecification ) {
this.vehicleSpecification = vehicleSpecification;
- battery = new BatteryImpl(vehicleSpecification.getBatteryCapacity(), vehicleSpecification.getInitialCharge());
+ battery = new BatteryDefaultImpl(vehicleSpecification.getBatteryCapacity(), vehicleSpecification.getInitialCharge());
}
@Override
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java
similarity index 73%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java
index 70d4c100f77..ef18ae6cce6 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecificationDefaultImpl.java
@@ -33,23 +33,11 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class ElectricVehicleSpecificationImpl implements ElectricVehicleSpecification {
- public static final String EV_ENGINE_HBEFA_TECHNOLOGY = "electricity";
-
- public static final String INITIAL_SOC = "initialSoc";// in [0, 1]
- public static final String CHARGER_TYPES = "chargerTypes";
-
- public static void createAndAddVehicleSpecificationsFromMatsimVehicles(ElectricFleetSpecification fleetSpecification,
- Collection vehicles) {
- vehicles.stream()
- .filter(vehicle -> EV_ENGINE_HBEFA_TECHNOLOGY.equals(VehicleUtils.getHbefaTechnology(vehicle.getType().getEngineInformation())))
- .map(ElectricVehicleSpecificationImpl::new)
- .forEach(fleetSpecification::addVehicleSpecification);
- }
+final class ElectricVehicleSpecificationDefaultImpl implements ElectricVehicleSpecification {
private final Vehicle matsimVehicle;
- public ElectricVehicleSpecificationImpl(Vehicle matsimVehicle) {
+ ElectricVehicleSpecificationDefaultImpl( Vehicle matsimVehicle ) {
this.matsimVehicle = matsimVehicle;
//provided per vehicle type (in engine info)
Preconditions.checkArgument(getInitialSoc() >= 0 && getInitialSoc() <= 1, "Invalid initialCharge or batteryCapacity of vehicle: %s", getId());
@@ -68,12 +56,12 @@ public Vehicle getMatsimVehicle() {
@Override
public ImmutableList getChargerTypes() {
var engineInfo = matsimVehicle.getType().getEngineInformation();
- return ImmutableList.copyOf((Collection)engineInfo.getAttributes().getAttribute(CHARGER_TYPES));
+ return ImmutableList.copyOf((Collection)engineInfo.getAttributes().getAttribute( ElectricFleetUtils.CHARGER_TYPES ) );
}
@Override
public double getInitialSoc() {
- return (double)matsimVehicle.getAttributes().getAttribute(INITIAL_SOC);
+ return (double)matsimVehicle.getAttributes().getAttribute( ElectricFleetUtils.INITIAL_SOC );
}
@Override
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
similarity index 95%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
index a37cd181c9e..d2efb68578d 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerDefaultImpl.java
@@ -29,13 +29,13 @@
import com.google.common.base.Preconditions;
-public class ChargerImpl implements Charger {
+class ChargerDefaultImpl implements Charger {
private final ChargerSpecification specification;
private final Link link;
private final ChargingLogic logic;
- public ChargerImpl(ChargerSpecification specification, Link link, ChargingLogic logic) {
+ ChargerDefaultImpl( ChargerSpecification specification, Link link, ChargingLogic logic ) {
Preconditions.checkArgument(link.getId().equals(specification.getLinkId()), "link.id != specification.linkId");
this.specification = specification;
this.link = link;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
index 27f21fe2fff..9864622b4cb 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerReader.java
@@ -28,7 +28,7 @@
import org.matsim.core.utils.io.MatsimXmlParser;
import org.xml.sax.Attributes;
-public class ChargerReader extends MatsimXmlParser {
+public final class ChargerReader extends MatsimXmlParser {
private final static String CHARGER = "charger";
private final ChargingInfrastructureSpecification chargingInfrastructure;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
index bb03bc9f063..8955b266984 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargerWriter.java
@@ -29,7 +29,7 @@
import org.matsim.core.utils.collections.Tuple;
import org.matsim.core.utils.io.MatsimXmlWriter;
-public class ChargerWriter extends MatsimXmlWriter {
+public final class ChargerWriter extends MatsimXmlWriter {
private final Stream extends ChargerSpecification> chargerSpecifications;
public ChargerWriter(Stream extends ChargerSpecification> chargerSpecifications) {
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
index ea2e2526afb..f44bee53f11 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureModule.java
@@ -36,7 +36,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class ChargingInfrastructureModule extends AbstractModule {
+public final class ChargingInfrastructureModule extends AbstractModule {
public static final String CHARGERS = "chargers";
private final Key networkKey;
@@ -56,7 +56,7 @@ public void install() {
bind(Network.class).annotatedWith(Names.named(CHARGERS)).to(networkKey).asEagerSingleton();
bind(ChargingInfrastructureSpecification.class).toProvider(() -> {
- ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationImpl();
+ ChargingInfrastructureSpecification chargingInfrastructureSpecification = new ChargingInfrastructureSpecificationDefaultImpl();
new ChargerReader(chargingInfrastructureSpecification).parse(
ConfigGroup.getInputFileURL(getConfig().getContext(), evCfg.chargersFile));
return chargingInfrastructureSpecification;
@@ -76,8 +76,8 @@ protected void configureQSim() {
@Override
public ChargingInfrastructure get() {
- return ChargingInfrastructures.createChargingInfrastructure(chargingInfrastructureSpecification,
- network.getLinks()::get, chargingLogicFactory);
+ return ChargingInfrastructureUtils.createChargingInfrastructure(chargingInfrastructureSpecification,
+ network.getLinks()::get, chargingLogicFactory );
}
}).asEagerSingleton();
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java
similarity index 95%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java
index ceeba42372f..48a27563616 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationImpl.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureSpecificationDefaultImpl.java
@@ -28,7 +28,7 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class ChargingInfrastructureSpecificationImpl implements ChargingInfrastructureSpecification {
+final class ChargingInfrastructureSpecificationDefaultImpl implements ChargingInfrastructureSpecification {
private final SpecificationContainer container = new SpecificationContainer<>();
@Override
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java
similarity index 90%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java
rename to contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java
index b86a140fcbb..e4e7ca5c4fa 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructures.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ChargingInfrastructureUtils.java
@@ -37,8 +37,10 @@
/**
* @author Michal Maciejewski (michalm)
*/
-public class ChargingInfrastructures {
- static final Logger log = LogManager.getLogger(ChargingInfrastructures.class);
+public class ChargingInfrastructureUtils{
+ static final Logger log = LogManager.getLogger( ChargingInfrastructureUtils.class );
+
+ private ChargingInfrastructureUtils(){} // do not instantiate
public static ChargingInfrastructure createChargingInfrastructure(
ChargingInfrastructureSpecification infrastructureSpecification, Function, Link> linkProvider,
@@ -46,7 +48,7 @@ public static ChargingInfrastructure createChargingInfrastructure(
var chargers = infrastructureSpecification.getChargerSpecifications()
.values()
.stream()
- .map(s -> new ChargerImpl(s, linkProvider.apply(s.getLinkId()), chargingLogicFactory.create(s)))
+ .map(s -> new ChargerDefaultImpl(s, linkProvider.apply(s.getLinkId() ), chargingLogicFactory.create(s )) )
.collect(ImmutableMap.toImmutableMap(Charger::getId, c -> (Charger)c));
return () -> chargers;
}
@@ -72,7 +74,7 @@ public static ChargingInfrastructure createModalNetworkChargers(ChargingInfrastr
var reachableLinks = network.getLinks();
var filteredChargers = infrastructure.getChargers().values().stream().map(c -> {
var link = reachableLinks.get(c.getLink().getId());
- return link == null ? null : new ChargerImpl(c.getSpecification(), link, c.getLogic());
+ return link == null ? null : new ChargerDefaultImpl(c.getSpecification(), link, c.getLogic());
}).filter(Objects::nonNull).collect(ImmutableMap.toImmutableMap(Charger::getId, c -> (Charger)c));
int chargerCount = infrastructure.getChargers().size();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
index aa08f5d6b85..a3d7192b793 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/ImmutableChargerSpecification.java
@@ -40,7 +40,7 @@ public class ImmutableChargerSpecification implements ChargerSpecification {
private final double plugPower;
private final int plugCount;
- private ImmutableChargerSpecification(Builder builder) {
+ private ImmutableChargerSpecification( ChargerSpecificationBuilder builder ) {
id = Objects.requireNonNull(builder.id);
linkId = Objects.requireNonNull(builder.linkId);
chargerType = Objects.requireNonNull(builder.chargerType);
@@ -51,12 +51,12 @@ private ImmutableChargerSpecification(Builder builder) {
Preconditions.checkArgument(plugCount >= 0, "Negative plugCount of charger: %s", id);
}
- public static Builder newBuilder() {
- return new Builder();
+ public static ChargerSpecificationBuilder newBuilder() {
+ return new ChargerSpecificationBuilder();
}
- public static Builder newBuilder(ChargerSpecification copy) {
- Builder builder = new Builder();
+ public static ChargerSpecificationBuilder newBuilder( ChargerSpecification copy ) {
+ ChargerSpecificationBuilder builder = new ChargerSpecificationBuilder();
builder.id = copy.getId();
builder.linkId = copy.getLinkId();
builder.chargerType = copy.getChargerType();
@@ -101,37 +101,37 @@ public String toString() {
.toString();
}
- public static final class Builder {
+ public static final class ChargerSpecificationBuilder{
private Id id;
private Id linkId;
private String chargerType;
private Double plugPower;
private Integer plugCount;
- private Builder() {
+ private ChargerSpecificationBuilder() {
}
- public Builder id(Id val) {
+ public ChargerSpecificationBuilder id( Id val ) {
id = val;
return this;
}
- public Builder linkId(Id val) {
+ public ChargerSpecificationBuilder linkId( Id val ) {
linkId = val;
return this;
}
- public Builder chargerType(String val) {
+ public ChargerSpecificationBuilder chargerType( String val ) {
chargerType = val;
return this;
}
- public Builder plugPower(double val) {
+ public ChargerSpecificationBuilder plugPower( double val ) {
plugPower = val;
return this;
}
- public Builder plugCount(int val) {
+ public ChargerSpecificationBuilder plugCount( int val ) {
plugCount = val;
return this;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java
index 5cb4e90d129..0b8e732e85a 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/infrastructure/LTHConsumptionModelReader.java
@@ -28,6 +28,7 @@
import java.util.List;
import org.matsim.api.core.v01.Id;
+import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
import org.matsim.contrib.ev.discharging.LTHDriveEnergyConsumption;
import org.matsim.core.utils.io.tabularFileParser.TabularFileHandler;
import org.matsim.core.utils.io.tabularFileParser.TabularFileParser;
@@ -43,10 +44,10 @@
*/
public class LTHConsumptionModelReader {
- public LTHConsumptionModelReader(Id vehicleTypeId) {
+ public LTHConsumptionModelReader() {
}
- public LTHDriveEnergyConsumption.Factory readURL(URL fileUrl) {
+ public DriveEnergyConsumption.Factory readURL( URL fileUrl ) {
List speeds = new ArrayList<>();
List slopes = new ArrayList<>();
TabularFileParserConfig tabularFileParserConfig = new TabularFileParserConfig();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java
index b8acc39a3f7..1ae999170d8 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/package-info.java
@@ -17,8 +17,6 @@
* *
* *********************************************************************** */
-package org.matsim.contrib.ev;
-
/**
* All values used in this package use SI base and derived units. In particular:
*
@@ -34,3 +32,5 @@
* Consequently, energy consumption is measured in [J/m], rather than [kWh/100km] or [Wh/km], as typically done in
* transport.
*/
+package org.matsim.contrib.ev;
+
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/routing/EvNetworkRoutingModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/routing/EvNetworkRoutingModule.java
index 6d8a0e89f61..10123db4717 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/routing/EvNetworkRoutingModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/routing/EvNetworkRoutingModule.java
@@ -36,10 +36,7 @@
import org.matsim.contrib.ev.charging.VehicleChargingHandler;
import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
-import org.matsim.contrib.ev.fleet.ElectricFleetSpecification;
-import org.matsim.contrib.ev.fleet.ElectricVehicle;
-import org.matsim.contrib.ev.fleet.ElectricVehicleImpl;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
+import org.matsim.contrib.ev.fleet.*;
import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureSpecification;
import org.matsim.contrib.common.util.StraightLineKnnFinder;
@@ -180,10 +177,10 @@ private Map estimateConsumption(ElectricVehicleSpecification ev, L
Map consumptions = new LinkedHashMap<>();
NetworkRoute route = (NetworkRoute)basicLeg.getRoute();
List links = NetworkUtils.getLinks(network, route.getLinkIds());
- ElectricVehicle pseudoVehicle = ElectricVehicleImpl.create(ev, driveConsumptionFactory, auxConsumptionFactory,
+ ElectricVehicle pseudoVehicle = ElectricFleetUtils.create(ev, driveConsumptionFactory, auxConsumptionFactory,
v -> charger -> {
throw new UnsupportedOperationException();
- });
+ } );
DriveEnergyConsumption driveEnergyConsumption = pseudoVehicle.getDriveEnergyConsumption();
AuxEnergyConsumption auxEnergyConsumption = pseudoVehicle.getAuxEnergyConsumption();
double linkEnterTime = basicLeg.getDepartureTime().seconds();
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyTimeProfileCollectorProvider.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyTimeProfileCollectorProvider.java
index 5c13fac0868..a11883f50f2 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyTimeProfileCollectorProvider.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyTimeProfileCollectorProvider.java
@@ -34,12 +34,12 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
-public class ChargerOccupancyTimeProfileCollectorProvider implements Provider {
+public final class ChargerOccupancyTimeProfileCollectorProvider implements Provider {
private final ChargingInfrastructure chargingInfrastructure;
private final MatsimServices matsimServices;
@Inject
- public ChargerOccupancyTimeProfileCollectorProvider(ChargingInfrastructure chargingInfrastructure, MatsimServices matsimServices) {
+ ChargerOccupancyTimeProfileCollectorProvider(ChargingInfrastructure chargingInfrastructure, MatsimServices matsimServices) {
this.chargingInfrastructure = chargingInfrastructure;
this.matsimServices = matsimServices;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyXYDataCollector.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyXYDataCollector.java
index fa2dd8618aa..c0b1c5df506 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyXYDataCollector.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerOccupancyXYDataCollector.java
@@ -37,7 +37,7 @@
import com.google.inject.Inject;
-public class ChargerOccupancyXYDataCollector implements MobsimInitializedListener, MobsimBeforeSimStepListener, MobsimBeforeCleanupListener {
+public final class ChargerOccupancyXYDataCollector implements MobsimInitializedListener, MobsimBeforeSimStepListener, MobsimBeforeCleanupListener {
private final ChargingInfrastructure chargingInfrastructure;
private final MatsimServices matsimServices;
@@ -45,7 +45,7 @@ public class ChargerOccupancyXYDataCollector implements MobsimInitializedListene
private CompactCSVWriter writer;
@Inject
- public ChargerOccupancyXYDataCollector(ChargingInfrastructure chargingInfrastructure, MatsimServices matsimServices) {
+ ChargerOccupancyXYDataCollector(ChargingInfrastructure chargingInfrastructure, MatsimServices matsimServices) {
this.chargingInfrastructure = chargingInfrastructure;
this.matsimServices = matsimServices;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerCollector.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerCollector.java
index 14ffb1e84a6..1db79d2ae97 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerCollector.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerCollector.java
@@ -53,7 +53,7 @@
/*
* created by jbischoff, 26.10.2018
*/
-public class ChargerPowerCollector
+public final class ChargerPowerCollector
implements ChargingStartEventHandler, ChargingEndEventHandler, MobsimScopeEventHandler, MobsimBeforeCleanupListener {
@Inject
@@ -65,6 +65,8 @@ public class ChargerPowerCollector
@Inject
private ElectricFleet fleet;
+ @Inject ChargerPowerCollector(){} // this forces instantiation via guice. kai, oct'23
+
private record TimeCharge(double time, double charge) {
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileCalculator.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileCalculator.java
index 78e7f6987ef..576d06d4a9e 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileCalculator.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileCalculator.java
@@ -19,7 +19,7 @@
import com.google.inject.Inject;
-public class ChargerPowerTimeProfileCalculator implements ChargingStartEventHandler, ChargingEndEventHandler {
+public final class ChargerPowerTimeProfileCalculator implements ChargingStartEventHandler, ChargingEndEventHandler {
private final Map, double[]> chargerProfiles = new HashMap<>();
private final Map, Double> chargingStartTimeMap = new HashMap<>();
@@ -35,7 +35,7 @@ public class ChargerPowerTimeProfileCalculator implements ChargingStartEventHand
* @author mattiasingelstrom
*/
@Inject
- public ChargerPowerTimeProfileCalculator(Config config) {
+ ChargerPowerTimeProfileCalculator(Config config) {
int chargeTimeStep = ConfigUtils.addOrGetModule(config, EvConfigGroup.class).chargeTimeStep;
qsimEndTime = ConfigUtils.addOrGetModule(config, QSimConfigGroup.class).getEndTime().orElse(0.0);
timeDiscretizer = new TimeDiscretizer((int)Math.ceil(qsimEndTime), chargeTimeStep);
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileView.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileView.java
index d0941954540..666a1abebe7 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileView.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/ChargerPowerTimeProfileView.java
@@ -8,10 +8,10 @@
import java.awt.*;
import java.util.Map;
-public class ChargerPowerTimeProfileView implements ProfileWriter.ProfileView {
+final class ChargerPowerTimeProfileView implements ProfileWriter.ProfileView {
private final ChargerPowerTimeProfileCalculator calculator;
- public ChargerPowerTimeProfileView(ChargerPowerTimeProfileCalculator calculator) {
+ ChargerPowerTimeProfileView(ChargerPowerTimeProfileCalculator calculator) {
this.calculator = calculator;
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/EnergyConsumptionCollector.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/EnergyConsumptionCollector.java
index 4995a3ba41b..2f1a90c1d47 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/EnergyConsumptionCollector.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/EnergyConsumptionCollector.java
@@ -56,6 +56,8 @@ public class EnergyConsumptionCollector implements DrivingEnergyConsumptionEvent
private final Map, Double> energyConsumptionPerLink = new HashMap<>();
+ @Inject EnergyConsumptionCollector(){} // so that class can only be instantiated via guice. kai, oct'23
+
@Override
public void handleEvent(DrivingEnergyConsumptionEvent event) {
energyConsumptionPerLink.merge(event.getLinkId(), event.getEnergy(), Double::sum);
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/IndividualChargeTimeProfileCollectorProvider.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/IndividualChargeTimeProfileCollectorProvider.java
index a623b04e6e8..44667aa3e84 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/IndividualChargeTimeProfileCollectorProvider.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/stats/IndividualChargeTimeProfileCollectorProvider.java
@@ -39,13 +39,13 @@
import com.google.inject.Inject;
import com.google.inject.Provider;
-public class IndividualChargeTimeProfileCollectorProvider implements Provider {
+public final class IndividualChargeTimeProfileCollectorProvider implements Provider {
private final ElectricFleet evFleet;
private final MatsimServices matsimServices;
private final int maxVehicleColumns;
@Inject
- public IndividualChargeTimeProfileCollectorProvider(ElectricFleet evFleet, MatsimServices matsimServices, Config config) {
+ IndividualChargeTimeProfileCollectorProvider(ElectricFleet evFleet, MatsimServices matsimServices, Config config) {
this.evFleet = evFleet;
this.matsimServices = matsimServices;
maxVehicleColumns = ConfigUtils.addOrGetModule(config, EvConfigGroup.class).numberOfIndividualTimeProfiles;
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureChangeModule.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureChangeModule.java
index 697e0437ed2..2a4530061e2 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureChangeModule.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureChangeModule.java
@@ -21,14 +21,29 @@
* created by jbischoff, 15.08.2018
*/
+import com.google.inject.Singleton;
import org.matsim.core.controler.AbstractModule;
public class TemperatureChangeModule extends AbstractModule {
@Override
public void install() {
- addMobsimListenerBinding().to(TemperatureManager.class).asEagerSingleton();
- bind(TemperatureServiceImpl.class).asEagerSingleton();
- bind(TemperatureService.class).to(TemperatureServiceImpl.class);
- addEventHandlerBinding().to(TemperatureServiceImpl.class);
+
+ addMobsimListenerBinding().to(TemperatureManager.class).in( Singleton.class );
+
+ bind(TemperatureServiceImpl.class).in( Singleton.class );
+ bind(TemperatureService.class).to(TemperatureServiceImpl.class);
+ addEventHandlerBinding().to(TemperatureServiceImpl.class);
+
+ // yyyy Shouldn't we think about just having a like
+
+// bind(TemperatureService.class).to(TemperatureServiceImpl.class)(.in( Singleton.class ));
+
+ // and then make sure that the implementation registers itself? But how to actually achieve that? kai, oct'23
+
+ // I think that the answer to that last question is to bind the interface rather than the implementation, and have that further "upstairs" in the ev module:
+ // addEventHandlerBinding().to( TemperatureService.class );
+ // for this, evidently, the interface needs to implement the right things (which it currently does not).
+
+
}
}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureManager.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureManager.java
index 74bdb5055b6..ffddbf850a6 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureManager.java
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/TemperatureManager.java
@@ -51,7 +51,7 @@ public class TemperatureManager implements MobsimBeforeSimStepListener, MobsimIn
private final EventsManager events;
@Inject
- public TemperatureManager(Config config, EventsManager events) {
+ TemperatureManager(Config config, EventsManager events) {
this.events = events;
TemperatureChangeConfigGroup temperatureChangeConfigGroup = (TemperatureChangeConfigGroup)config.getModules()
.get(TemperatureChangeConfigGroup.GROUP_NAME);
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/package-info.java b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/package-info.java
new file mode 100644
index 00000000000..bab62cd2b51
--- /dev/null
+++ b/contribs/ev/src/main/java/org/matsim/contrib/ev/temperature/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * I think that this is about ambient temperature. And it is here since charging may depend on ambient temperatur.
+ */
+package org.matsim.contrib.ev.temperature;
diff --git a/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/FastThenSlowChargingTest.java b/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/FastThenSlowChargingTest.java
index 66e8fd19a87..08eed4fe613 100644
--- a/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/FastThenSlowChargingTest.java
+++ b/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/FastThenSlowChargingTest.java
@@ -25,8 +25,8 @@
import org.junit.Test;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.ev.EvUnits;
+import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.contrib.ev.fleet.ElectricVehicle;
-import org.matsim.contrib.ev.fleet.ElectricVehicleImpl;
import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
import org.matsim.contrib.ev.infrastructure.Charger;
import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
@@ -160,11 +160,11 @@ record TestEvSpecification(Id getId, Vehicle getMatsimVehicle, String g
var specification = new TestEvSpecification(Id.create("ev_id", Vehicle.class), null, "vt",
ImmutableList.of("ct"), EvUnits.kWh_to_J(capacity_kWh), charge_kWh / capacity_kWh);
- return ElectricVehicleImpl.create(specification, ev -> (link, travelTime, linkEnterTime) -> {
+ return ElectricFleetUtils.create(specification, ev -> ( link, travelTime, linkEnterTime) -> {
throw new UnsupportedOperationException();
}, ev -> (beginTime, duration, linkId) -> {
throw new UnsupportedOperationException();
- }, FastThenSlowCharging::new);
+ }, FastThenSlowCharging::new );
}
@Test
diff --git a/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/VariableSpeedChargingTest.java b/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/VariableSpeedChargingTest.java
index 06091cae47c..1f0c78ffab9 100644
--- a/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/VariableSpeedChargingTest.java
+++ b/contribs/ev/src/test/java/org/matsim/contrib/ev/charging/VariableSpeedChargingTest.java
@@ -25,7 +25,7 @@
import org.junit.Test;
import org.matsim.api.core.v01.Id;
import org.matsim.contrib.ev.EvUnits;
-import org.matsim.contrib.ev.fleet.ElectricVehicleImpl;
+import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
import org.matsim.contrib.ev.infrastructure.Charger;
import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
@@ -96,11 +96,11 @@ record TestEvSpecification(Id getId, Vehicle getMatsimVehicle, String g
.plugCount(1)
.build();
- var electricVehicle = ElectricVehicleImpl.create(specification, ev -> (link, travelTime, linkEnterTime) -> {
+ var electricVehicle = ElectricFleetUtils.create(specification, ev -> ( link, travelTime, linkEnterTime) -> {
throw new UnsupportedOperationException();
}, ev -> (beginTime, duration, linkId) -> {
throw new UnsupportedOperationException();
- }, VariableSpeedCharging::createForTesla);
+ }, VariableSpeedCharging::createForTesla );
Assertions.assertThat(electricVehicle.getChargingPower().calcChargingPower(charger))
.isCloseTo(EvUnits.kW_to_W(expectedChargingPower_kW), Percentage.withPercentage(1e-13));
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
index c49c04aa533..c02717031fa 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryEndEvent.java
@@ -84,7 +84,7 @@ public static CarrierShipmentDeliveryEndEvent convert(GenericEvent event) {
Id shipmentTo = Id.createLinkId(attributes.get(ATTRIBUTE_LINK));
int size = Integer.parseInt(attributes.get(CarrierEventAttributes.ATTRIBUTE_CAPACITYDEMAND));
CarrierShipment shipment = CarrierShipment.Builder.newInstance(shipmentId, null, shipmentTo, size)
- .setDeliveryServiceTime(Double.parseDouble(attributes.get(CarrierEventAttributes.ATTRIBUTE_SERVICE_DURATION)))
+ .setDeliveryServiceTime(Double.parseDouble(attributes.get(CarrierEventAttributes.ATTRIBUTE_DROPOFF_DURATION)))
.build();
Id vehicleId = Id.createVehicleId(attributes.get(ATTRIBUTE_VEHICLE));
return new CarrierShipmentDeliveryEndEvent(time, carrierId, shipment, vehicleId);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
index e12222973c1..43cf21fc752 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/CarrierShipmentDeliveryStartEvent.java
@@ -85,7 +85,7 @@ public static CarrierShipmentDeliveryStartEvent convert(GenericEvent event) {
Id shipmentTo = Id.createLinkId(attributes.get(ATTRIBUTE_LINK));
int size = Integer.parseInt(attributes.get(ATTRIBUTE_CAPACITYDEMAND));
CarrierShipment shipment = CarrierShipment.Builder.newInstance(shipmentId, null, shipmentTo, size)
- .setDeliveryServiceTime(Double.parseDouble(attributes.get(ATTRIBUTE_SERVICE_DURATION)))
+ .setDeliveryServiceTime(Double.parseDouble(attributes.get(ATTRIBUTE_DROPOFF_DURATION)))
.build();
Id vehicleId = Id.createVehicleId(attributes.get(ATTRIBUTE_VEHICLE));
return new CarrierShipmentDeliveryStartEvent(time, carrierId, shipment, vehicleId);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceEndEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceEndEventHandler.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceEndEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceEndEventHandler.java
index 65db8298b92..11ccfde0372 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceEndEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceEndEventHandler.java
@@ -25,7 +25,7 @@
import org.matsim.core.events.handler.EventHandler;
import org.matsim.freight.carriers.events.CarrierServiceEndEvent;
-public interface FreightServiceEndEventHandler extends EventHandler{
+public interface CarrierServiceEndEventHandler extends EventHandler{
void handleEvent( CarrierServiceEndEvent event );
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
similarity index 96%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceStartEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
index 78534b0337e..a8ea55c13e8 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightServiceStartEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierServiceStartEventHandler.java
@@ -25,7 +25,7 @@
import org.matsim.freight.carriers.events.CarrierServiceStartEvent;
-public interface FreightServiceStartEventHandler extends EventHandler {
+public interface CarrierServiceStartEventHandler extends EventHandler {
void handleEvent( CarrierServiceStartEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentDeliveryEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryEndEventHandler.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentDeliveryEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryEndEventHandler.java
index 858a91fdca5..b2cc8ff31dc 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentDeliveryEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryEndEventHandler.java
@@ -30,7 +30,7 @@
* @author sschroeder
*
*/
-public interface FreightShipmentDeliveryEventHandler extends EventHandler {
+public interface CarrierShipmentDeliveryEndEventHandler extends EventHandler {
void handleEvent(CarrierShipmentDeliveryEndEvent event);
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryStartEventHandler.java
new file mode 100644
index 00000000000..df8a7b9785a
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentDeliveryStartEventHandler.java
@@ -0,0 +1,37 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * ***********************************************************************
+ *
+ */
+
+package org.matsim.freight.carriers.events.eventhandler;
+
+import org.matsim.core.events.handler.EventHandler;
+import org.matsim.freight.carriers.events.CarrierShipmentDeliveryStartEvent;
+
+/**
+ * Interface to listen to shipmentDeliveredEvents.
+ *
+ * @author sschroeder
+ *
+ */
+public interface CarrierShipmentDeliveryStartEventHandler extends EventHandler {
+
+ void handleEvent(CarrierShipmentDeliveryStartEvent event);
+
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentPickupEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupEndEventHandler.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentPickupEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupEndEventHandler.java
index 126942b432f..4c7282c29c7 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightShipmentPickupEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupEndEventHandler.java
@@ -30,6 +30,6 @@
* @author sschroeder
*
*/
-public interface FreightShipmentPickupEventHandler extends EventHandler {
+public interface CarrierShipmentPickupEndEventHandler extends EventHandler {
void handleEvent(CarrierShipmentPickupEndEvent event);
}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupStartEventHandler.java
new file mode 100644
index 00000000000..79c2426f023
--- /dev/null
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierShipmentPickupStartEventHandler.java
@@ -0,0 +1,35 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * ***********************************************************************
+ *
+ */
+
+package org.matsim.freight.carriers.events.eventhandler;
+
+import org.matsim.core.events.handler.EventHandler;
+import org.matsim.freight.carriers.events.CarrierShipmentPickupStartEvent;
+
+/**
+ * Interface to listen to shipmentPickedUpEvents.
+ *
+ * @author sschroeder
+ *
+ */
+public interface CarrierShipmentPickupStartEventHandler extends EventHandler {
+ void handleEvent(CarrierShipmentPickupStartEvent event);
+}
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourEndEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourEndEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
index 7a91f767c4d..2d30ce4d70c 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourEndEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourEndEventHandler.java
@@ -25,7 +25,7 @@
import org.matsim.freight.carriers.events.CarrierTourEndEvent;
-public interface FreightTourEndEventHandler extends EventHandler {
+public interface CarrierTourEndEventHandler extends EventHandler {
void handleEvent( CarrierTourEndEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourStartEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
similarity index 95%
rename from contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourStartEventHandler.java
rename to contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
index 21b14f86ce0..5f4b26ce4bb 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/FreightTourStartEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/CarrierTourStartEventHandler.java
@@ -25,7 +25,7 @@
import org.matsim.freight.carriers.events.CarrierTourStartEvent;
-public interface FreightTourStartEventHandler extends EventHandler {
+public interface CarrierTourStartEventHandler extends EventHandler {
void handleEvent( CarrierTourStartEvent event );
diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
index e116ab1493e..bc9236decbf 100644
--- a/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
+++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/events/eventhandler/Vehicle2CarrierEventHandler.java
@@ -36,7 +36,7 @@
*
* @author kturner
*/
-public final class Vehicle2CarrierEventHandler implements FreightTourStartEventHandler, FreightTourEndEventHandler {
+public final class Vehicle2CarrierEventHandler implements CarrierTourStartEventHandler, CarrierTourEndEventHandler {
// Comment from Janek (in https://github.com/matsim-org/matsim-libs/pull/2128)
diff --git a/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierEventsReadersTest.java b/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierEventsReadersTest.java
new file mode 100644
index 00000000000..37a4cabaf82
--- /dev/null
+++ b/contribs/freight/src/test/java/org/matsim/freight/carriers/CarrierEventsReadersTest.java
@@ -0,0 +1,251 @@
+/*
+ * *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2023 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** *
+ */
+
+package org.matsim.freight.carriers;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.events.Event;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.core.api.experimental.events.EventsManager;
+import org.matsim.core.config.groups.ControllerConfigGroup;
+import org.matsim.core.events.EventsUtils;
+import org.matsim.core.events.algorithms.EventWriterXML;
+import org.matsim.freight.carriers.events.*;
+import org.matsim.freight.carriers.events.eventhandler.*;
+import org.matsim.testcases.MatsimTestUtils;
+import org.matsim.testcases.utils.EventsCollector;
+import org.matsim.vehicles.Vehicle;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * @author Kai Martins-Turner (kturner)
+ * @author Niclas Richter (nixlaos)
+ */
+public class CarrierEventsReadersTest {
+
+
+ @Rule
+ public final MatsimTestUtils utils = new MatsimTestUtils();
+
+ private final Id linkId = Id.createLinkId("demoLink");
+ private final Id linkId2 = Id.createLinkId("demoLink2");
+ private final Id carrierId = Id.create("testCarrier", Carrier.class);
+ private final Id vehicleId = Id.createVehicleId("myVehicle");
+
+ private final Id tourId = Id.create("myCarrierTour", Tour.class);
+ private final CarrierService service = CarrierService.Builder.newInstance(Id.create("service42", CarrierService.class), linkId2 ).build();
+ private final CarrierShipment shipment = CarrierShipment.Builder.newInstance(Id.create("shipment11", CarrierShipment.class), linkId, linkId2,7 ).build();
+
+ private final List carrierEvents = List.of(
+ new CarrierTourStartEvent(10, carrierId, linkId, vehicleId, tourId),
+ new CarrierTourEndEvent(500, carrierId, linkId, vehicleId, tourId),
+ new CarrierServiceStartEvent(20, carrierId, service, vehicleId),
+ new CarrierServiceEndEvent(25, carrierId, service, vehicleId),
+ new CarrierShipmentPickupStartEvent(100, carrierId, shipment, vehicleId),
+ new CarrierShipmentPickupEndEvent(115, carrierId, shipment, vehicleId),
+ new CarrierShipmentDeliveryStartEvent(210, carrierId, shipment, vehicleId),
+ new CarrierShipmentDeliveryEndEvent(225, carrierId, shipment, vehicleId)
+ );
+
+ @Test
+ public void testWriteReadServiceBasedEvents() {
+ EventsManager eventsManager1 = EventsUtils.createEventsManager();
+ EventsManager eventsManager2 = EventsUtils.createEventsManager();
+ EventsCollector collector1 = new EventsCollector();
+ EventsCollector collector2 = new EventsCollector();
+
+ eventsManager1.addHandler(collector1);
+ eventsManager1.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager1)
+ .readFile(utils.getClassInputDirectory() + "serviceBasedEvents.xml");
+ eventsManager1.finishProcessing();
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ EventWriterXML writer = new EventWriterXML(outputStream);
+ collector1.getEvents().forEach(writer::handleEvent);
+ writer.closeFile();
+
+ eventsManager2.addHandler(collector2);
+ eventsManager2.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager2)
+ .readStream(new ByteArrayInputStream(outputStream.toByteArray()), ControllerConfigGroup.EventsFileFormat.xml);
+ eventsManager2.finishProcessing();
+
+ Assert.assertEquals(collector1.getEvents(), collector2.getEvents());
+ }
+
+
+ @Test
+ public void testReadServiceBasedEvents() {
+
+ EventsManager eventsManager = EventsUtils.createEventsManager();
+ TestEventHandlerTours eventHandlerTours = new TestEventHandlerTours();
+ TestEventHandlerServices eventHandlerServices = new TestEventHandlerServices();
+
+ eventsManager.addHandler(eventHandlerTours);
+ eventsManager.addHandler(eventHandlerServices);
+ eventsManager.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager)
+ .readFile(utils.getClassInputDirectory() + "serviceBasedEvents.xml");
+ eventsManager.finishProcessing();
+
+ Assert.assertEquals("Number of tour related carrier events is not correct", 4 , eventHandlerTours.handledEvents.size());
+ Assert.assertEquals("Number of service related carrier events is not correct", 14 , eventHandlerServices.handledEvents.size());
+ }
+
+ @Test
+ public void testWriteReadShipmentBasedEvents() {
+ EventsManager eventsManager1 = EventsUtils.createEventsManager();
+ EventsManager eventsManager2 = EventsUtils.createEventsManager();
+ EventsCollector collector1 = new EventsCollector();
+ EventsCollector collector2 = new EventsCollector();
+
+ eventsManager1.addHandler(collector1);
+ eventsManager1.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager1)
+ .readFile(utils.getClassInputDirectory() + "shipmentBasedEvents.xml");
+ eventsManager1.finishProcessing();
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ EventWriterXML writer = new EventWriterXML(outputStream);
+ collector1.getEvents().forEach(writer::handleEvent);
+ writer.closeFile();
+
+ eventsManager2.addHandler(collector2);
+ eventsManager2.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager2)
+ .readStream(new ByteArrayInputStream(outputStream.toByteArray()), ControllerConfigGroup.EventsFileFormat.xml);
+ eventsManager2.finishProcessing();
+
+ Assert.assertEquals(collector1.getEvents(), collector2.getEvents());
+ }
+
+ @Test
+ public void testReadShipmentBasedEvents() {
+
+ EventsManager eventsManager = EventsUtils.createEventsManager();
+ TestEventHandlerTours eventHandlerTours = new TestEventHandlerTours();
+ TestEventHandlerShipments testEventHandlerShipments = new TestEventHandlerShipments();
+
+ eventsManager.addHandler(eventHandlerTours);
+ eventsManager.addHandler(testEventHandlerShipments);
+ eventsManager.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager)
+ .readFile(utils.getClassInputDirectory() + "shipmentBasedEvents.xml");
+ eventsManager.finishProcessing();
+
+ Assert.assertEquals("Number of tour related carrier events is not correct", 2 , eventHandlerTours.handledEvents.size());
+ Assert.assertEquals("Number of shipments related carrier events is not correct", 20 , testEventHandlerShipments.handledEvents.size());
+ }
+
+
+ /**
+ * This test is testing the reader with some locally created events (see above).
+ * This test is inspired by the DrtEventsReaderTest from michalm.
+ */
+ @Test
+ public void testReader() {
+ var outputStream = new ByteArrayOutputStream();
+ EventWriterXML writer = new EventWriterXML(outputStream);
+ carrierEvents.forEach(writer::handleEvent);
+ writer.closeFile();
+
+ EventsManager eventsManager = EventsUtils.createEventsManager();
+ TestEventHandlerTours eventHandlerTours = new TestEventHandlerTours();
+ TestEventHandlerServices eventHandlerServices = new TestEventHandlerServices();
+ TestEventHandlerShipments eventHandlerShipments = new TestEventHandlerShipments();
+
+ eventsManager.addHandler(eventHandlerTours);
+ eventsManager.addHandler(eventHandlerServices);
+ eventsManager.addHandler(eventHandlerShipments);
+
+ eventsManager.initProcessing();
+ CarrierEventsReaders.createEventsReader(eventsManager)
+ .readStream(new ByteArrayInputStream(outputStream.toByteArray()),
+ ControllerConfigGroup.EventsFileFormat.xml);
+ eventsManager.finishProcessing();
+
+ var handledEvents = new ArrayList();
+ handledEvents.addAll(eventHandlerTours.handledEvents);
+ handledEvents.addAll(eventHandlerServices.handledEvents);
+ handledEvents.addAll(eventHandlerShipments.handledEvents);
+
+ //Please note: This test is sensitive to the order of events as they are added in carrierEvents (input) and the resukts of the handler...
+ Assert.assertArrayEquals(carrierEvents.toArray(), handledEvents.toArray());
+ }
+
+ private static class TestEventHandlerTours
+ implements CarrierTourStartEventHandler, CarrierTourEndEventHandler {
+ private final List handledEvents = new ArrayList<>();
+
+
+ @Override public void handleEvent(CarrierTourEndEvent event) {
+ handledEvents.add(event);
+ }
+
+ @Override public void handleEvent(CarrierTourStartEvent event) {
+ handledEvents.add(event);
+ }
+ }
+
+ private static class TestEventHandlerServices
+ implements CarrierServiceStartEventHandler, CarrierServiceEndEventHandler {
+ private final List handledEvents = new ArrayList<>();
+
+ @Override public void handleEvent(CarrierServiceEndEvent event) {
+ handledEvents.add(event);
+ }
+
+ @Override public void handleEvent(CarrierServiceStartEvent event) {
+ handledEvents.add(event);
+ }
+
+ }
+
+ private static class TestEventHandlerShipments
+ implements CarrierShipmentDeliveryStartEventHandler, CarrierShipmentDeliveryEndEventHandler, CarrierShipmentPickupStartEventHandler, CarrierShipmentPickupEndEventHandler {
+ private final List handledEvents = new ArrayList<>();
+
+
+ @Override public void handleEvent(CarrierShipmentDeliveryEndEvent event) {
+ handledEvents.add(event);
+ }
+
+ @Override public void handleEvent(CarrierShipmentPickupEndEvent event) {
+ handledEvents.add(event);
+ }
+
+ @Override public void handleEvent(CarrierShipmentDeliveryStartEvent event) {
+ handledEvents.add(event);
+ }
+
+ @Override public void handleEvent(CarrierShipmentPickupStartEvent event) {
+ handledEvents.add(event);
+ }
+ }
+}
diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/serviceBasedEvents.xml b/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/serviceBasedEvents.xml
new file mode 100644
index 00000000000..b4121096264
--- /dev/null
+++ b/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/serviceBasedEvents.xml
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/shipmentBasedEvents.xml b/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/shipmentBasedEvents.xml
new file mode 100644
index 00000000000..ca675a9bcbf
--- /dev/null
+++ b/contribs/freight/test/input/org/matsim/freight/carriers/CarrierEventsReadersTest/shipmentBasedEvents.xml
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/contribs/hybridsim/pom.xml b/contribs/hybridsim/pom.xml
index 2a8fffb488b..fe40487e7f4 100644
--- a/contribs/hybridsim/pom.xml
+++ b/contribs/hybridsim/pom.xml
@@ -11,7 +11,7 @@
3.24.4
- 1.58.0
+ 1.59.0
diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java
index d151624afe2..a6229390386 100644
--- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java
+++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/InformedModeChoiceModule.java
@@ -167,7 +167,7 @@ public > Builder withFixedCosts(Class extends FixedCostsEsti
/**
* Adds a {@link LegEstimator} to one or more modes.
*/
- public > Builder withLegEstimator(Class extends LegEstimator> estimator, Class extends ModeOptions> option,
+ public > Builder withLegEstimator(Class extends LegEstimator> estimator, Class extends ModeOptions> option,
String... modes) {
for (String mode : modes) {
diff --git a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java
index 4930197c262..93c2ca21a0f 100644
--- a/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java
+++ b/contribs/informed-mode-choice/src/main/java/org/matsim/modechoice/PlanModelService.java
@@ -157,6 +157,7 @@ public List allowedModes(PlanModel planModel) {
/**
* Calculate the estimates for all options. Note that plan model has to be routed before computing estimates.
*/
+ @SuppressWarnings("rawtypes")
public void calculateEstimates(EstimatorContext context, PlanModel planModel) {
for (Map.Entry> e : planModel.getEstimates().entrySet()) {
@@ -208,7 +209,7 @@ public void calculateEstimates(EstimatorContext context, PlanModel planModel) {
if (tripEst != null && legMode.equals(c.getMode()))
continue;
- LegEstimator> legEst = (LegEstimator>) legEstimators.get(legMode);
+ LegEstimator legEst = legEstimators.get(legMode);
if (legEst == null)
throw new IllegalStateException("No leg estimator defined for mode: " + legMode);
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
index 96bbd7928c5..a5f4cdcf143 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/NearestParkingDynLeg.java
@@ -1,20 +1,21 @@
package org.matsim.contrib.parking.parkingsearch.DynAgent;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.population.Activity;
import org.matsim.api.core.v01.population.Leg;
import org.matsim.api.core.v01.population.Plan;
-import org.matsim.contrib.parking.parkingsearch.events.RemoveParkingActivityEvent;
-import org.matsim.contrib.parking.parkingsearch.events.ReserveParkingLocationEvent;
-import org.matsim.contrib.parking.parkingsearch.events.SelectNewParkingLocationEvent;
-import org.matsim.contrib.parking.parkingsearch.events.StartParkingSearchEvent;
+import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.contrib.parking.parkingsearch.events.*;
import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.search.NearestParkingSpotSearchLogic;
import org.matsim.contrib.parking.parkingsearch.search.ParkingSearchLogic;
import org.matsim.core.api.experimental.events.EventsManager;
import org.matsim.core.mobsim.framework.MobsimTimer;
+import org.matsim.core.population.PopulationUtils;
import org.matsim.core.population.routes.NetworkRoute;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.vehicles.Vehicle;
@@ -26,6 +27,7 @@
*/
public class NearestParkingDynLeg extends ParkingDynLeg {
private boolean parkingAtEndOfLeg = true;
+ private boolean passangerInteractionAtParkingFacilityAtEndOfLeg = false;
private boolean reachedDestinationWithoutParking = false;
private boolean alreadyReservedParking = false;
private boolean driveToBaseWithoutParking = false;
@@ -34,18 +36,19 @@ public class NearestParkingDynLeg extends ParkingDynLeg {
private final int planIndexNextActivity;
private Plan plan;
private Id nextSelectedParkingLink = null;
+ protected static final Logger log = LogManager.getLogger(NearestParkingDynLeg.class);
public NearestParkingDynLeg(Leg currentPlannedLeg, NetworkRoute route, Plan plan, int planIndexNextActivity, ParkingSearchLogic logic,
ParkingSearchManager parkingManager, Id vehicleId, MobsimTimer timer, EventsManager events) {
super(currentPlannedLeg.getMode(), route, logic, parkingManager, vehicleId, timer, events);
this.followingActivity = (Activity) plan.getPlanElements().get(planIndexNextActivity);
- followingActivity.setStartTime(timer.getTimeOfDay());
this.currentPlannedLeg = currentPlannedLeg;
this.plan = plan;
this.planIndexNextActivity = planIndexNextActivity;
- if (followingActivity.getAttributes().getAsMap().containsKey("parking") && followingActivity.getAttributes().getAttribute("parking").equals(
- "noParking"))
+ if (ParkingUtils.checkIfActivityHasNoParking(followingActivity))
parkingAtEndOfLeg = false;
+ if (ParkingUtils.checkIfActivityHasPassengerInteraction(followingActivity))
+ passangerInteractionAtParkingFacilityAtEndOfLeg = true;
}
@Override
@@ -85,7 +88,7 @@ public void movedOverNode(Id newLinkId) {
@Override
public Id getNextLinkId() {
- if (!parkingMode && parkingAtEndOfLeg) {
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg && (!parkingMode && parkingAtEndOfLeg)) {
parkingMode = true;
this.events.processEvent(new StartParkingSearchEvent(timer.getTimeOfDay(), vehicleId, currentLinkId));
}
@@ -98,12 +101,18 @@ public Id getNextLinkId() {
return linkIds.get(currentLinkIdx + 1);
} else {
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && !hasFoundParking && followingActivity.getLinkId().equals(currentLinkId)) {
+ createWaitingActivityUntilPassengerInteractionIsPossible(currentLinkId, vehicleId, timer.getTimeOfDay());
+ this.events
+ .processEvent(new StartWaitingForParkingEvent(timer.getTimeOfDay(), vehicleId, currentLinkId));
+ }
if (hasFoundParking || reachedDestinationWithoutParking) {
// easy, we can just park where at our destination link
- if (hasFoundParking) {
+ if (hasFoundParking && !passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ //calculate parkingTime for parking_activity
double parkingDuration;
double expectedDrivingDurationToPickup;
- double drivingDurationFromDropOff = timer.getTimeOfDay() - currentPlannedLeg.getDepartureTime().seconds();
+ double drivingDurationFromGetOff = timer.getTimeOfDay() - currentPlannedLeg.getDepartureTime().seconds();
if (nextSelectedParkingLink.equals(currentLinkId)) {
expectedDrivingDurationToPickup = ((NearestParkingSpotSearchLogic) this.logic).getExpectedTravelTime(
@@ -112,7 +121,9 @@ public Id getNextLinkId() {
expectedDrivingDurationToPickup = ((NearestParkingSpotSearchLogic) this.logic).getExpectedTravelTime(
currentPlannedLeg.getRoute().getStartLinkId(), timer.getTimeOfDay(), currentLinkId);
}
- parkingDuration = followingActivity.getMaximumDuration().seconds() - drivingDurationFromDropOff - expectedDrivingDurationToPickup;
+ parkingDuration = followingActivity.getMaximumDuration().seconds()
+ - drivingDurationFromGetOff - expectedDrivingDurationToPickup
+ - ((FacilityBasedParkingManager) parkingManager).getParkStageActivityDuration();
followingActivity.setMaximumDuration(parkingDuration);
}
this.logic.reset();
@@ -125,10 +136,19 @@ public Id getNextLinkId() {
}
}
// need to find the next link
- double nextPickupTime = followingActivity.getStartTime().seconds() + followingActivity.getMaximumDuration().seconds();
- double maxParkingDuration = followingActivity.getMaximumDuration().seconds() - (followingActivity.getStartTime().seconds() - timer.getTimeOfDay());
+ double nextPickupTime;
+ double maxParkingDuration;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg){
+ nextPickupTime = 0.;
+ maxParkingDuration = followingActivity.getMaximumDuration().seconds();
+ }
+ else {
+ nextPickupTime = currentPlannedLeg.getDepartureTime().seconds() + followingActivity.getMaximumDuration().seconds();
+ maxParkingDuration = nextPickupTime - timer.getTimeOfDay();
+ }
Id nextLinkId = ((NearestParkingSpotSearchLogic) this.logic).getNextLink(currentLinkId, route.getEndLinkId(), vehicleId, mode,
- timer.getTimeOfDay(), maxParkingDuration, nextPickupTime);
+ timer.getTimeOfDay(), maxParkingDuration, nextPickupTime, passangerInteractionAtParkingFacilityAtEndOfLeg,
+ followingActivity.getCoord());
if (((NearestParkingSpotSearchLogic) this.logic).isNextParkingActivitySkipped() && parkingAtEndOfLeg) {
removeNextActivityAndFollowingLeg();
parkingAtEndOfLeg = false;
@@ -163,9 +183,19 @@ public Id getNextLinkId() {
}
}
+ private void createWaitingActivityUntilPassengerInteractionIsPossible(Id newLinkId, Id vehicleId, double now) {
+ Activity waitingActivity = PopulationUtils.createActivityFromLinkId(ParkingUtils.WaitingForParkingActivityType, newLinkId);
+ ParkingUtils.setNoParkingForActivity(waitingActivity);
+ plan.getPlanElements().add(planIndexNextActivity, waitingActivity);
+ hasFoundParking = true;
+ ((FacilityBasedParkingManager) parkingManager).addVehicleForWaitingForParking(newLinkId, vehicleId, now);
+ }
+
private void removeNextActivityAndFollowingLeg() {
plan.getPlanElements().remove(planIndexNextActivity);
plan.getPlanElements().remove(planIndexNextActivity);
+// log.info(
+// plan.getPerson().getId().toString() + ": Parking activity after getOff point '" + ((Activity)plan.getPlanElements().get(planIndexNextActivity - 2)).getType() + "' is removed, because no parking facility was found.");
}
public boolean driveToBaseWithoutParking() {
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
index c799cbc1355..381bfd331d2 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/BenensonParkingAgentLogic.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic;
@@ -9,7 +9,6 @@
import org.matsim.api.core.v01.population.Route;
import org.matsim.contrib.dynagent.DynAction;
import org.matsim.contrib.parking.parkingsearch.DynAgent.BenensonDynLeg;
-import org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic.ParkingAgentLogic;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationLogic;
import org.matsim.contrib.parking.parkingsearch.routing.ParkingRouter;
@@ -29,37 +28,37 @@ public class BenensonParkingAgentLogic extends ParkingAgentLogic {
/**
* @param plan
* @param parkingManager
- * @param walkLegFactory
+ * @param walkRouter
* @param parkingRouter
* @param events
* @param parkingLogic
* @param timer
* @param teleportationLogic
*/
-
-
+
+
public BenensonParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
super(plan, parkingManager, walkRouter, network, parkingRouter, events, parkingLogic, timer, teleportationLogic, configGroup);
}
-
+
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
-
+
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isInitialLocation)){
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new BenensonDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
}
else throw new RuntimeException("parking location mismatch");
-
+
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
index dbe7b937923..b7358bc6a39 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/MemoryBasedParkingAgentLogic.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.DynAgent.agentLogic;
@@ -31,22 +31,22 @@ public MemoryBasedParkingAgentLogic(Plan plan, ParkingSearchManager parkingManag
super(plan, parkingManager, walkRouter, network, parkingRouter, events, parkingLogic, timer, teleportationLogic, configGroup);
}
-
+
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
-
+
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isInitialLocation)){
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new DistanceMemoryDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
}
else throw new RuntimeException("parking location mismatch");
-
+
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
index faec3310574..f3a7e671b14 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/NearestParkingSpotAgentLogic.java
@@ -10,6 +10,7 @@
import org.matsim.contrib.dynagent.StaticPassengerDynLeg;
import org.matsim.contrib.parking.parkingsearch.DynAgent.NearestParkingDynLeg;
import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.contrib.parking.parkingsearch.manager.FacilityBasedParkingManager;
import org.matsim.contrib.parking.parkingsearch.manager.ParkingSearchManager;
import org.matsim.contrib.parking.parkingsearch.manager.vehicleteleportationlogic.VehicleTeleportationLogic;
import org.matsim.contrib.parking.parkingsearch.routing.ParkingRouter;
@@ -54,50 +55,35 @@ public DynAction computeNextAction(DynAction oldAction, double now) {
if (lastParkActionState.equals(LastParkActionState.CARTRIP) && ((NearestParkingDynLeg) oldAction).driveToBaseWithoutParking())
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
- switch (lastParkActionState) {
- case ACTIVITY:
- return nextStateAfterActivity(oldAction, now);
-
- case CARTRIP:
- return nextStateAfterCarTrip(oldAction, now);
-
- case NONCARTRIP:
- return nextStateAfterNonCarTrip(oldAction, now);
-
- case PARKACTIVITY:
- return nextStateAfterParkActivity(oldAction, now);
-
- case UNPARKACTIVITY:
- return nextStateAfterUnParkActivity(oldAction, now);
-
- case WALKFROMPARK:
- return nextStateAfterWalkFromPark(oldAction, now);
-
- case WALKTOPARK:
- return nextStateAfterWalkToPark(oldAction, now);
-
- }
- throw new RuntimeException("unreachable code");
- }
+ return switch (lastParkActionState) {
+ case ACTIVITY -> nextStateAfterActivity(oldAction, now);
+ case CARTRIP -> nextStateAfterCarTrip(oldAction, now);
+ case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now);
+ case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now);
+ case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now);
+ case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now);
+ case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now);
+ };
+ }
@Override
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
Leg currentPlannedLeg = (Leg) currentPlanElement;
+ currentPlannedLeg.setDepartureTime(timer.getTimeOfDay());
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
actualRoute.setVehicleId(currentlyAssignedVehicleId);
if (!plannedRoute.getStartLinkId().equals(actualRoute.getStartLinkId()))
currentPlannedLeg.setRoute(actualRoute);
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isinitialLocation)) {
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isInitialLocation)) {
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
// Leg currentLeg = (Leg) this.currentPlanElement;
int planIndexNextActivity = planIndex + 1;
Activity nextPlanElement = (Activity) plan.getPlanElements().get(planIndexNextActivity);
- if (nextPlanElement.getAttributes().getAsMap().containsKey("parking") && nextPlanElement.getAttributes().getAttribute("parking").equals(
- "noParking"))
+ if (ParkingUtils.checkIfActivityHasNoParking(nextPlanElement))
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new NearestParkingDynLeg(currentPlannedLeg, actualRoute, plan, planIndexNextActivity, parkingLogic, parkingManager,
@@ -133,6 +119,22 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
// we could either depart by car or not next
if (plan.getPlanElements().size() >= planIndex + 1) {
+ if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType().equals(
+ ParkingUtils.WaitingForParkingActivityType)) {
+ //now the waiting activity has finished and we can park now
+ this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now);
+ return nextStateAfterNonCarTrip(oldAction, now);
+ }
+ if (plan.getPlanElements().get(planIndex + 1) instanceof Activity)
+ return nextStateAfterNonCarTrip(oldAction, now);
+ if (plan.getPlanElements().get(planIndex) instanceof Activity && ((Activity) plan.getPlanElements().get(planIndex)).getType().contains("_GetOff")) {
+ ((Activity) plan.getPlanElements().get(planIndex)).setEndTime(now);
+ ((Activity) plan.getPlanElements().get(planIndex + 4)).setStartTime(now + ((Activity) plan.getPlanElements().get(planIndex + 2)).getMaximumDuration().seconds());
+ // checks if it is possible to stay from getOff until getIn
+ boolean possibleToStay = checkIfParkingIsPossibleUntilNextActivities(this.planIndex,this.planIndex + 2);
+ if (possibleToStay)
+ return nextStateAfterNonCarTrip(oldAction, now);
+ }
planIndex++;
this.currentPlanElement = plan.getPlanElements().get(planIndex);
Leg currentLeg = (Leg) currentPlanElement;
@@ -141,7 +143,7 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Id parkLink = this.parkingManager.getVehicleParkingLocation(vehicleId);
if (parkLink == null) {
- //this is the first activity of a day and our parking manager does not provide informations about initial stages. We suppose the car is parked where we are
+ //this is the first activity of a day and our parking manager does not provide information about initial stages. We suppose the car is parked where we are
parkLink = agent.getCurrentLinkId();
}
@@ -151,14 +153,13 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Facility toFacility = new LinkWrapperFacility(network.getLinks().get(teleportedParkLink));
List extends PlanElement> walkTrip = walkRouter.calcRoute(
DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg)) {
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.currentlyAssignedVehicleId = vehicleId;
- this.stageInteractionType = ParkingUtils.PARKACTIVITYTYPE;
+ this.stageInteractionType = ParkingUtils.ParkingStageInteractionType;
if (!walkLeg.getTravelTime().equals(OptionalTime.defined(0.))) {
this.lastParkActionState = LastParkActionState.WALKTOPARK;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
@@ -188,10 +189,96 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
protected DynAction nextStateAfterWalkToPark(DynAction oldAction, double now) {
//walk2park is complete, we can unpark.
this.lastParkActionState = LastParkActionState.UNPARKACTIVITY;
- PlanElement beforePlanElement = plan.getPlanElements().get(planIndex - 1);
- if (beforePlanElement.getAttributes().getAsMap().containsKey("parking") && beforePlanElement.getAttributes().getAttribute("parking").equals(
- "noParking"))
- return nextStateAfterUnParkActivity(oldAction, now);
+ Activity beforePlanElement = (Activity) plan.getPlanElements().get(planIndex - 1);
+ if (ParkingUtils.checkIfActivityHasNoParking(beforePlanElement))
+ return nextStateAfterUnParkActivity(oldAction, now); // wenn kein Parken dann einfach weiter
return new IdleDynActivity(this.stageInteractionType, now + configGroup.getUnparkduration());
}
+
+ @Override
+ protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) {
+ if (this.plan.getPlanElements().get(planIndex + 1) instanceof Activity && ((Activity) this.plan.getPlanElements().get(
+ planIndex + 1)).getType().equals(ParkingUtils.WaitingForParkingActivityType)) {
+ //next activity is waiting for parking. Thats why we have no parkVehicleHere at this moment
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
+ return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
+ }
+ // car trip is complete, we have found a parking space (not part of the logic), block it and start to park
+ if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)) {
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
+ return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
+ } else throw new RuntimeException("No parking possible");
+ }
+
+ @Override
+ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
+
+ this.currentPlanElement = plan.getPlanElements().get(planIndex + 1);
+ Activity nextPlannedActivity = (Activity) this.currentPlanElement;
+ // checks if you can extend parking here until getIn
+ if (nextPlannedActivity.getType().equals(ParkingUtils.ParkingActivityType) && plan.getPlanElements().get(planIndex + 2) instanceof Leg) {
+ checkIfParkingIsPossibleUntilNextActivities(planIndex + 1,planIndex + 1);
+ }
+ // switch back to activity
+ planIndex++;
+ this.lastParkActionState = LastParkActionState.ACTIVITY;
+ final double endTime;
+ if (nextPlannedActivity.getEndTime().isUndefined()) {
+ if (nextPlannedActivity.getMaximumDuration().isUndefined()) {
+ endTime = Double.POSITIVE_INFINITY;
+ //last activity of a day
+ } else {
+ endTime = now + nextPlannedActivity.getMaximumDuration().seconds();
+ }
+ } else {
+ endTime = nextPlannedActivity.getEndTime().seconds();
+ }
+ return new IdleDynActivity(nextPlannedActivity.getType(), endTime);
+
+ }
+
+ private boolean checkIfParkingIsPossibleUntilNextActivities(int indexOfCurrentActivity, int indexOfParkingActivity) {
+ int indexOfFollowingActivity = indexOfCurrentActivity + 2;
+ Activity followingActivity = ((Activity) plan.getPlanElements().get(indexOfFollowingActivity));
+ //checks if it is possible to stay from the current getOff until the getIn
+ if (indexOfFollowingActivity == indexOfParkingActivity) {
+ Activity currentActivity = ((Activity) plan.getPlanElements().get(this.planIndex));
+ Activity activityAfterFollowing = ((Activity) plan.getPlanElements().get(this.planIndex + 4));
+ if (agent.getCurrentLinkId().equals(activityAfterFollowing.getLinkId()) && !ParkingUtils.checkIfActivityHasNoParking(
+ (Activity) currentPlanElement)) {
+ boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd(
+ agent.getCurrentLinkId(),
+ followingActivity.getMaximumDuration().seconds(), currentActivity.getMaximumDuration().seconds(),
+ activityAfterFollowing.getMaximumDuration().seconds(), timer.getTimeOfDay());
+ if (canParkAtFacilityUntilGetIn) {
+ plan.getPlanElements().remove(this.planIndex + 3);
+ plan.getPlanElements().remove(this.planIndex + 1);
+ ((FacilityBasedParkingManager) parkingManager).registerStayFromGetOffUntilGetIn(this.agent.getVehicle().getId());
+ return true;
+ }
+ }
+ }
+ // checks if the now started parking activity can extend until the end of the following GetIn activity
+ else if (indexOfCurrentActivity == indexOfParkingActivity) {
+ Activity currentActivity = ((Activity) plan.getPlanElements().get(this.planIndex + 1));
+ if (agent.getCurrentLinkId().equals(followingActivity.getLinkId()) && !ParkingUtils.checkIfActivityHasNoParking(
+ followingActivity)) {
+ boolean canParkAtFacilityUntilGetIn = ((FacilityBasedParkingManager) parkingManager).canParkAtThisFacilityUntilEnd(
+ agent.getCurrentLinkId(),
+ currentActivity.getMaximumDuration().seconds(), 0.,
+ followingActivity.getMaximumDuration().seconds(), timer.getTimeOfDay());
+ if (canParkAtFacilityUntilGetIn) {
+ plan.getPlanElements().remove(indexOfParkingActivity + 1);
+ currentActivity.setEndTime(followingActivity.getStartTime().seconds());
+ ((FacilityBasedParkingManager) parkingManager).registerParkingBeforeGetIn(this.agent.getVehicle().getId());
+ return true;
+ }
+ }
+ }
+ return false;
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
index 2bda5aa8698..dd2fb4fa74b 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/DynAgent/agentLogic/ParkingAgentLogic.java
@@ -59,25 +59,25 @@
/**
* @author jbischoff
- *
*/
public class ParkingAgentLogic implements DynAgentLogic {
- public enum LastParkActionState {
+ public enum LastParkActionState {
- // we have the following cases of ending dynacts:
- NONCARTRIP, // non-car trip arrival: start Activity
- CARTRIP, // car-trip arrival: add park-car activity
- PARKACTIVITY, // park-car activity: get next PlanElement & add walk leg to activity location
- WALKFROMPARK ,// walk-leg to act: start next PlanElement Activity
- ACTIVITY, // ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
- WALKTOPARK, // walk-leg to car: add unpark activity
- UNPARKACTIVITY // unpark activity: find the way to the next route & start leg
+ // we have the following cases of ending dynacts:
+ NONCARTRIP, // non-car trip arrival: start Activity
+ CARTRIP, // car-trip arrival: add park-car activity
+ PARKACTIVITY, // park-car activity: get next PlanElement & add walk leg to activity location
+ WALKFROMPARK,// walk-leg to act: start next PlanElement Activity
+ ACTIVITY, // ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
+ WALKTOPARK, // walk-leg to car: add unpark activity
+ UNPARKACTIVITY // unpark activity: find the way to the next route & start leg
}
+
protected LastParkActionState lastParkActionState;
protected DynAgent agent;
protected int planIndex;
-// protected Iterator planElemIter;
+ // protected Iterator planElemIter;
protected Plan plan;
protected PlanElement currentPlanElement;
protected ParkingSearchManager parkingManager;
@@ -88,20 +88,18 @@ public enum LastParkActionState {
protected EventsManager events;
protected ParkingSearchLogic parkingLogic;
protected VehicleTeleportationLogic teleportationLogic;
- protected boolean isinitialLocation = true;
+ protected boolean isInitialLocation = true;
protected Id currentlyAssignedVehicleId = null;
protected String stageInteractionType = null;
protected ParkingSearchConfigGroup configGroup;
protected static final Logger log = LogManager.getLogger(ParkingAgentLogic.class);
/**
- * @param plan
- * (always starts with Activity)
+ * @param plan (always starts with Activity)
*/
- public ParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
- ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
- VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
-// planElemIter = plan.getPlanElements().iterator();
+ public ParkingAgentLogic(Plan plan, ParkingSearchManager parkingManager, RoutingModule walkRouter, Network network,
+ ParkingRouter parkingRouter, EventsManager events, ParkingSearchLogic parkingLogic, MobsimTimer timer,
+ VehicleTeleportationLogic teleportationLogic, ParkingSearchConfigGroup configGroup) {
this.plan = plan;
this.parkingManager = parkingManager;
this.walkRouter = walkRouter;
@@ -141,32 +139,17 @@ public DynAction computeNextAction(DynAction oldAction, double now) {
// ordinary activity: get next Leg, if car: go to car, otherwise add ordinary leg by other mode
// walk-leg to car: add unpark activity
// unpark activity: find the way to the next route & start leg
- switch (lastParkActionState){
- case ACTIVITY:
- return nextStateAfterActivity(oldAction, now);
-
- case CARTRIP:
- return nextStateAfterCarTrip(oldAction,now);
-
- case NONCARTRIP:
- return nextStateAfterNonCarTrip(oldAction,now);
-
- case PARKACTIVITY:
- return nextStateAfterParkActivity(oldAction,now);
-
- case UNPARKACTIVITY:
- return nextStateAfterUnParkActivity(oldAction,now);
-
- case WALKFROMPARK:
- return nextStateAfterWalkFromPark(oldAction,now);
-
- case WALKTOPARK:
- return nextStateAfterWalkToPark(oldAction,now);
-
- }
- throw new RuntimeException("unreachable code");
-
- }
+ return switch (lastParkActionState) {
+ case ACTIVITY -> nextStateAfterActivity(oldAction, now);
+ case CARTRIP -> nextStateAfterCarTrip(oldAction, now);
+ case NONCARTRIP -> nextStateAfterNonCarTrip(oldAction, now);
+ case PARKACTIVITY -> nextStateAfterParkActivity(oldAction, now);
+ case UNPARKACTIVITY -> nextStateAfterUnParkActivity(oldAction, now);
+ case WALKFROMPARK -> nextStateAfterWalkFromPark(oldAction, now);
+ case WALKTOPARK -> nextStateAfterWalkToPark(oldAction, now);
+ };
+
+ }
protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now) {
// we have unparked, now we need to get going by car again.
@@ -174,15 +157,14 @@ protected DynAction nextStateAfterUnParkActivity(DynAction oldAction, double now
Leg currentPlannedLeg = (Leg) currentPlanElement;
Route plannedRoute = currentPlannedLeg.getRoute();
NetworkRoute actualRoute = this.parkingRouter.getRouteFromParkingToDestination(plannedRoute.getEndLinkId(), now, agent.getCurrentLinkId());
- if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now))||(isinitialLocation)){
+ if ((this.parkingManager.unParkVehicleHere(currentlyAssignedVehicleId, agent.getCurrentLinkId(), now)) || (isInitialLocation)) {
this.lastParkActionState = LastParkActionState.CARTRIP;
- isinitialLocation = false;
+ isInitialLocation = false;
Leg currentLeg = (Leg) this.currentPlanElement;
//this could be Car, Carsharing, Motorcylce, or whatever else mode we have, so we want our leg to reflect this.
return new ParkingDynLeg(currentLeg.getMode(), actualRoute, parkingLogic, parkingManager, currentlyAssignedVehicleId, timer, events);
- }
- else throw new RuntimeException("parking location mismatch");
+ } else throw new RuntimeException("parking location mismatch");
}
@@ -200,15 +182,15 @@ protected DynAction nextStateAfterWalkFromPark(DynAction oldAction, double now)
protected DynAction nextStateAfterParkActivity(DynAction oldAction, double now) {
// add a walk leg after parking
Leg currentPlannedLeg = (Leg) currentPlanElement;
- Facility fromFacility = new LinkWrapperFacility (network.getLinks().get(agent.getCurrentLinkId()));
- Facility toFacility = new LinkWrapperFacility (network.getLinks().get(currentPlannedLeg.getRoute().getEndLinkId()));
- List extends PlanElement> walkTrip = walkRouter.calcRoute(DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || ! (walkTrip.get(0) instanceof Leg)) {
+ Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId()));
+ Facility toFacility = new LinkWrapperFacility(network.getLinks().get(currentPlannedLeg.getRoute().getEndLinkId()));
+ List extends PlanElement> walkTrip = walkRouter.calcRoute(
+ DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.lastParkActionState = LastParkActionState.WALKFROMPARK;
this.stageInteractionType = null;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
@@ -223,11 +205,11 @@ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
final double endTime;
if (nextPlannedActivity.getEndTime().isUndefined()) {
if (nextPlannedActivity.getMaximumDuration().isUndefined()) {
- endTime = Double.POSITIVE_INFINITY;
- //last activity of a day
- } else {
+ endTime = Double.POSITIVE_INFINITY;
+ //last activity of a day
+ } else {
endTime = now + nextPlannedActivity.getMaximumDuration().seconds();
- }
+ }
} else {
endTime = nextPlannedActivity.getEndTime().seconds();
}
@@ -237,13 +219,12 @@ protected DynAction nextStateAfterNonCarTrip(DynAction oldAction, double now) {
protected DynAction nextStateAfterCarTrip(DynAction oldAction, double now) {
// car trip is complete, we have found a parking space (not part of the logic), block it and start to park
- if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)){
- this.lastParkActionState = LastParkActionState.PARKACTIVITY;
- this.currentlyAssignedVehicleId = null;
- this.parkingLogic.reset();
+ if (this.parkingManager.parkVehicleHere(Id.create(this.agent.getId(), Vehicle.class), agent.getCurrentLinkId(), now)) {
+ this.lastParkActionState = LastParkActionState.PARKACTIVITY;
+ this.currentlyAssignedVehicleId = null;
+ this.parkingLogic.reset();
return new IdleDynActivity(this.stageInteractionType, now + configGroup.getParkduration());
- }
- else throw new RuntimeException ("No parking possible");
+ } else throw new RuntimeException("No parking possible");
}
protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
@@ -263,19 +244,18 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
Facility fromFacility = new LinkWrapperFacility(network.getLinks().get(agent.getCurrentLinkId()));
Id teleportedParkLink = this.teleportationLogic.getVehicleLocation(agent.getCurrentLinkId(), vehicleId, parkLink, now,
- currentLeg.getMode());
+ currentLeg.getMode());
Facility toFacility = new LinkWrapperFacility(network.getLinks().get(teleportedParkLink));
List extends PlanElement> walkTrip = walkRouter.calcRoute(
- DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
- if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg)) {
+ DefaultRoutingRequest.withoutAttributes(fromFacility, toFacility, now, plan.getPerson()));
+ if (walkTrip.size() != 1 || !(walkTrip.get(0) instanceof Leg walkLeg)) {
String message = "walkRouter returned something else than a single Leg, e.g. it routes walk on the network with non_network_walk to access the network. Not implemented in parking yet!";
log.error(message);
throw new RuntimeException(message);
}
- Leg walkLeg = (Leg) walkTrip.get(0);
this.lastParkActionState = LastParkActionState.WALKTOPARK;
this.currentlyAssignedVehicleId = vehicleId;
- this.stageInteractionType = ParkingUtils.PARKACTIVITYTYPE;
+ this.stageInteractionType = ParkingUtils.ParkingStageInteractionType;
return new StaticPassengerDynLeg(walkLeg.getRoute(), walkLeg.getMode());
} else if (currentLeg.getMode().equals(TransportMode.pt)) {
if (currentLeg.getRoute() instanceof TransitPassengerRoute) {
@@ -292,8 +272,8 @@ protected DynAction nextStateAfterActivity(DynAction oldAction, double now) {
}
} else throw new RuntimeException(
- "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime(
- now));
+ "no more leg to follow but activity is ending\nLastPlanElement: " + currentPlanElement.toString() + "\n Agent " + this.agent.getId() + "\nTime: " + Time.writeTime(
+ now));
}
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
index fc5abd290c6..c3f2a38eb87 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/ParkingUtils.java
@@ -21,18 +21,21 @@
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.population.Activity;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
- * @author jbischoff, tschlenther
+ * @author jbischoff, tschlenther, Ricardo Ewert
*
*/
public class ParkingUtils {
- static public final String PARKACTIVITYTYPE = "parking";
+ static public final String ParkingStageInteractionType = "parking";
+ static public final String ParkingActivityType = "parking_activity";
+ static public final String WaitingForParkingActivityType = "waitingForParkingSpace_activity";
static public final int NO_OF_LINKS_TO_GET_ON_ROUTE = 5;
@@ -143,4 +146,45 @@ public static List getOutgoingLinksForMode(Link link, String mode) {
return outGoingModeLinks;
}
+ /**
+ * Checks if the activity has parking while the activity.
+ *
+ * @param followingActivity
+ * @return
+ */
+ public static boolean checkIfActivityHasNoParking(Activity followingActivity) {
+ return followingActivity.getAttributes().getAsMap().containsKey("parking") && followingActivity.getAttributes().getAttribute(
+ "parking").equals("noParking");
+
+ }
+
+ /**
+ * Sets that while this activity we simulate no parking activities.
+ *
+ * @param activity
+ */
+ public static void setNoParkingForActivity(Activity activity) {
+ activity.getAttributes().putAttribute("parking", "noParking");
+ }
+
+ /**
+ * This activity has a passenger interaction. This would mean that the location is fixed, and can not be changed.
+ *
+ * @param activity
+ */
+ public static void setPassangerInteractionForActivity(Activity activity) {
+ activity.getAttributes().putAttribute("parking", "PassangerInteraction");
+ }
+
+ /**
+ * Checks if the activity has a passanger interaction. This would mean that the location is fixed, and can not be changed.
+ *
+ * @param activity
+ * @return
+ */
+ public static boolean checkIfActivityHasPassengerInteraction(Activity activity) {
+ return activity.getAttributes().getAsMap().containsKey("parking") && activity.getAttributes().getAttribute(
+ "parking").equals(
+ "PassangerInteraction");
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
index 9203fe45526..41e370c8065 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingListener.java
@@ -26,9 +26,13 @@
import org.matsim.core.controler.OutputDirectoryHierarchy;
import org.matsim.core.controler.events.IterationEndsEvent;
import org.matsim.core.controler.listener.IterationEndsListener;
+import org.matsim.core.mobsim.framework.events.MobsimBeforeSimStepEvent;
+import org.matsim.core.mobsim.framework.events.MobsimInitializedEvent;
+import org.matsim.core.mobsim.framework.listeners.MobsimBeforeSimStepListener;
+import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener;
+import org.matsim.core.mobsim.qsim.QSim;
import org.matsim.core.utils.io.IOUtils;
-
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.List;
@@ -38,7 +42,7 @@
*
*/
-public class ParkingListener implements IterationEndsListener {
+public class ParkingListener implements IterationEndsListener, MobsimBeforeSimStepListener, MobsimInitializedListener {
@Inject
ParkingSearchManager manager;
@@ -59,7 +63,7 @@ private void writeStatsByTimesteps(List produceBeneStatistics, int itera
BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStatsPerTimeSteps.csv"));
try {
- String header = "time;rejectedReservations;foundParking;unpark";
+ String header = "time;rejectedParkingRequest;foundParking;unpark";
bw.write(header);
bw.newLine();
for (String s : produceBeneStatistics){
@@ -82,7 +86,7 @@ private void writeStats(List produceStatistics, int iteration) {
BufferedWriter bw = IOUtils.getBufferedWriter(output.getIterationFilename(iteration, "parkingStats.csv"));
try {
- String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedReservations";
+ String header = "linkId;X;Y;parkingFacility;capacity;EndOccupation;reservationsRequests;numberOfParkedVehicles;rejectedParkingRequest;numberOfWaitingActivities;numberOfStaysFromGetOffUntilGetIn;numberOfParkingBeforeGetIn";
bw.write(header);
bw.newLine();
for (String s : produceStatistics){
@@ -99,4 +103,15 @@ private void writeStats(List produceStatistics, int iteration) {
}
+ @Override
+ public void notifyMobsimBeforeSimStep(MobsimBeforeSimStepEvent event) {
+ ((FacilityBasedParkingManager) manager).checkFreeCapacitiesForWaitingVehicles((QSim) event.getQueueSimulation(), event.getSimulationTime());
+ }
+
+ @Override
+ public void notifyMobsimInitialized(final MobsimInitializedEvent e) {
+ QSim qSim = (QSim) e.getQueueSimulation();
+ ((FacilityBasedParkingManager) manager).setQSim(qSim);
+
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
index e475acbb181..50587d72059 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/evaluation/ParkingSlotVisualiser.java
@@ -1,202 +1,202 @@
-/* *********************************************************************** *
- * project: org.matsim.*
- * *********************************************************************** *
- * *
- * copyright : (C) ${year} by the members listed in the COPYING, *
- * LICENSE and WARRANTY file. *
- * email : info at matsim dot org *
- * *
- * *********************************************************************** *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * See also COPYING, LICENSE and WARRANTY file *
- * *
- * *********************************************************************** */
-
-package org.matsim.contrib.parking.parkingsearch.evaluation;
-
-import com.google.inject.Inject;
-import org.apache.commons.lang3.mutable.MutableDouble;
-import org.apache.logging.log4j.LogManager;
-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.events.PersonEntersVehicleEvent;
-import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent;
-import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
-import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
-import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
-import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler;
-import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler;
-import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler;
-import org.matsim.api.core.v01.network.Link;
-import org.matsim.api.core.v01.network.Network;
-import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
-import org.matsim.core.controler.events.IterationEndsEvent;
-import org.matsim.core.controler.listener.IterationEndsListener;
-import org.matsim.core.gbl.MatsimRandom;
-import org.matsim.core.utils.collections.Tuple;
-import org.matsim.core.utils.io.IOUtils;
-import org.matsim.facilities.ActivityFacility;
-import org.matsim.vehicles.Vehicle;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.util.*;
-import java.util.Map.Entry;
-
-public class ParkingSlotVisualiser implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, VehicleLeavesTrafficEventHandler, VehicleEntersTrafficEventHandler, IterationEndsListener {
-
- Network network;
-
- protected Map, ParkingSlotManager> slotsOnLink = new HashMap, ParkingSlotManager>();
- protected Map, Double> midnightParkers = new HashMap, Double>();
- protected Map, ParkingSlotManager> vehiclesResponsibleManager = new HashMap<>();
- Random r = MatsimRandom.getLocalInstance();
- protected List parkings = new ArrayList<>();
-
- Map, Id> parkedVehicles = new HashMap, Id>();
-
- /**
- *
- */
- @Inject
- public ParkingSlotVisualiser(Scenario scenario) {
- this.network = scenario.getNetwork();
- Map, ActivityFacility> parkingFacilities = scenario.getActivityFacilities().getFacilitiesForActivityType(
- ParkingUtils.PARKACTIVITYTYPE);
- initialize(parkingFacilities);
- }
-
- public ParkingSlotVisualiser(Network network, Map, ActivityFacility> parkingFacilities) {
- this.network = network;
- initialize(parkingFacilities);
- }
-
- private void initialize(Map, ActivityFacility> parkingFacilities) {
- Map, MutableDouble> nrOfSlotsPerLink = new HashMap, MutableDouble>();
- for (ActivityFacility fac : parkingFacilities.values()) {
- Id linkId = fac.getLinkId();
- if (nrOfSlotsPerLink.containsKey(linkId)) {
- nrOfSlotsPerLink.get(linkId).add(fac.getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity());
- } else {
- nrOfSlotsPerLink.put(linkId, new MutableDouble(fac.getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity()));
- }
- }
-
- for (Id linkID : nrOfSlotsPerLink.keySet()) {
-// LogManager.getLogger(getClass()).info("initialize parking visualisation for link " + linkID);
- this.slotsOnLink.put(linkID, new ParkingSlotManager(network.getLinks().get(linkID), nrOfSlotsPerLink.get(linkID).intValue()));
- }
- }
-
-
- @Override
- public void reset(int iteration) {
- for (Id link : this.slotsOnLink.keySet()) {
- this.slotsOnLink.get(link).setAllParkingTimesToZero();
- }
- }
-
- @Override
- public void handleEvent(VehicleLeavesTrafficEvent event) {
- if (this.slotsOnLink.containsKey(event.getLinkId())) {
- this.vehiclesResponsibleManager.put(event.getVehicleId(), this.slotsOnLink.get(event.getLinkId()));
- }
- }
-
- @Override
- public void handleEvent(PersonLeavesVehicleEvent event) {
- ParkingSlotManager manager = this.vehiclesResponsibleManager.remove(event.getVehicleId());
- if (manager != null) {
- Tuple parkingTuple = manager.processParking(event.getTime(), event.getVehicleId());
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
- this.parkedVehicles.put(event.getVehicleId(), manager.getLinkId());
- }
- }
-
-
- @Override
- public void handleEvent(PersonEntersVehicleEvent event) {
- if (this.parkedVehicles.containsKey(event.getVehicleId())) {
- ParkingSlotManager manager = this.slotsOnLink.get(this.parkedVehicles.get(event.getVehicleId()));
- Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
- this.parkedVehicles.remove(event.getVehicleId());
- } else {
- midnightParkers.put(event.getVehicleId(), event.getTime());
- }
- }
-
- /* (non-Javadoc)
- * @see org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler#handleEvent(org.matsim.api.core.v01.events.VehicleEntersTrafficEvent)
- */
- @Override
- public void handleEvent(VehicleEntersTrafficEvent event) {
- if (this.midnightParkers.containsKey(event.getVehicleId())) {
- if (this.slotsOnLink.containsKey(event.getLinkId())) {
- ParkingSlotManager manager = this.slotsOnLink.get(event.getLinkId());
- Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
- if (parkingTuple != null) {
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
- }
- }
- this.midnightParkers.remove(event.getVehicleId());
- }
- }
-
- public void finishDay() {
-
- for (Id linkId : this.slotsOnLink.keySet()) {
- ParkingSlotManager manager = this.slotsOnLink.get(linkId);
- Map, Tuple> occupiedSlots = manager.getOccupiedSlots();
-
- double endOfDay = 30 * 3600;
- for (Entry, Tuple> e : occupiedSlots.entrySet()) {
- Tuple parkingTuple = e.getValue();
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + e.getKey());
-
- // set back to 0
- }
-
- List> freeSlots = manager.getFreeSlots();
- for (Tuple parkingTuple : freeSlots) {
- this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
- parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
- }
- }
- }
-
- public void plotSlotOccupation(String filename) {
- String head = "LinkId;from;To;X;Y;OccupiedByVehicle";
- BufferedWriter bw = IOUtils.getBufferedWriter(filename);
- try {
- bw.write(head);
- for (String s : this.parkings) {
- bw.newLine();
- bw.write(s);
- }
- bw.flush();
- bw.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- LogManager.getLogger(getClass()).info("FINISHED WRITING PARKING SLOT VISUALISATION FILE TO: " + filename);
- }
-
- @Override
- public void notifyIterationEnds(IterationEndsEvent event) {
- String path = event.getServices().getControlerIO().getIterationFilename(event.getIteration(),
- "ParkingSlots_it" + event.getIteration() + ".csv");
- this.finishDay();
- this.plotSlotOccupation(path);
- }
-}
-
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *********************************************************************** *
+ * *
+ * copyright : (C) ${year} by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.evaluation;
+
+import com.google.inject.Inject;
+import org.apache.commons.lang3.mutable.MutableDouble;
+import org.apache.logging.log4j.LogManager;
+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.events.PersonEntersVehicleEvent;
+import org.matsim.api.core.v01.events.PersonLeavesVehicleEvent;
+import org.matsim.api.core.v01.events.VehicleEntersTrafficEvent;
+import org.matsim.api.core.v01.events.VehicleLeavesTrafficEvent;
+import org.matsim.api.core.v01.events.handler.PersonEntersVehicleEventHandler;
+import org.matsim.api.core.v01.events.handler.PersonLeavesVehicleEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler;
+import org.matsim.api.core.v01.events.handler.VehicleLeavesTrafficEventHandler;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.api.core.v01.network.Network;
+import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
+import org.matsim.core.controler.events.IterationEndsEvent;
+import org.matsim.core.controler.listener.IterationEndsListener;
+import org.matsim.core.gbl.MatsimRandom;
+import org.matsim.core.utils.collections.Tuple;
+import org.matsim.core.utils.io.IOUtils;
+import org.matsim.facilities.ActivityFacility;
+import org.matsim.vehicles.Vehicle;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.util.*;
+import java.util.Map.Entry;
+
+public class ParkingSlotVisualiser implements PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, VehicleLeavesTrafficEventHandler, VehicleEntersTrafficEventHandler, IterationEndsListener {
+
+ Network network;
+
+ protected Map, ParkingSlotManager> slotsOnLink = new HashMap, ParkingSlotManager>();
+ protected Map, Double> midnightParkers = new HashMap, Double>();
+ protected Map, ParkingSlotManager> vehiclesResponsibleManager = new HashMap<>();
+ Random r = MatsimRandom.getLocalInstance();
+ protected List parkings = new ArrayList<>();
+
+ protected Map, Id> parkedVehicles = new HashMap, Id>();
+
+ /**
+ *
+ */
+ @Inject
+ public ParkingSlotVisualiser(Scenario scenario) {
+ this.network = scenario.getNetwork();
+ Map, ActivityFacility> parkingFacilities = scenario.getActivityFacilities().getFacilitiesForActivityType(
+ ParkingUtils.ParkingStageInteractionType);
+ initialize(parkingFacilities);
+ }
+
+ public ParkingSlotVisualiser(Network network, Map, ActivityFacility> parkingFacilities) {
+ this.network = network;
+ initialize(parkingFacilities);
+ }
+
+ private void initialize(Map, ActivityFacility> parkingFacilities) {
+ Map, MutableDouble> nrOfSlotsPerLink = new HashMap, MutableDouble>();
+ for (ActivityFacility fac : parkingFacilities.values()) {
+ Id linkId = fac.getLinkId();
+ if (nrOfSlotsPerLink.containsKey(linkId)) {
+ nrOfSlotsPerLink.get(linkId).add(fac.getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity());
+ } else {
+ nrOfSlotsPerLink.put(linkId, new MutableDouble(fac.getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity()));
+ }
+ }
+
+ for (Id linkID : nrOfSlotsPerLink.keySet()) {
+// LogManager.getLogger(getClass()).info("initialize parking visualisation for link " + linkID);
+ this.slotsOnLink.put(linkID, new ParkingSlotManager(network.getLinks().get(linkID), nrOfSlotsPerLink.get(linkID).intValue()));
+ }
+ }
+
+
+ @Override
+ public void reset(int iteration) {
+ for (Id link : this.slotsOnLink.keySet()) {
+ this.slotsOnLink.get(link).setAllParkingTimesToZero();
+ }
+ }
+
+ @Override
+ public void handleEvent(VehicleLeavesTrafficEvent event) {
+ if (this.slotsOnLink.containsKey(event.getLinkId())) {
+ this.vehiclesResponsibleManager.put(event.getVehicleId(), this.slotsOnLink.get(event.getLinkId()));
+ }
+ }
+
+ @Override
+ public void handleEvent(PersonLeavesVehicleEvent event) {
+ ParkingSlotManager manager = this.vehiclesResponsibleManager.remove(event.getVehicleId());
+ if (manager != null) {
+ Tuple parkingTuple = manager.processParking(event.getTime(), event.getVehicleId());
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
+ this.parkedVehicles.put(event.getVehicleId(), manager.getLinkId());
+ }
+ }
+
+
+ @Override
+ public void handleEvent(PersonEntersVehicleEvent event) {
+ if (this.parkedVehicles.containsKey(event.getVehicleId())) {
+ ParkingSlotManager manager = this.slotsOnLink.get(this.parkedVehicles.get(event.getVehicleId()));
+ Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
+ this.parkedVehicles.remove(event.getVehicleId());
+ } else {
+ midnightParkers.put(event.getVehicleId(), event.getTime());
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.matsim.api.core.v01.events.handler.VehicleEntersTrafficEventHandler#handleEvent(org.matsim.api.core.v01.events.VehicleEntersTrafficEvent)
+ */
+ @Override
+ public void handleEvent(VehicleEntersTrafficEvent event) {
+ if (this.midnightParkers.containsKey(event.getVehicleId())) {
+ if (this.slotsOnLink.containsKey(event.getLinkId())) {
+ ParkingSlotManager manager = this.slotsOnLink.get(event.getLinkId());
+ Tuple parkingTuple = manager.processUnParking(event.getTime(), event.getVehicleId());
+ if (parkingTuple != null) {
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + event.getTime() + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + event.getVehicleId());
+ }
+ }
+ this.midnightParkers.remove(event.getVehicleId());
+ }
+ }
+
+ public void finishDay() {
+
+ for (Id linkId : this.slotsOnLink.keySet()) {
+ ParkingSlotManager manager = this.slotsOnLink.get(linkId);
+ Map, Tuple> occupiedSlots = manager.getOccupiedSlots();
+
+ double endOfDay = 30 * 3600;
+ for (Entry, Tuple> e : occupiedSlots.entrySet()) {
+ Tuple parkingTuple = e.getValue();
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "veh" + e.getKey());
+
+ // set back to 0
+ }
+
+ List> freeSlots = manager.getFreeSlots();
+ for (Tuple parkingTuple : freeSlots) {
+ this.parkings.add(manager.getLinkId() + ";" + parkingTuple.getSecond() + ";" + endOfDay + ";" +
+ parkingTuple.getFirst().getX() + ";" + parkingTuple.getFirst().getY() + ";" + "free");
+ }
+ }
+ }
+
+ public void plotSlotOccupation(String filename) {
+ String head = "LinkId;from;To;X;Y;OccupiedByVehicle";
+ BufferedWriter bw = IOUtils.getBufferedWriter(filename);
+ try {
+ bw.write(head);
+ for (String s : this.parkings) {
+ bw.newLine();
+ bw.write(s);
+ }
+ bw.flush();
+ bw.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ LogManager.getLogger(getClass()).info("FINISHED WRITING PARKING SLOT VISUALISATION FILE TO: " + filename);
+ }
+
+ @Override
+ public void notifyIterationEnds(IterationEndsEvent event) {
+ String path = event.getServices().getControlerIO().getIterationFilename(event.getIteration(),
+ "ParkingSlots_it" + event.getIteration() + ".csv");
+ this.finishDay();
+ this.plotSlotOccupation(path);
+ }
+}
+
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java
new file mode 100644
index 00000000000..992fd8763e6
--- /dev/null
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEvent.java
@@ -0,0 +1,68 @@
+/* *********************************************************************** *
+ * project: org.matsim.*
+ * *
+ * *********************************************************************** *
+ * *
+ * copyright : (C) 2016 by the members listed in the COPYING, *
+ * LICENSE and WARRANTY file. *
+ * email : info at matsim dot org *
+ * *
+ * *********************************************************************** *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * See also COPYING, LICENSE and WARRANTY file *
+ * *
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.events;
+
+import org.matsim.api.core.v01.Id;
+import org.matsim.api.core.v01.events.Event;
+import org.matsim.api.core.v01.network.Link;
+import org.matsim.vehicles.Vehicle;
+
+import java.util.Map;
+
+/**
+ * @author jbischoff
+ */
+
+public class StartWaitingForParkingEvent extends Event {
+ public static final String EVENT_TYPE = "started waiting for parking";
+ public static final String ATTRIBUTE_VEHICLE = "vehicle";
+ public static final String ATTRIBUTE_LINK = "link";
+ private final Id linkId;
+ private final Id vehicleId;
+
+ public StartWaitingForParkingEvent(final double time, Id vehicleId, Id linkId) {
+ super(time);
+ this.linkId = linkId;
+ this.vehicleId = vehicleId;
+
+ }
+
+ @Override
+ public String getEventType() {
+ return EVENT_TYPE;
+ }
+
+ public Id getLinkId() {
+ return linkId;
+ }
+
+ public Id getVehicleId() {
+ return vehicleId;
+ }
+
+ @Override
+ public Map getAttributes() {
+ Map attr = super.getAttributes();
+ attr.put(ATTRIBUTE_VEHICLE, this.vehicleId.toString());
+ attr.put(ATTRIBUTE_LINK, this.linkId.toString());
+ return attr;
+ }
+
+}
diff --git a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java
similarity index 60%
rename from contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java
rename to contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java
index 225d5be689d..24d5beb7d33 100644
--- a/contribs/ev/src/main/java/org/matsim/contrib/ev/fleet/ElectricVehicleSpecifications.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/events/StartWaitingForParkingEventHandler.java
@@ -1,9 +1,9 @@
-/*
- * *********************************************************************** *
+/* *********************************************************************** *
* project: org.matsim.*
+ * *
* *********************************************************************** *
* *
- * copyright : (C) 2022 by the members listed in the COPYING, *
+ * copyright : (C) 2016 by the members listed in the COPYING, *
* LICENSE and WARRANTY file. *
* email : info at matsim dot org *
* *
@@ -15,22 +15,18 @@
* (at your option) any later version. *
* See also COPYING, LICENSE and WARRANTY file *
* *
- * *********************************************************************** *
- */
+ * *********************************************************************** */
+
+package org.matsim.contrib.parking.parkingsearch.events;
-package org.matsim.contrib.ev.fleet;
+import org.matsim.core.events.handler.EventHandler;
-import java.util.Collection;
+/**
+ * @author jbischoff
+ */
-import org.matsim.vehicles.EngineInformation;
-import org.matsim.vehicles.Vehicle;
+public interface StartWaitingForParkingEventHandler extends EventHandler {
-public class ElectricVehicleSpecifications {
- public static void setInitialSoc(Vehicle vehicle, double initialSoc) {
- vehicle.getAttributes().putAttribute(ElectricVehicleSpecificationImpl.INITIAL_SOC, initialSoc);
- }
+ public void handleEvent(StartWaitingForParkingEvent event);
- public static void setChargerTypes(EngineInformation engineInformation, Collection chargerTypes) {
- engineInformation.getAttributes().putAttribute(ElectricVehicleSpecificationImpl.CHARGER_TYPES, chargerTypes);
- }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
index ce0cc3a9e4d..9b3b8eff107 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/FacilityBasedParkingManager.java
@@ -26,26 +26,32 @@
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.dynagent.DynAgent;
import org.matsim.contrib.parking.parkingsearch.ParkingUtils;
import org.matsim.contrib.parking.parkingsearch.sim.ParkingSearchConfigGroup;
+import org.matsim.core.mobsim.qsim.QSim;
import org.matsim.core.utils.misc.Time;
import org.matsim.facilities.ActivityFacility;
+import org.matsim.facilities.ActivityOption;
import org.matsim.vehicles.Vehicle;
import java.util.*;
import java.util.Map.Entry;
/**
- * @author jbischoff, schlenther
- *
+ * @author jbischoff, schlenther, Ricardo Ewert
*/
public class FacilityBasedParkingManager implements ParkingSearchManager {
protected Map, Integer> capacity = new HashMap<>();
protected Map, MutableLong> occupation = new HashMap<>();
protected Map, MutableLong> reservationsRequests = new HashMap<>();
- protected Map, MutableLong> rejectedReservations = new HashMap<>();
+ protected Map, MutableLong> rejectedParkingRequest = new HashMap<>();
protected Map, MutableLong> numberOfParkedVehicles = new HashMap<>();
+ protected Map, MutableLong> numberOfWaitingActivities = new HashMap<>();
+ protected Map, MutableLong> numberOfStaysFromGetOffUntilGetIn = new HashMap<>();
+ protected Map, MutableLong> numberOfParkingBeforeGetIn = new HashMap<>();
+ protected Map, TreeMap>> waitingVehicles = new HashMap<>();
protected TreeMap rejectedReservationsByTime = new TreeMap<>();
protected TreeMap foundParkingByTime = new TreeMap<>();
protected TreeMap unparkByTime = new TreeMap<>();
@@ -54,8 +60,10 @@ public class FacilityBasedParkingManager implements ParkingSearchManager {
protected Map, Id> parkingReservation = new HashMap<>();
protected Map, Id> parkingLocationsOutsideFacilities = new HashMap<>();
protected Map, Set>> facilitiesPerLink = new HashMap<>();
- protected Network network;
+ protected Network network;
+ protected ParkingSearchConfigGroup psConfigGroup;
protected boolean canParkOnlyAtFacilities;
+ private QSim qsim;
private final int maxSlotIndex;
private final int maxTime;
private final int timeBinSize;
@@ -63,14 +71,15 @@ public class FacilityBasedParkingManager implements ParkingSearchManager {
@Inject
public FacilityBasedParkingManager(Scenario scenario) {
- ParkingSearchConfigGroup psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get(ParkingSearchConfigGroup.GROUP_NAME);
+ psConfigGroup = (ParkingSearchConfigGroup) scenario.getConfig().getModules().get(
+ ParkingSearchConfigGroup.GROUP_NAME);
canParkOnlyAtFacilities = psConfigGroup.getCanParkOnlyAtFacilities();
this.network = scenario.getNetwork();
parkingFacilities = scenario.getActivityFacilities()
- .getFacilitiesForActivityType(ParkingUtils.PARKACTIVITYTYPE);
+ .getFacilitiesForActivityType(ParkingUtils.ParkingStageInteractionType);
LogManager.getLogger(getClass()).info(parkingFacilities.toString());
- this.timeBinSize = 15*60;
- this.maxTime = 24 * 3600 -1;
+ this.timeBinSize = 15 * 60;
+ this.maxTime = 24 * 3600 - 1;
this.maxSlotIndex = (this.maxTime / this.timeBinSize) + 1;
this.startTime = 9 * 3600;
@@ -82,10 +91,14 @@ public FacilityBasedParkingManager(Scenario scenario) {
}
parkingOnLink.add(fac.getId());
this.facilitiesPerLink.put(linkId, parkingOnLink);
+ this.waitingVehicles.computeIfAbsent(linkId, (k) -> new TreeMap<>());
this.occupation.put(fac.getId(), new MutableLong(0));
this.reservationsRequests.put(fac.getId(), new MutableLong(0));
- this.rejectedReservations.put(fac.getId(), new MutableLong(0));
+ this.rejectedParkingRequest.put(fac.getId(), new MutableLong(0));
this.numberOfParkedVehicles.put(fac.getId(), new MutableLong(0));
+ this.numberOfWaitingActivities.put(fac.getId(), new MutableLong(0));
+ this.numberOfStaysFromGetOffUntilGetIn.put(fac.getId(), new MutableLong(0));
+ this.numberOfParkingBeforeGetIn.put(fac.getId(), new MutableLong(0));
}
int slotIndex = getTimeSlotIndex(startTime);
while (slotIndex <= maxSlotIndex) {
@@ -109,6 +122,39 @@ public boolean reserveSpaceIfVehicleCanParkHere(Id vehicleId, Id
return canPark;
}
+ /**
+ * Checks if it is possible if you can park at this link for the complete time.
+ *
+ * @param linkId
+ * @param stopDuration
+ * @param getOffDuration
+ * @param pickUpDuration
+ * @param now
+ * @return
+ */
+ public boolean canParkAtThisFacilityUntilEnd(Id linkId, double stopDuration, double getOffDuration, double pickUpDuration, double now) {
+ Set> facilities = this.facilitiesPerLink.get(linkId);
+ if (facilities != null) {
+ double totalNeededParkingDuration = getOffDuration + stopDuration + pickUpDuration;
+ for (Id facility : facilities) {
+ double maxParkingDurationAtFacilityInHours = Double.MAX_VALUE;
+ if (this.parkingFacilities.get(facility).getAttributes().getAsMap().containsKey("maxParkingDurationInHours"))
+ maxParkingDurationAtFacilityInHours = 3600 * (double) this.parkingFacilities.get(facility).getAttributes().getAsMap().get(
+ "maxParkingDurationInHours");
+ if (maxParkingDurationAtFacilityInHours > totalNeededParkingDuration) {
+ ActivityOption parkingOptions = this.parkingFacilities.get(facility).getActivityOptions().get("parking");
+ if (!parkingOptions.getOpeningTimes().isEmpty()) {
+ if ((parkingOptions.getOpeningTimes().first().getStartTime() == 0 && parkingOptions.getOpeningTimes().first().getEndTime() == 24 * 3600))
+ if (parkingOptions.getOpeningTimes().first().getStartTime() <= now && parkingOptions.getOpeningTimes().first().getEndTime() >= now + totalNeededParkingDuration)
+ return true;
+ } else
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id vid) {
// LogManager.getLogger(getClass()).info("link "+linkId+" vehicle "+vid);
if (!this.facilitiesPerLink.containsKey(linkId) && !canParkOnlyAtFacilities) {
@@ -125,8 +171,8 @@ private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id
}
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
for (Id fac : parkingFacilitiesAtLink) {
- double cap = this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE)
- .getCapacity();
+ double cap = this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType)
+ .getCapacity();
this.reservationsRequests.get(fac).increment();
if (this.occupation.get(fac).doubleValue() < cap) {
// LogManager.getLogger(getClass()).info("occ:
@@ -136,7 +182,7 @@ private boolean linkIdHasAvailableParkingForVehicle(Id linkId, Id
return true;
}
- this.rejectedReservations.get(fac).increment();
+ this.rejectedParkingRequest.get(fac).increment();
}
return false;
}
@@ -150,7 +196,7 @@ public Id getVehicleParkingLocation(Id vehicleId) {
@Override
public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) {
- return parkVehicleAtLink(vehicleId, linkId, time);
+ return parkVehicleAtLink(vehicleId, linkId, time);
}
protected boolean parkVehicleAtLink(Id vehicleId, Id linkId, double time) {
@@ -167,7 +213,7 @@ protected boolean parkVehicleAtLink(Id vehicleId, Id linkId, doub
return true;
} else {
throw new RuntimeException("no parking reservation found for vehicle " + vehicleId.toString()
- + "arrival on link " + linkId + " with parking restriction");
+ + " arrival on link " + linkId + " with parking restriction");
}
}
}
@@ -193,11 +239,14 @@ public List produceStatistics() {
for (Entry, MutableLong> e : this.occupation.entrySet()) {
Id linkId = this.parkingFacilities.get(e.getKey()).getLinkId();
double capacity = this.parkingFacilities.get(e.getKey()).getActivityOptions()
- .get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ .get(ParkingUtils.ParkingStageInteractionType).getCapacity();
double x = this.parkingFacilities.get(e.getKey()).getCoord().getX();
double y = this.parkingFacilities.get(e.getKey()).getCoord().getY();
- String s = linkId.toString() + ";" + x + ";" + y + ";" + e.getKey().toString() + ";" + capacity + ";" + e.getValue().toString() + ";" + this.reservationsRequests.get(e.getKey()).toString() + ";" + this.numberOfParkedVehicles.get(e.getKey()).toString() + ";" + this.rejectedReservations.get(e.getKey()).toString();
+ String s = linkId.toString() + ";" + x + ";" + y + ";" + e.getKey().toString() + ";" + capacity + ";" + e.getValue().toString() + ";" + this.reservationsRequests.get(
+ e.getKey()).toString() + ";" + this.numberOfParkedVehicles.get(e.getKey()).toString() + ";" + this.rejectedParkingRequest.get(
+ e.getKey()).toString() + ";" + this.numberOfWaitingActivities.get(
+ e.getKey()).toString() + ";" + this.numberOfStaysFromGetOffUntilGetIn.get(e.getKey()).intValue() + ";" + this.numberOfParkingBeforeGetIn.get(e.getKey()).intValue();
stats.add(s);
}
return stats;
@@ -208,31 +257,32 @@ public List produceTimestepsStatistics() {
for (int time : rejectedReservationsByTime.keySet()) {
String s = Time.writeTime(time, Time.TIMEFORMAT_HHMM) + ";" + rejectedReservationsByTime.get(time) + ";" + foundParkingByTime.get(
- time) + ";" + unparkByTime.get(time);
+ time) + ";" + unparkByTime.get(time);
stats.add(s);
}
return stats;
}
- public double getNrOfAllParkingSpacesOnLink (Id linkId){
+
+ public double getNrOfAllParkingSpacesOnLink(Id linkId) {
double allSpaces = 0;
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
if (!(parkingFacilitiesAtLink == null)) {
- for (Id fac : parkingFacilitiesAtLink){
- allSpaces += this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ for (Id fac : parkingFacilitiesAtLink) {
+ allSpaces += this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
}
}
return allSpaces;
}
- public double getNrOfFreeParkingSpacesOnLink (Id linkId){
+ public double getNrOfFreeParkingSpacesOnLink(Id linkId) {
double allFreeSpaces = 0;
Set> parkingFacilitiesAtLink = this.facilitiesPerLink.get(linkId);
if (parkingFacilitiesAtLink == null) {
return 0;
} else {
- for (Id fac : parkingFacilitiesAtLink){
- int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.PARKACTIVITYTYPE).getCapacity();
+ for (Id fac : parkingFacilitiesAtLink) {
+ int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
allFreeSpaces += (cap - this.occupation.get(fac).intValue());
}
}
@@ -243,11 +293,11 @@ public Map, ActivityFacility> getParkingFacilities() {
return this.parkingFacilities;
}
- public void registerRejectedReservation(double now){
+ public void registerRejectedReservation(double now) {
rejectedReservationsByTime.get(getTimeSlotIndex(now) * timeBinSize).increment();
}
- public TreeSet getTimeSteps(){
+ public TreeSet getTimeSteps() {
TreeSet timeSteps = new TreeSet<>();
int slotIndex = 0;
while (slotIndex <= maxSlotIndex) {
@@ -261,15 +311,77 @@ private int getTimeSlotIndex(final double time) {
if (time > this.maxTime) {
return this.maxSlotIndex;
}
- return ((int)time / this.timeBinSize);
+ return ((int) time / this.timeBinSize);
+ }
+
+ /**
+ * Gives the duration of the staging activity of parking
+ *
+ * @return
+ */
+ public double getParkStageActivityDuration() {
+ return psConfigGroup.getParkduration();
+ }
+
+ /**
+ * Gives the duration of the staging activity of unparking
+ *
+ * @return
+ */
+ public double getUnParkStageActivityDuration() {
+ return psConfigGroup.getUnparkduration();
}
@Override
public void reset(int iteration) {
- for (Id fac : this.rejectedReservations.keySet()) {
- this.rejectedReservations.get(fac).setValue(0);
+ for (Id fac : this.rejectedParkingRequest.keySet()) {
+ this.rejectedParkingRequest.get(fac).setValue(0);
this.reservationsRequests.get(fac).setValue(0);
this.numberOfParkedVehicles.get(fac).setValue(0);
+ this.numberOfWaitingActivities.get(fac).setValue(0);
+ }
+ waitingVehicles.clear();
+ }
+
+ public void addVehicleForWaitingForParking(Id linkId, Id vehicleId, double now) {
+// System.out.println(now + ": vehicle " +vehicleId.toString() + " starts waiting here: " + linkId.toString());
+ waitingVehicles.get(linkId).put(now + getParkStageActivityDuration() + 1, vehicleId);
+ for (Id fac : this.facilitiesPerLink.get(linkId)) {
+ this.numberOfWaitingActivities.get(fac).increment();
+ break;
+ }
+
+ }
+
+ public void checkFreeCapacitiesForWaitingVehicles(QSim qSim, double now) {
+ for (Id linkId : waitingVehicles.keySet()) {
+ if (!waitingVehicles.get(linkId).isEmpty()) {
+ for (Id fac : this.facilitiesPerLink.get(linkId)) {
+ int cap = (int) this.parkingFacilities.get(fac).getActivityOptions().get(ParkingUtils.ParkingStageInteractionType).getCapacity();
+ while (this.occupation.get(fac).intValue() < cap && !waitingVehicles.get(linkId).isEmpty()) {
+ double startWaitingTime = waitingVehicles.get(linkId).firstKey();
+ if (startWaitingTime > now)
+ break;
+ Id vehcileId = waitingVehicles.get(linkId).remove(startWaitingTime);
+ DynAgent agent = (DynAgent) qSim.getAgents().get(Id.createPersonId(vehcileId.toString()));
+ reserveSpaceIfVehicleCanParkHere(vehcileId, linkId);
+ agent.endActivityAndComputeNextState(now);
+ qsim.rescheduleActivityEnd(agent);
+ }
+ }
+ }
}
}
+
+ public void setQSim(QSim qSim) {
+ qsim = qSim;
+ }
+
+ public void registerStayFromGetOffUntilGetIn(Id vehcileId) {
+ this.numberOfStaysFromGetOffUntilGetIn.get(parkingLocations.get(vehcileId)).increment();
+ }
+
+ public void registerParkingBeforeGetIn(Id vehcileId) {
+ this.numberOfParkingBeforeGetIn.get(parkingLocations.get(vehcileId)).increment();
+ }
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
index 5311933db84..b9fbebe4699 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/manager/ZoneParkingManager.java
@@ -1,5 +1,5 @@
/**
- *
+ *
*/
package org.matsim.contrib.parking.parkingsearch.manager;
@@ -23,90 +23,92 @@
*/
public class ZoneParkingManager extends FacilityBasedParkingManager {
- private HashMap>> linksOfZone;
- private HashMap totalCapOfZone;
- private HashMap occupationOfZone;
-
+ private HashMap>> linksOfZone;
+ private HashMap totalCapOfZone;
+ private HashMap occupationOfZone;
+
/**
* @param scenario
*/
@Inject
public ZoneParkingManager(Scenario scenario, String[] pathToZoneTxtFiles) {
super(scenario);
-
- this.linksOfZone = new HashMap>>();
- this.totalCapOfZone = new HashMap();
- this.occupationOfZone = new HashMap();
-
- for(String zone: pathToZoneTxtFiles){
+
+ this.linksOfZone = new HashMap>>();
+ this.totalCapOfZone = new HashMap();
+ this.occupationOfZone = new HashMap();
+
+ for (String zone : pathToZoneTxtFiles) {
readZone(zone);
}
-
- for(String zone: this.linksOfZone.keySet()){
+
+ for (String zone : this.linksOfZone.keySet()) {
calculateTotalZoneParkCapacity(zone);
- this.occupationOfZone.put(zone,0.0);
+ this.occupationOfZone.put(zone, 0.0);
}
}
-
+
/**
* reads in a tabular file that declares which link id's are in the monitored zone
- * the part between the last '/' and the file type extension in the given path is considered to be the zone name
+ * the part between the last '/' and the file type extension in the given path is considered to be the zone name
* @param pathToZoneFile
*/
- void readZone(String pathToZoneFile){
- String zone = pathToZoneFile.substring(pathToZoneFile.lastIndexOf("/")+1, pathToZoneFile.lastIndexOf("."));
-
+ void readZone(String pathToZoneFile) {
+ String zone = pathToZoneFile.substring(pathToZoneFile.lastIndexOf("/") + 1, pathToZoneFile.lastIndexOf("."));
+
HashSet> links = new HashSet>();
-
+
TabularFileParserConfig config = new TabularFileParserConfig();
- config.setDelimiterTags(new String[] {"\t"});
- config.setFileName(pathToZoneFile);
- config.setCommentTags(new String[] { "#" });
- new TabularFileParser().parse(config, new TabularFileHandler() {
+ config.setDelimiterTags(new String[]{"\t"});
+ config.setFileName(pathToZoneFile);
+ config.setCommentTags(new String[]{"#"});
+ new TabularFileParser().parse(config, new TabularFileHandler() {
@Override
public void startRow(String[] row) {
Id linkId = Id.createLinkId(row[0]);
links.add(linkId);
}
-
- });
-
- this.linksOfZone.put(zone, links);
+
+ });
+
+ this.linksOfZone.put(zone, links);
}
-
- private void calculateTotalZoneParkCapacity(String zoneName){
+
+ private void calculateTotalZoneParkCapacity(String zoneName) {
double cap = 0.0;
- for(Id link : this.linksOfZone.get(zoneName)){
+ for (Id link : this.linksOfZone.get(zoneName)) {
cap += getNrOfAllParkingSpacesOnLink(link);
- }
+ }
this.totalCapOfZone.put(zoneName, cap);
}
-
+
@Override
public boolean parkVehicleHere(Id vehicleId, Id linkId, double time) {
if (parkVehicleAtLink(vehicleId, linkId, time)) {
- for(String zone : this.linksOfZone.keySet()){
- if(linksOfZone.get(zone).contains(linkId) && this.facilitiesPerLink.containsKey(linkId)){
+ for (String zone : this.linksOfZone.keySet()) {
+ if (linksOfZone.get(zone).contains(linkId) && this.facilitiesPerLink.containsKey(linkId)) {
double newOcc = this.occupationOfZone.get(zone) + 1;
- if(this.totalCapOfZone.get(zone) vehicleId, Id linkId, double time) {
if (!this.parkingLocations.containsKey(vehicleId)) {
@@ -115,35 +117,36 @@ public boolean unParkVehicleHere(Id vehicleId, Id linkId, double
} else {
Id fac = this.parkingLocations.remove(vehicleId);
this.occupation.get(fac).decrement();
-
+
Id parkingLink = this.parkingFacilities.get(fac).getLinkId();
- for(String zone : this.linksOfZone.keySet()){
- if(linksOfZone.get(zone).contains(parkingLink)){
+ for (String zone : this.linksOfZone.keySet()) {
+ if (linksOfZone.get(zone).contains(parkingLink)) {
double newOcc = this.occupationOfZone.get(zone) - 1;
- if(newOcc < 0 ){
- //in iteration 0 agents can "leave parking spaces" (get into traffic), but the manager didn't record them to be parked
+ if (newOcc < 0) {
+ //in iteration 0 agents can "leave parking spaces" (get into traffic), but the manager didn't record them to be parked
newOcc = 0;
}
- this.occupationOfZone.put(zone,newOcc);
+ this.occupationOfZone.put(zone, newOcc);
}
}
- return true;
+ return true;
}
}
-
-
- public double getOccupancyRatioOfZone(String zone){
- if(!(this.linksOfZone.keySet().contains(zone))) throw new RuntimeException("zone " + zone + " was not defined. thus, could'nt calculate occupancy ratio.");
+
+
+ public double getOccupancyRatioOfZone(String zone) {
+ if (!(this.linksOfZone.keySet().contains(zone)))
+ throw new RuntimeException("zone " + zone + " was not defined. thus, could'nt calculate occupancy ratio.");
return (this.occupationOfZone.get(zone) / this.totalCapOfZone.get(zone));
}
-
- public Set getZones(){
+
+ public Set getZones() {
return this.linksOfZone.keySet();
}
-
- public double getTotalCapacityOfZone(String zone){
+
+ public double getTotalCapacityOfZone(String zone) {
return this.totalCapOfZone.get(zone);
}
-
+
}
diff --git a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
index 041e74c2198..d87bf0408fe 100644
--- a/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
+++ b/contribs/parking/src/main/java/org/matsim/contrib/parking/parkingsearch/search/NearestParkingSpotSearchLogic.java
@@ -49,6 +49,7 @@ public class NearestParkingSpotSearchLogic implements ParkingSearchLogic {
private NetworkRoute actualRoute = null;
private final boolean canReserveParkingSlot;
private final boolean canCheckParkingCapacitiesInAdvanced;
+ private double distanceFromBaseToAttraction = Double.NaN;
private boolean useRandomLinkChoice;
private int currentLinkIdx;
private final HashSet> triedParking;
@@ -79,22 +80,32 @@ public NearestParkingSpotSearchLogic(Network network, ParkingRouter parkingRoute
* @param baseLinkId linkId of the origin destination where the parkingSearch starts
*/
public Id getNextLink(Id currentLinkId, Id baseLinkId, Id vehicleId, String mode, double now,
- double maxParkingDuration, double nextPickupTime) {
-
+ double maxParkingDuration, double nextPickupTime, boolean passangerInteractionAtParkingFacilityAtEndOfLeg,
+ Coord coordOfAttraction) {
+ double maxAdditionalDistanceToAttraction = Double.MAX_VALUE;
+ // if a passenger interaction take place at a facility the walking distance to the attraction should be not extended by the value of maxAdditionalDistanceToAttraction
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ if (Double.isNaN(distanceFromBaseToAttraction))
+ findDistanceBetweenBaseLinkAndAttraction(baseLinkId, coordOfAttraction);
+ maxAdditionalDistanceToAttraction = 200.;
+ }
if (actualRoute == null) {
- actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now, maxParkingDuration);
- checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
- if (actualRoute != null) {
- actualRoute.setVehicleId(vehicleId);
- }
+ actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now,
+ maxParkingDuration,
+ passangerInteractionAtParkingFacilityAtEndOfLeg, maxAdditionalDistanceToAttraction, coordOfAttraction);
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg)
+ checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
triedParking.clear();
} else if (currentLinkId.equals(actualRoute.getEndLinkId()) && !skipParkingActivity) {
currentLinkIdx = 0;
- actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now, maxParkingDuration);
- checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
- if (actualRoute != null) {
- actualRoute.setVehicleId(vehicleId);
- }
+ actualRoute = findRouteToNearestParkingFacility(baseLinkId, currentLinkId, canCheckParkingCapacitiesInAdvanced, now,
+ maxParkingDuration,
+ passangerInteractionAtParkingFacilityAtEndOfLeg, maxAdditionalDistanceToAttraction, coordOfAttraction);
+ if (!passangerInteractionAtParkingFacilityAtEndOfLeg)
+ checkIfDrivingToNextParkingLocationIsPossible(currentLinkId, baseLinkId, now, nextPickupTime);
+ }
+ if (actualRoute != null) {
+ actualRoute.setVehicleId(vehicleId);
}
//if no possible parking was found. The vehicle takes a random next link. Background assumption: parking only at given parking slots
if (actualRoute == null) {
@@ -111,6 +122,20 @@ public Id getNextLink(Id currentLinkId, Id baseLinkId, Id baseLinkId, Coord coordOfAttraction) {
+ for (ActivityFacility activityFacility : activityFacilities.values()) {
+ if (activityFacility.getLinkId().equals(baseLinkId))
+ distanceFromBaseToAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(),
+ coordOfAttraction);
+ }
+ }
+
/**
* Checks if it is possible to drive to the new parking facility and to drive back to the base without extending the startTime of the following activity.
* If the resulting parking time at the new facility is less then 5 minutes the vehicle will drive directly to the next activity location.
@@ -175,7 +200,9 @@ public boolean isUseRandomLinkChoice() {
}
private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id currentLinkId, boolean canCheckParkingCapacitiesInAdvanced,
- double now, double maxParkingDuration) {
+ double now, double maxParkingDuration,
+ boolean passangerInteractionAtParkingFacilityAtEndOfLeg, double maxDistanceFromBase,
+ Coord coordOfAttraction) {
TreeMap euclideanDistanceToParkingFacilities = new TreeMap<>();
ActivityFacility nearstActivityFacility = null;
NetworkRoute selectedRoute = null;
@@ -183,29 +210,31 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id now || parkingOptions.getOpeningTimes().first().getEndTime() < latestEndOfParking)
- continue;
+ if (parkingOptions.getOpeningTimes().first().getStartTime() > now && parkingOptions.getOpeningTimes().first().getEndTime() < latestEndOfParking)
+ continue;
}
- //check if approx. the max parking time at facility will not exceed
+ //check if approx. the max parking time at facility will not exceed, assumption: "parking duration - 30 minutes" is parking Time.
if (activityFacility.getAttributes().getAsMap().containsKey("maxParkingDurationInHours")) { //TODO vielleicht etwas sparsamer machen
double maxParkingDurationAtFacility = 3600 * (double) activityFacility.getAttributes().getAsMap().get("maxParkingDurationInHours");
- if (maxParkingDuration > maxParkingDurationAtFacility)
+ if (maxParkingDuration - 30*60 > maxParkingDurationAtFacility)
continue;
- double expectedTravelTimeFromParkingToBase = getExpectedTravelTime(baseLinkId, now, activityFacility.getLinkId());
- double expectedTravelTimeFromCurrentToParking = getExpectedTravelTime(activityFacility.getLinkId(), now, currentLinkId);
- double expectedParkingTime = maxParkingDuration - expectedTravelTimeFromCurrentToParking - expectedTravelTimeFromParkingToBase;
- if (expectedParkingTime > maxParkingDurationAtFacility)
+ }
+
+ //TODO beschreiben was passiert
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg) {
+ double distanceBetweenThisParkingFacilityAndTheAttraction = NetworkUtils.getEuclideanDistance(activityFacility.getCoord(),
+ coordOfAttraction);
+ if (distanceBetweenThisParkingFacilityAndTheAttraction - distanceFromBaseToAttraction > maxDistanceFromBase)
continue;
}
// create Euclidean distances to the parking activities to find routes only to the nearest facilities in the next step
@@ -213,7 +242,11 @@ private NetworkRoute findRouteToNearestParkingFacility(Id baseLinkId, Id baseLinkId, Id maxParkingDurationAtFacility)
+ continue;
+ }
counter++;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() > triedParking.size())
+ if (triedParking.contains(activityFacility.getId()))
+ continue;
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg && euclideanDistanceToParkingFacilities.size() == triedParking.size())
+ triedParking.clear();
NetworkRoute possibleRoute = this.parkingRouter.getRouteFromParkingToDestination(activityFacility.getLinkId(), now,
currentLinkId);
+ // reason is that we expect that the driver will always take the nearest possible getOff point to reduce the walk distance for the guests
+ if (passangerInteractionAtParkingFacilityAtEndOfLeg){
+ selectedRoute = possibleRoute;
+ nearstActivityFacility = activityFacility;
+ break;
+ }
double travelTimeToParking = possibleRoute.getTravelTime().seconds();
double travelTimeFromParking = travelTimeToParking;
if (!baseLinkId.equals(currentLinkId)) {
@@ -276,6 +328,7 @@ public void reset() {
actualRoute = null;
currentLinkIdx = 0;
skipParkingActivity = false;
+ distanceFromBaseToAttraction = Double.NaN;
}
}
diff --git a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java
index 3fd984a8a7d..3c42d7111c2 100644
--- a/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java
+++ b/contribs/taxi/src/main/java/org/matsim/contrib/etaxi/optimizer/ETaxiModeOptimizerQSimModule.java
@@ -35,7 +35,7 @@
import org.matsim.contrib.etaxi.ETaxiScheduler;
import org.matsim.contrib.etaxi.util.ETaxiStayTaskEndTimeCalculator;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
-import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures;
+import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils;
import org.matsim.contrib.taxi.analysis.TaxiEventSequenceCollector;
import org.matsim.contrib.taxi.optimizer.TaxiOptimizer;
import org.matsim.contrib.taxi.run.TaxiConfigGroup;
@@ -91,8 +91,8 @@ public TaxiOptimizer get() {
});
bindModal(ChargingInfrastructure.class).toProvider(modalProvider(
- getter -> ChargingInfrastructures.createModalNetworkChargers(getter.get(ChargingInfrastructure.class),
- getter.getModal(Network.class), getMode()))).asEagerSingleton();
+ getter -> ChargingInfrastructureUtils.createModalNetworkChargers(getter.get(ChargingInfrastructure.class ),
+ getter.getModal(Network.class), getMode() ))).asEagerSingleton();
addModalComponent(ETaxiScheduler.class,
new ModalProviders.AbstractProvider<>(taxiCfg.getMode(), DvrpModes::mode) {
diff --git a/contribs/vsp/pom.xml b/contribs/vsp/pom.xml
index 96a0cd8ca37..99614d63e78 100644
--- a/contribs/vsp/pom.xml
+++ b/contribs/vsp/pom.xml
@@ -174,12 +174,12 @@
org.openjfx
javafx-graphics
- 21
+ 21.0.1
com.graphhopper
graphhopper-core
- 7.0
+ 8.0
diff --git a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventHandler.java b/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventHandler.java
index 5a9daccf1cf..2f322e8640f 100644
--- a/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventHandler.java
+++ b/contribs/vsp/src/main/java/org/matsim/freight/carriers/analysis/FreightAnalysisEventHandler.java
@@ -36,10 +36,10 @@
import org.matsim.freight.carriers.events.CarrierServiceStartEvent;
import org.matsim.freight.carriers.events.CarrierShipmentDeliveryEndEvent;
import org.matsim.freight.carriers.events.CarrierShipmentPickupEndEvent;
-import org.matsim.freight.carriers.events.eventhandler.FreightServiceEndEventHandler;
-import org.matsim.freight.carriers.events.eventhandler.FreightServiceStartEventHandler;
-import org.matsim.freight.carriers.events.eventhandler.FreightShipmentDeliveryEventHandler;
-import org.matsim.freight.carriers.events.eventhandler.FreightShipmentPickupEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierServiceEndEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierServiceStartEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentDeliveryEndEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentPickupEndEventHandler;
import org.matsim.core.network.NetworkUtils;
import org.matsim.vehicles.Vehicle;
import org.matsim.vehicles.Vehicles;
@@ -59,7 +59,7 @@
* */
@Deprecated(since = "apr23")
-class FreightAnalysisEventHandler implements ActivityStartEventHandler, LinkEnterEventHandler, LinkLeaveEventHandler, PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, FreightShipmentPickupEventHandler, FreightShipmentDeliveryEventHandler, FreightServiceStartEventHandler, FreightServiceEndEventHandler {
+class FreightAnalysisEventHandler implements ActivityStartEventHandler, LinkEnterEventHandler, LinkLeaveEventHandler, PersonEntersVehicleEventHandler, PersonLeavesVehicleEventHandler, CarrierShipmentPickupEndEventHandler, CarrierShipmentDeliveryEndEventHandler, CarrierServiceStartEventHandler, CarrierServiceEndEventHandler {
private final static Logger log = LogManager.getLogger(FreightAnalysisEventHandler.class);
private final Vehicles vehicles;
diff --git a/contribs/vsp/src/main/java/playground/vsp/ev/ElectricFleetUpdater.java b/contribs/vsp/src/main/java/playground/vsp/ev/ElectricFleetUpdater.java
index e89f9fcf55b..5b5ab616092 100644
--- a/contribs/vsp/src/main/java/playground/vsp/ev/ElectricFleetUpdater.java
+++ b/contribs/vsp/src/main/java/playground/vsp/ev/ElectricFleetUpdater.java
@@ -24,7 +24,7 @@
import org.matsim.api.core.v01.population.Plan;
import org.matsim.api.core.v01.population.Population;
import org.matsim.contrib.ev.fleet.ElectricFleetSpecification;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecificationImpl;
+import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.core.controler.events.IterationStartsEvent;
import org.matsim.core.controler.listener.IterationStartsListener;
import org.matsim.core.router.TripStructureUtils;
@@ -56,6 +56,6 @@ private void registerEVs(Plan plan) {
var modalVehicles = TripStructureUtils.getLegs(plan).stream()
.map(leg -> vehicles.getVehicles().get(VehicleUtils.getVehicleId(plan.getPerson(), leg.getMode())))
.toList();
- ElectricVehicleSpecificationImpl.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification, modalVehicles);
+ ElectricFleetUtils.createAndAddVehicleSpecificationsFromMatsimVehicles(fleetSpecification, modalVehicles );
}
}
diff --git a/contribs/vsp/src/main/java/playground/vsp/ev/RunUrbanEVExample.java b/contribs/vsp/src/main/java/playground/vsp/ev/RunUrbanEVExample.java
index e5b374733f6..97d90f45650 100644
--- a/contribs/vsp/src/main/java/playground/vsp/ev/RunUrbanEVExample.java
+++ b/contribs/vsp/src/main/java/playground/vsp/ev/RunUrbanEVExample.java
@@ -50,7 +50,7 @@
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.population.Person;
import org.matsim.contrib.ev.EvConfigGroup;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecifications;
+import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.config.groups.RoutingConfigGroup;
@@ -144,11 +144,11 @@ static void createAndRegisterPersonalCarAndBikeVehicles(Scenario scenario) {
VehicleType.class)); //TODO should at least have a suffix "_car"
VehicleUtils.setHbefaTechnology(carVehicleType.getEngineInformation(), "electricity");
VehicleUtils.setEnergyCapacity(carVehicleType.getEngineInformation(), CAR_BATTERY_CAPACITY_kWh);
- ElectricVehicleSpecifications.setChargerTypes(carVehicleType.getEngineInformation(), Arrays.asList("a", "b", "default"));
+ ElectricFleetUtils.setChargerTypes(carVehicleType.getEngineInformation(), Arrays.asList("a", "b", "default" ) );
scenario.getVehicles().addVehicleType(carVehicleType);
Vehicle carVehicle = vehicleFactory.createVehicle(VehicleUtils.createVehicleId(person, TransportMode.car),
carVehicleType);
- ElectricVehicleSpecifications.setInitialSoc(carVehicle, CAR_INITIAL_SOC);
+ ElectricFleetUtils.setInitialSoc(carVehicle, CAR_INITIAL_SOC );
scenario.getVehicles().addVehicle(carVehicle);
VehicleType bikeVehicleType = vehicleFactory.createVehicleType(
diff --git a/contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVTripsPlanner.java b/contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVTripsPlanner.java
index 0449190e8f6..b68f4d5bcff 100644
--- a/contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVTripsPlanner.java
+++ b/contribs/vsp/src/main/java/playground/vsp/ev/UrbanEVTripsPlanner.java
@@ -54,10 +54,7 @@
import org.matsim.contrib.ev.charging.ChargingPower;
import org.matsim.contrib.ev.discharging.AuxEnergyConsumption;
import org.matsim.contrib.ev.discharging.DriveEnergyConsumption;
-import org.matsim.contrib.ev.fleet.ElectricFleetSpecification;
-import org.matsim.contrib.ev.fleet.ElectricVehicle;
-import org.matsim.contrib.ev.fleet.ElectricVehicleImpl;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
+import org.matsim.contrib.ev.fleet.*;
import org.matsim.contrib.ev.infrastructure.ChargerSpecification;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureSpecification;
import org.matsim.core.config.Config;
@@ -208,8 +205,8 @@ private void processPlans(Map>> selectedEVPlans) {
*/
ElectricVehicleSpecification evSpec = electricFleetSpecification.getVehicleSpecifications().get(Id.create(ev, Vehicle.class));
Leg legWithCriticalSOC;
- ElectricVehicle pseudoVehicle = ElectricVehicleImpl.create(evSpec, driveConsumptionFactory, auxConsumptionFactory,
- chargingPowerFactory);
+ ElectricVehicle pseudoVehicle = ElectricFleetUtils.create(evSpec, driveConsumptionFactory, auxConsumptionFactory,
+ chargingPowerFactory );
//TODO: erase hardcoding of car mode!
List evCarLegs = TripStructureUtils.getLegs(modifiablePlan)
.stream()
diff --git a/contribs/vsp/src/main/java/playground/vsp/ev/UrbanVehicleChargingHandler.java b/contribs/vsp/src/main/java/playground/vsp/ev/UrbanVehicleChargingHandler.java
index 543080da322..592722998fe 100644
--- a/contribs/vsp/src/main/java/playground/vsp/ev/UrbanVehicleChargingHandler.java
+++ b/contribs/vsp/src/main/java/playground/vsp/ev/UrbanVehicleChargingHandler.java
@@ -30,7 +30,7 @@
import org.matsim.contrib.ev.fleet.ElectricVehicle;
import org.matsim.contrib.ev.infrastructure.Charger;
import org.matsim.contrib.ev.infrastructure.ChargingInfrastructure;
-import org.matsim.contrib.ev.infrastructure.ChargingInfrastructures;
+import org.matsim.contrib.ev.infrastructure.ChargingInfrastructureUtils;
import org.matsim.core.events.MobsimScopeEventHandler;
import org.matsim.core.utils.collections.Tuple;
import org.matsim.vehicles.Vehicle;
@@ -67,7 +67,7 @@ class UrbanVehicleChargingHandler
UrbanVehicleChargingHandler(ChargingInfrastructure chargingInfrastructure, ElectricFleet electricFleet) {
this.chargingInfrastructure = chargingInfrastructure;
this.electricFleet = electricFleet;
- this.chargersAtLinks = ChargingInfrastructures.getChargersAtLinks(chargingInfrastructure);
+ this.chargersAtLinks = ChargingInfrastructureUtils.getChargersAtLinks(chargingInfrastructure );
}
/**
diff --git a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyServiceTrackerEventHandler.java b/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyServiceTrackerEventHandler.java
index 43c9dd2d524..ae51676c57b 100644
--- a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyServiceTrackerEventHandler.java
+++ b/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyServiceTrackerEventHandler.java
@@ -29,11 +29,11 @@
import org.matsim.freight.carriers.Carriers;
import org.matsim.freight.carriers.events.CarrierServiceEndEvent;
import org.matsim.freight.carriers.events.CarrierServiceStartEvent;
-import org.matsim.freight.carriers.events.eventhandler.FreightServiceEndEventHandler;
-import org.matsim.freight.carriers.events.eventhandler.FreightServiceStartEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierServiceEndEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierServiceStartEventHandler;
import org.matsim.vehicles.Vehicles;
- class MyServiceTrackerEventHandler implements ActivityStartEventHandler, FreightServiceStartEventHandler, FreightServiceEndEventHandler {
+ class MyServiceTrackerEventHandler implements ActivityStartEventHandler, CarrierServiceStartEventHandler, CarrierServiceEndEventHandler {
private final Vehicles vehicles;
private final Network network;
private final Carriers carriers;
diff --git a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyShipmentTrackerEventHandler.java b/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyShipmentTrackerEventHandler.java
index 35b455b8944..178652c1c7d 100644
--- a/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyShipmentTrackerEventHandler.java
+++ b/contribs/vsp/src/test/java/org/matsim/freight/carriers/analysis/MyShipmentTrackerEventHandler.java
@@ -29,11 +29,11 @@
import org.matsim.freight.carriers.Carriers;
import org.matsim.freight.carriers.events.CarrierShipmentDeliveryEndEvent;
import org.matsim.freight.carriers.events.CarrierShipmentPickupEndEvent;
-import org.matsim.freight.carriers.events.eventhandler.FreightShipmentDeliveryEventHandler;
-import org.matsim.freight.carriers.events.eventhandler.FreightShipmentPickupEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentDeliveryEndEventHandler;
+import org.matsim.freight.carriers.events.eventhandler.CarrierShipmentPickupEndEventHandler;
import org.matsim.vehicles.Vehicles;
-public class MyShipmentTrackerEventHandler implements ActivityStartEventHandler, FreightShipmentPickupEventHandler, FreightShipmentDeliveryEventHandler {
+public class MyShipmentTrackerEventHandler implements ActivityStartEventHandler, CarrierShipmentPickupEndEventHandler, CarrierShipmentDeliveryEndEventHandler {
private final Vehicles vehicles;
private final Network network;
@@ -69,7 +69,7 @@ public void handleEvent(CarrierShipmentPickupEndEvent event) {
@Override
public void reset(int iteration) {
- FreightShipmentPickupEventHandler.super.reset(iteration);
+ CarrierShipmentPickupEndEventHandler.super.reset(iteration);
}
@Override
diff --git a/contribs/vsp/src/test/java/playground/vsp/ev/TransferFinalSocToNextIterTest.java b/contribs/vsp/src/test/java/playground/vsp/ev/TransferFinalSocToNextIterTest.java
index b77b0352fc0..172fc201ad2 100644
--- a/contribs/vsp/src/test/java/playground/vsp/ev/TransferFinalSocToNextIterTest.java
+++ b/contribs/vsp/src/test/java/playground/vsp/ev/TransferFinalSocToNextIterTest.java
@@ -28,9 +28,8 @@
import org.junit.Test;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
+import org.matsim.contrib.ev.fleet.ElectricFleetUtils;
import org.matsim.contrib.ev.fleet.ElectricVehicleSpecification;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecificationImpl;
-import org.matsim.contrib.ev.fleet.ElectricVehicleSpecifications;
import org.matsim.core.controler.Controler;
import org.matsim.core.controler.events.AfterMobsimEvent;
import org.matsim.core.controler.events.BeforeMobsimEvent;
@@ -56,7 +55,7 @@ public void test() {
scenario.getConfig().controller().setOutputDirectory("test/output/playground/vsp/ev/FinalSoc2VehicleTypeTest/");
var vehicle1 = scenario.getVehicles().getVehicles().get(Id.create("Triple Charger_car", Vehicle.class));
- ElectricVehicleSpecifications.setInitialSoc(vehicle1, INITIAL_SOC);
+ ElectricFleetUtils.setInitialSoc(vehicle1, INITIAL_SOC );
//controler
Controler controler = RunUrbanEVExample.prepareControler(scenario);
@@ -69,7 +68,7 @@ public void test() {
// testSOCIsDumpedIntoVehicleType
//agent has driven the car so SOC should have changed and should be dumped into the vehicle type
var vehicle = scenario.getVehicles().getVehicles().get(Id.create("Triple Charger_car", Vehicle.class));
- var evSpec = new ElectricVehicleSpecificationImpl(vehicle);
+ var evSpec = ElectricFleetUtils.createElectricVehicleSpecificationDefaultImpl(vehicle );
Assert.assertNotEquals(evSpec.getInitialSoc(), INITIAL_SOC);
Assert.assertEquals(0.7273605127621898, evSpec.getInitialSoc(), MatsimTestUtils.EPSILON); //should not be fully charged
@@ -86,7 +85,7 @@ private static class SOCHandler implements BeforeMobsimListener, AfterMobsimList
SOCHandler(Scenario scenario) {
var car = scenario.getVehicles().getVehicles().get(Id.create("Triple Charger_car", Vehicle.class));
- evSpec = new ElectricVehicleSpecificationImpl(car);
+ evSpec = ElectricFleetUtils.createElectricVehicleSpecificationDefaultImpl(car );
}
@Override
diff --git a/matsim/pom.xml b/matsim/pom.xml
index ff071fb253a..eaff0f036bb 100644
--- a/matsim/pom.xml
+++ b/matsim/pom.xml
@@ -117,7 +117,7 @@
org.apache.maven.plugins
maven-surefire-report-plugin
- 3.1.2
+ 3.2.1
diff --git a/pom.xml b/pom.xml
index 44d423b0f53..3582b5ca0c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@
17
- 2.20.0
+ 2.21.1
29.2
1.19.0
7.0.0
@@ -177,7 +177,7 @@
org.glassfish.jaxb
jaxb-bom
- 4.0.3
+ 4.0.4
pom
import
@@ -185,7 +185,7 @@
com.google.errorprone
error_prone_annotations
- 2.22.0
+ 2.23.0
@@ -346,7 +346,7 @@
- 3.6.3
+ 3.8
@@ -382,12 +382,12 @@
org.apache.maven.plugins
maven-surefire-plugin
- 3.1.2
+ 3.2.1
org.apache.maven.plugins
maven-failsafe-plugin
- 3.1.2
+ 3.2.1
org.apache.maven.plugins
@@ -469,7 +469,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.10
+ 0.8.11
default-prepare-agent