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