MSLaneChanger Class Reference

#include <MSLaneChanger.h>


Detailed Description

Performs lane changing of vehicles.

Definition at line 51 of file MSLaneChanger.h.


Public Types

typedef std::vector< ChangeElemChanger
 The list of changers; For each lane, a ChangeElem is being build.
typedef Changer::iterator ChangerIt
 the iterator moving over the ChangeElems
typedef Changer::const_iterator ConstChangerIt
 the iterator moving over the ChangeElems

Public Member Functions

void laneChange (SUMOTime t)
 Start lane-change-process for all vehicles on the edge'e lanes.
 MSLaneChanger (std::vector< MSLane * > *lanes)
 Constructor.
 ~MSLaneChanger ()
 Destructor.

Protected Member Functions

int advan2left (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, int blocked, const std::vector< MSVehicle::LaneQ > &preb) const throw ()
int advan2right (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, int blocked, const std::vector< MSVehicle::LaneQ > &preb) const throw ()
bool change ()
int change2left (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, const std::vector< MSVehicle::LaneQ > &preb) const throw ()
int change2right (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, const std::vector< MSVehicle::LaneQ > &preb) const throw ()
ChangerIt findCandidate ()
 Find current candidate. If there is none, myChanger.end() is returned.
std::pair< MSVehicle *const,
SUMOReal > 
getRealFollower (const ChangerIt &target) const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealLeader (const ChangerIt &target) const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealLeftFollower () const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealLeftLeader () const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealRightFollower () const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealRightLeader () const throw ()
std::pair< MSVehicle *const,
SUMOReal > 
getRealThisLeader (const ChangerIt &target) const throw ()
void initChanger ()
 Initialize the changer before looping over all vehicles.
bool overlapWithHopped (ChangerIt target) const throw ()
void setIsSafeChange (const std::pair< MSVehicle *const, SUMOReal > &neighLead, const std::pair< MSVehicle *const, SUMOReal > &neighFollow, const ChangerIt &target, int &blocked) const throw ()
void setOverlap (const std::pair< MSVehicle *const, SUMOReal > &neighLead, const std::pair< MSVehicle *const, SUMOReal > &neighFollow, int &blocked) const throw ()
void updateChanger (bool vehHasChanged)
void updateLanes (SUMOTime t)
MSVehicleveh (ConstChangerIt ce) const throw ()
bool vehInChanger () const throw ()
 Check if there is a single change-candidate in the changer. Returns true if there is one.

Protected Attributes

ChangerIt myCandi
Changer myChanger
 Container for ChangeElemements, one for every lane in the edge.

Private Member Functions

 MSLaneChanger (const MSLaneChanger &)
 Copy constructor.
 MSLaneChanger ()
 Default constructor.
MSLaneChangeroperator= (const MSLaneChanger &)
 Assignment operator.

Data Structures

struct  ChangeElem

Member Typedef Documentation

typedef std::vector< ChangeElem > MSLaneChanger::Changer

The list of changers; For each lane, a ChangeElem is being build.

Definition at line 88 of file MSLaneChanger.h.

typedef Changer::iterator MSLaneChanger::ChangerIt

the iterator moving over the ChangeElems

Definition at line 91 of file MSLaneChanger.h.

typedef Changer::const_iterator MSLaneChanger::ConstChangerIt

the iterator moving over the ChangeElems

Definition at line 94 of file MSLaneChanger.h.


Constructor & Destructor Documentation

MSLaneChanger::MSLaneChanger ( std::vector< MSLane * > *  lanes  ) 

Constructor.

Definition at line 49 of file MSLaneChanger.cpp.

References MSLaneChanger::ChangeElem::follow, MSLaneChanger::ChangeElem::hoppedVeh, MSLaneChanger::ChangeElem::lane, MSLaneChanger::ChangeElem::lastBlocked, MSLaneChanger::ChangeElem::lead, myChanger, and MSLaneChanger::ChangeElem::veh.

