|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Representation of a lane in the micro simulation 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 <utils/common/UtilExceptions.h> 00031 #include <utils/common/StdDefs.h> 00032 #include "MSVehicle.h" 00033 #include "MSVehicleType.h" 00034 #include "MSEdge.h" 00035 #include "MSEdgeControl.h" 00036 #include "MSJunction.h" 00037 #include "MSLogicJunction.h" 00038 #include "MSLink.h" 00039 #include "MSLane.h" 00040 #include "MSVehicleTransfer.h" 00041 #include "MSGlobals.h" 00042 #include "MSVehicleControl.h" 00043 #include <cmath> 00044 #include <bitset> 00045 #include <iostream> 00046 #include <cassert> 00047 #include <functional> 00048 #include <algorithm> 00049 #include <iterator> 00050 #include <exception> 00051 #include <climits> 00052 #include <set> 00053 #include <utils/common/MsgHandler.h> 00054 #include <utils/common/ToString.h> 00055 #include <utils/options/OptionsCont.h> 00056 #include <utils/common/HelpersHarmonoise.h> 00057 00058 #ifdef CHECK_MEMORY_LEAKS 00059 #include <foreign/nvwa/debug_new.h> 00060 #endif // CHECK_MEMORY_LEAKS 00061 00062 00063 // =========================================================================== 00064 // static member definitions 00065 // =========================================================================== 00066 MSLane::DictType MSLane::myDict; 00067 00068 00069 // =========================================================================== 00070 // member method definitions 00071 // =========================================================================== 00072 MSLane::MSLane(const std::string& id, SUMOReal maxSpeed, SUMOReal length, MSEdge* const edge, 00073 unsigned int numericalID, const PositionVector& shape, SUMOReal width, 00074 const SUMOVehicleClasses& allowed, 00075 const SUMOVehicleClasses& disallowed) throw() : 00076 Named(id), 00077 myShape(shape), myNumericalID(numericalID), 00078 myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed), 00079 myAllowedClasses(allowed), myNotAllowedClasses(disallowed), 00080 myLogicalPredecessorLane(0), 00081 myVehicleLengthSum(0), myInlappingVehicleEnd(10000), myInlappingVehicle(0) { 00082 } 00083 00084 00085 MSLane::~MSLane() throw() { 00086 for (MSLinkCont::iterator i=myLinks.begin(); i!=myLinks.end(); ++i) { 00087 delete *i; 00088 } 00089 } 00090 00091 00092 void 00093 MSLane::initialize(MSLinkCont* links) { 00094 myLinks = *links; 00095 delete links; 00096 } 00097 00098 00099 void 00100 MSLane::addLink(MSLink* link) { 00101 myLinks.push_back(link); 00102 } 00103 00104 00105 // ------ interaction with MSMoveReminder ------ 00106 void 00107 MSLane::addMoveReminder(MSMoveReminder* rem) throw() { 00108 myMoveReminders.push_back(rem); 00109 for (VehCont::iterator veh=myVehicles.begin(); veh != myVehicles.end(); ++veh) { 00110 (*veh)->addReminder(rem); 00111 } 00112 } 00113 00114 00115 00116 // ------ Vehicle emission ------ 00117 void 00118 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) throw(ProcessError) { 00119 bool wasInactive = myVehicles.size()==0; 00120 veh->enterLaneAtInsertion(this, pos, speed, notification); 00121 if (at==myVehicles.end()) { 00122 // vehicle will be the first on the lane 00123 myVehicles.push_back(veh); 00124 } else { 00125 myVehicles.insert(at, veh); 00126 } 00127 myVehicleLengthSum += veh->getVehicleType().getLengthWithGap(); 00128 if (wasInactive) { 00129 MSNet::getInstance()->getEdgeControl().gotActive(this); 00130 } 00131 } 00132 00133 00134 bool 00135 MSLane::pWagGenericInsertion(MSVehicle& veh, SUMOReal mspeed, SUMOReal maxPos, SUMOReal minPos) throw() { 00136 SUMOReal xIn = maxPos; 00137 SUMOReal vIn = mspeed; 00138 SUMOReal leaderDecel; 00139 if (myVehicles.size()!=0) { 00140 MSVehicle* leader = myVehicles.front(); 00141 xIn = leader->getPositionOnLane() - leader->getVehicleType().getLengthWithGap(); 00142 vIn = leader->getSpeed(); 00143 leaderDecel = leader->getCarFollowModel().getMaxDecel(); 00144 } else { 00145 veh.getBestLanes(true, this); 00146 SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed); 00147 std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this)); 00148 if (leader.first!=0) { 00149 xIn = getLength() + leader.second; 00150 vIn = leader.first->getSpeed(); 00151 leaderDecel = leader.first->getCarFollowModel().getMaxDecel(); 00152 } else { 00153 incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end()); 00154 return true; 00155 } 00156 } 00157 int nIter = 10; 00158 SUMOReal vHlp = 0.5*(vIn + mspeed); 00159 SUMOReal x2 = xIn;// have seen leader length already - skCar::lCar; 00160 SUMOReal x1 = x2 - 100.0; 00161 SUMOReal v = vIn; 00162 SUMOReal x = 0; 00163 for (int i=0; i<=nIter; i++) { 00164 x = 0.5*(x1 + x2); 00165 SUMOReal vSafe = veh.getCarFollowModel().followSpeed(&veh, v, xIn - x, vIn, leaderDecel); 00166 if (vSafe<vHlp) { 00167 x2 = x; 00168 } else { 00169 x1 = x; 00170 } 00171 } 00172 if (xIn<minPos) { 00173 return false; 00174 } else if (xIn>maxPos) { 00175 xIn = maxPos; 00176 } 00177 incorporateVehicle(&veh, x, v, myVehicles.begin()); 00178 return true; 00179 } 00180 00181 00182 bool 00183 MSLane::pWagSimpleInsertion(MSVehicle& veh, SUMOReal mspeed, SUMOReal maxPos, SUMOReal minPos) throw() { 00184 SUMOReal xIn = maxPos; 00185 SUMOReal vIn = mspeed; 00186 if (myVehicles.size()!=0) { 00187 MSVehicle* leader = myVehicles.front(); 00188 xIn = leader->getPositionOnLane() - leader->getVehicleType().getLengthWithGap(); 00189 vIn = leader->getSpeed(); 00190 } else { 00191 veh.getBestLanes(true, this); 00192 SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed); 00193 std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this)); 00194 if (leader.first!=0) { 00195 xIn = getLength() + leader.second; 00196 vIn = leader.first->getSpeed(); 00197 } else { 00198 incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end()); 00199 return true; 00200 } 00201 } 00202 SUMOReal vHlp = 0.5*(mspeed + vIn); 00203 xIn = xIn - vHlp * veh.getCarFollowModel().getHeadwayTime(); 00204 if (xIn<minPos) { 00205 return false; 00206 } else if (xIn>maxPos) { 00207 xIn = maxPos; 00208 } 00209 incorporateVehicle(&veh, xIn, vHlp, myVehicles.begin()); 00210 return true; 00211 } 00212 00213 00214 bool 00215 MSLane::maxSpeedGapInsertion(MSVehicle& veh, SUMOReal mspeed) throw() { 00216 if (myVehicles.size()==0) { 00217 return isInsertionSuccess(&veh, mspeed, myLength / 2, true); 00218 } 00219 // go through the lane, look for free positions (starting after the last vehicle) 00220 MSLane::VehCont::iterator predIt = myVehicles.begin(); 00221 while (predIt!=myVehicles.end()) { 00222 // get leader (may be zero) and follower 00223 const MSVehicle* leader = predIt!=myVehicles.end()-1 ? *(predIt+1) : getPartialOccupator(); 00224 const MSVehicle* follower = *predIt; 00225 SUMOReal leaderRearPos = getLength(); 00226 SUMOReal leaderSpeed = mspeed; 00227 if (leader!=0) { 00228 leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLengthWithGap(); 00229 if (leader == getPartialOccupator()) { 00230 leaderRearPos = getPartialOccupatorEnd(); 00231 } 00232 leaderSpeed = leader->getSpeed(); 00233 } 00234 const SUMOReal gap = leaderRearPos - follower->getPositionOnLane(); 00235 const SUMOReal fSpeed = follower->getSpeed(); 00236 const SUMOReal maxSpeed = (gap + leaderSpeed * leaderSpeed / veh.getCarFollowModel().getMaxDecel() - fSpeed * fSpeed / follower->getCarFollowModel().getMaxDecel()) / veh.getCarFollowModel().getHeadwayTime() - fSpeed; 00237 if (maxSpeed > 0) { 00238 if (isInsertionSuccess(&veh, MIN2(maxSpeed, mspeed), (leaderRearPos + follower->getPositionOnLane() + veh.getVehicleType().getLengthWithGap()) / 2, true)) { 00239 return true; 00240 } 00241 } 00242 ++predIt; 00243 } 00244 // first check at lane's begin 00245 return false; 00246 } 00247 00248 00249 bool 00250 MSLane::freeInsertion(MSVehicle& veh, SUMOReal mspeed, 00251 MSMoveReminder::Notification notification) throw() { 00252 bool adaptableSpeed = true; 00253 if (myVehicles.size()==0) { 00254 if (isInsertionSuccess(&veh, mspeed, 0, adaptableSpeed, notification)) { 00255 return true; 00256 } 00257 } else { 00258 // check whether the vehicle can be put behind the last one if there is such 00259 MSVehicle* leader = myVehicles.back(); 00260 SUMOReal leaderPos = leader->getPositionOnLane() - leader->getVehicleType().getLengthWithGap(); 00261 SUMOReal speed = mspeed; 00262 if (adaptableSpeed) { 00263 speed = leader->getSpeed(); 00264 } 00265 SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()); 00266 if (leaderPos-frontGapNeeded>=0) { 00267 SUMOReal tspeed = MIN2(veh.getCarFollowModel().followSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed); 00268 // check whether we can insert our vehicle behind the last vehicle on the lane 00269 if (isInsertionSuccess(&veh, tspeed, 0, adaptableSpeed, notification)) { 00270 return true; 00271 } 00272 } 00273 } 00274 // go through the lane, look for free positions (starting after the last vehicle) 00275 MSLane::VehCont::iterator predIt = myVehicles.begin(); 00276 while (predIt!=myVehicles.end()) { 00277 // get leader (may be zero) and follower 00278 const MSVehicle* leader = predIt!=myVehicles.end()-1 ? *(predIt+1) : getPartialOccupator(); 00279 const MSVehicle* follower = *predIt; 00280 00281 // patch speed if allowed 00282 SUMOReal speed = mspeed; 00283 if (adaptableSpeed&&leader!=0) { 00284 speed = MIN2(leader->getSpeed(), mspeed); 00285 } 00286 00287 // compute the space needed to not collide with leader 00288 SUMOReal frontMax = getLength(); 00289 if (leader!=0) { 00290 SUMOReal leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLengthWithGap(); 00291 if (leader == getPartialOccupator()) { 00292 leaderRearPos = getPartialOccupatorEnd(); 00293 } 00294 SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()); 00295 frontMax = leaderRearPos - frontGapNeeded; 00296 } 00297 // compute the space needed to not let the follower collide 00298 const SUMOReal followPos = follower->getPositionOnLane(); 00299 const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel()); 00300 const SUMOReal backMin = followPos + backGapNeeded + veh.getVehicleType().getLengthWithGap(); 00301 00302 // check whether there is enough room (given some extra space for rounding errors) 00303 if (frontMax>0 && backMin+POSITION_EPS<frontMax) { 00304 // try to insert vehicle (should be always ok) 00305 if (isInsertionSuccess(&veh, speed, backMin+POSITION_EPS, adaptableSpeed, notification)) { 00306 return true; 00307 } 00308 } 00309 ++predIt; 00310 } 00311 // first check at lane's begin 00312 return false; 00313 } 00314 00315 00316 bool 00317 MSLane::insertVehicle(MSVehicle& veh) throw(ProcessError) { 00318 SUMOReal pos = 0; 00319 SUMOReal speed = 0; 00320 bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front 00321 00322 // determine the speed 00323 const SUMOVehicleParameter& pars = veh.getParameter(); 00324 switch (pars.departSpeedProcedure) { 00325 case DEPART_SPEED_GIVEN: 00326 speed = pars.departSpeed; 00327 patchSpeed = false; 00328 break; 00329 case DEPART_SPEED_RANDOM: 00330 speed = RandHelper::rand(MIN2(veh.getMaxSpeed(), getMaxSpeed())); 00331 patchSpeed = true; // !!!(?) 00332 break; 00333 case DEPART_SPEED_MAX: 00334 speed = MIN2(veh.getMaxSpeed(), getMaxSpeed()); 00335 patchSpeed = true; // !!!(?) 00336 break; 00337 case DEPART_SPEED_DEFAULT: 00338 default: 00339 // speed = 0 was set before 00340 patchSpeed = false; // !!!(?) 00341 break; 00342 } 00343 00344 // determine the position 00345 switch (pars.departPosProcedure) { 00346 case DEPART_POS_GIVEN: 00347 // Maybe we should warn the user about invalid inputs! 00348 if (pars.departPos >= 0.) { 00349 pos = MIN2(pars.departPos, getLength()); 00350 } else { 00351 pos = MAX2(pars.departPos + getLength(), static_cast<SUMOReal>(0)); 00352 } 00353 break; 00354 case DEPART_POS_RANDOM: 00355 pos = RandHelper::rand(getLength()); 00356 break; 00357 case DEPART_POS_RANDOM_FREE: { 00358 for (unsigned int i=0; i < 10; i++) { 00359 // we will try some random positions ... 00360 pos = RandHelper::rand(getLength()); 00361 if (isInsertionSuccess(&veh, speed, pos, patchSpeed)) { 00362 return true; 00363 } 00364 } 00365 // ... and if that doesn't work, we put the vehicle to the free position 00366 return freeInsertion(veh, speed); 00367 } 00368 break; 00369 case DEPART_POS_FREE: 00370 return freeInsertion(veh, speed); 00371 case DEPART_POS_PWAG_SIMPLE: 00372 return pWagSimpleInsertion(veh, speed, getLength(), 0.0); 00373 case DEPART_POS_PWAG_GENERIC: 00374 return pWagGenericInsertion(veh, speed, getLength(), 0.0); 00375 case DEPART_POS_MAX_SPEED_GAP: 00376 return maxSpeedGapInsertion(veh, speed); 00377 case DEPART_POS_BASE: 00378 case DEPART_POS_DEFAULT: 00379 default: 00380 pos = MIN2(static_cast<SUMOReal>(veh.getVehicleType().getLengthWithGap() + POSITION_EPS), myLength); 00381 break; 00382 } 00383 // try to insert 00384 return isInsertionSuccess(&veh, speed, pos, patchSpeed); 00385 } 00386 00387 00388 bool 00389 MSLane::isInsertionSuccess(MSVehicle* aVehicle, 00390 SUMOReal speed, SUMOReal pos, bool patchSpeed, 00391 MSMoveReminder::Notification notification) throw(ProcessError) { 00392 aVehicle->getBestLanes(true, this); 00393 const MSCFModel& cfModel = aVehicle->getCarFollowModel(); 00394 const std::vector<MSLane*> &bestLaneConts = aVehicle->getBestLanesContinuation(this); 00395 std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin(); 00396 SUMOReal seen = getLength() - pos; 00397 SUMOReal dist = cfModel.brakeGap(speed); 00398 const MSRoute& r = aVehicle->getRoute(); 00399 MSRouteIterator ce = r.begin(); 00400 MSLane* currentLane = this; 00401 MSLane* nextLane = this; 00402 SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen/speed); 00403 while (seen<dist&&ri!=bestLaneConts.end()) { 00404 // get the next link used... 00405 MSLinkCont::const_iterator link = currentLane->succLinkSec(*aVehicle, 1, *currentLane, bestLaneConts); 00406 // ...and the next used lane (including internal) 00407 if (!currentLane->isLinkEnd(link) && (*link)->opened(arrivalTime, speed, aVehicle->getVehicleType().getLengthWithGap()) && (*link)->getState()!=LINKSTATE_TL_RED) { // red may have priority? 00408 #ifdef HAVE_INTERNAL_LANES 00409 bool nextInternal = false; 00410 nextLane = (*link)->getViaLane(); 00411 if (nextLane==0) { 00412 nextLane = (*link)->getLane(); 00413 } else { 00414 nextInternal = true; 00415 } 00416 #else 00417 nextLane = (*link)->getLane(); 00418 #endif 00419 } else { 00420 break; 00421 } 00422 // check how next lane effects the journey 00423 if (nextLane!=0) { 00424 arrivalTime += TIME2STEPS(nextLane->getLength()/speed); 00425 SUMOReal gap = 0; 00426 MSVehicle* leader = currentLane->getPartialOccupator(); 00427 if (leader!=0) { 00428 gap = getPartialOccupatorEnd(); 00429 } else { 00430 // check leader on next lane 00431 leader = nextLane->getLastVehicle(); 00432 if (leader!=0) { 00433 gap = seen+leader->getPositionOnLane()-leader->getVehicleType().getLengthWithGap(); 00434 } 00435 } 00436 if (leader!=0) { 00437 SUMOReal nspeed = gap>=0 ? cfModel.followSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) : 0; 00438 if (nspeed<speed) { 00439 if (patchSpeed) { 00440 speed = MIN2(nspeed, speed); 00441 dist = cfModel.brakeGap(speed); 00442 } else { 00443 // we may not drive with the given velocity - we crash into the leader 00444 return false; 00445 } 00446 } 00447 } 00448 // check next lane's maximum velocity 00449 SUMOReal nspeed = nextLane->getMaxSpeed(); 00450 if (nspeed<speed) { 00451 // patch speed if needed 00452 if (patchSpeed) { 00453 speed = MIN2(cfModel.freeSpeed(aVehicle, speed, seen, nspeed), speed); 00454 dist = cfModel.brakeGap(speed); 00455 } else { 00456 // we may not drive with the given velocity - we would be too fast on the next lane 00457 return false; 00458 } 00459 } 00460 // check traffic on next junctions 00461 const SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed); 00462 #ifdef HAVE_INTERNAL_LANES 00463 const SUMOTime leaveTime = (*link)->getViaLane()==0 ? arrivalTime + TIME2STEPS((*link)->getLength() * speed) : arrivalTime + TIME2STEPS((*link)->getViaLane()->getLength() * speed); 00464 #else 00465 const SUMOTime leaveTime = arrivalTime + TIME2STEPS((*link)->getLength() * speed); 00466 #endif 00467 if ((*link)->hasApproachingFoe(arrivalTime, leaveTime)) { 00468 SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0); 00469 if (nspeed<speed) { 00470 if (patchSpeed) { 00471 speed = MIN2(nspeed, speed); 00472 dist = cfModel.brakeGap(speed); 00473 } else { 00474 // we may not drive with the given velocity - we crash into the leader 00475 return false; 00476 } 00477 } 00478 } else { 00479 // we can only drive to the end of the current lane... 00480 SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0); 00481 if (nspeed<speed) { 00482 if (patchSpeed) { 00483 speed = MIN2(nspeed, speed); 00484 dist = cfModel.brakeGap(speed); 00485 } else { 00486 // we may not drive with the given velocity - we crash into the leader 00487 return false; 00488 } 00489 } 00490 } 00491 seen += nextLane->getLength(); 00492 ++ce; 00493 ++ri; 00494 currentLane = nextLane; 00495 } 00496 } 00497 if (seen<dist) { 00498 SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0); 00499 if (nspeed<speed) { 00500 if (patchSpeed) { 00501 speed = MIN2(nspeed, speed); 00502 dist = cfModel.brakeGap(speed); 00503 } else { 00504 // we may not drive with the given velocity - we crash into the leader 00505 WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using given velocity!"); 00506 // !!! we probably should do something else... 00507 return false; 00508 } 00509 } 00510 } 00511 00512 // get the pointer to the vehicle next in front of the given position 00513 MSLane::VehCont::iterator predIt = find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)); 00514 if (predIt != myVehicles.end()) { 00515 // ok, there is one (a leader) 00516 MSVehicle* leader = *predIt; 00517 SUMOReal frontGapNeeded = cfModel.getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()); 00518 SUMOReal gap = MSVehicle::gap(leader->getPositionOnLane(), leader->getVehicleType().getLengthWithGap(), pos); 00519 if (gap<frontGapNeeded) { 00520 // too close to the leader on this lane 00521 return false; 00522 } 00523 } 00524 00525 // check back vehicle 00526 if (predIt!=myVehicles.begin()) { 00527 // there is direct follower on this lane 00528 MSVehicle* follower = *(predIt-1); 00529 SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), aVehicle->getSpeed(), cfModel.getMaxDecel()); 00530 SUMOReal gap = MSVehicle::gap(pos, aVehicle->getVehicleType().getLengthWithGap(), follower->getPositionOnLane()); 00531 if (gap<backGapNeeded) { 00532 // too close to the follower on this lane 00533 return false; 00534 } 00535 } else { 00536 // check approaching vehicle (consecutive follower) 00537 SUMOReal lspeed = getMaxSpeed(); 00538 // in order to look back, we'd need the minimum braking ability of vehicles in the net... 00539 // we'll assume it to be 4m/s^2 00540 // !!!revisit 00541 SUMOReal dist = lspeed * lspeed / (2.*4.) + SPEED2DIST(lspeed); 00542 std::pair<const MSVehicle* const, SUMOReal> approaching = getFollowerOnConsecutive(dist, 0, speed, pos - aVehicle->getVehicleType().getLengthWithGap(), 4.5); 00543 if (approaching.first!=0) { 00544 const MSVehicle* const follower = approaching.first; 00545 SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), aVehicle->getSpeed(), cfModel.getMaxDecel()); 00546 SUMOReal gap = approaching.second - pos - aVehicle->getVehicleType().getLengthWithGap(); 00547 if (gap<backGapNeeded) { 00548 // too close to the consecutive follower 00549 return false; 00550 } 00551 } 00552 // check for in-lapping vehicle 00553 MSVehicle* leader = getPartialOccupator(); 00554 if (leader!=0) { 00555 SUMOReal frontGapNeeded = cfModel.getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()); 00556 SUMOReal gap = getPartialOccupatorEnd() - pos; 00557 if (gap<=frontGapNeeded) { 00558 // too close to the leader on this lane 00559 return false; 00560 } 00561 } 00562 } 00563 00564 // may got negative while adaptation 00565 if (speed<0) { 00566 return false; 00567 } 00568 // enter 00569 incorporateVehicle(aVehicle, pos, speed, predIt, notification); 00570 return true; 00571 } 00572 00573 00574 void 00575 MSLane::forceVehicleInsertion(MSVehicle* veh, SUMOReal pos) throw() { 00576 incorporateVehicle(veh, pos, veh->getSpeed(), find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos))); 00577 } 00578 00579 00580 // ------ Handling vehicles lapping into lanes ------ 00581 SUMOReal 00582 MSLane::setPartialOccupation(MSVehicle* v, SUMOReal leftVehicleLength) throw() { 00583 myInlappingVehicle = v; 00584 if (leftVehicleLength>myLength) { 00585 myInlappingVehicleEnd = 0; 00586 } else { 00587 myInlappingVehicleEnd = myLength-leftVehicleLength; 00588 } 00589 return myLength; 00590 } 00591 00592 00593 void 00594 MSLane::resetPartialOccupation(MSVehicle* v) throw() { 00595 if (v==myInlappingVehicle) { 00596 myInlappingVehicleEnd = 10000; 00597 } 00598 myInlappingVehicle = 0; 00599 } 00600 00601 00602 std::pair<MSVehicle*, SUMOReal> 00603 MSLane::getLastVehicleInformation() const throw() { 00604 if (myVehicles.size()!=0) { 00605 // the last vehicle is the one in scheduled by this lane 00606 MSVehicle* last = *myVehicles.begin(); 00607 const SUMOReal pos = last->getPositionOnLane()-last->getVehicleType().getLengthWithGap(); 00608 return std::make_pair(last, pos); 00609 } 00610 if (myInlappingVehicle!=0) { 00611 // the last one is a vehicle extending into this lane 00612 return std::make_pair(myInlappingVehicle, myInlappingVehicleEnd); 00613 } 00614 return std::make_pair<MSVehicle*, SUMOReal>(0, 0); 00615 } 00616 00617 00618 // ------ ------ 00619 bool 00620 MSLane::moveCritical(SUMOTime t) { 00621 myLeftVehLength = myVehicleLengthSum; 00622 assert(myVehicles.size()!=0); 00623 std::vector<MSVehicle*> collisions; 00624 VehCont::iterator lastBeforeEnd = myVehicles.end() - 1; 00625 VehCont::iterator veh; 00626 // Move all next vehicles beside the first 00627 for (veh=myVehicles.begin(); veh != lastBeforeEnd;) { 00628 myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap(); 00629 VehCont::const_iterator pred(veh + 1); 00630 if ((*veh)->moveRegardingCritical(t, this, *pred, 0, myLeftVehLength)) { 00631 collisions.push_back(*veh); 00632 } 00633 ++veh; 00634 } 00635 myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap(); 00636 if ((*veh)->moveRegardingCritical(t, this, 0, 0, myLeftVehLength)) { 00637 collisions.push_back(*veh); 00638 } 00639 assert((*veh)->getPositionOnLane() <= myLength); 00640 assert((*veh)->getLane()==this); 00641 // deal with collisions 00642 for (std::vector<MSVehicle*>::iterator i=collisions.begin(); i!=collisions.end(); ++i) { 00643 WRITE_WARNING("Teleporting vehicle '" + (*i)->getID() + "'; collision, lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00644 myVehicleLengthSum -= (*i)->getVehicleType().getLengthWithGap(); 00645 myVehicles.erase(find(myVehicles.begin(), myVehicles.end(), *i)); 00646 MSVehicleTransfer::getInstance()->addVeh(t, *i); 00647 } 00648 return myVehicles.size()==0; 00649 } 00650 00651 00652 void 00653 MSLane::detectCollisions(SUMOTime timestep) { 00654 if (myVehicles.size() < 2) { 00655 return; 00656 } 00657 00658 VehCont::iterator lastVeh = myVehicles.end() - 1; 00659 for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) { 00660 VehCont::iterator pred = veh + 1; 00661 SUMOReal gap = (*pred)->getPositionOnLane() - (*pred)->getVehicleType().getLengthWithGap() - (*veh)->getPositionOnLane(); 00662 if (gap < 0) { 00663 MSVehicle* vehV = *veh; 00664 WRITE_WARNING("Teleporting vehicle '" + vehV->getID() + "'; collision, lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00665 myVehicleLengthSum -= vehV->getVehicleType().getLengthWithGap(); 00666 MSVehicleTransfer::getInstance()->addVeh(timestep, vehV); 00667 veh = myVehicles.erase(veh); // remove current vehicle 00668 lastVeh = myVehicles.end() - 1; 00669 if (veh==myVehicles.end()) { 00670 break; 00671 } 00672 } else { 00673 ++veh; 00674 } 00675 } 00676 } 00677 00678 00679 SUMOReal 00680 getMaxSpeedRegardingNextLanes(MSVehicle& veh, SUMOReal speed, SUMOReal pos) { 00681 MSRouteIterator next = veh.getRoute().begin(); 00682 const MSCFModel& cfModel = veh.getCarFollowModel(); 00683 MSLane* currentLane = (*next)->getLanes()[0]; 00684 SUMOReal seen = currentLane->getLength() - pos; 00685 SUMOReal dist = SPEED2DIST(speed) + cfModel.brakeGap(speed); 00686 SUMOReal tspeed = speed; 00687 while (seen<dist&&next!=veh.getRoute().end()-1) { 00688 ++next; 00689 MSLane* nextLane = (*next)->getLanes()[0]; 00690 tspeed = MIN2(cfModel.freeSpeed(&veh, tspeed, seen, nextLane->getMaxSpeed()), nextLane->getMaxSpeed()); 00691 dist = SPEED2DIST(tspeed) + cfModel.brakeGap(tspeed); 00692 seen += nextLane->getMaxSpeed(); 00693 } 00694 return tspeed; 00695 } 00696 00697 00698 bool 00699 MSLane::setCritical(SUMOTime t, std::vector<MSLane*> &into) { 00700 // move critical vehicles 00701 for (VehCont::iterator i=myVehicles.begin(); i!=myVehicles.end();) { 00702 MSVehicle* veh = *i; 00703 bool moved = veh->moveChecked(); 00704 MSLane* target = veh->getLane(); 00705 SUMOReal length = veh->getVehicleType().getLengthWithGap(); 00706 if (veh->ends()) { 00707 // vehicle has reached its arrival position 00708 veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_ARRIVED); 00709 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(veh); 00710 } else if (target!=0&&moved) { 00711 if (target->getEdge().isVaporizing()) { 00712 // vehicle has reached a vaporizing edge 00713 veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_VAPORIZED); 00714 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(veh); 00715 } else { 00716 // vehicle has entered a new lane 00717 target->myVehBuffer.push_back(veh); 00718 SUMOReal pspeed = veh->getSpeed(); 00719 SUMOReal oldPos = veh->getPositionOnLane() - SPEED2DIST(veh->getSpeed()); 00720 veh->workOnMoveReminders(oldPos, veh->getPositionOnLane(), pspeed); 00721 into.push_back(target); 00722 } 00723 } else if (veh->isParking()) { 00724 // vehicle started to park 00725 veh->leaveLane(MSMoveReminder::NOTIFICATION_JUNCTION); 00726 MSVehicleTransfer::getInstance()->addVeh(t, veh); 00727 } else if (veh->getPositionOnLane()>getLength()) { 00728 // for any reasons the vehicle is beyond its lane... error 00729 WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond lane (2), targetLane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00730 MSVehicleTransfer::getInstance()->addVeh(t, veh); 00731 } else { 00732 ++i; 00733 continue; 00734 } 00735 myVehicleLengthSum -= length; 00736 i = myVehicles.erase(i); 00737 } 00738 if (myVehicles.size()>0) { 00739 if (MSGlobals::gTimeToGridlock>0 00740 && !(*(myVehicles.end()-1))->isStopped() 00741 && (*(myVehicles.end()-1))->getWaitingTime()>MSGlobals::gTimeToGridlock) { 00742 MSVehicle* veh = *(myVehicles.end()-1); 00743 myVehicleLengthSum -= veh->getVehicleType().getLengthWithGap(); 00744 myVehicles.erase(myVehicles.end()-1); 00745 WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00746 MSVehicleTransfer::getInstance()->addVeh(t, veh); 00747 } 00748 } 00749 return myVehicles.size()==0; 00750 } 00751 00752 00753 bool 00754 MSLane::dictionary(std::string id, MSLane* ptr) { 00755 DictType::iterator it = myDict.find(id); 00756 if (it == myDict.end()) { 00757 // id not in myDict. 00758 myDict.insert(DictType::value_type(id, ptr)); 00759 return true; 00760 } 00761 return false; 00762 } 00763 00764 00765 MSLane* 00766 MSLane::dictionary(std::string id) { 00767 DictType::iterator it = myDict.find(id); 00768 if (it == myDict.end()) { 00769 // id not in myDict. 00770 return 0; 00771 } 00772 return it->second; 00773 } 00774 00775 00776 void 00777 MSLane::clear() { 00778 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); ++i) { 00779 delete(*i).second; 00780 } 00781 myDict.clear(); 00782 } 00783 00784 00785 void 00786 MSLane::insertIDs(std::vector<std::string> &into) throw() { 00787 for (DictType::iterator i=myDict.begin(); i!=myDict.end(); ++i) { 00788 into.push_back((*i).first); 00789 } 00790 } 00791 00792 00793 bool 00794 MSLane::appropriate(const MSVehicle* veh) { 00795 if (myEdge->getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) { 00796 return true; 00797 } 00798 MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation()); 00799 return (link != myLinks.end()); 00800 } 00801 00802 00803 bool 00804 MSLane::integrateNewVehicle(SUMOTime) { 00805 bool wasInactive = myVehicles.size()==0; 00806 sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter()); 00807 for (std::vector<MSVehicle*>::const_iterator i=myVehBuffer.begin(); i!=myVehBuffer.end(); ++i) { 00808 MSVehicle* veh = *i; 00809 myVehicles.push_front(veh); 00810 myVehicleLengthSum += veh->getVehicleType().getLengthWithGap(); 00811 } 00812 myVehBuffer.clear(); 00813 return wasInactive&&myVehicles.size()!=0; 00814 } 00815 00816 00817 bool 00818 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const { 00819 return i==myLinks.end(); 00820 } 00821 00822 00823 bool 00824 MSLane::isLinkEnd(MSLinkCont::iterator& i) { 00825 return i==myLinks.end(); 00826 } 00827 00828 00829 MSVehicle* 00830 MSLane::getLastVehicle() const { 00831 if (myVehicles.size()==0) { 00832 return 0; 00833 } 00834 return *myVehicles.begin(); 00835 } 00836 00837 00838 const MSVehicle* 00839 MSLane::getFirstVehicle() const { 00840 if (myVehicles.size()==0) { 00841 return 0; 00842 } 00843 return *(myVehicles.end()-1); 00844 } 00845 00846 00847 MSLinkCont::const_iterator 00848 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs, 00849 const MSLane& succLinkSource, const std::vector<MSLane*> &conts) const { 00850 const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs); 00851 // check whether the vehicle tried to look beyond its route 00852 if (nRouteEdge==0) { 00853 // return end (no succeeding link) if so 00854 return succLinkSource.myLinks.end(); 00855 } 00856 // a link may be used if 00857 // 1) there is a destination lane ((*link)->getLane()!=0) 00858 // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge) 00859 // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass())) 00860 00861 // at first, we'll assume we have the continuations of our route in "conts" (built in "getBestLanes") 00862 // "conts" stores the best continuations of our current lane 00863 MSLinkCont::const_iterator link; 00864 if (nRouteSuccs>0&&conts.size()>=nRouteSuccs&&nRouteSuccs>0) { 00865 // we go through the links in our list and return the matching one 00866 for (link=succLinkSource.myLinks.begin(); link!=succLinkSource.myLinks.end() ; ++link) { 00867 if ((*link)->getLane()!=0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) { 00868 // we should use the link if it connects us to the best lane 00869 if ((*link)->getLane()==conts[nRouteSuccs-1]) { 00870 return link; 00871 } 00872 } 00873 } 00874 } 00875 00876 // ok, we were not able to use the conts for any reason 00877 // we will now collect allowed links, at first 00878 // collect allowed links 00879 std::vector<MSLinkCont::const_iterator> valid; 00880 for (link=succLinkSource.myLinks.begin(); link!=succLinkSource.myLinks.end() ; ++link) { 00881 if ((*link)->getLane()!=0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) { 00882 valid.push_back(link); 00883 } 00884 } 00885 // if no valid link was found... 00886 if (valid.size()==0) { 00887 // ... return end (no succeeding link) 00888 return succLinkSource.myLinks.end(); 00889 } 00890 // if there is only one valid link, let's use it... 00891 if (valid.size()==1) { 00892 return *(valid.begin()); 00893 } 00894 // if the next edge is the route end, then we may return an arbitary link 00895 // also, if there is no allowed lane on the edge following the current one (recheck?) 00896 const MSEdge* nRouteEdge2 = veh.succEdge(nRouteSuccs+1); 00897 const std::vector<MSLane*> *next_allowed = nRouteEdge->allowedLanes(*nRouteEdge2, veh.getVehicleType().getVehicleClass()); 00898 if (nRouteEdge2==0||next_allowed==0) { 00899 return *(valid.begin()); 00900 } 00901 // now let's determine which link is the best 00902 // in fact, we do not know it, here... 00903 for (std::vector<MSLinkCont::const_iterator>::iterator i=valid.begin(); i!=valid.end(); ++i) { 00904 if (find(next_allowed->begin(), next_allowed->end(), (**i)->getLane())!=next_allowed->end()) { 00905 return *i; 00906 } 00907 } 00908 return *(valid.begin()); 00909 } 00910 00911 00912 00913 const MSLinkCont& 00914 MSLane::getLinkCont() const { 00915 return myLinks; 00916 } 00917 00918 00919 void 00920 MSLane::swapAfterLaneChange(SUMOTime) { 00921 myVehicles = myTmpVehicles; 00922 myTmpVehicles.clear(); 00923 } 00924 00925 00926 00927 00928 GUILaneWrapper* 00929 MSLane::buildLaneWrapper(unsigned int) { 00930 throw "Only within the gui-version"; 00931 } 00932 00933 00934 MSVehicle* 00935 MSLane::removeVehicle(MSVehicle* remVehicle) { 00936 for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) { 00937 if (remVehicle->getID() == (*it)->getID()) { 00938 remVehicle->leaveLane(MSMoveReminder::NOTIFICATION_ARRIVED); 00939 myVehicles.erase(it); 00940 myVehicleLengthSum -= remVehicle->getVehicleType().getLengthWithGap(); 00941 break; 00942 } 00943 } 00944 return remVehicle; 00945 } 00946 00947 00948 MSLane* 00949 MSLane::getLeftLane() const { 00950 return myEdge->leftLane(this); 00951 } 00952 00953 00954 MSLane* 00955 MSLane::getRightLane() const { 00956 return myEdge->rightLane(this); 00957 } 00958 00959 00960 bool 00961 MSLane::allowsVehicleClass(SUMOVehicleClass vclass) const { 00962 if (vclass==SVC_UNKNOWN) { 00963 return true; 00964 } 00965 if (myAllowedClasses.size()==0&&myNotAllowedClasses.size()==0) { 00966 return true; 00967 } 00968 if (find(myAllowedClasses.begin(), myAllowedClasses.end(), vclass)!=myAllowedClasses.end()) { 00969 return true; 00970 } 00971 if (myAllowedClasses.size()!=0) { 00972 return false; 00973 } 00974 if (find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), vclass)!=myNotAllowedClasses.end()) { 00975 return false; 00976 } 00977 return true; 00978 } 00979 00980 00981 void 00982 MSLane::addIncomingLane(MSLane* lane, MSLink* viaLink) { 00983 IncomingLaneInfo ili; 00984 ili.lane = lane; 00985 ili.viaLink = viaLink; 00986 ili.length = lane->getLength(); 00987 myIncomingLanes.push_back(ili); 00988 } 00989 00990 00991 void 00992 MSLane::addApproachingLane(MSLane* lane) { 00993 MSEdge* approachingEdge = &lane->getEdge(); 00994 if (myApproachingLanes.find(approachingEdge)==myApproachingLanes.end()) { 00995 myApproachingLanes[approachingEdge] = std::vector<MSLane*>(); 00996 } 00997 myApproachingLanes[approachingEdge].push_back(lane); 00998 } 00999 01000 01001 bool 01002 MSLane::isApproachedFrom(MSEdge* const edge) { 01003 return myApproachingLanes.find(edge)!=myApproachingLanes.end(); 01004 } 01005 01006 01007 bool 01008 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) { 01009 std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i=myApproachingLanes.find(edge); 01010 if (i==myApproachingLanes.end()) { 01011 return false; 01012 } 01013 const std::vector<MSLane*> &lanes = (*i).second; 01014 return find(lanes.begin(), lanes.end(), lane)!=lanes.end(); 01015 } 01016 01017 01018 class by_second_sorter { 01019 public: 01020 inline int operator()(const std::pair<const MSVehicle* , SUMOReal> &p1, const std::pair<const MSVehicle* , SUMOReal> &p2) const { 01021 return p1.second<p2.second; 01022 } 01023 }; 01024 01025 std::pair<MSVehicle* const, SUMOReal> 01026 MSLane::getFollowerOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal leaderSpeed, 01027 SUMOReal backOffset, SUMOReal predMaxDecel) const { 01028 // ok, a vehicle has not noticed the lane about itself; 01029 // iterate as long as necessary to search for an approaching one 01030 std::set<MSLane*> visited; 01031 std::vector<std::pair<MSVehicle*, SUMOReal> > possible; 01032 std::vector<MSLane::IncomingLaneInfo> newFound; 01033 std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes; 01034 while (toExamine.size()!=0) { 01035 for (std::vector<MSLane::IncomingLaneInfo>::iterator i=toExamine.begin(); i!=toExamine.end(); ++i) { 01036 /* 01037 if ((*i).viaLink->getState()==LINKSTATE_TL_RED) { 01038 continue; 01039 } 01040 */ 01041 MSLane* next = (*i).lane; 01042 if (next->getFirstVehicle()!=0) { 01043 MSVehicle* v = (MSVehicle*) next->getFirstVehicle(); 01044 SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset; 01045 if (agap<=v->getCarFollowModel().getSecureGap(v->getCarFollowModel().maxNextSpeed(v->getSpeed()), leaderSpeed, predMaxDecel)) { 01046 possible.push_back(std::make_pair(v, (*i).length-v->getPositionOnLane()+seen)); 01047 } 01048 } else { 01049 if ((*i).length+seen<dist) { 01050 const std::vector<MSLane::IncomingLaneInfo> &followers = next->getIncomingLanes(); 01051 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j=followers.begin(); j!=followers.end(); ++j) { 01052 if (visited.find((*j).lane)==visited.end()) { 01053 visited.insert((*j).lane); 01054 MSLane::IncomingLaneInfo ili; 01055 ili.lane = (*j).lane; 01056 ili.length = (*j).length + (*i).length; 01057 ili.viaLink = (*j).viaLink; 01058 newFound.push_back(ili); 01059 } 01060 } 01061 } 01062 } 01063 } 01064 toExamine.clear(); 01065 swap(newFound, toExamine); 01066 } 01067 if (possible.size()==0) { 01068 return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1); 01069 } 01070 sort(possible.begin(), possible.end(), by_second_sorter()); 01071 return *(possible.begin()); 01072 } 01073 01074 01075 std::pair<MSVehicle* const, SUMOReal> 01076 MSLane::getLeaderOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle& veh, 01077 const std::vector<MSLane*> &bestLaneConts) const throw() { 01078 if (seen>dist) { 01079 return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1); 01080 } 01081 unsigned int view = 1; 01082 // loop over following lanes 01083 const MSLane* targetLane = this; 01084 MSVehicle* leader = targetLane->getPartialOccupator(); 01085 if (leader!=0) { 01086 return std::pair<MSVehicle * const, SUMOReal>(leader, seen-targetLane->getPartialOccupatorEnd()); 01087 } 01088 const MSLane* nextLane = targetLane; 01089 SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen/speed); 01090 while (true) { 01091 // get the next link used 01092 MSLinkCont::const_iterator link = targetLane->succLinkSec(veh, view, *nextLane, bestLaneConts); 01093 if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, veh.getVehicleType().getLengthWithGap()) || (*link)->getState()==LINKSTATE_TL_RED) { 01094 return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1); 01095 } 01096 #ifdef HAVE_INTERNAL_LANES 01097 bool nextInternal = false; 01098 nextLane = (*link)->getViaLane(); 01099 if (nextLane==0) { 01100 nextLane = (*link)->getLane(); 01101 } else { 01102 nextInternal = true; 01103 } 01104 #else 01105 nextLane = (*link)->getLane(); 01106 #endif 01107 if (nextLane==0) { 01108 return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1); 01109 } 01110 arrivalTime += TIME2STEPS(nextLane->getLength()/speed); 01111 MSVehicle* leader = nextLane->getLastVehicle(); 01112 if (leader!=0) { 01113 return std::pair<MSVehicle * const, SUMOReal>(leader, seen+leader->getPositionOnLane()-leader->getVehicleType().getLengthWithGap()); 01114 } else { 01115 leader = nextLane->getPartialOccupator(); 01116 if (leader!=0) { 01117 return std::pair<MSVehicle * const, SUMOReal>(leader, seen+nextLane->getPartialOccupatorEnd()); 01118 } 01119 } 01120 if (nextLane->getMaxSpeed()<speed) { 01121 dist = veh.getCarFollowModel().brakeGap(nextLane->getMaxSpeed()); 01122 } 01123 seen += nextLane->getLength(); 01124 if (seen>dist) { 01125 return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1); 01126 } 01127 #ifdef HAVE_INTERNAL_LANES 01128 if (!nextInternal) { 01129 view++; 01130 } 01131 #else 01132 view++; 01133 #endif 01134 } 01135 } 01136 01137 01138 MSLane* 01139 MSLane::getLogicalPredecessorLane() const throw() { 01140 if (myLogicalPredecessorLane!=0) { 01141 return myLogicalPredecessorLane; 01142 } 01143 if (myLogicalPredecessorLane==0) { 01144 std::vector<MSEdge*> pred = myEdge->getIncomingEdges(); 01145 // get only those edges which connect to this lane 01146 for (std::vector<MSEdge*>::iterator i=pred.begin(); i!=pred.end();) { 01147 std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i)); 01148 if (j==myIncomingLanes.end()) { 01149 i = pred.erase(i); 01150 } else { 01151 ++i; 01152 } 01153 } 01154 // get the edge with the most connections to this lane's edge 01155 if (pred.size()!=0) { 01156 std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge())); 01157 MSEdge* best = *pred.begin(); 01158 std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best)); 01159 myLogicalPredecessorLane = (*j).lane; 01160 } 01161 } 01162 return myLogicalPredecessorLane; 01163 } 01164 01165 01166 void 01167 MSLane::leftByLaneChange(MSVehicle* v) { 01168 myVehicleLengthSum -= v->getVehicleType().getLengthWithGap(); 01169 } 01170 01171 01172 void 01173 MSLane::enteredByLaneChange(MSVehicle* v) { 01174 myVehicleLengthSum += v->getVehicleType().getLengthWithGap(); 01175 } 01176 01177 01178 // ------------ Current state retrieval 01179 SUMOReal 01180 MSLane::getOccupancy() const throw() { 01181 return myVehicleLengthSum / myLength; 01182 } 01183 01184 01185 SUMOReal 01186 MSLane::getVehLenSum() const throw() { 01187 return myVehicleLengthSum; 01188 } 01189 01190 01191 SUMOReal 01192 MSLane::getMeanSpeed() const throw() { 01193 if (myVehicles.size()==0) { 01194 return myMaxSpeed; 01195 } 01196 SUMOReal v = 0; 01197 const MSLane::VehCont& vehs = getVehiclesSecure(); 01198 for (VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01199 v += (*i)->getSpeed(); 01200 } 01201 SUMOReal ret = v / (SUMOReal) myVehicles.size(); 01202 releaseVehicles(); 01203 return ret; 01204 } 01205 01206 01207 SUMOReal 01208 MSLane::getHBEFA_CO2Emissions() const throw() { 01209 SUMOReal ret = 0; 01210 const MSLane::VehCont& vehs = getVehiclesSecure(); 01211 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01212 ret += (*i)->getHBEFA_CO2Emissions(); 01213 } 01214 releaseVehicles(); 01215 return ret; 01216 } 01217 01218 01219 SUMOReal 01220 MSLane::getHBEFA_COEmissions() const throw() { 01221 SUMOReal ret = 0; 01222 const MSLane::VehCont& vehs = getVehiclesSecure(); 01223 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01224 ret += (*i)->getHBEFA_COEmissions(); 01225 } 01226 releaseVehicles(); 01227 return ret; 01228 } 01229 01230 01231 SUMOReal 01232 MSLane::getHBEFA_PMxEmissions() const throw() { 01233 SUMOReal ret = 0; 01234 const MSLane::VehCont& vehs = getVehiclesSecure(); 01235 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01236 ret += (*i)->getHBEFA_PMxEmissions(); 01237 } 01238 releaseVehicles(); 01239 return ret; 01240 } 01241 01242 01243 SUMOReal 01244 MSLane::getHBEFA_NOxEmissions() const throw() { 01245 SUMOReal ret = 0; 01246 const MSLane::VehCont& vehs = getVehiclesSecure(); 01247 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01248 ret += (*i)->getHBEFA_NOxEmissions(); 01249 } 01250 releaseVehicles(); 01251 return ret; 01252 } 01253 01254 01255 SUMOReal 01256 MSLane::getHBEFA_HCEmissions() const throw() { 01257 SUMOReal ret = 0; 01258 const MSLane::VehCont& vehs = getVehiclesSecure(); 01259 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01260 ret += (*i)->getHBEFA_HCEmissions(); 01261 } 01262 releaseVehicles(); 01263 return ret; 01264 } 01265 01266 01267 SUMOReal 01268 MSLane::getHBEFA_FuelConsumption() const throw() { 01269 SUMOReal ret = 0; 01270 const MSLane::VehCont& vehs = getVehiclesSecure(); 01271 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01272 ret += (*i)->getHBEFA_FuelConsumption(); 01273 } 01274 releaseVehicles(); 01275 return ret; 01276 } 01277 01278 01279 SUMOReal 01280 MSLane::getHarmonoise_NoiseEmissions() const throw() { 01281 SUMOReal ret = 0; 01282 const MSLane::VehCont& vehs = getVehiclesSecure(); 01283 if (vehs.size()==0) { 01284 releaseVehicles(); 01285 return 0; 01286 } 01287 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 01288 SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions(); 01289 ret += (SUMOReal) pow(10., (sv/10.)); 01290 } 01291 releaseVehicles(); 01292 return HelpersHarmonoise::sum(ret); 01293 } 01294 01295 01296 01297 /****************************************************************************/ 01298