1 package org.opentrafficsim.ahfe;
2
3 import java.util.ArrayList;
4 import java.util.LinkedHashMap;
5 import java.util.List;
6
7 import org.djunits.value.vdouble.scalar.Duration;
8 import org.djunits.value.vdouble.scalar.Time;
9 import org.djutils.exceptions.Throw;
10 import org.opentrafficsim.base.Identifiable;
11 import org.opentrafficsim.base.TimeStampedObject;
12 import org.opentrafficsim.base.Type;
13 import org.opentrafficsim.base.parameters.ParameterException;
14 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
15 import org.opentrafficsim.base.parameters.Parameters;
16 import org.opentrafficsim.core.gtu.GTUException;
17 import org.opentrafficsim.core.gtu.perception.PerceptionException;
18 import org.opentrafficsim.core.network.LateralDirectionality;
19 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
20 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
21 import org.opentrafficsim.road.gtu.lane.perception.categories.LaneBasedAbstractPerceptionCategory;
22 import org.opentrafficsim.road.gtu.lane.perception.categories.LaneBasedPerceptionCategory;
23
24
25
26
27
28
29
30
31
32
33
34
35 @Deprecated
36 public abstract class AbstractDelayedPerceptionCategory extends LaneBasedAbstractPerceptionCategory
37 implements LaneBasedPerceptionCategory
38 {
39
40
41 private static final Duration MARGIN = Duration.instantiateSI(0.001);
42
43
44 private static final long serialVersionUID = 20170217L;
45
46
47
48
49 public AbstractDelayedPerceptionCategory(final LanePerception perception)
50 {
51 super(perception);
52 }
53
54
55 private final LinkedHashMap<DelayedInfoType<?>, LinkedHashMap<RelativeLane, List<TimeStampedObject<?>>>> map =
56 new LinkedHashMap<>();
57
58
59
60
61
62
63
64 public final <T> void setInfo(final DelayedInfoType<T> delayedInfoType, final TimeStampedObject<T> info)
65 {
66 setInfo(delayedInfoType, null, info);
67 }
68
69
70
71
72
73
74
75
76 public final <T> void setInfo(final DelayedInfoType<T> delayedInfoType, final RelativeLane lane,
77 final TimeStampedObject<T> info)
78 {
79 Throw.whenNull(delayedInfoType, "Delayed info type may not be null.");
80 Throw.whenNull(info, "Info may not be null.");
81 if (!this.map.containsKey(delayedInfoType))
82 {
83 this.map.put(delayedInfoType, new LinkedHashMap<>());
84 }
85 if (!this.map.get(delayedInfoType).containsKey(lane))
86 {
87 this.map.get(delayedInfoType).put(lane, new ArrayList<TimeStampedObject<?>>());
88 }
89 List<TimeStampedObject<?>> list = this.map.get(delayedInfoType).get(lane);
90 if (!list.isEmpty())
91 {
92 Throw.when(!list.isEmpty() && info.getTimestamp().le(list.get(list.size() - 1).getTimestamp()),
93 RuntimeException.class,
94 "Setting delayed info for type %s with timestamp %s while info with timestamp %s is already present.",
95 delayedInfoType, info.getTimestamp(), list.get(list.size() - 1).getTimestamp());
96 }
97
98
99 list.add(info);
100 }
101
102
103
104
105
106
107
108
109
110 public final <T> TimeStampedObject<T> getInfo(final DelayedInfoType<T> delayedInfoType) throws PerceptionException
111 {
112 return getInfo(delayedInfoType, null);
113 }
114
115
116
117
118
119
120
121
122
123
124 @SuppressWarnings("unchecked")
125 public final <T> TimeStampedObject<T> getInfo(final DelayedInfoType<T> delayedInfoType, final RelativeLane lane)
126 throws PerceptionException
127 {
128 Throw.whenNull(delayedInfoType, "Delayed info type may not be null.");
129 Throw.when(!this.map.containsKey(delayedInfoType), PerceptionException.class,
130 "Perception does not contain any data for info type %s.", delayedInfoType);
131 Throw.when(!this.map.get(delayedInfoType).containsKey(lane), PerceptionException.class,
132 "Perception does not contain any data for info type %s for lane %s.", delayedInfoType, lane);
133 List<TimeStampedObject<?>> list = this.map.get(delayedInfoType).get(lane);
134 Throw.when(list.isEmpty(), RuntimeException.class, "Perception does not contain any data for info type %s.",
135 delayedInfoType);
136
137
138 Parameters params;
139 Time now;
140 try
141 {
142 params = getPerception().getGtu().getParameters();
143 now = getPerception().getGtu().getSimulator().getSimulatorAbsTime();
144 }
145 catch (GTUException exception)
146 {
147 throw new RuntimeException("GTU not yet initialized.", exception);
148 }
149 Time delayedTime;
150 try
151 {
152 delayedTime = now.minus(params.getParameter(delayedInfoType.getDelayParameter())).plus(MARGIN);
153 }
154 catch (ParameterException exception)
155 {
156 throw new RuntimeException("Delay parameter not found.", exception);
157 }
158 while (list.size() > 1 && list.get(1).getTimestamp().le(delayedTime))
159 {
160 list.remove(0);
161 }
162
163 return (TimeStampedObject<T>) list.get(0);
164 }
165
166
167
168
169
170
171 public final void changeLane(final LateralDirectionality dir)
172 {
173 for (DelayedInfoType<?> delayedInfoType : this.map.keySet())
174 {
175 LinkedHashMap<RelativeLane, List<TimeStampedObject<?>>> newMap = new LinkedHashMap<>();
176 for (RelativeLane lane : this.map.get(delayedInfoType).keySet())
177 {
178 if (lane != null)
179 {
180 newMap.put(dir.isLeft() ? lane.getRight() : lane.getLeft(), this.map.get(delayedInfoType).get(lane));
181 }
182 else
183 {
184 newMap.put(lane, this.map.get(delayedInfoType).get(lane));
185 }
186 }
187 this.map.put(delayedInfoType, newMap);
188 }
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 public static class DelayedInfoType<T> extends Type<DelayedInfoType<T>> implements Identifiable
205 {
206
207
208 private final String id;
209
210
211 private final ParameterTypeDuration delayParameter;
212
213
214
215
216
217
218 public DelayedInfoType(final String id, final ParameterTypeDuration delayParameter)
219 {
220 this.id = id;
221 this.delayParameter = delayParameter;
222 }
223
224
225
226
227
228 @Override
229 public final String getId()
230 {
231 return this.getId();
232 }
233
234
235
236
237
238 public final ParameterTypeDuration getDelayParameter()
239 {
240 return this.delayParameter;
241 }
242
243
244 @Override
245 public final int hashCode()
246 {
247 final int prime = 31;
248 int result = 1;
249 result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
250 return result;
251 }
252
253
254 @Override
255 public final boolean equals(final Object obj)
256 {
257 if (this == obj)
258 {
259 return true;
260 }
261 if (obj == null)
262 {
263 return false;
264 }
265 if (getClass() != obj.getClass())
266 {
267 return false;
268 }
269 DelayedInfoType<?> other = (DelayedInfoType<?>) obj;
270 if (this.id == null)
271 {
272 if (other.id != null)
273 {
274 return false;
275 }
276 }
277 else if (!this.id.equals(other.id))
278 {
279 return false;
280 }
281 return true;
282 }
283
284 }
285
286 }