SUMO - Simulation of Urban MObility

MSLane.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines