1 package strategies;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.rmi.RemoteException;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.Hashtable;
10 import java.util.Iterator;
11 import java.util.LinkedHashSet;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.Set;
15
16 import javax.naming.NamingException;
17 import javax.swing.Box;
18 import javax.swing.JLabel;
19 import javax.swing.JSlider;
20 import javax.swing.SwingConstants;
21 import javax.swing.event.ChangeEvent;
22 import javax.swing.event.ChangeListener;
23
24 import org.djunits.unit.SpeedUnit;
25 import org.djunits.value.vdouble.scalar.Acceleration;
26 import org.djunits.value.vdouble.scalar.Duration;
27 import org.djunits.value.vdouble.scalar.Length;
28 import org.djunits.value.vdouble.scalar.Speed;
29 import org.opentrafficsim.base.parameters.ParameterException;
30 import org.opentrafficsim.base.parameters.ParameterSet;
31 import org.opentrafficsim.base.parameters.ParameterTypes;
32 import org.opentrafficsim.base.parameters.Parameters;
33 import org.opentrafficsim.core.geometry.OTSGeometryException;
34 import org.opentrafficsim.core.geometry.OTSPoint3D;
35 import org.opentrafficsim.core.gtu.GTU;
36 import org.opentrafficsim.core.gtu.GTUCharacteristics;
37 import org.opentrafficsim.core.gtu.GTUDirectionality;
38 import org.opentrafficsim.core.gtu.GTUException;
39 import org.opentrafficsim.core.gtu.GTUType;
40 import org.opentrafficsim.core.gtu.Try;
41 import org.opentrafficsim.core.gtu.animation.AccelerationGTUColorer;
42 import org.opentrafficsim.core.gtu.animation.SpeedGTUColorer;
43 import org.opentrafficsim.core.gtu.animation.SwitchableGTUColorer;
44 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactoryByType;
45 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
46 import org.opentrafficsim.core.network.Link;
47 import org.opentrafficsim.core.network.NetworkException;
48 import org.opentrafficsim.core.network.OTSNetwork;
49 import org.opentrafficsim.core.network.OTSNode;
50 import org.opentrafficsim.core.network.animation.NodeAnimation;
51 import org.opentrafficsim.road.animation.AbstractSimulationScript;
52 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
53 import org.opentrafficsim.road.gtu.animation.DesiredHeadwayColorer;
54 import org.opentrafficsim.road.gtu.animation.FixedColor;
55 import org.opentrafficsim.road.gtu.animation.IncentiveColorer;
56 import org.opentrafficsim.road.gtu.animation.SocialPressureColorer;
57 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
58 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
59 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
60 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
61 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
62 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
63 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
64 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectNeighborsPerception;
65 import org.opentrafficsim.road.gtu.lane.perception.categories.HeadwayGtuType;
66 import org.opentrafficsim.road.gtu.lane.plan.operational.LaneOperationalPlanBuilder;
67 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
68 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
69 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
70 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
71 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationIncentive;
72 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
73 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
74 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSocioSpeed;
75 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
76 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveStayRight;
77 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
78 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.SocioDesiredSpeed;
79 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
80 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
81 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
84 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
85 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
86 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
87 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
88 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
89 import org.opentrafficsim.road.network.factory.LaneFactory;
90 import org.opentrafficsim.road.network.lane.CrossSectionLink;
91 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
92 import org.opentrafficsim.road.network.lane.Lane;
93 import org.opentrafficsim.road.network.lane.LaneType;
94 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
95
96 import nl.tudelft.simulation.dsol.SimRuntimeException;
97 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
98 import nl.tudelft.simulation.event.EventInterface;
99 import nl.tudelft.simulation.event.EventListenerInterface;
100 import nl.tudelft.simulation.jstats.distributions.DistNormal;
101 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
102 import nl.tudelft.simulation.jstats.streams.StreamInterface;
103
104
105
106
107
108
109
110
111
112
113
114
115 public class StrategiesDemo extends AbstractSimulationScript
116 {
117
118
119 private final Map<GTUType, LaneBasedStrategicalPlannerFactory<?>> factories = new HashMap<>();
120
121
122 private int gtuIdNum = 0;
123
124
125 private int gtuNum = 60;
126
127
128 private final StreamInterface stream = new MersenneTwister(1L);
129
130
131 private final List<Double> queue = new ArrayList<>();
132
133
134 private KmplcListener kmplcListener;
135
136
137
138
139
140 protected StrategiesDemo(final String[] properties)
141 {
142 super("Strategies demo", "Demo of driving strategies in LMRS.", properties);
143 setGtuColorer(SwitchableGTUColorer.builder().addColorer(new FixedColor(Color.BLUE, "Blue"))
144 .addColorer(new SpeedGTUColorer(new Speed(150, SpeedUnit.KM_PER_HOUR)))
145 .addColorer(new AccelerationGTUColorer(Acceleration.createSI(-6.0), Acceleration.createSI(2)))
146 .addActiveColorer(new SocialPressureColorer())
147 .addColorer(new DesiredHeadwayColorer(Duration.createSI(0.5), Duration.createSI(1.6)))
148 .addColorer(new IncentiveColorer(IncentiveSocioSpeed.class)).build());
149 }
150
151
152
153
154
155 public static void main(final String[] args)
156 {
157 StrategiesDemo demo = new StrategiesDemo(args);
158 demo.start();
159 }
160
161
162 @Override
163 protected void setDefaultProperties()
164 {
165 setProperty("simulationTime", "360000");
166 }
167
168
169 @Override
170 protected void setupDemo(final AbstractWrappableAnimation animation, final OTSNetwork net)
171 {
172
173 JLabel textLabel = new JLabel("<html><p align=\"justify\">"
174 + "Adjust the sliders below to change the ego-speed sensitivity and socio-speed sensitivity of the drivers, "
175 + "and observe how traffic is affected. Detailed instructions are in the attached read-me." + "</html>");
176 textLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
177 animation.getDemoPanel().add(textLabel);
178
179
180 animation.getDemoPanel().add(Box.createVerticalStrut(20));
181
182
183 JLabel gtuLabel = new JLabel("<html>Number of vehicles</html>");
184 gtuLabel.setHorizontalAlignment(SwingConstants.CENTER);
185 gtuLabel.setPreferredSize(new Dimension(200, 0));
186 gtuLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
187 animation.getDemoPanel().add(gtuLabel);
188 JSlider gtuSlider = new JSlider(0, 120, 60);
189 gtuSlider.setMinorTickSpacing(10);
190 gtuSlider.setMajorTickSpacing(30);
191 gtuSlider.setPaintTicks(true);
192 gtuSlider.setPaintLabels(true);
193 gtuSlider.setToolTipText("<html>Number of vehicles</html>");
194 gtuSlider.addChangeListener(new ChangeListener()
195 {
196 @SuppressWarnings("synthetic-access")
197 @Override
198 public void stateChanged(final ChangeEvent e)
199 {
200 StrategiesDemo.this.gtuNum = ((JSlider) e.getSource()).getValue();
201 if (!StrategiesDemo.this.getSimulator().isRunning())
202 {
203 StrategiesDemo.this.checkVehicleNumber();
204 animation.getDemoPanel().getParent().repaint();
205 }
206 }
207 });
208 animation.getDemoPanel().add(gtuSlider);
209
210
211 animation.getDemoPanel().add(Box.createVerticalStrut(20));
212
213
214 JLabel egoLabel = new JLabel("<html>Ego-speed sensitivity<sup>-1</sup> [km/h]</html>");
215 egoLabel.setHorizontalAlignment(SwingConstants.CENTER);
216 egoLabel.setPreferredSize(new Dimension(200, 0));
217 egoLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
218 animation.getDemoPanel().add(egoLabel);
219 int egoSteps = 70;
220 JSlider egoSlider = new JSlider(0, egoSteps, egoSteps / 2);
221 egoSlider.setMinorTickSpacing(2);
222 egoSlider.setMajorTickSpacing(egoSteps / 5);
223 egoSlider.setPaintTicks(true);
224 egoSlider.setPaintLabels(true);
225 Hashtable<Integer, JLabel> egoTable = new Hashtable<>();
226 for (int i = 0; i <= egoSteps; i += egoSteps / 5)
227 {
228 egoTable.put(i, new JLabel(String.format("%d", i)));
229 }
230 egoSlider.setLabelTable(egoTable);
231 egoSlider.setToolTipText("<html>Ego-speed sensitivity as 1/<i>v<sub>gain</sub></i></html>");
232 egoSlider.addChangeListener(new ChangeListener()
233 {
234 @Override
235 public void stateChanged(final ChangeEvent e)
236 {
237 double v = Math.max(((JSlider) e.getSource()).getValue(), 0.01);
238 Speed vGain = new Speed(v, SpeedUnit.KM_PER_HOUR);
239 for (GTU gtu : getNetwork().getGTUs())
240 {
241 if (gtu.getGTUType().isOfType(GTUType.CAR))
242 {
243 Try.execute(() -> gtu.getParameters().setParameter(LmrsParameters.VGAIN, vGain),
244 "Exception while setting vGain");
245 }
246 }
247 }
248 });
249 animation.getDemoPanel().add(egoSlider);
250
251
252 animation.getDemoPanel().add(Box.createVerticalStrut(20));
253
254
255 JLabel socioLabel = new JLabel("Socio-speed sensitivity [-]");
256 socioLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
257 animation.getDemoPanel().add(socioLabel);
258 int socioSteps = 20;
259 JSlider socioSlider = new JSlider(0, socioSteps, socioSteps / 2);
260 socioSlider.setMinorTickSpacing(1);
261 socioSlider.setMajorTickSpacing(socioSteps / 5);
262 socioSlider.setPaintTicks(true);
263 socioSlider.setPaintLabels(true);
264 Hashtable<Integer, JLabel> socioTable = new Hashtable<>();
265 for (int i = 0; i <= socioSteps; i += socioSteps / 5)
266 {
267 double val = (double) i / socioSteps;
268 socioTable.put(i, new JLabel(String.format("%.2f", val)));
269 }
270 socioSlider.setLabelTable(socioTable);
271 socioSlider.setToolTipText("Socio-speed sensitivity between 0 and 1");
272 socioSlider.addChangeListener(new ChangeListener()
273 {
274 @Override
275 public void stateChanged(final ChangeEvent e)
276 {
277 JSlider slider = (JSlider) e.getSource();
278 double sigma = ((double) slider.getValue()) / slider.getMaximum();
279 for (GTU gtu : getNetwork().getGTUs())
280 {
281 if (gtu.getGTUType().isOfType(GTUType.CAR))
282 {
283 Try.execute(() -> gtu.getParameters().setParameter(LmrsParameters.SOCIO, sigma),
284 "Exception while setting vGain");
285 }
286 }
287 }
288 });
289 animation.getDemoPanel().add(socioSlider);
290
291
292 animation.getDemoPanel().add(Box.createVerticalStrut(20));
293
294
295 JLabel kmplcLabel = new JLabel("Km between lane changes (last 0): -");
296 this.kmplcListener = new KmplcListener(kmplcLabel, net);
297 for (GTU gtu : net.getGTUs())
298 {
299 Try.execute(() -> gtu.addListener(this.kmplcListener, LaneBasedGTU.LANE_CHANGE_EVENT),
300 "Exception while adding lane change listener");
301 }
302 kmplcLabel.setHorizontalAlignment(SwingConstants.LEFT);
303 kmplcLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
304 animation.getDemoPanel().add(kmplcLabel);
305 }
306
307
308
309
310 private void checkVehicleNumber()
311 {
312 while (getNetwork().getGTUs().size() > this.gtuNum)
313 {
314 int i = StrategiesDemo.this.stream.nextInt(0, getNetwork().getGTUs().size());
315 Iterator<GTU> it = getNetwork().getGTUs().iterator();
316 GTU gtu = it.next();
317 for (int j = 0; j < i; j++)
318 {
319 gtu = it.next();
320 }
321 gtu.destroy();
322 this.queue.clear();
323 }
324 while (getNetwork().getGTUs().size() < this.gtuNum)
325 {
326 Lane lane = null;
327 Length pos = null;
328 Speed initialSpeed = null;
329 Length gap = Length.ZERO;
330 for (Link link : getNetwork().getLinkMap().values())
331 {
332 for (Lane l : ((CrossSectionLink) link).getLanes())
333 {
334 if (l.numberOfGtus() == 0)
335 {
336 lane = l;
337 pos = lane.getLength().multiplyBy(0.5);
338 gap = Length.POSITIVE_INFINITY;
339 initialSpeed = Speed.ZERO;
340 }
341 for (int i = 0; i < l.numberOfGtus(); i++)
342 {
343 LaneBasedGTU gtu1 = l.getGtu(i);
344 Length up = Try.assign(() -> gtu1.position(l, gtu1.getReference()), "");
345 LaneBasedGTU gtu2;
346 Length down;
347 if (i < l.numberOfGtus() - 1)
348 {
349 gtu2 = l.getGtu(i + 1);
350 down = Try.assign(() -> gtu2.position(l, gtu2.getReference()), "");
351 }
352 else
353 {
354 Lane nextLane = l.nextLanes(GTUType.VEHICLE).keySet().iterator().next();
355 if (nextLane.numberOfGtus() == 0)
356 {
357 continue;
358 }
359 gtu2 = nextLane.getGtu(0);
360 down = l.getLength().plus(Try.assign(() -> gtu2.position(nextLane, gtu2.getReference()), ""));
361 }
362 if (down.minus(up).gt(gap))
363 {
364 gap = down.minus(up);
365 lane = l;
366 pos = Length.interpolate(up, down, 0.5);
367 initialSpeed = Speed.interpolate(gtu1.getSpeed(), gtu2.getSpeed(), 0.5);
368 }
369 }
370 }
371 }
372 GTUType gtuType = this.stream.nextDouble() > 0.1 ? GTUType.CAR : GTUType.TRUCK;
373 try
374 {
375 createGtu(lane, pos, gtuType, initialSpeed, getNetwork());
376 }
377 catch (NamingException | GTUException | NetworkException | SimRuntimeException | OTSGeometryException exception)
378 {
379 throw new RuntimeException(exception);
380 }
381 this.queue.clear();
382 }
383 Try.execute(() -> getSimulator().scheduleEventRel(Duration.createSI(0.1), this, this, "checkVehicleNumber",
384 new Object[] {}), "");
385 }
386
387
388 private class KmplcListener implements EventListenerInterface
389 {
390
391 private final JLabel label;
392
393
394 private final OTSNetwork network;
395
396
397
398
399
400
401 @SuppressWarnings("synthetic-access")
402 KmplcListener(final JLabel label, final OTSNetwork network)
403 {
404 this.label = label;
405 this.network = network;
406 StrategiesDemo.this.queue.add(0.0);
407 }
408
409
410 @SuppressWarnings("synthetic-access")
411 @Override
412 public void notify(final EventInterface event) throws RemoteException
413 {
414 if (event.getType().equals(LaneBasedGTU.LANE_CHANGE_EVENT))
415 {
416 double cumul = 0.0;
417 for (GTU gtu : this.network.getGTUs())
418 {
419 cumul += gtu.getOdometer().si;
420 }
421 cumul /= 1000;
422 StrategiesDemo.this.queue.add(cumul);
423 while (StrategiesDemo.this.queue.size() > 51)
424 {
425 StrategiesDemo.this.queue.remove(0);
426 }
427 double val =
428 (StrategiesDemo.this.queue.get(StrategiesDemo.this.queue.size() - 1) - StrategiesDemo.this.queue.get(0))
429 / (StrategiesDemo.this.queue.size() - 1.0);
430 this.label.setText(
431 String.format("Lane change rate (last %d): %.1f km/lc", StrategiesDemo.this.queue.size() - 1, val));
432 }
433 }
434 }
435
436
437 @Override
438 protected OTSNetwork setupSimulation(final DEVSSimulatorInterface.TimeDoubleUnit sim) throws Exception
439 {
440 LaneOperationalPlanBuilder.INSTANT_LANE_CHANGES = true;
441
442 OTSNetwork net = new OTSNetwork("Strategies demo");
443 double radius = 250;
444 LaneType laneType = LaneType.FREEWAY;
445 Speed speedLimit = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
446 OTSNode nodeA = new OTSNode(net, "A", new OTSPoint3D(-radius, 0, 0));
447 OTSNode nodeB = new OTSNode(net, "B", new OTSPoint3D(radius, 0, 0));
448 new NodeAnimation(nodeA, sim);
449 new NodeAnimation(nodeB, sim);
450
451 OTSPoint3D[] coordsHalf1 = new OTSPoint3D[127];
452 for (int i = 0; i < coordsHalf1.length; i++)
453 {
454 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
455 coordsHalf1[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
456 }
457 Lane[] lanes1 = LaneFactory.makeMultiLane(net, "North", nodeB, nodeA, coordsHalf1, 2, laneType, speedLimit, sim);
458 OTSPoint3D[] coordsHalf2 = new OTSPoint3D[127];
459 for (int i = 0; i < coordsHalf2.length; i++)
460 {
461 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
462 coordsHalf2[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
463 }
464 Lane[] lanes2 = LaneFactory.makeMultiLane(net, "South", nodeA, nodeB, coordsHalf2, 2, laneType, speedLimit, sim);
465
466
467 PerceptionFactory perceptionFactory = new LmrsStrategiesPerceptionFactory();
468
469 ParameterFactoryByType parameterFactory = new ParameterFactoryByType();
470 parameterFactory.addParameter(Tailgating.RHO, 0.0);
471 parameterFactory.addParameter(GTUType.CAR, LmrsParameters.SOCIO, 0.5);
472 parameterFactory.addParameter(GTUType.TRUCK, LmrsParameters.SOCIO, 1.0);
473 parameterFactory.addParameter(GTUType.CAR, LmrsParameters.VGAIN, new Speed(35.0, SpeedUnit.KM_PER_HOUR));
474 parameterFactory.addParameter(GTUType.TRUCK, LmrsParameters.VGAIN, new Speed(50.0, SpeedUnit.KM_PER_HOUR));
475 parameterFactory.addParameter(ParameterTypes.TMAX, Duration.createSI(1.6));
476 parameterFactory.addParameter(GTUType.CAR, ParameterTypes.FSPEED,
477 new DistNormal(this.stream, 123.7 / 120.0, 12.0 / 120.0));
478 parameterFactory.addParameter(GTUType.TRUCK, ParameterTypes.A, Acceleration.createSI(0.4));
479 parameterFactory.addParameter(GTUType.TRUCK, ParameterTypes.FSPEED, 1.0);
480 for (GTUType gtuType : new GTUType[] { GTUType.CAR, GTUType.TRUCK })
481 {
482
483 Set<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
484 Set<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
485 Set<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
486 mandatoryIncentives.add(new IncentiveRoute());
487 voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
488 voluntaryIncentives.add(new IncentiveKeep());
489 voluntaryIncentives.add(new IncentiveSocioSpeed());
490 if (gtuType.equals(GTUType.TRUCK))
491 {
492 voluntaryIncentives.add(new IncentiveStayRight());
493 }
494
495 CarFollowingModelFactory<?> cfFactory =
496 gtuType.equals(GTUType.CAR) ? new SocioIDMFactory() : new IDMPlusFactory(this.stream);
497
498 Tailgating tlgt = Tailgating.PRESSURE;
499
500 LaneBasedStrategicalPlannerFactory<?> laneBasedStrategicalPlannerFactory =
501 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(cfFactory, perceptionFactory,
502 Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, tlgt, mandatoryIncentives,
503 voluntaryIncentives, accelerationIncentives), parameterFactory);
504 this.factories.put(gtuType, laneBasedStrategicalPlannerFactory);
505 }
506 double pTruck = 0.1;
507 for (int i = 0; i < lanes1.length; i++)
508 {
509 Length pos = Length.createSI(10.0);
510 Length gap = lanes1[i].getLength().plus(lanes2[i].getLength()).divideBy(this.gtuNum / 2);
511 for (int j = 0; j < 2; j++)
512 {
513 Lane lane = j == 0 ? lanes1[i] : lanes2[i];
514 while (true)
515 {
516 GTUType gtuType;
517 if (i == 0)
518 {
519 gtuType = GTUType.CAR;
520 }
521 else
522 {
523 gtuType = this.stream.nextDouble() < 2 * pTruck ? GTUType.TRUCK : GTUType.CAR;
524 }
525
526 Speed initialSpeed = Speed.ZERO;
527
528 createGtu(lane, pos, gtuType, initialSpeed, net);
529
530 pos = pos.plus(gap);
531 if (pos.si > lane.getLength().si)
532 {
533 pos = pos.minus(lane.getLength());
534 break;
535 }
536 }
537 }
538 }
539
540 sim.scheduleEventNow(this, this, "checkVehicleNumber", new Object[] {});
541
542 return net;
543 }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 public void createGtu(final Lane lane, final Length pos, final GTUType gtuType, final Speed initialSpeed,
559 final OTSNetwork net)
560 throws NamingException, GTUException, NetworkException, SimRuntimeException, OTSGeometryException
561 {
562 GTUCharacteristics gtuCharacteristics = Try.assign(() -> GTUType.defaultCharacteristics(gtuType, this.stream),
563 "Exception while applying default GTU characteristics.");
564
565 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.gtuIdNum), gtuType, gtuCharacteristics.getLength(),
566 gtuCharacteristics.getWidth(), gtuCharacteristics.getMaximumSpeed(), gtuCharacteristics.getFront(),
567 getSimulator(), net);
568 gtu.setMaximumAcceleration(gtuCharacteristics.getMaximumAcceleration());
569 gtu.setMaximumDeceleration(gtuCharacteristics.getMaximumDeceleration());
570 gtu.setNoLaneChangeDistance(Length.createSI(50));
571
572
573 LaneBasedStrategicalPlanner strategicalPlanner = this.factories.get(gtuType).create(gtu, null, null, null);
574
575
576 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
577 initialPositions.add(new DirectedLanePosition(lane, pos, GTUDirectionality.DIR_PLUS));
578 if (pos.plus(gtu.getFront().getDx()).gt(lane.getLength()))
579 {
580 Lane nextLane = lane.nextLanes(gtuType).keySet().iterator().next();
581 Length nextPos = pos.minus(lane.getLength());
582 initialPositions.add(new DirectedLanePosition(nextLane, nextPos, GTUDirectionality.DIR_PLUS));
583 }
584 if (pos.plus(gtu.getRear().getDx()).lt0())
585 {
586 Lane prevLane = lane.prevLanes(gtuType).keySet().iterator().next();
587 Length prevPos = prevLane.getLength().plus(pos.plus(gtu.getRear().getDx()));
588 initialPositions.add(new DirectedLanePosition(prevLane, prevPos, GTUDirectionality.DIR_PLUS));
589 }
590 gtu.initWithAnimation(strategicalPlanner, initialPositions, initialSpeed, DefaultCarAnimation.class, getGtuColorer());
591
592 Try.execute(() -> gtu.addListener(this.kmplcListener, LaneBasedGTU.LANE_CHANGE_EVENT),
593 "Exception while adding lane change listener");
594 }
595
596
597 class SocioIDMFactory implements CarFollowingModelFactory<IDMPlus>
598 {
599
600 @Override
601 public Parameters getParameters() throws ParameterException
602 {
603 ParameterSet parameters = new ParameterSet();
604 parameters.setDefaultParameters(AbstractIDM.class);
605 return parameters;
606 }
607
608
609 @Override
610 public IDMPlus generateCarFollowingModel()
611 {
612 return new IDMPlus(AbstractIDM.HEADWAY, new SocioDesiredSpeed(AbstractIDM.DESIRED_SPEED));
613 }
614 }
615
616
617 class LmrsStrategiesPerceptionFactory implements PerceptionFactory
618 {
619
620 @Override
621 public LanePerception generatePerception(final LaneBasedGTU gtu)
622 {
623 LanePerception perception = new CategoricalLanePerception(gtu);
624 perception.addPerceptionCategory(new DirectEgoPerception(perception));
625 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
626 perception.addPerceptionCategory(new DirectNeighborsPerception(perception, HeadwayGtuType.WRAP));
627 perception.addPerceptionCategory(new AnticipationTrafficPerception(perception));
628 return perception;
629 }
630
631
632 @Override
633 public Parameters getParameters() throws ParameterException
634 {
635 return new ParameterSet().setDefaultParameter(ParameterTypes.LOOKAHEAD)
636 .setDefaultParameter(ParameterTypes.LOOKBACKOLD).setDefaultParameter(ParameterTypes.PERCEPTION)
637 .setDefaultParameter(ParameterTypes.LOOKBACK);
638 }
639 }
640
641 }