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