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