MSLaneChanger.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Performs lane changing of vehicles
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 // included modules
00022 // ===========================================================================
00023 #ifdef _MSC_VER
00024 #include <windows_config.h>
00025 #else
00026 #include <config.h>
00027 #endif
00028 
00029 #include "MSLaneChanger.h"
00030 #include "MSVehicle.h"
00031 #include "MSVehicleType.h"
00032 #include "MSVehicleTransfer.h"
00033 #include "MSGlobals.h"
00034 #include <cassert>
00035 #include <iterator>
00036 #include <cstdlib>
00037 #include <cmath>
00038 #include <microsim/MSAbstractLaneChangeModel.h>
00039 #include <utils/common/MsgHandler.h>
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // ===========================================================================
00047 // member method definitions
00048 // ===========================================================================
00049 MSLaneChanger::MSLaneChanger(std::vector<MSLane*>* lanes) {
00050     assert(lanes->size() > 1);
00051 
00052     // Fill the changer with the lane-data.
00053     myChanger.reserve(lanes->size());
00054     for (std::vector<MSLane*>::iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
00055         ChangeElem ce;
00056         ce.follow    = 0;
00057         ce.lead      = 0;
00058         ce.lane      = *lane;
00059         ce.veh       = (*lane)->myVehicles.rbegin();
00060         ce.hoppedVeh = 0;
00061         ce.lastBlocked = 0;
00062         myChanger.push_back(ce);
00063     }
00064 }
00065 
00066 
00067 MSLaneChanger::~MSLaneChanger() {}
00068 
00069 
00070 void
00071 MSLaneChanger::laneChange(SUMOTime t) {
00072     // This is what happens in one timestep. After initialization of the
00073     // changer, each vehicle will try to change. After that the changer
00074     // nedds an update to prevent multiple changes of one vehicle.
00075     // Finally, the change-result has to be given back to the lanes.
00076     initChanger();
00077     while (vehInChanger()) {
00078 
00079         bool haveChanged = change();
00080         updateChanger(haveChanged);
00081     }
00082     updateLanes(t);
00083 }
00084 
00085 
00086 void
00087 MSLaneChanger::initChanger() {
00088     // Prepare myChanger with a safe state.
00089     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00090         ce->lead = 0;
00091         ce->hoppedVeh = 0;
00092         ce->lastBlocked = 0;
00093         ce->dens = 0;
00094 
00095         MSLane::VehCont& vehicles = ce->lane->myVehicles;
00096         if (vehicles.empty()) {
00097             ce->veh  = vehicles.rend();
00098             ce->follow = 0;
00099             continue;
00100         }
00101         ce->veh  = vehicles.rbegin();
00102         if (vehicles.size() == 1) {
00103             ce->follow = 0;
00104             continue;
00105         }
00106         ce->follow = *(vehicles.rbegin() + 1);
00107     }
00108 }
00109 
00110 
00111 bool
00112 MSLaneChanger::change() {
00113     // Find change-candidate. If it is on an allowed lane, try to change
00114     // to the right (there is a rule in Germany that you have to change
00115     // to the right, unless you are overtaking). If change to the right
00116     // isn't possible, check if there is a possibility to overtake (on the
00117     // left.
00118     // If candidate isn't on an allowed lane, changing to an allowed has
00119     // priority.
00120     myCandi = findCandidate();
00121     MSVehicle* vehicle = veh(myCandi);
00122     const std::vector<MSVehicle::LaneQ> &preb = vehicle->getBestLanes();
00123     assert(preb.size()==myChanger.size());
00124     for (int i=0; i<(int) myChanger.size(); ++i) {
00125         ((std::vector<MSVehicle::LaneQ>&) preb)[i].occupied = myChanger[i].dens + preb[i].v;
00126     }
00127 
00128     vehicle->getLaneChangeModel().prepareStep();
00129     // check whether the vehicle wants and is able to change to right lane
00130     std::pair<MSVehicle * const, SUMOReal> rLead = getRealRightLeader();
00131     std::pair<MSVehicle * const, SUMOReal> lLead = getRealLeftLeader();
00132     std::pair<MSVehicle * const, SUMOReal> rFollow = getRealRightFollower();
00133     std::pair<MSVehicle * const, SUMOReal> lFollow = getRealLeftFollower();
00134     std::pair<MSVehicle * const, SUMOReal> leader = getRealThisLeader(myCandi);
00135     int state1 = change2right(leader, rLead, rFollow, preb);
00136     bool changingAllowed =
00137         (state1&(LCA_BLOCKEDBY_LEADER|LCA_BLOCKEDBY_FOLLOWER))==0;
00138     if ((state1&LCA_URGENT)!=0||(state1&LCA_SPEEDGAIN)!=0) {
00139         state1 |= LCA_RIGHT;
00140     }
00141     // change if the vehicle wants to and is allowed to change
00142     if ((state1&LCA_RIGHT)!=0&&changingAllowed) {
00143 #ifndef NO_TRACI
00144         // inform lane change model about this change
00145         vehicle->getLaneChangeModel().fulfillChangeRequest(REQUEST_RIGHT);
00146         /*std::cout << "TraCI: lane changer fulfilled request for RIGHT |time " << MSNet::getInstance()->getCurrentTimeStep() << "s" << std::endl;*/
00147 #endif
00148         (myCandi - 1)->hoppedVeh = vehicle;
00149         (myCandi - 1)->lane->myTmpVehicles.push_front(vehicle);
00150         vehicle->leaveLane(false);
00151         myCandi->lane->leftByLaneChange(vehicle);
00152         vehicle->enterLaneAtLaneChange((myCandi - 1)->lane);
00153         (myCandi - 1)->lane->enteredByLaneChange(vehicle);
00154         vehicle->myLastLaneChangeOffset = 0;
00155         vehicle->getLaneChangeModel().changed();
00156         (myCandi - 1)->dens += (myCandi - 1)->hoppedVeh->getVehicleType().getLength();
00157         return true;
00158     }
00159     if ((state1&LCA_RIGHT)!=0&&(state1&LCA_URGENT)!=0) {
00160         (myCandi - 1)->lastBlocked = vehicle;
00161     }
00162 
00163     // check whether the vehicle wants and is able to change to left lane
00164     int state2 =
00165         change2left(leader, lLead, lFollow,preb);
00166     if ((state2&LCA_URGENT)!=0||(state2&LCA_SPEEDGAIN)!=0) {
00167         state2 |= LCA_LEFT;
00168     }
00169     changingAllowed =
00170         (state2&(LCA_BLOCKEDBY_LEADER|LCA_BLOCKEDBY_FOLLOWER))==0;
00171     vehicle->getLaneChangeModel().setState(state2|state1);
00172     // change if the vehicle wants to and is allowed to change
00173     if ((state2&LCA_LEFT)!=0&&changingAllowed) {
00174 #ifndef NO_TRACI
00175         // inform lane change model about this change
00176         vehicle->getLaneChangeModel().fulfillChangeRequest(REQUEST_LEFT);
00177         /*std::cout << "TraCI: lane changer fulfilled request for LEFT |time " << MSNet::getInstance()->getCurrentTimeStep() << "s" << std::endl;*/
00178 #endif
00179         (myCandi + 1)->hoppedVeh = veh(myCandi);
00180         (myCandi + 1)->lane->myTmpVehicles.push_front(veh(myCandi));
00181         vehicle->leaveLane(false);
00182         myCandi->lane->leftByLaneChange(vehicle);
00183         vehicle->enterLaneAtLaneChange((myCandi + 1)->lane);
00184         (myCandi + 1)->lane->enteredByLaneChange(vehicle);
00185         vehicle->myLastLaneChangeOffset = 0;
00186         vehicle->getLaneChangeModel().changed();
00187         (myCandi + 1)->dens += (myCandi + 1)->hoppedVeh->getVehicleType().getLength();
00188         return true;
00189     }
00190     if ((state2&LCA_LEFT)!=0&&(state2&LCA_URGENT)!=0) {
00191         (myCandi + 1)->lastBlocked = vehicle;
00192     }
00193 
00194     if ((state1&(LCA_URGENT))!=0&&(state2&(LCA_URGENT))!=0) {
00195         // ... wants to go to the left AND to the right
00196         // just let them go to the right lane...
00197         state2 = 0;
00198         vehicle->getLaneChangeModel().setState(state1);
00199     }
00200     // check whether the vehicles should be swapped
00201     if (false&&((state1&(LCA_URGENT))!=0||(state2&(LCA_URGENT))!=0)) {
00202         // get the direction ...
00203         ChangerIt target;
00204         int dir;
00205         if ((state1&(LCA_URGENT))!=0) {
00206             // ... wants to go right
00207             target = myCandi - 1;
00208             dir = -1;
00209         }
00210         if ((state2&(LCA_URGENT))!=0) {
00211             // ... wants to go left
00212             target = myCandi + 1;
00213             dir = 1;
00214         }
00215         MSVehicle *prohibitor = target->lead;
00216         if (target->hoppedVeh!=0) {
00217             SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00218             if (prohibitor==0||(
00219                         hoppedPos>vehicle->getPositionOnLane() && prohibitor->getPositionOnLane()>hoppedPos)) {
00220 
00221                 prohibitor = 0;// !!! vehicles should not jump over more than one lanetarget->hoppedVeh;
00222             }
00223         }
00224         if (prohibitor!=0
00225                 &&
00226                 ((prohibitor->getLaneChangeModel().getState()&(LCA_URGENT/*|LCA_SPEEDGAIN*/))!=0
00227                  &&
00228                  (prohibitor->getLaneChangeModel().getState()&(LCA_LEFT|LCA_RIGHT))
00229                  !=
00230                  (vehicle->getLaneChangeModel().getState()&(LCA_LEFT|LCA_RIGHT))
00231                 )
00232            ) {
00233 
00234             // check for position and speed
00235             if (prohibitor->getVehicleType().getLength()-vehicle->getVehicleType().getLength()==0) {
00236                 // ok, may be swapped
00237                 // remove vehicle to swap with
00238                 MSLane::VehCont::iterator i =
00239                     find(
00240                         target->lane->myTmpVehicles.begin(),
00241                         target->lane->myTmpVehicles.end(),
00242                         prohibitor);
00243                 if (i!=target->lane->myTmpVehicles.end()) {
00244                     MSVehicle *bla = *i;
00245                     assert(bla==prohibitor);
00246                     target->lane->myTmpVehicles.erase(i);
00247                     // set this vehicle
00248                     target->hoppedVeh = vehicle;
00249                     target->lane->myTmpVehicles.push_front(vehicle);
00250                     myCandi->hoppedVeh = prohibitor;
00251                     myCandi->lane->myTmpVehicles.push_front(prohibitor);
00252 
00253                     // leave lane and detectors
00254                     vehicle->leaveLane(false);
00255                     prohibitor->leaveLane(false);
00256                     // patch position and speed
00257                     SUMOReal p1 = vehicle->getPositionOnLane();
00258                     vehicle->myState.myPos = prohibitor->myState.myPos;
00259                     prohibitor->myState.myPos = p1;
00260                     p1 = vehicle->getSpeed();
00261                     vehicle->myState.mySpeed = prohibitor->myState.mySpeed;
00262                     prohibitor->myState.mySpeed = p1;
00263                     // enter lane and detectors
00264                     vehicle->enterLaneAtLaneChange(target->lane);
00265                     prohibitor->enterLaneAtLaneChange(myCandi->lane);
00266                     // mark lane change
00267                     vehicle->getLaneChangeModel().changed();
00268                     vehicle->myLastLaneChangeOffset = 0;
00269                     prohibitor->getLaneChangeModel().changed();
00270                     prohibitor->myLastLaneChangeOffset = 0;
00271                     (myCandi)->dens += prohibitor->getVehicleType().getLength();
00272                     (target)->dens += vehicle->getVehicleType().getLength();
00273                     return true;
00274                 }
00275             }
00276         }
00277     }
00278     // Candidate didn't change lane.
00279     myCandi->lane->myTmpVehicles.push_front(veh(myCandi));
00280     vehicle->myLastLaneChangeOffset += DELTA_T;
00281     (myCandi)->dens += vehicle->getVehicleType().getLength();
00282     return false;
00283 }
00284 
00285 
00286 std::pair<MSVehicle * const, SUMOReal>
00287 MSLaneChanger::getRealThisLeader(const ChangerIt &target) const throw() {
00288     // get the leading vehicle on the lane to change to
00289     MSVehicle* leader = target->lead;
00290     if (leader==0) {
00291         MSLane* targetLane = target->lane;
00292         MSVehicle *predP = targetLane->getPartialOccupator();
00293         if (predP!=0) {
00294             return std::pair<MSVehicle *, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane());
00295         }
00296         const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation();
00297         MSLinkCont::const_iterator link = targetLane->succLinkSec(*veh(myCandi), 1, *targetLane, bestLaneConts);
00298         if (targetLane->isLinkEnd(link)) {
00299             return std::pair<MSVehicle *, SUMOReal>(0, -1);
00300         }
00301         MSLane *nextLane = (*link)->getLane();
00302         if (nextLane==0) {
00303             return std::pair<MSVehicle *, SUMOReal>(0, -1);
00304         }
00305         leader = nextLane->getLastVehicle();
00306         if (leader==0) {
00307             return std::pair<MSVehicle *, SUMOReal>(0, -1);
00308         }
00309         SUMOReal gap =
00310             leader->getPositionOnLane()-leader->getVehicleType().getLength()
00311             +
00312             (myCandi->lane->getLength()-veh(myCandi)->getPositionOnLane());
00313         return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
00314     } else {
00315         MSVehicle *candi = veh(myCandi);
00316         SUMOReal gap = leader->getPositionOnLane()-leader->getVehicleType().getLength()-candi->getPositionOnLane();
00317         return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
00318     }
00319 }
00320 
00321 
00322 std::pair<MSVehicle * const, SUMOReal>
00323 MSLaneChanger::getRealLeader(const ChangerIt &target) const throw() {
00324     // get the leading vehicle on the lane to change to
00325     MSVehicle* neighLead = target->lead;
00326     // check whether the hopped vehicle got the leader
00327     if (target->hoppedVeh!=0) {
00328         SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00329         if (hoppedPos>veh(myCandi)->getPositionOnLane() &&
00330                 (neighLead==0 || neighLead->getPositionOnLane()>hoppedPos)) {
00331 
00332             neighLead = target->hoppedVeh;
00333         }
00334     }
00335     if (neighLead==0) {
00336         MSLane* targetLane = target->lane;
00337         MSVehicle *predP = targetLane->getPartialOccupator();
00338         if (predP!=0) {
00339             return std::pair<MSVehicle *, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane());
00340         }
00341         const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation(myCandi->lane);
00342         SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane();
00343         SUMOReal speed = veh(myCandi)->getSpeed();
00344         SUMOReal dist = veh(myCandi)->getCarFollowModel().brakeGap(speed);
00345         if (seen>dist) {
00346             return std::pair<MSVehicle * const, SUMOReal>(0, -1);
00347         }
00348         return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts);
00349     } else {
00350         MSVehicle *candi = veh(myCandi);
00351         return std::pair<MSVehicle * const, SUMOReal>(neighLead,
00352                 neighLead->getPositionOnLane()-neighLead->getVehicleType().getLength()-candi->getPositionOnLane());
00353     }
00354 }
00355 
00356 
00357 std::pair<MSVehicle * const, SUMOReal>
00358 MSLaneChanger::getRealRightLeader() const throw() {
00359     // there is no right lane
00360     if (myCandi == myChanger.begin()) {
00361         return std::pair<MSVehicle *, SUMOReal>(0, -1);
00362     }
00363     ChangerIt target = myCandi - 1;
00364     return getRealLeader(target);
00365 }
00366 
00367 
00368 std::pair<MSVehicle * const, SUMOReal>
00369 MSLaneChanger::getRealLeftLeader() const throw() {
00370     // there is no left lane
00371     if ((myCandi+1) == myChanger.end()) {
00372         return std::pair<MSVehicle *, SUMOReal>(0, -1);
00373     }
00374     ChangerIt target = myCandi + 1;
00375     return getRealLeader(target);
00376 }
00377 
00378 
00379 std::pair<MSVehicle * const, SUMOReal>
00380 MSLaneChanger::getRealFollower(const ChangerIt &target) const throw() {
00381     MSVehicle* neighFollow = veh(target);
00382     // check whether the hopped vehicle got the follower
00383     if (target->hoppedVeh!=0) {
00384         SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00385         if (hoppedPos<=veh(myCandi)->getPositionOnLane() &&
00386                 (neighFollow==0 || neighFollow->getPositionOnLane()>hoppedPos)) {
00387 
00388             neighFollow = target->hoppedVeh;
00389         }
00390     }
00391     if (neighFollow==0) {
00392         SUMOReal speed = target->lane->getMaxSpeed();
00393         // in order to look back, we'd need the minimum braking ability of vehicles in the net...
00394         // we'll assume it to be 4m/s^2
00395         // !!!revisit
00396         SUMOReal dist = speed * speed * SUMOReal(1./2.*4.) + SPEED2DIST(speed);
00397         dist = MIN2(dist, (SUMOReal) 500.);
00398         MSVehicle *candi = veh(myCandi);
00399         SUMOReal seen = candi->getPositionOnLane()-candi->getVehicleType().getLength();
00400         return target->lane->getFollowerOnConsecutive(dist, seen, candi->getSpeed(), candi->getPositionOnLane() - candi->getVehicleType().getLength());
00401     } else {
00402         MSVehicle *candi = veh(myCandi);
00403         return std::pair<MSVehicle * const, SUMOReal>(neighFollow,
00404                 candi->getPositionOnLane()-candi->getVehicleType().getLength()-neighFollow->getPositionOnLane());
00405     }
00406 }
00407 
00408 
00409 std::pair<MSVehicle * const, SUMOReal>
00410 MSLaneChanger::getRealRightFollower() const throw() {
00411     // there is no right lane
00412     if (myCandi == myChanger.begin()) {
00413         return std::pair<MSVehicle *, SUMOReal>(0, -1);
00414     }
00415     ChangerIt target = myCandi - 1;
00416     return getRealFollower(target);
00417 }
00418 
00419 
00420 std::pair<MSVehicle * const, SUMOReal>
00421 MSLaneChanger::getRealLeftFollower() const throw() {
00422     // there is no left lane
00423     if ((myCandi+1) == myChanger.end()) {
00424         return std::pair<MSVehicle *, SUMOReal>(0, -1);
00425     }
00426     ChangerIt target = myCandi + 1;
00427     return getRealFollower(target);
00428 }
00429 
00430 
00431 
00432 void
00433 MSLaneChanger::updateChanger(bool vehHasChanged) {
00434     assert(myCandi->veh != myCandi->lane->myVehicles.rend());
00435 
00436     // "Push" the vehicles to the back, i.e. follower becomes vehicle,
00437     // vehicle becomes leader, and leader becomes predecessor of vehicle,
00438     // if it exists.
00439     if (!vehHasChanged) {
00440         myCandi->lead = veh(myCandi);
00441     }
00442     myCandi->veh    = myCandi->veh + 1;
00443 
00444     if (veh(myCandi) == 0) {
00445         assert(myCandi->follow == 0);
00446         // leader already 0.
00447         return;
00448     }
00449     if (myCandi->veh + 1 == myCandi->lane->myVehicles.rend()) {
00450         myCandi->follow = 0;
00451     } else {
00452         myCandi->follow = *(myCandi->veh + 1) ;
00453     }
00454     return;
00455 }
00456 
00457 
00458 void
00459 MSLaneChanger::updateLanes(SUMOTime t) {
00460 
00461     // Update the lane's vehicle-container.
00462     // First: it is bad style to change other classes members, but for
00463     // this release, other attempts were too time-consuming. In a next
00464     // release we will change from this lane-centered design to a vehicle-
00465     // centered. This will solve many problems.
00466     // Second: this swap would be faster if vehicle-containers would have
00467     // been pointers, but then I had to change too much of the MSLane code.
00468     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00469 
00470         ce->lane->swapAfterLaneChange(t);
00471     }
00472 }
00473 
00474 
00475 MSLaneChanger::ChangerIt
00476 MSLaneChanger::findCandidate() {
00477     // Find the vehicle in myChanger with the smallest position. If there
00478     // is no vehicle in myChanger (shouldn't happen) , return
00479     // myChanger.end().
00480     ChangerIt max = myChanger.end();
00481     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00482         if (veh(ce) == 0) {
00483             continue;
00484         }
00485         if (max == myChanger.end()) {
00486             max = ce;
00487             continue;
00488         }
00489         assert(veh(ce)  != 0);
00490         assert(veh(max) != 0);
00491         if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) {
00492             max = ce;
00493         }
00494     }
00495     assert(max != myChanger.end());
00496     assert(veh(max) != 0);
00497     return max;
00498 }
00499 
00500 
00501 int
00502 MSLaneChanger::change2right(const std::pair<MSVehicle * const, SUMOReal> &leader,
00503                             const std::pair<MSVehicle * const, SUMOReal> &rLead,
00504                             const std::pair<MSVehicle * const, SUMOReal> &rFollow,
00505                             const std::vector<MSVehicle::LaneQ> &preb) const throw() {
00506     // Try to change to the right-lane if there is one. If this lane isn't
00507     // an allowed one, cancel the try. Otherwise, check some conditions. If
00508     // they are simultaniously fulfilled, a change is possible.
00509 
00510     // no right lane -> exit
00511     if (myCandi == myChanger.begin()) {
00512         return 0;
00513     }
00514 
00515     ChangerIt target = myCandi - 1;
00516     if (!target->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
00517         return 0;
00518     }
00519     int blocked = overlapWithHopped(target)
00520                   ? target->hoppedVeh->getPositionOnLane()<veh(myCandi)->getPositionOnLane()
00521                   ? LCA_BLOCKEDBY_FOLLOWER
00522                   : LCA_BLOCKEDBY_LEADER
00523                   : 0;
00524     setOverlap(rLead, rFollow, blocked);
00525     setIsSafeChange(rLead, rFollow, target, blocked);
00526     return blocked
00527            |
00528            advan2right(leader, rLead, rFollow,
00529                        blocked, preb);
00530 }
00531 
00532 
00533 int
00534 MSLaneChanger::change2left(const std::pair<MSVehicle * const, SUMOReal> &leader,
00535                            const std::pair<MSVehicle * const, SUMOReal> &rLead,
00536                            const std::pair<MSVehicle * const, SUMOReal> &rFollow,
00537                            const std::vector<MSVehicle::LaneQ> &preb) const throw() {
00538     // Try to change to the left-lane, if there is one. If this lane isn't
00539     // an allowed one, cancel the try. Otherwise, check some conditions.
00540     // If they are simultaniously fulfilled, a change is possible.
00541 
00542     // no left lane, overlapping or left lane not allowed -> exit
00543     ChangerIt target = myCandi + 1;
00544     if (target == myChanger.end()) {
00545         return 0;
00546     }
00547     if (!target->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
00548         return 0;
00549     }
00550     int blocked = overlapWithHopped(target)
00551                   ? target->hoppedVeh->getPositionOnLane()<veh(myCandi)->getPositionOnLane()
00552                   ? LCA_BLOCKEDBY_FOLLOWER
00553                   : LCA_BLOCKEDBY_LEADER
00554                   : 0;
00555     setOverlap(rLead, rFollow, blocked);
00556     setIsSafeChange(rLead, rFollow, target, blocked);
00557     return blocked
00558            |
00559            advan2left(leader, rLead, rFollow,
00560                       blocked, preb);
00561 }
00562 
00563 
00564 void
00565 MSLaneChanger::setOverlap(const std::pair<MSVehicle * const, SUMOReal> &rLead,
00566                           const std::pair<MSVehicle * const, SUMOReal> &rFollow,
00567                           int &blocked) const throw() {
00568     // check the follower only if not already known that...
00569     if ((blocked&LCA_BLOCKEDBY_FOLLOWER)==0) {
00570         if (rFollow.first!=0&&rFollow.second<0) {
00571             blocked |= (LCA_BLOCKEDBY_FOLLOWER|LCA_OVERLAPPING);
00572         }
00573     }
00574     // check the leader only if not already known that...
00575     if ((blocked&LCA_BLOCKEDBY_LEADER)==0) {
00576         if (rLead.first!=0&&rLead.second<0) {
00577             blocked |= (LCA_BLOCKEDBY_LEADER|LCA_OVERLAPPING);
00578         }
00579     }
00580 }
00581 
00582 
00583 void
00584 MSLaneChanger::setIsSafeChange(const std::pair<MSVehicle * const, SUMOReal> &neighLead,
00585                                const std::pair<MSVehicle * const, SUMOReal> &neighFollow,
00586                                const ChangerIt &target, int &blocked) const throw() {
00587     // Check if candidate's change to target-lane will be safe, i.e. is there
00588     // enough back-gap to the neighFollow to drive collision-free (if there is
00589     // no neighFollow, keep a safe-gap to the beginning of the lane) and is
00590     // there enough gap for the candidate to neighLead to drive collision-
00591     // free (if there is no neighLead, be sure that candidate is able to slow-
00592     // down towards the lane end).
00593     MSVehicle* vehicle     = veh(myCandi);
00594 
00595     // check back gap
00596     if ((blocked&LCA_BLOCKEDBY_FOLLOWER)==0) {
00597         if (neighFollow.first!=0) {
00598             MSLane* targetLane = target->lane;
00599             // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00600             if (!neighFollow.first->getCarFollowModel().hasSafeGap(neighFollow.first->getSpeed(), neighFollow.second, vehicle->getSpeed(), targetLane->getMaxSpeed())) {
00601                 blocked |= LCA_BLOCKEDBY_FOLLOWER;
00602             }
00603         }
00604     }
00605 
00606     // check front gap
00607     if ((blocked&LCA_BLOCKEDBY_LEADER)==0) {
00608         if (neighLead.first!=0) {
00609             MSLane* targetLane = target->lane;
00610             // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00611             if (!vehicle->getCarFollowModel().hasSafeGap(vehicle->getSpeed(), neighLead.second, neighLead.first->getSpeed(), targetLane->getMaxSpeed())) {
00612                 blocked |= LCA_BLOCKEDBY_LEADER;
00613             }
00614         }
00615     }
00616 }
00617 
00618 
00619 int
00620 MSLaneChanger::advan2right(const std::pair<MSVehicle * const, SUMOReal> &leader,
00621                            const std::pair<MSVehicle * const, SUMOReal> &neighLead,
00622                            const std::pair<MSVehicle * const, SUMOReal> &neighFollow,
00623                            int blocked,
00624                            const std::vector<MSVehicle::LaneQ> &preb) const throw() {
00625     MSAbstractLaneChangeModel::MSLCMessager
00626     msg(leader.first, neighLead.first, neighFollow.first);
00627     return veh(myCandi)->getLaneChangeModel().wantsChangeToRight(
00628                msg, blocked,
00629                leader, neighLead, neighFollow, *(myCandi-1)->lane,
00630                preb,
00631                &(myCandi->lastBlocked));
00632 }
00633 
00634 
00635 int
00636 MSLaneChanger::advan2left(const std::pair<MSVehicle * const, SUMOReal> &leader,
00637                           const std::pair<MSVehicle * const, SUMOReal> &neighLead,
00638                           const std::pair<MSVehicle * const, SUMOReal> &neighFollow,
00639                           int blocked,
00640                           const std::vector<MSVehicle::LaneQ> &preb) const throw() {
00641     MSAbstractLaneChangeModel::MSLCMessager
00642     msg(leader.first, neighLead.first, neighFollow.first);
00643     return veh(myCandi)->getLaneChangeModel().wantsChangeToLeft(
00644                msg, blocked,
00645                leader, neighLead, neighFollow, *(myCandi+1)->lane,
00646                preb,
00647                &(myCandi->lastBlocked));
00648 }
00649 
00650 
00651 /****************************************************************************/
00652 

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