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 }