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