View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.util;
2   
3   import static org.opentrafficsim.core.gtu.behavioralcharacteristics.AbstractParameterType.Check.POSITIVE;
4   
5   import java.util.Set;
6   import java.util.SortedMap;
7   import java.util.TreeMap;
8   
9   import org.djunits.unit.AccelerationUnit;
10  import org.djunits.value.vdouble.scalar.Acceleration;
11  import org.djunits.value.vdouble.scalar.Length;
12  import org.djunits.value.vdouble.scalar.Speed;
13  import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
14  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterException;
15  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypeAcceleration;
16  import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
17  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayTrafficLight;
18  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
19  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
20  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
21  
22  import nl.tudelft.simulation.language.Throw;
23  
24  /**
25   * Static methods regarding traffic lights for composition in tactical planners.
26   * <p>
27   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
28   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
29   * <p>
30   * @version $Revision$, $LastChangedDate$, by $Author$, initial version May 13, 2016 <br>
31   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
32   */
33  public final class TrafficLightUtil
34  {
35      /** Maximum deceleration for stopping for yellow traffic light. */
36      public static final ParameterTypeAcceleration B_YELLOW = new ParameterTypeAcceleration("bYellow",
37          "Maximum deceleration for stopping for yellow traffic light.", new Acceleration(3.5, AccelerationUnit.SI), POSITIVE);
38  
39      /**
40       * Do not instantiate.
41       */
42      private TrafficLightUtil()
43      {
44          //
45      }
46  
47      /**
48       * Returns an acceleration as response to a set of traffic lights, being positive infinity if ignored. The response is
49       * governed by the car-following model in case a traffic light is yellow or red. A constant deceleration to stop is also
50       * calculated, and the highest acceleration of both is used. If this value is below -bYellow (B_YELLOW), the traffic light
51       * is ignored, which usually occurs only during the yellow phase. By using the highest acceleration of the car-following
52       * model and the constant deceleration, it is ensured that comfortable deceleration is applied if approaching a red traffic
53       * light from far away, while strong deceleration is only applied if required and appropriately represents stopping for
54       * yellow.
55       * @param behavioralCharacteristics behavioral characteristics
56       * @param headwayTrafficLights set of headway traffic lights
57       * @param carFollowingModel car following model
58       * @param speed speed
59       * @param speedLimitInfo speed limit info
60       * @return acceleration as response to a traffic light, being positive infinity if ignored
61       * @throws ParameterException if a parameter is not defined
62       * @throws NullPointerException if any input is null
63       * @throws IllegalArgumentException if the traffic light is not downstream
64       */
65      public static Acceleration respondToTrafficLights(final BehavioralCharacteristics behavioralCharacteristics,
66          final Set<HeadwayTrafficLight> headwayTrafficLights, final CarFollowingModel carFollowingModel, final Speed speed,
67          final SpeedLimitInfo speedLimitInfo) throws ParameterException
68      {
69          Throw.whenNull(headwayTrafficLights, "Traffic light set may not be null.");
70          Acceleration a = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
71          for (HeadwayTrafficLight headwayTrafficLight : headwayTrafficLights)
72          {
73              Acceleration aLight =
74                  respondToTrafficLight(behavioralCharacteristics, headwayTrafficLight, carFollowingModel, speed,
75                      speedLimitInfo);
76              a = Acceleration.min(a, aLight);
77          }
78          return a;
79      }  
80      
81      /**
82       * Returns an acceleration as response to a traffic light, being positive infinity if ignored. The response is governed by
83       * the car-following model in case the traffic light is yellow or red. A constant deceleration to stop is also calculated,
84       * and the highest acceleration of both is used. If this value is below -bYellow (B_YELLOW), the traffic light is ignored,
85       * which usually occurs only during the yellow phase. By using the highest acceleration of the car-following model and the
86       * constant deceleration, it is ensured that comfortable deceleration is applied if approaching a red traffic light from far
87       * away, while strong deceleration is only applied if required and appropriately represents stopping for yellow.
88       * @param behavioralCharacteristics behavioral characteristics
89       * @param headwayTrafficLight headway traffic light
90       * @param carFollowingModel car following model
91       * @param speed speed
92       * @param speedLimitInfo speed limit info
93       * @return acceleration as response to a traffic light, being positive infinity if ignored
94       * @throws ParameterException if a parameter is not defined
95       * @throws NullPointerException if any input is null
96       * @throws IllegalArgumentException if the traffic light is not downstream
97       */
98      public static Acceleration respondToTrafficLight(final BehavioralCharacteristics behavioralCharacteristics,
99          final HeadwayTrafficLight headwayTrafficLight, final CarFollowingModel carFollowingModel, final Speed speed,
100         final SpeedLimitInfo speedLimitInfo) throws ParameterException
101     {
102         Throw.whenNull(behavioralCharacteristics, "Behavioral characteristics may not be null.");
103         Throw.whenNull(headwayTrafficLight, "Traffic light may not be null.");
104         Throw.whenNull(carFollowingModel, "Car-following model may not be null.");
105         Throw.whenNull(speed, "Speed may not be null.");
106         Throw.whenNull(speedLimitInfo, "Speed limit info may not be null.");
107         Throw.when(!headwayTrafficLight.isAhead(), IllegalArgumentException.class, "Traffic light must be downstream.");
108         if (headwayTrafficLight.getTrafficLightColor().isRed()
109             || headwayTrafficLight.getTrafficLightColor().isYellow())
110         {
111             // deceleration from car-following model
112             SortedMap<Length, Speed> leaders = new TreeMap<>();
113             leaders.put(headwayTrafficLight.getDistance(), Speed.ZERO);
114             Acceleration a =
115                 carFollowingModel.followingAcceleration(behavioralCharacteristics, speed, speedLimitInfo, leaders);
116             // compare to constant deceleration
117             Length s0 = behavioralCharacteristics.getParameter(ParameterTypes.S0);
118             if (headwayTrafficLight.getDistance().gt(s0)) // constant acceleration not applicable if within s0
119             {
120                 // constant acceleration is -.5*v^2/s, where s = distance-s0 > 0
121                 Acceleration aConstant =
122                     new Acceleration(-0.5 * speed.si * speed.si / (headwayTrafficLight.getDistance().si - s0.si),
123                         AccelerationUnit.SI);
124                 a = Acceleration.max(a, aConstant);
125             }
126             // return a if a > -b
127             if (a.gt(behavioralCharacteristics.getParameter(B_YELLOW).neg()))
128             {
129                 return a;
130             }
131         }
132         // ignore traffic light
133         return new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
134     }
135 
136 }