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