|
SUMO - Simulation of Urban MObility
|
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