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