1 package org.opentrafficsim.road.gtu.generator;
2
3 import java.util.LinkedHashSet;
4 import java.util.PriorityQueue;
5 import java.util.Queue;
6 import java.util.Set;
7
8 import javax.naming.NamingException;
9
10 import org.djunits.value.vdouble.scalar.Speed;
11 import org.djunits.value.vdouble.scalar.Time;
12 import org.opentrafficsim.base.parameters.ParameterException;
13 import org.opentrafficsim.core.distributions.ProbabilityException;
14 import org.opentrafficsim.core.geometry.OTSGeometryException;
15 import org.opentrafficsim.core.gtu.GTUException;
16 import org.opentrafficsim.core.network.NetworkException;
17 import org.opentrafficsim.core.network.Node;
18 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristicsGenerator;
19 import org.opentrafficsim.road.gtu.generator.od.GTUCharacteristicsGeneratorOD;
20 import org.opentrafficsim.road.gtu.strategical.od.Category;
21 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
22 import org.opentrafficsim.road.network.lane.LaneDirection;
23
24 import nl.tudelft.simulation.dsol.SimRuntimeException;
25 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
26 import nl.tudelft.simulation.jstats.streams.StreamInterface;
27 import nl.tudelft.simulation.language.Throw;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class Platoons
46 {
47
48
49 private final LaneBasedGTUGenerator generator;
50
51
52 private final LaneBasedGTUCharacteristicsGenerator characteristics;
53
54
55 private final GTUCharacteristicsGeneratorOD characteristicsOD;
56
57
58 private final DEVSSimulatorInterface.TimeDoubleUnit simulator;
59
60
61 private final StreamInterface stream;
62
63
64 private final Set<DirectedLanePosition> position;
65
66
67 private final Queue<PlatoonGtu> queue = new PriorityQueue<>();
68
69
70 private Time startTime;
71
72
73 private Time endTime;
74
75
76 private Node fixedOrigin;
77
78
79 private Node fixedDestination;
80
81
82 private Category fixedCategory;
83
84
85 private Speed fixedSpeed;
86
87
88 private boolean started = false;
89
90
91
92
93
94
95
96
97 public Platoons(final LaneBasedGTUGenerator generator, final LaneBasedGTUCharacteristicsGenerator characteristics,
98 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final Set<DirectedLanePosition> position)
99 {
100 this.generator = generator;
101 this.characteristics = characteristics;
102 this.characteristicsOD = null;
103 this.simulator = simulator;
104 this.stream = null;
105 this.position = position;
106 }
107
108
109
110
111
112
113
114
115
116 public Platoons(final LaneBasedGTUGenerator generator, final GTUCharacteristicsGeneratorOD characteristics,
117 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final StreamInterface stream, final Set<DirectedLanePosition> position)
118 {
119 this.generator = generator;
120 this.characteristics = null;
121 this.characteristicsOD = characteristics;
122 this.simulator = simulator;
123 this.stream = stream;
124 this.position = position;
125 }
126
127
128
129
130
131
132
133
134
135 public Platoons addPlatoon(final Time start, final Time end) throws SimRuntimeException
136 {
137 Throw.when(this.started, IllegalStateException.class, "Cannot add a platoon after the Platoons was started.");
138 Throw.whenNull(start, "Start may not be null.");
139 Throw.whenNull(end, "End may not be null.");
140 Set<LaneDirection> laneDirections = new LinkedHashSet<>();
141 for (DirectedLanePosition pos : this.position)
142 {
143 laneDirections.add(pos.getLaneDirection());
144 }
145 this.generator.disable(start, end, laneDirections);
146 this.startTime = start;
147 this.endTime = end;
148 return this;
149 }
150
151
152
153
154
155
156
157
158
159 public Platoons fixInfo(final Node origin, final Node destination, final Category category, final Speed speed)
160 {
161 this.fixedOrigin = origin;
162 this.fixedDestination = destination;
163 this.fixedCategory = category;
164 this.fixedSpeed = speed;
165 return this;
166 }
167
168
169
170
171
172
173
174
175 public Platoons addGtu(final Time time)
176 {
177 Throw.when(
178 this.fixedOrigin == null || this.fixedDestination == null || this.fixedCategory == null
179 || this.fixedSpeed == null,
180 IllegalStateException.class, "When using addGtu(Time), used fixInfo(...) before to set other info.");
181 return addGtu(time, this.fixedOrigin, this.fixedDestination, this.fixedCategory, this.fixedSpeed);
182 }
183
184
185
186
187
188
189
190
191
192
193
194 public Platoons addGtu(final Time time, final Node origin, final Node destination, final Category category,
195 final Speed speed)
196 {
197 Throw.when(this.started, IllegalStateException.class, "Cannot add a GTU after the Platoons was started.");
198 Throw.when(this.startTime == null || this.endTime == null, IllegalStateException.class,
199 "First call addPlatoon() before calling addGtu()");
200 Throw.when(time.gt(this.endTime) || time.lt(this.startTime), IllegalArgumentException.class,
201 "Time %s is not between %s and %s", time, this.startTime, this.endTime);
202 this.queue.add(new PlatoonGtu(time, origin, destination, category, speed));
203 return this;
204 }
205
206
207
208
209
210 public void start() throws SimRuntimeException
211 {
212 this.started = true;
213 if (!this.queue.isEmpty())
214 {
215 this.simulator.scheduleEventAbs(this.queue.peek().getTime(), this, this, "placeGtu",
216 new Object[] { this.queue.poll() });
217 }
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231 @SuppressWarnings("unused")
232 private void placeGtu(final PlatoonGtu platoonGtu) throws SimRuntimeException, NamingException, GTUException,
233 NetworkException, OTSGeometryException, ProbabilityException, ParameterException
234 {
235 if (this.characteristicsOD == null)
236 {
237 this.generator.placeGtu(this.characteristics.draw(), this.position, platoonGtu.getSpeed());
238 }
239 else
240 {
241 this.generator.placeGtu(this.characteristicsOD.draw(platoonGtu.getOrigin(), platoonGtu.getDestination(),
242 platoonGtu.getCategory(), this.stream), this.position, platoonGtu.getSpeed());
243 }
244 start();
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258
259 private class PlatoonGtu implements Comparable<PlatoonGtu>
260 {
261
262
263 private final Time time;
264
265
266 private final Node origin;
267
268
269 private final Node destination;
270
271
272 private final Category category;
273
274
275 private final Speed speed;
276
277
278
279
280
281
282
283
284
285 PlatoonGtu(final Time time, final Node origin, final Node destination, final Category category, final Speed speed)
286 {
287 this.time = time;
288 this.origin = origin;
289 this.destination = destination;
290 this.category = category;
291 this.speed = speed;
292 }
293
294
295 @Override
296 public int compareTo(final PlatoonGtu o)
297 {
298 if (o == null)
299 {
300 return 1;
301 }
302 return this.time.compareTo(o.time);
303 }
304
305
306
307
308 protected Time getTime()
309 {
310 return this.time;
311 }
312
313
314
315
316 protected Node getOrigin()
317 {
318 return this.origin;
319 }
320
321
322
323
324 protected Node getDestination()
325 {
326 return this.destination;
327 }
328
329
330
331
332 protected Category getCategory()
333 {
334 return this.category;
335 }
336
337
338
339
340 protected Speed getSpeed()
341 {
342 return this.speed;
343 }
344
345 }
346 }