1 package org.opentrafficsim.sim0mq.kpi;
2
3 import java.util.LinkedHashMap;
4 import java.util.LinkedHashSet;
5 import java.util.Map;
6
7 import org.djunits.value.vdouble.scalar.Time;
8 import org.opentrafficsim.kpi.interfaces.LaneData;
9 import org.opentrafficsim.kpi.sampling.Sampler;
10
11 /**
12 * XXX ABSTRACT TEMPORARILY
13 * <p>
14 * Copyright (c) 2013-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
15 * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
16 * </p>
17 * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
18 * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
19 * @author <a href="https://dittlab.tudelft.nl">Wouter Schakel</a>
20 */
21 public abstract class Sim0mqSampler extends Sampler
22 {
23 /** The IMBConnector. */
24 // private final IMBConnector imbConnector;
25
26 /** Transceiver of statistics. */
27 private Sim0mqKpiTransceiver sim0mqKpiTransceiver;
28
29 /** The last received timestamp. */
30 private Time lastTimestamp = Time.ZERO;
31
32 /** The recording start times per LaneData. */
33 private final Map<LaneData, Time> startRecordingMap = new LinkedHashMap<>();
34
35 /** The recording stop times per LaneData. */
36 private final Map<LaneData, Time> stopRecordingMap = new LinkedHashMap<>();
37
38 /** the nodes. */
39 protected final Map<String, String> nodes = new LinkedHashMap<>();
40
41 /** the links. */
42 protected final Map<String, LinkDataSim0> links = new LinkedHashMap<>();
43
44 /** the lanes. */
45 protected final Map<String, LaneDataSim0> lanes = new LinkedHashMap<>();
46
47 /** the gtus. */
48 protected final Map<String, GtuDataSim0> gtus = new LinkedHashMap<>();
49
50 /** last lane of gtus. */
51 protected final Map<String, LaneData> lastLanes = new LinkedHashMap<>();
52
53 /** the default gtu type (for now). */
54 // protected final GtuTypeData defaultGtuType;
55
56 /** the default route (for now). */
57 // protected final RouteData defaultRoute;
58
59 /**
60 */
61 public Sim0mqSampler()
62 {
63 super(new LinkedHashSet<>(), new LinkedHashSet<>());
64 }
65
66 // /**
67 // * Main program for IMBSampler. Listens to events on the IMB bus and calculates and publishes statistics.
68 // * @param args the arguments with [0]=IP address, [1]=port
69 // * @throws IMBException in case of invalid arguments
70 // */
71 // public static void main(final String[] args) throws IMBException
72 // {
73 // if (args.length == 0)
74 // {
75 // new Sim0MQSampler(new IMBConnector("localhost", 4000, "OTS_IMB_KPI", 1, "OTS_RT"));
76 // }
77 // else
78 // {
79 // if (args.length != 5)
80 // {
81 // throw new IMBException("Use as follows: java -jar IMBSampler host port model modelId federation");
82 // }
83 // String host = args[0];
84 // int port = Integer.valueOf(args[1]);
85 // String modelName = args[2];
86 // int modelId = Integer.valueOf(args[3]);
87 // String federation = args[4];
88 // new Sim0MQSampler(new IMBConnector(host, port, modelName, modelId, federation));
89 // }
90 // }
91 //
92 // /**
93 // * Constructor with listeners for nodes, links, lanes and gtu's.
94 // * @param imbConnector IMB connection
95 // * @throws IMBException on connection error
96 // */
97 // public Sim0MQSampler(IMBConnector imbConnector) throws IMBException
98 // {
99 // this.imbConnector = imbConnector;
100 //
101 // // default GTU Type and default route
102 // this.defaultGtuType = new GtuTypeData("car");
103 // NodeData nodeA = new NodeData("NodeA", new CartesianPoint(0, 0, 0));
104 // NodeData nodeB = new NodeData("NodeB", new CartesianPoint(1, 1, 0));
105 // this.nodes.put(nodeA.getNodeName(), nodeA);
106 // this.nodes.put(nodeB.getNodeName(), nodeB);
107 // this.defaultRoute = new RouteData("Route A-B", nodeA, nodeB);
108 //
109 // Transceiver nodeTransceiver = new NodeTransceiver(this, this.imbConnector);
110 // this.imbConnector.register(nodeTransceiver.getId(), nodeTransceiver);
111 //
112 // Transceiver linkTransceiver = new LinkTransceiver(this, this.imbConnector);
113 // this.imbConnector.register(linkTransceiver.getId(), linkTransceiver);
114 //
115 // Transceiver laneTransceiver = new LaneTransceiver(this, this.imbConnector);
116 // this.imbConnector.register(laneTransceiver.getId(), laneTransceiver);
117 //
118 // Transceiver gtuTransceiver = new GTUTransceiver(this, this.imbConnector);
119 // this.imbConnector.register(gtuTransceiver.getId(), gtuTransceiver);
120 // }
121 //
122 // /** {@inheritDoc} */
123 // @Override
124 // public final Time now()
125 // {
126 // return this.lastTimestamp;
127 // }
128 //
129 // /** {@inheritDoc} */
130 // @Override
131 // public final void scheduleStartRecording(final Time time, final LaneData kpiLaneDirection)
132 // {
133 // // store the start time in the internal map to indicate from which time we want to consider events.
134 // this.startRecordingMap.put(kpiLaneDirection, time);
135 // }
136 //
137 // /** {@inheritDoc} */
138 // @Override
139 // public final void scheduleStopRecording(final Time time, final LaneData kpiLaneDirection)
140 // {
141 // // store the stop time in the internal map to indicate from which time we want to consider events.
142 // this.stopRecordingMap.put(kpiLaneDirection, time);
143 // }
144 //
145 // /** {@inheritDoc} */
146 // @Override
147 // public final void initRecording(final LaneData kpiLaneDirection)
148 // {
149 // // Nothing to do -- we get data on all GTUs
150 // }
151 //
152 // /** {@inheritDoc} */
153 // @Override
154 // public final void finalizeRecording(final LaneData kpiLaneDirection)
155 // {
156 // // Nothing to do -- we get data on all GTUs
157 // }
158 //
159 // /**
160 // * Sample the data received from a GTU.
161 // * @param timeStamp time of the sampling
162 // * @param gtuId gtu
163 // * @param laneId lane
164 // * @param forward driving direction
165 // * @param longitudinalPosition position
166 // * @param speed speed
167 // * @param acceleration acceleration
168 // */
169 // protected void sample(double timeStamp, String gtuId, String laneId, boolean forward, double longitudinalPosition,
170 // double speed, double acceleration)
171 // {
172 // // update clock
173 // updateClock(timeStamp);
174 // if (!this.lanes.containsKey(laneId) || !this.gtus.containsKey(gtuId))
175 // {
176 // // lane not part of this network, or new message of gtu not (yet) received
177 // return;
178 // }
179 // LaneData kpiLaneDirection = new LaneData(this.lanes.get(laneId),
180 // forward ? KpiGtuDirectionality.DIR_PLUS : KpiGtuDirectionality.DIR_MINUS);
181 // GtuData gtu = this.gtus.get(gtuId);
182 // if (this.lastLanes.containsKey(gtuId) && contains(this.lastLanes.get(gtuId))
183 // && !this.lastLanes.get(gtuId).equals(kpiLaneDirection))
184 // {
185 // processGtuRemoveEvent(this.lastLanes.get(gtuId), gtu);
186 // }
187 // if ((!this.lastLanes.containsKey(gtuId) || !this.lastLanes.get(gtuId).equals(kpiLaneDirection))
188 // && contains(kpiLaneDirection))
189 // {
190 // processGtuAddEvent(kpiLaneDirection, new Length(longitudinalPosition, LengthUnit.SI),
191 // new Speed(speed, SpeedUnit.SI), new Acceleration(acceleration, AccelerationUnit.SI), now(), gtu);
192 // }
193 // else if (contains(kpiLaneDirection))
194 // {
195 // // TEST LOOP
196 // for (Trajectory trajectory : getTrajectoryGroup(kpiLaneDirection).getTrajectories())
197 // {
198 // if (trajectory.getGtuId().equals(gtu.getId()))
199 // {
200 // float[] x = trajectory.getX();
201 // float pos = (float) (kpiLaneDirection.getKpiDirection().isPlus() ? longitudinalPosition
202 // : kpiLaneDirection.getLaneData().getLength().si - longitudinalPosition);
203 // if (pos < x[x.length - 1])
204 // {
205 // System.err.println("Vehicle " + gtu.getId() + " is moving backwards on lane "
206 // + kpiLaneDirection.getLaneData() + " or direction on lane is incorrect.");
207 // }
208 // break;
209 // }
210 // }
211 // // END TEST LOOP
212 // // move on current
213 // processGtuMoveEvent(kpiLaneDirection, new Length(longitudinalPosition, LengthUnit.SI),
214 // new Speed(speed, SpeedUnit.SI), new Acceleration(acceleration, AccelerationUnit.SI), now(), gtu);
215 // }
216 // this.lastLanes.put(gtuId, kpiLaneDirection);
217 // }
218 //
219 // /**
220 // * @param imbKpiTransceiver set imbKpiTransceiver.
221 // */
222 // public void setImbKpiTransceiver(Sim0MQKpiTransceiver imbKpiTransceiver)
223 // {
224 // this.imbKpiTransceiver = imbKpiTransceiver;
225 // }
226 //
227 // /**
228 // * Updates clock and triggers timed events.
229 // * @param timeStamp most recent time stamp
230 // */
231 // protected void updateClock(double timeStamp)
232 // {
233 // if (this.lastTimestamp.si >= timeStamp && this.lastTimestamp.si > 0)
234 // {
235 // return;
236 // }
237 // if (this.imbKpiTransceiver != null)
238 // {
239 // this.imbKpiTransceiver.notifyTime(now());
240 // }
241 // this.lastTimestamp = new Time(timeStamp, TimeUnit.SI);
242 // Iterator<LaneData> iterator = this.startRecordingMap.keySet().iterator();
243 // while (iterator.hasNext())
244 // {
245 // LaneData kpiLaneDirection = iterator.next();
246 // if (now().ge(this.startRecordingMap.get(kpiLaneDirection)))
247 // {
248 // startRecording(kpiLaneDirection);
249 // iterator.remove();
250 // }
251 // }
252 // iterator = this.stopRecordingMap.keySet().iterator();
253 // while (iterator.hasNext())
254 // {
255 // LaneData kpiLaneDirection = iterator.next();
256 // if (now().ge(this.stopRecordingMap.get(kpiLaneDirection)))
257 // {
258 // stopRecording(kpiLaneDirection);
259 // iterator.remove();
260 // }
261 // }
262 // }
263 //
264 // /* ************************************************************************************************************** */
265 // /* ********************************************** GTU LISTENER ************************************************** */
266 // /* ************************************************************************************************************** */
267 //
268 // /** the IMB GTU listener. */
269 // private static class GTUTransceiver implements Transceiver
270 // {
271 // /** the sampler. */
272 // private final Sim0MQSampler sampler;
273 //
274 // /** The IMBConnector. */
275 // private final IMBConnector imbConnector;
276 //
277 // /**
278 // * @param sampler the sampler
279 // * @param imbConnector the connector
280 // */
281 // public GTUTransceiver(final Sim0MQSampler sampler, final IMBConnector imbConnector)
282 // {
283 // this.imbConnector = imbConnector;
284 // this.sampler = sampler;
285 // }
286 //
287 // /** {@inheritDoc} */
288 // @Override
289 // @SuppressWarnings("unused")
290 // public void handleMessageFromIMB(String imbEventName, TByteBuffer imbPayload) throws IMBException
291 // {
292 // int imbEventTypeNr = imbPayload.readInt32();
293 // switch (imbEventTypeNr)
294 // {
295 // case TEventEntry.ACTION_NEW:
296 // {
297 // double timeStamp = imbPayload.readDouble();
298 // String gtuId = imbPayload.readString();
299 // double x = imbPayload.readDouble();
300 // double y = imbPayload.readDouble();
301 // double z = imbPayload.readDouble();
302 // double rotZ = imbPayload.readDouble();
303 // String networkId = imbPayload.readString();
304 // String linkId = imbPayload.readString();
305 // // TODO laneId should be unique on its own
306 // String laneId = linkId + "." + imbPayload.readString();
307 // double longitudinalPosition = imbPayload.readDouble();
308 // double length = imbPayload.readDouble();
309 // double width = imbPayload.readDouble();
310 // byte r = imbPayload.readByte();
311 // byte g = imbPayload.readByte();
312 // byte b = imbPayload.readByte();
313 //
314 // // TODO GTU Type and Route should be part of the NEW message
315 // GtuData gtuData = new GtuData(gtuId, this.sampler.defaultGtuType, this.sampler.defaultRoute);
316 // this.sampler.gtus.put(gtuId, gtuData);
317 // break;
318 // }
319 //
320 // case TEventEntry.ACTION_CHANGE:
321 // {
322 // double timeStamp = imbPayload.readDouble();
323 // String gtuId = imbPayload.readString();
324 // double x = imbPayload.readDouble();
325 // double y = imbPayload.readDouble();
326 // double z = imbPayload.readDouble();
327 // double rotZ = imbPayload.readDouble();
328 // String networkId = imbPayload.readString();
329 // String linkId = imbPayload.readString();
330 // // TODO laneId should be unique on its own
331 // String laneId = linkId + "." + imbPayload.readString();
332 // double longitudinalPosition = imbPayload.readDouble();
333 // double speed = imbPayload.readDouble();
334 // double acceleration = imbPayload.readDouble();
335 // String turnIndicatorStatus = imbPayload.readString();
336 // boolean brakingLights = imbPayload.readBoolean();
337 // double odometer = imbPayload.readDouble();
338 // boolean forward = true;
339 //
340 // this.sampler.sample(timeStamp, gtuId, laneId, forward, longitudinalPosition, speed, acceleration);
341 //
342 // break;
343 // }
344 //
345 // case TEventEntry.ACTION_DELETE:
346 // {
347 // // ignore for now.
348 // break;
349 // }
350 //
351 // default:
352 // break;
353 // }
354 // }
355 //
356 // @Override
357 // public String getId()
358 // {
359 // return "GTU";
360 // }
361 //
362 // @Override
363 // public Connector getConnector()
364 // {
365 // return this.imbConnector;
366 // }
367 // }
368 //
369 // /* ************************************************************************************************************** */
370 // /* ********************************************* NODE LISTENER ************************************************** */
371 // /* ************************************************************************************************************** */
372 //
373 // /** the IMB Node listener. */
374 // private static class NodeTransceiver implements Transceiver
375 // {
376 // /** the sampler. */
377 // private final Sim0MQSampler sampler;
378 //
379 // /** The IMBConnector. */
380 // private final IMBConnector imbConnector;
381 //
382 // /**
383 // * @param sampler the sampler
384 // * @param imbConnector the connector
385 // */
386 // public NodeTransceiver(final Sim0MQSampler sampler, final IMBConnector imbConnector)
387 // {
388 // this.imbConnector = imbConnector;
389 // this.sampler = sampler;
390 // }
391 //
392 // /** {@inheritDoc} */
393 // @Override
394 // @SuppressWarnings("unused")
395 // public void handleMessageFromIMB(String imbEventName, TByteBuffer imbPayload) throws IMBException
396 // {
397 // int imbEventTypeNr = imbPayload.readInt32();
398 // switch (imbEventTypeNr)
399 // {
400 // case TEventEntry.ACTION_NEW:
401 // {
402 // double timeStamp = imbPayload.readDouble();
403 // String networkId = imbPayload.readString();
404 // String nodeId = imbPayload.readString();
405 // System.out.println("Node " + nodeId + " received.");
406 // double x = imbPayload.readDouble();
407 // double y = imbPayload.readDouble();
408 // double z = imbPayload.readDouble();
409 // CartesianPoint p = new CartesianPoint(x, y, z);
410 // NodeData nodeData = new NodeData(nodeId, p);
411 // this.sampler.nodes.put(nodeId, nodeData);
412 // break;
413 // }
414 //
415 // case TEventEntry.ACTION_CHANGE:
416 // {
417 // // ignore for now.
418 // break;
419 // }
420 //
421 // case TEventEntry.ACTION_DELETE:
422 // {
423 // // ignore for now.
424 // break;
425 // }
426 //
427 // default:
428 // break;
429 // }
430 // }
431 //
432 // @Override
433 // public String getId()
434 // {
435 // return "Node";
436 // }
437 //
438 // @Override
439 // public Connector getConnector()
440 // {
441 // return this.imbConnector;
442 // }
443 // }
444 //
445 // /* ************************************************************************************************************** */
446 // /* ********************************************* LINK LISTENER ************************************************** */
447 // /* ************************************************************************************************************** */
448 //
449 // /** the IMB Link listener. */
450 // private static class LinkTransceiver implements Transceiver
451 // {
452 // /** the sampler. */
453 // private final Sim0MQSampler sampler;
454 //
455 // /** The IMBConnector. */
456 // private final IMBConnector imbConnector;
457 //
458 // /**
459 // * @param sampler the sampler
460 // * @param imbConnector the connector
461 // */
462 // public LinkTransceiver(final Sim0MQSampler sampler, final IMBConnector imbConnector)
463 // {
464 // this.imbConnector = imbConnector;
465 // this.sampler = sampler;
466 // }
467 //
468 // /** {@inheritDoc} */
469 // @Override
470 // @SuppressWarnings("unused")
471 // public void handleMessageFromIMB(String imbEventName, TByteBuffer imbPayload) throws IMBException
472 // {
473 // int imbEventTypeNr = imbPayload.readInt32();
474 // switch (imbEventTypeNr)
475 // {
476 // case TEventEntry.ACTION_NEW:
477 // {
478 // double timeStamp = imbPayload.readDouble();
479 // String networkId = imbPayload.readString();
480 // String linkId = imbPayload.readString();
481 // System.out.println("Link " + linkId + " received.");
482 // String startNodeId = imbPayload.readString();
483 // String endNodeId = imbPayload.readString();
484 // int dlNumPoints = imbPayload.readInt32();
485 // double len = 0.0;
486 // double x = imbPayload.readDouble();
487 // double y = imbPayload.readDouble();
488 // double z = imbPayload.readDouble();
489 // CartesianPoint p1 = new CartesianPoint(x, y, z);
490 // for (int i = 1; i < dlNumPoints; i++)
491 // {
492 // x = imbPayload.readDouble();
493 // y = imbPayload.readDouble();
494 // z = imbPayload.readDouble();
495 // CartesianPoint p2 = new CartesianPoint(x, y, z);
496 // len += p1.distance(p2);
497 // p1 = p2;
498 // }
499 // Length length = new Length(len, LengthUnit.SI);
500 // LinkData linkData = new LinkData(linkId, this.sampler.nodes.get(startNodeId),
501 // this.sampler.nodes.get(endNodeId), length);
502 // this.sampler.links.put(linkId, linkData);
503 // break;
504 // }
505 //
506 // case TEventEntry.ACTION_CHANGE:
507 // {
508 // // ignore for now.
509 // break;
510 // }
511 //
512 // case TEventEntry.ACTION_DELETE:
513 // {
514 // // ignore for now.
515 // break;
516 // }
517 //
518 // default:
519 // break;
520 // }
521 // }
522 //
523 // @Override
524 // public String getId()
525 // {
526 // return "Link_GTU";
527 // }
528 //
529 // @Override
530 // public Connector getConnector()
531 // {
532 // return this.imbConnector;
533 // }
534 // }
535 //
536 // /* ************************************************************************************************************** */
537 // /* ********************************************* LANE LISTENER ************************************************** */
538 // /* ************************************************************************************************************** */
539 //
540 // /** the IMB Lane listener. */
541 // private static class LaneTransceiver implements Transceiver
542 // {
543 // /** the sampler. */
544 // private final Sim0MQSampler sampler;
545 //
546 // /** The IMBConnector. */
547 // private final IMBConnector imbConnector;
548 //
549 // /**
550 // * @param sampler the sampler
551 // * @param imbConnector the connector
552 // */
553 // public LaneTransceiver(final Sim0MQSampler sampler, final IMBConnector imbConnector)
554 // {
555 // this.imbConnector = imbConnector;
556 // this.sampler = sampler;
557 // }
558 //
559 // /** {@inheritDoc} */
560 // @Override
561 // @SuppressWarnings("unused")
562 // public void handleMessageFromIMB(String imbEventName, TByteBuffer imbPayload) throws IMBException
563 // {
564 // int imbEventTypeNr = imbPayload.readInt32();
565 // switch (imbEventTypeNr)
566 // {
567 // case TEventEntry.ACTION_NEW:
568 // {
569 // double timeStamp = imbPayload.readDouble();
570 // String networkId = imbPayload.readString();
571 // String linkId = imbPayload.readString();
572 // // TODO laneId should be unique on its own, or keep network, link and lane id separate
573 // String laneId = linkId + "." + imbPayload.readString();
574 // System.out.println("Lane " + laneId + " received.");
575 // int laneNumber = imbPayload.readInt32();
576 // int dlNumPoints = imbPayload.readInt32();
577 // double len = 0.0;
578 // double x = imbPayload.readDouble();
579 // double y = imbPayload.readDouble();
580 // double z = imbPayload.readDouble();
581 // CartesianPoint p1 = new CartesianPoint(x, y, z);
582 // for (int i = 1; i < dlNumPoints; i++)
583 // {
584 // x = imbPayload.readDouble();
585 // y = imbPayload.readDouble();
586 // z = imbPayload.readDouble();
587 // CartesianPoint p2 = new CartesianPoint(x, y, z);
588 // len += p1.distance(p2);
589 // p1 = p2;
590 // }
591 // Length length = new Length(len, LengthUnit.SI);
592 // if (!this.sampler.links.containsKey(linkId))
593 // {
594 // System.out.println("Link not received.");
595 // }
596 // LaneData laneData = new LaneData(this.sampler.links.get(linkId), laneId, length);
597 // if (this.sampler.lanes.containsKey(laneId))
598 // {
599 // System.out.println("Lanes not unique.");
600 // }
601 // this.sampler.lanes.put(laneId, laneData);
602 // break;
603 // }
604 //
605 // case TEventEntry.ACTION_CHANGE:
606 // {
607 // // ignore for now.
608 // break;
609 // }
610 //
611 // case TEventEntry.ACTION_DELETE:
612 // {
613 // // ignore for now.
614 // break;
615 // }
616 //
617 // default:
618 // break;
619 // }
620 // }
621 //
622 // @Override
623 // public String getId()
624 // {
625 // return "Lane_GTU";
626 // }
627 //
628 // @Override
629 // public Connector getConnector()
630 // {
631 // return this.imbConnector;
632 // }
633 // }
634 //
635 }