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