View Javadoc
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 }