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