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 MSE2Collector.h 11 /// @author Christian Roessel 12 /// @author Daniel Krajzewicz 13 /// @author Sascha Krieg 14 /// @author Michael Behrisch 15 /// @author Robbin Blokpoel 16 /// @author Jakob Erdmann 17 /// @author Leonhard Luecken 18 /// @date Mon Feb 03 2014 14:13 CET 19 /// @version $Id$ 20 /// 21 // An areal detector covering to a sequence of consecutive lanes 22 /****************************************************************************/ 23 #ifndef MSE2Collector_h 24 #define MSE2Collector_h 25 26 27 // =========================================================================== 28 // included modules 29 // =========================================================================== 30 #include <config.h> 31 32 #include <vector> 33 #include <list> 34 #include <microsim/MSLane.h> 35 #include <microsim/MSNet.h> 36 #include <microsim/MSMoveReminder.h> 37 #include <microsim/output/MSDetectorFileOutput.h> 38 #include <utils/common/UtilExceptions.h> 39 #include <cassert> 40 41 // =========================================================================== 42 // class declarations 43 // =========================================================================== 44 class OutputDevice; 45 class SUMOVehicle; 46 class SUMOTrafficObject; 47 48 49 // =========================================================================== 50 // class definitions 51 // =========================================================================== 52 /** 53 * @class MSE2Collector 54 * @brief An areal detector corresponding to a sequence of consecutive lanes 55 * 56 * This detector traces vehicles which are on a sequence of consecutive lanes. A 57 * vehicle that enters the detector is stored and the stored vehicles' speeds 58 * are used within each timestep to compute the detector values. As soon as the 59 * vehicle leaves the detector, it is no longer tracked. 60 * 61 * Determining entering and leaving vehicles is done via the MSMoveReminder 62 * interface. The values are computed by an event-callback (at the end of 63 * a time step). 64 * 65 * @note As soon as a vehicle enters the detector, a VehicleInfo object is created 66 * and stored in myVehicleInfos. This is constantly updated as long as the 67 * vehicle stays on the detector (i.e. calls notifyMove()). All movement 68 * notifications sent by vehicles on the detector are temporarily stored 69 * in myMoveNotifications, see notifyMove(). Finally they are integrated 70 * into myVehicleInfos when updateDetector is called. 71 * @note When subclassing this detector, it is probably sufficient to adapt the 72 * definition of the structs VehicleInfo and the MoveNotification, as well as 73 * the methods that define and create those structs, i.e., makeVehicleInfo() 74 * and makeMoveNotification(). Further the integration of new movement 75 * notifications of the last time step into the vehicle infos is done 76 * in updateVehicleInfos(). 77 * 78 */ 79 80 81 class MSE2Collector : public MSMoveReminder, public MSDetectorFileOutput { 82 public: 83 /** @brief A VehicleInfo stores values that are tracked for the individual vehicles on the detector, 84 * e.g., accumulated timeloss. These infos are stored in myVehicles. If a vehicle leaves the detector 85 * (may it be temporarily), the entry in myVehicles is discarded, i.e. all information on the vehicle is reset. 86 */ 87 struct VehicleInfo { 88 /** @note Constructor expects an entryLane argument corresponding to a lane, which is part of the detector. 89 */ VehicleInfoVehicleInfo90 VehicleInfo(std::string id, std::string type, double length, double minGap, const MSLane* entryLane, double entryOffset, 91 std::size_t currentOffsetIndex, double exitOffset, double distToDetectorEnd, bool onDetector) : 92 id(id), 93 type(type), 94 length(length), 95 minGap(minGap), 96 entryLaneID(entryLane->getID()), 97 entryOffset(entryOffset), 98 currentLane(entryLane), 99 currentOffsetIndex(currentOffsetIndex), 100 exitOffset(exitOffset), 101 distToDetectorEnd(distToDetectorEnd), 102 totalTimeOnDetector(0.), 103 accumulatedTimeLoss(0.), 104 onDetector(onDetector), 105 hasEntered(false), 106 lastAccel(0), 107 lastSpeed(0), 108 lastPos(0) { 109 assert(exitOffset < 0); 110 } ~VehicleInfoVehicleInfo111 virtual ~VehicleInfo() {}; 112 /// vehicle's ID 113 std::string id; 114 /// vehicle's type 115 std::string type; 116 /// vehicle's length 117 double length; 118 /// vehicle's minGap 119 double minGap; 120 /// ID of the lane, on which the vehicle entered the detector 121 std::string entryLaneID; 122 /// Distance of the vehicle's entry lane's beginning to the detector start (can be negative for the first lane) 123 /// In notifyMove(), the positional input arguments are relative to that position (since the vehicle picks up the MoveReminder 124 /// on the entry lane) 125 double entryOffset; 126 /// Lane, on which the vehicle currently resides (always the one for which the last notifyEnter was received) 127 const MSLane* currentLane; 128 /// Index of currentLane in the detector's myLanes vector. 129 std::size_t currentOffsetIndex; 130 /// Offset from the detector start, where the vehicle has leaves the detector (defaults to detector length and is updated 131 /// if the vehicle leaves the detector via a junction before reaching its end, i.e. enters a lane not part of the detector) 132 double exitOffset; 133 /// Distance left till the detector end after the last integration step (may become negative if the vehicle passes beyond the detector end) 134 double distToDetectorEnd; 135 /// Accumulated time that this vehicle has spent on the detector since its last entry 136 double totalTimeOnDetector; 137 /// Accumulated time loss that this vehicle suffered since it entered the detector 138 double accumulatedTimeLoss; 139 140 /// whether the vehicle is on the detector at the end of the current timestep 141 bool onDetector; 142 /// Whether the vehicle has already entered the detector (don't count twice!) 143 bool hasEntered; 144 /// Last value of the acceleration 145 double lastAccel; 146 /// Last value of the speed 147 double lastSpeed; 148 /// Last value of the vehicle position in reference to the start lane 149 /// @note NOT in reference to the entry lane as newPos argument in notifyMove()! 150 double lastPos; 151 }; 152 153 typedef std::map<std::string, VehicleInfo*> VehicleInfoMap; 154 155 156 private: 157 /** @brief Values collected in notifyMove and needed in detectorUpdate() to 158 * calculate the accumulated quantities for the detector. These are 159 * temporarily stored in myMoveNotifications for each step. 160 */ 161 struct MoveNotificationInfo { MoveNotificationInfoMoveNotificationInfo162 MoveNotificationInfo(std::string _vehID, double _oldPos, double _newPos, double _speed, double _accel, double _distToDetectorEnd, double _timeOnDetector, double _lengthOnDetector, double _timeLoss, bool _onDetector) : 163 id(_vehID), 164 oldPos(_oldPos), 165 newPos(_newPos), 166 speed(_speed), 167 accel(_accel), 168 distToDetectorEnd(_distToDetectorEnd), 169 timeOnDetector(_timeOnDetector), 170 lengthOnDetector(_lengthOnDetector), 171 timeLoss(_timeLoss), 172 onDetector(_onDetector) {} 173 ~MoveNotificationInfoMoveNotificationInfo174 virtual ~MoveNotificationInfo() {}; 175 176 /// Vehicle's id 177 std::string id; 178 /// Position before the last integration step (relative to the vehicle's entry lane on the detector) 179 double oldPos; 180 /// Position after the last integration step (relative to the vehicle's entry lane on the detector) 181 double newPos; 182 /// Speed after the last integration step 183 double speed; 184 /// Acceleration in the last integration step 185 double accel; 186 /// Distance left till the detector end after the last integration step (may become negative if the vehicle passes beyond the detector end) 187 double distToDetectorEnd; 188 /// Time spent on the detector during the last integration step 189 double timeOnDetector; 190 /// The length of the part of the vehicle on the detector at the end of the last time step 191 double lengthOnDetector; 192 /// timeloss during the last integration step 193 double timeLoss; 194 /// whether the vehicle is on the detector at the end of the current timestep 195 bool onDetector; 196 }; 197 198 199 200 /** @brief Internal representation of a jam 201 * 202 * Used in execute, instances of this structure are used to track 203 * begin and end positions (as vehicles) of a jam. 204 */ 205 struct JamInfo { 206 /// @brief The first standing vehicle 207 std::vector<MoveNotificationInfo*>::const_iterator firstStandingVehicle; 208 209 /// @brief The last standing vehicle 210 std::vector<MoveNotificationInfo*>::const_iterator lastStandingVehicle; 211 }; 212 213 214 public: 215 216 /** @brief Constructor with given end position and detector length 217 * 218 * @param[in] id The detector's unique id. 219 * @param[in] usage Information how the detector is used 220 * @param[in] lane The lane the detector ends 221 * @param[in] startPos The start position on the lane the detector is placed at 222 * @param[in] endPos The end position on the lane the detector is placed at 223 * @param[in] length The length the detector has (heuristic lane selection is done if the continuation is not unique) 224 * @param[in] haltingTimeThreshold The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed 225 * @param[in] haltingSpeedThreshold The speed a vehicle's speed must be below to be assigned as jammed 226 * @param[in] jamDistThreshold The distance between two vehicles in order to not count them to one jam 227 * @param[in] vTypes Vehicle types, that the detector takes into account 228 * 229 * @note Exactly one of the arguments startPos, endPos and length should be invalid (i.e. equal to std::numeric_limits<double>::max()). 230 * If length is invalid, it is required that 0 <= startPos < endPos <= lane->length 231 * If endPos is invalid, the detector may span over several lanes downstream of the lane 232 * If pos is invalid, the detector may span over several lanes upstream of the lane 233 */ 234 MSE2Collector(const std::string& id, 235 DetectorUsage usage, MSLane* lane, double startPos, double endPos, double length, 236 SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold, 237 const std::string& vTypes); 238 239 240 /** @brief Constructor with a sequence of lanes and given start and end position on the first and last lanes 241 * 242 * @param[in] id The detector's unique id. 243 * @param[in] usage Information how the detector is used 244 * @param[in] lanes A sequence of lanes the detector covers (must form a continuous piece) 245 * @param[in] startPos The position of the detector start on the first lane the detector is placed at 246 * @param[in] endPos The position of the detector end on the last lane the detector is placed at 247 * @param[in] haltingTimeThreshold The time a vehicle's speed must be below haltingSpeedThreshold to be assigned as jammed 248 * @param[in] haltingSpeedThreshold The speed a vehicle's speed must be below to be assigned as jammed 249 * @param[in] jamDistThreshold The distance between two vehicles in order to not count them to one jam 250 * @param[in] vTypes Vehicle types, that the detector takes into account 251 */ 252 MSE2Collector(const std::string& id, 253 DetectorUsage usage, std::vector<MSLane*> lanes, double startPos, double endPos, 254 SUMOTime haltingTimeThreshold, double haltingSpeedThreshold, double jamDistThreshold, 255 const std::string& vTypes); 256 257 258 /// @brief Destructor 259 virtual ~MSE2Collector(); 260 261 /** @brief Returns the detector's usage type 262 * 263 * @see DetectorUsage 264 * @return How the detector is used. 265 */ getUsageType()266 virtual DetectorUsage getUsageType() const { 267 return myUsage; 268 } 269 270 271 272 /// @name Methods inherited from MSMoveReminder 273 /// @{ 274 275 /** @brief Adds/removes vehicles from the list of vehicles to regard 276 * 277 * As soon as the reported vehicle enters the detector area (position>myStartPos) 278 * it is added to the list of vehicles to regard (myKnownVehicles). It 279 * is removed from this list if it leaves the detector (position<length>myEndPos). 280 * The method returns true as long as the vehicle is not beyond the detector. 281 * 282 * @param[in] veh The vehicle in question. 283 * @param[in] oldPos Position before the move-micro-timestep. 284 * @param[in] newPos Position after the move-micro-timestep. 285 * Note that this position is given in reference 286 * to the begin of the entry lane of the vehicle. 287 * @param[in] newSpeed Unused here. 288 * @return False, if vehicle passed the detector entirely, else true. 289 * @see MSMoveReminder 290 * @see MSMoveReminder::notifyMove 291 */ 292 virtual bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, 293 double newSpeed); 294 295 296 /** @brief Removes a known vehicle due to its lane-change 297 * 298 * If the reported vehicle is known, it is removed from the list of 299 * vehicles to regard (myKnownVehicles). 300 * 301 * @param[in] veh The leaving vehicle. 302 * @param[in] lastPos Position on the lane when leaving. 303 * @param[in] isArrival whether the vehicle arrived at its destination 304 * @param[in] isLaneChange whether the vehicle changed from the lane 305 * @see MSMoveReminder::notifyLeave 306 */ 307 virtual bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 308 309 310 /** @brief Adds the vehicle to known vehicles if not beyond the dector 311 * 312 * If the vehicles is within the detector are, it is added to the list 313 * of known vehicles. 314 * The method returns true as long as the vehicle is not beyond the detector. 315 * 316 * @param[in] veh The entering vehicle. 317 * @param[in] reason how the vehicle enters the lane 318 * @return False, if vehicle passed the detector entirely, else true. 319 * @see MSMoveReminder::notifyEnter 320 * @see MSMoveReminder::Notification 321 */ 322 virtual bool notifyEnter(SUMOTrafficObject& veh, MSMoveReminder::Notification reason, const MSLane* enteredLane); 323 /// @} 324 325 326 327 328 329 /// @name Methods inherited from MSDetectorFileOutput. 330 /// @{ 331 332 /** @brief Computes the detector values in each time step 333 * 334 * This method should be called at the end of a simulation step, when 335 * all vehicles have moved. The current values are computed and 336 * summed up with the previous. 337 * 338 * @param[in] currentTime The current simulation time 339 */ 340 virtual void detectorUpdate(const SUMOTime step); 341 342 343 /** @brief Write the generated output to the given device 344 * @param[in] dev The output device to write the data into 345 * @param[in] startTime First time step the data were gathered 346 * @param[in] stopTime Last time step the data were gathered 347 * @exception IOError If an error on writing occurs 348 */ 349 virtual void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime); 350 351 352 /** @brief Open the XML-output 353 * 354 * The implementing function should open an xml element using 355 * OutputDevice::writeXMLHeader. 356 * 357 * @param[in] dev The output device to write the root into 358 * @exception IOError If an error on writing occurs 359 */ 360 virtual void writeXMLDetectorProlog(OutputDevice& dev) const; 361 362 /// @} 363 364 365 /** @brief Returns the begin position of the detector 366 * 367 * @return The detector's begin position 368 */ getStartPos()369 double getStartPos() const { 370 return myStartPos; 371 } 372 373 374 /** @brief Returns the end position of the detector 375 * 376 * @return The detector's end position 377 */ getEndPos()378 double getEndPos() const { 379 return myEndPos; 380 } 381 382 /** @brief Returns the length of the detector 383 * 384 * @return The detector's length 385 */ getLength()386 double getLength() const { 387 return myDetectorLength; 388 } 389 390 391 /** @brief Returns the id of the detector's last lane 392 * 393 * @return The detector's end position 394 */ getLastLane()395 MSLane* getLastLane() const { 396 return myLastLane; 397 } 398 399 400 /** @brief Returns a vector containing pointers to the lanes covered by the detector ordered from its first to its last lane 401 */ 402 std::vector<MSLane*> getLanes(); 403 404 /** @brief Resets all values 405 * 406 * This method is called on initialisation and as soon as the values 407 * were written. Values for the next interval may be collected, then. 408 * The list of known vehicles stays untouched. 409 */ 410 virtual void reset(); 411 412 413 /// @name Methods returning current values 414 /// @{ 415 416 /** @brief Returns the number of vehicles currently on the detector */ 417 int getCurrentVehicleNumber() const; 418 419 /** @brief Returns the current detector occupancy */ getCurrentOccupancy()420 double getCurrentOccupancy() const { 421 return myCurrentOccupancy; 422 } 423 424 /** @brief Returns the mean vehicle speed of vehicles currently on the detector*/ getCurrentMeanSpeed()425 double getCurrentMeanSpeed() const { 426 return myCurrentMeanSpeed; 427 } 428 429 /** @brief Returns the mean vehicle length of vehicles currently on the detector*/ getCurrentMeanLength()430 double getCurrentMeanLength() const { 431 return myCurrentMeanLength; 432 } 433 434 /** @brief Returns the current number of jams */ getCurrentJamNumber()435 int getCurrentJamNumber() const { 436 return myCurrentJamNo; 437 } 438 439 /** @brief Returns the length in vehicles of the currently largest jam */ getCurrentMaxJamLengthInVehicles()440 int getCurrentMaxJamLengthInVehicles() const { 441 return myCurrentMaxJamLengthInVehicles; 442 } 443 444 /** @brief Returns the length in meters of the currently largest jam */ getCurrentMaxJamLengthInMeters()445 double getCurrentMaxJamLengthInMeters() const { 446 return myCurrentMaxJamLengthInMeters; 447 } 448 449 /** @brief Returns the length of all jams in vehicles */ getCurrentJamLengthInVehicles()450 int getCurrentJamLengthInVehicles() const { 451 return myCurrentJamLengthInVehicles; 452 } 453 454 /** @brief Returns the length of all jams in meters */ getCurrentJamLengthInMeters()455 double getCurrentJamLengthInMeters() const { 456 return myCurrentJamLengthInMeters; 457 } 458 459 /** @brief Returns the length of all jams in meters */ getCurrentStartedHalts()460 int getCurrentStartedHalts() const { 461 return myCurrentStartedHalts; 462 } 463 464 /** @brief Returns the number of current haltings within the area 465 * 466 * If no vehicle is within the area, 0 is returned. 467 * 468 * @return The mean number of haltings within the area 469 */ getCurrentHaltingNumber()470 int getCurrentHaltingNumber() const { 471 return myCurrentHaltingsNumber; 472 } 473 474 /** @brief Returns the IDs of the vehicles within the area 475 * 476 * @return The IDs of the vehicles that have passed the entry, but not yet an exit point 477 */ 478 std::vector<std::string> getCurrentVehicleIDs() const; 479 480 /** @brief Returns the VehicleInfos for the vehicles currently on the detector 481 */ 482 std::vector<VehicleInfo*> getCurrentVehicles() const; 483 484 /** \brief Returns the number of vehicles passed over the sensor (i.e. entered the sensor) 485 * 486 * @return number of cars passed over the sensor 487 */ getPassedVeh()488 int getPassedVeh() { 489 return myNumberOfEnteredVehicles; 490 } 491 492 /** \brief Subtract the number of vehicles indicated from passed from the sensor count. 493 * 494 * @param[in] passed - int that indicates the number of vehicles to subtract 495 */ subtractPassedVeh(int passed)496 void subtractPassedVeh(int passed) { 497 myNumberOfEnteredVehicles -= passed; 498 } 499 500 /// @} 501 502 503 504 505 506 /// @name Estimation methods 507 /// TODO: Need documentation, used for tls control in MSSOTLE2Sensors (->Daniel?) 508 /// @{ 509 /** @brief Returns an estimate of the number of vehicles currently on the detector */ 510 int getEstimatedCurrentVehicleNumber(double speedThreshold) const; 511 512 /** @brief Returns an estimate of the lenght of the queue of vehicles currently stopped on the detector */ 513 double getEstimateQueueLength() const; 514 /// @} 515 516 517 518 private: 519 520 /** @brief checks whether the vehicle stands in a jam 521 * 522 * @param[in] mni 523 * @param[in/out] haltingVehicles 524 * @param[in/out] intervalHaltingVehicles 525 * @return Whether vehicle is in a jam. 526 */ 527 bool checkJam(std::vector<MoveNotificationInfo*>::const_iterator mni, std::map<std::string, SUMOTime>& haltingVehicles, std::map<std::string, SUMOTime>& intervalHaltingVehicles); 528 529 530 /** @brief Either adds the vehicle to the end of an existing jam, or closes the last jam, and/or creates a new jam 531 * 532 * @param isInJam 533 * @param mni 534 * @param[in/out] currentJam 535 * @param[in/out] jams 536 */ 537 void buildJam(bool isInJam, std::vector<MoveNotificationInfo*>::const_iterator mni, JamInfo*& currentJam, std::vector<JamInfo*>& jams); 538 539 540 /** @brief Calculates aggregated values from the given jam structure, deletes all jam-pointers 541 * 542 * @param jams 543 */ 544 void processJams(std::vector<JamInfo*>& jams, JamInfo* currentJam); 545 546 /** @brief Calculates the time spent on the detector in the last step and the timeloss suffered in the last step for the given vehicle 547 * 548 * @param[in] veh Vehicle for which the values are to be calculated 549 * @param[in] oldPos Last position (before the last timestep) of the vehicle relative to the beginning of its entry lane 550 * @param[in] newPos Current position of the vehicle 551 * @param[in] vi VehicleInfo corresponding to the vehicle 552 * @param[in/out] timeOnDetector Total time spent on the detector during the last step 553 * @param[in/out] timeLoss Total time loss suffered during the last integration step 554 */ 555 void calculateTimeLossAndTimeOnDetector(const SUMOVehicle& veh, double oldPos, double newPos, const VehicleInfo& vi, double& timeOnDetector, double& timeLoss) const; 556 557 /** @brief Checks integrity of myLanes, adds internal-lane information, inits myLength, myFirstLane, myLastLane, myOffsets 558 * Called once at construction. 559 * @requires myLanes should form a continuous sequence. 560 */ 561 void initAuxiliaries(std::vector<MSLane*>& lanes); 562 563 /** @brief Adjusts positioning if the detector length is less than POSITION_EPS and tests some assertions 564 */ 565 void checkPositioning(bool posGiven = false, double desiredLength = 0.); 566 567 /** @brief Snaps value to snpPoint if they are closer than snapDist 568 */ 569 static double snap(double value, double snapPoint, double snapDist); 570 571 /** @brief Updates the detector length after myStartPos and myEndPos have been modified 572 */ 573 void recalculateDetectorLength(); 574 575 576 577 /** @brief This is called if no lane sequence is given to the constructor. Builds myLanes from the given information. 578 * Also inits startPos (case dir=="bw") / endPos (case dir=="fw"). 579 * Selects lanes heuristically if no unambiguous continuation exists. 580 * 581 * @param[in] lane Lane, where the detector starts/ends 582 * @param[in] length Length of the detector 583 * @param[in] dir Direction of detector extension with value in {"fw", "bw"} (forward / backward) 584 * If dir == "fw" lane is interpreted as corresponding to the start lane of the detector, 585 * otherwise the lane is interpreted as the end lane. 586 */ 587 std::vector<MSLane*> selectLanes(MSLane* endLane, double length, std::string dir); 588 589 590 /** @brief This adds the detector as a MoveReminder to the associated lanes. 591 */ 592 void addDetectorToLanes(std::vector<MSLane*>& lanes); 593 594 595 /** @brief Aggregates and normalize some values for the detector output during detectorUpdate() 596 */ 597 void aggregateOutputValues(); 598 599 600 /** @brief This updates the detector values and the VehicleInfo of a vehicle on the detector 601 * with the given MoveNotificationInfo generated by the vehicle during the last time step. 602 * 603 * @param[in/out] vi VehicleInfo corresponding to the notifying vehicle 604 * @param[in] mni MoveNotification for the vehicle 605 */ 606 void integrateMoveNotification(VehicleInfo* vi, const MoveNotificationInfo* mni); 607 608 /** @brief Creates and returns a MoveNotificationInfo containing detector specific information on the vehicle's last movement 609 * 610 * @param veh The vehicle sending the notification 611 * @param oldPos The vehicle's position before the last integration step 612 * @param newPos The vehicle's position after the last integration step 613 * @param newSpeed The vehicle's speed after the last integration step 614 * @param vehInfo Info on the detector's memory of the vehicle 615 * @return A MoveNotificationInfo containing quantities of interest for the detector 616 */ 617 MoveNotificationInfo* makeMoveNotification(const SUMOVehicle& veh, double oldPos, double newPos, double newSpeed, const VehicleInfo& vehInfo) const; 618 619 /** @brief Creates and returns a VehicleInfo (called at the vehicle's entry) 620 * 621 * @param veh The entering vehicle 622 * @param enteredLane The entry lane 623 * @return A vehicle info which can be used to store information about the vehicle's stay on the detector 624 */ 625 VehicleInfo* makeVehicleInfo(const SUMOVehicle& veh, const MSLane* enteredLane) const; 626 627 /** @brief Calculates the time loss for a segment with constant vmax 628 * 629 * @param timespan time needed to cover the segment 630 * @param initialSpeed speed at segment entry 631 * @param accel constant acceleration assumed during movement on the segment 632 * @param vmax Maximal possible speed for the considered vehicle on the segment 633 * @return Time loss (== MAX(timespan*(vmax - (initialSpeed + accel/2))/vmax), 0) 634 */ 635 static double calculateSegmentTimeLoss(double timespan, double initialSpeed, double accel, double vmax); 636 637 /** brief returns true if the vehicle corresponding to mni1 is closer to the detector end than the vehicle corresponding to mni2 638 */ compareMoveNotification(MoveNotificationInfo * mni1,MoveNotificationInfo * mni2)639 static bool compareMoveNotification(MoveNotificationInfo* mni1, MoveNotificationInfo* mni2) { 640 return mni1->distToDetectorEnd < mni2->distToDetectorEnd; 641 } 642 643 644 private: 645 646 /// @brief Information about how this detector is used 647 DetectorUsage myUsage; 648 649 /// @name Detector parameter 650 /// @{ 651 /// @brief The detector's lane sequence 652 std::vector<std::string> myLanes; 653 /// @brief The distances of the lane-beginnings from the detector start-point 654 std::vector<double> myOffsets; 655 /// @brief The first lane of the detector's lane sequence 656 MSLane* myFirstLane; 657 /// @brief The last lane of the detector's lane sequence 658 MSLane* myLastLane; 659 /// @brief The position the detector starts at on the first lane 660 double myStartPos; 661 /// @brief The position the detector ends at on the last lane 662 double myEndPos; 663 /// @brief The total detector length 664 double myDetectorLength; 665 666 /// @brief A vehicle must driver slower than this to be counted as a part of a jam 667 double myJamHaltingSpeedThreshold; 668 /// @brief A vehicle must be that long beyond myJamHaltingSpeedThreshold to be counted as a part of a jam 669 SUMOTime myJamHaltingTimeThreshold; 670 /// @brief Two standing vehicles must be closer than this to be counted into the same jam 671 double myJamDistanceThreshold; 672 /// @} 673 674 675 /// @name Container 676 /// @{ 677 /// @brief List of informations about the vehicles currently on the detector 678 VehicleInfoMap myVehicleInfos; 679 680 /// @brief Temporal storage for notifications from vehicles that did call the 681 /// detector's notifyMove() in the last time step. 682 std::vector<MoveNotificationInfo*> myMoveNotifications; 683 684 /// @brief Keep track of vehicles that left the detector by a regular move along a junction (not lanechange, teleport, etc.) 685 /// and should be removed from myVehicleInfos after taking into account their movement. Non-longitudinal exits 686 /// are processed immediately in notifyLeave() 687 std::set<std::string> myLeftVehicles; 688 689 /// @brief Storage for halting durations of known vehicles (for halting vehicles) 690 std::map<std::string, SUMOTime> myHaltingVehicleDurations; 691 692 /// @brief Storage for halting durations of known vehicles (current interval) 693 std::map<std::string, SUMOTime> myIntervalHaltingVehicleDurations; 694 695 /// @brief Halting durations of ended halts [s] 696 std::vector<SUMOTime> myPastStandingDurations; 697 698 /// @brief Halting durations of ended halts for the current interval [s] 699 std::vector<SUMOTime> myPastIntervalStandingDurations; 700 /// @} 701 702 703 704 /// @name Values generated for aggregated file output 705 /// @{ 706 /// @brief The number of collected samples [time x vehicle] since the last reset 707 double myVehicleSamples; 708 /// @brief The total amount of all time losses [time x vehicle] since the last reset 709 double myTotalTimeLoss; 710 /// @brief The sum of collected vehicle speeds [m/s] 711 double mySpeedSum; 712 /// @brief The number of started halts [#] 713 double myStartedHalts; 714 /// @brief The sum of jam lengths [m] 715 double myJamLengthInMetersSum; 716 /// @brief The sum of jam lengths [#veh] 717 int myJamLengthInVehiclesSum; 718 /// @brief The current aggregation duration [#steps] 719 int myTimeSamples; 720 /// @brief The sum of occupancies [%] 721 double myOccupancySum; 722 /// @brief The maximum occupancy [%] 723 double myMaxOccupancy; 724 /// @brief The mean jam length [#veh] 725 int myMeanMaxJamInVehicles; 726 /// @brief The mean jam length [m] 727 double myMeanMaxJamInMeters; 728 /// @brief The max jam length [#veh] 729 int myMaxJamInVehicles; 730 /// @brief The max jam length [m] 731 double myMaxJamInMeters; 732 /// @brief The mean number of vehicles [#veh] 733 int myMeanVehicleNumber; 734 /// @} 735 736 737 /// @name Values generated describing the current state 738 /// @{ 739 /// @brief The number of vehicles, which have entered the detector since the last reset 740 int myNumberOfEnteredVehicles; 741 /// @brief The number of vehicles, present on the detector at the last reset 742 int myNumberOfSeenVehicles; 743 /// @brief The number of vehicles, which have left the detector since the last reset 744 int myNumberOfLeftVehicles; 745 /// @brief The maximal number of vehicles located on the detector simultaneously since the last reset 746 int myMaxVehicleNumber; 747 748 /// @brief The current occupancy 749 double myCurrentOccupancy; 750 /// @brief The current mean speed 751 double myCurrentMeanSpeed; 752 /// @brief The current mean length 753 double myCurrentMeanLength; 754 /// @brief The current jam number 755 int myCurrentJamNo; 756 /// @brief the current maximum jam length in meters 757 double myCurrentMaxJamLengthInMeters; 758 /// @brief The current maximum jam length in vehicles 759 int myCurrentMaxJamLengthInVehicles; 760 /// @brief The overall jam length in meters 761 double myCurrentJamLengthInMeters; 762 /// @brief The overall jam length in vehicles 763 int myCurrentJamLengthInVehicles; 764 /// @brief The number of started halts in the last step 765 int myCurrentStartedHalts; 766 /// @brief The number of halted vehicles [#] 767 int myCurrentHaltingsNumber; 768 /// @} 769 770 771 private: 772 /// @brief Invalidated copy constructor. 773 MSE2Collector(const MSE2Collector&); 774 775 /// @brief Invalidated assignment operator. 776 MSE2Collector& operator=(const MSE2Collector&); 777 }; 778 779 780 #endif 781 782 /****************************************************************************/ 783 784