1 package org.opentrafficsim.road.gtu.lane.perception;
2
3 import org.djunits.value.vdouble.scalar.Length;
4 import org.opentrafficsim.base.parameters.ParameterException;
5 import org.opentrafficsim.core.gtu.GTUException;
6 import org.opentrafficsim.core.gtu.RelativePosition;
7 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
8 import org.opentrafficsim.road.gtu.lane.perception.categories.HeadwayGtuType;
9 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
10
11
12
13
14
15
16
17
18
19
20
21
22 public class UpstreamNeighborsIterable extends AbstractPerceptionIterable<HeadwayGTU, LaneBasedGTU, Integer>
23 {
24
25
26 private static final Length LEFT = Length.createSI(0.000001);
27
28
29 private static final Length RIGHT = Length.createSI(-0.000001);
30
31
32 private final HeadwayGtuType headwayGtuType;
33
34
35
36
37
38 private final Length margin;
39
40
41
42
43
44
45
46
47
48
49
50 public UpstreamNeighborsIterable(final LaneBasedGTU perceivingGtu, final LaneRecord<?> root, final Length initialPosition,
51 final Length maxDistance, final RelativePosition relativePosition, final HeadwayGtuType headwayGtuType,
52 final RelativeLane lane)
53 {
54 super(perceivingGtu, root, initialPosition, false, maxDistance, relativePosition, null);
55 this.headwayGtuType = headwayGtuType;
56 this.margin = lane.getLateralDirectionality().isLeft() ? LEFT : RIGHT;
57 }
58
59
60 @Override
61 protected Entry getNext(final LaneRecord<?> record, final Length position, final Integer counter) throws GTUException
62 {
63 int n;
64 LaneBasedGTU next;
65 Length pos;
66 boolean plus = record.getDirection().isPlus();
67 if (counter == null)
68 {
69 if (plus ? position.ge(record.getLane().getLength()) : position.eq0())
70 {
71 next = record.getLane().getLastGtu(record.getDirection());
72 }
73 else
74 {
75 Length searchPos = (plus ? position.plus(this.margin) : position.minus(this.margin));
76 next = record.getLane().getGtuBehind(searchPos, record.getDirection(), RelativePosition.FRONT,
77 record.getLane().getParentLink().getSimulator().getSimulatorTime());
78 }
79 if (next == null)
80 {
81 return null;
82 }
83 n = record.getLane().indexOfGtu(next);
84 pos = next.position(record.getLane(), next.getFront());
85
86 if (this.gtu != null && next.getId().equals(this.gtu.getId()))
87 {
88
89 pos = plus ? pos.minus(next.getLength()) : pos.plus(next.getLength());
90 return getNext(record, pos, n);
91 }
92 }
93 else
94 {
95 n = plus ? counter - 1 : counter + 1;
96 if (n < 0 || n >= record.getLane().numberOfGtus())
97 {
98 return null;
99 }
100 next = record.getLane().getGtu(n);
101 pos = next.position(record.getLane(), next.getFront());
102 }
103 return new Entry(next, n, pos);
104 }
105
106
107 @Override
108 protected Length getDistance(final LaneBasedGTU object, final LaneRecord<?> record, final Length position)
109 {
110 return record.getDistanceToPosition(position).neg().plus(getDx());
111 }
112
113
114 @Override
115 public HeadwayGTU perceive(final LaneBasedGTU perceivingGtu, final LaneBasedGTU object, final Length distance)
116 throws GTUException, ParameterException
117 {
118 return this.headwayGtuType.createHeadwayGtu(perceivingGtu, object, distance.neg(), false);
119 }
120
121 }