1 package org.opentrafficsim.road.gtu.lane.perception.categories.neighbors;
2
3 import org.djunits.value.vdouble.scalar.Duration;
4 import org.djunits.value.vdouble.scalar.Length;
5 import org.djunits.value.vdouble.scalar.Time;
6 import org.djutils.exceptions.Throw;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.base.parameters.ParameterTypes;
9 import org.opentrafficsim.core.gtu.GTUException;
10 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
11 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation.NeighborTriplet;
12 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
13 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTUPerceived;
14 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTUReal;
15 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTURealCopy;
16
17
18
19
20
21
22
23
24
25
26
27
28 public interface HeadwayGtuType
29 {
30
31
32 HeadwayGtuType WRAP = new HeadwayGtuType()
33 {
34 @Override
35 public HeadwayGTUReal createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
36 final Length distance) throws GTUException
37 {
38 return new HeadwayGTUReal(perceivedGtu, distance, true);
39 }
40
41 @Override
42 public HeadwayGTUReal createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
43 final Length distance) throws GTUException
44 {
45 return new HeadwayGTUReal(perceivedGtu, distance, true);
46 }
47
48 @Override
49 public HeadwayGTUReal createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
50 final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
51 {
52 return new HeadwayGTUReal(perceivedGtu, overlapFront, overlap, overlapRear, true);
53 }
54 };
55
56
57 HeadwayGtuType COPY = new HeadwayGtuType()
58 {
59 @Override
60 public HeadwayGTURealCopy createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
61 final Length distance) throws GTUException
62 {
63 return new HeadwayGTURealCopy(perceivedGtu, distance);
64 }
65
66 @Override
67 public HeadwayGTURealCopy createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
68 final Length distance) throws GTUException
69 {
70 return new HeadwayGTURealCopy(perceivedGtu, distance);
71 }
72
73 @Override
74 public HeadwayGTURealCopy createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
75 final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
76 {
77 return new HeadwayGTURealCopy(perceivedGtu, overlapFront, overlap, overlapRear);
78 }
79 };
80
81
82
83
84
85
86
87
88
89
90
91
92 default HeadwayGTU createHeadwayGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance,
93 boolean downstream) throws GTUException, ParameterException
94 {
95 if (distance.ge0())
96 {
97 if (downstream)
98 {
99 return createDownstreamGtu(perceivingGtu, perceivedGtu, distance);
100 }
101 return createUpstreamGtu(perceivingGtu, perceivedGtu, distance);
102 }
103 Throw.when(-distance.si > perceivingGtu.getLength().si + perceivedGtu.getLength().si, IllegalStateException.class,
104 "A GTU that is supposedly %s is actually %s.", downstream ? "downstream" : "upstream",
105 downstream ? "upstream" : "downstream");
106 Length overlapRear = distance.plus(perceivingGtu.getLength());
107 Length overlap = distance.neg();
108 Length overlapFront = distance.plus(perceivedGtu.getLength());
109 if (overlapRear.lt0())
110 {
111 overlap = overlap.plus(overlapRear);
112 }
113 if (overlapFront.lt0())
114 {
115 overlap = overlap.plus(overlapFront);
116 }
117 return createParallelGtu(perceivingGtu, perceivedGtu, overlapFront, overlap, overlapRear);
118 }
119
120
121
122
123
124
125
126
127
128
129 HeadwayGTU createDownstreamGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance)
130 throws GTUException, ParameterException;
131
132
133
134
135
136
137
138
139
140
141 HeadwayGTU createUpstreamGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length distance)
142 throws GTUException, ParameterException;
143
144
145
146
147
148
149
150
151
152
153
154 HeadwayGTU createParallelGtu(LaneBasedGTU perceivingGtu, LaneBasedGTU perceivedGtu, Length overlapFront, Length overlap,
155 Length overlapRear) throws GTUException;
156
157
158
159
160
161
162
163
164
165
166
167
168
169 class PerceivedHeadwayGtuType implements HeadwayGtuType
170 {
171
172
173 private final Estimation estimation;
174
175
176 private final Anticipation anticipation;
177
178
179 private Time updateTime = null;
180
181
182 private Duration tr;
183
184
185 private Time when;
186
187
188 private Length traveledDistance;
189
190
191
192
193
194
195 public PerceivedHeadwayGtuType(final Estimation estimation, final Anticipation anticipation)
196 {
197 this.estimation = estimation;
198 this.anticipation = anticipation;
199 }
200
201
202 @Override
203 public HeadwayGTU createHeadwayGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
204 final Length distance, final boolean downstream) throws GTUException, ParameterException
205 {
206 Time now = perceivedGtu.getSimulator().getSimulatorTime();
207 if (this.updateTime == null || now.si > this.updateTime.si)
208 {
209 this.updateTime = now;
210 this.tr = perceivingGtu.getParameters().getParameter(ParameterTypes.TR);
211 Time whenTemp = now.minus(this.tr);
212 if (this.when == null || (this.when != null && whenTemp.si > this.when.si))
213 {
214
215 this.when = whenTemp;
216 }
217 this.traveledDistance = perceivingGtu.getOdometer().minus(perceivingGtu.getOdometer(this.when));
218 }
219 NeighborTriplet triplet = this.estimation.estimate(perceivingGtu, perceivedGtu, distance, downstream, this.when);
220 triplet = this.anticipation.anticipate(triplet, this.tr, this.traveledDistance, downstream);
221 return new HeadwayGTUPerceived(perceivedGtu, triplet.getHeadway(), triplet.getSpeed(), triplet.getAcceleration());
222 }
223
224
225 @Override
226 public HeadwayGTU createDownstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
227 final Length distance) throws GTUException, ParameterException
228 {
229 return createHeadwayGtu(perceivingGtu, perceivedGtu, distance, true);
230 }
231
232
233 @Override
234 public HeadwayGTU createUpstreamGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
235 final Length distance) throws GTUException, ParameterException
236 {
237 return createHeadwayGtu(perceivingGtu, perceivedGtu, distance, false);
238 }
239
240
241 @Override
242 public HeadwayGTU createParallelGtu(final LaneBasedGTU perceivingGtu, final LaneBasedGTU perceivedGtu,
243 final Length overlapFront, final Length overlap, final Length overlapRear) throws GTUException
244 {
245 return new HeadwayGTUPerceived(perceivedGtu, overlapFront, overlap, overlapRear, perceivedGtu.getSpeed(),
246 perceivedGtu.getAcceleration());
247 }
248
249 }
250
251 }