View Javadoc
1   package org.opentrafficsim.demo.network.xml;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.djunits.unit.DurationUnit;
7   import org.djunits.unit.FrequencyUnit;
8   import org.djunits.unit.LengthUnit;
9   import org.djunits.unit.SpeedUnit;
10  import org.djunits.unit.TimeUnit;
11  import org.djunits.value.ValueRuntimeException;
12  import org.djunits.value.storage.StorageType;
13  import org.djunits.value.vdouble.scalar.Duration;
14  import org.djunits.value.vdouble.scalar.Frequency;
15  import org.djunits.value.vdouble.scalar.Length;
16  import org.djunits.value.vdouble.scalar.Speed;
17  import org.djunits.value.vdouble.scalar.Time;
18  import org.djunits.value.vdouble.vector.base.DoubleVector;
19  import org.opentrafficsim.core.animation.gtu.colorer.DefaultSwitchableGTUColorer;
20  import org.opentrafficsim.core.distributions.Distribution;
21  import org.opentrafficsim.core.distributions.ProbabilityException;
22  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
23  import org.opentrafficsim.core.gtu.GTUDirectionality;
24  import org.opentrafficsim.core.gtu.GTUType;
25  import org.opentrafficsim.core.network.Network;
26  import org.opentrafficsim.core.network.NetworkException;
27  import org.opentrafficsim.core.network.Node;
28  import org.opentrafficsim.core.network.route.ProbabilisticRouteGenerator;
29  import org.opentrafficsim.core.network.route.Route;
30  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
31  import org.opentrafficsim.kpi.sampling.KpiGtuDirectionality;
32  import org.opentrafficsim.kpi.sampling.Query;
33  import org.opentrafficsim.kpi.sampling.Sampler;
34  import org.opentrafficsim.kpi.sampling.meta.FilterDataSet;
35  import org.opentrafficsim.road.gtu.generator.GTUGeneratorIndividualOld;
36  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
37  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlannerFactory;
38  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
39  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
40  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
41  import org.opentrafficsim.road.gtu.strategical.od.Categorization;
42  import org.opentrafficsim.road.gtu.strategical.od.Category;
43  import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
44  import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
45  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
46  import org.opentrafficsim.road.network.OTSRoadNetwork;
47  import org.opentrafficsim.road.network.lane.CrossSectionLink;
48  import org.opentrafficsim.road.network.lane.Lane;
49  import org.opentrafficsim.road.network.sampling.LinkData;
50  
51  import nl.tudelft.simulation.dsol.SimRuntimeException;
52  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
53  
54  /**
55   * <p>
56   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
57   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
58   * <p>
59   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 okt. 2016 <br>
60   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
61   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
62   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
63   */
64  
65  public class N201ODfactory
66  {
67  
68      /**
69       * Creates origin-destination matrix.
70       * @param network network
71       * @return origin-destination matrix
72       */
73      public static ODMatrix get(final Network network)
74      {
75          List<Node> origins = new ArrayList<>();
76          origins.add(network.getNode("N1a")); // A, maar dan een stuk verder, tussenliggende kruispunten genegeerd
77          origins.add(network.getNode("N234b_in2")); // B
78          origins.add(network.getNode("N239a_in2")); // C
79          origins.add(network.getNode("N245a_in2")); // D
80          origins.add(network.getNode("N245b_in2")); // E
81          origins.add(network.getNode("N249a_in2")); // F // tegenoverliggende weg heeft geen data dus niet meegenomen
82          // G & H: Hoofdweg langs kanaal zit er niet in, op- en afritten zitten niet in het netwerk
83          origins.add(network.getNode("N291a_in2")); // I // tegenoverliggende weg heeft geen data dus niet meegenomen
84          origins.add(network.getNode("N50b")); // J
85  
86          List<Node> destinations = new ArrayList<>();
87          destinations.add(network.getNode("N1b")); // A
88          destinations.add(network.getNode("N234b_uit2")); // B
89          destinations.add(network.getNode("N239a_uit2")); // C
90          destinations.add(network.getNode("N245a_uit2")); // D
91          destinations.add(network.getNode("N249a_uit2")); // F
92          destinations.add(network.getNode("N291a_uit2")); // I
93          destinations.add(network.getNode("N50a")); // J
94  
95          ODMatrix matrix;
96          try
97          {
98              matrix = new ODMatrix("N201demo", origins, destinations, Categorization.UNCATEGORIZED, DoubleVector.instantiate(
99                  new double[] {0, 3600}, TimeUnit.DEFAULT, StorageType.DENSE), Interpolation.STEPWISE);
100         }
101         catch (ValueRuntimeException exception)
102         {
103             throw new RuntimeException(exception);
104         }
105 
106         // loop matrix
107         // 2*0 because the through movement on the IJweg is not incorporated
108         int[][] od = new int[][] {{0, 502, 309, 35, 285, 33, 218}, {331, 0, 229, 26, 212, 25, 162}, {150, 89, 0, 12, 98, 11,
109             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,
110                 63, 0, 787}, {373, 221, 180, 22, 350, 815, 0}};
111         for (int o = 0; o < origins.size(); o++)
112         {
113             for (int d = 0; d < destinations.size(); d++)
114             {
115                 if (od[o][d] > 0)
116                 {
117                     matrix.putTripsVector(origins.get(o), destinations.get(d), Category.UNCATEGORIZED, new int[] {od[o][d]});
118                 }
119             }
120         }
121 
122         return matrix;
123     }
124 
125     /**
126      * Makes generators at origin nodes of the OD.
127      * @param network network
128      * @param matrix origin-destination matrix
129      * @param simulator simulator
130      */
131     public static void makeGeneratorsFromOD(final OTSRoadNetwork network, final ODMatrix matrix,
132             final OTSSimulatorInterface simulator)
133     {
134 
135         // fixed generator input
136         Class<?> gtuClass = LaneBasedIndividualGTU.class;
137         Time startTime = Time.ZERO;
138         Time endTime = new Time(Double.MAX_VALUE, TimeUnit.BASE_SECOND);
139         Length position = new Length(1.0, LengthUnit.SI);
140         GTUType gtuType = network.getGtuType(GTUType.DEFAULTS.CAR);
141         ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> initSpeedDist = new ContinuousDistDoubleScalar.Rel<>(30,
142             SpeedUnit.KM_PER_HOUR);
143         ContinuousDistDoubleScalar.Rel<Length, LengthUnit> lengthDist = new ContinuousDistDoubleScalar.Rel<>(4,
144             LengthUnit.METER);
145         ContinuousDistDoubleScalar.Rel<Length, LengthUnit> widthDist = new ContinuousDistDoubleScalar.Rel<>(2,
146             LengthUnit.METER);
147         ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> maxSpeedDist = new ContinuousDistDoubleScalar.Rel<>(200,
148             SpeedUnit.KM_PER_HOUR);
149         DefaultSwitchableGTUColorer colorer = new DefaultSwitchableGTUColorer();
150         MersenneTwister rand = new MersenneTwister();
151         // loop origins
152         for (Node origin : matrix.getOrigins())
153         {
154             // route generator
155             double dem = matrix.originTotal(origin);
156             List<Distribution.FrequencyAndObject<Route>> routeList = new ArrayList<>();
157             for (Node destination : matrix.getDestinations())
158             {
159                 if (matrix.contains(origin, destination, Category.UNCATEGORIZED))
160                 {
161                     Route route = new Route(origin + "->" + destination);
162                     try
163                     {
164                         route = network.getShortestRouteBetween(network.getGtuType(GTUType.DEFAULTS.VEHICLE), origin,
165                             destination);
166                     }
167                     catch (NetworkException exception)
168                     {
169                         throw new RuntimeException("Problem finding route from " + origin + " to " + destination, exception);
170                     }
171                     double prob = matrix.originDestinationTotal(origin, destination) / dem;
172                     routeList.add(new Distribution.FrequencyAndObject<>(prob, route));
173                 }
174             }
175             ProbabilisticRouteGenerator routeGenerator;
176             try
177             {
178                 routeGenerator = new ProbabilisticRouteGenerator(routeList, rand);
179             }
180             catch (ProbabilityException exception)
181             {
182                 throw new RuntimeException(exception);
183             }
184             // strategical planner factory using route generator (i.e. a strategical planner factory required per origin)
185             LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactory =
186                     new LaneBasedStrategicalRoutePlannerFactory(new LaneBasedGTUFollowingTacticalPlannerFactory(
187                         new IDMPlusOld()));
188             // time
189             CrossSectionLink link = (CrossSectionLink) origin.getLinks().iterator().next(); // should be only 1 for origins
190             int lanes = link.getLanes().size();
191             double iat = 3600 / (dem / lanes);
192             ContinuousDistDoubleScalar.Rel<Duration, DurationUnit> iatDist = new ContinuousDistDoubleScalar.Rel<>(iat,
193                 DurationUnit.SECOND);
194             GTUDirectionality dir = link.getStartNode().equals(origin) ? GTUDirectionality.DIR_PLUS
195                     : GTUDirectionality.DIR_MINUS;
196             // put generator on each lane
197             for (Lane lane : link.getLanes())
198             {
199                 try
200                 {
201                     new GTUGeneratorIndividualOld(origin + "." + link.getLanes().indexOf(lane), simulator, gtuType, gtuClass,
202                         initSpeedDist, iatDist, lengthDist, widthDist, maxSpeedDist, Integer.MAX_VALUE, startTime, endTime,
203                         lane, position, dir, strategicalPlannerFactory, routeGenerator, network);
204                 }
205                 catch (SimRuntimeException exception)
206                 {
207                     throw new RuntimeException(exception);
208                 }
209             }
210         }
211     }
212 
213     // /**
214 
215     /**
216      * @param network network
217      * @param sampling sampling
218      * @param metaDataSet meta data set
219      * @return query covering the entire N201
220      */
221     public static Query getQuery(final OTSRoadNetwork network, final Sampler sampling, final FilterDataSet metaDataSet)
222     {
223         // String[] southBound = new String[] { "L1a", "L2a", "L3a4a", "L5a", "L6a", "L7a", "L8a9a", "L10a11a", "L12a",
224         // "L13a14a",
225         // "L15a16a", "L17a", "L18a19a", "L20a21a", "L22a", "L23a24a", "L25a", "L26a", "L27a", "L28a29a", "L30a", "L31a",
226         // "L32a", "L33a", "L34a", "L35a", "L36a", "L37a", "L38a", "L39a", "L40a", "L41a", "L42a", "L43a", "L44a", "L45a",
227         // "L46a", "L47a48a", "L49a" };
228         String[] southBound = new String[] {"L2a"};
229         String[] northBound = new String[] {"L49b", "L48b47b", "L46b", "L45b", "L44b", "L43b", "L42b", "L41b", "L40b", "L39b",
230             "L38b", "L37b", "L36b", "L35b", "L34b", "L33b", "L32b", "L31b", "L30b", "L29b28b", "L27b", "L26b", "L25b",
231             "L24b23b", "L22b21b", "L20b", "L19b18b", "L17b16b", "L15b", "L14b13b", "L12b", "L11b", "L10b", "L9b8b", "L7b",
232             "L6b", "L5b", "L4b3b", "L2b", "L1b"};
233         Query query = new Query(sampling, "N201 both directions", metaDataSet, new Frequency(2.0, FrequencyUnit.PER_MINUTE));
234         // addSpaceTimeRegions(query, network, northBound);
235         addSpaceTimeRegions(query, network, southBound);
236         return query;
237     }
238 
239     /**
240      * @param query query
241      * @param network network
242      * @param links link names
243      */
244     private static void addSpaceTimeRegions(final Query query, final OTSRoadNetwork network, final String[] links)
245     {
246         for (String link : links)
247         {
248             query.addSpaceTimeRegionLink(new LinkData((CrossSectionLink) network.getLink(link)), KpiGtuDirectionality.DIR_PLUS,
249                 Length.ZERO, network.getLink(link).getLength(), new Time(0, TimeUnit.BASE_HOUR), new Time(1.0,
250                     TimeUnit.BASE_HOUR));
251         }
252     }
253 
254 }