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