View Javadoc
1   package org.opentrafficsim.demo.carFollowing;
2   
3   import static org.opentrafficsim.core.gtu.GTUType.CAR;
4   import static org.opentrafficsim.core.gtu.GTUType.TRUCK;
5   
6   import java.io.InputStream;
7   import java.rmi.RemoteException;
8   import java.util.ArrayList;
9   import java.util.HashMap;
10  import java.util.LinkedHashSet;
11  import java.util.List;
12  import java.util.Map;
13  import java.util.Random;
14  import java.util.Set;
15  
16  import org.djunits.unit.AccelerationUnit;
17  import org.djunits.unit.DurationUnit;
18  import org.djunits.unit.FrequencyUnit;
19  import org.djunits.unit.LengthUnit;
20  import org.djunits.unit.SpeedUnit;
21  import org.djunits.value.vdouble.scalar.Acceleration;
22  import org.djunits.value.vdouble.scalar.Duration;
23  import org.djunits.value.vdouble.scalar.Frequency;
24  import org.djunits.value.vdouble.scalar.Length;
25  import org.djunits.value.vdouble.scalar.Speed;
26  import org.djunits.value.vdouble.scalar.Time;
27  import org.opentrafficsim.base.modelproperties.Property;
28  import org.opentrafficsim.base.parameters.ParameterException;
29  import org.opentrafficsim.base.parameters.ParameterSet;
30  import org.opentrafficsim.base.parameters.ParameterTypes;
31  import org.opentrafficsim.core.distributions.ConstantGenerator;
32  import org.opentrafficsim.core.distributions.Distribution;
33  import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
34  import org.opentrafficsim.core.distributions.Generator;
35  import org.opentrafficsim.core.distributions.ProbabilityException;
36  import org.opentrafficsim.core.dsol.OTSModelInterface;
37  import org.opentrafficsim.core.gtu.GTUDirectionality;
38  import org.opentrafficsim.core.gtu.GTUException;
39  import org.opentrafficsim.core.gtu.GTUType;
40  import org.opentrafficsim.core.gtu.animation.GTUColorer;
41  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactory;
42  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactoryByType;
43  import org.opentrafficsim.core.idgenerator.IdGenerator;
44  import org.opentrafficsim.core.network.LongitudinalDirectionality;
45  import org.opentrafficsim.core.network.NetworkException;
46  import org.opentrafficsim.core.network.OTSLink;
47  import org.opentrafficsim.core.network.OTSNetwork;
48  import org.opentrafficsim.core.network.OTSNode;
49  import org.opentrafficsim.core.network.route.ProbabilisticRouteGenerator;
50  import org.opentrafficsim.core.network.route.Route;
51  import org.opentrafficsim.core.network.route.RouteGenerator;
52  import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
53  import org.opentrafficsim.road.animation.AnimationToggles;
54  import org.opentrafficsim.road.gtu.animation.LmrsSwitchableColorer;
55  import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
56  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
57  import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
58  import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
59  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
60  import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
61  import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
62  import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
63  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
64  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
65  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
66  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationConflicts;
67  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationIncentive;
68  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationSpeedLimitTransition;
69  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationTrafficLights;
70  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
71  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveCourtesy;
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.LMRS;
77  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
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.route.LaneBasedStrategicalRoutePlannerFactory;
86  import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
87  import org.opentrafficsim.road.network.lane.CrossSectionLink;
88  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
89  import org.opentrafficsim.road.network.lane.Lane;
90  import org.opentrafficsim.road.network.lane.object.SpeedSign;
91  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
92  import org.opentrafficsim.simulationengine.OTSSimulationException;
93  
94  import nl.tudelft.simulation.dsol.SimRuntimeException;
95  import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
96  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
97  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
98  import nl.tudelft.simulation.jstats.distributions.DistNormal;
99  import nl.tudelft.simulation.jstats.distributions.DistUniform;
100 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
101 import nl.tudelft.simulation.jstats.streams.StreamInterface;
102 import nl.tudelft.simulation.language.io.URLResource;
103 
104 /**
105  * <p>
106  * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
107  * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
108  * <p>
109  * @version $Revision$, $LastChangedDate$, by $Author$, initial version 7 apr. 2017 <br>
110  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
111  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
112  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
113  */
114 public class ShortMerge extends AbstractWrappableAnimation
115 {
116 
117     /** Network. */
118     static final String NETWORK = "shortWeave";
119 
120     /** Truck fraction. */
121     static final double TRUCK_FRACTION = 0.15;
122 
123     /** Left traffic fraction. */
124     static final double LEFT_FRACTION = 0.3;
125 
126     /** Main demand. */
127     static final Frequency MAIN_DEMAND = new Frequency(1000, FrequencyUnit.PER_HOUR);
128 
129     /** Ramp demand. */
130     static final Frequency RAMP_DEMAND = new Frequency(200, FrequencyUnit.PER_HOUR);
131 
132     /** Synchronization. */
133     static final Synchronization SYNCHRONIZATION = Synchronization.PASSIVE_MOVING;
134 
135     /** Cooperation. */
136     static final Cooperation COOPERATION = Cooperation.PASSIVE_MOVING;
137 
138     /** Use additional incentives. */
139     static final boolean ADDITIONAL_INCENTIVES = true;
140 
141     /** Simulation time. */
142     public static final Time SIMTIME = Time.createSI(3600);
143 
144     /** */
145     private static final long serialVersionUID = 20170407L;
146 
147     /** Colorer. */
148     private GTUColorer colorer = new LmrsSwitchableColorer();
149 
150     /** The simulator. */
151     private DEVSSimulatorInterface.TimeDoubleUnit simulator;
152 
153     /** {@inheritDoc} */
154     @Override
155     public final String shortName()
156     {
157         return "ShortMerge";
158     }
159 
160     /** {@inheritDoc} */
161     @Override
162     public final String description()
163     {
164         return "Short merge to test lane change models.";
165     }
166 
167     /** {@inheritDoc} */
168     @Override
169     protected final void addAnimationToggles()
170     {
171         AnimationToggles.setIconAnimationTogglesFull(this);
172         toggleAnimationClass(OTSLink.class);
173         toggleAnimationClass(OTSNode.class);
174         showAnimationClass(SpeedSign.class);
175     }
176 
177     /** {@inheritDoc} */
178     @Override
179     public GTUColorer getColorer()
180     {
181         return this.colorer;
182     }
183 
184     /** {@inheritDoc} */
185     @Override
186     protected OTSModelInterface makeModel() throws OTSSimulationException
187     {
188         return new ShortMergeModel();
189     }
190 
191     /**
192      * @return simulator.
193      */
194     public final DEVSSimulatorInterface.TimeDoubleUnit getSimulator()
195     {
196         return this.simulator;
197     }
198 
199     /**
200      * @param simulator set simulator.
201      */
202     public final void setSimulator(final DEVSSimulatorInterface.TimeDoubleUnit simulator)
203     {
204         this.simulator = simulator;
205     }
206 
207     /**
208      * Main method.
209      * @param args args for main program
210      */
211     public static void main(final String[] args)
212     {
213 
214         ShortMerge shortMerge = new ShortMerge();
215         try
216         {
217             shortMerge.buildAnimator(Time.ZERO, Duration.ZERO, Duration.createSI(SIMTIME.si), new ArrayList<Property<?>>(),
218                     null, true);
219         }
220         catch (Exception exception)
221         {
222             exception.printStackTrace();
223         }
224 
225     }
226 
227     /**
228      * <p>
229      * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
230      * <br>
231      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
232      * <p>
233      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 7 apr. 2017 <br>
234      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
235      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
236      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
237      */
238     class ShortMergeModel implements OTSModelInterface
239     {
240 
241         /**
242          * @param network set network.
243          */
244         public void setNetwork(final OTSNetwork network)
245         {
246             this.network = network;
247         }
248 
249         /** */
250         private static final long serialVersionUID = 20170407L;
251 
252         /** The network. */
253         private OTSNetwork network;
254 
255         /** {@inheritDoc} */
256         @Override
257         public void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> theSimulator)
258                 throws SimRuntimeException
259         {
260             ShortMerge.this.setSimulator((DEVSSimulatorInterface.TimeDoubleUnit) theSimulator);
261 
262             try
263             {
264                 InputStream stream = URLResource.getResourceAsStream("/lmrs/" + NETWORK + ".xml");
265                 XmlNetworkLaneParser nlp = new XmlNetworkLaneParser((DEVSSimulatorInterface.TimeDoubleUnit) theSimulator);
266                 this.network = new OTSNetwork("ShortMerge");
267                 nlp.build(stream, this.network, false);
268 
269                 addGenerator();
270 
271             }
272             catch (Exception exception)
273             {
274                 exception.printStackTrace();
275             }
276         }
277 
278         /** {@inheritDoc} */
279         @Override
280         public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
281         {
282             return ShortMerge.this.getSimulator();
283         }
284 
285         /** {@inheritDoc} */
286         @Override
287         public OTSNetwork getNetwork()
288         {
289             return this.network;
290         }
291 
292         /**
293          * Create generators.
294          * @throws ParameterException on parameter exception
295          * @throws GTUException on GTU exception
296          * @throws NetworkException if not does not exist
297          * @throws ProbabilityException negative probability
298          * @throws SimRuntimeException in case of sim run time exception
299          * @throws RemoteException if no simulator
300          */
301         private void addGenerator() throws ParameterException, GTUException, NetworkException, ProbabilityException,
302                 SimRuntimeException, RemoteException
303         {
304 
305             Random seedGenerator = new Random(1L);
306             Map<String, StreamInterface> streams = new HashMap<>();
307             StreamInterface stream = new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1);
308             streams.put("headwayGeneration", stream);
309             streams.put("gtuClass", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
310             this.getSimulator().getReplication().setStreams(streams);
311 
312             TTCRoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
313             IdGenerator idGenerator = new IdGenerator("");
314 
315             CarFollowingModelFactory<IDMPlus> idmPlusFactory = new IDMPlusFactory(streams.get("gtuClass"));
316             ParameterSet params = new ParameterSet();
317             params.setDefaultParameter(AbstractIDM.DELTA);
318 
319             Set<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
320             Set<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
321             Set<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
322             mandatoryIncentives.add(new IncentiveRoute());
323             if (ADDITIONAL_INCENTIVES)
324             {
325                 // mandatoryIncentives.add(new IncentiveGetInLane());
326             }
327             voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
328             voluntaryIncentives.add(new IncentiveKeep());
329             if (ADDITIONAL_INCENTIVES)
330             {
331                 voluntaryIncentives.add(new IncentiveCourtesy());
332                 voluntaryIncentives.add(new IncentiveSocioSpeed());
333             }
334             accelerationIncentives.add(new AccelerationSpeedLimitTransition());
335             accelerationIncentives.add(new AccelerationTrafficLights());
336             accelerationIncentives.add(new AccelerationConflicts());
337             LaneBasedTacticalPlannerFactory<LMRS> tacticalFactory = new LMRSFactory(idmPlusFactory,
338                     new DefaultLMRSPerceptionFactory(), SYNCHRONIZATION, COOPERATION, GapAcceptance.INFORMED, Tailgating.NONE,
339                     mandatoryIncentives, voluntaryIncentives, accelerationIncentives);
340 
341             GTUType car = new GTUType("car", CAR);
342             GTUType truck = new GTUType("truck", TRUCK);
343             Route routeAE = this.network.getShortestRouteBetween(car, this.network.getNode("A"), this.network.getNode("E"));
344             Route routeAG = !NETWORK.equals("shortWeave") ? null
345                     : this.network.getShortestRouteBetween(car, this.network.getNode("A"), this.network.getNode("G"));
346             Route routeFE = this.network.getShortestRouteBetween(car, this.network.getNode("F"), this.network.getNode("E"));
347             Route routeFG = !NETWORK.equals("shortWeave") ? null
348                     : this.network.getShortestRouteBetween(car, this.network.getNode("F"), this.network.getNode("G"));
349 
350             double leftFraction = NETWORK.equals("shortWeave") ? LEFT_FRACTION : 0.0;
351             List<FrequencyAndObject<Route>> routesA = new ArrayList<>();
352             routesA.add(new FrequencyAndObject<>(1.0 - leftFraction, routeAE));
353             routesA.add(new FrequencyAndObject<>(leftFraction, routeAG));
354             List<FrequencyAndObject<Route>> routesF = new ArrayList<>();
355             routesF.add(new FrequencyAndObject<>(1.0 - leftFraction, routeFE));
356             routesF.add(new FrequencyAndObject<>(leftFraction, routeFG));
357             RouteGenerator routeGeneratorA = new ProbabilisticRouteGenerator(routesA, stream);
358             RouteGenerator routeGeneratorF = new ProbabilisticRouteGenerator(routesF, stream);
359 
360             Speed speedA = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
361             Speed speedF = new Speed(20.0, SpeedUnit.KM_PER_HOUR);
362 
363             CrossSectionLink linkA = (CrossSectionLink) this.network.getLink("AB");
364             CrossSectionLink linkF = (CrossSectionLink) this.network.getLink("FF2");
365 
366             ParameterFactoryByType bcFactory = new ParameterFactoryByType();
367             bcFactory.addParameter(car, ParameterTypes.FSPEED, new DistNormal(stream, 123.7 / 120, 12.0 / 120));
368             bcFactory.addParameter(car, LmrsParameters.SOCIO, new DistNormal(stream, 0.5, 0.1));
369             bcFactory.addParameter(truck, ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.SI));
370             bcFactory.addParameter(truck, LmrsParameters.SOCIO, new DistNormal(stream, 0.5, 0.1));
371             bcFactory.addParameter(Tailgating.RHO, Tailgating.RHO.getDefaultValue());
372 
373             Generator<Duration> headwaysA1 = new HeadwayGenerator(MAIN_DEMAND);
374             Generator<Duration> headwaysA2 = new HeadwayGenerator(MAIN_DEMAND);
375             Generator<Duration> headwaysA3 = new HeadwayGenerator(MAIN_DEMAND);
376             Generator<Duration> headwaysF = new HeadwayGenerator(RAMP_DEMAND);
377 
378             // speed generators
379             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
380                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(stream, 160, 200), SpeedUnit.KM_PER_HOUR);
381             ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
382                     new ContinuousDistDoubleScalar.Rel<>(new DistUniform(stream, 80, 95), SpeedUnit.KM_PER_HOUR);
383             // strategical planner factory
384             LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
385                     new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, bcFactory);
386             // vehicle templates, with routes
387             LaneBasedTemplateGTUType carA =
388                     new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
389                             new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, routeGeneratorA);
390             LaneBasedTemplateGTUType carF =
391                     new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
392                             new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, routeGeneratorF);
393             LaneBasedTemplateGTUType truckA =
394                     new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK), new ConstantGenerator<>(Length.createSI(15.0)),
395                             new ConstantGenerator<>(Length.createSI(2.5)), speedTruck, strategicalFactory, routeGeneratorA);
396             LaneBasedTemplateGTUType truckF =
397                     new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK), new ConstantGenerator<>(Length.createSI(15.0)),
398                             new ConstantGenerator<>(Length.createSI(2.5)), speedTruck, strategicalFactory, routeGeneratorF);
399             //
400             Distribution<LaneBasedTemplateGTUType> gtuTypeAllCarA = new Distribution<>(streams.get("gtuClass"));
401             gtuTypeAllCarA.add(new FrequencyAndObject<>(1.0, carA));
402 
403             Distribution<LaneBasedTemplateGTUType> gtuType1LaneF = new Distribution<>(streams.get("gtuClass"));
404             gtuType1LaneF.add(new FrequencyAndObject<>(1.0 - 2 * TRUCK_FRACTION, carF));
405             gtuType1LaneF.add(new FrequencyAndObject<>(2 * TRUCK_FRACTION, truckF));
406 
407             Distribution<LaneBasedTemplateGTUType> gtuType2ndLaneA = new Distribution<>(streams.get("gtuClass"));
408             gtuType2ndLaneA.add(new FrequencyAndObject<>(1.0 - 2 * TRUCK_FRACTION, carA));
409             gtuType2ndLaneA.add(new FrequencyAndObject<>(2 * TRUCK_FRACTION, truckA));
410 
411             Distribution<LaneBasedTemplateGTUType> gtuType3rdLaneA = new Distribution<>(streams.get("gtuClass"));
412             gtuType3rdLaneA.add(new FrequencyAndObject<>(1.0 - 3 * TRUCK_FRACTION, carA));
413             gtuType3rdLaneA.add(new FrequencyAndObject<>(3 * TRUCK_FRACTION, truckA));
414 
415             GTUColorer color = ShortMerge.this.getColorer();
416             makeGenerator(getLane(linkA, "FORWARD1"), speedA, "gen1", idGenerator, gtuTypeAllCarA, headwaysA1, color,
417                     roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
418             if (NETWORK.equals("shortWeave"))
419             {
420                 makeGenerator(getLane(linkA, "FORWARD2"), speedA, "gen2", idGenerator, gtuTypeAllCarA, headwaysA2, color,
421                         roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
422                 makeGenerator(getLane(linkA, "FORWARD3"), speedA, "gen3", idGenerator, gtuType3rdLaneA, headwaysA3, color,
423                         roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
424             }
425             else
426             {
427                 makeGenerator(getLane(linkA, "FORWARD2"), speedA, "gen2", idGenerator, gtuType2ndLaneA, headwaysA2, color,
428                         roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
429             }
430             makeGenerator(getLane(linkF, "FORWARD1"), speedF, "gen4", idGenerator, gtuType1LaneF, headwaysF, color, roomChecker,
431                     bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
432 
433             new SpeedSign("sign1", getLane(linkA, "FORWARD1"), LongitudinalDirectionality.DIR_PLUS, Length.createSI(10),
434                     (SimulatorInterface.TimeDoubleUnit) this.getSimulator(), new Speed(130.0, SpeedUnit.KM_PER_HOUR));
435 
436         }
437 
438         /**
439          * Get lane from link by id.
440          * @param link link
441          * @param id id
442          * @return lane
443          */
444         private Lane getLane(final CrossSectionLink link, final String id)
445         {
446             return (Lane) link.getCrossSectionElement(id);
447         }
448 
449         /**
450          * @param lane the reference lane for this generator
451          * @param generationSpeed the speed of the GTU
452          * @param id the id of the generator itself
453          * @param idGenerator the generator for the ID
454          * @param distribution the type generator for the GTU
455          * @param headwayGenerator the headway generator for the GTU
456          * @param gtuColorer the GTU colorer for animation
457          * @param roomChecker the checker to see if there is room for the GTU
458          * @param bcFactory the factory to generate parameters for the GTU
459          * @param tacticalFactory the generator for the tactical planner
460          * @param simulationTime simulation time
461          * @param stream random numbers stream
462          * @throws SimRuntimeException in case of scheduling problems
463          * @throws ProbabilityException in case of an illegal probability distribution
464          * @throws GTUException in case the GTU is inconsistent
465          * @throws ParameterException in case a parameter for the perception is missing
466          */
467         private void makeGenerator(final Lane lane, final Speed generationSpeed, final String id, final IdGenerator idGenerator,
468                 final Distribution<LaneBasedTemplateGTUType> distribution, final Generator<Duration> headwayGenerator,
469                 final GTUColorer gtuColorer, final RoomChecker roomChecker, final ParameterFactory bcFactory,
470                 final LaneBasedTacticalPlannerFactory<?> tacticalFactory, final Time simulationTime,
471                 final StreamInterface stream) throws SimRuntimeException, ProbabilityException, GTUException, ParameterException
472         {
473 
474             Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
475             // TODO DIR_MINUS
476             initialLongitudinalPositions
477                     .add(new DirectedLanePosition(lane, new Length(5.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
478             LaneBasedTemplateGTUTypeDistribution characteristicsGenerator =
479                     new LaneBasedTemplateGTUTypeDistribution(distribution);
480             new LaneBasedGTUGenerator(id, headwayGenerator, gtuColorer, characteristicsGenerator,
481                     GeneratorPositions.create(initialLongitudinalPositions, stream), this.network,
482                     ShortMerge.this.getSimulator(), roomChecker, idGenerator);
483         }
484 
485     }
486 
487     /**
488      * <p>
489      * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
490      * <br>
491      * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
492      * <p>
493      * @version $Revision$, $LastChangedDate$, by $Author$, initial version 29 jan. 2017 <br>
494      * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
495      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
496      * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
497      */
498     private class HeadwayGenerator implements Generator<Duration>
499     {
500 
501         /** Demand level. */
502         private final Frequency demand;
503 
504         /**
505          * @param demand demand
506          */
507         HeadwayGenerator(final Frequency demand)
508         {
509             this.demand = demand;
510         }
511 
512         /** {@inheritDoc} */
513         @Override
514         public Duration draw() throws ProbabilityException, ParameterException
515         {
516             return new Duration(
517                     -Math.log(ShortMerge.this.getSimulator().getReplication().getStream("headwayGeneration").nextDouble())
518                             / this.demand.si,
519                     DurationUnit.SI);
520         }
521 
522     }
523 
524 }