SUMO - Simulation of Urban MObility

MSLane.cpp

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