1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others. 4 // This program and the accompanying materials 5 // are made available under the terms of the Eclipse Public License v2.0 6 // which accompanies this distribution, and is available at 7 // http://www.eclipse.org/legal/epl-v20.html 8 // SPDX-License-Identifier: EPL-2.0 9 /****************************************************************************/ 10 /// @file MSMeanData.h 11 /// @author Daniel Krajzewicz 12 /// @author Michael Behrisch 13 /// @date Tue, 17.11.2009 14 /// @version $Id$ 15 /// 16 // Data collector for edges/lanes 17 /****************************************************************************/ 18 #ifndef MSMeanData_h 19 #define MSMeanData_h 20 21 22 // =========================================================================== 23 // included modules 24 // =========================================================================== 25 #include <config.h> 26 27 #include <vector> 28 #include <set> 29 #include <list> 30 #include <limits> 31 #include <microsim/output/MSDetectorFileOutput.h> 32 #include <microsim/MSMoveReminder.h> 33 #include <utils/common/SUMOTime.h> 34 35 36 // =========================================================================== 37 // class declarations 38 // =========================================================================== 39 class OutputDevice; 40 class MSEdge; 41 class MSLane; 42 class SUMOTrafficObject; 43 44 typedef std::vector<MSEdge*> MSEdgeVector; 45 46 // =========================================================================== 47 // class definitions 48 // =========================================================================== 49 /** 50 * @class MSMeanData 51 * @brief Data collector for edges/lanes 52 * 53 * This structure does not contain the data itself, it is stored within 54 * MeanDataValues-MoveReminder objects. 55 * This class is used to build the output, optionally, in the case 56 * of edge-based dump, aggregated over the edge's lanes. 57 * 58 * @todo consider error-handling on write (using IOError) 59 */ 60 class MSMeanData : public MSDetectorFileOutput { 61 public: 62 /** 63 * @class MeanDataValues 64 * @brief Data structure for mean (aggregated) edge/lane values 65 * 66 * Structure holding values that describe the emissions (XXX: emissions?) aggregated, refs. #2579 67 * over some seconds. 68 */ 69 class MeanDataValues : public MSMoveReminder { 70 public: 71 /** @brief Constructor */ 72 MeanDataValues(MSLane* const lane, const double length, const bool doAdd, const MSMeanData* const parent); 73 74 /** @brief Destructor */ 75 virtual ~MeanDataValues(); 76 77 78 /** @brief Resets values so they may be used for the next interval 79 */ 80 virtual void reset(bool afterWrite = false) = 0; 81 82 /** @brief Add the values of this to the given one and store them there 83 * 84 * @param[in] val The meandata to add to 85 */ 86 virtual void addTo(MeanDataValues& val) const = 0; 87 88 89 /** @brief Called if the vehicle enters the reminder's lane 90 * 91 * @param[in] veh The entering vehicle. 92 * @param[in] reason how the vehicle enters the lane 93 * @see MSMoveReminder 94 * @see MSMoveReminder::notifyEnter 95 * @see MSMoveReminder::Notification 96 */ 97 virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 98 99 100 /** @brief Checks whether the reminder still has to be notified about the vehicle moves 101 * 102 * Indicator if the reminders is still active for the passed 103 * vehicle/parameters. If false, the vehicle will erase this reminder 104 * from it's reminder-container. 105 * 106 * @param[in] veh Vehicle that asks this reminder. 107 * @param[in] oldPos Position before move. 108 * @param[in] newPos Position after move with newSpeed. 109 * @param[in] newSpeed Moving speed. 110 * 111 * @return True if vehicle hasn't passed the reminder completely. 112 */ 113 bool notifyMove(SUMOTrafficObject& veh, double oldPos, 114 double newPos, double newSpeed); 115 116 117 /** @brief Called if the vehicle leaves the reminder's lane 118 * 119 * @param veh The leaving vehicle. 120 * @param[in] lastPos Position on the lane when leaving. 121 * @param[in] reason how the vehicle leaves the lane 122 * @see MSMoveReminder 123 * @see MSMoveReminder::notifyLeave 124 */ 125 virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos, 126 MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 127 128 129 /** @brief Returns whether any data was collected. 130 * 131 * @return whether no data was collected 132 */ 133 virtual bool isEmpty() const; 134 135 136 /** @brief Called if a per timestep update is needed. Default does nothing. 137 */ 138 virtual void update(); 139 140 /** @brief Writes output values into the given stream 141 * 142 * @param[in] dev The output device to write the data into 143 * @param[in] period Length of the period the data were gathered 144 * @param[in] numLanes The total number of lanes for which the data was collected 145 * @exception IOError If an error on writing occurs (!!! not yet implemented) 146 */ 147 virtual void write(OutputDevice& dev, const SUMOTime period, 148 const double numLanes, const double defaultTravelTime, 149 const int numVehicles = -1) const = 0; 150 151 /** @brief Returns the number of collected sample seconds. 152 * @return the number of collected sample seconds 153 */ 154 virtual double getSamples() const; 155 156 /** @brief Returns the total travelled distance. 157 * @return the total travelled distance 158 */ getTravelledDistance()159 double getTravelledDistance() const { 160 return travelledDistance; 161 } 162 163 protected: 164 /// @brief The meandata parent 165 const MSMeanData* const myParent; 166 167 /// @brief The length of the lane / edge the data collector is on 168 const double myLaneLength; 169 170 /// @name Collected values 171 /// @{ 172 /// @brief The number of sampled vehicle movements (in s) 173 double sampleSeconds; 174 175 /// @brief The sum of the distances the vehicles travelled 176 double travelledDistance; 177 //@} 178 179 }; 180 181 182 /** 183 * @class MeanDataValueTracker 184 * @brief Data structure for mean (aggregated) edge/lane values for tracked vehicles 185 */ 186 class MeanDataValueTracker : public MeanDataValues { 187 public: 188 /** @brief Constructor */ 189 MeanDataValueTracker(MSLane* const lane, const double length, 190 const MSMeanData* const parent); 191 192 /** @brief Destructor */ 193 virtual ~MeanDataValueTracker(); 194 195 /** @brief Resets values so they may be used for the next interval 196 */ 197 void reset(bool afterWrite); 198 199 /** @brief Add the values of this to the given one and store them there 200 * 201 * @param[in] val The meandata to add to 202 */ 203 void addTo(MSMeanData::MeanDataValues& val) const; 204 205 /// @name Methods inherited from MSMoveReminder 206 /// @{ 207 208 /** @brief Internal notification about the vehicle moves 209 * @see MSMoveReminder::notifyMoveInternal(). 210 */ 211 void notifyMoveInternal(const SUMOTrafficObject& veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane); 212 213 214 /** @brief Called if the vehicle leaves the reminder's lane 215 * 216 * @param veh The leaving vehicle. 217 * @param[in] lastPos Position on the lane when leaving. 218 * @param[in] isArrival whether the vehicle arrived at its destination 219 * @param[in] isLaneChange whether the vehicle changed from the lane 220 * @see MSMoveReminder 221 * @see MSMoveReminder::notifyLeave 222 */ 223 bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 224 225 226 /** @brief Computes current values and adds them to their sums 227 * 228 * The fraction of time the vehicle is on the lane is computed and 229 * used as a weight for the vehicle's current values. 230 * The "emitted" field is incremented, additionally. 231 * 232 * @param[in] veh The entering vehicle. 233 * @param[in] reason how the vehicle enters the lane 234 * @see MSMoveReminder::notifyEnter 235 * @return Always true 236 */ 237 bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 238 //@} 239 240 bool isEmpty() const; 241 242 /** @brief Writes output values into the given stream 243 * 244 * @param[in] dev The output device to write the data into 245 * @param[in] period Length of the period the data were gathered 246 * @param[in] numLanes The total number of lanes for which the data was collected 247 * @exception IOError If an error on writing occurs (!!! not yet implemented) 248 */ 249 void write(OutputDevice& dev, const SUMOTime period, 250 const double numLanes, const double defaultTravelTime, 251 const int numVehicles = -1) const; 252 253 int getNumReady() const; 254 255 void clearFirst(); 256 257 double getSamples() const; 258 259 private: 260 class TrackerEntry { 261 public: 262 /** @brief Constructor */ TrackerEntry(MeanDataValues * const values)263 TrackerEntry(MeanDataValues* const values) 264 : myNumVehicleEntered(0), myNumVehicleLeft(0), myValues(values) {} 265 266 /** @brief Constructor */ ~TrackerEntry()267 virtual ~TrackerEntry() { 268 delete myValues; 269 } 270 271 /// @brief The number of vehicles which entered in the current interval 272 int myNumVehicleEntered; 273 274 /// @brief The number of vehicles which left in the current interval 275 int myNumVehicleLeft; 276 277 /// @brief The number of vehicles which left in the current interval 278 MeanDataValues* myValues; 279 }; 280 281 /// @brief The map of vehicles to data entries 282 std::map<const SUMOTrafficObject*, TrackerEntry*> myTrackedData; 283 284 /// @brief The currently active meandata "intervals" 285 std::list<TrackerEntry*> myCurrentData; 286 287 }; 288 289 290 public: 291 /** @brief Constructor 292 * 293 * @param[in] id The id of the detector 294 * @param[in] dumpBegin Begin time of dump 295 * @param[in] dumpEnd End time of dump 296 * @param[in] useLanes Information whether lane-based or edge-based dump shall be generated 297 * @param[in] withEmpty Information whether empty lanes/edges shall be written 298 * @param[in] withInternal Information whether internal lanes/edges shall be written 299 * @param[in] trackVehicles Information whether vehicles shall be tracked 300 * @param[in] detectPersons Whether pedestrians shall be detected instead of vehicles 301 * @param[in] maxTravelTime the maximum travel time to use when calculating per vehicle output 302 * @param[in] defaultEffort the value to use when calculating defaults 303 * @param[in] minSamples the minimum number of sample seconds before the values are valid 304 * @param[in] vTypes the set of vehicle types to consider 305 */ 306 MSMeanData(const std::string& id, 307 const SUMOTime dumpBegin, const SUMOTime dumpEnd, 308 const bool useLanes, const bool withEmpty, 309 const bool printDefaults, const bool withInternal, 310 const bool trackVehicles, const int detectPersons, 311 const double minSamples, 312 const double maxTravelTime, 313 const std::string& vTypes); 314 315 316 /// @brief Destructor 317 virtual ~MSMeanData(); 318 319 /** @brief Adds the value collectors to all relevant edges. 320 */ 321 void init(); 322 323 /// @name Methods inherited from MSDetectorFileOutput. 324 /// @{ 325 326 /** @brief Writes collected values into the given stream 327 * 328 * At first, it is checked whether the values for the current interval shall be written. 329 * If not, a reset is performed, only, using "resetOnly". Otherwise, 330 * both the list of single-lane edges and the list of multi-lane edges 331 * are gone through and each edge is written using "writeEdge". 332 * 333 * @param[in] dev The output device to write the data into 334 * @param[in] startTime First time step the data were gathered 335 * @param[in] stopTime Last time step the data were gathered 336 * @see MSDetectorFileOutput::writeXMLOutput 337 * @see write 338 * @exception IOError If an error on writing occurs (!!! not yet implemented) 339 */ 340 void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime); 341 342 /** @brief Opens the XML-output using "netstats" as root element 343 * 344 * @param[in] dev The output device to write the root into 345 * @see MSDetectorFileOutput::writeXMLDetectorProlog 346 * @exception IOError If an error on writing occurs (!!! not yet implemented) 347 */ 348 virtual void writeXMLDetectorProlog(OutputDevice& dev) const; 349 /// @} 350 351 /** @brief Updates the detector 352 */ 353 virtual void detectorUpdate(const SUMOTime step); 354 getMinSamples()355 double getMinSamples() const { 356 return myMinSamples; 357 } 358 getMaxTravelTime()359 double getMaxTravelTime() const { 360 return myMaxTravelTime; 361 } 362 363 364 protected: 365 /** @brief Create an instance of MeanDataValues 366 * 367 * @param[in] lane The lane to create for 368 * @param[in] doAdd whether to add the values as reminder to the lane 369 */ 370 virtual MSMeanData::MeanDataValues* createValues(MSLane* const lane, const double length, const bool doAdd) const = 0; 371 372 /** @brief Resets network value in order to allow processing of the next interval 373 * 374 * Goes through the lists of edges and starts "resetOnly" for each edge. 375 * @param[in] edge The last time step that is reported 376 */ 377 void resetOnly(SUMOTime stopTime); 378 379 /** @brief Return the relevant edge id 380 * 381 * @param[in] edge The edge to retrieve the id for 382 */ 383 virtual std::string getEdgeID(const MSEdge* const edge); 384 385 /** @brief Writes edge values into the given stream 386 * 387 * microsim: It is checked whether the dump shall be generated edge- 388 * or lane-wise. In the first case, the lane-data are collected 389 * and aggregated and written directly. In the second case, "writeLane" 390 * is used to write each lane's state. 391 * 392 * @param[in] dev The output device to write the data into 393 * @param[in] edgeValues List of this edge's value collectors 394 * @param[in] edge The edge to write the dump of 395 * @param[in] startTime First time step the data were gathered 396 * @param[in] stopTime Last time step the data were gathered 397 * @exception IOError If an error on writing occurs (!!! not yet implemented) 398 */ 399 void writeEdge(OutputDevice& dev, const std::vector<MeanDataValues*>& edgeValues, 400 MSEdge* edge, SUMOTime startTime, SUMOTime stopTime); 401 402 /** @brief Writes the interval opener 403 * 404 * @param[in] dev The output device to write the data into 405 * @param[in] startTime First time step the data were gathered 406 * @param[in] stopTime Last time step the data were gathered 407 */ 408 virtual void openInterval(OutputDevice& dev, const SUMOTime startTime, const SUMOTime stopTime); 409 410 /** @brief Checks for emptiness and writes prefix into the given stream 411 * 412 * @param[in] dev The output device to write the data into 413 * @param[in] values The values to check for emptiness 414 * @param[in] tag The xml tag to write (lane / edge) 415 * @param[in] id The id for the lane / edge to write 416 * @return whether further output should be generated 417 * @exception IOError If an error on writing occurs (!!! not yet implemented) 418 */ 419 virtual bool writePrefix(OutputDevice& dev, const MeanDataValues& values, 420 const SumoXMLTag tag, const std::string id) const; 421 422 protected: 423 /// @brief the minimum sample seconds 424 const double myMinSamples; 425 426 /// @brief the maximum travel time to write 427 const double myMaxTravelTime; 428 429 /// @brief Value collectors; sorted by edge, then by lane 430 std::vector<std::vector<MeanDataValues*> > myMeasures; 431 432 /// @brief Whether empty lanes/edges shall be written 433 const bool myDumpEmpty; 434 435 private: 436 /// @brief Information whether the output shall be edge-based (not lane-based) 437 const bool myAmEdgeBased; 438 439 /// @brief The first and the last time step to write information (-1 indicates always) 440 const SUMOTime myDumpBegin, myDumpEnd; 441 442 /// @brief The corresponding first edges 443 MSEdgeVector myEdges; 444 445 /// @brief Whether empty lanes/edges shall be written 446 const bool myPrintDefaults; 447 448 /// @brief Whether internal lanes/edges shall be written 449 const bool myDumpInternal; 450 451 /// @brief Whether vehicles are tracked 452 const bool myTrackVehicles; 453 454 /// @brief The intervals for which output still has to be generated (only in the tracking case) 455 std::list< std::pair<SUMOTime, SUMOTime> > myPendingIntervals; 456 457 private: 458 /// @brief Invalidated copy constructor. 459 MSMeanData(const MSMeanData&); 460 461 /// @brief Invalidated assignment operator. 462 MSMeanData& operator=(const MSMeanData&); 463 464 }; 465 466 467 #endif 468 469 /****************************************************************************/ 470 471