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-2018 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 }