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.neighbors.HeadwayGtuType;
9 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
10 import org.opentrafficsim.road.gtu.lane.perception.structure.LaneRecordInterface;
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.instantiateSI(0.000001);
27
28
29 private static final Length RIGHT = Length.instantiateSI(-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 LaneRecordInterface<?> root,
51 final Length initialPosition, final Length maxDistance, final RelativePosition relativePosition,
52 final HeadwayGtuType headwayGtuType, 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 LaneRecordInterface<?> record, final Length position, final Integer counter)
62 throws GtuException
63 {
64 int n;
65 LaneBasedGtu next;
66 Length pos;
67 if (counter == null)
68 {
69 if (position.ge(record.getLane().getLength()))
70 {
71 next = record.getLane().getLastGtu();
72 }
73 else
74 {
75 Length searchPos = position.plus(this.margin);
76 next = record.getLane().getGtuBehind(searchPos, RelativePosition.FRONT,
77 record.getLane().getLink().getSimulator().getSimulatorAbsTime());
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.getGtu() != null && next.getId().equals(this.getGtu().getId()))
87 {
88
89 pos = pos.minus(next.getLength());
90 return getNext(record, pos, n);
91 }
92 }
93 else
94 {
95 n = 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 LaneRecordInterface<?> 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.createUpstreamGtu(perceivingGtu, object, distance);
119 }
120
121 }