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
87
88
89
90
91
92
93
94
95 public class ODApplierExample extends AbstractWrappableAnimation
96 {
97
98
99 static final boolean LANE_BASED = true;
100
101
102 static final Duration PERIOD = new Duration(60.0, DurationUnit.MINUTE);
103
104
105 static final Double DEMAND = 2.0;
106
107
108 private static final long serialVersionUID = 20171211L;
109
110
111 private GTUColorer colorer = new LmrsSwitchableColorer();
112
113
114
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
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
139 @Override
140 public String shortName()
141 {
142 return "ODApplierExample";
143 }
144
145
146 @Override
147 public String description()
148 {
149 return "Example use of the utility ODApplier.applyOD()";
150 }
151
152
153 @Override
154 protected final void addAnimationToggles()
155 {
156 AnimationToggles.setIconAnimationTogglesStandard(this);
157 }
158
159
160 @Override
161 protected OTSModelInterface makeModel() throws OTSSimulationException
162 {
163 return new ODApplierExampleModel();
164 }
165
166
167 @Override
168 public GTUColorer getColorer()
169 {
170 return this.colorer;
171 }
172
173
174
175
176 class ODApplierExampleModel implements OTSModelInterface
177 {
178
179
180 private static final long serialVersionUID = 20171211L;
181
182
183 private OTSNetwork network;
184
185
186 private DEVSSimulatorInterface.TimeDoubleUnit simulator;
187
188
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
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
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
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
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
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
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
373 @Override
374 public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
375 {
376 return this.simulator;
377 }
378
379
380 @Override
381 public OTSNetwork getNetwork()
382 {
383 return this.network;
384 }
385
386 }
387
388 }