1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2003-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 MSE3Collector.h 11 /// @author Christian Roessel 12 /// @author Daniel Krajzewicz 13 /// @author Michael Behrisch 14 /// @author Jakob Erdmann 15 /// @date Tue Dec 02 2003 22:17 CET 16 /// @version $Id$ 17 /// 18 // A detector of vehicles passing an area between entry/exit points 19 /****************************************************************************/ 20 #ifndef MSE3Collector_h 21 #define MSE3Collector_h 22 23 24 // =========================================================================== 25 // included modules 26 // =========================================================================== 27 #include <config.h> 28 29 #include <string> 30 #include <vector> 31 #include <limits> 32 #include <microsim/MSMoveReminder.h> 33 #include <microsim/output/MSDetectorFileOutput.h> 34 #include <utils/common/Named.h> 35 #include <microsim/output/MSCrossSection.h> 36 #include <utils/common/UtilExceptions.h> 37 38 39 // =========================================================================== 40 // class declarations 41 // =========================================================================== 42 class SUMOTrafficObject; 43 class OutputDevice; 44 45 46 // =========================================================================== 47 // class definitions 48 // =========================================================================== 49 /** 50 * @class MSE3Collector 51 * @brief A detector of vehicles passing an area between entry/exit points 52 * 53 * E3 detectors are defined by a set of in-cross-sections and out-cross-sections. 54 * Vehicles, that pass an in- and out-cross-section are detected when they pass the 55 * out-cross-section. Vehicles passing the out-cross-section without having 56 * passed the in-cross-section are not detected. 57 */ 58 class MSE3Collector : public MSDetectorFileOutput { 59 public: 60 /** 61 * @class MSE3EntryReminder 62 * @brief A place on the road net (at a certain lane and position on it) where the E3 area begins 63 */ 64 class MSE3EntryReminder : public MSMoveReminder { 65 public: 66 /** @brief Constructor 67 * 68 * @param[in] crossSection The position at which the entry lies 69 * @param[in] collector The detector the entry belongs to 70 */ 71 MSE3EntryReminder(const MSCrossSection& crossSection, MSE3Collector& collector); 72 73 74 /// @name Methods inherited from MSMoveReminder. 75 /// @{ 76 /** @brief Checks whether the reminder is activated by a vehicle entering the lane 77 * 78 * Lane change means in this case that the vehicle changes to the lane 79 * the reminder is placed at. 80 * 81 * @param[in] veh The entering vehicle. 82 * @param[in] reason how the vehicle enters the lane 83 * @return True if vehicle enters the reminder. 84 * @see Notification 85 */ 86 bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane); 87 88 /** @brief Checks whether the vehicle enters 89 * 90 * As soon as the reported vehicle enters the detector area (position>myPosition) 91 * the entering time is computed and both are added to the parent detector using 92 * "enter". 93 * 94 * @param[in] veh The vehicle in question. 95 * @param[in] oldPos Position before the move-micro-timestep. 96 * @param[in] newPos Position after the move-micro-timestep. 97 * @param[in] newSpeed Unused here. 98 * @return False, if vehicle passed the detector entierly, else true. 99 * @see MSMoveReminder 100 * @see MSMoveReminder::notifyMove 101 * @see MSE3Collector::enter 102 */ 103 bool notifyMove(SUMOTrafficObject& veh, double, double newPos, double); 104 105 106 /** @brief Processes state changes of a vehicle 107 * 108 * If the reported vehicle is known, and the reason indicates a removal from the network 109 * (permanent or temporary), the vehicle is removed from the list of vehicles to regard. 110 * 111 * @param[in] veh The leaving vehicle. 112 * @param[in] lastPos Position on the lane when leaving. 113 * @param[in] reason The reason for the state change 114 * @see MSMoveReminder::notifyLeave 115 */ 116 bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 117 /// @} 118 119 120 private: 121 /// @brief The parent collector 122 MSE3Collector& myCollector; 123 124 /// @brief The position on the lane 125 double myPosition; 126 127 private: 128 /// @brief Invalidated copy constructor. 129 MSE3EntryReminder(const MSE3EntryReminder&); 130 131 /// @brief Invalidated assignment operator. 132 MSE3EntryReminder& operator=(const MSE3EntryReminder&); 133 134 }; 135 136 137 138 /** 139 * @class MSE3LeaveReminder 140 * @brief A place on the road net (at a certain lane and position on it) where the E3 area ends 141 */ 142 class MSE3LeaveReminder : public MSMoveReminder { 143 public: 144 /** @brief Constructor 145 * 146 * @param[in] crossSection The position at which the exit lies 147 * @param[in] collector The detector the exit belongs to 148 */ 149 MSE3LeaveReminder(const MSCrossSection& crossSection, MSE3Collector& collector); 150 151 152 /// @name methods from MSMoveReminder 153 //@{ 154 /** @brief Checks whether the reminder is activated by a vehicle entering the lane 155 * 156 * Lane change means in this case that the vehicle changes to the lane 157 * the reminder is placed at. 158 * 159 * @param[in] veh The entering vehicle. 160 * @param[in] reason how the vehicle enters the lane 161 * @return True if vehicle enters the reminder. 162 * @see Notification 163 */ 164 bool notifyEnter(SUMOTrafficObject& veh, Notification reason, const MSLane* enteredLane); 165 166 /** @brief Checks whether the vehicle leaves 167 * 168 * As soon as the reported vehicle leaves the detector area (position-length>myPosition) 169 * the leaving time is computed and both are made known to the parent detector using 170 * "leave". 171 * 172 * @param[in] veh The vehicle in question. 173 * @param[in] oldPos Position before the move-micro-timestep. 174 * @param[in] newPos Position after the move-micro-timestep. 175 * @param[in] newSpeed Unused here. 176 * @return False, if vehicle passed the detector entirely, else true. 177 * @see MSMoveReminder 178 * @see MSMoveReminder::notifyMove 179 * @see MSE3Collector::leave 180 */ 181 bool notifyMove(SUMOTrafficObject& veh, double oldPos, double newPos, double); 182 183 /** @brief Processes state changes of a vehicle 184 * 185 * Checks whether the vehicle has changed lanes and this reminder needs to be removed 186 * 187 * @param[in] veh The leaving vehicle (unused). 188 * @param[in] lastPos Position on the lane when leaving (unused). 189 * @param[in] reason The reason for the state change 190 * @see MSMoveReminder::notifyLeave 191 */ 192 bool notifyLeave(SUMOTrafficObject& veh, double lastPos, MSMoveReminder::Notification reason, const MSLane* enteredLane = 0); 193 //@} 194 195 196 private: 197 /// @brief The parent collector 198 MSE3Collector& myCollector; 199 200 /// @brief The position on the lane 201 double myPosition; 202 203 private: 204 /// @brief Invalidated copy constructor. 205 MSE3LeaveReminder(const MSE3LeaveReminder&); 206 207 /// @brief Invalidated assignment operator. 208 MSE3LeaveReminder& operator=(const MSE3LeaveReminder&); 209 210 }; 211 212 213 /** @brief Constructor 214 * 215 * Sets reminder objects on entry- and leave-lanes 216 * 217 * @param[in] id The detector's unique id. 218 * @param[in] entries Entry-cross-sections. 219 * @param[in] exits Leavey-cross-sections. 220 * @param[in] haltingSpeedThreshold A vehicle must not drive a greater speed than haltingSpeedThreshold to be a "halting" vehicle. 221 * @param[in] haltingTimeThreshold A vehicle must not drive a greater speed for more than haltingTimeThreshold to be a "halting" vehicle. 222 */ 223 MSE3Collector(const std::string& id, 224 const CrossSectionVector& entries, const CrossSectionVector& exits, 225 double haltingSpeedThreshold, 226 SUMOTime haltingTimeThreshold, 227 const std::string& vTypes, bool openEntry); 228 229 230 /// @brief Destructor 231 virtual ~MSE3Collector(); 232 233 234 /** @brief Resets all generated values to allow computation of next interval 235 */ 236 void reset(); 237 238 239 /** @brief Called if a vehicle touches an entry-cross-section. 240 * 241 * Inserts vehicle into internal containers. 242 * 243 * @param[in] veh The vehicle that entered the area 244 * @param[in] entryTimestep The time in seconds the vehicle entered the area 245 * @param[in] fractionTimeOnDet The interpolated time in seconds the vehicle already spent on the detector 246 */ 247 void enter(const SUMOTrafficObject& veh, const double entryTimestep, const double fractionTimeOnDet, MSE3EntryReminder* entryReminder); 248 249 250 /** @brief Called if a vehicle front passes a leave-cross-section. 251 * 252 * @param[in] veh The vehicle that left the area 253 * @param[in] leaveTimestep The time in seconds the vehicle started crossing the line 254 */ 255 void leaveFront(const SUMOTrafficObject& veh, const double leaveTimestep); 256 257 258 /** @brief Called if a vehicle back passes a leave-cross-section. 259 * 260 * Removes vehicle from internal containers. 261 * 262 * @param[in] veh The vehicle that left the area 263 * @param[in] leaveTimestep The time in seconds the vehicle left the area 264 * @param[in] fractionTimeOnDet The interpolated time in seconds the vehicle still spent on the detector 265 */ 266 void leave(const SUMOTrafficObject& veh, const double leaveTimestep, const double fractionTimeOnDet); 267 268 269 /// @name Methods returning current values 270 /// @{ 271 272 /** @brief Returns the mean speed within the area 273 * 274 * If no vehicle is within the area, -1 is returned. 275 * 276 * @return The mean speed [m/s] of all vehicles within the area, -1 if there is none 277 */ 278 double getCurrentMeanSpeed() const; 279 280 281 /** @brief Returns the number of current haltings within the area 282 * 283 * If no vehicle is within the area, 0 is returned. 284 * 285 * @return The mean number of haltings within the area 286 */ 287 int getCurrentHaltingNumber() const; 288 289 290 /** @brief Returns the number of vehicles within the area 291 * @return The number of vehicles that passed the entry collector 292 */ 293 int getVehiclesWithin() const; 294 295 296 /** @brief Returns the number of vehicles within the area 297 * 298 * @return The number of vehicles that have passed the entry, but not yet an exit point 299 */ 300 std::vector<std::string> getCurrentVehicleIDs() const; 301 /// @} 302 303 304 /// @name Methods inherited from MSDetectorFileOutput. 305 /// @{ 306 307 /** @brief Writes collected values into the given stream 308 * 309 * @param[in] dev The output device to write the data into 310 * @param[in] startTime First time step the data were gathered 311 * @param[in] stopTime Last time step the data were gathered 312 * @see MSDetectorFileOutput::writeXMLOutput 313 * @exception IOError If an error on writing occurs (!!! not yet implemented) 314 */ 315 void writeXMLOutput(OutputDevice& dev, SUMOTime startTime, SUMOTime stopTime); 316 317 318 /** @brief Opens the XML-output using "e3Detector" as root element 319 * 320 * The lists of entries/exists are written, too. 321 * 322 * @param[in] dev The output device to write the root into 323 * @see MSDetectorFileOutput::writeXMLDetectorProlog 324 * @exception IOError If an error on writing occurs (!!! not yet implemented) 325 */ 326 void writeXMLDetectorProlog(OutputDevice& dev) const; 327 /// @} 328 329 330 331 /** @brief Computes the detector values in each time step 332 * 333 * This method should be called at the end of a simulation step, when 334 * all vehicles have moved. The current values are computed and 335 * summed up with the previous. 336 * 337 * @param[in] currentTime The current simulation time (unused) 338 */ 339 void detectorUpdate(const SUMOTime step); 340 341 342 protected: 343 /// @brief The detector's entries 344 CrossSectionVector myEntries; 345 346 /// @brief The detector's exits 347 CrossSectionVector myExits; 348 349 /// @brief The detector's built entry reminder 350 std::vector<MSE3EntryReminder*> myEntryReminders; 351 352 /// @brief The detector's built exit reminder 353 std::vector<MSE3LeaveReminder*> myLeaveReminders; 354 355 356 // @brief Time-threshold to determine if a vehicle is halting. 357 SUMOTime myHaltingTimeThreshold; 358 359 /// @brief Speed-threshold to determine if a vehicle is halting. 360 double myHaltingSpeedThreshold; 361 362 /** 363 * @struct E3Values 364 * @brief Internal storage for values from a vehicle 365 * 366 * For each vehicle within the area (that entered through an entry point), 367 * this structure is allocated. All values gathered from the vehicle are aggregated 368 * within this structure. 369 */ 370 struct E3Values { 371 /// @brief The vehicle's entry time 372 double entryTime; 373 /// @brief The time the vehicle's front was crossing the leave line 374 double frontLeaveTime; 375 /// @brief The time the vehicle's back was crossing the leave line 376 double backLeaveTime; 377 /// @brief The sum of registered speeds the vehicle has/had inside the area 378 double speedSum; 379 /// @brief The sum of haltings the vehicle has/had within the area 380 int haltings; 381 /// @brief Begin time of last halt begin 382 SUMOTime haltingBegin; 383 /// @brief The sum of registered speeds the vehicle has/had inside the area during the current interval 384 double intervalSpeedSum; 385 /// @brief The sum of haltings the vehicle has/had within the area during the current interval 386 int intervalHaltings; 387 /// @brief The timeLoss of the vehicle when entering. Updated to the actual time loss within the area when leaving 388 SUMOTime timeLoss; 389 /// @brief The timeLoss of the vehicle when entering. Updated to the current timeLoss at interval write 390 SUMOTime intervalTimeLoss; 391 /// @brief An internal information whether the update step was performed 392 bool hadUpdate; 393 /// @brief the reminder on which the vehicle entered the detector 394 MSE3EntryReminder* entryReminder; 395 }; 396 397 /// @brief Container for vehicles that have entered the area 398 std::map<const SUMOTrafficObject*, E3Values> myEnteredContainer; 399 400 /// @brief Container for vehicles that have left the area 401 std::vector<E3Values> myLeftContainer; 402 403 404 /// @name Storages for current values 405 /// @{ 406 407 /// @brief The current mean speed of known vehicles (inside) 408 double myCurrentMeanSpeed; 409 410 /// @brief The current number of haltings (inside) 411 int myCurrentHaltingsNumber; 412 /// @} 413 414 415 /// @brief Information when the last reset has been done 416 SUMOTime myLastResetTime; 417 418 /// @brief whether this dector is declared as having incomplete entry detectors 419 const bool myOpenEntry; 420 421 private: 422 /// @brief Invalidated copy constructor. 423 MSE3Collector(const MSE3Collector&); 424 425 /// @brief Invalidated assignment operator. 426 MSE3Collector& operator=(const MSE3Collector&); 427 428 429 }; 430 431 432 #endif 433 434 /****************************************************************************/ 435 436