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