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