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