|
SUMO - Simulation of Urban MObility
|
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