1 package org.opentrafficsim.road.gtu.lane.plan.operational;
2
3 import org.djunits.value.vdouble.scalar.Acceleration;
4 import org.djunits.value.vdouble.scalar.Duration;
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djutils.exceptions.Throw;
7 import org.opentrafficsim.base.logger.Logger;
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 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
13
14
15
16
17
18
19
20
21
22
23
24
25 public class SimpleOperationalPlan
26 {
27
28
29 private Acceleration acceleration;
30
31
32 private final Duration duration;
33
34
35 private final Length deviation;
36
37
38 private final LateralDirectionality laneChangeDirection;
39
40
41 private TurnIndicatorIntent indicatorIntent = TurnIndicatorIntent.NONE;
42
43
44 private Length indicatorObjectDistance = null;
45
46
47
48
49
50
51 public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration)
52 {
53 this(acceleration, duration, Length.ZERO, LateralDirectionality.NONE);
54 }
55
56
57
58
59
60
61
62 public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration, final Length deviation)
63 {
64 this(acceleration, duration, deviation, LateralDirectionality.NONE);
65 }
66
67
68
69
70
71
72
73 public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration,
74 final LateralDirectionality laneChangeDirection)
75 {
76 this(acceleration, duration, Length.ZERO, laneChangeDirection);
77 }
78
79
80
81
82
83
84
85
86 public SimpleOperationalPlan(final Acceleration acceleration, final Duration duration, final Length deviation,
87 final LateralDirectionality laneChangeDirection)
88 {
89 Throw.whenNull(acceleration, "Acceleration may not be null.");
90 Throw.whenNull(duration, "Duration may not be null.");
91 Throw.whenNull(deviation, "Deviation may not be null.");
92 Throw.whenNull(laneChangeDirection, "Lane change direction may not be null.");
93 checkAcceleration(acceleration);
94 this.acceleration = Acceleration.max(Acceleration.ofSI(-100.0), acceleration);
95 this.duration = duration;
96 this.deviation = deviation;
97 this.laneChangeDirection = laneChangeDirection;
98 }
99
100
101
102
103
104 public final Acceleration getAcceleration()
105 {
106 return this.acceleration;
107 }
108
109
110
111
112
113 public final void setAcceleration(final Acceleration acceleration)
114 {
115 checkAcceleration(acceleration);
116 this.acceleration = acceleration;
117 }
118
119
120
121
122
123 public Duration getDuration()
124 {
125 return this.duration;
126 }
127
128
129
130
131
132 public Length getDeviation()
133 {
134 return this.deviation;
135 }
136
137
138
139
140
141 public final boolean isLaneChange()
142 {
143 return this.laneChangeDirection != LateralDirectionality.NONE;
144 }
145
146
147
148
149
150 public final LateralDirectionality getLaneChangeDirection()
151 {
152 return this.laneChangeDirection;
153 }
154
155
156
157
158
159 public final void minimizeAcceleration(final Acceleration a)
160 {
161 checkAcceleration(a);
162 this.acceleration = Acceleration.max(Acceleration.ofSI(-100.0), Acceleration.min(this.acceleration, a));
163 }
164
165
166
167
168
169 private void checkAcceleration(final Acceleration a)
170 {
171 if (a.equals(Acceleration.NEGATIVE_INFINITY) || a.equals(Acceleration.NEG_MAXVALUE))
172 {
173 Logger.ots().error("Model has calculated a negative infinite or negative max value acceleration.");
174 }
175 }
176
177
178
179
180
181 public final TurnIndicatorIntent getIndicatorIntent()
182 {
183 return this.indicatorIntent;
184 }
185
186
187
188
189 public final void setIndicatorIntentLeft()
190 {
191 if (this.indicatorObjectDistance != null)
192 {
193 return;
194 }
195 if (this.indicatorIntent.isRight())
196 {
197 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
198 }
199 else
200 {
201 this.indicatorIntent = TurnIndicatorIntent.LEFT;
202 }
203 }
204
205
206
207
208 public final void setIndicatorIntentRight()
209 {
210 if (this.indicatorObjectDistance != null)
211 {
212 return;
213 }
214 if (this.indicatorIntent.isLeft())
215 {
216 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
217 }
218 else
219 {
220 this.indicatorIntent = TurnIndicatorIntent.RIGHT;
221 }
222 }
223
224
225
226
227
228 public final void setIndicatorIntentLeft(final Length distance)
229 {
230 if (compareAndIgnore(distance))
231 {
232 return;
233 }
234 if (this.indicatorIntent.isRight())
235 {
236 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
237 }
238 else
239 {
240 this.indicatorIntent = TurnIndicatorIntent.LEFT;
241 }
242
243 }
244
245
246
247
248
249 public final void setIndicatorIntentRight(final Length distance)
250 {
251 if (compareAndIgnore(distance))
252 {
253 return;
254 }
255 if (this.indicatorIntent.isLeft())
256 {
257 this.indicatorIntent = TurnIndicatorIntent.CONFLICTING;
258 }
259 else
260 {
261 this.indicatorIntent = TurnIndicatorIntent.RIGHT;
262 }
263 }
264
265
266
267
268
269
270 private boolean compareAndIgnore(final Length distance)
271 {
272 if (this.indicatorObjectDistance != null)
273 {
274 if (this.indicatorObjectDistance.lt(distance))
275 {
276
277 return true;
278 }
279 if (this.indicatorObjectDistance.gt(distance))
280 {
281
282 this.indicatorIntent = TurnIndicatorIntent.NONE;
283 }
284 }
285 else
286 {
287
288 this.indicatorIntent = TurnIndicatorIntent.NONE;
289 }
290 return false;
291 }
292
293 @Override
294 @SuppressWarnings("checkstyle:designforextension")
295 public String toString()
296 {
297 return "SimpleOperationalPlan [Acceleration=" + this.acceleration + ", change=" + this.laneChangeDirection
298 + ", indicator intent=" + this.indicatorIntent + "]";
299 }
300
301
302
303
304
305
306 public final void setTurnIndicator(final LaneBasedGtu gtu) throws GtuException
307 {
308 if (this.indicatorIntent.isLeft())
309 {
310 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.LEFT);
311 }
312 else if (this.indicatorIntent.isRight())
313 {
314 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.RIGHT);
315 }
316 else
317 {
318 gtu.setTurnIndicatorStatus(TurnIndicatorStatus.NONE);
319 }
320 }
321
322 }