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