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