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