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