SUMO - Simulation of Urban MObility

MSEdge.cpp

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