1 package strategies;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Component;
6 import java.awt.Dimension;
7 import java.rmi.RemoteException;
8 import java.util.ArrayList;
9 import java.util.Hashtable;
10 import java.util.Iterator;
11 import java.util.LinkedHashMap;
12 import java.util.LinkedHashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16
17 import javax.naming.NamingException;
18 import javax.swing.Box;
19 import javax.swing.BoxLayout;
20 import javax.swing.JLabel;
21 import javax.swing.JSlider;
22 import javax.swing.SwingConstants;
23 import javax.swing.border.EmptyBorder;
24 import javax.swing.event.ChangeEvent;
25 import javax.swing.event.ChangeListener;
26
27 import org.djunits.unit.DirectionUnit;
28 import org.djunits.unit.SpeedUnit;
29 import org.djunits.value.vdouble.scalar.Acceleration;
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.event.EventInterface;
37 import org.djutils.event.EventListenerInterface;
38 import org.djutils.exceptions.Try;
39 import org.opentrafficsim.base.parameters.ParameterException;
40 import org.opentrafficsim.base.parameters.ParameterSet;
41 import org.opentrafficsim.base.parameters.ParameterTypes;
42 import org.opentrafficsim.base.parameters.Parameters;
43 import org.opentrafficsim.core.animation.gtu.colorer.AccelerationGTUColorer;
44 import org.opentrafficsim.core.animation.gtu.colorer.SpeedGTUColorer;
45 import org.opentrafficsim.core.animation.gtu.colorer.SwitchableGTUColorer;
46 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
47 import org.opentrafficsim.core.geometry.OTSGeometryException;
48 import org.opentrafficsim.core.geometry.OTSLine3D;
49 import org.opentrafficsim.core.geometry.OTSPoint3D;
50 import org.opentrafficsim.core.gtu.GTU;
51 import org.opentrafficsim.core.gtu.GTUCharacteristics;
52 import org.opentrafficsim.core.gtu.GTUDirectionality;
53 import org.opentrafficsim.core.gtu.GTUException;
54 import org.opentrafficsim.core.gtu.GTUType;
55 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
56 import org.opentrafficsim.core.network.Link;
57 import org.opentrafficsim.core.network.LinkType;
58 import org.opentrafficsim.core.network.NetworkException;
59 import org.opentrafficsim.core.parameters.ParameterFactoryByType;
60 import org.opentrafficsim.road.gtu.colorer.DesiredHeadwayColorer;
61 import org.opentrafficsim.road.gtu.colorer.FixedColor;
62 import org.opentrafficsim.road.gtu.colorer.IncentiveColorer;
63 import org.opentrafficsim.road.gtu.colorer.SocialPressureColorer;
64 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
65 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
66 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
67 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
68 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
69 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
70 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
71 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.DirectNeighborsPerception;
72 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.HeadwayGtuType;
73 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
74 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
75 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
76 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
77 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationIncentive;
78 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
79 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
80 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSocioSpeed;
81 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
82 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveStayRight;
83 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
84 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.SocioDesiredSpeed;
85 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
86 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
87 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
88 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
89 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
90 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
91 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
92 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
93 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
94 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
95 import org.opentrafficsim.road.network.OTSRoadNetwork;
96 import org.opentrafficsim.road.network.factory.LaneFactory;
97 import org.opentrafficsim.road.network.lane.CrossSectionLink;
98 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
99 import org.opentrafficsim.road.network.lane.Lane;
100 import org.opentrafficsim.road.network.lane.LaneType;
101 import org.opentrafficsim.road.network.lane.OTSRoadNode;
102 import org.opentrafficsim.road.network.lane.Stripe.Permeable;
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
123 public class StrategiesDemo extends AbstractSimulationScript
124 {
125
126 private final Map<GTUType, LaneBasedStrategicalPlannerFactory<?>> factories = new LinkedHashMap<>();
127
128
129 private int gtuIdNum = 0;
130
131
132 private int gtuNum = 60;
133
134
135 private final StreamInterface stream = new MersenneTwister(1L);
136
137
138 private final List<Double> queue = new ArrayList<>();
139
140
141 private KmplcListener kmplcListener;
142
143
144 private double truckFraction = 0.1;
145
146
147 private GTUType nextGtuType;
148
149
150 private Length truckLength;
151
152
153 private Length truckMid;
154
155
156 @Option(names = "--length", description = "Length", defaultValue = "2m")
157 private Length carLength;
158
159
160 private Length carMid;
161
162
163
164
165 protected StrategiesDemo()
166 {
167 super("Strategies demo", "Demo of driving strategies in LMRS.");
168 setGtuColorer(SwitchableGTUColorer.builder().addColorer(new FixedColor(Color.BLUE, "Blue")).addColorer(
169 new SpeedGTUColorer(new Speed(150, SpeedUnit.KM_PER_HOUR))).addColorer(new AccelerationGTUColorer(Acceleration
170 .instantiateSI(-6.0), Acceleration.instantiateSI(2))).addActiveColorer(new SocialPressureColorer()).addColorer(
171 new DesiredHeadwayColorer(Duration.instantiateSI(0.5), Duration.instantiateSI(1.6))).addColorer(
172 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 StrategiesDemomo">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 OTSRoadNetwork 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. Detailed instructions are in the attached read-me." + "</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.getGTUType().isOfType(GTUType.DEFAULTS.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.getGTUType().isOfType(GTUType.DEFAULTS.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 i = StrategiesDemo.this.stream.nextInt(0, getNetwork().getGTUs().size());
355 Iterator<GTU> it = getNetwork().getGTUs().iterator();
356 GTU gtu = it.next();
357 for (int j = 0; j < i; j++)
358 {
359 gtu = it.next();
360 }
361 gtu.destroy();
362 this.queue.clear();
363 }
364
365 if (getNetwork().getGTUs().size() < this.gtuNum)
366 {
367 Lane lane = null;
368 Length pos = null;
369 Speed initialSpeed = null;
370 Length gap = Length.ZERO;
371 for (Link link : getNetwork().getLinkMap().values())
372 {
373 for (Lane l : ((CrossSectionLink) link).getLanes())
374 {
375 if (l.numberOfGtus() == 0)
376 {
377 lane = l;
378 pos = lane.getLength().times(0.5);
379 gap = Length.POSITIVE_INFINITY;
380 initialSpeed = Speed.ZERO;
381 }
382 for (int i = 0; i < l.numberOfGtus(); i++)
383 {
384 LaneBasedGTU gtu1 = l.getGtu(i);
385 Length up = Try.assign(() -> gtu1.position(l, gtu1.getFront()), "");
386 LaneBasedGTU gtu2;
387 Length down;
388 if (i < l.numberOfGtus() - 1)
389 {
390 gtu2 = l.getGtu(i + 1);
391 down = Try.assign(() -> gtu2.position(l, gtu2.getRear()), "");
392 }
393 else
394 {
395 Lane nextLane = l.nextLanes(getNetwork().getGtuType(GTUType.DEFAULTS.VEHICLE)).keySet().iterator()
396 .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).minus(this.nextGtuType.isOfType(getNetwork().getGtuType(
405 GTUType.DEFAULTS.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)).minus(this.nextGtuType.isOfType(getNetwork().getGtuType(
415 GTUType.DEFAULTS.TRUCK)) ? this.truckMid : this.carMid);
416 if (pos.gt(l.getLength()))
417 {
418 pos = pos.minus(l.getLength());
419 lane = l.nextLanes(getNetwork().getGtuType(GTUType.DEFAULTS.VEHICLE)).keySet().iterator()
420 .next();
421 }
422 else
423 {
424 lane = l;
425 }
426 }
427 }
428 }
429 }
430 }
431 if (lane != null)
432 {
433 try
434 {
435 createGtu(lane, pos, this.nextGtuType, initialSpeed, getNetwork());
436 }
437 catch (NamingException | GTUException | NetworkException | SimRuntimeException | OTSGeometryException exception)
438 {
439 throw new RuntimeException(exception);
440 }
441 this.nextGtuType = this.stream.nextDouble() < this.truckFraction ? getNetwork().getGtuType(
442 GTUType.DEFAULTS.TRUCK) : getNetwork().getGtuType(GTUType.DEFAULTS.CAR);
443 this.queue.clear();
444 }
445 }
446 Try.execute(() -> getSimulator().scheduleEventRel(Duration.instantiateSI(0.5), this, this, "checkVehicleNumber",
447 new Object[] {}), "");
448 }
449
450
451 private class KmplcListener implements EventListenerInterface
452 {
453
454 private final JLabel label;
455
456
457 private final OTSRoadNetwork network;
458
459
460
461
462
463
464 @SuppressWarnings("synthetic-access")
465 KmplcListener(final JLabel label, final OTSRoadNetwork network)
466 {
467 this.label = label;
468 this.network = network;
469 StrategiesDemo.this.queue.add(0.0);
470 }
471
472
473 @SuppressWarnings("synthetic-access")
474 @Override
475 public void notify(final EventInterface event) throws RemoteException
476 {
477 if (event.getType().equals(LaneBasedGTU.LANE_CHANGE_EVENT))
478 {
479 double cumul = 0.0;
480 for (GTU gtu : this.network.getGTUs())
481 {
482 cumul += gtu.getOdometer().si;
483 }
484 cumul /= 1000;
485 StrategiesDemo.this.queue.add(cumul);
486 while (StrategiesDemo.this.queue.size() > 51)
487 {
488 StrategiesDemo.this.queue.remove(0);
489 }
490 double val = (StrategiesDemo.this.queue.get(StrategiesDemo.this.queue.size() - 1) - StrategiesDemo.this.queue
491 .get(0)) / (StrategiesDemo.this.queue.size() - 1.0);
492 this.label.setText(String.format("Lane change rate (last %d): %.1f km/lc", StrategiesDemo.this.queue.size() - 1,
493 val));
494 }
495 }
496 }
497
498
499 @Override
500 protected OTSRoadNetwork setupSimulation(final OTSSimulatorInterface sim) throws Exception
501 {
502 OTSRoadNetwork network = new OTSRoadNetwork("Strategies demo", true, getSimulator());
503
504 GTUCharacteristics truck = GTUType.defaultCharacteristics(network.getGtuType(GTUType.DEFAULTS.TRUCK), network,
505 this.stream);
506 GTUCharacteristics car = GTUType.defaultCharacteristics(network.getGtuType(GTUType.DEFAULTS.CAR), network, this.stream);
507 this.truckLength = truck.getLength();
508 this.truckMid = truck.getLength().times(0.5).minus(truck.getFront());
509 this.carLength = car.getLength();
510 this.carMid = car.getLength().times(0.5).minus(car.getFront());
511
512 double radius = 150;
513 Speed speedLimit = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
514 OTSRoadNode nodeA = new OTSRoadNode(network, "A", new OTSPoint3D(-radius, 0, 0), new Direction(270,
515 DirectionUnit.EAST_DEGREE));
516 OTSRoadNode nodeB = new OTSRoadNode(network, "B", new OTSPoint3D(radius, 0, 0), new Direction(90,
517 DirectionUnit.EAST_DEGREE));
518
519 OTSPoint3D[] coordsHalf1 = new OTSPoint3D[127];
520 for (int i = 0; i < coordsHalf1.length; i++)
521 {
522 double angle = Math.PI * (i) / (coordsHalf1.length - 1);
523 coordsHalf1[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
524 }
525 List<Lane> lanes1 = new LaneFactory(network, nodeB, nodeA, network.getLinkType(LinkType.DEFAULTS.FREEWAY), sim,
526 LaneKeepingPolicy.KEEPLEFT, new OTSLine3D(coordsHalf1)).leftToRight(0.0, Length.instantiateSI(3.5), network
527 .getLaneType(LaneType.DEFAULTS.FREEWAY), speedLimit).addLanes(Permeable.BOTH).getLanes();
528 OTSPoint3D[] coordsHalf2 = new OTSPoint3D[127];
529 for (int i = 0; i < coordsHalf2.length; i++)
530 {
531 double angle = Math.PI + Math.PI * (i) / (coordsHalf2.length - 1);
532 coordsHalf2[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
533 }
534 List<Lane> lanes2 = new LaneFactory(network, nodeA, nodeB, network.getLinkType(LinkType.DEFAULTS.FREEWAY), sim,
535 LaneKeepingPolicy.KEEPLEFT, new OTSLine3D(coordsHalf2)).leftToRight(0.0, Length.instantiateSI(3.5), network
536 .getLaneType(LaneType.DEFAULTS.FREEWAY), speedLimit).addLanes(Permeable.BOTH).getLanes();
537
538
539 PerceptionFactory perceptionFactory = new LmrsStrategiesPerceptionFactory();
540
541 ParameterFactoryByType parameterFactory = new ParameterFactoryByType();
542 parameterFactory.addParameter(Tailgating.RHO, 0.0);
543 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), LmrsParameters.SOCIO, 0.5);
544 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), LmrsParameters.SOCIO, 1.0);
545 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), LmrsParameters.VGAIN, new Speed(35.0,
546 SpeedUnit.KM_PER_HOUR));
547 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), LmrsParameters.VGAIN, new Speed(50.0,
548 SpeedUnit.KM_PER_HOUR));
549 parameterFactory.addParameter(ParameterTypes.TMAX, Duration.instantiateSI(1.6));
550 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), ParameterTypes.FSPEED, new DistNormal(
551 this.stream, 123.7 / 120.0, 12.0 / 120.0));
552 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), ParameterTypes.A, Acceleration.instantiateSI(
553 0.4));
554 parameterFactory.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), ParameterTypes.FSPEED, 1.0);
555 for (GTUType gtuType : new GTUType[] {network.getGtuType(GTUType.DEFAULTS.CAR), network.getGtuType(
556 GTUType.DEFAULTS.TRUCK)})
557 {
558
559 Set<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
560 Set<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
561 Set<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
562 mandatoryIncentives.add(new IncentiveRoute());
563 voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
564 voluntaryIncentives.add(new IncentiveKeep());
565 voluntaryIncentives.add(new IncentiveSocioSpeed());
566 if (gtuType.equals(network.getGtuType(GTUType.DEFAULTS.TRUCK)))
567 {
568 voluntaryIncentives.add(new IncentiveStayRight());
569 }
570
571 CarFollowingModelFactory<?> cfFactory =
572 gtuType.equals(network.getGtuType(GTUType.DEFAULTS.CAR)) ? new SocioIDMFactory() : new IDMPlusFactory(
573 this.stream);
574
575 Tailgating tlgt = Tailgating.PRESSURE;
576
577 LaneBasedStrategicalPlannerFactory<?> laneBasedStrategicalPlannerFactory =
578 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(cfFactory, perceptionFactory,
579 Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, tlgt, mandatoryIncentives,
580 voluntaryIncentives, accelerationIncentives), parameterFactory);
581 this.factories.put(gtuType, laneBasedStrategicalPlannerFactory);
582 }
583 for (int i = 0; i < lanes1.size(); i++)
584 {
585 Length pos = Length.instantiateSI(10.0);
586 Length gap = lanes1.get(i).getLength().plus(lanes2.get(i).getLength()).divide(this.gtuNum / 2);
587 for (int j = 0; j < 2; j++)
588 {
589 Lane lane = j == 0 ? lanes1.get(i) : lanes2.get(i);
590 while (true)
591 {
592 GTUType gtuType;
593 if (i == 0)
594 {
595 gtuType = network.getGtuType(GTUType.DEFAULTS.CAR);
596 }
597 else
598 {
599 gtuType = this.stream.nextDouble() < 2 * this.truckFraction ? network.getGtuType(GTUType.DEFAULTS.TRUCK)
600 : network.getGtuType(GTUType.DEFAULTS.CAR);
601 }
602
603 Speed initialSpeed = Speed.ZERO;
604
605 createGtu(lane, pos, gtuType, initialSpeed, network);
606
607 pos = pos.plus(gap);
608 if (pos.si > lane.getLength().si)
609 {
610 pos = pos.minus(lane.getLength());
611 break;
612 }
613 }
614 }
615 }
616
617 this.nextGtuType = this.stream.nextDouble() < this.truckFraction ? network.getGtuType(GTUType.DEFAULTS.TRUCK) : network
618 .getGtuType(GTUType.DEFAULTS.CAR);
619 sim.scheduleEventNow(this, this, "checkVehicleNumber", new Object[] {});
620
621 return network;
622 }
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 public void createGtu(final Lane lane, final Length pos, final GTUType gtuType, final Speed initialSpeed,
638 final OTSRoadNetwork net) throws NamingException, GTUException, NetworkException, SimRuntimeException,
639 OTSGeometryException
640 {
641 GTUCharacteristics gtuCharacteristics = Try.assign(() -> GTUType.defaultCharacteristics(gtuType, net, this.stream),
642 "Exception while applying default GTU characteristics.");
643
644 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.gtuIdNum), gtuType, gtuCharacteristics.getLength(),
645 gtuCharacteristics.getWidth(), gtuCharacteristics.getMaximumSpeed(), gtuCharacteristics.getFront(), getSimulator(),
646 net);
647 gtu.setMaximumAcceleration(gtuCharacteristics.getMaximumAcceleration());
648 gtu.setMaximumDeceleration(gtuCharacteristics.getMaximumDeceleration());
649 gtu.setNoLaneChangeDistance(Length.instantiateSI(50));
650 gtu.setInstantaneousLaneChange(true);
651
652
653 LaneBasedStrategicalPlanner strategicalPlanner = this.factories.get(gtuType).create(gtu, null, null, null);
654
655
656 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
657 initialPositions.add(new DirectedLanePosition(lane, pos, GTUDirectionality.DIR_PLUS));
658 if (pos.plus(gtu.getFront().getDx()).gt(lane.getLength()))
659 {
660 Lane nextLane = lane.nextLanes(gtuType).keySet().iterator().next();
661 Length nextPos = pos.minus(lane.getLength());
662 initialPositions.add(new DirectedLanePosition(nextLane, nextPos, GTUDirectionality.DIR_PLUS));
663 }
664 if (pos.plus(gtu.getRear().getDx()).lt0())
665 {
666 Lane prevLane = lane.prevLanes(gtuType).keySet().iterator().next();
667 Length prevPos = prevLane.getLength().plus(pos.plus(gtu.getRear().getDx()));
668 initialPositions.add(new DirectedLanePosition(prevLane, prevPos, GTUDirectionality.DIR_PLUS));
669 }
670 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
671
672 if (this.kmplcListener != null)
673 {
674 Try.execute(() -> gtu.addListener(this.kmplcListener, LaneBasedGTU.LANE_CHANGE_EVENT),
675 "Exception while adding lane change listener");
676 }
677 }
678
679
680 class SocioIDMFactory implements CarFollowingModelFactory<IDMPlus>
681 {
682
683 @Override
684 public Parameters getParameters() throws ParameterException
685 {
686 ParameterSet parameters = new ParameterSet();
687 parameters.setDefaultParameters(AbstractIDM.class);
688 return parameters;
689 }
690
691
692 @Override
693 public IDMPlus generateCarFollowingModel()
694 {
695 return new IDMPlus(AbstractIDM.HEADWAY, new SocioDesiredSpeed(AbstractIDM.DESIRED_SPEED));
696 }
697 }
698
699
700 class LmrsStrategiesPerceptionFactory implements PerceptionFactory
701 {
702
703 @Override
704 public LanePerception generatePerception(final LaneBasedGTU gtu)
705 {
706 LanePerception perception = new CategoricalLanePerception(gtu);
707 perception.addPerceptionCategory(new DirectEgoPerception<>(perception));
708 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
709 perception.addPerceptionCategory(new DirectNeighborsPerception(perception, HeadwayGtuType.WRAP));
710 perception.addPerceptionCategory(new AnticipationTrafficPerception(perception));
711 return perception;
712 }
713
714
715 @Override
716 public Parameters getParameters() throws ParameterException
717 {
718 return new ParameterSet().setDefaultParameter(ParameterTypes.LOOKAHEAD).setDefaultParameter(
719 ParameterTypes.LOOKBACKOLD).setDefaultParameter(ParameterTypes.PERCEPTION).setDefaultParameter(
720 ParameterTypes.LOOKBACK);
721 }
722 }
723
724 }