View Javadoc
1   package org.opentrafficsim.road.gtu.generator.od;
2   
3   import java.util.LinkedHashMap;
4   import java.util.Map;
5   
6   import org.djunits.value.vdouble.scalar.Frequency;
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djutils.exceptions.Throw;
9   import org.opentrafficsim.core.gtu.GTUErrorHandler;
10  import org.opentrafficsim.core.gtu.GTUType;
11  import org.opentrafficsim.core.idgenerator.IdGenerator;
12  import org.opentrafficsim.core.network.LinkType;
13  import org.opentrafficsim.core.network.Node;
14  import org.opentrafficsim.road.gtu.generator.CFBARoomChecker;
15  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBias;
16  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBiases;
17  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
18  import org.opentrafficsim.road.gtu.generator.MarkovCorrelation;
19  import org.opentrafficsim.road.gtu.generator.headway.ArrivalsHeadwayGenerator.HeadwayDistribution;
20  import org.opentrafficsim.road.network.RoadNetwork;
21  import org.opentrafficsim.road.network.lane.Lane;
22  
23  /**
24   * Options for vehicle generation based on an OD matrix.
25   * <p>
26   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
27   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
28   * <p>
29   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 dec. 2017 <br>
30   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
31   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
32   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
33   */
34  public class ODOptions
35  {
36      /** Headway randomization option. */
37      public static final Option<HeadwayDistribution> HEADWAY_DIST =
38              new Option<>("headway distribution", HeadwayDistribution.EXPONENTIAL);
39  
40      /** ID generator option. */
41      public static final Option<IdGenerator> GTU_ID = new Option<>("gtu id", new IdGenerator(""));
42  
43      /** GTU characteristics generator option. */
44      public static final Option<GTUCharacteristicsGeneratorOD> GTU_TYPE =
45              new Option<>("gtu type", new DefaultGTUCharacteristicsGeneratorOD());
46  
47      /** Room checker option. */
48      public static final Option<RoomChecker> ROOM_CHECKER = new Option<>("room checker", new CFBARoomChecker());
49  
50      /** Markov chain for GTU type option. */
51      public static final Option<MarkovCorrelation<GTUType, Frequency>> MARKOV = new Option<>("markov", null);
52  
53      /** Initial distance over which lane changes shouldn't be performed option. */
54      public static final Option<Length> NO_LC_DIST = new Option<>("no lc distance", null);
55      
56      /** Whether to perform instantaneous lane changes. */
57      public static final Option<Boolean> INSTANT_LC = new Option<>("instant lc", false);
58      
59      /** Error handler when GTU exceptions occur. */
60      public static final Option<GTUErrorHandler> ERROR_HANDLER = new Option<>("error handler", GTUErrorHandler.THROW);
61  
62      /** Options overall. */
63      private OptionSet<Void> options = new OptionSet<>();
64  
65      /** Options per lane. */
66      private OptionSet<Lane> laneOptions = new OptionSet<>();
67  
68      /** Options per node. */
69      private OptionSet<Node> nodeOptions = new OptionSet<>();
70  
71      /** Options per road type. */
72      private OptionSet<LinkType> linkTypeOptions = new OptionSet<>();
73  
74      /** cache for lane biases per network. */
75      private static final Map<RoadNetwork, Option<LaneBiases>> LANE_BIAS_CACHE = new LinkedHashMap<>();
76  
77      /**
78       * Lane bias. Default is Truck: truck right (strong right, max 2 lanes), Vehicle (other): weak left.
79       * @param network the network for which to return the lane bias
80       * @return the lane bias
81       */
82      public static final Option<LaneBiases> getLaneBiasOption(final RoadNetwork network)
83      {
84          Option<LaneBiases> laneBiases = LANE_BIAS_CACHE.get(network);
85          if (laneBiases == null)
86          {
87              laneBiases = new Option<>("lane bias",
88                      new LaneBiases().addBias(network.getGtuType(GTUType.DEFAULTS.TRUCK), LaneBias.TRUCK_RIGHT)
89                              .addBias(network.getGtuType(GTUType.DEFAULTS.VEHICLE), LaneBias.WEAK_LEFT));
90              LANE_BIAS_CACHE.put(network, laneBiases);
91          }
92          return laneBiases;
93      }
94  
95      /**
96       * Set option value.
97       * @param option Option&lt;K&gt;; option
98       * @param value K; option value
99       * @param <K> value type
100      * @return this option set
101      */
102     public final <K> ODOptions set(final Option<K> option, final K value)
103     {
104         this.options.set(null, option, value);
105         return this;
106     }
107 
108     /**
109      * Set option value for lane.
110      * @param lane Lane; lane
111      * @param option Option&lt;K&gt;; option
112      * @param value K; option value
113      * @param <K> value type
114      * @return this option set
115      */
116     public final <K> ODOptions set(final Lane lane, final Option<K> option, final K value)
117     {
118         this.laneOptions.set(lane, option, value);
119         return this;
120     }
121 
122     /**
123      * Set option value for node.
124      * @param node Node; node
125      * @param option Option&lt;K&gt;; option
126      * @param value K; option value
127      * @param <K> value type
128      * @return this option set
129      */
130     public final <K> ODOptions set(final Node node, final Option<K> option, final K value)
131     {
132         this.nodeOptions.set(node, option, value);
133         return this;
134     }
135 
136     /**
137      * Set option value for link type.
138      * @param linkType LinkType; link type
139      * @param option Option&lt;K&gt;; option
140      * @param value K; option value
141      * @param <K> value type
142      * @return this option set
143      */
144     public final <K> ODOptions set(final LinkType linkType, final Option<K> option, final K value)
145     {
146         this.linkTypeOptions.set(linkType, option, value);
147         return this;
148     }
149 
150     /**
151      * Get option value. If a value is specified for a specific category, it is returned. The following order is used:
152      * <ul>
153      * <li>{@code Lane}</li>
154      * <li>{@code Node} (origin)</li>
155      * <li>{@code LinkType}</li>
156      * <li>None (global option value)</li>
157      * <li>Default option value</li>
158      * </ul>
159      * @param option Option&lt;K&gt;; option
160      * @param lane Lane; lane to obtain specific option value, may be null
161      * @param node Node; node to obtain specific option value, may be null
162      * @param linkType LinkType; link type to obtain specific option value, may be null
163      * @param <K> value type
164      * @return K; option value
165      */
166     public final <K> K get(final Option<K> option, final Lane lane, final Node node, final LinkType linkType)
167     {
168         Throw.whenNull(option, "Option may not be null.");
169         K value = this.laneOptions.get(lane, option);
170         if (value != null)
171         {
172             return value;
173         }
174         value = this.nodeOptions.get(node, option);
175         if (value != null)
176         {
177             return value;
178         }
179         value = this.linkTypeOptions.get(linkType, option);
180         if (value != null)
181         {
182             return value;
183         }
184         value = this.options.get(null, option);
185         if (value != null)
186         {
187             return value;
188         }
189         return option.getDefaultValue();
190     }
191 
192     /**
193      * Utility class to store options.
194      * <p>
195      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
196      * <br>
197      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
198      * <p>
199      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 6 dec. 2017 <br>
200      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
201      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
202      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
203      * @param <K> option value type
204      */
205     public static final class Option<K>
206     {
207 
208         /** Id. */
209         private final String id;
210 
211         /** Default value. */
212         private final K defaultValue;
213 
214         /**
215          * Constructor.
216          * @param id String; id
217          * @param defaultValue K; default value
218          */
219         Option(final String id, final K defaultValue)
220         {
221             this.id = id;
222             this.defaultValue = defaultValue;
223         }
224 
225         /**
226          * Returns the default value.
227          * @return default value
228          */
229         public K getDefaultValue()
230         {
231             return this.defaultValue;
232         }
233 
234         /** {@inheritDoc} */
235         @Override
236         public int hashCode()
237         {
238             final int prime = 31;
239             int result = 1;
240             result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
241             return result;
242         }
243 
244         /** {@inheritDoc} */
245         @Override
246         public boolean equals(final Object obj)
247         {
248             if (this == obj)
249             {
250                 return true;
251             }
252             if (obj == null)
253             {
254                 return false;
255             }
256             if (getClass() != obj.getClass())
257             {
258                 return false;
259             }
260             Option<?> other = (Option<?>) obj;
261             if (this.id == null)
262             {
263                 if (other.id != null)
264                 {
265                     return false;
266                 }
267             }
268             else if (!this.id.equals(other.id))
269             {
270                 return false;
271             }
272             return true;
273         }
274 
275         /** {@inheritDoc} */
276         @Override
277         public String toString()
278         {
279             return "Option [id=" + this.id + "]";
280         }
281 
282     }
283 
284     /**
285      * Single set of options for a certain category, i.e. lane, node, link type or null (i.e. global).
286      * <p>
287      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
288      * <br>
289      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
290      * <p>
291      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 jan. 2018 <br>
292      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
293      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
294      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
295      * @param <C> category type, i.e. {@code Lane}, {@code Node}, {@code LinkType} or {@code Void} (i.e. global).
296      */
297     private class OptionSet<C>
298     {
299 
300         /** Options. */
301         private Map<C, Map<Option<?>, Object>> optionsSet = new LinkedHashMap<>();
302 
303         /**
304          * Constructor.
305          */
306         OptionSet()
307         {
308             //
309         }
310 
311         /**
312          * Set value in option set.
313          * @param category C; category
314          * @param option Option&lt;K&gt;; option
315          * @param value K; value
316          * @param <K> option value type
317          */
318         public <K> void set(final C category, final Option<K> option, final K value)
319         {
320             Map<Option<?>, Object> map = this.optionsSet.get(category);
321             if (map == null)
322             {
323                 map = new LinkedHashMap<>();
324                 this.optionsSet.put(category, map);
325             }
326             map.put(option, value);
327         }
328 
329         /**
330          * Returns the option value for the category.
331          * @param category C; category
332          * @param option Option&lt;K&gt;; option
333          * @return option value for the category
334          * @param <K> value type
335          */
336         @SuppressWarnings("unchecked")
337         public <K> K get(final C category, final Option<K> option)
338         {
339             if (!this.optionsSet.containsKey(category))
340             {
341                 return null;
342             }
343             return (K) this.optionsSet.get(category).get(option);
344         }
345 
346     }
347 
348 }