View Javadoc
1   package org.opentrafficsim.imb.transceiver.urbanstrategy;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import org.djunits.unit.SpeedUnit;
7   import org.djunits.unit.TimeUnit;
8   import org.djunits.value.vdouble.scalar.Dimensionless;
9   import org.djunits.value.vdouble.scalar.Duration;
10  import org.djunits.value.vdouble.scalar.Length;
11  import org.djunits.value.vdouble.scalar.Speed;
12  import org.djunits.value.vdouble.scalar.Time;
13  import org.opentrafficsim.core.network.Network;
14  import org.opentrafficsim.imb.IMBException;
15  import org.opentrafficsim.imb.connector.Connector;
16  import org.opentrafficsim.imb.connector.Connector.IMBEventType;
17  import org.opentrafficsim.imb.transceiver.AbstractTransceiver;
18  import org.opentrafficsim.kpi.sampling.Query;
19  import org.opentrafficsim.kpi.sampling.indicator.MeanSpeed;
20  import org.opentrafficsim.kpi.sampling.indicator.MeanTravelTime;
21  import org.opentrafficsim.kpi.sampling.indicator.MeanTripLength;
22  import org.opentrafficsim.kpi.sampling.indicator.TotalDelay;
23  import org.opentrafficsim.kpi.sampling.indicator.TotalNumberOfStops;
24  import org.opentrafficsim.kpi.sampling.indicator.TotalTravelDistance;
25  import org.opentrafficsim.kpi.sampling.indicator.TotalTravelTime;
26  import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
27  
28  import nl.tudelft.simulation.dsol.SimRuntimeException;
29  
30  /**
31   * OTS can publish messages about statistics or Key Performance Indicators (KPIs) of the relation between GTUs and a part of the
32   * network. Examples are average speeds, travel times, trip durations, and number of stops. The statistics can be transmitted
33   * via IMB at certain intervals. The statistics are based on the classes in the ots.road.sampling package. Most statistics
34   * consider a time interval (can be unbound) and a region in space (a collection of lanes; can be the entire network), filtered
35   * on metadata such as GTU type, origin, destination, or route.<br>
36   * When a statistic is published for the first time, a NEW message is sent to IMB to identify the type of statistic, the time
37   * interval and the lane(s) for which the statistic is calculated, and the metadata used to filter the GTUs. The CHANGE message
38   * is posted whenever an updated statistic is available, or when the sample frequency time is reached. When a statistic is no
39   * longer published, a DELETE event is posted. The Graph NEW messages are posted after the Network NEW, Node NEW, Link NEW, and
40   * Lane NEW messages are posted, as it has to be able to identify Lanes.
41   * <p>
42   * <style>table,th,td {border:1px solid grey; border-style:solid; text-align:left; border-collapse: collapse;}</style>
43   * <h2>NEW</h2>
44   * <table summary="" style="width:800px;">
45   * <thead>
46   * <tr>
47   * <th style="width:25%;">Variable</th>
48   * <th style="width:15%;">Type</th>
49   * <th style="width:60%;">Comments</th>
50   * </tr>
51   * </thead><tbody>
52   * <tr>
53   * <td>timestamp</td>
54   * <td>double</td>
55   * <td>time of the event, in simulation time seconds</td>
56   * </tr>
57   * <tr>
58   * <td>statisticId</td>
59   * <td>String</td>
60   * <td>a unique id for the statistic, e.g. a UUID string</td>
61   * </tr>
62   * <tr>
63   * <td>description</td>
64   * <td>String</td>
65   * <td>textual description of the statistic</td>
66   * </tr>
67   * <tr>
68   * <td>networkId</td>
69   * <td>String</td>
70   * <td>id of the Network for which the statistic is made</td>
71   * </tr>
72   * <tr>
73   * <td>numberMetadataEntries</td>
74   * <td>int</td>
75   * <td>number of metadata entries</td>
76   * </tr>
77   * <tr>
78   * <td>metadataId_1</td>
79   * <td>String</td>
80   * <td>id of the first metadata entry</td>
81   * </tr>
82   * <tr>
83   * <td>metadataType_1</td>
84   * <td>String</td>
85   * <td>type of metadata, one of GTUTYPE, ORIGIN, DESTINATION, ROUTE</td>
86   * </tr>
87   * <tr>
88   * <td>metadataValue_1</td>
89   * <td>String</td>
90   * <td>value of the first metadata entry</td>
91   * </tr>
92   * <tr>
93   * <td>...</td>
94   * <td>&nbsp;</td>
95   * <td>&nbsp;</td>
96   * </tr>
97   * <tr>
98   * <td>metadataId_n</td>
99   * <td>String</td> <tdid of the last metadata entry</td>
100  * </tr>
101  * <tr>
102  * <td>metadataType_n</td>
103  * <td>String</td>
104  * <td>type of metadata, one of GTUTYPE, ORIGIN, DESTINATION, ROUTE</td>
105  * </tr>
106  * <tr>
107  * <td>metadataValue_n</td>
108  * <td>String</td>
109  * <td>value of the last metadata entry</td>
110  * </tr>
111  * <td>numberSpaceTimeRegions</td>
112  * <td>int</td>
113  * <td>number of space-time regions for this statistic</td> </tr>
114  * <tr>
115  * <td>startTime_1</td>
116  * <td>double</td>
117  * <td>start time for the first space time region, in seconds</td>
118  * </tr>
119  * <tr>
120  * <td>endTime_1</td>
121  * <td>double</td>
122  * <td>end time for the first space time region, in seconds</td>
123  * </tr>
124  * <tr>
125  * <td>linkId_1</td>
126  * <td>String</td>
127  * <td>id of the first Link for the space-time region</td>
128  * </tr>
129  * <tr>
130  * <td>laneId_1</td>
131  * <td>String</td>
132  * <td>id of the first Lane in the link for the space-time region</td>
133  * </tr>
134  * <tr>
135  * <td>...</td>
136  * <td>&nbsp;</td>
137  * <td>&nbsp;</td>
138  * </tr>
139  * <tr>
140  * <td>startTime_n</td>
141  * <td>double</td>
142  * <td>start time for the last space time region, in seconds</td>
143  * </tr>
144  * <tr>
145  * <td>endTime_n</td>
146  * <td>double</td>
147  * <td>end time for the last space time region, in seconds</td>
148  * </tr>
149  * <tr>
150  * <td>linkId_n</td>
151  * <td>String</td>
152  * <td>id of the last Link for the space-time region</td>
153  * </tr>
154  * <tr>
155  * <td>laneId_n</td>
156  * <td>String</td>
157  * <td>id of the last Lane in the link for the space-time region</td>
158  * </tr>
159  * <tr>
160  * <td>connected</td>
161  * <td>boolean</td>
162  * <td>whether the lanes in the space-time regions are longitudinally connected or not</td>
163  * </tr>
164  * <tr>
165  * <td>totalTrajectory</td>
166  * <td>boolean</td>
167  * <td>whether the sampling takes place of GTUs that have traveled the entire space region or not</td>
168  * </tr>
169  * <tr>
170  * <td>transmissionInterval</td>
171  * <td>double</td>
172  * <td>transmission interval of the statistic in seconds</td>
173  * </tr>
174  * </tbody>
175  * </table>
176  * </p>
177  * <p>
178  * <h2>CHANGE</h2>
179  * <table summary="" style="width:800px;">
180  * <thead>
181  * <tr>
182  * <th style="width:25%;">Variable</th>
183  * <th style="width:15%;">Type</th>
184  * <th style="width:60%;">Comments</th>
185  * </tr>
186  * </thead><tbody>
187  * <tr>
188  * <td>timestamp</td>
189  * <td>double</td>
190  * <td>time of the event, in simulation time seconds</td>
191  * </tr>
192  * <tr>
193  * <td>statisticId</td>
194  * <td>String</td>
195  * <td>the unique id for the statistic, e.g. a UUID string</td>
196  * </tr>
197  * <tr>
198  * <td>totalGtuDistance/td>
199  * <td>double</td>
200  * <td>total distance traveled by filtered GTUs in the given time and space, in meters</td>
201  * </tr>
202  * <tr>
203  * <td>totalGtuTravelTime/td>
204  * <td>double</td>
205  * <td>total travel time by filtered GTUs in the given time and space, in seconds</td>
206  * </tr>
207  * <tr>
208  * <td>averageGtuSpeed/td>
209  * <td>double</td>
210  * <td>average filtered GTU speed in the given time and space, in meter/second</td>
211  * </tr>
212  * <tr>
213  * <td>averageGtuTravelTime/td>
214  * <td>double</td>
215  * <td>average filtered GTU travel time in the given time and space, in seconds</td>
216  * </tr>
217  * <tr>
218  * <td>totalGtuTimeDelay/td>
219  * <td>double</td>
220  * <td>total time delay incurred by the filtered GTUs in the given time and space, in seconds</td>
221  * </tr>
222  * <tr>
223  * <td>averageTripLength/td>
224  * <td>double</td>
225  * <td>average length of the trip of the filtered GTUs in the given time and space, in seconds</td>
226  * </tr>
227  * <tr>
228  * <td>totalNumberStops/td>
229  * <td>double</td>
230  * <td>total number of stops that GTUs made in the given time and space, dimensionless</td>
231  * </tr>
232  * </tbody>
233  * </table>
234  * </p>
235  * <p>
236  * <h2>DELETE</h2>
237  * <table summary="" style="width:800px;">
238  * <thead>
239  * <tr>
240  * <th style="width:25%;">Variable</th>
241  * <th style="width:15%;">Type</th>
242  * <th style="width:60%;">Comments</th>
243  * </tr>
244  * </thead><tbody>
245  * <tr>
246  * <td>timestamp</td>
247  * <td>double</td>
248  * <td>time of the event, in simulation time seconds</td>
249  * </tr>
250  * <tr>
251  * <td>statisticId</td>
252  * <td>String</td>
253  * <td>the unique id for the statistic that is removed</td>
254  * </tr>
255  * </tbody>
256  * </table>
257  * </p>
258  * <p>
259  * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
260  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
261  * <p>
262  * @version $Revision$, $LastChangedDate$, by $Author$, initial version Sep 16, 2016 <br>
263  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
264  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
265  */
266 public class StatisticsGTULaneTransceiver extends AbstractTransceiver
267 {
268     /** */
269     private static final long serialVersionUID = 20160923L;
270 
271     /** The query for the statistic. */
272     private final Query query;
273 
274     /** The Network id for which the graph is made. */
275     private final String networkId;
276 
277     /** The interval between generation of graphs. */
278     private final Duration transmissionInterval;
279 
280     private TotalTravelDistance totalTravelDistance = new TotalTravelDistance();
281 
282     private TotalTravelTime totalTravelTime = new TotalTravelTime();
283 
284     private MeanSpeed meanSpeed = new MeanSpeed(this.totalTravelDistance, this.totalTravelTime);
285 
286     private MeanTravelTime meanTravelTime = new MeanTravelTime(this.meanSpeed);
287 
288     private MeanTripLength meanTripLength = new MeanTripLength();
289 
290     private TotalDelay totalDelay = new TotalDelay(new Speed(80.0, SpeedUnit.KM_PER_HOUR));
291 
292     private TotalNumberOfStops totalNumberOfStops = new TotalNumberOfStops();
293 
294     // TODO implement DELETE message
295 
296     /**
297      * Construct a new StatisticsGTULaneTransceiver.
298      * @param connector Connector; the IMB connector
299      * @param simulator SimpleSimulatorInterface; the simulator
300      * @param networkId String; the network id
301      * @param query Query; the statistics query
302      * @param transmissionInterval Duration; the interval between generation of graphs
303      * @throws IMBException when the message cannot be posted, or the scheduling of the publish event fails
304      */
305     public StatisticsGTULaneTransceiver(final Connector connector, SimpleSimulatorInterface simulator, String networkId,
306             final Query query, final Duration transmissionInterval) throws IMBException
307     {
308         super("StatisticsGTULane", connector, simulator);
309         this.query = query;
310         this.networkId = networkId;
311         this.transmissionInterval = transmissionInterval;
312 
313         List<Object> newMessage = new ArrayList<>();
314         newMessage.add(getSimulator().getSimulatorTime().getTime().si);
315         newMessage.add(query.getId());
316         newMessage.add(query.toString());
317         newMessage.add(this.networkId);
318         newMessage.add((int) 0); // TODO numberMetadataEntries
319         newMessage.add((int) 0); // TODO numberSpaceTimeRegions
320         newMessage.add(false); // TODO "connected" not part of query anymore
321         newMessage.add(true); // TODO totalTrajectory
322         newMessage.add(transmissionInterval.si);
323 
324         getConnector().postIMBMessage("StatisticsGTULane", IMBEventType.NEW, newMessage.toArray());
325 
326         try
327         {
328             simulator.scheduleEventRel(this.transmissionInterval, this, this, "sendStatisticsUpdate", new Object[] {});
329         }
330         catch (SimRuntimeException exception)
331         {
332             throw new IMBException(exception);
333         }
334     }
335 
336     /**
337      * @throws IMBException when the transmission of the IMB message fails
338      * @throws SimRuntimeException when the scheduling of the next publish event fails
339      */
340     public void sendStatisticsUpdate() throws IMBException, SimRuntimeException
341     {
342         double time = getSimulator().getSimulatorTime().getTime().si;
343         Length tdist = this.totalTravelDistance.getValue(this.query, new Time(time, TimeUnit.SI));
344         Duration ttt = this.totalTravelTime.getValue(this.query, new Time(time, TimeUnit.SI));
345         Speed ms = this.meanSpeed.getValue(this.query, new Time(time, TimeUnit.SI));
346         Duration mtt = this.meanTravelTime.getValue(this.query, new Time(time, TimeUnit.SI));
347         Length mtl = this.meanTripLength.getValue(this.query, new Time(time, TimeUnit.SI));
348         Duration tdel = this.totalDelay.getValue(this.query, new Time(time, TimeUnit.SI));
349         Dimensionless nos = this.totalNumberOfStops.getValue(this.query, new Time(time, TimeUnit.SI));
350         System.out.println("===== @time " + time + " s =====");
351         System.out.println("Total distance " + tdist);
352         System.out.println("Total travel time " + ttt);
353         System.out.println("Mean speed " + ms);
354         System.out.println("Mean travel time " + mtt);
355         System.out.println("Mean trip length " + mtl);
356         System.out.println("Total delay " + tdel);
357         System.out.println("Number of stops " + nos);
358         getConnector().postIMBMessage(
359                 "StatisticsGTULane",
360                 IMBEventType.CHANGE,
361                 new Object[] { getSimulator().getSimulatorTime().getTime().si, this.query.getId(), tdist.si, ttt.si, ms.si,
362                         mtt.si, tdel.si, mtl.si, nos.si });
363         getSimulator().scheduleEventRel(this.transmissionInterval, this, this, "sendStatisticsUpdate", new Object[] {});
364     }
365 
366 }