SUMO - Simulation of Urban MObility
MSLaneChanger.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00011 // Performs lane changing of vehicles
00012 /****************************************************************************/
00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00015 /****************************************************************************/
00016 //
00017 //   This file is part of SUMO.
00018 //   SUMO is free software: you can redistribute it and/or modify
00019 //   it under the terms of the GNU General Public License as published by
00020 //   the Free Software Foundation, either version 3 of the License, or
00021 //   (at your option) any later version.
00022 //
00023 /****************************************************************************/
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include "MSLaneChanger.h"
00035 #include "MSVehicle.h"
00036 #include "MSVehicleType.h"
00037 #include "MSVehicleTransfer.h"
00038 #include "MSGlobals.h"
00039 #include <cassert>
00040 #include <iterator>
00041 #include <cstdlib>
00042 #include <cmath>
00043 #include <microsim/MSAbstractLaneChangeModel.h>
00044 #include <utils/common/MsgHandler.h>
00045 
00046 #ifdef CHECK_MEMORY_LEAKS
00047 #include <foreign/nvwa/debug_new.h>
00048 #endif // CHECK_MEMORY_LEAKS
00049 
00050 //#define DEBUG_VEHICLE_GUI_SELECTION 1
00051 #ifdef DEBUG_VEHICLE_GUI_SELECTION
00052 #include <utils/gui/div/GUIGlobalSelection.h>
00053 #include <guisim/GUIVehicle.h>
00054 #include <guisim/GUILane.h>
00055 #endif
00056 
00057 
00058 // ===========================================================================
00059 // member method definitions
00060 // ===========================================================================
00061 MSLaneChanger::MSLaneChanger(std::vector<MSLane*>* lanes, bool allowSwap)
00062     : myAllowsSwap(allowSwap) {
00063     assert(lanes->size() > 1);
00064 
00065     // Fill the changer with the lane-data.
00066     myChanger.reserve(lanes->size());
00067     for (std::vector<MSLane*>::iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
00068         ChangeElem ce;
00069         ce.follow    = 0;
00070         ce.lead      = 0;
00071         ce.lane      = *lane;
00072         ce.veh       = (*lane)->myVehicles.rbegin();
00073         ce.hoppedVeh = 0;
00074         ce.lastBlocked = 0;
00075         myChanger.push_back(ce);
00076     }
00077 }
00078 
00079 
00080 MSLaneChanger::~MSLaneChanger() {}
00081 
00082 
00083 void
00084 MSLaneChanger::laneChange(SUMOTime t) {
00085     // This is what happens in one timestep. After initialization of the
00086     // changer, each vehicle will try to change. After that the changer
00087     // nedds an update to prevent multiple changes of one vehicle.
00088     // Finally, the change-result has to be given back to the lanes.
00089     initChanger();
00090     while (vehInChanger()) {
00091 
00092         bool haveChanged = change();
00093         updateChanger(haveChanged);
00094     }
00095     updateLanes(t);
00096 }
00097 
00098 
00099 void
00100 MSLaneChanger::initChanger() {
00101     // Prepare myChanger with a safe state.
00102     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00103         ce->lead = 0;
00104         ce->hoppedVeh = 0;
00105         ce->lastBlocked = 0;
00106         ce->dens = 0;
00107 
00108         MSLane::VehCont& vehicles = ce->lane->myVehicles;
00109         if (vehicles.empty()) {
00110             ce->veh  = vehicles.rend();
00111             ce->follow = 0;
00112             continue;
00113         }
00114         ce->veh  = vehicles.rbegin();
00115         if (vehicles.size() == 1) {
00116             ce->follow = 0;
00117             continue;
00118         }
00119         ce->follow = *(vehicles.rbegin() + 1);
00120     }
00121 }
00122 
00123 
00124 bool
00125 MSLaneChanger::change() {
00126     // Find change-candidate. If it is on an allowed lane, try to change
00127     // to the right (there is a rule in Germany that you have to change
00128     // to the right, unless you are overtaking). If change to the right
00129     // isn't possible, check if there is a possibility to overtake (on the
00130     // left.
00131     // If candidate isn't on an allowed lane, changing to an allowed has
00132     // priority.
00133     myCandi = findCandidate();
00134     MSVehicle* vehicle = veh(myCandi);
00135 #ifdef DEBUG_VEHICLE_GUI_SELECTION
00136     if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(vehicle)->getGlID())) {
00137         int bla = 0;
00138     }
00139 #endif
00140     const std::vector<MSVehicle::LaneQ> &preb = vehicle->getBestLanes();
00141     assert(preb.size() == myChanger.size());
00142     for (int i = 0; i < (int) myChanger.size(); ++i) {
00143         ((std::vector<MSVehicle::LaneQ>&) preb)[i].occupation = myChanger[i].dens + preb[i].nextOccupation;
00144     }
00145 
00146     vehicle->getLaneChangeModel().prepareStep();
00147     std::pair<MSVehicle* const, SUMOReal> leader = getRealThisLeader(myCandi);
00148     // check whether the vehicle wants and is able to change to right lane
00149     int state1 = 0;
00150     if (myCandi != myChanger.begin() && (myCandi - 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
00151         std::pair<MSVehicle* const, SUMOReal> rLead = getRealLeader(myCandi - 1);
00152         std::pair<MSVehicle* const, SUMOReal> rFollow = getRealFollower(myCandi - 1);
00153         state1 = change2right(leader, rLead, rFollow, preb);
00154         if ((state1 & LCA_URGENT) != 0 || (state1 & LCA_SPEEDGAIN) != 0) {
00155             state1 |= LCA_RIGHT;
00156         }
00157         bool changingAllowed1 = (state1 & LCA_BLOCKED) == 0;
00158         // change if the vehicle wants to and is allowed to change
00159         if ((state1 & LCA_RIGHT) != 0 && changingAllowed1) {
00160 #ifndef NO_TRACI
00161             // inform lane change model about this change
00162             vehicle->getLaneChangeModel().fulfillChangeRequest(MSVehicle::REQUEST_RIGHT);
00163 #endif
00164             (myCandi - 1)->hoppedVeh = vehicle;
00165             (myCandi - 1)->lane->myTmpVehicles.push_front(vehicle);
00166             vehicle->leaveLane(MSMoveReminder::NOTIFICATION_LANE_CHANGE);
00167             myCandi->lane->leftByLaneChange(vehicle);
00168             vehicle->enterLaneAtLaneChange((myCandi - 1)->lane);
00169             (myCandi - 1)->lane->enteredByLaneChange(vehicle);
00170             vehicle->myLastLaneChangeOffset = 0;
00171             vehicle->getLaneChangeModel().changed();
00172             (myCandi - 1)->dens += (myCandi - 1)->hoppedVeh->getVehicleType().getLengthWithGap();
00173             return true;
00174         }
00175         if ((state1 & LCA_RIGHT) != 0 && (state1 & LCA_URGENT) != 0) {
00176             (myCandi - 1)->lastBlocked = vehicle;
00177         }
00178     }
00179 
00180 
00181 
00182     // check whether the vehicle wants and is able to change to left lane
00183     int state2 = 0;
00184     if ((myCandi + 1) != myChanger.end() && (myCandi + 1)->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) {
00185         std::pair<MSVehicle* const, SUMOReal> lLead = getRealLeader(myCandi + 1);
00186         std::pair<MSVehicle* const, SUMOReal> lFollow = getRealFollower(myCandi + 1);
00187         state2 = change2left(leader, lLead, lFollow, preb);
00188         if ((state2 & LCA_URGENT) != 0 || (state2 & LCA_SPEEDGAIN) != 0) {
00189             state2 |= LCA_LEFT;
00190         }
00191         bool changingAllowed2 = (state2 & LCA_BLOCKED) == 0;
00192         //vehicle->getLaneChangeModel().setOwnState(state2|state1);
00193         // change if the vehicle wants to and is allowed to change
00194         if ((state2 & LCA_LEFT) != 0 && changingAllowed2) {
00195 #ifndef NO_TRACI
00196             // inform lane change model about this change
00197             vehicle->getLaneChangeModel().fulfillChangeRequest(MSVehicle::REQUEST_LEFT);
00198 #endif
00199             (myCandi + 1)->hoppedVeh = veh(myCandi);
00200             (myCandi + 1)->lane->myTmpVehicles.push_front(veh(myCandi));
00201             vehicle->leaveLane(MSMoveReminder::NOTIFICATION_LANE_CHANGE);
00202             myCandi->lane->leftByLaneChange(vehicle);
00203             vehicle->enterLaneAtLaneChange((myCandi + 1)->lane);
00204             (myCandi + 1)->lane->enteredByLaneChange(vehicle);
00205             vehicle->myLastLaneChangeOffset = 0;
00206             vehicle->getLaneChangeModel().changed();
00207             (myCandi + 1)->dens += (myCandi + 1)->hoppedVeh->getVehicleType().getLengthWithGap();
00208             return true;
00209         }
00210         if ((state2 & LCA_LEFT) != 0 && (state2 & LCA_URGENT) != 0) {
00211             (myCandi + 1)->lastBlocked = vehicle;
00212         }
00213     }
00214     vehicle->getLaneChangeModel().setOwnState(state2 | state1);
00215 
00216     if ((state1 & (LCA_URGENT)) != 0 && (state2 & (LCA_URGENT)) != 0) {
00217         // ... wants to go to the left AND to the right
00218         // just let them go to the right lane...
00219         state2 = 0;
00220         vehicle->getLaneChangeModel().setOwnState(state1);
00221     }
00222     // check whether the vehicles should be swapped
00223     if (myAllowsSwap && ((state1 & (LCA_URGENT)) != 0 || (state2 & (LCA_URGENT)) != 0)) {
00224         // get the direction ...
00225         ChangerIt target;
00226         int dir;
00227         if ((state1 & (LCA_URGENT)) != 0) {
00228             // ... wants to go right
00229             target = myCandi - 1;
00230             dir = -1;
00231         }
00232         if ((state2 & (LCA_URGENT)) != 0) {
00233             // ... wants to go left
00234             target = myCandi + 1;
00235             dir = 1;
00236         }
00237         MSVehicle* prohibitor = target->lead;
00238         if (target->hoppedVeh != 0) {
00239             SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00240             if (prohibitor == 0 || (hoppedPos > vehicle->getPositionOnLane() && prohibitor->getPositionOnLane() > hoppedPos)) {
00241                 prohibitor = 0;// !!! vehicles should not jump over more than one lanetarget->hoppedVeh;
00242             }
00243         }
00244         if (prohibitor != 0
00245                 &&
00246                 ((prohibitor->getLaneChangeModel().getOwnState() & (LCA_URGENT/*|LCA_SPEEDGAIN*/)) != 0
00247                  &&
00248                  (prohibitor->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
00249                  !=
00250                  (vehicle->getLaneChangeModel().getOwnState() & (LCA_LEFT | LCA_RIGHT))
00251                 )
00252            ) {
00253 
00254             // check for position and speed
00255             if (prohibitor->getVehicleType().getLengthWithGap() - vehicle->getVehicleType().getLengthWithGap() == 0) {
00256                 // ok, may be swapped
00257                 // remove vehicle to swap with
00258                 MSLane::VehCont::iterator i = find(target->lane->myTmpVehicles.begin(), target->lane->myTmpVehicles.end(), prohibitor);
00259                 if (i != target->lane->myTmpVehicles.end()) {
00260                     MSVehicle* bla = *i;
00261                     assert(bla == prohibitor);
00262                     target->lane->myTmpVehicles.erase(i);
00263                     // set this vehicle
00264                     target->hoppedVeh = vehicle;
00265                     target->lane->myTmpVehicles.push_front(vehicle);
00266                     myCandi->hoppedVeh = prohibitor;
00267                     myCandi->lane->myTmpVehicles.push_front(prohibitor);
00268 
00269                     // leave lane and detectors
00270                     vehicle->leaveLane(MSMoveReminder::NOTIFICATION_LANE_CHANGE);
00271                     prohibitor->leaveLane(MSMoveReminder::NOTIFICATION_LANE_CHANGE);
00272                     // patch position and speed
00273                     SUMOReal p1 = vehicle->getPositionOnLane();
00274                     vehicle->myState.myPos = prohibitor->myState.myPos;
00275                     prohibitor->myState.myPos = p1;
00276                     p1 = vehicle->getSpeed();
00277                     vehicle->myState.mySpeed = prohibitor->myState.mySpeed;
00278                     prohibitor->myState.mySpeed = p1;
00279                     // enter lane and detectors
00280                     vehicle->enterLaneAtLaneChange(target->lane);
00281                     prohibitor->enterLaneAtLaneChange(myCandi->lane);
00282                     // mark lane change
00283                     vehicle->getLaneChangeModel().changed();
00284                     vehicle->myLastLaneChangeOffset = 0;
00285                     prohibitor->getLaneChangeModel().changed();
00286                     prohibitor->myLastLaneChangeOffset = 0;
00287                     (myCandi)->dens += prohibitor->getVehicleType().getLengthWithGap();
00288                     (target)->dens += vehicle->getVehicleType().getLengthWithGap();
00289                     return true;
00290                 }
00291             }
00292         }
00293     }
00294     // Candidate didn't change lane.
00295     myCandi->lane->myTmpVehicles.push_front(veh(myCandi));
00296     vehicle->myLastLaneChangeOffset += DELTA_T;
00297     (myCandi)->dens += vehicle->getVehicleType().getLengthWithGap();
00298     return false;
00299 }
00300 
00301 
00302 std::pair<MSVehicle* const, SUMOReal>
00303 MSLaneChanger::getRealThisLeader(const ChangerIt& target) const {
00304     // get the leading vehicle on the lane to change to
00305     MSVehicle* leader = target->lead;
00306     if (leader == 0) {
00307         MSLane* targetLane = target->lane;
00308         MSVehicle* predP = targetLane->getPartialOccupator();
00309         if (predP != 0) {
00310             return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane());
00311         }
00312         const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation();
00313         MSLinkCont::const_iterator link = targetLane->succLinkSec(*veh(myCandi), 1, *targetLane, bestLaneConts);
00314         if (targetLane->isLinkEnd(link)) {
00315             return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
00316         }
00317         MSLane* nextLane = (*link)->getLane();
00318         if (nextLane == 0) {
00319             return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
00320         }
00321         leader = nextLane->getLastVehicle();
00322         if (leader == 0) {
00323             return std::pair<MSVehicle*, SUMOReal>(static_cast<MSVehicle*>(0), -1);
00324         }
00325         SUMOReal gap =
00326             leader->getPositionOnLane() - leader->getVehicleType().getLength()
00327             +
00328             (myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap()); // !!! recheck
00329         return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
00330     } else {
00331         MSVehicle* candi = veh(myCandi);
00332         SUMOReal gap = leader->getPositionOnLane() - leader->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap();
00333         return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap));
00334     }
00335 }
00336 
00337 
00338 std::pair<MSVehicle* const, SUMOReal>
00339 MSLaneChanger::getRealLeader(const ChangerIt& target) const {
00340     // get the leading vehicle on the lane to change to
00341     MSVehicle* neighLead = target->lead;
00342     // check whether the hopped vehicle got the leader
00343     if (target->hoppedVeh != 0) {
00344         SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00345         if (hoppedPos > veh(myCandi)->getPositionOnLane() && (neighLead == 0 || neighLead->getPositionOnLane() > hoppedPos)) {
00346             neighLead = target->hoppedVeh;
00347         }
00348     }
00349     if (neighLead == 0) {
00350         MSLane* targetLane = target->lane;
00351         MSVehicle* predP = targetLane->getPartialOccupator();
00352         if (predP != 0) {
00353             return std::pair<MSVehicle*, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane() - veh(myCandi)->getVehicleType().getMinGap());
00354         }
00355         const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation(myCandi->lane);
00356         SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane();
00357         SUMOReal speed = veh(myCandi)->getSpeed();
00358         SUMOReal dist = veh(myCandi)->getCarFollowModel().brakeGap(speed);
00359         if (seen > dist) {
00360             return std::pair<MSVehicle * const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
00361         }
00362         return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts);
00363     } else {
00364         MSVehicle* candi = veh(myCandi);
00365         return std::pair<MSVehicle * const, SUMOReal>(neighLead, neighLead->getPositionOnLane() - neighLead->getVehicleType().getLength() - candi->getPositionOnLane() - candi->getVehicleType().getMinGap());
00366     }
00367 }
00368 
00369 
00370 std::pair<MSVehicle* const, SUMOReal>
00371 MSLaneChanger::getRealFollower(const ChangerIt& target) const {
00372     MSVehicle* neighFollow = veh(target);
00373     // check whether the hopped vehicle got the follower
00374     if (target->hoppedVeh != 0) {
00375         SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane();
00376         if (hoppedPos <= veh(myCandi)->getPositionOnLane() && (neighFollow == 0 || neighFollow->getPositionOnLane() > hoppedPos)) {
00377             neighFollow = target->hoppedVeh;
00378         }
00379     }
00380     if (neighFollow == 0) {
00381         SUMOReal speed = target->lane->getMaxSpeed();
00382         // in order to look back, we'd need the minimum braking ability of vehicles in the net...
00383         // we'll assume it to be 4m/s^2
00384         // !!!revisit
00385         SUMOReal dist = speed * speed / (2.*4.) + SPEED2DIST(speed);
00386         dist = MIN2(dist, (SUMOReal) 500.);
00387         MSVehicle* candi = veh(myCandi);
00388         SUMOReal seen = candi->getPositionOnLane() - candi->getVehicleType().getLength();
00389         return target->lane->getFollowerOnConsecutive(dist, seen, candi->getSpeed(), candi->getPositionOnLane() - candi->getVehicleType().getLength(), 4.5);
00390     } else {
00391         MSVehicle* candi = veh(myCandi);
00392         return std::pair<MSVehicle * const, SUMOReal>(neighFollow, candi->getPositionOnLane() - candi->getVehicleType().getLength() - neighFollow->getPositionOnLane() - neighFollow->getVehicleType().getMinGap());
00393     }
00394 }
00395 
00396 
00397 
00398 
00399 void
00400 MSLaneChanger::updateChanger(bool vehHasChanged) {
00401     assert(myCandi->veh != myCandi->lane->myVehicles.rend());
00402 
00403     // "Push" the vehicles to the back, i.e. follower becomes vehicle,
00404     // vehicle becomes leader, and leader becomes predecessor of vehicle,
00405     // if it exists.
00406     if (!vehHasChanged) {
00407         myCandi->lead = veh(myCandi);
00408     }
00409     myCandi->veh    = myCandi->veh + 1;
00410 
00411     if (veh(myCandi) == 0) {
00412         assert(myCandi->follow == 0);
00413         // leader already 0.
00414         return;
00415     }
00416     if (myCandi->veh + 1 == myCandi->lane->myVehicles.rend()) {
00417         myCandi->follow = 0;
00418     } else {
00419         myCandi->follow = *(myCandi->veh + 1) ;
00420     }
00421     return;
00422 }
00423 
00424 
00425 void
00426 MSLaneChanger::updateLanes(SUMOTime t) {
00427 
00428     // Update the lane's vehicle-container.
00429     // First: it is bad style to change other classes members, but for
00430     // this release, other attempts were too time-consuming. In a next
00431     // release we will change from this lane-centered design to a vehicle-
00432     // centered. This will solve many problems.
00433     // Second: this swap would be faster if vehicle-containers would have
00434     // been pointers, but then I had to change too much of the MSLane code.
00435     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00436 
00437         ce->lane->swapAfterLaneChange(t);
00438     }
00439 }
00440 
00441 
00442 MSLaneChanger::ChangerIt
00443 MSLaneChanger::findCandidate() {
00444     // Find the vehicle in myChanger with the smallest position. If there
00445     // is no vehicle in myChanger (shouldn't happen) , return
00446     // myChanger.end().
00447     ChangerIt max = myChanger.end();
00448     for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00449         if (veh(ce) == 0) {
00450             continue;
00451         }
00452         if (max == myChanger.end()) {
00453             max = ce;
00454             continue;
00455         }
00456         assert(veh(ce)  != 0);
00457         assert(veh(max) != 0);
00458         if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) {
00459             max = ce;
00460         }
00461     }
00462     assert(max != myChanger.end());
00463     assert(veh(max) != 0);
00464     return max;
00465 }
00466 
00467 
00468 int
00469 MSLaneChanger::change2right(const std::pair<MSVehicle* const, SUMOReal> &leader,
00470                             const std::pair<MSVehicle* const, SUMOReal> &rLead,
00471                             const std::pair<MSVehicle* const, SUMOReal> &rFollow,
00472                             const std::vector<MSVehicle::LaneQ> &preb) const {
00473     ChangerIt target = myCandi - 1;
00474     int blocked = overlapWithHopped(target)
00475                   ? target->hoppedVeh->getPositionOnLane() < veh(myCandi)->getPositionOnLane()
00476                   ? LCA_BLOCKED_BY_RIGHT_FOLLOWER
00477                   : LCA_BLOCKED_BY_RIGHT_LEADER
00478                   : 0;
00479     // overlap
00480     if (rFollow.first != 0 && rFollow.second < 0) {
00481         blocked |= (LCA_BLOCKED_BY_RIGHT_FOLLOWER);
00482     }
00483     if (rLead.first != 0 && rLead.second < 0) {
00484         blocked |= (LCA_BLOCKED_BY_RIGHT_LEADER);
00485     }
00486     // safe back gap
00487     if (rFollow.first != 0) {
00488         // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00489         if (rFollow.second < rFollow.first->getCarFollowModel().getSecureGap(rFollow.first->getSpeed(), veh(myCandi)->getSpeed(), veh(myCandi)->getCarFollowModel().getMaxDecel())) {
00490             blocked |= LCA_BLOCKED_BY_RIGHT_FOLLOWER;
00491         }
00492     }
00493 
00494     // safe front gap
00495     if (rLead.first != 0) {
00496         // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00497         if (rLead.second < veh(myCandi)->getCarFollowModel().getSecureGap(veh(myCandi)->getSpeed(), rLead.first->getSpeed(), rLead.first->getCarFollowModel().getMaxDecel())) {
00498             blocked |= LCA_BLOCKED_BY_RIGHT_LEADER;
00499         }
00500     }
00501 
00502     MSAbstractLaneChangeModel::MSLCMessager msg(leader.first, rLead.first, rFollow.first);
00503     return blocked | veh(myCandi)->getLaneChangeModel().wantsChangeToRight(
00504                msg, blocked, leader, rLead, rFollow, *(myCandi - 1)->lane, preb, &(myCandi->lastBlocked));
00505 }
00506 
00507 
00508 int
00509 MSLaneChanger::change2left(const std::pair<MSVehicle* const, SUMOReal> &leader,
00510                            const std::pair<MSVehicle* const, SUMOReal> &rLead,
00511                            const std::pair<MSVehicle* const, SUMOReal> &rFollow,
00512                            const std::vector<MSVehicle::LaneQ> &preb) const {
00513     ChangerIt target = myCandi + 1;
00514     int blocked = overlapWithHopped(target)
00515                   ? target->hoppedVeh->getPositionOnLane() < veh(myCandi)->getPositionOnLane()
00516                   ? LCA_BLOCKED_BY_LEFT_FOLLOWER
00517                   : LCA_BLOCKED_BY_LEFT_LEADER
00518                   : 0;
00519     // overlap
00520     if (rFollow.first != 0 && rFollow.second < 0) {
00521         blocked |= (LCA_BLOCKED_BY_LEFT_FOLLOWER);
00522     }
00523     if (rLead.first != 0 && rLead.second < 0) {
00524         blocked |= (LCA_BLOCKED_BY_LEFT_LEADER);
00525     }
00526     // safe back gap
00527     if (rFollow.first != 0) {
00528         // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00529         if (rFollow.second < rFollow.first->getCarFollowModel().getSecureGap(rFollow.first->getSpeed(), veh(myCandi)->getSpeed(), veh(myCandi)->getCarFollowModel().getMaxDecel())) {
00530             blocked |= LCA_BLOCKED_BY_LEFT_FOLLOWER;
00531         }
00532     }
00533     // safe front gap
00534     if (rLead.first != 0) {
00535         // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
00536         if (rLead.second < veh(myCandi)->getCarFollowModel().getSecureGap(veh(myCandi)->getSpeed(), rLead.first->getSpeed(), rLead.first->getCarFollowModel().getMaxDecel())) {
00537             blocked |= LCA_BLOCKED_BY_LEFT_LEADER;
00538         }
00539     }
00540     MSAbstractLaneChangeModel::MSLCMessager msg(leader.first, rLead.first, rFollow.first);
00541     return blocked | veh(myCandi)->getLaneChangeModel().wantsChangeToLeft(
00542                msg, blocked, leader, rLead, rFollow, *(myCandi + 1)->lane, preb, &(myCandi->lastBlocked));
00543 }
00544 
00545 
00546 
00547 
00548 /****************************************************************************/
00549 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines