SUMO - Simulation of Urban MObility

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