1 package org.opentrafficsim.road.network.lane.object.trafficlight;
2
3 import java.util.LinkedHashSet;
4 import java.util.Set;
5
6 import org.djunits.unit.LengthUnit;
7 import org.djunits.value.vdouble.scalar.Length;
8 import org.djunits.value.vdouble.scalar.Time;
9 import org.djutils.event.EventType;
10 import org.djutils.metadata.MetaData;
11 import org.djutils.metadata.ObjectDescriptor;
12 import org.opentrafficsim.core.gtu.GtuType;
13 import org.opentrafficsim.core.network.Link;
14 import org.opentrafficsim.core.network.NetworkException;
15 import org.opentrafficsim.core.network.Node;
16 import org.opentrafficsim.core.network.route.Route;
17 import org.opentrafficsim.core.perception.Historical;
18 import org.opentrafficsim.core.perception.HistoricalValue;
19 import org.opentrafficsim.road.network.lane.Lane;
20 import org.opentrafficsim.road.network.lane.object.AbstractLaneBasedObject;
21 import org.opentrafficsim.road.network.lane.object.LaneBasedObject;
22
23
24
25
26
27
28
29
30
31
32
33 public class TrafficLight extends AbstractLaneBasedObject
34 {
35
36 private static final long serialVersionUID = 20230216L;
37
38
39 private final Historical<TrafficLightColor> trafficLightColor;
40
41
42 private Set<Node> turnOnRed = null;
43
44
45 public static final Length DEFAULT_TRAFFICLIGHT_ELEVATION = new Length(1, LengthUnit.METER);
46
47
48
49
50
51 public static final EventType TRAFFICLIGHT_CHANGE_EVENT = new EventType("TRAFFICLIGHT.CHANGE",
52 new MetaData("Traffic light changed", "Color of traffic light has changed",
53 new ObjectDescriptor("Traffic light id", "Id of the traffic light", String.class),
54 new ObjectDescriptor("Traffic light", "The traffic light itself", TrafficLight.class),
55 new ObjectDescriptor("Traffic light color", "New traffic light color", TrafficLightColor.class)));
56
57
58
59
60
61
62
63
64
65 public TrafficLight(final String id, final Lane lane, final Length longitudinalPosition, final Length height)
66 throws NetworkException
67 {
68 super(id, lane, longitudinalPosition, LaneBasedObject.makeLine(lane, longitudinalPosition), height);
69 this.trafficLightColor = new HistoricalValue<>(getSimulator().getReplication().getHistoryManager(getSimulator()), this,
70 TrafficLightColor.RED);
71 init();
72 }
73
74
75
76
77
78
79
80
81 public TrafficLight(final String id, final Lane lane, final Length longitudinalPosition) throws NetworkException
82 {
83 this(id, lane, longitudinalPosition, DEFAULT_TRAFFICLIGHT_ELEVATION);
84 }
85
86
87
88
89
90 public final TrafficLightColor getTrafficLightColor()
91 {
92 return this.trafficLightColor.get();
93 }
94
95
96
97
98
99
100 public final TrafficLightColor getTrafficLightColor(final Time time)
101 {
102 return this.trafficLightColor.get(time);
103 }
104
105
106
107
108
109 public final void setTrafficLightColor(final TrafficLightColor trafficLightColor)
110 {
111 this.trafficLightColor.set(trafficLightColor);
112 fireTimedEvent(TRAFFICLIGHT_CHANGE_EVENT, new Object[] {getId(), this, trafficLightColor},
113 getSimulator().getSimulatorTime());
114 }
115
116
117
118
119
120 public void addTurnOnRed(final Node node)
121 {
122 if (this.turnOnRed == null)
123 {
124 this.turnOnRed = new LinkedHashSet<>();
125 }
126 this.turnOnRed.add(node);
127 }
128
129
130
131
132
133
134
135 public boolean canTurnOnRed(final Route route, final GtuType gtuType)
136 {
137 if (this.turnOnRed == null)
138 {
139 return false;
140 }
141 try
142 {
143
144 Link link = this.getLane().getLink();
145 Set<Link> next = link.getEndNode().nextLinks(gtuType, link);
146 while (next.size() == 1)
147 {
148 link = next.iterator().next();
149 next = link.getEndNode().nextLinks(gtuType, link);
150 }
151
152 Node endNode = link.getEndNode();
153 int nodeIndex = route.indexOf(endNode);
154 if (nodeIndex < 0 || nodeIndex == route.size() - 1)
155 {
156 return false;
157 }
158 return this.turnOnRed.contains(route.getNode(nodeIndex + 1));
159 }
160 catch (NetworkException ex)
161 {
162
163 throw new RuntimeException(ex);
164 }
165 }
166
167 @Override
168 @SuppressWarnings("checkstyle:designforextension")
169 public String toString()
170 {
171 return "TrafficLight [trafficLightColor=" + getTrafficLightColor() + "]";
172 }
173
174 }