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