package org.opentrafficsim.imb.demo; import static org.opentrafficsim.road.gtu.lane.RoadGTUTypes.BUS; import static org.opentrafficsim.road.gtu.lane.RoadGTUTypes.CAR; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.djunits.unit.DurationUnit; import org.djunits.unit.FrequencyUnit; import org.djunits.unit.LengthUnit; import org.djunits.unit.SpeedUnit; import org.djunits.unit.TimeUnit; import org.djunits.value.StorageType; import org.djunits.value.ValueException; import org.djunits.value.vdouble.scalar.Duration; import org.djunits.value.vdouble.scalar.Frequency; import org.djunits.value.vdouble.scalar.Length; import org.djunits.value.vdouble.scalar.Speed; import org.djunits.value.vdouble.scalar.Time; import org.djunits.value.vdouble.vector.DurationVector; import org.opentrafficsim.core.distributions.Distribution; import org.opentrafficsim.core.distributions.ProbabilityException; import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface; import org.opentrafficsim.core.gtu.GTUDirectionality; import org.opentrafficsim.core.gtu.GTUType; import org.opentrafficsim.core.network.Network; import org.opentrafficsim.core.network.NetworkException; import org.opentrafficsim.core.network.Node; import org.opentrafficsim.core.network.OTSNetwork; import org.opentrafficsim.core.network.route.ProbabilisticRouteGenerator; import org.opentrafficsim.core.network.route.Route; import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar; import org.opentrafficsim.kpi.interfaces.GtuTypeDataInterface; import org.opentrafficsim.kpi.sampling.KpiGtuDirectionality; import org.opentrafficsim.kpi.sampling.Query; import org.opentrafficsim.kpi.sampling.Sampler; import org.opentrafficsim.kpi.sampling.meta.MetaDataGtuType; import org.opentrafficsim.kpi.sampling.meta.MetaDataSet; import org.opentrafficsim.road.gtu.animation.DefaultSwitchableGTUColorer; import org.opentrafficsim.road.gtu.generator.GTUGeneratorIndividual; import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU; import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlannerFactory; import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner; import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory; import org.opentrafficsim.road.gtu.strategical.od.Categorization; import org.opentrafficsim.road.gtu.strategical.od.Category; import org.opentrafficsim.road.gtu.strategical.od.Interpolation; import org.opentrafficsim.road.gtu.strategical.od.ODMatrixTrips; import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory; import org.opentrafficsim.road.network.lane.CrossSectionLink; import org.opentrafficsim.road.network.lane.Lane; import org.opentrafficsim.road.network.sampling.GtuTypeData; import org.opentrafficsim.road.network.sampling.LinkData; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.jstats.streams.MersenneTwister; /** *

* Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 okt. 2016
* @author Alexander Verbraeck * @author Peter Knoppers * @author Wouter Schakel */ public class N201ODfactory { /** * Creates origin-destination matrix * @param network network * @return origin-destination matrix */ public static ODMatrixTrips get(final Network network) { List origins = new ArrayList<>(); origins.add(network.getNode("N1a")); // A, maar dan een stuk verder, tussenliggende kruispunten genegeerd origins.add(network.getNode("N234b_in2")); // B origins.add(network.getNode("N239a_in2")); // C origins.add(network.getNode("N245a_in2")); // D origins.add(network.getNode("N245b_in2")); // E origins.add(network.getNode("N249a_in2")); // F // tegenoverliggende weg heeft geen data dus niet meegenomen // G & H: Hoofdweg langs kanaal zit er niet in, op- en afritten zitten niet in het netwerk origins.add(network.getNode("N291a_in2")); // I // tegenoverliggende weg heeft geen data dus niet meegenomen origins.add(network.getNode("N50b")); // J List destinations = new ArrayList<>(); destinations.add(network.getNode("N1b")); // A destinations.add(network.getNode("N234b_uit2")); // B destinations.add(network.getNode("N239a_uit2")); // C destinations.add(network.getNode("N245a_uit2")); // D destinations.add(network.getNode("N249a_uit2")); // F destinations.add(network.getNode("N291a_uit2")); // I destinations.add(network.getNode("N50a")); // J ODMatrixTrips matrix; try { matrix = new ODMatrixTrips("N201demo", origins, destinations, Categorization.UNCATEGORIZED, new DurationVector(new double[] { 0, 3600 }, DurationUnit.SI, StorageType.DENSE), Interpolation.STEPWISE); } catch (ValueException exception) { throw new RuntimeException(exception); } // loop matrix // 2*0 because the through movement on the IJweg is not incorporated int[][] od = new int[][] { { 0, 502, 309, 35, 285, 33, 218 }, { 331, 0, 229, 26, 212, 25, 162 }, { 150, 89, 0, 12, 98, 11, 75 }, { 29, 17, 14, 0, 30, 4, 23 }, { 30, 18, 14, 2 * 0, 32, 4, 25 }, { 296, 175, 143, 18, 0, 21, 136 }, { 67, 40, 32, 4, 63, 0, 787 }, { 373, 221, 180, 22, 350, 815, 0 } }; for (int o = 0; o < origins.size(); o++) { for (int d = 0; d < destinations.size(); d++) { if (od[o][d] > 0) { matrix.putTripsVector(origins.get(o), destinations.get(d), Category.UNCATEGORIZED, new int[] { od[o][d] }); } } } return matrix; } /** * Makes generators at origin nodes of the OD. * @param network network * @param matrix origin-destination matrix * @param simulator simulator */ public static void makeGeneratorsFromOD(final OTSNetwork network, final ODMatrixTrips matrix, final OTSDEVSSimulatorInterface simulator) { // fixed generator input Class gtuClass = LaneBasedIndividualGTU.class; Time startTime = Time.ZERO; Time endTime = new Time(Double.MAX_VALUE, TimeUnit.BASE_SECOND); Length position = new Length(1.0, LengthUnit.SI); GTUType gtuType = CAR; ContinuousDistDoubleScalar.Rel initSpeedDist = new ContinuousDistDoubleScalar.Rel<>(30, SpeedUnit.KM_PER_HOUR); ContinuousDistDoubleScalar.Rel lengthDist = new ContinuousDistDoubleScalar.Rel<>(4, LengthUnit.METER); ContinuousDistDoubleScalar.Rel widthDist = new ContinuousDistDoubleScalar.Rel<>(2, LengthUnit.METER); ContinuousDistDoubleScalar.Rel maxSpeedDist = new ContinuousDistDoubleScalar.Rel<>(200, SpeedUnit.KM_PER_HOUR); DefaultSwitchableGTUColorer colorer = new DefaultSwitchableGTUColorer(); MersenneTwister rand = new MersenneTwister(); // loop origins for (Node origin : matrix.getOrigins()) { // route generator double dem = matrix.originTotal(origin); List> routeList = new ArrayList<>(); for (Node destination : matrix.getDestinations()) { if (matrix.contains(origin, destination, Category.UNCATEGORIZED)) { Route route = new Route(origin + "->" + destination); try { route = network.getShortestRouteBetween(GTUType.ALL, origin, destination); } catch (NetworkException exception) { throw new RuntimeException("Problem finding route from " + origin + " to " + destination, exception); } double prob = matrix.originDestinationTotal(origin, destination) / dem; routeList.add(new Distribution.FrequencyAndObject<>(prob, route)); } } ProbabilisticRouteGenerator routeGenerator; try { routeGenerator = new ProbabilisticRouteGenerator(routeList, rand); } catch (ProbabilityException exception) { throw new RuntimeException(exception); } // strategical planner factory using route generator (i.e. a strategical planner factory required per origin) LaneBasedStrategicalPlannerFactory strategicalPlannerFactory = new LaneBasedStrategicalRoutePlannerFactory( new LaneBasedGTUFollowingTacticalPlannerFactory(new IDMPlusOld())); // time CrossSectionLink link = (CrossSectionLink) origin.getLinks().iterator().next(); // should be only 1 for origins int lanes = link.getLanes().size(); double iat = 3600 / (dem / lanes); ContinuousDistDoubleScalar.Rel iatDist = new ContinuousDistDoubleScalar.Rel<>(iat, DurationUnit.SECOND); GTUDirectionality dir = link.getStartNode().equals(origin) ? GTUDirectionality.DIR_PLUS : GTUDirectionality.DIR_MINUS; // put generator on each lane for (Lane lane : link.getLanes()) { try { new GTUGeneratorIndividual(origin + "." + link.getLanes().indexOf(lane), simulator, gtuType, gtuClass, initSpeedDist, iatDist, lengthDist, widthDist, maxSpeedDist, Integer.MAX_VALUE, startTime, endTime, lane, position, dir, colorer, strategicalPlannerFactory, routeGenerator, network); } catch (SimRuntimeException exception) { throw new RuntimeException(exception); } } } } /** * @param network network * @param sampler sampling * @return query covering the entire N201 */ public static Query getQuery(final OTSNetwork network, final Sampler sampler) { // String[] southBound = new String[] { "L1a", "L2a", "L3a4a", "L5a", "L6a", "L7a", "L8a9a", "L10a11a", "L12a", // "L13a14a", // "L15a16a", "L17a", "L18a19a", "L20a21a", "L22a", "L23a24a", "L25a", "L26a", "L27a", "L28a29a", "L30a", "L31a", // "L32a", "L33a", "L34a", "L35a", "L36a", "L37a", "L38a", "L39a", "L40a", "L41a", "L42a", "L43a", "L44a", "L45a", // "L46a", "L47a48a", "L49a" }; String[] southBound = new String[] { "L2a" }; String[] northBound = new String[] { "L49b", "L48b47b", "L46b", "L45b", "L44b", "L43b", "L42b", "L41b", "L40b", "L39b", "L38b", "L37b", "L36b", "L35b", "L34b", "L33b", "L32b", "L31b", "L30b", "L29b28b", "L27b", "L26b", "L25b", "L24b23b", "L22b21b", "L20b", "L19b18b", "L17b16b", "L15b", "L14b13b", "L12b", "L11b", "L10b", "L9b8b", "L7b", "L6b", "L5b", "L4b3b", "L2b", "L1b" }; MetaDataSet metaDataSet = new MetaDataSet(); Set gtuTypes = new HashSet<>(); gtuTypes.add(new GtuTypeData(CAR)); gtuTypes.add(new GtuTypeData(BUS)); metaDataSet.put(new MetaDataGtuType(), gtuTypes); Query query = new Query(sampler, "N201 both directions", metaDataSet, new Frequency(2.0, FrequencyUnit.PER_MINUTE)); // addSpaceTimeRegions(query, network, northBound); addSpaceTimeRegions(query, network, southBound); return query; } /** * @param query query * @param network network * @param links link names */ private static void addSpaceTimeRegions(final Query query, final OTSNetwork network, final String[] links) { for (String link : links) { query.addSpaceTimeRegionLink(new LinkData((CrossSectionLink) network.getLink(link)), KpiGtuDirectionality.DIR_PLUS, Length.ZERO, network.getLink(link).getLength(), new Time(0, TimeUnit.BASE_HOUR), new Time(1.0, TimeUnit.BASE_HOUR)); } } }