1 package org.opentrafficsim.road.gtu.generator;
2
3 import java.io.Serializable;
4 import java.util.LinkedList;
5 import java.util.Queue;
6 import java.util.Set;
7
8 import javax.naming.NamingException;
9
10 import org.djunits.unit.LengthUnit;
11 import org.djunits.unit.TimeUnit;
12 import org.djunits.value.vdouble.scalar.Duration;
13 import org.djunits.value.vdouble.scalar.Length;
14 import org.djunits.value.vdouble.scalar.Speed;
15 import org.djunits.value.vdouble.scalar.Time;
16 import org.opentrafficsim.core.distributions.Generator;
17 import org.opentrafficsim.core.distributions.ProbabilityException;
18 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
19 import org.opentrafficsim.core.geometry.OTSGeometryException;
20 import org.opentrafficsim.core.gtu.GTUDirectionality;
21 import org.opentrafficsim.core.gtu.GTUException;
22 import org.opentrafficsim.core.gtu.GTUType;
23 import org.opentrafficsim.core.gtu.RelativePosition;
24 import org.opentrafficsim.core.gtu.animation.GTUColorer;
25 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
26 import org.opentrafficsim.core.network.NetworkException;
27 import org.opentrafficsim.core.network.OTSNetwork;
28 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
29 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
30 import org.opentrafficsim.road.gtu.lane.LaneBasedGTUCharacteristics;
31 import org.opentrafficsim.road.gtu.lane.LaneBasedGTUCharacteristicsGenerator;
32 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
33 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
34 import org.opentrafficsim.road.network.lane.Lane;
35
36 import nl.tudelft.simulation.dsol.SimRuntimeException;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class LaneBasedGTUGenerator implements Serializable
52 {
53
54 private static final long serialVersionUID = 20160000L;
55
56
57 private final Queue<LaneBasedGTUCharacteristics> unplacedTemplates = new LinkedList<>();
58
59
60 private final String id;
61
62
63 private final Generator<Duration> interarrivelTimeGenerator;
64
65
66 private final LaneBasedGTUCharacteristicsGenerator laneBasedGTUCharacteristicsGenerator;
67
68
69 private final Time endTime;
70
71
72 private final long maxGTUs;
73
74
75 private long generatedGTUs = 0;
76
77
78 Duration reTryInterval = new Duration(0.1, TimeUnit.SI);
79
80
81 final Set<DirectedLanePosition> initialLongitudinalPositions;
82
83
84 final RoomChecker roomChecker;
85
86
87 final GTUColorer gtuColorer;
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public LaneBasedGTUGenerator(String id, final Generator<Duration> interarrivelTimeGenerator, final long maxGTUs,
109 final Time startTime, final Time endTime, final GTUColorer gtuColorer,
110 final LaneBasedGTUCharacteristicsGenerator laneBasedGTUCharacteristicsGenerator,
111 final Set<DirectedLanePosition> initialLongitudinalPositions, final OTSNetwork network, RoomChecker roomChecker)
112 throws SimRuntimeException, ProbabilityException, ParameterException
113 {
114 this.id = id;
115 this.interarrivelTimeGenerator = interarrivelTimeGenerator;
116 this.laneBasedGTUCharacteristicsGenerator = laneBasedGTUCharacteristicsGenerator;
117 this.endTime = endTime;
118 this.maxGTUs = maxGTUs;
119 this.initialLongitudinalPositions = initialLongitudinalPositions;
120 this.roomChecker = roomChecker;
121 this.gtuColorer = gtuColorer;
122 laneBasedGTUCharacteristicsGenerator.getSimulator().scheduleEventAbs(
123 startTime.plus(this.interarrivelTimeGenerator.draw()), this, this, "generateCharacteristics", new Object[] {});
124 }
125
126
127
128
129
130
131
132
133
134 @SuppressWarnings("unused")
135 private void generateCharacteristics() throws ProbabilityException, SimRuntimeException, ParameterException, GTUException
136 {
137 OTSDEVSSimulatorInterface simulator = this.laneBasedGTUCharacteristicsGenerator.getSimulator();
138 if (this.generatedGTUs >= this.maxGTUs
139 || this.laneBasedGTUCharacteristicsGenerator.getSimulator().getSimulatorTime().get().ge(this.endTime))
140 {
141 return;
142 }
143 synchronized (this.unplacedTemplates)
144 {
145 this.generatedGTUs++;
146 this.unplacedTemplates.add(this.laneBasedGTUCharacteristicsGenerator.draw());
147 if (this.unplacedTemplates.size() == 1)
148 {
149 simulator.scheduleEventNow(this, this, "tryToPlaceGTU", new Object[] {});
150 }
151 }
152 if (this.generatedGTUs < this.maxGTUs)
153 {
154 simulator.scheduleEventRel(this.interarrivelTimeGenerator.draw(), this, this, "generateCharacteristics",
155 new Object[] {});
156 }
157 }
158
159
160 private int lastReportedQueueLength = 0;
161
162
163
164
165
166
167
168
169
170
171 @SuppressWarnings("unused")
172 private void tryToPlaceGTU() throws SimRuntimeException, GTUException, NamingException, NetworkException,
173 OTSGeometryException, ProbabilityException
174 {
175
176 LaneBasedGTUCharacteristics characteristics;
177 OTSDEVSSimulatorInterface simulator = this.laneBasedGTUCharacteristicsGenerator.getSimulator();
178 synchronized (this.unplacedTemplates)
179 {
180 characteristics = this.unplacedTemplates.peek();
181 }
182 if (null == characteristics)
183 {
184 return;
185 }
186 Length shortestHeadway = new Length(Double.MAX_VALUE, LengthUnit.SI);
187 Speed leaderSpeed = null;
188
189 GTUType gtuType = characteristics.getGTUType();
190 for (DirectedLanePosition dlp : this.initialLongitudinalPositions)
191 {
192 Lane lane = dlp.getLane();
193
194 LaneBasedGTU leader = lane.getGtuAhead(dlp.getPosition(), dlp.getGtuDirection(), RelativePosition.FRONT,
195 simulator.getSimulatorTime().getTime());
196
197 Length headway = Length.ZERO;
198 GTUDirectionality leaderDir = dlp.getGtuDirection();
199
200 while (leader == null && (leaderDir.isPlus() && lane.nextLanes(gtuType).size() == 1)
201 || (leaderDir.isMinus() && lane.prevLanes(gtuType).size() == 1) && headway.si < 300)
202 {
203 headway = headway.plus(lane.getLength());
204 if (leaderDir.isPlus())
205 {
206 leaderDir = lane.nextLanes(gtuType).values().iterator().next();
207 lane = lane.nextLanes(gtuType).keySet().iterator().next();
208 }
209 else
210 {
211 leaderDir = lane.prevLanes(gtuType).values().iterator().next();
212 lane = lane.prevLanes(gtuType).keySet().iterator().next();
213 }
214 leader = lane.getGtuAhead(Length.ZERO, leaderDir, RelativePosition.FRONT,
215 simulator.getSimulatorTime().getTime());
216 }
217 if (null != leader)
218 {
219 Length egoPos =
220 dlp.getGtuDirection().isPlus() ? dlp.getPosition() : dlp.getLane().getLength().minus(dlp.getPosition());
221 Length leaderPos = leaderDir.isPlus() ? leader.position(lane, leader.getRear())
222 : lane.getLength().minus(leader.position(lane, leader.getRear()));
223 headway = headway.plus(leaderPos.minus(egoPos));
224 if (headway.si < 0)
225 {
226 headway = new Length(Math.abs(headway.si), headway.getUnit());
227 }
228
229 headway = new Length(headway.si - characteristics.getLength().si / 2, LengthUnit.SI);
230 if (shortestHeadway.gt(headway))
231 {
232 shortestHeadway = headway;
233 leaderSpeed = leader.getSpeed();
234 }
235 }
236 }
237 if (shortestHeadway.si > 0)
238 {
239 Speed safeSpeed = characteristics.getSpeed();
240 if (null != leaderSpeed)
241 {
242 safeSpeed = this.roomChecker.canPlace(leaderSpeed, shortestHeadway, characteristics);
243 }
244 if (null != safeSpeed)
245 {
246
247 synchronized (this.unplacedTemplates)
248 {
249 this.unplacedTemplates.remove();
250 }
251 if (safeSpeed.gt(characteristics.getMaximumSpeed()))
252 {
253 safeSpeed = characteristics.getMaximumSpeed();
254 }
255 String gtuId = null == characteristics.getIdGenerator() ? null : characteristics.getIdGenerator().nextId();
256 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU(gtuId, characteristics.getGTUType(),
257 characteristics.getLength(), characteristics.getWidth(), characteristics.getMaximumSpeed(), simulator,
258 characteristics.getNetwork());
259 gtu.initWithAnimation(characteristics.getStrategicalPlannerFactory().create(gtu),
260 this.initialLongitudinalPositions, safeSpeed, DefaultCarAnimation.class, this.gtuColorer);
261
262
263 }
264 }
265 int queueLength = this.unplacedTemplates.size();
266 if (queueLength != this.lastReportedQueueLength)
267 {
268 System.out.println("Generator " + this.id + ": queue length is " + queueLength + " at time "
269 + simulator.getSimulatorTime().get());
270 this.lastReportedQueueLength = queueLength;
271 }
272 if (queueLength > 0)
273 {
274
275 this.laneBasedGTUCharacteristicsGenerator.getSimulator().scheduleEventRel(this.reTryInterval, this, this,
276 "tryToPlaceGTU", new Object[] {});
277 }
278 }
279
280
281 public String toString()
282 {
283 return "LaneBasedGTUGenerator " + this.id + " on " + this.initialLongitudinalPositions;
284 }
285
286
287
288
289 public long getGeneratedGTUs()
290 {
291 return this.generatedGTUs;
292 }
293
294
295
296
297 public void setGeneratedGTUs(long generatedGTUs)
298 {
299 this.generatedGTUs = generatedGTUs;
300 }
301
302
303
304
305
306 public String getId()
307 {
308 return this.id;
309 }
310
311
312
313
314
315 public Time getEndTime()
316 {
317 return this.endTime;
318 }
319
320
321
322
323
324 public long getMaxGTUs()
325 {
326 return this.maxGTUs;
327 }
328
329
330
331
332
333 public GTUColorer getGtuColorer()
334 {
335 return this.gtuColorer;
336 }
337
338
339
340
341
342 public interface RoomChecker
343 {
344
345
346
347
348
349
350
351
352
353
354
355 public Speed canPlace(final Speed leaderSpeed, final Length headway,
356 final LaneBasedGTUCharacteristics laneBasedGTUCharacteristics) throws NetworkException;
357 }
358
359 }