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 MSVehicleControl.h 11 /// @author Daniel Krajzewicz 12 /// @author Jakob Erdmann 13 /// @author Michael Behrisch 14 /// @date Wed, 10. Dec 2003 15 /// @version $Id$ 16 /// 17 // The class responsible for building and deletion of vehicles 18 /****************************************************************************/ 19 #ifndef MSVehicleControl_h 20 #define MSVehicleControl_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 #include <config.h> 27 28 #include <cmath> 29 #include <string> 30 #include <map> 31 #include <set> 32 #ifdef HAVE_FOX 33 #include <fx.h> 34 #include <utils/foxtools/FXSynchQue.h> 35 #endif 36 #include <utils/distribution/RandomDistributor.h> 37 #include <utils/common/SUMOTime.h> 38 #include <utils/common/SUMOVehicleClass.h> 39 #include "MSNet.h" 40 41 42 // =========================================================================== 43 // class declarations 44 // =========================================================================== 45 class SUMOVehicle; 46 class SUMOVehicleParameter; 47 class MSVehicle; 48 class MSRoute; 49 class MSVehicleType; 50 class OutputDevice; 51 class MSEdge; 52 53 54 // =========================================================================== 55 // class definitions 56 // =========================================================================== 57 /** 58 * @class MSVehicleControl 59 * @brief The class responsible for building and deletion of vehicles 60 * 61 * This class is responsible for vehicle building and deletion. It stores 62 * vehicle types, vehicles and statistics about the last. 63 * 64 * This class also realizes the tripinfos and the vehroutes - outputs, both 65 * generated when a vehicle is removed from the simulation, see 66 * scheduleVehicleRemoval. 67 * 68 * Use this class for the pure microsim and GUIVehicleControl within the gui. 69 * 70 * @see GUIVehicleControl 71 */ 72 class MSVehicleControl { 73 public: 74 /// @brief Definition of the internal vehicles map iterator 75 typedef std::map<std::string, SUMOVehicle*>::const_iterator constVehIt; 76 77 public: 78 /// @brief Constructor 79 MSVehicleControl(); 80 81 82 /// @brief Destructor 83 virtual ~MSVehicleControl(); 84 85 86 /// @name Vehicle creation 87 /// @{ 88 89 /** @brief Builds a vehicle, increases the number of built vehicles 90 * 91 * Builds a MSVehicle instance using the given parameter. 92 * Increases the number of loaded vehicles ("myLoadedVehNo"). 93 * 94 * @param[in] defs The parameter defining the vehicle 95 * @param[in] route The route of this vehicle 96 * @param[in] type The type of this vehicle 97 * @param[in] ignoreStopErrors whether invalid stops trigger a warning only 98 * @param[in] fromRouteFile whether we are just reading the route file or creating via trigger, traci, ... 99 * @return The built vehicle (MSVehicle instance) 100 */ 101 virtual SUMOVehicle* buildVehicle(SUMOVehicleParameter* defs, const MSRoute* route, 102 MSVehicleType* type, 103 const bool ignoreStopErrors, const bool fromRouteFile = true); 104 /// @} 105 106 107 108 /// @name Insertion, deletion and retrieval of vehicles 109 /// @{ 110 111 /** @brief Tries to insert the vehicle into the internal vehicle container 112 * 113 * Checks whether another vehicle with the same id exists; returns false 114 * if so. Otherwise, the vehicle is added to "myVehicleDict". 115 * It also checks whether the vehicle has a "triggered" departure 116 * and registers it accordingly. 117 * 118 * The vehicle control gets responsible for vehicle deletion. 119 * 120 * @param[in] id The id of the vehicle 121 * @param[in] v The vehicle 122 * @return Whether the vehicle could be inserted (no other vehicle with the same id was inserted before) 123 */ 124 virtual bool addVehicle(const std::string& id, SUMOVehicle* v); 125 126 127 /** @brief Returns the vehicle with the given id 128 * 129 * If no vehicle with the given id is store din "myVehicleDict", 0 130 * is returned. 131 * 132 * @param[in] id The id of the vehicle to retrieve 133 * @return The vehicle with the given id, 0 if no such vehicle exists 134 */ 135 SUMOVehicle* getVehicle(const std::string& id) const; 136 137 138 /** @brief Deletes the vehicle 139 * 140 * @param[in] v The vehicle to delete 141 * @param[discard] Whether the vehicle is discard during loading (scale < 1) 142 * @todo Isn't this quite insecure? 143 */ 144 virtual void deleteVehicle(SUMOVehicle* v, bool discard = false); 145 146 147 /** @brief Removes a vehicle after it has ended 148 * 149 * Writes output to tripinfos and vehroutes if wished; decrements 150 * the number of running vehicles and increments the number of ended 151 * vehicles. Then deletes the vehicle using "deleteVehicle". 152 * 153 * This method should be called for each vehicle that was inserted 154 * into the network and quits its ride. 155 * 156 * @param[in] veh The vehicle to remove 157 */ 158 void scheduleVehicleRemoval(SUMOVehicle* veh); 159 160 161 /** @brief Removes a vehicle after it has ended 162 * 163 * Writes output to tripinfos and vehroutes if wished; decrements 164 * the number of running vehicles and increments the number of ended 165 * vehicles. Then deletes the vehicle using "deleteVehicle". 166 * 167 * This method should be called for each vehicle that was inserted 168 * into the network and quits its ride. 169 * 170 * @param[in] veh The vehicle to remove 171 */ 172 void removePending(); 173 174 175 /** @brief Returns the begin of the internal vehicle map 176 * @return The begin of the internal vehicle map 177 */ loadedVehBegin()178 constVehIt loadedVehBegin() const { 179 return myVehicleDict.begin(); 180 } 181 182 183 /** @brief Returns the end of the internal vehicle map 184 * @return The end of the internal vehicle map 185 */ loadedVehEnd()186 constVehIt loadedVehEnd() const { 187 return myVehicleDict.end(); 188 } 189 /// @} 190 191 192 193 /// @name Setting vehicle statistics 194 /// @{ 195 196 /** @brief Informs this control about a vehicle's departure 197 * 198 * If the mean waiting time shall be computed (f.e. for summary-output), 199 * the absolut waiting time is increased by the waiting time of the given 200 * vehicle. 201 * @param[in] v The inserted vehicle 202 */ 203 void vehicleDeparted(const SUMOVehicle& v); 204 /// @} 205 206 207 208 /// @name Retrieval of vehicle statistics (always accessable) 209 /// @{ 210 211 /** @brief Returns the number of build vehicles 212 * @return The number of loaded (build) vehicles 213 */ getLoadedVehicleNo()214 int getLoadedVehicleNo() const { 215 return myLoadedVehNo; 216 } 217 218 219 /** @brief Returns the number of halting vehicles 220 * @return The number of halting vehicles 221 */ 222 virtual int getHaltingVehicleNo() const; 223 224 /// @brief get current absolute and relative mean vehicle speed in the network 225 virtual std::pair<double, double> getVehicleMeanSpeeds() const; getVehicleMeanSpeed()226 double getVehicleMeanSpeed() const { 227 return getVehicleMeanSpeeds().first; 228 } getVehicleMeanSpeedRelative()229 double getVehicleMeanSpeedRelative() const { 230 return getVehicleMeanSpeeds().second; 231 } 232 233 /** @brief Returns the number of removed vehicles 234 * @return The number of vehicles that have left the simulation 235 */ getEndedVehicleNo()236 int getEndedVehicleNo() const { 237 return myEndedVehNo; 238 } 239 240 /** @brief Returns the number of arrived vehicles 241 * @return The number of vehicles that have arrived at their destination 242 */ getArrivedVehicleNo()243 int getArrivedVehicleNo() const { 244 return myEndedVehNo - myDiscarded; 245 } 246 247 /** @brief Returns the number of discarded vehicles 248 * @return The number of vehicles that could not be inserted and were permantently discarded 249 */ getDiscardedVehicleNo()250 int getDiscardedVehicleNo() const { 251 return myDiscarded; 252 } 253 254 255 /** @brief Returns the number of build and inserted, but not yet deleted vehicles 256 * @return The number simulated vehicles (including those in teleporter) 257 */ getRunningVehicleNo()258 int getRunningVehicleNo() const { 259 return myRunningVehNo; 260 } 261 262 263 /** @brief Returns the number of inserted vehicles 264 * @return The number of vehicles that have entered the simulation so far 265 */ getDepartedVehicleNo()266 int getDepartedVehicleNo() const { 267 return myRunningVehNo + myEndedVehNo - myDiscarded; 268 } 269 270 271 /** @brief Returns the number of instances of the current vehicle that shall be emitted 272 * considering that "frac" of all vehicles shall be emitted overall 273 * if a negative fraction is given the demand scaling factor is used 274 * (--scale) 275 * @return the number of vehicles to create (something between 0 and ceil(frac)) 276 */ 277 int getQuota(double frac = -1) const; 278 279 280 /** @brief Returns the number of build vehicles that have not been removed or 281 * need to wait for a passenger or a container 282 * @return Number of active vehicles 283 */ getActiveVehicleCount()284 int getActiveVehicleCount() const { 285 return myLoadedVehNo - (myWaitingForPerson + myWaitingForContainer + myEndedVehNo); 286 } 287 288 289 /// @brief return the number of collisions getCollisionCount()290 int getCollisionCount() const { 291 return myCollisions; 292 } 293 294 /// @brief return the number of teleports due to jamming getTeleportsJam()295 int getTeleportsJam() const { 296 return myTeleportsJam; 297 } 298 299 /// @brief return the number of teleports due to vehicles stuck on a minor road getTeleportsYield()300 int getTeleportsYield() const { 301 return myTeleportsYield; 302 } 303 304 /// @brief return the number of teleports due to vehicles stuck on the wrong lane getTeleportsWrongLane()305 int getTeleportsWrongLane() const { 306 return myTeleportsWrongLane; 307 } 308 309 /// @brief return the number of teleports (including collisions) 310 int getTeleportCount() const; 311 312 /// @brief return the number of emergency stops getEmergencyStops()313 int getEmergencyStops() const { 314 return myEmergencyStops; 315 } 316 317 /** @brief Returns the total departure delay 318 * @return Sum of steps vehicles had to wait until being inserted 319 */ getTotalDepartureDelay()320 double getTotalDepartureDelay() const { 321 return myTotalDepartureDelay; 322 } 323 324 325 /** @brief Returns the total travel time 326 * @return Sum of travel times of arrived vehicles 327 */ getTotalTravelTime()328 double getTotalTravelTime() const { 329 return myTotalTravelTime; 330 } 331 /// @} 332 333 334 335 /// @name Insertion and retrieval of vehicle types 336 /// @{ 337 338 /** @brief Adds a vehicle type 339 * 340 * If another vehicle type (or distribution) with the same id exists, false is returned. 341 * Otherwise, the vehicle type is added to the internal vehicle type 342 * container "myVTypeDict". 343 * 344 * This control get responsible for deletion of the added vehicle 345 * type. 346 * 347 * @param[in] vehType The vehicle type to add 348 * @return Whether the vehicle type could be added 349 */ 350 bool addVType(MSVehicleType* vehType); 351 352 /* 353 * @param[in] vehType The vehicle type to remove 354 * @return Whether the vehicle type could be removed 355 */ 356 void removeVType(const MSVehicleType* vehType); 357 358 359 /** @brief Adds a vehicle type distribution 360 * 361 * If another vehicle type (or distribution) with the same id exists, false is returned. 362 * Otherwise, the vehicle type distribution is added to the internal vehicle type distribution 363 * container "myVTypeDistDict". 364 * 365 * This control get responsible for deletion of the added vehicle 366 * type distribution. 367 * 368 * @param[in] id The id of the distribution to add 369 * @param[in] vehTypeDistribution The vehicle type distribution to add 370 * @return Whether the vehicle type could be added 371 */ 372 bool addVTypeDistribution(const std::string& id, RandomDistributor<MSVehicleType*>* vehTypeDistribution); 373 374 375 /** @brief Asks for existence of a vehicle type 376 * 377 * If vehicle type or distribution with the id exists, true is returned, false otherwise. 378 * 379 * @param[in] id The id of the type or distribution 380 * @return Whether the vehicle type or distribution exists 381 */ 382 bool hasVType(const std::string& id) const; 383 384 385 /** @brief Asks for a vehicle type distribution 386 * 387 * If vehicle type distribution with the id exists, true is returned, false otherwise. 388 * 389 * @param[in] id The id of the distribution 390 * @return Whether the vehicle type distribution exists 391 */ 392 bool hasVTypeDistribution(const std::string& id) const; 393 394 395 /** @brief Returns the named vehicle type or a sample from the named distribution 396 * @param[in] id The id of the vehicle type to return. If left out, the default type is returned. 397 * @return The named vehicle type, or 0 if no such type exists 398 */ 399 MSVehicleType* getVType(const std::string& id = DEFAULT_VTYPE_ID, std::mt19937* rng = 0); 400 401 402 /** @brief Inserts ids of all known vehicle types and vehicle type distributions to the given vector 403 * @param[in] into The vector to fill with ids 404 */ 405 void insertVTypeIDs(std::vector<std::string>& into) const; 406 407 408 /** @brief Return the distribution IDs the vehicle type is a member of 409 * @param[in] vehType The vehicle type to look for membership in distributions 410 */ 411 std::set<std::string> getVTypeDistributionMembership(const std::string& id) const; 412 413 /// @} 414 415 /// @brief Adds a vehicle to the list of waiting vehiclse to a given edge 416 void addWaiting(const MSEdge* const edge, SUMOVehicle* vehicle); 417 418 /// @brief Removes a vehicle from the list of waiting vehicles to a given edge 419 void removeWaiting(const MSEdge* const edge, const SUMOVehicle* vehicle); 420 421 /* @brief returns a vehicle of the given lines that is waiting for a for a person or a container at this edge at the given positions 422 * @param[in] edge The edge at which the vehicle is positioned. 423 * @param[in] lines The set of lines from which at least one must correspond to the line of the vehicle 424 * @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance 425 * @param[in] ridingID The id of the person or container that wants to ride 426 */ 427 SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const MSEdge* const edge, const double position); 428 429 /** @brief increases the count of vehicles waiting for a transport to allow recognition of person / container related deadlocks 430 */ registerOneWaiting(const bool isPerson)431 void registerOneWaiting(const bool isPerson) { 432 if (isPerson) { 433 myWaitingForPerson++; 434 } else { 435 myWaitingForContainer++; 436 } 437 } 438 439 /** @brief decreases the count of vehicles waiting for a transport to allow recognition of person / container related deadlocks 440 */ unregisterOneWaiting(const bool isPerson)441 void unregisterOneWaiting(const bool isPerson) { 442 if (isPerson) { 443 myWaitingForPerson--; 444 } else { 445 myWaitingForContainer--; 446 } 447 } 448 449 /// @brief registers one collision-related teleport registerCollision()450 void registerCollision() { 451 myCollisions++; 452 } 453 454 /// @brief register one non-collision-related teleport registerTeleportJam()455 void registerTeleportJam() { 456 myTeleportsJam++; 457 } 458 459 /// @brief register one non-collision-related teleport registerTeleportYield()460 void registerTeleportYield() { 461 myTeleportsYield++; 462 } 463 464 /// @brief register one non-collision-related teleport registerTeleportWrongLane()465 void registerTeleportWrongLane() { 466 myTeleportsWrongLane++; 467 } 468 469 /// @brief register emergency stop registerEmergencyStop()470 void registerEmergencyStop() { 471 myEmergencyStops++; 472 } 473 474 /// @name State I/O 475 /// @{ 476 477 /** @brief Sets the current state variables as loaded from the stream 478 */ 479 void setState(int runningVehNo, int loadedVehNo, int endedVehNo, double totalDepartureDelay, double totalTravelTime); 480 481 /** @brief Saves the current state into the given stream 482 */ 483 void saveState(OutputDevice& out); 484 /// @} 485 486 /// @brief avoid counting a vehicle twice if it was loaded from state and route input 487 void discountStateLoaded(bool removed = false) { 488 if (removed) { 489 myRunningVehNo--; 490 myDiscarded++; 491 myEndedVehNo++; 492 } else { 493 myLoadedVehNo--; 494 } 495 } 496 497 498 /** @brief informes about all waiting vehicles (deletion in destructor) 499 */ 500 void abortWaiting(); 501 502 /// @brief return the maximum speed factor for all vehicles that ever entered the network getMaxSpeedFactor()503 double getMaxSpeedFactor() const { 504 return myMaxSpeedFactor; 505 } 506 507 /// @brief return the minimum deceleration capability for all vehicles that ever entered the network getMinDeceleration()508 double getMinDeceleration() const { 509 return myMinDeceleration; 510 } 511 512 void adaptIntermodalRouter(MSNet::MSIntermodalRouter& router) const; 513 514 /// @brief sets the demand scaling factor setScale(double scale)515 void setScale(double scale) { 516 myScale = scale; 517 } 518 519 private: 520 /** @brief Checks whether the vehicle type (distribution) may be added 521 * 522 * This method checks also whether the default type may still be replaced 523 * @param[in] id The id of the vehicle type (distribution) to add 524 * @return Whether the type (distribution) may be added 525 */ 526 bool checkVType(const std::string& id); 527 528 protected: 529 /// @name Vehicle statistics (always accessible) 530 /// @{ 531 532 /// @brief The number of build vehicles 533 int myLoadedVehNo; 534 535 private: 536 /// @brief The number of vehicles within the network (build and inserted but not removed) 537 int myRunningVehNo; 538 539 /// @brief The number of removed vehicles 540 int myEndedVehNo; 541 542 /// @brief The number of vehicles which were discarded while loading 543 int myDiscarded; 544 545 /// @brief The number of collisions 546 int myCollisions; 547 548 /// @brief The number of teleports due to jam 549 int myTeleportsJam; 550 551 /// @brief The number of teleports due to vehicles stuck on a minor road 552 int myTeleportsYield; 553 554 /// @brief The number of teleports due to vehicles stuck on the wrong lane 555 int myTeleportsWrongLane; 556 557 /// @brief The number of emergency stops 558 int myEmergencyStops; 559 560 /// @} 561 562 563 /// @name Vehicle statistics 564 /// @{ 565 566 /// @brief The aggregated time vehicles had to wait for departure (in seconds) 567 double myTotalDepartureDelay; 568 569 /// @brief The aggregated time vehicles needed to aacomplish their route (in seconds) 570 double myTotalTravelTime; 571 /// @} 572 573 574 protected: 575 /// @name Vehicle container 576 /// @{ 577 578 /// @brief Vehicle dictionary type 579 typedef std::map< std::string, SUMOVehicle* > VehicleDictType; 580 /// @brief Dictionary of vehicles 581 VehicleDictType myVehicleDict; 582 /// @} 583 584 585 private: 586 /// @name Vehicle type container 587 /// @{ 588 589 /// @brief Vehicle type dictionary type 590 typedef std::map< std::string, MSVehicleType* > VTypeDictType; 591 /// @brief Dictionary of vehicle types 592 VTypeDictType myVTypeDict; 593 594 /// @brief Vehicle type distribution dictionary type 595 typedef std::map< std::string, RandomDistributor<MSVehicleType*>* > VTypeDistDictType; 596 /// @brief A distribution of vehicle types (probability->vehicle type) 597 VTypeDistDictType myVTypeDistDict; 598 599 /// @brief Inverse lookup from vehicle type to distributions it is a member of 600 std::map<std::string, std::set<std::string>> myVTypeToDist; 601 602 /// @brief Whether the default vehicle type was already used or can still be replaced 603 bool myDefaultVTypeMayBeDeleted; 604 605 /// @brief Whether the default pedestrian type was already used or can still be replaced 606 bool myDefaultPedTypeMayBeDeleted; 607 608 /// @brief Whether the default bicycle type was already used or can still be replaced 609 bool myDefaultBikeTypeMayBeDeleted; 610 611 /// the lists of waiting vehicles to a given edge 612 std::map<const MSEdge* const, std::vector<SUMOVehicle*> > myWaiting; 613 614 /// the number of vehicles wainting for persons contained in myWaiting which can only continue by being triggered 615 int myWaitingForPerson; 616 617 /// the number of vehicles wainting for containers contained in myWaiting which can only continue by being triggered 618 int myWaitingForContainer; 619 620 /// @brief The scaling factor (especially for inc-dua) 621 double myScale; 622 623 /// @brief The maximum speed factor for all vehicles in the network 624 double myMaxSpeedFactor; 625 626 /// @brief The minimum deceleration capability for all vehicles in the network 627 double myMinDeceleration; 628 629 /// @brief List of vehicles which belong to public transport 630 std::vector<SUMOVehicle*> myPTVehicles; 631 632 /// @brief List of vehicles which are going to be removed 633 #ifdef HAVE_FOX 634 FXSynchQue<SUMOVehicle*, std::vector<SUMOVehicle*> > myPendingRemovals; 635 #else 636 std::vector<SUMOVehicle*> myPendingRemovals; 637 #endif 638 639 private: 640 /// @brief invalidated copy constructor 641 MSVehicleControl(const MSVehicleControl& s); 642 643 /// @brief invalidated assignment operator 644 MSVehicleControl& operator=(const MSVehicleControl& s); 645 646 647 }; 648 649 650 #endif 651 652 /****************************************************************************/ 653 654