1 package org.opentrafficsim.road.gtu.lane.perception;
2
3 import java.util.LinkedHashSet;
4 import java.util.Set;
5
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.core.gtu.GtuException;
9 import org.opentrafficsim.core.gtu.RelativePosition;
10 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
11 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.HeadwayGtuType;
12 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class DownstreamNeighborsIterable extends AbstractPerceptionIterable<HeadwayGtu, LaneBasedGtu, Integer>
43 {
44
45
46 private static final Length LEFT = Length.instantiateSI(-0.000001);
47
48
49 private static final Length RIGHT = Length.instantiateSI(0.000001);
50
51
52 private final HeadwayGtuType headwayGtuType;
53
54
55 private final Set<String> ids = new LinkedHashSet<>();
56
57
58
59
60
61 private final Length margin;
62
63
64 private final boolean ignoreIfUpstream;
65
66
67
68
69
70
71
72
73
74
75
76
77 public DownstreamNeighborsIterable(final LaneBasedGtu perceivingGtu, final LaneRecordInterface<?> root,
78 final Length initialPosition, final Length maxDistance, final RelativePosition relativePosition,
79 final HeadwayGtuType headwayGtuType, final RelativeLane lane, final boolean ignoreIfUpstream)
80 {
81 super(perceivingGtu, root, initialPosition, true, maxDistance, relativePosition, null);
82 this.headwayGtuType = headwayGtuType;
83 this.margin = lane.getLateralDirectionality().isLeft() ? LEFT : RIGHT;
84 if (perceivingGtu != null)
85 {
86 this.ids.add(perceivingGtu.getId());
87 }
88 this.ignoreIfUpstream = ignoreIfUpstream;
89 }
90
91
92 @Override
93 protected Entry getNext(final LaneRecordInterface<?> record, final Length position, final Integer counter)
94 throws GtuException
95 {
96 int n;
97 LaneBasedGtu next;
98 Length pos;
99 if (counter == null)
100 {
101 Length searchPos = position.plus(this.margin);
102 next = record.getLane().getGtuAhead(searchPos, RelativePosition.FRONT,
103 record.getLane().getLink().getSimulator().getSimulatorAbsTime());
104 if (next == null)
105 {
106 return null;
107 }
108 n = record.getLane().indexOfGtu(next);
109 pos = next.position(record.getLane(), next.getRear());
110
111 if (this.ids.contains(next.getId()))
112 {
113
114 pos = pos.plus(next.getLength());
115 return getNext(record, pos, n);
116 }
117 if (this.ignoreIfUpstream)
118 {
119 if (pos.si < 0.0)
120 {
121 pos = pos.plus(next.getLength());
122 return getNext(record, pos, n);
123 }
124 }
125 }
126 else
127 {
128 n = counter + 1;
129 if (n < 0 || n >= record.getLane().numberOfGtus())
130 {
131 return null;
132 }
133 next = record.getLane().getGtu(n);
134 pos = next.position(record.getLane(), next.getRear());
135 if (this.ids.contains(next.getId()))
136 {
137
138 pos = pos.plus(next.getLength());
139 return getNext(record, pos, n);
140 }
141 }
142 return new Entry(next, n, pos);
143 }
144
145
146 @Override
147 protected Length getDistance(final LaneBasedGtu object, final LaneRecordInterface<?> record, final Length position)
148 {
149 return record.getDistanceToPosition(position).minus(getDx());
150 }
151
152
153 @Override
154 public HeadwayGtu perceive(final LaneBasedGtu perceivingGtu, final LaneBasedGtu object, final Length distance)
155 throws GtuException, ParameterException
156 {
157 return this.headwayGtuType.createDownstreamGtu(perceivingGtu, object, distance);
158 }
159
160 }