00049                                                       {
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 }

MSLaneChanger::~MSLaneChanger (  ) 

Destructor.

Definition at line 67 of file MSLaneChanger.cpp.

00067 {}

MSLaneChanger::MSLaneChanger (  )  [private]

Default constructor.

MSLaneChanger::MSLaneChanger ( const MSLaneChanger  )  [private]

Copy constructor.


Member Function Documentation

int MSLaneChanger::advan2left ( const std::pair< MSVehicle *const, SUMOReal > &  leader,
const std::pair< MSVehicle *const, SUMOReal > &  rLead,
const std::pair< MSVehicle *const, SUMOReal > &  rFollow,
int  blocked,
const std::vector< MSVehicle::LaneQ > &  preb 
) const throw () [protected]

Returns true, if candidate has an advantage by changing to the left.

Definition at line 636 of file MSLaneChanger.cpp.

References MSVehicle::getLaneChangeModel(), myCandi, veh(), and MSAbstractLaneChangeModel::wantsChangeToLeft().

Referenced by change2left().

00640                                                                                {
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 }

int MSLaneChanger::advan2right ( const std::pair< MSVehicle *const, SUMOReal > &  leader,
const std::pair< MSVehicle *const, SUMOReal > &  rLead,
const std::pair< MSVehicle *const, SUMOReal > &  rFollow,
int  blocked,
const std::vector< MSVehicle::LaneQ > &  preb 
) const throw () [protected]

Returns true, if candidate has an advantage by changing to the right.

Definition at line 620 of file MSLaneChanger.cpp.

References MSVehicle::getLaneChangeModel(), myCandi, veh(), and MSAbstractLaneChangeModel::wantsChangeToRight().

Referenced by change2right().

00624                                                                                 {
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 }

bool MSLaneChanger::change (  )  [protected]

Find a new candidate and try to change it.

Definition at line 112 of file MSLaneChanger.cpp.

References bla, change2left(), change2right(), MSAbstractLaneChangeModel::changed(), DELTA_T, MSVehicle::enterLaneAtLaneChange(), findCandidate(), MSAbstractLaneChangeModel::fulfillChangeRequest(), MSVehicle::getBestLanes(), MSVehicle::getLaneChangeModel(), MSVehicleType::getLength(), MSVehicle::getPositionOnLane(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), getRealThisLeader(), MSVehicle::getSpeed(), MSAbstractLaneChangeModel::getState(), MSVehicle::getVehicleType(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, LCA_LEFT, LCA_RIGHT, LCA_SPEEDGAIN, LCA_URGENT, MSVehicle::leaveLane(), myCandi, myChanger, MSVehicle::myLastLaneChangeOffset, MSVehicle::myState, MSAbstractLaneChangeModel::prepareStep(), REQUEST_LEFT, REQUEST_RIGHT, MSAbstractLaneChangeModel::setState(), SUMOReal, and veh().

Referenced by laneChange().

00112                       {
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 }

int MSLaneChanger::change2left ( const std::pair< MSVehicle *const, SUMOReal > &  leader,
const std::pair< MSVehicle *const, SUMOReal > &  rLead,
const std::pair< MSVehicle *const, SUMOReal > &  rFollow,
const std::vector< MSVehicle::LaneQ > &  preb 
) const throw () [protected]

Definition at line 534 of file MSLaneChanger.cpp.

References advan2left(), MSVehicle::getPositionOnLane(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, myChanger, overlapWithHopped(), setIsSafeChange(), setOverlap(), and veh().

Referenced by change().

00537                                                                                 {
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 }

int MSLaneChanger::change2right ( const std::pair< MSVehicle *const, SUMOReal > &  leader,
const std::pair< MSVehicle *const, SUMOReal > &  rLead,
const std::pair< MSVehicle *const, SUMOReal > &  rFollow,
const std::vector< MSVehicle::LaneQ > &  preb 
) const throw () [protected]

Definition at line 502 of file MSLaneChanger.cpp.

References advan2right(), MSVehicle::getPositionOnLane(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, myChanger, overlapWithHopped(), setIsSafeChange(), setOverlap(), and veh().

Referenced by change().

00505                                                                                  {
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 }

MSLaneChanger::ChangerIt MSLaneChanger::findCandidate (  )  [protected]

Find current candidate. If there is none, myChanger.end() is returned.

Definition at line 476 of file MSLaneChanger.cpp.

References max, myChanger, and veh().

Referenced by change().

00476                              {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealFollower ( const ChangerIt target  )  const throw () [protected]

Definition at line 380 of file MSLaneChanger.cpp.

References MSVehicleType::getLength(), MSVehicle::getPositionOnLane(), MSVehicle::getSpeed(), MSVehicle::getVehicleType(), MIN2(), myCandi, SPEED2DIST, SUMOReal, and veh().

Referenced by getRealLeftFollower(), and getRealRightFollower().

00380                                                                     {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeader ( const ChangerIt target  )  const throw () [protected]

Definition at line 323 of file MSLaneChanger.cpp.

References MSCFModel::brakeGap(), MSVehicle::getBestLanesContinuation(), MSVehicle::getCarFollowModel(), MSLane::getPartialOccupator(), MSLane::getPartialOccupatorEnd(), MSVehicle::getPositionOnLane(), MSVehicle::getSpeed(), myCandi, SUMOReal, and veh().

Referenced by getRealLeftLeader(), and getRealRightLeader().

00323                                                                   {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeftFollower (  )  const throw () [protected]

Definition at line 421 of file MSLaneChanger.cpp.

References getRealFollower(), myCandi, and myChanger.

Referenced by change().

00421                                                  {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeftLeader (  )  const throw () [protected]

Definition at line 369 of file MSLaneChanger.cpp.

References getRealLeader(), myCandi, and myChanger.

Referenced by change().

00369                                                {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealRightFollower (  )  const throw () [protected]

Definition at line 410 of file MSLaneChanger.cpp.

References getRealFollower(), myCandi, and myChanger.

Referenced by change().

00410                                                   {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealRightLeader (  )  const throw () [protected]

Definition at line 358 of file MSLaneChanger.cpp.

References getRealLeader(), myCandi, and myChanger.

Referenced by change().

00358                                                 {
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 }

std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealThisLeader ( const ChangerIt target  )  const throw () [protected]

Definition at line 287 of file MSLaneChanger.cpp.

References MSVehicle::getBestLanesContinuation(), MSLane::getLastVehicle(), MSVehicleType::getLength(), MSLane::getPartialOccupator(), MSLane::getPartialOccupatorEnd(), MSVehicle::getPositionOnLane(), MSVehicle::getVehicleType(), MSLane::isLinkEnd(), MAX2(), myCandi, MSLane::succLinkSec(), SUMOReal, and veh().

Referenced by change().

00287                                                                       {
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 }

void MSLaneChanger::initChanger (  )  [protected]

Initialize the changer before looping over all vehicles.

Definition at line 87 of file MSLaneChanger.cpp.

References myChanger.

Referenced by laneChange().

00087                            {
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 }

void MSLaneChanger::laneChange ( SUMOTime  t  ) 

Start lane-change-process for all vehicles on the edge'e lanes.

Definition at line 71 of file MSLaneChanger.cpp.

References change(), initChanger(), updateChanger(), updateLanes(), and vehInChanger().

Referenced by MSEdge::changeLanes().

00071                                     {
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 }

MSLaneChanger& MSLaneChanger::operator= ( const MSLaneChanger  )  [private]

Assignment operator.

bool MSLaneChanger::overlapWithHopped ( ChangerIt  target  )  const throw () [inline, protected]

Returns true if candidate overlaps with a vehicle, that already changed the lane.

Definition at line 179 of file MSLaneChanger.h.

References myCandi, MSVehicle::overlap(), and veh().

Referenced by change2left(), and change2right().

00179                                                            {
00180         MSVehicle *v1 = target->hoppedVeh;
00181         MSVehicle *v2 = veh(myCandi);
00182         if (v1!=0 && v2!=0) {
00183             return MSVehicle::overlap(v1, v2);
00184         }
00185         return false;
00186     }

void MSLaneChanger::setIsSafeChange ( const std::pair< MSVehicle *const, SUMOReal > &  neighLead,
const std::pair< MSVehicle *const, SUMOReal > &  neighFollow,
const ChangerIt target,
int &  blocked 
) const throw () [protected]

Definition at line 584 of file MSLaneChanger.cpp.

References MSVehicle::getCarFollowModel(), MSLane::getMaxSpeed(), MSVehicle::getSpeed(), MSCFModel::hasSafeGap(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, and veh().

Referenced by change2left(), and change2right().

00586                                                                                     {
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 }

void MSLaneChanger::setOverlap ( const std::pair< MSVehicle *const, SUMOReal > &  neighLead,
const std::pair< MSVehicle *const, SUMOReal > &  neighFollow,
int &  blocked 
) const throw () [protected]

Definition at line 565 of file MSLaneChanger.cpp.

References LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, and LCA_OVERLAPPING.

Referenced by change2left(), and change2right().

00567                                                       {
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 }

void MSLaneChanger::updateChanger ( bool  vehHasChanged  )  [protected]

After the possible change, update the changer.

Definition at line 433 of file MSLaneChanger.cpp.

References myCandi, and veh().

Referenced by laneChange().

00433                                                {
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 }

void MSLaneChanger::updateLanes ( SUMOTime  t  )  [protected]

During lane-change a temporary vehicle container is filled within the lanes (bad pratice to modify foreign members, I know). Swap this container with the real one.

Definition at line 459 of file MSLaneChanger.cpp.

References myChanger.

Referenced by laneChange().

00459                                      {
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 }

MSVehicle* MSLaneChanger::veh ( ConstChangerIt  ce  )  const throw () [inline, protected]

Returns a pointer to the changer-element-iterator vehicle, or 0 if there is none.

Definition at line 115 of file MSLaneChanger.h.

Referenced by advan2left(), advan2right(), change(), change2left(), change2right(), findCandidate(), getRealFollower(), getRealLeader(), getRealThisLeader(), overlapWithHopped(), setIsSafeChange(), updateChanger(), and vehInChanger().

00115                                                     {
00116         // If ce has a valid vehicle, return it. Otherwise return 0.
00117         if (ce->veh != ce->lane->myVehicles.rend()) {
00118             return *(ce->veh);
00119         }
00120         return 0;
00121     }

bool MSLaneChanger::vehInChanger (  )  const throw () [inline, protected]

Check if there is a single change-candidate in the changer. Returns true if there is one.

Definition at line 102 of file MSLaneChanger.h.

References myChanger, and veh().

Referenced by laneChange().

00102                                       {
00103         // If there is at least one valid vehicle under the veh's in myChanger
00104         // return true.
00105         for (ConstChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
00106             if (veh(ce) != 0) {
00107                 return true;
00108             }
00109         }
00110         return false;
00111     }


Field Documentation

Change-candidate. Last of the vehicles in changer. Only this one will try to change. Every vehicle on the edge will be a candidate once in the change-process.

Definition at line 205 of file MSLaneChanger.h.

Referenced by advan2left(), advan2right(), change(), change2left(), change2right(), getRealFollower(), getRealLeader(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), getRealThisLeader(), overlapWithHopped(), setIsSafeChange(), and updateChanger().

Container for ChangeElemements, one for every lane in the edge.

Definition at line 200 of file MSLaneChanger.h.

Referenced by change(), change2left(), change2right(), findCandidate(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), initChanger(), MSLaneChanger(), updateLanes(), and vehInChanger().


The documentation for this class was generated from the following files:

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