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