1 package org.opentrafficsim.road.gtu.lane.plan.operational;
2
3 import java.io.Serializable;
4
5 import org.djunits.value.vdouble.scalar.Acceleration;
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.opentrafficsim.core.gtu.GTU;
8 import org.opentrafficsim.core.gtu.GTUException;
9 import org.opentrafficsim.core.gtu.TurnIndicatorIntent;
10 import org.opentrafficsim.core.gtu.TurnIndicatorStatus;
11 import org.opentrafficsim.core.network.LateralDirectionality;
12
13 import nl.tudelft.simulation.language.Throw;
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public class SimpleOperationalPlan implements Serializable
28 {
29
30
31 private static final long serialVersionUID = 20160811L;
32
33
34 private Acceleration acceleration;
35
36
37 private final LateralDirectionality laneChangeDirection;
38
39
40 private TurnIndicatorIntent indicatorIntent = TurnIndicatorIntent.NONE;
41
42
43 private Length indicatorObjectDistance = null;
44
45
46
47
48 public SimpleOperationalPlan(final Acceleration acceleration)
49 {
50 this(acceleration, LateralDirectionality.NONE);
51 }
52
53
54
55
56
57 public SimpleOperationalPlan(final Acceleration acceleration, final LateralDirectionality laneChangeDirection)
58 {
59 Throw.whenNull(acceleration, "Acceleration may not be null.");
60 Throw.whenNull(laneChangeDirection, "Lane change direction may not be null.");
61 checkAcceleration(acceleration);
62 this.acceleration = acceleration;
63 this.laneChangeDirection = laneChangeDirection;
64 }
65
66
67
68
69 public final Acceleration getAcceleration()
70 {
71 return this.acceleration;
72 }
73
74
75
76
77 public final boolean isLaneChange()
78 {
79 return this.laneChangeDirection != LateralDirectionality.NONE;
80 }
81
82
83
84
85 public final LateralDirectionality getLaneChangeDirection()
86 {
87 return this.laneChangeDirection;
88 }
89
90
91
92
93
94 public final void minimizeAcceleration(final Acceleration a)
95 {
96 checkAcceleration(a);
97 this.acceleration = Acceleration.min(this.acceleration, a);
98 }
99
100
101
102
103
104 private void checkAcceleration(final Acceleration a)
105 {
106 if (a.equals(Acceleration.NEGATIVE_INFINITY) || a.equals(Acceleration.NEG_MAXVALUE))
107 {
108 throw new RuntimeException("Model has calcalated a negative infinite or negative max value acceleration.");
109 }
110 }
111
112
113
114
115 public final TurnIndicatorIntent getIndicatorIntent()
116 {
117 return this.indicatorIntent;
118 }
119
120
121
122
123 public final void setIndicatorIntentLeft()
124 {
125 if (this.indicatorObjectDistance != null)
126 {
127 return;
128 }
129 if (this.indicatorIntent.isRight())
130 {
131 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
132 }
133 else
134 {
135 this.indicatorIntent = TurnIndicatorIntent.LEFT;
136 }
137 }
138
139
140
141
142 public final void setIndicatorIntentRight()
143 {
144 if (this.indicatorObjectDistance != null)
145 {
146 return;
147 }
148 if (this.indicatorIntent.isLeft())
149 {
150 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
151 }
152 else
153 {
154 this.indicatorIntent = TurnIndicatorIntent.RIGHT;
155 }
156 }
157
158
159
160
161
162 public final void setIndicatorIntentLeft(final Length distance)
163 {
164 if (compareAndIgnore(distance))
165 {
166 return;
167 }
168 if (this.indicatorIntent.isRight())
169 {
170 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
171 }
172 else
173 {
174 this.indicatorIntent = TurnIndicatorIntent.LEFT;
175 }
176
177 }
178
179
180
181
182
183 public final void setIndicatorIntentRight(final Length distance)
184 {
185 if (compareAndIgnore(distance))
186 {
187 return;
188 }
189 if (this.indicatorIntent.isLeft())
190 {
191 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
192 }
193 else
194 {
195 this.indicatorIntent = TurnIndicatorIntent.RIGHT;
196 }
197 }
198
199
200
201
202
203
204 private boolean compareAndIgnore(final Length distance)
205 {
206 if (this.indicatorObjectDistance != null)
207 {
208 if (this.indicatorObjectDistance.lt(distance))
209 {
210
211 return true;
212 }
213 if (this.indicatorObjectDistance.gt(distance))
214 {
215
216 this.indicatorIntent = TurnIndicatorIntent.NONE;
217 }
218 }
219 else
220 {
221
222 this.indicatorIntent = TurnIndicatorIntent.NONE;
223 }
224 return false;
225 }
226
227
228 @Override
229 @SuppressWarnings("checkstyle:designforextension")
230 public String toString()
231 {
232 return "SimpleOperationalPlan [Acceleration=" + this.acceleration + ", change=" + this.laneChangeDirection
233 + ", indicator intent=" + this.indicatorIntent + "]";
234 }
235
236
237
238
239
240 public void setTurnIndicator(final GTU gtu) throws GTUException
241 {
242 if (this.indicatorIntent.isLeft())
243 {
244 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.LEFT);
245 }
246 else if (this.indicatorIntent.isRight())
247 {
248 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.RIGHT);
249 }
250 else
251 {
252 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.NONE);
253 }
254 }
255
256 }