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

Generated on Wed May 5 00:06:31 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6