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

Generated on Wed May 5 00:06:31 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6