SUMO - Simulation of Urban MObility

MSEdge.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00013 // A road/street connecting two junctions
00014 /****************************************************************************/
00015 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00016 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00017 /****************************************************************************/
00018 //
00019 //   This file is part of SUMO.
00020 //   SUMO is free software: you can redistribute it and/or modify
00021 //   it under the terms of the GNU General Public License as published by
00022 //   the Free Software Foundation, either version 3 of the License, or
00023 //   (at your option) any later version.
00024 //
00025 /****************************************************************************/
00026 
00027 
00028 // ===========================================================================
00029 // included modules
00030 // ===========================================================================
00031 #ifdef _MSC_VER
00032 #include <windows_config.h>
00033 #else
00034 #include <config.h>
00035 #endif
00036 
00037 #include "MSEdge.h"
00038 #include "MSLane.h"
00039 #include "MSLaneChanger.h"
00040 #include "MSGlobals.h"
00041 #include <algorithm>
00042 #include <iostream>
00043 #include <cassert>
00044 #include "MSVehicle.h"
00045 #include <utils/common/StringTokenizer.h>
00046 #include <utils/options/OptionsCont.h>
00047 #include "MSEdgeWeightsStorage.h"
00048 
00049 #ifdef HAVE_MESOSIM
00050 #include <mesosim/MELoop.h>
00051 #include <mesosim/MESegment.h>
00052 #endif
00053 
00054 #ifdef CHECK_MEMORY_LEAKS
00055 #include <foreign/nvwa/debug_new.h>
00056 #endif // CHECK_MEMORY_LEAKS
00057 
00058 
00059 // ===========================================================================
00060 // static member definitions
00061 // ===========================================================================
00062 MSEdge::DictType MSEdge::myDict;
00063 std::vector<MSEdge*> MSEdge::myEdges;
00064 
00065 
00066 // ===========================================================================
00067 // member method definitions
00068 // ===========================================================================
00069 MSEdge::MSEdge(const std::string& id, unsigned int numericalID,
00070                const std::string& streetName) :
00071     myID(id), myNumericalID(numericalID), myLanes(0),
00072     myLaneChanger(0), myVaporizationRequests(0), myLastFailedInsertionTime(-1),
00073     myStreetName(streetName) {}
00074 
00075 
00076 MSEdge::~MSEdge() {
00077     delete myLaneChanger;
00078     for (AllowedLanesCont::iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); i1++) {
00079         delete(*i1).second;
00080     }
00081     for (ClassedAllowedLanesCont::iterator i2 = myClassedAllowed.begin(); i2 != myClassedAllowed.end(); i2++) {
00082         for (AllowedLanesCont::iterator i1 = (*i2).second.begin(); i1 != (*i2).second.end(); i1++) {
00083             delete(*i1).second;
00084         }
00085     }
00086     delete myLanes;
00087     // Note: Lanes are delete using MSLane::clear();
00088 }
00089 
00090 
00091 void
00092 MSEdge::initialize(std::vector<MSLane*>* lanes, EdgeBasicFunction function) {
00093     assert(function == EDGEFUNCTION_DISTRICT || lanes != 0);
00094     myLanes = lanes;
00095     myFunction = function;
00096     if (myLanes && myLanes->size() > 1 && function != EDGEFUNCTION_INTERNAL) {
00097         myLaneChanger = new MSLaneChanger(myLanes, OptionsCont::getOptions().getBool("lanechange.allow-swap"));
00098     }
00099 }
00100 
00101 
00102 void
00103 MSEdge::closeBuilding() {
00104     myAllowed[0] = new std::vector<MSLane*>();
00105     for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
00106         myAllowed[0]->push_back(*i);
00107         const MSLinkCont& lc = (*i)->getLinkCont();
00108         for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
00109             MSLane* toL = (*j)->getLane();
00110             if (toL != 0) {
00111                 MSEdge& to = toL->getEdge();
00112                 //
00113                 if (std::find(mySuccessors.begin(), mySuccessors.end(), &to) == mySuccessors.end()) {
00114                     mySuccessors.push_back(&to);
00115                 }
00116                 if (std::find(to.myPredeccesors.begin(), to.myPredeccesors.end(), this) == to.myPredeccesors.end()) {
00117                     to.myPredeccesors.push_back(this);
00118                 }
00119                 //
00120                 if (myAllowed.find(&to) == myAllowed.end()) {
00121                     myAllowed[&to] = new std::vector<MSLane*>();
00122                 }
00123                 myAllowed[&to]->push_back(*i);
00124             }
00125         }
00126     }
00127     std::sort(mySuccessors.begin(), mySuccessors.end(), by_id_sorter());
00128     rebuildAllowedLanes();
00129 }
00130 
00131 
00132 void
00133 MSEdge::rebuildAllowedLanes() {
00134     // build the classed allowed lanes
00135     myHaveClassConstraints = false;
00136     // build list of vehicle classes that are constrained
00137     // ... all others will be not regarded (allowed) ...
00138     SUMOVehicleClasses vclasses;
00139     for (std::vector<MSLane*>::const_iterator i2 = myLanes->begin(); i2 != myLanes->end(); ++i2) {
00140         const SUMOVehicleClasses& allowed = (*i2)->getAllowedClasses();
00141         for (SUMOVehicleClasses::const_iterator j = allowed.begin(); j != allowed.end(); j++) {
00142             vclasses.insert(*j);
00143         }
00144         const SUMOVehicleClasses& disallowed = (*i2)->getNotAllowedClasses();
00145         for (SUMOVehicleClasses::const_iterator j = disallowed.begin(); j != disallowed.end(); j++) {
00146             vclasses.insert(*j);
00147         }
00148     }
00149     // go through these classes
00150     for (SUMOVehicleClasses::const_iterator j = vclasses.begin(); j != vclasses.end(); ++j) {
00151         // go through connected edges
00152         for (AllowedLanesCont::iterator i1 = myAllowed.begin(); i1 != myAllowed.end(); ++i1) {
00153             delete myClassedAllowed[*j][(*i1).first];
00154             myClassedAllowed[*j][(*i1).first] = new std::vector<MSLane*>();
00155             // go through lanes approaching current edge
00156             for (std::vector<MSLane*>::iterator i2 = (*i1).second->begin(); i2 != (*i1).second->end(); ++i2) {
00157                 // allows the current vehicle class?
00158                 if ((*i2)->allowsVehicleClass(*j)) {
00159                     // -> may be used
00160                     myClassedAllowed[*j][(*i1).first]->push_back(*i2);
00161                 }
00162             }
00163             // assert that 0 is returned if no connection is allowed for a class
00164             if (myClassedAllowed[*j][(*i1).first]->size() == 0) {
00165                 delete myClassedAllowed[*j][(*i1).first];
00166                 myClassedAllowed[*j][(*i1).first] = 0;
00167             }
00168         }
00169         myHaveClassConstraints = true;
00170     }
00171 }
00172 
00173 
00174 // ------------ Access to the edge's lanes
00175 MSLane*
00176 MSEdge::leftLane(const MSLane* const lane) const {
00177     std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
00178     if (laneIt == myLanes->end() || laneIt == myLanes->end() - 1) {
00179         return 0;
00180     }
00181     return *(laneIt + 1);
00182 }
00183 
00184 
00185 MSLane*
00186 MSEdge::rightLane(const MSLane* const lane) const {
00187     std::vector<MSLane*>::iterator laneIt = find(myLanes->begin(), myLanes->end(), lane);
00188     if (laneIt == myLanes->end() || laneIt == myLanes->begin()) {
00189         return 0;
00190     }
00191     return *(laneIt - 1);
00192 }
00193 
00194 
00195 const std::vector<MSLane*>*
00196 MSEdge::allowedLanes(const MSEdge& destination, SUMOVehicleClass vclass) const {
00197     return allowedLanes(&destination, vclass);
00198 }
00199 
00200 
00201 const std::vector<MSLane*>*
00202 MSEdge::allowedLanes(SUMOVehicleClass vclass) const {
00203     return allowedLanes(0, vclass);
00204 }
00205 
00206 
00207 const std::vector<MSLane*>*
00208 MSEdge::allowedLanes(const MSEdge* destination, SUMOVehicleClass vclass) const {
00209     if (myHaveClassConstraints && vclass != SVC_UNKNOWN) {
00210         ClassedAllowedLanesCont::const_iterator i = myClassedAllowed.find(vclass);
00211         if (i != myClassedAllowed.end()) {
00212             const AllowedLanesCont& c = (*i).second;
00213             AllowedLanesCont::const_iterator j = (*i).second.find(destination);
00214             if (j == c.end()) {
00215                 // Destination-edge not found.
00216                 return 0;
00217             }
00218             return (*j).second;
00219         }
00220     }
00221     AllowedLanesCont::const_iterator it = myAllowed.find(destination);
00222     if (it != myAllowed.end()) {
00223         return it->second;
00224     } else {
00225         // Destination-edge not found.
00226         return 0;
00227     }
00228 }
00229 
00230 
00231 // ------------
00232 SUMOTime
00233 MSEdge::incVaporization(SUMOTime) {
00234     ++myVaporizationRequests;
00235     return 0;
00236 }
00237 
00238 
00239 SUMOTime
00240 MSEdge::decVaporization(SUMOTime) {
00241     --myVaporizationRequests;
00242     return 0;
00243 }
00244 
00245 
00246 MSLane*
00247 MSEdge::getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass) const {
00248     if (allowed == 0) {
00249         allowed = allowedLanes(vclass);
00250     }
00251     MSLane* res = 0;
00252     if (allowed != 0) {
00253         unsigned int noCars = INT_MAX;
00254         for (std::vector<MSLane*>::const_iterator i = allowed->begin(); i != allowed->end(); ++i) {
00255             if ((*i)->getVehicleNumber() < noCars) {
00256                 res = (*i);
00257                 noCars = (*i)->getVehicleNumber();
00258             }
00259         }
00260     }
00261     return res;
00262 }
00263 
00264 
00265 MSLane*
00266 MSEdge::getDepartLane(const MSVehicle& veh) const {
00267     switch (veh.getParameter().departLaneProcedure) {
00268         case DEPART_LANE_GIVEN:
00269             if ((int) myLanes->size() <= veh.getParameter().departLane || !(*myLanes)[veh.getParameter().departLane]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
00270                 return 0;
00271             }
00272             return (*myLanes)[veh.getParameter().departLane];
00273         case DEPART_LANE_RANDOM:
00274             return RandHelper::getRandomFrom(*allowedLanes(veh.getVehicleType().getVehicleClass()));
00275         case DEPART_LANE_FREE:
00276             return getFreeLane(0, veh.getVehicleType().getVehicleClass());
00277         case DEPART_LANE_ALLOWED_FREE:
00278             if (veh.getRoute().size() == 1) {
00279                 return getFreeLane(0, veh.getVehicleType().getVehicleClass());
00280             } else {
00281                 return getFreeLane(allowedLanes(**(veh.getRoute().begin() + 1)), veh.getVehicleType().getVehicleClass());
00282             }
00283         case DEPART_LANE_BEST_FREE: {
00284             const std::vector<MSVehicle::LaneQ> &bl = veh.getBestLanes(false, (*myLanes)[0]);
00285             SUMOReal bestLength = -1;
00286             for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
00287                 if ((*i).length > bestLength) {
00288                     bestLength = (*i).length;
00289                 }
00290             }
00291             std::vector<MSLane*> *bestLanes = new std::vector<MSLane*>();
00292             for (std::vector<MSVehicle::LaneQ>::const_iterator i = bl.begin(); i != bl.end(); ++i) {
00293                 if ((*i).length == bestLength) {
00294                     bestLanes->push_back((*i).lane);
00295                 }
00296             }
00297             MSLane* ret = getFreeLane(bestLanes, veh.getVehicleType().getVehicleClass());
00298             delete bestLanes;
00299             return ret;
00300         }
00301         case DEPART_LANE_DEFAULT:
00302         default:
00303             break;
00304     }
00305     if (!(*myLanes)[0]->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
00306         return 0;
00307     }
00308     return (*myLanes)[0];
00309 }
00310 
00311 
00312 bool
00313 MSEdge::insertVehicle(SUMOVehicle& v, SUMOTime time) const {
00314     // when vaporizing, no vehicles are inserted...
00315     if (isVaporizing()) {
00316         return false;
00317     }
00318 #ifdef HAVE_MESOSIM
00319     if (MSGlobals::gUseMesoSim) {
00320         const SUMOVehicleParameter& pars = v.getParameter();
00321         SUMOReal pos = 0.0;
00322         switch (pars.departPosProcedure) {
00323             case DEPART_POS_GIVEN:
00324                 if (pars.departPos >= 0.) {
00325                     pos = pars.departPos;
00326                 } else {
00327                     pos = pars.departPos + getLanes()[0]->getLength();
00328                 }
00329                 break;
00330             case DEPART_POS_RANDOM:
00331             case DEPART_POS_RANDOM_FREE:
00332                 pos = RandHelper::rand(getLanes()[0]->getLength());
00333                 break;
00334             default:
00335                 break;
00336         }
00337         bool result = false;
00338         MESegment* segment = MSGlobals::gMesoNet->getSegmentForEdge(*this, pos);
00339         MEVehicle* veh = static_cast<MEVehicle*>(&v);
00340         if (pars.departPosProcedure == DEPART_POS_FREE) {
00341             while (segment != 0 && !result) {
00342                 result = segment->initialise(veh, time);
00343                 segment = segment->getNextSegment();
00344             }
00345         } else {
00346             result = segment->initialise(veh, time);
00347         }
00348         return result;
00349     }
00350 #endif
00351     MSLane* insertionLane = getDepartLane(static_cast<MSVehicle&>(v));
00352     return insertionLane != 0 && insertionLane->insertVehicle(static_cast<MSVehicle&>(v));
00353 }
00354 
00355 
00356 void
00357 MSEdge::changeLanes(SUMOTime t) {
00358     if (myFunction == EDGEFUNCTION_INTERNAL) {
00359         return;
00360     }
00361     assert(myLaneChanger != 0);
00362     myLaneChanger->laneChange(t);
00363 }
00364 
00365 
00366 
00367 #ifdef HAVE_INTERNAL_LANES
00368 const MSEdge*
00369 MSEdge::getInternalFollowingEdge(MSEdge* followerAfterInternal) const {
00370     //@todo to be optimized
00371     for (std::vector<MSLane*>::const_iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
00372         MSLane* l = *i;
00373         const MSLinkCont& lc = l->getLinkCont();
00374         for (MSLinkCont::const_iterator j = lc.begin(); j != lc.end(); ++j) {
00375             MSLink* link = *j;
00376             if (&link->getLane()->getEdge() == followerAfterInternal) {
00377                 return &link->getViaLane()->getEdge();
00378             }
00379         }
00380     }
00381     return 0;
00382 }
00383 #endif
00384 
00385 
00386 SUMOReal
00387 MSEdge::getCurrentTravelTime() const {
00388     SUMOReal v = 0;
00389 #ifdef HAVE_MESOSIM
00390     if (MSGlobals::gUseMesoSim) {
00391         MESegment* first = MSGlobals::gMesoNet->getSegmentForEdge(*this);
00392         unsigned segments = 0;
00393         do {
00394             v += first->getMeanSpeed();
00395             first = first->getNextSegment();
00396             segments++;
00397         } while (first != 0);
00398         v /= (SUMOReal) segments;
00399     } else {
00400 #endif
00401         for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
00402             v += (*i)->getMeanSpeed();
00403         }
00404         v /= (SUMOReal) myLanes->size();
00405 #ifdef HAVE_MESOSIM
00406     }
00407 #endif
00408     if (v != 0) {
00409         return (*myLanes)[0]->getLength() / v;
00410     } else {
00411         return 1000000.;
00412     }
00413 }
00414 
00415 
00416 bool
00417 MSEdge::prohibits(const SUMOVehicle* const vehicle) const {
00418     if (myFunction == EDGEFUNCTION_DISTRICT || !myHaveClassConstraints) {
00419         return false;
00420     }
00421     SUMOVehicleClass vclass = vehicle->getVehicleType().getVehicleClass();
00422     for (std::vector<MSLane*>::iterator i = myLanes->begin(); i != myLanes->end(); ++i) {
00423         if ((*i)->allowsVehicleClass(vclass)) {
00424             return false;
00425         }
00426     }
00427     return true;
00428 }
00429 
00430 
00431 bool
00432 MSEdge::dictionary(const std::string& id, MSEdge* ptr) {
00433     DictType::iterator it = myDict.find(id);
00434     if (it == myDict.end()) {
00435         // id not in myDict.
00436         myDict[id] = ptr;
00437         while (myEdges.size() < ptr->getNumericalID() + 1) {
00438             myEdges.push_back(0);
00439         }
00440         myEdges[ptr->getNumericalID()] = ptr;
00441         return true;
00442     }
00443     return false;
00444 }
00445 
00446 
00447 MSEdge*
00448 MSEdge::dictionary(const std::string& id) {
00449     DictType::iterator it = myDict.find(id);
00450     if (it == myDict.end()) {
00451         // id not in myDict.
00452         return 0;
00453     }
00454     return it->second;
00455 }
00456 
00457 
00458 MSEdge*
00459 MSEdge::dictionary(size_t id) {
00460     assert(myEdges.size() > id);
00461     return myEdges[id];
00462 }
00463 
00464 
00465 size_t
00466 MSEdge::dictSize() {
00467     return myDict.size();
00468 }
00469 
00470 
00471 void
00472 MSEdge::clear() {
00473     for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
00474         delete(*i).second;
00475     }
00476     myDict.clear();
00477 }
00478 
00479 
00480 void
00481 MSEdge::insertIDs(std::vector<std::string> &into) {
00482     for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
00483         into.push_back((*i).first);
00484     }
00485 }
00486 
00487 
00488 void
00489 MSEdge::parseEdgesList(const std::string& desc, std::vector<const MSEdge*> &into,
00490                        const std::string& rid) {
00491     StringTokenizer st(desc);
00492     parseEdgesList(st.getVector(), into, rid);
00493 }
00494 
00495 
00496 void
00497 MSEdge::parseEdgesList(const std::vector<std::string> &desc, std::vector<const MSEdge*> &into,
00498                        const std::string& rid) {
00499     for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
00500         const MSEdge* edge = MSEdge::dictionary(*i);
00501         // check whether the edge exists
00502         if (edge == 0) {
00503             throw ProcessError("The edge '" + *i + "' within the route " + rid + " is not known."
00504                                + "\n The route can not be build.");
00505         }
00506         into.push_back(edge);
00507     }
00508 }
00509 
00510 
00511 /****************************************************************************/
00512 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines