1 package org.opentrafficsim.ahfe;
2
3 import java.rmi.RemoteException;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.SortedSet;
7 import java.util.TreeSet;
8
9 import org.djunits.value.vdouble.scalar.Acceleration;
10 import org.djunits.value.vdouble.scalar.Duration;
11 import org.djunits.value.vdouble.scalar.Length;
12 import org.djunits.value.vdouble.scalar.Speed;
13 import org.djunits.value.vdouble.scalar.Time;
14 import org.djutils.exceptions.Throw;
15 import org.opentrafficsim.base.TimeStampedObject;
16 import org.opentrafficsim.base.parameters.ParameterException;
17 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
18 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
19 import org.opentrafficsim.base.parameters.Parameters;
20 import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
21 import org.opentrafficsim.core.gtu.GTUException;
22 import org.opentrafficsim.core.gtu.perception.EgoPerception;
23 import org.opentrafficsim.core.gtu.perception.PerceptionException;
24 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
25 import org.opentrafficsim.core.network.LateralDirectionality;
26 import org.opentrafficsim.core.network.OTSNetwork;
27 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
28 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
29 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
30 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
31 import org.opentrafficsim.road.gtu.lane.perception.SortedSetPerceptionIterable;
32 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation;
33 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborTriplet;
34 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
35
36 import nl.tudelft.simulation.event.EventInterface;
37 import nl.tudelft.simulation.event.EventListenerInterface;
38 import nl.tudelft.simulation.jstats.distributions.DistNormal;
39
40
41
42
43
44
45
46
47
48
49
50
51 @Deprecated
52 public class DelayedNeighborsPerception extends AbstractDelayedNeighborsPerception implements EventListenerInterface
53 {
54
55
56 public static final ParameterTypeDuration TA =
57 new ParameterTypeDuration("ta", "anticipation time in future", Duration.ZERO, ConstraintInterface.POSITIVEZERO);
58
59
60 public static final ParameterTypeDuration TAUE =
61 new ParameterTypeDuration("tau_e", "error correlation time", Duration.createSI(20), ConstraintInterface.POSITIVE);
62
63
64 public static final ParameterTypeDouble SERROR =
65 new ParameterTypeDouble("s_error", "distance error factor", 0.1, ConstraintInterface.POSITIVEZERO);
66
67
68 public static final ParameterTypeDouble VERROR =
69 new ParameterTypeDouble("v_error", "speed error factor", 0.1, ConstraintInterface.POSITIVEZERO);
70
71
72 public static final ParameterTypeDouble AERROR =
73 new ParameterTypeDouble("a_error", "acceleration error factor", 0.2, ConstraintInterface.POSITIVEZERO);
74
75
76 private static final double MARGIN = 1e-6;
77
78
79 private static final long serialVersionUID = 20170217L;
80
81
82 private final Anticipation anticipation;
83
84
85 private Time rearrangeTime;
86
87
88 private final Map<RelativeLane, PerceptionCollectable<HeadwayGTU, LaneBasedGTU>> followers = new HashMap<>();
89
90
91 private final Map<RelativeLane, PerceptionCollectable<HeadwayGTU, LaneBasedGTU>> leaders = new HashMap<>();
92
93
94 private final Map<LateralDirectionality, SortedSet<HeadwayGTU>> firstFollowers = new HashMap<>();
95
96
97 private final Map<LateralDirectionality, SortedSet<HeadwayGTU>> firstLeaders = new HashMap<>();
98
99
100 private final Map<LateralDirectionality, Boolean> gtuAlongside = new HashMap<>();
101
102
103 private HashMap<String, ErrorValue> errors = new HashMap<>();
104
105
106 private final DistNormal norm;
107
108
109
110
111
112 public DelayedNeighborsPerception(final LanePerception perception, final Anticipation anticipation)
113 {
114 super(perception);
115 Throw.whenNull(anticipation, "Anticipation may not be null.");
116 this.anticipation = anticipation;
117 try
118 {
119 this.norm = new DistNormal(perception.getGtu().getSimulator().getReplication().getStream("perception"));
120 perception.getGtu().addListener(this, LaneBasedGTU.LANE_CHANGE_EVENT);
121 }
122 catch (GTUException | RemoteException exception)
123 {
124 throw new RuntimeException("GTU not initialized.", exception);
125 }
126 }
127
128
129 @Override
130 public void notify(final EventInterface event) throws RemoteException
131 {
132 changeLane((LateralDirectionality) ((Object[]) event.getContent())[1]);
133 }
134
135
136
137
138 private void rearrangeNeighbors()
139 {
140 Time time;
141 Duration ta;
142 Duration taue;
143 Length length;
144 Length traveledDistance;
145 double distanceError;
146 double speedError;
147 double accelerationError;
148 Speed egoSpeed;
149 Duration dt;
150 try
151 {
152 time = getPerception().getGtu().getSimulator().getSimulatorTime();
153 if (time.equals(this.rearrangeTime))
154 {
155 return;
156 }
157 Parameters params = getPerception().getGtu().getParameters();
158 ta = params.getParameter(TA);
159 taue = params.getParameter(TAUE);
160 distanceError = params.getParameter(SERROR);
161 speedError = params.getParameter(VERROR);
162 accelerationError = params.getParameter(AERROR);
163 length = getPerception().getGtu().getLength();
164 EgoPerception ego = getPerception().getPerceptionCategory(EgoPerception.class);
165 egoSpeed = ego.getSpeed();
166 dt = params.getParameter(DT);
167 try
168 {
169 traveledDistance = getPerception().getGtu().getOdometer().minus(getInfo(ODOMETER).getObject());
170 }
171 catch (PerceptionException exception)
172 {
173 throw new RuntimeException("Odometer not percieved.", exception);
174 }
175 if (!ta.eq0())
176 {
177 Acceleration acceleration = ego.getAcceleration();
178 traveledDistance = traveledDistance.plus(this.anticipation.egoAnticipation(egoSpeed, acceleration, ta));
179 }
180 this.rearrangeTime = time;
181 }
182 catch (GTUException exception)
183 {
184 throw new RuntimeException("GTU not initialized while rearranging neighbors.", exception);
185 }
186 catch (ParameterException exception)
187 {
188 throw new RuntimeException("Could not obtain parameter.", exception);
189 }
190 catch (OperationalPlanException exception)
191 {
192 throw new RuntimeException("No ego perception.", exception);
193 }
194 this.firstFollowers.clear();
195 this.firstLeaders.clear();
196 this.gtuAlongside.clear();
197 this.followers.clear();
198 this.leaders.clear();
199 try
200 {
201 for (RelativeLane lane : getDelayedCrossSection())
202 {
203
204
205 if (lane.getNumLanes() == 1)
206 {
207
208 boolean gtuAlongSide = getInfo(NeighborsInfoType.getBooleanType(GTUALONGSIDE), lane).getObject();
209
210
211 SortedSet<HeadwayGTU> firstFollowersSet = new TreeSet<>();
212 this.firstFollowers.put(lane.getLateralDirectionality(), firstFollowersSet);
213 TimeStampedObject<SortedSet<HeadwayGTU>> delayedFirstFollowers =
214 getInfo(NeighborsInfoType.getSortedSetType(FIRSTFOLLOWERS), lane);
215 Duration d = time.minus(delayedFirstFollowers.getTimestamp()).plus(ta);
216 for (HeadwayGTU gtu : delayedFirstFollowers.getObject())
217 {
218 NeighborTriplet info = this.anticipation.anticipate(erroneousTriplet(gtu.getDistance().neg(),
219 gtu.getSpeed(), gtu.getAcceleration(), getError(gtu.getId(), taue, dt), distanceError,
220 speedError, accelerationError, egoSpeed), d, traveledDistance, false);
221 if (info.getHeadway().le0())
222 {
223 firstFollowersSet.add(gtu.moved(info.getHeadway().neg(), info.getSpeed(), info.getAcceleration()));
224 }
225 else
226 {
227 gtuAlongSide = true;
228 }
229 }
230
231
232 SortedSet<HeadwayGTU> firstLeaderssSet = new TreeSet<>();
233 this.firstLeaders.put(lane.getLateralDirectionality(), firstLeaderssSet);
234 TimeStampedObject<SortedSet<HeadwayGTU>> delayedFirstLeaders =
235 getInfo(NeighborsInfoType.getSortedSetType(FIRSTLEADERS), lane);
236 d = time.minus(delayedFirstLeaders.getTimestamp()).plus(ta);
237 for (HeadwayGTU gtu : delayedFirstLeaders.getObject())
238 {
239 NeighborTriplet info = this.anticipation.anticipate(erroneousTriplet(gtu.getDistance(), gtu.getSpeed(),
240 gtu.getAcceleration(), getError(gtu.getId(), taue, dt), distanceError, speedError,
241 accelerationError, egoSpeed), d, traveledDistance, true);
242 if (info.getHeadway().ge0())
243 {
244 firstLeaderssSet.add(gtu.moved(info.getHeadway(), info.getSpeed(), info.getAcceleration()));
245 }
246 else
247 {
248 gtuAlongSide = true;
249 }
250 }
251
252
253 this.gtuAlongside.put(lane.getLateralDirectionality(), gtuAlongSide);
254 }
255
256
257 SortedSetPerceptionIterable<HeadwayGTU> followersSet = new SortedSetPerceptionIterable<>(
258 (OTSNetwork) getPerception().getGtu().getReferencePosition().getLane().getParentLink().getNetwork());
259 this.followers.put(lane, followersSet);
260 SortedSetPerceptionIterable<HeadwayGTU> leadersSet = new SortedSetPerceptionIterable<>(
261 (OTSNetwork) getPerception().getGtu().getReferencePosition().getLane().getParentLink().getNetwork());
262 this.leaders.put(lane, leadersSet);
263
264
265 TimeStampedObject<PerceptionCollectable<HeadwayGTU, LaneBasedGTU>> delayedFollowers =
266 getInfo(NeighborsInfoType.getIterableType(FOLLOWERS), lane);
267 Duration d = time.minus(delayedFollowers.getTimestamp()).plus(ta);
268
269 PerceptionCollectable<HeadwayGTU, LaneBasedGTU> perc = delayedFollowers.getObject();
270 for (HeadwayGTU gtu : delayedFollowers.getObject())
271 {
272 NeighborTriplet info = this.anticipation.anticipate(
273 erroneousTriplet(gtu.getDistance().neg(), gtu.getSpeed(), gtu.getAcceleration(),
274 getError(gtu.getId(), taue, dt), distanceError, speedError, accelerationError, egoSpeed),
275 d, traveledDistance, false);
276 if (info.getHeadway().le(length) || lane.isCurrent())
277 {
278 followersSet.add(gtu.moved(info.getHeadway().neg(), info.getSpeed(), info.getAcceleration()));
279 }
280 else
281 {
282 leadersSet.add(gtu.moved(info.getHeadway().minus(length).minus(gtu.getLength()), info.getSpeed(),
283 info.getAcceleration()));
284 }
285 }
286
287
288 TimeStampedObject<PerceptionCollectable<HeadwayGTU, LaneBasedGTU>> delayedLeaders =
289 getInfo(NeighborsInfoType.getIterableType(LEADERS), lane);
290 d = time.minus(delayedLeaders.getTimestamp()).plus(ta);
291 for (HeadwayGTU gtu : delayedLeaders.getObject())
292 {
293
294 NeighborTriplet info = this.anticipation.anticipate(
295 erroneousTriplet(gtu.getDistance(), gtu.getSpeed(), gtu.getAcceleration(),
296 getError(gtu.getId(), taue, dt), distanceError, speedError, accelerationError, egoSpeed),
297 d, traveledDistance, true);
298 if (info.getHeadway().ge(gtu.getLength().neg()) || lane.isCurrent())
299 {
300 leadersSet.add(gtu.moved(info.getHeadway(), info.getSpeed(), info.getAcceleration()));
301 }
302 else
303 {
304 followersSet.add(gtu.moved(info.getHeadway().plus(length).plus(gtu.getLength()).neg(), info.getSpeed(),
305 info.getAcceleration()));
306 }
307 }
308
309 }
310
311 }
312 catch (PerceptionException | GTUException exception)
313 {
314
315 }
316
317 try
318 {
319
320 for (RelativeLane lane : getPerception().getLaneStructure().getExtendedCrossSection())
321 {
322 if (!this.followers.containsKey(lane))
323 {
324 this.followers.put(lane, new SortedSetPerceptionIterable<>((OTSNetwork) getPerception().getGtu()
325 .getReferencePosition().getLane().getParentLink().getNetwork()));
326 }
327 if (!this.leaders.containsKey(lane))
328 {
329 this.leaders.put(lane, new SortedSetPerceptionIterable<>((OTSNetwork) getPerception().getGtu()
330 .getReferencePosition().getLane().getParentLink().getNetwork()));
331 }
332 if (lane.isLeft() || lane.isRight())
333 {
334 if (!this.firstFollowers.containsKey(lane.getLateralDirectionality()))
335 {
336 this.firstFollowers.put(lane.getLateralDirectionality(), new TreeSet<>());
337 }
338 if (!this.firstLeaders.containsKey(lane.getLateralDirectionality()))
339 {
340 this.firstLeaders.put(lane.getLateralDirectionality(), new TreeSet<>());
341 }
342 if (!this.gtuAlongside.containsKey(lane.getLateralDirectionality()))
343 {
344 this.gtuAlongside.put(lane.getLateralDirectionality(), false);
345 }
346 }
347 }
348 }
349 catch (ParameterException | GTUException pe)
350 {
351
352 }
353
354 }
355
356
357
358
359
360
361
362
363 private double getError(final String gtuId, final Duration tau, final Duration dt)
364 {
365 Time now;
366 try
367 {
368 now = getTimestamp();
369 }
370 catch (GTUException exception)
371 {
372 throw new RuntimeException("Could not get time stamp.", exception);
373 }
374
375 double err;
376 ErrorValue errorValue;
377 if (!this.errors.containsKey(gtuId))
378 {
379 err = this.norm.draw();
380 errorValue = new ErrorValue();
381 this.errors.put(gtuId, errorValue);
382 }
383 else
384 {
385 errorValue = this.errors.get(gtuId);
386 if (errorValue.getTime().eq(now))
387 {
388 return errorValue.getError();
389 }
390 double dtErr = now.si - errorValue.getTime().si;
391 if (dtErr <= dt.si + MARGIN)
392 {
393 err = Math.exp(-dtErr / tau.si) * errorValue.getError() + Math.sqrt((2 * dtErr) / tau.si) * this.norm.draw();
394 }
395 else
396 {
397
398 err = this.norm.draw();
399 }
400 }
401 errorValue.set(now, err);
402 return err;
403
404 }
405
406
407
408
409
410
411
412
413
414
415
416
417
418 @SuppressWarnings("checkstyle:parameternumber")
419 private NeighborTriplet erroneousTriplet(final Length distance, final Speed speed, final Acceleration acceleration,
420 final double error, final double distanceError, final double speedError, final double accelerationError,
421 final Speed egoSpeed)
422 {
423 Length s = Length.createSI(distance.si * (1 + ((distance.ge0() ? error : -error) * distanceError)));
424 Speed v = Speed.createSI(speed.si + (error * speedError * distance.si));
425 if (v.lt0())
426 {
427 v = Speed.ZERO;
428 }
429 Acceleration a = Acceleration.createSI(acceleration.si * (1 + error * accelerationError));
430 return new NeighborTriplet(s, v, a);
431 }
432
433
434 @Override
435 public final SortedSet<HeadwayGTU> getFirstLeaders(final LateralDirectionality lat)
436 throws ParameterException, NullPointerException, IllegalArgumentException
437 {
438 rearrangeNeighbors();
439 return this.firstLeaders.get(lat);
440 }
441
442
443 @Override
444 public final SortedSet<HeadwayGTU> getFirstFollowers(final LateralDirectionality lat)
445 throws ParameterException, NullPointerException, IllegalArgumentException
446 {
447 rearrangeNeighbors();
448 return this.firstFollowers.get(lat);
449 }
450
451
452 @Override
453 public final boolean isGtuAlongside(final LateralDirectionality lat)
454 throws ParameterException, NullPointerException, IllegalArgumentException
455 {
456 if (isGtuAlongsideOverride(lat))
457 {
458 return true;
459 }
460 rearrangeNeighbors();
461 if (this.gtuAlongside.containsKey(lat))
462 {
463 return this.gtuAlongside.get(lat);
464 }
465
466
467 return true;
468 }
469
470
471 @Override
472 public final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> getLeaders(final RelativeLane lane)
473 {
474 rearrangeNeighbors();
475 return this.leaders.get(lane);
476 }
477
478
479 @Override
480 public final PerceptionCollectable<HeadwayGTU, LaneBasedGTU> getFollowers(final RelativeLane lane)
481 {
482 rearrangeNeighbors();
483 return this.followers.get(lane);
484 }
485
486
487
488
489
490
491
492
493
494
495
496
497 private class ErrorValue
498 {
499
500
501 private Time time;
502
503
504 private double error;
505
506
507
508
509 ErrorValue()
510 {
511 }
512
513
514
515
516 public Time getTime()
517 {
518 return this.time;
519 }
520
521
522
523
524 public double getError()
525 {
526 return this.error;
527 }
528
529
530
531
532
533 public void set(final Time t, final double err)
534 {
535 this.time = t;
536 this.error = err;
537 }
538
539
540 @Override
541 public final String toString()
542 {
543 return "ErrorValue [time=" + this.time + ", error=" + this.error + "]";
544 }
545
546 }
547
548
549 @Override
550 public final String toString()
551 {
552 return "DelayedNeighborsPerception [anticipation=" + this.anticipation + ", rearrangeTime=" + this.rearrangeTime
553 + ", followers=" + this.followers + ", leaders=" + this.leaders + ", firstFollowers=" + this.firstFollowers
554 + ", firstLeaders=" + this.firstLeaders + ", gtuAlongside=" + this.gtuAlongside + ", errors=" + this.errors
555 + ", norm=" + this.norm + "]";
556 }
557
558 }