diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java index dbf40292057..4b54cb14200 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/emissions/AirPollutionAnalysis.java @@ -205,11 +205,11 @@ private void writeOutput(Network network, EmissionsOnLinkEventHandler emissionsE if (link2pollutants.get(linkId).get(pollutant) != null) { emissionValue = link2pollutants.get(linkId).get(pollutant); } - absolute.print(nf.format(emissionValue)); + absolute.print(nf.format(emissionValue * sample.getUpscaleFactor())); Link link = network.getLinks().get(linkId); double emissionPerM = emissionValue / link.getLength(); - perMeter.print(nf.format(emissionPerM)); + perMeter.print(nf.format(emissionPerM * sample.getUpscaleFactor())); } absolute.println(); @@ -246,7 +246,7 @@ private void writeTotal(Network network, EmissionsOnLinkEventHandler emissionsEv total.printRecord("Pollutant", "kg"); for (Pollutant p : Pollutant.values()) { - double val = (sum.getDouble(p) / sample.getSample()) / 1000; + double val = (sum.getDouble(p) * sample.getUpscaleFactor()) / 1000; total.printRecord(p, val < 100_000 && val > 100 ? simple.format(val) : scientific.format(val)); } @@ -286,7 +286,7 @@ private void writeAvroRaster(Network network, Config config, EmissionsOnLinkEven for (int xi = 0; xi < xLength.get(0); xi++) { for (int yi = 0; yi < yLength.get(0); yi++) { Coord coord = raster.getCoordForIndex(xi, yi); - double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi); + double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor(); if (xi == 0) yCoords.add((float) coord.getY()); if (yi == 0) xCoords.add((float) coord.getX()); valuesList.add((float) value); @@ -349,7 +349,7 @@ private void writeRaster(Network network, Config config, EmissionsOnLinkEventHan for (int yi = 0; yi < yLength.get(0); yi++) { Coord coord = raster.getCoordForIndex(xi, yi); - double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi); + double value = rasterMap.get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor(); if (value == 0) continue; @@ -406,7 +406,7 @@ private void writeTimeDependentRaster(Network network, Config config, EmissionsO for (TimeBinMap.TimeBin> timeBin : timeBinMap.getTimeBins()) { Coord coord = raster.getCoordForIndex(xi, yi); - double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi); + double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor(); if (value == 0) continue; @@ -467,7 +467,8 @@ private void writeTimeDependentAvroRaster(Network network, Config config, Emissi if (yi == 0 && isFirst) xCoords.add((float) coord.getX()); - valuesList.add((float) timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi)); + double value = timeBin.getValue().get(Pollutant.CO2_TOTAL).getValueByIndex(xi, yi) * sample.getUpscaleFactor(); + valuesList.add((float) value); } } } 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 4da59a48294..6d6ee80f8c1 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 @@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVPrinter; +import org.apache.commons.math3.analysis.interpolation.LoessInterpolator; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.locationtech.jts.geom.Coordinate; @@ -32,6 +33,7 @@ import java.math.RoundingMode; import java.nio.file.Files; import java.util.*; +import java.util.stream.IntStream; import static tech.tablesaw.aggregate.AggregateFunctions.count; @@ -41,6 +43,7 @@ produces = { "mode_share.csv", "mode_share_per_dist.csv", "mode_users.csv", "trip_stats.csv", "mode_share_per_%s.csv", "population_trip_stats.csv", "trip_purposes_by_hour.csv", + "mode_share_distance_distribution.csv", "mode_choices.csv", "mode_choice_evaluation.csv", "mode_choice_evaluation_per_mode.csv", "mode_confusion_matrix.csv", "mode_prediction_error.csv" } @@ -109,6 +112,25 @@ private static int durationToSeconds(String d) { return (Integer.parseInt(split[0]) * 60 * 60) + (Integer.parseInt(split[1]) * 60) + Integer.parseInt(split[2]); } + private static double[] calcHistogram(double[] data, double[] bins) { + + double[] hist = new double[bins.length - 1]; + + for (int i = 0; i < bins.length - 1; i++) { + + double binStart = bins[i]; + double binEnd = bins[i + 1]; + + // The last right bin edge is inclusive, which is consistent with the numpy implementation + if (i == bins.length - 2) + hist[i] = Arrays.stream(data).filter(d -> d >= binStart && d <= binEnd).count(); + else + hist[i] = Arrays.stream(data).filter(d -> d >= binStart && d < binEnd).count(); + } + + return hist; + } + @Override public Integer call() throws Exception { @@ -247,6 +269,8 @@ public Integer call() throws Exception { writeTripPurposes(joined); + writeTripDistribution(joined); + return 0; } @@ -293,6 +317,7 @@ private void writeTripStats(Table trips) throws IOException { Object2IntMap n = new Object2IntLinkedOpenHashMap<>(); Object2LongMap travelTime = new Object2LongOpenHashMap<>(); Object2LongMap travelDistance = new Object2LongOpenHashMap<>(); + Object2LongMap beelineDistance = new Object2LongOpenHashMap<>(); for (Row trip : trips) { String mainMode = trip.getString("main_mode"); @@ -300,6 +325,7 @@ private void writeTripStats(Table trips) throws IOException { n.mergeInt(mainMode, 1, Integer::sum); travelTime.mergeLong(mainMode, durationToSeconds(trip.getString("trav_time")), Long::sum); travelDistance.mergeLong(mainMode, trip.getLong("traveled_distance"), Long::sum); + beelineDistance.mergeLong(mainMode, trip.getLong("euclidean_distance"), Long::sum); } try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("trip_stats.csv")), CSVFormat.DEFAULT)) { @@ -338,6 +364,13 @@ private void writeTripStats(Table trips) throws IOException { } printer.println(); + printer.print("Avg. beeline speed [km/h]"); + for (String m : modeOrder) { + double speed = (beelineDistance.getLong(m) / 1000d) / (travelTime.getLong(m) / (60d * 60d)); + printer.print(new BigDecimal(speed).setScale(2, RoundingMode.HALF_UP)); + } + printer.println(); + printer.print("Avg. distance per trip [km]"); for (String m : modeOrder) { double avg = (travelDistance.getLong(m) / 1000d) / (n.getInt(m)); @@ -458,6 +491,55 @@ private void writeTripPurposes(Table trips) { } + private void writeTripDistribution(Table trips) throws IOException { + + Map dists = new LinkedHashMap<>(); + + // Note that the results of this interpolator are consistent with the one performed in matsim-python-tools + // This makes the results comparable with reference data, changes here will also require changes in the python package + LoessInterpolator inp = new LoessInterpolator(0.05, 0); + + long max = distGroups.get(distGroups.size() - 3) + distGroups.get(distGroups.size() - 2); + + double[] bins = IntStream.range(0, (int) (max / 100)).mapToDouble(i -> i * 100).toArray(); + double[] x = Arrays.copyOf(bins, bins.length - 1); + + for (String mode : modeOrder) { + double[] distances = trips.where( + trips.stringColumn("main_mode").equalsIgnoreCase(mode)) + .numberColumn("traveled_distance").asDoubleArray(); + + double[] hist = calcHistogram(distances, bins); + + double[] y = inp.smooth(x, hist); + dists.put(mode, y); + } + + try (CSVPrinter printer = new CSVPrinter(Files.newBufferedWriter(output.getPath("mode_share_distance_distribution.csv")), CSVFormat.DEFAULT)) { + + printer.print("dist"); + for (String s : modeOrder) { + printer.print(s); + } + printer.println(); + + for (int i = 0; i < x.length; i++) { + + double sum = 0; + for (String s : modeOrder) { + sum += Math.max(0, dists.get(s)[i]); + } + + printer.print(x[i]); + for (String s : modeOrder) { + double value = Math.max(0, dists.get(s)[i]) / sum; + printer.print(value); + } + printer.println(); + } + } + } + /** * How shape file filtering should be applied. */ diff --git a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/TrafficStatsCalculator.java b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/TrafficStatsCalculator.java index b6d29a5319b..f24ad081146 100644 --- a/contribs/application/src/main/java/org/matsim/application/analysis/traffic/TrafficStatsCalculator.java +++ b/contribs/application/src/main/java/org/matsim/application/analysis/traffic/TrafficStatsCalculator.java @@ -13,7 +13,7 @@ /** * Class to calculate the traffic congestion index based on the paper - * "A Traffic Congestion Assessment Method for Urban Road Networks Based on Speed Performance Index" by Feifei He, Xuedong Yan*, Yang Liu, Lu Ma. + * "A Traffic Congestion Assessment Method for Urban Road Networks Based on Speed Performance Index" by Feifei He, Xuedong Yan, Yang Liu, Lu Ma. */ public final class TrafficStatsCalculator { diff --git a/contribs/application/src/main/java/org/matsim/application/options/SampleOptions.java b/contribs/application/src/main/java/org/matsim/application/options/SampleOptions.java index 6a1cba85545..f9ac12190a9 100644 --- a/contribs/application/src/main/java/org/matsim/application/options/SampleOptions.java +++ b/contribs/application/src/main/java/org/matsim/application/options/SampleOptions.java @@ -124,6 +124,13 @@ public double getSample() { return sample; } + /** + * Return factor that is used to upscale the sample size. + */ + public double getUpscaleFactor() { + return 1.0 / sample; + } + private void setSize(double sample) { this.set = true; this.sample = sample; diff --git a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java index 4d78448cbe7..02ae5072583 100644 --- a/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java +++ b/contribs/application/src/main/java/org/matsim/freightDemandGeneration/DemandReaderFromCSV.java @@ -712,7 +712,6 @@ else if (samplingOption.equals("changeDemandOnLocation")) { .skip(rand.nextInt(usedServiceLocations.size() - 1)).findFirst().get())); } int demandForThisLink = calculateDemandForThisLink(demandToDistribute, numberOfJobs, distributedDemand, i); - Carrier thisCarrier = CarriersUtils.getCarriers(scenario).getCarriers() .get(Id.create(newDemandInformationElement.getCarrierName(), Carrier.class)); int numberOfJobsForDemand = calculateNumberOfJobsForDemand(thisCarrier, demandForThisLink); diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorDefaultImpl.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorDefaultImpl.java index f580b7e77f1..f6e5104fa86 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorDefaultImpl.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleLinkSpeedCalculatorDefaultImpl.java @@ -18,7 +18,10 @@ public final class BicycleLinkSpeedCalculatorDefaultImpl implements BicycleLinkS private static final Logger log = LogManager.getLogger(BicycleLinkSpeedCalculatorDefaultImpl.class ); @Inject private BicycleConfigGroup bicycleConfigGroup; @Inject private QSimConfigGroup qSimConfigGroup; - @Inject private BicycleLinkSpeedCalculatorDefaultImpl() { } + @Inject private Config config; + @Inject private BicycleLinkSpeedCalculatorDefaultImpl() { + } + /** * for unit testing */ diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java index 7bf5a766bf4..030a54935f5 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleModule.java @@ -22,8 +22,12 @@ import com.google.inject.Singleton; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.checkerframework.checker.units.qual.C; import org.matsim.api.core.v01.Id; import org.matsim.api.core.v01.Scenario; +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.events.StartupEvent; import org.matsim.core.controler.listener.StartupListener; @@ -34,30 +38,41 @@ * @author smetzler, dziemke */ public final class BicycleModule extends AbstractModule { - private static final Logger LOG = LogManager.getLogger(BicycleModule.class); - @Inject - private BicycleConfigGroup bicycleConfigGroup; + @Inject private BicycleConfigGroup bicycleConfigGroup; + + @Override public void install() { +// BicycleConfigGroup bicycleConfigGroup = ConfigUtils.addOrGetModule( this.getConfig(), BicycleConfigGroup.class ); +// this.bind( BicycleConfigGroup.class ).toInstance( bicycleConfigGroup ); + // the above feels odd. But it seems to work. I actually have no idea where the config groups are bound, neither for the core config + // groups nor for the added config groups. In general, the original idea was that AbstractModule provides the config from + // getConfig(), not from injection. kai, jun'24 + + // It actually does not work in general. The ExplodedConfigModule injects all config groups that are materialized by then. Which + // means that it needs to be materialized "quite early", and in particular before this install method is called. For the time being, + // a run script using the contrib thus needs to materialize the config group. kai, jul'24 + - @Override - public void install() { // The idea here is the following: // * scores are just added as score events. no scoring function is replaced. // * link speeds are computed via a plugin handler to the DefaultLinkSpeedCalculator. If the plugin handler returns a speed, it is // used, otherwise the default speed is used. This has the advantage that multiple plugins can register such special link speed calculators. + // this gives the typical things to the router: addTravelTimeBinding(bicycleConfigGroup.getBicycleMode()).to(BicycleTravelTime.class).in(Singleton.class); addTravelDisutilityFactoryBinding(bicycleConfigGroup.getBicycleMode()).to(BicycleTravelDisutilityFactory.class).in(Singleton.class); + // (the BicycleTravelTime uses the BicycleLinkSpeed Calculator bound below) + // (the BicycleDisutility uses a BicycleTravelDisutility) + // compute and throw the additional score events: this.addEventHandlerBinding().to( BicycleScoreEventsCreator.class ); - // (the motorized interaction is in the BicycleScoreEventsCreator) + // (this uses the AdditionalBicycleLinkScore to compute and throw corresponding scoring events) + // (it also computes and throws the motorized interaction events, if they are switched on) this.bind( AdditionalBicycleLinkScore.class ).to( AdditionalBicycleLinkScoreDefaultImpl.class ); - - bind( BicycleLinkSpeedCalculator.class ).to( BicycleLinkSpeedCalculatorDefaultImpl.class ) ; - // this is still needed because the bicycle travel time calculator for routing needs to use the same bicycle speed as the mobsim. kai, jun'23 + // (this computes the value of the per-link scoring event. yyyy Very unfortunately, it is a re-implementation of the BicycleTravelDisutility (mentioned above).) this.installOverridingQSimModule( new AbstractQSimModule(){ @Override protected void configureQSim(){ @@ -65,6 +80,9 @@ public void install() { } } ); + bind( BicycleLinkSpeedCalculator.class ).to( BicycleLinkSpeedCalculatorDefaultImpl.class ) ; + // (both the router and the mobsim need this) + addControlerListenerBinding().to(ConsistencyCheck.class); } @@ -73,7 +91,6 @@ static class ConsistencyCheck implements StartupListener { @Inject private Scenario scenario; @Override public void notifyStartup(StartupEvent event) { - Id bicycleVehTypeId = Id.create(bicycleConfigGroup.getBicycleMode(), VehicleType.class); if (scenario.getVehicles().getVehicleTypes().get(bicycleVehTypeId) == null) { LOG.warn("There is no vehicle type '" + bicycleConfigGroup.getBicycleMode() + "' specified in the vehicle types. " diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java index 135bc7e011f..ab7ffad85ad 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleTravelDisutilityFactory.java @@ -21,6 +21,8 @@ import com.google.inject.Inject; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.matsim.core.config.Config; +import org.matsim.core.config.ConfigUtils; import org.matsim.core.config.groups.ScoringConfigGroup; import org.matsim.core.config.groups.RoutingConfigGroup; import org.matsim.core.router.costcalculators.TravelDisutilityFactory; @@ -35,21 +37,20 @@ */ public final class BicycleTravelDisutilityFactory implements TravelDisutilityFactory { // public-final is ok since ctor is package-private: can only be used through injection - private static final Logger LOG = LogManager.getLogger(BicycleTravelDisutilityFactory.class); - - @Inject BicycleConfigGroup bicycleConfigGroup; - @Inject - ScoringConfigGroup cnScoringGroup; - @Inject - RoutingConfigGroup routingConfigGroup; - + private BicycleConfigGroup bicycleConfigGroup; + @Inject Config config; + @Inject ScoringConfigGroup cnScoringGroup; + @Inject RoutingConfigGroup routingConfigGroup; private static int normalisationWrnCnt = 0; - /* package-private */ BicycleTravelDisutilityFactory(){} + /* package-private */ BicycleTravelDisutilityFactory(){ + } @Override public TravelDisutility createTravelDisutility(TravelTime timeCalculator) { + this.bicycleConfigGroup = ConfigUtils.addOrGetModule( config, BicycleConfigGroup.class ); + double sigma = routingConfigGroup.getRoutingRandomness(); double normalization = 1; diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleUtils.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleUtils.java index 43bf5e63776..3af954d9c70 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleUtils.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/BicycleUtils.java @@ -127,4 +127,11 @@ private static boolean hasNoCycleway( String cyclewayType ) { } return userDefinedNetworkAttributeFactor; } + // === + public static void setSmoothness( Link link, String smoothness ){ + link.getAttributes().putAttribute( SMOOTHNESS, smoothness ); + } + public static void setBicycleInfrastructureFactor( Link link, double factor ){ + link.getAttributes().putAttribute( BICYCLE_INFRASTRUCTURE_SPEED_FACTOR, factor ); + } } diff --git a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/network/BicycleOsmNetworkReaderV2.java b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/network/BicycleOsmNetworkReaderV2.java index cd51b40275b..549f4c25656 100644 --- a/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/network/BicycleOsmNetworkReaderV2.java +++ b/contribs/bicycle/src/main/java/org/matsim/contrib/bicycle/network/BicycleOsmNetworkReaderV2.java @@ -225,7 +225,7 @@ protected void setOrModifyLinkAttributes(Link l, OsmWay way, boolean forwardDire // Smoothness String smoothness = way.tags.get(BicycleUtils.SMOOTHNESS); if (smoothness != null) { - l.getAttributes().putAttribute(BicycleUtils.SMOOTHNESS, smoothness); + BicycleUtils.setSmoothness( l, smoothness ); this.countSmoothness++; } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java index dc053728a40..a87c54a1be8 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/eshifts/scheduler/EShiftTaskScheduler.java @@ -6,6 +6,7 @@ import org.matsim.api.core.v01.network.Link; import org.matsim.api.core.v01.network.Network; import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtShiftChangeoverTaskImpl; +import org.matsim.contrib.drt.extension.operations.eshifts.schedule.EDrtWaitForShiftTask; import org.matsim.contrib.drt.extension.operations.eshifts.schedule.ShiftEDrtTaskFactoryImpl; import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacilities; import org.matsim.contrib.drt.extension.operations.operationFacilities.OperationFacility; @@ -22,10 +23,7 @@ import org.matsim.contrib.dvrp.fleet.Fleet; import org.matsim.contrib.dvrp.path.VrpPathWithTravelData; import org.matsim.contrib.dvrp.path.VrpPaths; -import org.matsim.contrib.dvrp.schedule.DriveTask; -import org.matsim.contrib.dvrp.schedule.Schedule; -import org.matsim.contrib.dvrp.schedule.StayTask; -import org.matsim.contrib.dvrp.schedule.Task; +import org.matsim.contrib.dvrp.schedule.*; import org.matsim.contrib.dvrp.tracker.OnlineDriveTaskTracker; import org.matsim.contrib.dvrp.util.LinkTimePair; import org.matsim.contrib.ev.charging.BatteryCharging; @@ -348,16 +346,20 @@ private void appendShiftChange(DvrpVehicle vehicle, DrtShift shift, OperationFac link, breakFacility)); } + @Override public void startShift(ShiftDvrpVehicle vehicle, double now, DrtShift shift) { - Schedule schedule = vehicle.getSchedule(); - StayTask stayTask = (StayTask) schedule.getCurrentTask(); - if (stayTask instanceof WaitForShiftTask) { - ((WaitForShiftTask) stayTask).getFacility().deregisterVehicle(vehicle.getId()); - stayTask.setEndTime(now); - schedule.addTask(taskFactory.createStayTask(vehicle, now, shift.getEndTime(), stayTask.getLink())); - } else { - throw new IllegalStateException("Vehicle cannot start shift during task:" + stayTask.getTaskType().name()); - } + Schedule schedule = vehicle.getSchedule(); + StayTask stayTask = (StayTask) schedule.getCurrentTask(); + if (stayTask instanceof WaitForShiftTask) { + ((WaitForShiftTask) stayTask).getFacility().deregisterVehicle(vehicle.getId()); + stayTask.setEndTime(now); + if(Schedules.getLastTask(schedule).equals(stayTask)) { + //nothing planned yet. + schedule.addTask(taskFactory.createStayTask(vehicle, now, shift.getEndTime(), stayTask.getLink())); + } + } else { + throw new IllegalStateException("Vehicle cannot start shift during task:" + stayTask.getTaskType().name()); + } } public boolean updateShiftChange(ShiftDvrpVehicle vehicle, Link link, DrtShift shift, @@ -379,17 +381,51 @@ public boolean updateShiftChange(ShiftDvrpVehicle vehicle, Link link, DrtShift s public void planAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) { Schedule schedule = vehicle.getSchedule(); StayTask stayTask = (StayTask) schedule.getCurrentTask(); - if (stayTask instanceof WaitForShiftTask) { - stayTask.setEndTime(Math.max(timeStep, shift.getStartTime())); + if (stayTask instanceof WaitForShiftTask waitForShiftTask) { + if(waitForShiftTask instanceof EDrtWaitForShiftTask eDrtWaitForShiftTask) { + if(eDrtWaitForShiftTask.getChargingTask() != null) { + Task nextTask = Schedules.getNextTask(vehicle.getSchedule()); + if(nextTask instanceof WaitForShiftTask) { + // set +1 to ensure this update happens after next shift start check + nextTask.setEndTime(Math.max(timeStep + 1, shift.getStartTime())); + //append stay task if required + if(Schedules.getLastTask(schedule).equals(nextTask)) { + schedule.addTask(taskFactory.createStayTask(vehicle, nextTask.getEndTime(), shift.getEndTime(), ((WaitForShiftTask) nextTask).getLink())); + } + } else { + throw new RuntimeException(); + } + } else { + stayTask.setEndTime(Math.max(timeStep +1 , shift.getStartTime())); + //append stay task if required + if(Schedules.getLastTask(schedule).equals(stayTask)) { + schedule.addTask(taskFactory.createStayTask(vehicle, stayTask.getEndTime(), shift.getEndTime(), stayTask.getLink())); + } + } + } } } + @Override public void cancelAssignedShift(ShiftDvrpVehicle vehicle, double timeStep, DrtShift shift) { Schedule schedule = vehicle.getSchedule(); StayTask stayTask = (StayTask) schedule.getCurrentTask(); - if (stayTask instanceof WaitForShiftTask) { - stayTask.setEndTime(vehicle.getServiceEndTime()); + if (stayTask instanceof WaitForShiftTask waitForShiftTask) { + if(waitForShiftTask instanceof EDrtWaitForShiftTask eDrtWaitForShiftTask) { + if(eDrtWaitForShiftTask.getChargingTask() != null) { + Task nextTask = Schedules.getNextTask(vehicle.getSchedule()); + if(nextTask instanceof WaitForShiftTask) { + nextTask.setEndTime(vehicle.getServiceEndTime()); + } else { + throw new RuntimeException(); + } + } else { + stayTask.setEndTime(vehicle.getServiceEndTime()); + } + } + } else { + throw new IllegalStateException("Vehicle should be in WaitForShiftTask"); } } diff --git a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java index 5d983e81f05..6e082f6f7d5 100644 --- a/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java +++ b/contribs/drt-extensions/src/main/java/org/matsim/contrib/drt/extension/operations/shifts/dispatcher/DrtShiftDispatcherImpl.java @@ -51,10 +51,10 @@ public class DrtShiftDispatcherImpl implements DrtShiftDispatcher { private final String mode; - private Queue unscheduledShifts; - private Queue assignedShifts; - private Queue activeShifts; - private Queue endingShifts; + private SortedSet unscheduledShifts; + private SortedSet assignedShifts; + private SortedSet activeShifts; + private SortedSet endingShifts; private Map, Queue> idleVehiclesQueues; @@ -63,8 +63,8 @@ public class DrtShiftDispatcherImpl implements DrtShiftDispatcher { private final MobsimTimer timer; - private final OperationFacilities operationFacilities; - private final OperationFacilityFinder breakFacilityFinder; + private final OperationFacilities operationFacilities; + private final OperationFacilityFinder breakFacilityFinder; private final ShiftTaskScheduler shiftTaskScheduler; private final Network network; @@ -73,8 +73,8 @@ public class DrtShiftDispatcherImpl implements DrtShiftDispatcher { private final ShiftsParams drtShiftParams; - private final ShiftStartLogic shiftStartLogic; - private final AssignShiftToVehicleLogic assignShiftToVehicleLogic; + private final ShiftStartLogic shiftStartLogic; + private final AssignShiftToVehicleLogic assignShiftToVehicleLogic; public DrtShiftDispatcherImpl(String mode, DrtShifts shifts, Fleet fleet, MobsimTimer timer, OperationFacilities operationFacilities, OperationFacilityFinder breakFacilityFinder, ShiftTaskScheduler shiftTaskScheduler, @@ -84,54 +84,56 @@ public DrtShiftDispatcherImpl(String mode, DrtShifts shifts, Fleet fleet, Mobsim this.shifts = shifts; this.fleet = fleet; this.timer = timer; - this.operationFacilities = operationFacilities; - this.breakFacilityFinder = breakFacilityFinder; + this.operationFacilities = operationFacilities; + this.breakFacilityFinder = breakFacilityFinder; this.shiftTaskScheduler = shiftTaskScheduler; this.network = network; this.eventsManager = eventsManager; this.drtShiftParams = drtShiftParams; - this.shiftStartLogic = shiftStartLogic; - this.assignShiftToVehicleLogic = assignShiftToVehicleLogic; + this.shiftStartLogic = shiftStartLogic; + this.assignShiftToVehicleLogic = assignShiftToVehicleLogic; } - @Override - public void initialize() { + @Override + public void initialize() { - unscheduledShifts = new PriorityQueue<>(Comparator.comparingDouble(DrtShift::getStartTime)); + unscheduledShifts = new TreeSet<>(Comparator.comparingDouble(DrtShift::getStartTime)); unscheduledShifts.addAll(shifts.getShifts().values()); - assignedShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getStartTime())); + assignedShifts = new TreeSet<>(Comparator.comparingDouble(v -> v.shift().getStartTime())); idleVehiclesQueues = new LinkedHashMap<>(); - for(OperationFacility facility: operationFacilities.getDrtOperationFacilities().values()) { - PriorityQueue queue = new PriorityQueue<>((v1, v2) -> String.CASE_INSENSITIVE_ORDER.compare(v1.getId().toString(), v2.getId().toString())); - Set> registeredVehicles = facility.getRegisteredVehicles(); - for (Id registeredVehicle : registeredVehicles) { - queue.add((ShiftDvrpVehicle) fleet.getVehicles().get(registeredVehicle)); - } - idleVehiclesQueues.put( - facility.getId(), - queue - ); - } - activeShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); - endingShifts = new PriorityQueue<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); + for(OperationFacility facility: operationFacilities.getDrtOperationFacilities().values()) { + PriorityQueue queue = new PriorityQueue<>((v1, v2) -> String.CASE_INSENSITIVE_ORDER.compare(v1.getId().toString(), v2.getId().toString())); + Set> registeredVehicles = facility.getRegisteredVehicles(); + for (Id registeredVehicle : registeredVehicles) { + queue.add((ShiftDvrpVehicle) fleet.getVehicles().get(registeredVehicle)); + } + idleVehiclesQueues.put( + facility.getId(), + queue + ); + } + activeShifts = new TreeSet<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); + endingShifts = new TreeSet<>(Comparator.comparingDouble(v -> v.shift().getEndTime())); } - @Override + @Override public void dispatch(double timeStep) { - if(timeStep % drtShiftParams.loggingInterval == 0) { - logger.info(String.format("Active shifts: %s | Assigned shifts: %s | Unscheduled shifts: %s", - activeShifts.size(), assignedShifts.size(), unscheduledShifts.size())); - for (Map.Entry, Queue> queueEntry : idleVehiclesQueues.entrySet()) { - logger.info(String.format("Idle vehicles at facility %s: %d", queueEntry.getKey().toString(), queueEntry.getValue().size())); - } - } + if(timeStep % drtShiftParams.loggingInterval == 0) { + logger.info(String.format("Active shifts: %s | Assigned shifts: %s | Unscheduled shifts: %s", + activeShifts.size(), assignedShifts.size(), unscheduledShifts.size())); + StringJoiner print = new StringJoiner(" | "); + for (Map.Entry, Queue> queueEntry : idleVehiclesQueues.entrySet()) { + print.add(String.format("Idle vehicles at facility %s: %d", queueEntry.getKey().toString(), queueEntry.getValue().size())); + } + logger.info(print.toString()); + } endShifts(timeStep); - if (timeStep % (drtShiftParams.updateShiftEndInterval) == 0) { - updateShiftEnds(timeStep); - } - assignShifts(timeStep); + if (timeStep % (drtShiftParams.updateShiftEndInterval) == 0) { + updateShiftEnds(timeStep); + } + assignShifts(timeStep); startShifts(timeStep); checkBreaks(); } @@ -166,13 +168,13 @@ private void startShifts(double timeStep) { final ShiftEntry assignedShiftEntry = iterator.next(); if (assignedShiftEntry.shift().getStartTime() > timeStep) { shiftTaskScheduler.planAssignedShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift()); - break; + continue; } else if (assignedShiftEntry.shift().getEndTime() < timeStep) { logger.warn("Too late to start shift " + assignedShiftEntry.shift().getId()); shiftTaskScheduler.cancelAssignedShift(assignedShiftEntry.vehicle(), timeStep, assignedShiftEntry.shift()); assignedShiftEntry.vehicle().getShifts().remove(assignedShiftEntry.shift()); iterator.remove(); - continue; + continue; } if (shiftStartLogic.shiftStarts(assignedShiftEntry)) { @@ -193,17 +195,24 @@ private void startShifts(double timeStep) { private void assignShifts(double timeStep) { // Remove elapsed shifts unscheduledShifts.removeIf(shift -> { - if (shift.getStartTime() + drtShiftParams.maxUnscheduledShiftDelay < timeStep ) { - logger.warn("Shift with ID " + shift.getId() + " could not be assigned and is being removed as start time is longer in the past than defined by maxUnscheduledShiftDelay."); + if (shift.getStartTime() + drtShiftParams.maxUnscheduledShiftDelay < timeStep ) { + logger.warn("Shift with ID " + shift.getId() + " could not be assigned and is being removed as start time is longer in the past than defined by maxUnscheduledShiftDelay."); return true; - } - return false; - }); + } + return false; + }); // Assign shifts Set assignableShifts = new LinkedHashSet<>(); - while (!this.unscheduledShifts.isEmpty() && isSchedulable(this.unscheduledShifts.peek(), timeStep)) { - assignableShifts.add(this.unscheduledShifts.poll()); + Iterator unscheduledShiftsIterator = unscheduledShifts.iterator(); + while(unscheduledShiftsIterator.hasNext()) { + DrtShift unscheduledShift = unscheduledShiftsIterator.next(); + if(isSchedulable(unscheduledShift, timeStep)) { + assignableShifts.add(unscheduledShift); + unscheduledShiftsIterator.remove(); + } else { + break; + } } for (DrtShift shift : assignableShifts) { @@ -213,24 +222,24 @@ private void assignShifts(double timeStep) { if (active.shift().getEndTime() > shift.getStartTime()) { break; } - if(shift.getOperationFacilityId().isPresent()) { - //we have to check that the vehicle ends the previous shift at the same facility where - //the new shift is to start. - if(active.shift().getOperationFacilityId().isPresent()) { - if(!active.shift().getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) { - continue; - } - } else { - Optional nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle().getSchedule()); - if(nextShiftChangeover.isPresent()) { - Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift())); - if(!nextShiftChangeover.get().getFacility().getId().equals(shift.getOperationFacilityId().get())) { - // there is already a shift changeover scheduled elsewhere - continue; - } - } - } - } + if(shift.getOperationFacilityId().isPresent()) { + //we have to check that the vehicle ends the previous shift at the same facility where + //the new shift is to start. + if(active.shift().getOperationFacilityId().isPresent()) { + if(!active.shift().getOperationFacilityId().get().equals(shift.getOperationFacilityId().get())) { + continue; + } + } else { + Optional nextShiftChangeover = ShiftSchedules.getNextShiftChangeover(active.vehicle().getSchedule()); + if(nextShiftChangeover.isPresent()) { + Verify.verify(nextShiftChangeover.get().getShift().equals(active.shift())); + if(!nextShiftChangeover.get().getFacility().getId().equals(shift.getOperationFacilityId().get())) { + // there is already a shift changeover scheduled elsewhere + continue; + } + } + } + } if (assignShiftToVehicleLogic.canAssignVehicleToShift(active.vehicle(), shift)) { vehicle = active.vehicle(); break; @@ -238,29 +247,29 @@ private void assignShifts(double timeStep) { } if (vehicle == null) { - final Iterator iterator; - - if(shift.getOperationFacilityId().isPresent()) { - //shift has to start at specific hub/facility - iterator = idleVehiclesQueues.get(shift.getOperationFacilityId().get()).iterator(); - } else { - //shift can start at random location - IteratorChain iteratorChain = new IteratorChain<>(); - for (Queue value : idleVehiclesQueues.values()) { - iteratorChain.addIterator(value.iterator()); - } - iterator = iteratorChain; - } - - while (iterator.hasNext()) { - final ShiftDvrpVehicle next = iterator.next(); - if (assignShiftToVehicleLogic.canAssignVehicleToShift(next, shift)) { - vehicle = next; - iterator.remove(); - break; - } - } - } + final Iterator iterator; + + if(shift.getOperationFacilityId().isPresent()) { + //shift has to start at specific hub/facility + iterator = idleVehiclesQueues.get(shift.getOperationFacilityId().get()).iterator(); + } else { + //shift can start at random location + IteratorChain iteratorChain = new IteratorChain<>(); + for (Queue value : idleVehiclesQueues.values()) { + iteratorChain.addIterator(value.iterator()); + } + iterator = iteratorChain; + } + + while (iterator.hasNext()) { + final ShiftDvrpVehicle next = iterator.next(); + if (assignShiftToVehicleLogic.canAssignVehicleToShift(next, shift)) { + vehicle = next; + iterator.remove(); + break; + } + } + } if (vehicle != null) { logger.debug("Shift assigned"); @@ -297,37 +306,37 @@ private void endShifts(double timeStep) { throw new IllegalStateException("Shifts don't match!"); } - logger.debug("Scheduling shift end for shift " + next.shift().getId() + " of vehicle " + next.vehicle().getId()); - scheduleShiftEnd(next); - endingShifts.add(next); - iterator.remove(); + logger.debug("Scheduling shift end for shift " + next.shift().getId() + " of vehicle " + next.vehicle().getId()); + scheduleShiftEnd(next); + endingShifts.add(next); + iterator.remove(); + } + } + + private void updateShiftEnds(double timeStep) { + final Iterator endingShiftsIterator = this.endingShifts.iterator(); + while (endingShiftsIterator.hasNext()) { + final ShiftEntry next = endingShiftsIterator.next(); + if (next.shift().isEnded()) { + endingShiftsIterator.remove(); + continue; + } + if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift().getEndTime()) { + if (next.vehicle().getShifts().size() > 1) { + updateShiftEnd(next); + } + } else { + break; + } + } + } + + private void updateShiftEnd(ShiftEntry next) { + + if(next.shift().getOperationFacilityId().isPresent()) { + //start and end facility are fixed + return; } - } - - private void updateShiftEnds(double timeStep) { - final Iterator endingShiftsIterator = this.endingShifts.iterator(); - while (endingShiftsIterator.hasNext()) { - final ShiftEntry next = endingShiftsIterator.next(); - if (next.shift().isEnded()) { - endingShiftsIterator.remove(); - continue; - } - if (timeStep + drtShiftParams.shiftEndRescheduleLookAhead > next.shift().getEndTime()) { - if (next.vehicle().getShifts().size() > 1) { - updateShiftEnd(next); - } - } else { - break; - } - } - } - - private void updateShiftEnd(ShiftEntry next) { - - if(next.shift().getOperationFacilityId().isPresent()) { - //start and end facility are fixed - return; - } final List tasks = next.vehicle().getSchedule().getTasks(); @@ -415,31 +424,31 @@ private void scheduleShiftEnd(ShiftEntry endingShift) { } final Coord coord = lastLink.getCoord(); - OperationFacility shiftChangeoverFacility = null; - - //check whether current shift has to end at specific facility - if(endingShift.shift().getOperationFacilityId().isPresent()) { - shiftChangeoverFacility = operationFacilities - .getDrtOperationFacilities() - .get(endingShift.shift().getOperationFacilityId().get()); - } else { - //check whether next shift has to start at specific facility - for (DrtShift shift : endingShift.vehicle().getShifts()) { - if (shift != endingShift.shift()) { - if (shift.getOperationFacilityId().isPresent()) { - shiftChangeoverFacility = operationFacilities - .getDrtOperationFacilities() - .get(shift.getOperationFacilityId().get()); - } - break; - } - } - } - - if(shiftChangeoverFacility == null) { - shiftChangeoverFacility = breakFacilityFinder.findFacilityOfType(coord, - OperationFacilityType.hub).orElseThrow(() -> new RuntimeException("Could not find shift end location!")); - } + OperationFacility shiftChangeoverFacility = null; + + //check whether current shift has to end at specific facility + if(endingShift.shift().getOperationFacilityId().isPresent()) { + shiftChangeoverFacility = operationFacilities + .getDrtOperationFacilities() + .get(endingShift.shift().getOperationFacilityId().get()); + } else { + //check whether next shift has to start at specific facility + for (DrtShift shift : endingShift.vehicle().getShifts()) { + if (shift != endingShift.shift()) { + if (shift.getOperationFacilityId().isPresent()) { + shiftChangeoverFacility = operationFacilities + .getDrtOperationFacilities() + .get(shift.getOperationFacilityId().get()); + } + break; + } + } + } + + if(shiftChangeoverFacility == null) { + shiftChangeoverFacility = breakFacilityFinder.findFacilityOfType(coord, + OperationFacilityType.hub).orElseThrow(() -> new RuntimeException("Could not find shift end location!")); + } Verify.verify(shiftChangeoverFacility.register(endingShift.vehicle().getId()), "Could not register vehicle at facility."); @@ -488,14 +497,14 @@ public void endBreak(ShiftDvrpVehicle vehicle, ShiftBreakTask previousTask) { new VehicleLeftShiftFacilityEvent(timer.getTimeOfDay(), mode, vehicle.getId(), facility.getId())); eventsManager.processEvent( new DrtShiftBreakEndedEvent(timer.getTimeOfDay(), mode, vehicle.getShifts().peek().getId(), - vehicle.getId(), previousTask.getFacility().getLinkId()) + vehicle.getId(), previousTask.getFacility().getLinkId()) ); } public void startBreak(ShiftDvrpVehicle vehicle, Id linkId) { eventsManager.processEvent( new DrtShiftBreakStartedEvent(timer.getTimeOfDay(), mode, - vehicle.getShifts().peek().getId(), vehicle.getId(), linkId) + vehicle.getShifts().peek().getId(), vehicle.getId(), linkId) ); } diff --git a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java index fc58f3b3b63..120cff4f5a3 100644 --- a/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java +++ b/contribs/drt-extensions/src/test/java/org/matsim/contrib/drt/extension/fiss/RunFissDrtScenarioIT.java @@ -184,7 +184,7 @@ public void install() { } run.run(); - Assertions.assertEquals(20842, linkCounter.getLinkLeaveCount()); + Assertions.assertEquals(20000, linkCounter.getLinkLeaveCount(), 2000); } static class LinkCounter implements LinkLeaveEventHandler { diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java index 88423d00a1f..da31ae5637d 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/CarrierAgent.java @@ -179,7 +179,7 @@ void scoreSelectedPlan() { } scoringFunction.finish(); final double score = scoringFunction.getScore(); - log.warn("score={}", score); + log.debug("score of carrier {} = {}", carrier.getId(), score); carrier.getSelectedPlan().setScore( score ); } void handleEvent(Event event, Id driverId) { diff --git a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java index 6b60f14d91b..f5613f1a961 100644 --- a/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java +++ b/contribs/freight/src/main/java/org/matsim/freight/carriers/controler/FreightAgentSource.java @@ -83,7 +83,7 @@ public final class FreightAgentSource implements AgentSource { vehicle = CarriersUtils.getVehicle( freightDriverPlan ); } - log.warn("inserting vehicleId={} into mobsim.", vehicle.getId()); + log.debug("inserting vehicleId={} into mobsim.", vehicle.getId()); qsim.addParkedVehicle( new QVehicleImpl( vehicle ), agent.getCurrentLinkId() ); // yyyyyy should rather use QVehicleFactory. kai, nov'18 diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java index d7befe82fc0..9a6f00f9520 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/DefaultDashboardProvider.java @@ -19,10 +19,13 @@ public List getDashboards(Config config, SimWrapper simWrapper) { List result = new ArrayList<>(List.of( new OverviewDashboard(), new TripDashboard(), - new TrafficDashboard(), - new StuckAgentDashboard() + new TrafficDashboard() )); + if (config.transit().isUseTransit()) { + result.add(new PublicTransitDashboard()); + } + if (config.counts().getCountsFileName() != null) { result.add(new TrafficCountsDashboard()); } @@ -35,6 +38,8 @@ public List getDashboards(Config config, SimWrapper simWrapper) { result.add(new NoiseDashboard()); } + result.add(new StuckAgentDashboard()); + return result; } diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java index b12052b7c7a..a7487fd625b 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/EmissionsDashboard.java @@ -20,7 +20,7 @@ public class EmissionsDashboard implements Dashboard { public void configure(Header header, Layout layout) { header.title = "Emissions"; - header.description = "Shows the emissions footprint and spatial distribution."; + header.description = "Shows the emissions footprint and spatial distribution. Shown values are already upscaled from simulated sample size."; layout.row("links") diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java new file mode 100644 index 00000000000..6903902d098 --- /dev/null +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/PublicTransitDashboard.java @@ -0,0 +1,28 @@ +package org.matsim.simwrapper.dashboard; + +import org.matsim.simwrapper.Dashboard; +import org.matsim.simwrapper.Header; +import org.matsim.simwrapper.Layout; +import org.matsim.simwrapper.viz.TransitViewer; + +/** + * Standard dashboard for public transit. + */ +public class PublicTransitDashboard implements Dashboard { + + @Override + public void configure(Header header, Layout layout) { + + header.title = "Public Transit"; + header.tab = "PT"; + header.triggerPattern = "*output_transitSchedule*xml*"; + + layout.row("viewer").el(TransitViewer.class, (viz, data) -> { + viz.title = "Transit Viewer"; + viz.height = 12d; + viz.description = "Visualize the transit schedule."; + viz.network = "*output_network.xml.gz"; + viz.transitSchedule = data.output("*output_transitSchedule.xml.gz"); + }); + } +} diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TrafficCountsDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TrafficCountsDashboard.java index 2bd83f1baba..8b65fba29ec 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TrafficCountsDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TrafficCountsDashboard.java @@ -69,7 +69,7 @@ public TrafficCountsDashboard withQualityLabels(List limits, List { + viz.backgroundColor = "transparent"; + viz.content = """ + ### Notes + - The speed performance index is the ratio of average travel speed and the maximum permissible road speed. + A performance index of 0.5, means that the average speed is half of the maximum permissible speed. A road with a performance index below 0.5 is considered to be in a congested state. + - The congestion index is the ratio of time a road is in an uncongested state. 0.5 means that a road is congested half of the time. A road with 1.0 is always uncongested. + + cf. *A Traffic Congestion Assessment Method for Urban Road Networks Based on Speed Performance Index* by Feifei He, Xuedong Yan*, Yang Liu, Lu Ma. + """; + }); + } } diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java index 28078cbd24b..6b52b1f4ae8 100644 --- a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/dashboard/TripDashboard.java @@ -11,7 +11,9 @@ import org.matsim.simwrapper.Layout; import org.matsim.simwrapper.viz.*; import tech.tablesaw.plotly.components.Axis; +import tech.tablesaw.plotly.components.Line; import tech.tablesaw.plotly.traces.BarTrace; +import tech.tablesaw.plotly.traces.ScatterTrace; import javax.annotation.Nullable; import java.io.BufferedReader; @@ -40,6 +42,8 @@ public class TripDashboard implements Dashboard { private String groupedRefCsv; @Nullable private String[] categories; + @Nullable + private String distanceRefCsv; private String[] args; @@ -83,6 +87,14 @@ private static String[] detectCategories(String groupedRefCsv) { } } + /** + * This enables detailed analysis of the distance distribution. + */ + public TripDashboard withDistanceDistribution(String modeShareDistRefCsv) { + this.distanceRefCsv = modeShareDistRefCsv; + return this; + } + /** * Set grouped reference data. Will enable additional tab with analysis for subgroups of the population. * @@ -257,6 +269,7 @@ public void configure(Header header, Layout layout) { }); + createDistancePlot(layout, args, tab); layout.row("departures", tab).el(Plotly.class, (viz, data) -> { @@ -306,6 +319,57 @@ public void configure(Header header, Layout layout) { } + private void createDistancePlot(Layout layout, String[] args, String tab) { + + layout.row("dist-dist", tab).el(Plotly.class, (viz, data) -> { + + viz.title = "Detailed distance distribution"; + viz.description = "by mode."; + viz.layout = tech.tablesaw.plotly.components.Layout.builder() + .xAxis(Axis.builder().title("Distance [m]").build()) + .yAxis(Axis.builder().title("Share").build()) + .showLegend(false) + .build(); + + viz.colorRamp = ColorScheme.Viridis; + viz.interactive = Plotly.Interactive.dropdown; + + Plotly.DataSet ds = viz.addDataset(data.compute(TripAnalysis.class, "mode_share_distance_distribution.csv", args)) + .pivot(List.of("dist"), "main_mode", "share") + .constant("source", "Sim"); + + viz.addTrace(ScatterTrace.builder(Plotly.INPUT, Plotly.INPUT) + .mode(ScatterTrace.Mode.LINE) + .build(), + ds.mapping() + .name("main_mode") + .x("dist") + .y("share") + ); + + if (distanceRefCsv != null) { + viz.description += " Dashed line represents the reference data."; + + Plotly.DataSet ref = viz.addDataset(data.resource(distanceRefCsv)) + .pivot(List.of("dist"), "main_mode", "share") + .constant("source", "Ref"); + + viz.addTrace(ScatterTrace.builder(Plotly.INPUT, Plotly.INPUT) + .mode(ScatterTrace.Mode.LINE) + .line(Line.builder().dash(Line.Dash.DASH).color("black").build()) + .build(), + ref.mapping() + .name("main_mode") + .text("source") + .x("dist") + .y("share") + ); + } + + }); + + } + private void createChoiceTab(Layout layout, String[] args) { layout.row("choice-intro", "Mode Choice").el(TextBlock.class, (viz, data) -> { @@ -421,8 +485,6 @@ private void createGroupedTab(Layout layout, String[] args) { viz.interactive = Plotly.Interactive.dropdown; - // TODO: modes are not separated into different traces - // probably dropdown config in plotly needs to be extended Plotly.DataMapping ds = viz.addDataset(data.computeWithPlaceholder(TripAnalysis.class, "mode_share_per_%s.csv", cat)) .pivot(List.of("main_mode", "dist_group", cat), "source", "share") .normalize(List.of("dist_group", "source", cat), "share") @@ -444,5 +506,4 @@ private void createGroupedTab(Layout layout, String[] args) { } } - } diff --git a/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java new file mode 100644 index 00000000000..ff9e8176b60 --- /dev/null +++ b/contribs/simwrapper/src/main/java/org/matsim/simwrapper/viz/TransitViewer.java @@ -0,0 +1,19 @@ +package org.matsim.simwrapper.viz; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * Transit viewer for pt schedules. + */ +public class TransitViewer extends Viz { + + @JsonProperty(required = true) + public String network; + + @JsonProperty(required = true) + public String transitSchedule; + + public TransitViewer() { + super("transit"); + } +} diff --git a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java index 0f5b273b809..2a248f2e1ea 100644 --- a/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java +++ b/contribs/simwrapper/src/test/java/org/matsim/simwrapper/dashboard/DashboardTests.java @@ -79,6 +79,7 @@ void tripRef() { TripDashboard dashboard = new TripDashboard("mode_share_ref.csv", "mode_share_per_dist_ref.csv", "mode_users_ref.csv") .withGroupedRefData("mode_share_per_group_dist_ref.csv") + .withDistanceDistribution("mode_share_distance_distribution.csv") .withChoiceEvaluation(true); run(dashboard); diff --git a/contribs/simwrapper/src/test/resources/mode_share_distance_distribution.csv b/contribs/simwrapper/src/test/resources/mode_share_distance_distribution.csv new file mode 100644 index 00000000000..fd654629c14 --- /dev/null +++ b/contribs/simwrapper/src/test/resources/mode_share_distance_distribution.csv @@ -0,0 +1,300 @@ +dist,car,bike,pt,ride,walk +0,0.003944185709709211,0.03574277628200462,0.0,0.00037518566775610664,0.9599378523405301 +100,0.011701245224666933,0.06340817090597038,0.0001121407069974153,0.0042250894716089485,0.9205533536907563 +200,0.019169744514796645,0.0893122044564802,0.0029477228742061396,0.007943944214489625,0.8806263839400273 +300,0.026454120383840485,0.11387016806273764,0.005852946985418339,0.01157440300941457,0.8422483615585888 +400,0.03358969683040535,0.13726864579468073,0.00883146182418116,0.01512659005423139,0.8051836054965014 +500,0.04061323303247179,0.1597872858612186,0.011867749118957528,0.018614271787587497,0.7691174601997646 +600,0.04784678709775937,0.18276920810315928,0.015044169123967811,0.022210598702522306,0.7321292369725912 +700,0.05734213014395564,0.2063976466031354,0.020761095019876587,0.027226351467094633,0.6882727767659378 +800,0.06816214612398162,0.23075623072886828,0.02809996433770487,0.03334978383688804,0.6396318749725572 +900,0.08024003137598233,0.2537713669048177,0.03722715420046467,0.04053105229077874,0.5882303952279565 +1000,0.09364179803228202,0.27369856857082314,0.04819638462547296,0.04853551992162743,0.5359277288497946 +1100,0.10815209473295054,0.2896612754900817,0.061088691181933455,0.05700637493902756,0.48409156365600664 +1200,0.1232212719481538,0.3019622446542897,0.07559986698022046,0.06546549661451352,0.4337511198028226 +1300,0.13836634275344512,0.3108373606129935,0.09091282143275427,0.07344298190904162,0.3864404932917656 +1400,0.15305940553232467,0.3166167362865903,0.106622022782901,0.08054229035462031,0.34315954504356383 +1500,0.16718472705231266,0.3196662233207097,0.12243086717410893,0.0866287797100008,0.30408940274286794 +1600,0.18074160725323074,0.31998662551253926,0.13803737572256664,0.09151578936071274,0.26971860215095056 +1700,0.1935482723020434,0.31817337820339026,0.15321472621092924,0.09518315363206561,0.23988046965157156 +1800,0.20532034709529492,0.31611869272157034,0.1679915712780288,0.09760140565798013,0.21296798324712582 +1900,0.21580176882702776,0.3146373506893864,0.18231537962307767,0.09915606961335534,0.18808943124715283 +2000,0.22468765695699847,0.3135340991553317,0.19583828064196956,0.10039147352520297,0.1655484897204973 +2100,0.2320390038133107,0.3116926400097604,0.20855096231240602,0.10166512340515747,0.14605227045936547 +2200,0.2380819792506679,0.30869778321984614,0.22053019447943822,0.10310428120772884,0.12958576184231907 +2300,0.24319551277452806,0.30508552753141654,0.2313966740266772,0.1046602681206329,0.11566201754674531 +2400,0.24740978487991802,0.3017946569397511,0.24027214876964206,0.10619319093791682,0.10433021847277195 +2500,0.25147380264601127,0.29858419290780464,0.24745094294156134,0.10784057535174722,0.09465048615287541 +2600,0.2557081800597713,0.2944242245483245,0.254338405626125,0.10983364707192515,0.08569554269385418 +2700,0.26005333523487556,0.28838565315986364,0.26158066268749924,0.11234778706359465,0.07763256185416688 +2800,0.26438416817880983,0.280611150092087,0.26888318706237135,0.11521145502857368,0.07091003963815808 +2900,0.2682783800528302,0.2726124724825396,0.2756396595690925,0.11833178417595261,0.06513770371958504 +3000,0.27132169151827706,0.26621281194912927,0.281363176346151,0.12160735741899721,0.05949496276744551 +3100,0.2737623173544646,0.2613722495444328,0.28602764052844565,0.12465212676448884,0.054185665808168096 +3200,0.2752050644701451,0.25765183237406514,0.29053676388248717,0.12692664007901375,0.0496796991942889 +3300,0.2755335668276074,0.25414256527537704,0.2961907003290296,0.12822749403075626,0.045905673537229595 +3400,0.27546962770627187,0.24959144103020722,0.3038254719339772,0.128650706320345,0.04246275300919872 +3500,0.275852888106488,0.24461016400363972,0.31218634809445833,0.12807332486763146,0.03927727492778241 +3600,0.2767344858836351,0.24055620257468846,0.319580451397353,0.12682070092540043,0.03630815921892315 +3700,0.27805269721474923,0.23775684456973434,0.32586250733517447,0.12497622419270152,0.033351726687640526 +3800,0.27990378773934443,0.23490832801299452,0.331806257334882,0.12301388863447164,0.03036773827830728 +3900,0.2824088112165455,0.2310003638838484,0.33771130717376985,0.12131495561119951,0.027564562114636655 +4000,0.2852664175352708,0.22624522603645245,0.3435830853261446,0.11963105302180563,0.025274218080326673 +4100,0.28757227850383676,0.22219425556166225,0.34895088956114434,0.11810340256156933,0.023179173811787322 +4200,0.2892860820110079,0.21950746602333254,0.35266462797361464,0.11730689319530663,0.021234930796738084 +4300,0.2905846066726926,0.21817348003240541,0.3544434350048095,0.11696017192331501,0.01983830636677753 +4400,0.29079767729915024,0.21832389444644654,0.3552632635110481,0.11671696692773488,0.01889819781562023 +4500,0.29054464552643655,0.2187565545308431,0.35621331692068825,0.11644817822293935,0.01803730479909268 +4600,0.29071376079094585,0.21815056970721644,0.35814530168997827,0.11602278248671279,0.016967585325146833 +4700,0.29149314706948726,0.21628524084231726,0.3611948723023975,0.11521754980569271,0.01580918998010539 +4800,0.2927416557039059,0.21329664797980755,0.36484248837838756,0.11448678443678055,0.014632423501118458 +4900,0.2939283284766885,0.2093825114338426,0.36909058733655126,0.11419257101424245,0.01340600173867514 +5000,0.2943703318843527,0.20503505319621854,0.3740579024965238,0.11425386578069209,0.012282846642212707 +5100,0.2947281320102329,0.20064785365238091,0.37920970585179475,0.11399087352866029,0.011423434956931168 +5200,0.2952005810632277,0.1966183253462185,0.3842091954611987,0.11297690633918127,0.010994991790173709 +5300,0.2954694412637997,0.19305650254355664,0.38862751336965484,0.11200435977565158,0.01084218304733732 +5400,0.2956013995192241,0.19003237035082865,0.39145872828055284,0.11198568246374727,0.010921819385647139 +5500,0.295920289526642,0.18765361137233574,0.3928612135544049,0.11245785812593388,0.01110702742068355 +5600,0.29620274791867335,0.18602174454261,0.3939712285519109,0.11278590827065553,0.011018370716150317 +5700,0.29700022366082723,0.18460542080407022,0.3953244047532656,0.1124379144039675,0.010632036377869396 +5800,0.2991712652148869,0.18316762386679863,0.3956759916902435,0.11177576119688537,0.010209358031185575 +5900,0.30281068623960566,0.18107647112858022,0.3948546754217751,0.1112549206294131,0.010003246580626022 +6000,0.30760418385322613,0.17801668245256075,0.39340985019348257,0.11105953395226086,0.009909749548469605 +6100,0.3120780594034644,0.17430955427982733,0.39273877608556473,0.1112310729291791,0.009642537301964448 +6200,0.3149138339517079,0.17060832803704515,0.39421250391680623,0.11101290406126946,0.009252430033171307 +6300,0.3163211386544086,0.16688128870624544,0.39833815779540177,0.10963883358605299,0.008820581257890986 +6400,0.3168885716270779,0.1631029587545106,0.4039846665931847,0.10748564138323057,0.008538161641996302 +6500,0.3163853132336465,0.1601672329456284,0.40972902212947393,0.10514820322266033,0.008570228468590872 +6600,0.3146552775257205,0.15894417720988466,0.4148907108245583,0.1029047418962418,0.008605092543594872 +6700,0.31178450759837123,0.1589825476919096,0.42054070390500253,0.10040983964878102,0.008282401155935619 +6800,0.30765869257616435,0.15897938297567632,0.42790233035724856,0.09788817923493068,0.007571414855980117 +6900,0.3031234488944087,0.15835248013794465,0.43562916456461576,0.09608202872773462,0.006812877675296376 +7000,0.30059353222822577,0.15649830655749544,0.4406048531416794,0.09599479772562099,0.00630851034697845 +7100,0.30147734178805335,0.15348495830904818,0.44207247110851283,0.09697598730724549,0.005989241487140272 +7200,0.30477037670371454,0.15043709304413938,0.44132338730885484,0.09798080768138748,0.005488335261903595 +7300,0.30931379002328574,0.14744495887545409,0.4391650248839597,0.09926294271788191,0.004813283499418607 +7400,0.3145250031363783,0.1441665231160985,0.4361382426512812,0.10084213626174753,0.00432809483449452 +7500,0.3199953787910249,0.1399930976671494,0.4335633611166701,0.1022618051664066,0.004186357258748942 +7600,0.3255444419424304,0.13491940666015817,0.4318459378422744,0.10330157780809669,0.004388635747040414 +7700,0.33066978269969555,0.1303864944222729,0.4305132883122282,0.10356744233071624,0.004862992235087065 +7800,0.3346043891458717,0.1269827960715251,0.4302755165111089,0.10296319610511989,0.005174102166374413 +7900,0.3360715638175254,0.12519883396270184,0.43200679058006564,0.10144914081550105,0.005273670824206123 +8000,0.334640790446691,0.12477426399902476,0.43573008222127113,0.09924847720302252,0.005606386129990566 +8100,0.33213142714296695,0.12443653103813718,0.4395962197986949,0.0976268418752624,0.0062089801449385406 +8200,0.33107092875929944,0.12301440992229622,0.4416068653574643,0.09738599288239812,0.006921803078541837 +8300,0.3322562552375935,0.12071335448683616,0.44175999507415387,0.09785345887779752,0.007416936323619015 +8400,0.3343026623829796,0.11857176277621778,0.44152588643373936,0.09815898784420019,0.007440700562863161 +8500,0.33674968239776865,0.11653183762443622,0.4408253211737455,0.09863097778223112,0.007262181021818691 +8600,0.33912167321391457,0.11504978101230556,0.4399428826279596,0.098746063513719,0.007139599632101268 +8700,0.34161552574285703,0.11377864300132756,0.43921050150302954,0.09829491376650987,0.007100415986275998 +8800,0.34345221253717667,0.11244637975200669,0.43954782701958567,0.09736731572590539,0.007186264965325571 +8900,0.34396420494945923,0.11150514754309751,0.4412610391057008,0.09613948545629122,0.007130122945451008 +9000,0.3427447518662358,0.11145571035801106,0.44449734501386234,0.09452926480212648,0.00677292795976445 +9100,0.33889285241848643,0.11253183053236336,0.45031265872217896,0.09196385741190528,0.006298800915065851 +9200,0.3336669482783479,0.1134892023479546,0.45865681683120374,0.08819420623329507,0.005992826309198492 +9300,0.3289025705331273,0.11348663993291781,0.46731014926673503,0.08447376399968726,0.005826876267532717 +9400,0.32493268245886175,0.11252817183693045,0.4750992797553844,0.08170200775760447,0.0057378581912189775 +9500,0.32214693234402464,0.1106579594925726,0.48173691905293803,0.07995360401807224,0.005504585092392341 +9600,0.3212856976546727,0.10798132357698269,0.4866778855681674,0.07888060651350967,0.005174486686667575 +9700,0.3231233065511186,0.10451121792877666,0.4882523772684013,0.0790186948898093,0.005094403361894107 +9800,0.326591288702599,0.10233748770925298,0.4867177339140384,0.07934799272908354,0.005005496945026043 +9900,0.33033199309304595,0.10223317100731696,0.48295479127151086,0.07964759443149812,0.004832450196628059 +10000,0.332623476986607,0.10392322548495701,0.47831054579067794,0.08034515909139255,0.004797592646365311 +10100,0.33349673860375345,0.1064764414583982,0.4736181791737175,0.08136887706342233,0.0050397637007084245 +10200,0.33432874916821775,0.10839986317417392,0.46940861773685993,0.08239100408191506,0.0054717658388332285 +10300,0.33663453365083645,0.10770460087860513,0.46633675581615114,0.08337864074198886,0.0059454689124185025 +10400,0.3404049839843345,0.10441995340275494,0.46428750916833894,0.08460044534143857,0.0062871081031330295 +10500,0.34365790107945965,0.09964272875511318,0.46364958750285873,0.08671726100033575,0.006332521662232755 +10600,0.34552044112406316,0.09458183118584063,0.4651552779891012,0.0887975232378272,0.005944926463167861 +10700,0.3466808424969561,0.08992592353099621,0.46809316115262406,0.09004150177341785,0.005258571046005839 +10800,0.3476540383110092,0.08531568124768088,0.4715528688669912,0.09077744628192347,0.004699965292395249 +10900,0.3487618868010548,0.08021569909171704,0.47450283652222763,0.09179030665719705,0.0047292709278034875 +11000,0.34981810379387535,0.0756182560815686,0.4766986605697859,0.09269930852597585,0.005165671028794336 +11100,0.35069008988381656,0.07199811807143205,0.4781583176488935,0.09344522991095218,0.005708244484905714 +11200,0.3512373404433965,0.07004144053928892,0.47918590883550166,0.09311988712594702,0.0064154230558660305 +11300,0.3510728703568192,0.06988528846316891,0.4814511810046708,0.09042664919057947,0.007164010984761484 +11400,0.3501659797384926,0.07119782536102774,0.4849013222420671,0.08594282610847258,0.0077920465499397755 +11500,0.3502266428625708,0.07244678514010582,0.48726891172242254,0.08172118958629243,0.008336470688608292 +11600,0.3515476656858425,0.07332265456510285,0.48723536488396574,0.07919064759050176,0.0087036672745871 +11700,0.35280716517037564,0.07392414008446771,0.48688809612729905,0.07788442160756133,0.008496177010296136 +11800,0.3535518317940175,0.07488697212045167,0.4877126534366569,0.07622975764465151,0.007618785004222498 +11900,0.3532559622571539,0.07630204763313102,0.48968744124971497,0.07443407018363783,0.006320478676362388 +12000,0.3515930492142177,0.07766164992831871,0.4925650844213227,0.07325799694409808,0.004922219492042807 +12100,0.3486746530901627,0.0786184358762612,0.49575026770104924,0.07322696307157492,0.0037296802609520364 +12200,0.3459631830156185,0.07910539121020793,0.49734216915848095,0.07471306045813585,0.0028761961575567967 +12300,0.34515164645623286,0.07852330317132618,0.497099722911959,0.07690528383052488,0.002320043629957131 +12400,0.3459692806589574,0.07614271216448953,0.49751775821913646,0.07829200754828933,0.0020782414091272796 +12500,0.3473294269536054,0.07284667617898927,0.49909875988414526,0.078785545697462,0.0019395912857979472 +12600,0.3492697734782812,0.07055652236622659,0.4993771084837752,0.07887081410385641,0.0019257815678606154 +12700,0.35165913759661094,0.06930984359987807,0.49734401770347036,0.0793690132210364,0.0023179878790042198 +12800,0.3534330142705426,0.0685168380910896,0.4942301979699518,0.08060951994893653,0.0032104297194793657 +12900,0.35421885101175854,0.06776758717632732,0.49180707969249465,0.0819005661128331,0.004305916006586208 +13000,0.3540822179979868,0.0661512996857427,0.4919734187183986,0.08253613716916212,0.005256926428709651 +13100,0.35342829486563304,0.06405367530755271,0.49394237720987055,0.08266669727070296,0.005908955346240877 +13200,0.3527830056486237,0.062079886000871755,0.49724567618502824,0.08170438670049396,0.006187045464982326 +13300,0.35118847649542645,0.060669747155702516,0.5014068771485422,0.08043809680516903,0.006296802395159802 +13400,0.3496204769128433,0.05942459609269626,0.5049403839900514,0.07963710509984248,0.006377437904566406 +13500,0.3495314643746348,0.057607537059823515,0.5070270014551675,0.07942874580916505,0.006405251301209198 +13600,0.3512771833636974,0.05467792754601138,0.5088506982237178,0.0792095850794595,0.005984605787114015 +13700,0.3536751452904462,0.05190061697309672,0.5107738723328092,0.0786834845029321,0.004966880900715792 +13800,0.354742578974646,0.05086258511488499,0.5128743614793818,0.07780940769315979,0.00371106673792734 +13900,0.35337846055225414,0.05129948384736346,0.5141394594794085,0.07826314837774705,0.0029194477432267353 +14000,0.3502608353310682,0.05176879006408448,0.5146490409198109,0.08031357999632413,0.0030077536887120047 +14100,0.3479646876052328,0.052001256018598334,0.5126737098783506,0.08369621619637188,0.0036641303014464765 +14200,0.3467724704687371,0.05234536611327431,0.5094025274461869,0.08721332470421704,0.004266311267584765 +14300,0.3458939420186927,0.05283868653849691,0.5069653056867282,0.08982480736812844,0.004477258387953727 +14400,0.34419383949094845,0.05317154579641435,0.5077953632376326,0.09054675442316235,0.0042924970518421 +14500,0.34206579427473216,0.0533915811873866,0.5105773837658292,0.0900344684454732,0.003930772326578891 +14600,0.34096457737932545,0.0531642950978982,0.5137539489580658,0.08847091840444228,0.003646260160268298 +14700,0.34185829504357707,0.05206629441210561,0.5153786536953597,0.08705653960769522,0.0036402172412623502 +14800,0.3451136746853569,0.051363986408669876,0.5139185494433137,0.08605099480616986,0.0035527946564896744 +14900,0.34876836765395003,0.05134269666917897,0.5119371007087012,0.0848413259434568,0.003110509024712872 +15000,0.34987479519923204,0.051848430797233586,0.5123654205637322,0.08354519285053809,0.0023661605892641006 +15100,0.35073491475575935,0.05160374430672114,0.5132647067219768,0.08266891528617965,0.0017277189293630518 +15200,0.3533769908219431,0.04982294800478374,0.51286121936596,0.0824108546089649,0.0015279871983482267 +15300,0.35829879100781925,0.047619887984084106,0.5081203160440892,0.0843046766430162,0.0016563283209913118 +15400,0.36438903901491226,0.046767064832046214,0.4994026972613257,0.08769563691522099,0.0017455619764948213 +15500,0.3703076027775079,0.04560064577822244,0.4919479639255102,0.09047439801465251,0.0016693895041069008 +15600,0.37644880054132307,0.043149337858934884,0.48747282882555154,0.0914725597900988,0.0014564729840916718 +15700,0.3832533527154736,0.03987087187931813,0.4846315317068988,0.09105568446572862,0.001188559232580744 +15800,0.38911481145173965,0.036635718038923376,0.483185340127183,0.09012260707422778,0.0009415233079263451 +15900,0.39333782273404705,0.034346239793475515,0.48148048326239373,0.09007831588833208,0.0007571383217516961 +16000,0.39671288097581386,0.03387630220257963,0.47827303537421684,0.09060979644498543,0.0005279850024043422 +16100,0.3998092415304151,0.03369447134976605,0.4757602526959003,0.09048109019026992,0.00025494423364862264 +16200,0.40144457611037515,0.03301595193542206,0.47597561517437054,0.08951300056839265,5.085621143955609e-05 +16300,0.40307373382750894,0.0317049768812926,0.47757465657186055,0.087646632719338,0.0 +16400,0.40567004311313576,0.030514899198242473,0.4782678421523515,0.08554721553627018,0.0 +16500,0.40777822694196014,0.030177353127346283,0.47763707434011793,0.08440734559057571,0.0 +16600,0.4081581418343006,0.030722333058722327,0.47742204736276,0.0836974777442171,0.0 +16700,0.4072558170344897,0.03105266190784093,0.47890330589226493,0.08273236764788475,5.584751751956769e-05 +16800,0.4077100348839108,0.030938097193742294,0.479310621620526,0.08175182762701788,0.00028941867480312245 +16900,0.4090694716869422,0.03141730714937055,0.4779228616654376,0.08096905727333781,0.00062130222491177 +17000,0.4096325774592674,0.03317240921254907,0.4765725189111758,0.0796999429999717,0.0009225514170361303 +17100,0.409318950129627,0.036416273191669915,0.4759463860501217,0.0772010848219748,0.0011173058066065345 +17200,0.4091322273159482,0.03971971816744722,0.4761228299047345,0.07382438051613933,0.0012008440957308444 +17300,0.40917878287625953,0.041376286772682035,0.47732946132916715,0.07089644446189847,0.0012190245599926076 +17400,0.40796678344949716,0.04134184760987771,0.4808650383610144,0.06860969238333003,0.0012166381962804955 +17500,0.4069055769398501,0.040259317584171485,0.48534215525436136,0.0663396391468098,0.0011533110748072363 +17600,0.4073714217435671,0.03867637636174271,0.48873322626000065,0.06424237237588457,0.0009766032588049169 +17700,0.4082070183450192,0.03681720852155175,0.4917890615422369,0.06251096202188594,0.0006757495693060654 +17800,0.40851930992274343,0.03405948660427341,0.4956107932771341,0.06148761266152315,0.00032279753432586496 +17900,0.40834638056816525,0.030057523585525523,0.4992926369932518,0.062175477327735026,0.00012798152532237834 +18000,0.40869966431198385,0.025485516620014383,0.5007566895943754,0.06473163216966882,0.00032649730395761193 +18100,0.4103114989276243,0.02206435248347342,0.4990825597685239,0.0678483880870413,0.0006932007333369842 +18200,0.4125275955278045,0.020471448306712096,0.4962059690581323,0.06977318455160707,0.0010218025557439737 +18300,0.41556837263605517,0.0206159334052642,0.49291632607629127,0.06966729786541252,0.0012320700169767373 +18400,0.41922344744217654,0.021424654150831928,0.4895518490887264,0.06847296087200397,0.001327088446261135 +18500,0.42232284778449486,0.0217839827158899,0.4867244275846881,0.06780939466890122,0.0013593472460257043 +18600,0.4233615462574494,0.022240682195265638,0.4854909346659724,0.06753024566346263,0.0013765912178499511 +18700,0.42221463009837973,0.023175998277689874,0.4862114474386642,0.06706868155366034,0.0013292426316058692 +18800,0.41938452682387994,0.024671257246244315,0.48845387119608186,0.06634303755896588,0.0011473071748282068 +18900,0.4162698274751706,0.02606826102222086,0.4918802760301444,0.0649713055171278,0.0008103299553361399 +19000,0.41370970500856974,0.02619427177378781,0.49541371836161135,0.06428721934177216,0.00039508551425894553 +19100,0.4111836219465369,0.024935190838525294,0.49810665113387514,0.06569494066032154,7.959542074096334e-05 +19200,0.40900764184359,0.023272440638810805,0.500030017898224,0.06768989961937528,0.0 +19300,0.4077586478909343,0.021863494759432046,0.5012108598178834,0.06916699753175017,0.0 +19400,0.408311133192338,0.02043513389032554,0.5000603914760281,0.07094521295009655,0.0002481284912116819 +19500,0.410657267981849,0.018745544224635223,0.4962127982796929,0.07311330075798793,0.001271088755835052 +19600,0.4129873601348296,0.017541385732083054,0.491204116898825,0.0755496223485488,0.0027175148857134764 +19700,0.4155038566448603,0.01783483589445665,0.48429098444630636,0.0783316029268498,0.004038720087526871 +19800,0.4194232425491414,0.019943310031264753,0.4745851157306195,0.0811460202126344,0.00490231147634016 +19900,0.4237634410357246,0.02274289988633667,0.46453684930906475,0.08366798824179451,0.005288821527079398 +20000,0.42924811067875895,0.025272981164161663,0.45383841362633387,0.08624649868021858,0.005393995850526764 +20100,0.435043355622225,0.02711028131661334,0.44499696189855414,0.08742500693034187,0.005424394232265606 +20200,0.4381158298860281,0.028752098345993304,0.4412202762654395,0.08670593887789967,0.0052058566246392666 +20300,0.43629361335970757,0.030858715295792465,0.44443228092985504,0.08395950185201377,0.004455888562631062 +20400,0.4301135651058379,0.03229097649863405,0.45497696288948875,0.07952490603192432,0.0030935894741149603 +20500,0.4229102459145983,0.03199253408632643,0.4681190576986417,0.07549949461909383,0.001478667681339733 +20600,0.4158022740307024,0.029769281238211487,0.48033066235687283,0.07370570116985865,0.0003920812043545203 +20700,0.4070478601985252,0.027064485172408996,0.49220904618105293,0.073174473103939,0.0005041353440738187 +20800,0.39614273429614333,0.025981097158521337,0.5027713369503549,0.07402198766670785,0.001082843928272513 +20900,0.3872177116718546,0.026557635242180744,0.5087847224084467,0.0758282435040628,0.0016116871734550978 +21000,0.38398482616329394,0.027228215559169877,0.5085444034607474,0.07829032074796632,0.00195223406882252 +21100,0.3875603035923633,0.02685374484593285,0.5021392195650695,0.08134417588854626,0.0021025561080882244 +21200,0.3978927373794572,0.02541002434753572,0.4902379575422398,0.08432013650391704,0.002139144226850326 +21300,0.41151318116860797,0.02372890718179091,0.4770756142023481,0.08543752773436995,0.0022447697128831837 +21400,0.42436562739417444,0.0227365967225967,0.4653685865307477,0.08493939959299171,0.0025897897594894764 +21500,0.4358877624320956,0.02220953030988447,0.45558016303078025,0.08340550425415166,0.002917039973088014 +21600,0.44642680413653185,0.021174874782133524,0.4482061421154049,0.08122859103575707,0.0029635879301725993 +21700,0.45775849923504686,0.019856265060823254,0.44139246353032185,0.07826547741833999,0.0027272947554679993 +21800,0.4658513182991035,0.019149391365781768,0.4374855081463585,0.07505499949051757,0.002458782698238717 +21900,0.46881670530836345,0.019440780279391227,0.4373238344796474,0.07198624195049307,0.0024324379821049984 +22000,0.4681729774766497,0.02094882734441416,0.4379040741275592,0.07048253252957828,0.0024915885217985647 +22100,0.4653750905928244,0.023669971931632054,0.4376461934110921,0.07089950364094785,0.002409240423503521 +22200,0.46265914347386955,0.026838523765721486,0.43511445967853835,0.07332780925396575,0.0020600638279048757 +22300,0.4618967857243901,0.029186048225720025,0.43049337975308427,0.07698764200459184,0.001436144292213776 +22400,0.45995327004306485,0.030540930532941254,0.4275623253211247,0.08125460241384186,0.0006888716890271567 +22500,0.45575973471448344,0.031464642145538894,0.4286101753494344,0.08402988505949326,0.00013556273105010428 +22600,0.4520944155950475,0.03200617677241399,0.4305683798237246,0.08533102780881391,0.0 +22700,0.4518830954733447,0.03168387156406179,0.4312106796254198,0.0852223533371737,0.0 +22800,0.45458546969373964,0.030382457343753496,0.43228790023171615,0.08274417273079053,0.0 +22900,0.46001913818967993,0.02936451405390396,0.4330924556750935,0.07752389208132256,0.0 +23000,0.46778067441738336,0.028956505216714695,0.4309893167285267,0.07227350363737518,0.0 +23100,0.47627422783211293,0.028237285206726033,0.4271334384627051,0.06820951467957559,0.00014553381888040876 +23200,0.48290756775606597,0.02775470136824582,0.4231227486653074,0.06545419917490443,0.0007607830354762156 +23300,0.4858705505533305,0.0279681679700472,0.4202439721647368,0.06427099024193132,0.0016463190699540669 +23400,0.48584305871213085,0.02736877345662722,0.4190982807641512,0.06522977243789538,0.0024601146291954703 +23500,0.4864184247251404,0.02574038245309708,0.4167272558732944,0.0681033683903014,0.0030105685581667432 +23600,0.4905049504365615,0.024752648848085798,0.40830015068507347,0.07316042974375656,0.0032818202865225665 +23700,0.49652123563701683,0.024465530904079637,0.39672567713807644,0.0789294495175657,0.0033581068032613455 +23800,0.5011079550606421,0.022760950317863304,0.3883145259103277,0.08446151073270322,0.0033550579784637157 +23900,0.5019675996278283,0.019104984769266125,0.3877078559911522,0.08802584180783582,0.0031937178039173823 +24000,0.49892111687839974,0.014672586175812668,0.395172204172851,0.08851029255439923,0.002723800218537321 +24100,0.4970959884538086,0.011589232340675552,0.4039045212229103,0.08550835133123207,0.001901906651373451 +24200,0.5008157494993369,0.010812911777747219,0.4068400063549502,0.08060889903084516,0.0009224333371204349 +24300,0.5055672381199657,0.011139838890019089,0.40845148254600955,0.07465550386400038,0.00018593658000528064 +24400,0.5058483546632243,0.011631946219614176,0.4133992078890603,0.0691204912281013,0.0 +24500,0.500471052955471,0.011010559715707507,0.4218404344311667,0.06667795289765487,0.0 +24600,0.49201847943224153,0.009367474600624778,0.4297153384224725,0.06889870754466125,0.0 +24700,0.4840179911951928,0.008072269168697499,0.4352122514459639,0.07269748819014586,0.0 +24800,0.4777419954944325,0.008583703565690076,0.439012971058813,0.07466132988106439,0.0 +24900,0.4743511229403143,0.00993515341935268,0.4400404773560362,0.07567324628429696,0.0 +25000,0.4734263239294324,0.011154329451766821,0.4372720195216476,0.07814732709715325,0.0 +25100,0.47214954717521307,0.012671469202629534,0.4328887995120403,0.08229018411011717,0.0 +25200,0.4690412224027795,0.01458640258016774,0.4293233325637628,0.08685261919026369,0.00019642326302624378 +25300,0.46541516194794424,0.01676258867265909,0.4270562982545973,0.0897400434602404,0.0010259076645590048 +25400,0.46371117679792273,0.019231579596808768,0.4245349273933989,0.090290016396749,0.002232299815120635 +25500,0.46548730579355985,0.02080148751916184,0.42241703205340264,0.0879314977338606,0.0033626769000151876 +25600,0.4702117449491536,0.020905075354453503,0.4202569994500889,0.08426106329527593,0.004365116951028285 +25700,0.47452820586510747,0.019811697793625436,0.41893292325246656,0.08098069950856415,0.005746473580236355 +25800,0.4787973600696003,0.017579398694637944,0.4171538855568278,0.07906001982355138,0.007409335855382714 +25900,0.48142864162616433,0.0140995800494763,0.41736066595998533,0.07793627260616152,0.009174839758212388 +26000,0.48319206932827824,0.00987895547419868,0.41961113811415,0.07634724309639615,0.010970593986977013 +26100,0.4890404081481975,0.005766224994094788,0.41821353168396563,0.07488991983456728,0.012089915339174813 +26200,0.4967791938836907,0.0032090395745093155,0.4136953061633807,0.07421000404663687,0.012106456331782424 +26300,0.5013375254417362,0.003071183723581195,0.4098453014258729,0.07437963568018743,0.011366353728622328 +26400,0.5020974566982717,0.004384168111285972,0.40774669367025057,0.07538033902354604,0.01039134249664566 +26500,0.49960899714016527,0.0063583787595273295,0.4041740782314293,0.08032433322189636,0.00953421264698191 +26600,0.49686458348494156,0.008269567304640532,0.3975788568737938,0.08901742503198401,0.008269567304640181 +26700,0.4928365318579985,0.009846004085564072,0.39367858516160126,0.09725443409512388,0.006384444799712293 +26800,0.48747500664289206,0.011578157452110837,0.39256459798642773,0.10395896155580454,0.004423276362764687 +26900,0.4834007422248019,0.013139469962275342,0.39266560606065687,0.10792090861600813,0.0028732731362576393 +27000,0.48407554133299224,0.014070101502755429,0.39053714985592974,0.1099082970620983,0.0014089102462242521 +27100,0.48654607843642134,0.014122168992316735,0.3872612525025102,0.11177922787737984,0.0002912721913718988 +27200,0.4905762986614257,0.013528898298745684,0.3835451153836923,0.11234968765613614,0.0 +27300,0.4984953521662186,0.013791622013005763,0.37847502002558253,0.10923800579519302,0.0 +27400,0.5089467922889178,0.01658631168041578,0.37301284841924776,0.10145404761141844,0.0 +27500,0.5158703347160895,0.021859211399435936,0.3729749087785873,0.08929554510588739,0.0 +27600,0.5174345326831371,0.027735182067464833,0.3798964310884988,0.07493385416089918,0.0 +27700,0.5146615220449425,0.032430250232968555,0.38999249050927554,0.06291573721281346,0.0 +27800,0.5084072214615385,0.034526829449010144,0.4005966001108651,0.05646934897858625,0.0 +27900,0.4993792257376335,0.035369599090715895,0.4103442288046927,0.05490694636695788,0.0 +28000,0.4938930436802014,0.03587908059151177,0.4147284268946161,0.05549944883367072,0.0 +28100,0.49464245824154235,0.03456594206602891,0.4154814030969438,0.05531019659548498,0.0 +28200,0.5000885569959538,0.030255552773458236,0.4139605901258766,0.05569530010471126,0.0 +28300,0.508379706466494,0.023529079170246145,0.4109854898982044,0.05710572446505556,0.0 +28400,0.5233670056598699,0.01622321288261602,0.4004475127001733,0.0599622687573406,0.0 +28500,0.5415726575196643,0.010398382390995853,0.38416610897816433,0.06386285111117565,0.0 +28600,0.55688077321784,0.006860667426251073,0.36852746617331844,0.06773109318259067,0.0 +28700,0.5647665244047986,0.0052126390629984,0.3603799461996729,0.06964089033253007,0.0 +28800,0.567739962595055,0.003645132545491197,0.3593266707328587,0.06928823412659503,0.0 +28900,0.5668082797742972,0.001788159879239637,0.36319936083069615,0.06820419951576714,0.0 +29000,0.5599182873353039,0.0003668955119694547,0.37100035436052825,0.0687144627921983,0.0 +29100,0.5492079709954166,0.0,0.38185387719312813,0.06893815181145525,0.0 +29200,0.5367564900298941,0.0,0.39640774923272315,0.0668357607373827,0.0 +29300,0.5226709898915272,0.0,0.41003116124743305,0.06729784886103982,0.0 +29400,0.5074946096335676,0.0,0.423084416065869,0.06942097430056333,0.0 +29500,0.4929595511904631,0.0,0.4353468944442865,0.07169355436525046,0.0 +29600,0.4797674757805357,0.0,0.446112691496679,0.07411983272278536,0.0 +29700,0.4683000690972654,0.0,0.45483607519171604,0.07686385571101863,0.0 +29800,0.4583692388607079,0.0,0.46146753125899365,0.08016322988029849,0.0 diff --git a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java index c0d97be1587..a02b58c7b35 100644 --- a/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java +++ b/matsim/src/main/java/ch/sbb/matsim/routing/pt/raptor/SwissRailRaptorData.java @@ -651,7 +651,6 @@ public Transfer get() { } RTransfer[] calculateTransfers(RRouteStop fromRouteStop) { - // We tested this in a parallel set-up and things seem to work as they are // implemented. The routing threads will access the cache as read-only an // retrieve the cached stop connections. It can happen that two of them try to diff --git a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java index fc5c43da358..293ac9ed415 100755 --- a/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java +++ b/matsim/src/main/java/org/matsim/core/controler/ControlerDefaultsModule.java @@ -85,8 +85,7 @@ public void install() { // Maybe not the best place to but this but since ChartUtils is used by many modules, including default ones, // the cache needs to be always set correctly. addControlerListenerBinding().toInstance(new StartupListener() { - @Inject - private OutputDirectoryHierarchy outputDirectoryHierarchy; + @Inject private OutputDirectoryHierarchy outputDirectoryHierarchy; @Override public void notifyStartup(StartupEvent event) { ImageIO.setCacheDirectory(new File(outputDirectoryHierarchy.getTempPath())); } diff --git a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/AbstractAgentSnapshotInfoBuilder.java b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/AbstractAgentSnapshotInfoBuilder.java index 78d2b0afe5d..c6bf2e47d49 100644 --- a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/AbstractAgentSnapshotInfoBuilder.java +++ b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/AbstractAgentSnapshotInfoBuilder.java @@ -139,12 +139,13 @@ public final void positionAgentGivenDistanceFromFNode(final Collection positionVehiclesAlongLine(Collection positions, - double now, Collection vehs, double curvedLength, double storageCapacity, - Coord upstreamCoord, Coord downstreamCoord, double inverseFlowCapPerTS, double freeSpeed, - int numberOfLanesAsInt, Queue holes) + public final Collection positionVehiclesAlongLine( Collection positions, + double now, Collection vehs, double curvedLength, double storageCapacity, + Coord upstreamCoord, Coord downstreamCoord, double inverseFlowCapPerTS, double freeSpeed, + int numberOfLanesAsInt, Queue holes, AbstractQLink.QLinkInternalInterface qLinkInternalInterface ) { double spacingOfOnePCE = this.calculateVehicleSpacing( curvedLength, storageCapacity, vehs ); + // ("vehs" is needed since the link may be more than full because of squeezing. In this case, spacingOfOnePCE is smaller than one "cell".) double ttimeOfHoles = curvedLength / (QueueWithBuffer.HOLE_SPEED_KM_H*1000./3600.); @@ -211,8 +212,16 @@ public final Collection positionVehiclesAlongLine(Collection< // (starts off relatively small (rightmost vehicle)) final double vehicleSpacing = mveh.getSizeInEquivalents() * spacingOfOnePCE; + + double speed = min( freeSpeed, veh.getMaximumVelocity() ); + if ( qLinkInternalInterface!=null ){ + speed = qLinkInternalInterface.getMaximumVelocityFromLinkSpeedCalculator( veh, now ); + } + distanceFromFromNode = this.calculateOdometerDistanceFromFromNode( - now, curvedLength, min( freeSpeed, veh.getMaximumVelocity()), vehicleSpacing, distanceFromFromNode, remainingTravelTime + now, curvedLength, + speed, // min( freeSpeed, veh.getMaximumVelocity()), + vehicleSpacing, distanceFromFromNode, remainingTravelTime ); // yyyy if the LinkSpeedCalculator says something that is not free speed, we are out of luck here. kai, jan'23 diff --git a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java index 868e9813c65..741763e4c87 100644 --- a/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java +++ b/matsim/src/main/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueWithBuffer.java @@ -162,7 +162,7 @@ private void addValue(double value1, double now) { * pointer, and give access only to reduced number of methods (in particular not the full Link information). kai, feb'18 * This is now done with the {@link AbstractQLink.QLinkInternalInterface}. kai, feb'18 */ - private final AbstractQLink.QLinkInternalInterface qLink; + private final AbstractQLink.QLinkInternalInterface qLinkInternalInterface; private final Id id; private static int spaceCapWarningCount = 0; final static double HOLE_SPEED_KM_H = 15.0; @@ -202,7 +202,7 @@ private QueueWithBuffer(AbstractQLink.QLinkInternalInterface qlink, final Vehicl // log.setLevel(Level.DEBUG); this.flowEfficiencyCalculator = flowEfficiencyCalculator; - this.qLink = qlink; + this.qLinkInternalInterface = qlink; this.id = laneId ; this.context = context ; this.vehQueue = vehicleQueue ; @@ -239,7 +239,7 @@ private void addToBuffer(final QVehicle veh) { // need to reset the lastMovedTime. If, in contrast, there was already a vehicle in the buffer before, we can // use the lastMovedTime that was (somehow) computed for that vehicle.) } - final QNodeI toNode = qLink.getToNodeQ(); + final QNodeI toNode = qLinkInternalInterface.getToNodeQ(); if ( toNode instanceof AbstractQNode ) { ((AbstractQNode) toNode).activateNode(); // yy for an "upstream" QLane, this activates the toNode too early. Yet I think I founds this @@ -266,9 +266,9 @@ private void moveQueueToBuffer() { MobsimDriverAgent driver = veh.getDriver(); if (driver instanceof TransitDriverAgent) { - HandleTransitStopResult handleTransitStop = qLink.handleTransitStop( - now, veh, (TransitDriverAgent) driver, this.qLink.getId() - ); + HandleTransitStopResult handleTransitStop = qLinkInternalInterface.handleTransitStop( + now, veh, (TransitDriverAgent) driver, this.qLinkInternalInterface.getId() + ); if (handleTransitStop == HandleTransitStopResult.accepted) { // vehicle has been accepted into the transit vehicle queue of the link. removeVehicleFromQueue(veh); @@ -285,7 +285,7 @@ private void moveQueueToBuffer() { // Check if veh has reached destination: if (driver.isWantingToArriveOnCurrentLink()) { - if (qLink.letVehicleArrive(veh)) { + if ( qLinkInternalInterface.letVehicleArrive(veh )) { // remove _after_ processing the arrival to keep link active: removeVehicleFromQueue(veh); continue; @@ -395,8 +395,8 @@ private void calculateFlowCapacity() { // yyyyyy this should possibly be getFreespeed(now). But if that's the case, then maxFlowFromFdiag would // also have to be re-computed with each freespeed change. kai, feb'18 - final double maxFlowFromFdiag = (this.effectiveNumberOfLanes/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLink.getFreespeed() ) ; - final double minimumNumberOfLanesFromFdiag = this.flowCapacityPerTimeStep * context.effectiveCellSize * ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLink.getFreespeed() ); + final double maxFlowFromFdiag = (this.effectiveNumberOfLanes/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ) ; + final double minimumNumberOfLanesFromFdiag = this.flowCapacityPerTimeStep * context.effectiveCellSize * ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ); QSimConfigGroup.InflowCapacitySetting inflowCapacitySetting = context.qsimConfig.getInflowCapacitySetting(); @@ -411,19 +411,19 @@ private void calculateFlowCapacity() { log.warn( Gbl.FUTURE_SUPPRESSED ) ; } - this.maxInflowUsedInQsim = (1/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLink.getFreespeed() ) ; + this.maxInflowUsedInQsim = (1/context.effectiveCellSize) / ( 1./(HOLE_SPEED_KM_H/3.6) + 1/this.qLinkInternalInterface.getFreespeed() ) ; // write out the modified qsim behavior as link attribute - qLink.getLink().getAttributes().putAttribute("maxInflowUsedInQsim", 3600* maxInflowUsedInQsim /context.qsimConfig.getTimeStepSize()); + qLinkInternalInterface.getLink().getAttributes().putAttribute("maxInflowUsedInQsim", 3600* maxInflowUsedInQsim /context.qsimConfig.getTimeStepSize() ); } else { if ( maxFlowFromFdiag < flowCapacityPerTimeStep ){ //warnings if (wrnCnt<10) { wrnCnt++ ; - log.warn( "max flow from fdiag < flow cap in network file; linkId=" + qLink.getId() + + log.warn( "max flow from fdiag < flow cap in network file; linkId=" + qLinkInternalInterface.getId() + "; network file flow cap/h=" + 3600.*flowCapacityPerTimeStep/context.qsimConfig.getTimeStepSize() + "; max flow from fdiag/h=" + 3600*maxFlowFromFdiag/context.qsimConfig.getTimeStepSize() ) ; - log.warn( "number of lanes from fdiag > number of lanes in network file; linkId=" + qLink.getId() + + log.warn( "number of lanes from fdiag > number of lanes in network file; linkId=" + qLinkInternalInterface.getId() + "; number of lanes in network file=" + this.effectiveNumberOfLanes + "; number of lanes from fdiag=" + minimumNumberOfLanesFromFdiag ) ; @@ -445,11 +445,11 @@ private void calculateFlowCapacity() { if (inflowCapacitySetting == QSimConfigGroup.InflowCapacitySetting.INFLOW_FROM_FDIAG) { this.maxInflowUsedInQsim = maxFlowFromFdiag; // write out the modified qsim behavior as link attribute - qLink.getLink().getAttributes().putAttribute("maxInflowUsedInQsim", 3600* maxInflowUsedInQsim /context.qsimConfig.getTimeStepSize()); + qLinkInternalInterface.getLink().getAttributes().putAttribute("maxInflowUsedInQsim", 3600* maxInflowUsedInQsim /context.qsimConfig.getTimeStepSize() ); } else if (inflowCapacitySetting == QSimConfigGroup.InflowCapacitySetting.NR_OF_LANES_FROM_FDIAG) { this.effectiveNumberOfLanesUsedInQsim = minimumNumberOfLanesFromFdiag; // write out the modified qsim behavior as link attribute - qLink.getLink().getAttributes().putAttribute("effectiveNumberOfLanesUsedInQsim", effectiveNumberOfLanesUsedInQsim); + qLinkInternalInterface.getLink().getAttributes().putAttribute("effectiveNumberOfLanesUsedInQsim", effectiveNumberOfLanesUsedInQsim ); } else { throw new RuntimeException("The approach "+ inflowCapacitySetting.toString()+" is not implemented yet."); } @@ -483,7 +483,7 @@ private void calculateStorageCapacity() { * Will base these computations (for the time being) on the standard free speed; i.e. reductions in free speed * will also reduce the maximum flow. */ - double freespeedTravelTime = this.length / qLink.getFreespeed(); + double freespeedTravelTime = this.length / qLinkInternalInterface.getFreespeed(); // yyyyyy this should possibly be getFreespeed(now). But if that's the case, then storageCap would // also have to be re-computed with each freespeed change. kai, feb'18 if (Double.isNaN(freespeedTravelTime)) { @@ -507,7 +507,7 @@ private void calculateStorageCapacity() { storageCapacity = tempStorageCapacity; // write out the modified qsim behavior as link attribute - qLink.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity); + qLinkInternalInterface.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity ); } /* About minStorCapForHoles: @@ -527,7 +527,7 @@ private void calculateStorageCapacity() { case withHoles: case kinematicWaves: // final double minStorCapForHoles = 2. * flowCapacityPerTimeStep * context.getSimTimer().getSimTimestepSize(); - final double freeSpeed = qLink.getFreespeed() ; // yyyyyy not clear why this is not time-dep. kai, feb'18 + final double freeSpeed = qLinkInternalInterface.getFreespeed() ; // yyyyyy not clear why this is not time-dep. kai, feb'18 final double holeSpeed = HOLE_SPEED_KM_H/3.6; final double minStorCapForHoles = length * flowCapacityPerTimeStep * (freeSpeed + holeSpeed) / freeSpeed / holeSpeed ; // final double minStorCapForHoles = 2.* length * flowCapacityPerTimeStep * (freeSpeed + holeSpeed) / freeSpeed / holeSpeed ; @@ -541,7 +541,7 @@ private void calculateStorageCapacity() { } storageCapacity = minStorCapForHoles ; // write out the modified qsim behavior as link attribute - qLink.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity); + qLinkInternalInterface.getLink().getAttributes().putAttribute("storageCapacityUsedInQsim", storageCapacity ); } remainingHolesStorageCapacity = this.storageCapacity; @@ -589,12 +589,12 @@ public final void addFromUpstream(final QVehicle veh) { if (this.context.qsimConfig.isUseLanes()) { if (hasMoreThanOneLane()) { - this.context.getEventsManager().processEvent(new LaneEnterEvent(now, veh.getId(), this.qLink.getId(), this.getId())); + this.context.getEventsManager().processEvent(new LaneEnterEvent(now, veh.getId(), this.qLinkInternalInterface.getId(), this.getId()) ); } } // activate link since there is now action on it: - qLink.activateLink(); + qLinkInternalInterface.activateLink(); if (context.qsimConfig.isSeepModeStorageFree() && context.qsimConfig.getSeepModes().contains(veh.getVehicle().getType().getId().toString())) { // do nothing @@ -604,7 +604,7 @@ public final void addFromUpstream(final QVehicle veh) { // compute and set earliest link exit time: // double linkTravelTime = this.length / this.linkSpeedCalculator.getMaximumVelocity(veh, qLink.getLink(), now); - double linkTravelTime = this.length / this.qLink.getMaximumVelocityFromLinkSpeedCalculator(veh, now); + double linkTravelTime = this.length / this.qLinkInternalInterface.getMaximumVelocityFromLinkSpeedCalculator(veh, now ); linkTravelTime = context.qsimConfig.getTimeStepSize() * Math.floor(linkTravelTime / context.qsimConfig.getTimeStepSize()); veh.setEarliestLinkExitTime(now + linkTravelTime); @@ -619,7 +619,7 @@ public final void addFromUpstream(final QVehicle veh) { // inserted and thus end up after vehicles with a later link exit time. theresa & kai, jun'14 // veh.setCurrentLink(qLink.getLink()); - this.qLink.setCurrentLinkToVehicle(veh); + this.qLinkInternalInterface.setCurrentLinkToVehicle(veh ); vehQueue.add(veh); switch (context.qsimConfig.getTrafficDynamics()) { @@ -795,7 +795,7 @@ public final QVehicle popFirstVehicle() { QVehicle veh = removeFirstVehicle(); if (this.context.qsimConfig.isUseLanes() ) { if ( hasMoreThanOneLane() ) { - this.context.getEventsManager().processEvent(new LaneLeaveEvent( now, veh.getId(), this.qLink.getId(), this.getId() )); + this.context.getEventsManager().processEvent(new LaneLeaveEvent( now, veh.getId(), this.qLinkInternalInterface.getId(), this.getId() ) ); } } return veh; @@ -813,7 +813,7 @@ private final QVehicle removeFirstVehicle(){ @Override public final void setSignalStateForTurningMove( final SignalGroupState state, final Id toLinkId) { - if (!qLink.getToNode().getOutLinks().containsKey(toLinkId)){ + if (!qLinkInternalInterface.getToNode().getOutLinks().containsKey(toLinkId )){ throw new IllegalArgumentException("ToLink " + toLinkId + " is not reachable from QLink Id " + this.id ); } qSignalizedItem.setSignalStateForTurningMove(state, toLinkId); @@ -879,12 +879,12 @@ public final void clearVehicles() { } private double getFlowCapacityConsumptionInEquivalents(QVehicle vehicle, QVehicle prevVehicle, Double timeDiff) { - double flowEfficiency = flowEfficiencyCalculator.calculateFlowEfficiency(vehicle, prevVehicle, timeDiff, qLink.getLink(), id); + double flowEfficiency = flowEfficiencyCalculator.calculateFlowEfficiency(vehicle, prevVehicle, timeDiff, qLinkInternalInterface.getLink(), id ); return vehicle.getSizeInEquivalents() / flowEfficiency; } private boolean hasMoreThanOneLane() { - return this.qLink.getAcceptingQLane() != this.qLink.getOfferingQLanes().get(0); + return this.qLinkInternalInterface.getAcceptingQLane() != this.qLinkInternalInterface.getOfferingQLanes().get(0 ); // this works independent from sorting since if there is only one lane, then it has to be the one to be returned by // getOfferingQLanes().get(0), and it is also the same as the accepting QLane. If, however, "lanes" is used, // there are at least two lanes in sequence, so the accepting lane is never the same as any of the offering lanes, and @@ -919,7 +919,7 @@ public final void addTransitSlightlyUpstreamOfStop( final QVehicle veh) { @Override public final void setSignalized( final boolean isSignalized) { - qSignalizedItem = new DefaultSignalizeableItem(qLink.getToNode().getOutLinks().keySet()); + qSignalizedItem = new DefaultSignalizeableItem( qLinkInternalInterface.getToNode().getOutLinks().keySet()); } @Override @@ -989,10 +989,10 @@ public final Collection addAgentSnapshotInfo(Collection addAgentSnapshotInfo(Collection() - ); + new LinkedList<>(), + null ); // assert assertEquals(1, outCollection.size()); @@ -85,8 +85,8 @@ void positionVehiclesAlongLine_congestedAboveCapacityLimit() { 1 / setUp.linkCapacity, // this would mean the flow capacity is 100 setUp.freespeed, 1, - new LinkedList<>() - ); + new LinkedList<>(), + null ); // assert assertEquals(vehicles.size(), outCollection.size()); @@ -337,4 +337,4 @@ private static Collection createAgents(int size) { return result; } -} \ No newline at end of file +} diff --git a/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueAgentSnapshotInfoBuilderTest.java b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueAgentSnapshotInfoBuilderTest.java index b81a8fb91a0..b815ced0819 100644 --- a/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueAgentSnapshotInfoBuilderTest.java +++ b/matsim/src/test/java/org/matsim/core/mobsim/qsim/qnetsimengine/QueueAgentSnapshotInfoBuilderTest.java @@ -53,8 +53,8 @@ void positionVehiclesAlongLine_singleVehicleFreeFlow() { 1 / setUp.linkCapacity, // this would mean the flow capacity is 100 setUp.freespeed, 1, - new LinkedList<>() - ); + new LinkedList<>(), + null ); // assert assertEquals(1, outCollection.size()); @@ -94,8 +94,8 @@ void positionVehiclesAlongLine_congestedAboveCapacityLimit() { 1 / setUp.linkCapacity, // this would mean the flow capacity is 100 setUp.freespeed, 1, - new LinkedList<>() - ); + new LinkedList<>(), + null ); // assert assertEquals(vehicles.size(), outCollection.size()); @@ -132,8 +132,8 @@ void positionVehiclesAlongLine_queueAtEnd() { 1 / setUp.linkCapacity, setUp.freespeed, 1, - new LinkedList<>() - ); + new LinkedList<>(), + null ); // assert assertEquals(5, outCollection.size()); @@ -473,4 +473,4 @@ private static Collection createAgents(int size) { } return result; } -} \ No newline at end of file +}