View Javadoc
1   package org.opentrafficsim.road.gtu.generator.od;
2   
3   import java.awt.Color;
4   import java.rmi.RemoteException;
5   import java.util.ArrayList;
6   import java.util.HashMap;
7   import java.util.HashSet;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.Set;
11  
12  import javax.naming.NamingException;
13  import javax.swing.SwingUtilities;
14  
15  import org.djunits.unit.DurationUnit;
16  import org.djunits.unit.FrequencyUnit;
17  import org.djunits.unit.SpeedUnit;
18  import org.djunits.unit.TimeUnit;
19  import org.djunits.value.StorageType;
20  import org.djunits.value.ValueException;
21  import org.djunits.value.vdouble.scalar.Duration;
22  import org.djunits.value.vdouble.scalar.Frequency;
23  import org.djunits.value.vdouble.scalar.Length;
24  import org.djunits.value.vdouble.scalar.Speed;
25  import org.djunits.value.vdouble.scalar.Time;
26  import org.djunits.value.vdouble.vector.FrequencyVector;
27  import org.djunits.value.vdouble.vector.TimeVector;
28  import org.opentrafficsim.base.modelproperties.Property;
29  import org.opentrafficsim.base.modelproperties.PropertyException;
30  import org.opentrafficsim.base.parameters.ParameterException;
31  import org.opentrafficsim.core.dsol.OTSModelInterface;
32  import org.opentrafficsim.core.geometry.OTSGeometryException;
33  import org.opentrafficsim.core.geometry.OTSLine3D;
34  import org.opentrafficsim.core.geometry.OTSPoint3D;
35  import org.opentrafficsim.core.gtu.GTUDirectionality;
36  import org.opentrafficsim.core.gtu.GTUException;
37  import org.opentrafficsim.core.gtu.GTUType;
38  import org.opentrafficsim.core.gtu.animation.GTUColorer;
39  import org.opentrafficsim.core.network.LinkType;
40  import org.opentrafficsim.core.network.NetworkException;
41  import org.opentrafficsim.core.network.Node;
42  import org.opentrafficsim.core.network.OTSNetwork;
43  import org.opentrafficsim.core.network.OTSNode;
44  import org.opentrafficsim.core.network.animation.LinkAnimation;
45  import org.opentrafficsim.core.network.animation.NodeAnimation;
46  import org.opentrafficsim.road.animation.AnimationToggles;
47  import org.opentrafficsim.road.gtu.animation.LmrsSwitchableColorer;
48  import org.opentrafficsim.road.gtu.generator.CFBARoomChecker;
49  import org.opentrafficsim.road.gtu.generator.GTUGeneratorAnimation;
50  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBias;
51  import org.opentrafficsim.road.gtu.generator.GeneratorPositions.LaneBiases;
52  import org.opentrafficsim.road.gtu.generator.MarkovCorrelation;
53  import org.opentrafficsim.road.gtu.generator.Platoons;
54  import org.opentrafficsim.road.gtu.generator.od.ODApplier.GeneratorObjects;
55  import org.opentrafficsim.road.gtu.strategical.od.Categorization;
56  import org.opentrafficsim.road.gtu.strategical.od.Category;
57  import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
58  import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
59  import org.opentrafficsim.road.network.animation.LaneAnimation;
60  import org.opentrafficsim.road.network.animation.StripeAnimation;
61  import org.opentrafficsim.road.network.animation.StripeAnimation.TYPE;
62  import org.opentrafficsim.road.network.animation.TrafficLightAnimation;
63  import org.opentrafficsim.road.network.lane.CrossSectionLink;
64  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
65  import org.opentrafficsim.road.network.lane.Lane;
66  import org.opentrafficsim.road.network.lane.LaneType;
67  import org.opentrafficsim.road.network.lane.Stripe;
68  import org.opentrafficsim.road.network.lane.Stripe.Permeable;
69  import org.opentrafficsim.road.network.lane.changing.LaneKeepingPolicy;
70  import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
71  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
72  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
73  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
74  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
75  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
76  import org.opentrafficsim.simulationengine.OTSSimulationException;
77  
78  import nl.tudelft.simulation.dsol.SimRuntimeException;
79  import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
80  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
81  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
82  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
83  import nl.tudelft.simulation.jstats.streams.StreamInterface;
84  
85  /**
86   * <p>
87   * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
88   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
89   * <p>
90   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 11 dec. 2017 <br>
91   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
92   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
93   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
94   */
95  public class ODApplierExample extends AbstractWrappableAnimation
96  {
97  
98      /** Lane based or not. */
99      static final boolean LANE_BASED = true;
100 
101     /** Simulation period. */
102     static final Duration PERIOD = new Duration(60.0, DurationUnit.MINUTE);
103 
104     /** Demand factor. */
105     static final Double DEMAND = 2.0;
106 
107     /** */
108     private static final long serialVersionUID = 20171211L;
109 
110     /** Colorer. */
111     private GTUColorer colorer = new LmrsSwitchableColorer();
112 
113     /**
114      * @param args arguments
115      */
116     public static void main(final String[] args)
117     {
118         SwingUtilities.invokeLater(new Runnable()
119         {
120             @Override
121             public void run()
122             {
123                 try
124                 {
125                     ODApplierExample animation = new ODApplierExample();
126                     // 1 hour simulation run for testing
127                     animation.buildAnimator(Time.ZERO, Duration.ZERO, PERIOD, new ArrayList<Property<?>>(), null, true);
128 
129                 }
130                 catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
131                 {
132                     exception.printStackTrace();
133                 }
134             }
135         });
136     }
137 
138     /** {@inheritDoc} */
139     @Override
140     public String shortName()
141     {
142         return "ODApplierExample";
143     }
144 
145     /** {@inheritDoc} */
146     @Override
147     public String description()
148     {
149         return "Example use of the utility ODApplier.applyOD()";
150     }
151 
152     /** {@inheritDoc} */
153     @Override
154     protected final void addAnimationToggles()
155     {
156         AnimationToggles.setIconAnimationTogglesStandard(this);
157     }
158 
159     /** {@inheritDoc} */
160     @Override
161     protected OTSModelInterface makeModel() throws OTSSimulationException
162     {
163         return new ODApplierExampleModel();
164     }
165 
166     /** {@inheritDoc} */
167     @Override
168     public GTUColorer getColorer()
169     {
170         return this.colorer;
171     }
172 
173     /**
174      * The simulation model.
175      */
176     class ODApplierExampleModel implements OTSModelInterface
177     {
178 
179         /** */
180         private static final long serialVersionUID = 20171211L;
181 
182         /** The network. */
183         private OTSNetwork network;
184 
185         /** Simulator. */
186         private DEVSSimulatorInterface.TimeDoubleUnit simulator;
187 
188         /** {@inheritDoc} */
189         @Override
190         public void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> sim) throws SimRuntimeException
191         {
192             this.simulator = (DEVSSimulatorInterface.TimeDoubleUnit) sim;
193             Map<String, StreamInterface> streams = new HashMap<>();
194             streams.put("generation", new MersenneTwister(1L));
195             this.simulator.getReplication().setStreams(streams);
196 
197             this.network = new OTSNetwork("ODApplierExample");
198             try
199             {
200                 // Network
201                 OTSPoint3D pointA = new OTSPoint3D(-100, 50, 0);
202                 OTSPoint3D pointA1 = new OTSPoint3D(50, 50, 0);
203                 OTSPoint3D pointA2 = new OTSPoint3D(0, 0, 0);
204                 OTSPoint3D pointA3 = new OTSPoint3D(0, -100, 0);
205                 OTSPoint3D pointB = new OTSPoint3D(1000, 0, 0);
206                 OTSNode nodeA = new OTSNode(this.network, "A", pointA);
207                 OTSNode nodeA1 = new OTSNode(this.network, "A1", pointA1);
208                 OTSNode nodeA2 = new OTSNode(this.network, "A2", pointA2);
209                 OTSNode nodeA3 = new OTSNode(this.network, "A3", pointA3);
210                 OTSNode nodeB = new OTSNode(this.network, "B", pointB);
211                 CrossSectionLink linkAA1 = new CrossSectionLink(this.network, "AA1", nodeA, nodeA1, LinkType.CONNECTOR,
212                         new OTSLine3D(pointA, pointA1), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
213                 CrossSectionLink linkAA2 = new CrossSectionLink(this.network, "AA2", nodeA, nodeA2, LinkType.CONNECTOR,
214                         new OTSLine3D(pointA, pointA2), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
215                 CrossSectionLink linkAA3 = new CrossSectionLink(this.network, "AA3", nodeA, nodeA3, LinkType.CONNECTOR,
216                         new OTSLine3D(pointA, pointA3), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
217                 CrossSectionLink linkA1B = new CrossSectionLink(this.network, "A1B", nodeA1, nodeB, LinkType.FREEWAY,
218                         new OTSLine3D(pointA1, pointB), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
219                 CrossSectionLink linkA2B = new CrossSectionLink(this.network, "A2B", nodeA2, nodeB, LinkType.FREEWAY,
220                         new OTSLine3D(pointA2, pointB), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
221                 CrossSectionLink linkA3B = new CrossSectionLink(this.network, "A3B", nodeA3, nodeB, LinkType.FREEWAY,
222                         new OTSLine3D(pointA3, pointB), this.simulator, LaneKeepingPolicy.KEEP_RIGHT);
223                 Lane lane0 = new Lane(linkA1B, "lane0", Length.createSI(0.0), Length.createSI(3.5), LaneType.HIGHWAY,
224                         new Speed(120, SpeedUnit.KM_PER_HOUR), new OvertakingConditions.LeftOnly());
225                 Lane lane1 = new Lane(linkA2B, "lane1", Length.createSI(3.5), Length.createSI(3.5), LaneType.HIGHWAY,
226                         new Speed(120, SpeedUnit.KM_PER_HOUR), new OvertakingConditions.LeftOnly());
227                 Lane lane2 = new Lane(linkA2B, "lane2", Length.createSI(0.0), Length.createSI(3.5), LaneType.HIGHWAY,
228                         new Speed(120, SpeedUnit.KM_PER_HOUR), new OvertakingConditions.LeftOnly());
229                 Lane lane3 = new Lane(linkA2B, "lane3", Length.createSI(-3.5), Length.createSI(3.5), LaneType.HIGHWAY,
230                         new Speed(120, SpeedUnit.KM_PER_HOUR), new OvertakingConditions.LeftOnly());
231                 Lane lane4 = new Lane(linkA3B, "lane4", Length.createSI(0.0), Length.createSI(3.5), LaneType.HIGHWAY,
232                         new Speed(120, SpeedUnit.KM_PER_HOUR), new OvertakingConditions.LeftOnly());
233                 Set<GTUType> gtuTypes = new HashSet<>();
234                 gtuTypes.add(GTUType.VEHICLE);
235                 Stripe stripe12 = new Stripe(linkA2B, Length.createSI(1.75), Length.createSI(1.75), Length.createSI(0.2),
236                         gtuTypes, Permeable.BOTH);
237                 Stripe stripe23 = new Stripe(linkA2B, Length.createSI(-1.75), Length.createSI(-1.75), Length.createSI(0.2),
238                         gtuTypes, Permeable.BOTH);
239 
240                 // animation
241                 new NodeAnimation(nodeA, this.simulator);
242                 new NodeAnimation(nodeA1, this.simulator);
243                 new NodeAnimation(nodeA2, this.simulator);
244                 new NodeAnimation(nodeA3, this.simulator);
245                 new NodeAnimation(nodeB, this.simulator);
246                 new LinkAnimation(linkAA1, this.simulator, 0.5f);
247                 new LinkAnimation(linkAA2, this.simulator, 0.5f);
248                 new LinkAnimation(linkAA3, this.simulator, 0.5f);
249                 new LinkAnimation(linkA1B, this.simulator, 0.5f);
250                 new LinkAnimation(linkA2B, this.simulator, 0.5f);
251                 new LinkAnimation(linkA3B, this.simulator, 0.5f);
252                 new LaneAnimation(lane0, this.simulator, Color.GRAY.brighter(), false);
253                 new LaneAnimation(lane1, this.simulator, Color.GRAY.brighter(), false);
254                 new LaneAnimation(lane2, this.simulator, Color.GRAY.brighter(), false);
255                 new LaneAnimation(lane3, this.simulator, Color.GRAY.brighter(), false);
256                 new LaneAnimation(lane4, this.simulator, Color.GRAY.brighter(), false);
257                 new StripeAnimation(stripe12, this.simulator, TYPE.DASHED);
258                 new StripeAnimation(stripe23, this.simulator, TYPE.DASHED);
259                 new SinkSensor(lane0, Length.createSI(904), this.simulator);
260                 new SinkSensor(lane1, Length.createSI(900), this.simulator);
261                 new SinkSensor(lane2, Length.createSI(900), this.simulator);
262                 new SinkSensor(lane3, Length.createSI(900), this.simulator);
263                 new SinkSensor(lane4, Length.createSI(904), this.simulator);
264                 // traffic light
265                 TrafficLight trafficLight = new SimpleTrafficLight("light1", lane1, Length.createSI(800.0), this.simulator);
266                 new TrafficLightAnimation(trafficLight, this.simulator);
267                 this.simulator.scheduleEventAbs(Time.createSI(30 * 60), this, trafficLight, "setTrafficLightColor",
268                         new Object[] { TrafficLightColor.YELLOW });
269                 this.simulator.scheduleEventAbs(Time.createSI(30 * 60 + 6), this, trafficLight, "setTrafficLightColor",
270                         new Object[] { TrafficLightColor.RED });
271                 this.simulator.scheduleEventAbs(Time.createSI(35 * 60), this, trafficLight, "setTrafficLightColor",
272                         new Object[] { TrafficLightColor.GREEN });
273 
274                 // OD
275                 Categorization categorization;
276                 if (ODApplierExample.LANE_BASED)
277                 {
278                     categorization = new Categorization("ODExample", Lane.class, GTUType.class);
279                 }
280                 else
281                 {
282                     categorization = new Categorization("ODExample", GTUType.class);
283                 }
284                 List<Node> origins = new ArrayList<>();
285                 if (ODApplierExample.LANE_BASED)
286                 {
287                     origins.add(nodeA1);
288                     origins.add(nodeA2);
289                     origins.add(nodeA3);
290                 }
291                 else
292                 {
293                     origins.add(nodeA);
294                 }
295                 List<Node> destinations = new ArrayList<>();
296                 destinations.add(nodeB);
297                 double fT = PERIOD.si / 3600;
298                 TimeVector timeVector = new TimeVector(new double[] { 5 * fT, 600 * fT, 610 * fT, 1800 * fT, 3000 * fT },
299                         TimeUnit.BASE, StorageType.DENSE);
300                 ODMatrix od =
301                         new ODMatrix("ODExample", origins, destinations, categorization, timeVector, Interpolation.STEPWISE);
302                 FrequencyVector demand = new FrequencyVector(
303                         new double[] { 0 * DEMAND, 1000 * DEMAND, 3000 * DEMAND, 7000 * DEMAND, 0 * DEMAND },
304                         FrequencyUnit.PER_HOUR, StorageType.DENSE);
305 
306                 Category platoonCategory;
307                 if (ODApplierExample.LANE_BASED)
308                 {
309                     Category category = new Category(categorization, lane1, GTUType.CAR);
310                     platoonCategory = category;
311                     od.putDemandVector(nodeA2, nodeB, category, demand, timeVector, Interpolation.LINEAR, .4);
312                     category = new Category(categorization, lane2, GTUType.CAR);
313                     od.putDemandVector(nodeA2, nodeB, category, demand, timeVector, Interpolation.LINEAR, .25);
314                     category = new Category(categorization, lane2, GTUType.TRUCK);
315                     od.putDemandVector(nodeA2, nodeB, category, demand, timeVector, Interpolation.LINEAR, .05);
316                     category = new Category(categorization, lane3, GTUType.CAR);
317                     od.putDemandVector(nodeA2, nodeB, category, demand, timeVector, Interpolation.LINEAR, .1);
318                     category = new Category(categorization, lane3, GTUType.TRUCK);
319                     od.putDemandVector(nodeA2, nodeB, category, demand, timeVector, Interpolation.LINEAR, .2);
320                 }
321                 else
322                 {
323                     Category category = new Category(categorization, GTUType.CAR);
324                     platoonCategory = category;
325                     od.putDemandVector(nodeA, nodeB, category, demand, timeVector, Interpolation.LINEAR, .9);
326                     category = new Category(categorization, GTUType.TRUCK);
327                     od.putDemandVector(nodeA, nodeB, category, demand, timeVector, Interpolation.LINEAR, .1);
328                 }
329                 // options
330                 MarkovCorrelation<GTUType, Frequency> markov = new MarkovCorrelation<>();
331                 markov.addState(GTUType.TRUCK, 0.4);
332                 LaneBiases biases = new LaneBiases().addBias(GTUType.VEHICLE, LaneBias.bySpeed(130, 80)).addBias(GTUType.TRUCK,
333                         LaneBias.TRUCK_RIGHT);
334                 ODOptions odOptions = new ODOptions().set(ODOptions.GTU_COLORER, getColorer())
335                         .set(ODOptions.ROOM_CHECKER, new CFBARoomChecker()).set(ODOptions.MARKOV, markov)
336                         .set(ODOptions.LANE_BIAS, biases).set(ODOptions.NO_LC_DIST, Length.createSI(100.0));
337                 Map<String, GeneratorObjects> generatedObjects = ODApplier.applyOD(this.network, od, this.simulator, odOptions);
338                 for (String str : generatedObjects.keySet())
339                 {
340                     new GTUGeneratorAnimation(generatedObjects.get(str).getGenerator(), this.simulator);
341                 }
342 
343                 // platoons
344                 String id = LANE_BASED ? "A21" : "A";
345                 Lane platoonLane = LANE_BASED ? lane1 : lane0;
346                 Set<DirectedLanePosition> position = new HashSet<>();
347                 position.add(new DirectedLanePosition(platoonLane, Length.ZERO, GTUDirectionality.DIR_PLUS));
348                 Platoons platoons = new Platoons(generatedObjects.get(id).getGenerator(),
349                         odOptions.get(ODOptions.GTU_TYPE, null, null, null), this.simulator, streams.get("generation"),
350                         position);
351                 platoons.addPlatoon(Time.createSI(60), Time.createSI(90));
352                 platoons.fixInfo(nodeA, nodeB, platoonCategory, new Speed(90, SpeedUnit.KM_PER_HOUR));
353                 for (double t = 62; t < 90; t += 2)
354                 {
355                     platoons.addGtu(Time.createSI(t));
356                 }
357                 platoons.addPlatoon(Time.createSI(300), Time.createSI(330));
358                 for (double t = 302; t < 330; t += 2)
359                 {
360                     platoons.addGtu(Time.createSI(t));
361                 }
362                 platoons.start();
363 
364             }
365             catch (NetworkException | OTSGeometryException | NamingException | ValueException | ParameterException
366                     | GTUException | RemoteException exception)
367             {
368                 exception.printStackTrace();
369             }
370         }
371 
372         /** {@inheritDoc} */
373         @Override
374         public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
375         {
376             return this.simulator;
377         }
378 
379         /** {@inheritDoc} */
380         @Override
381         public OTSNetwork getNetwork()
382         {
383             return this.network;
384         }
385 
386     }
387 
388 }