|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // A lane change model developed by D. Krajzewicz between 2004 and 2010 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 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 #ifdef _MSC_VER 00025 #include <windows_config.h> 00026 #else 00027 #include <config.h> 00028 #endif 00029 00030 #include "MSLCM_DK2004.h" 00031 #include <utils/common/RandHelper.h> 00032 #include <iostream> 00033 00034 #ifdef CHECK_MEMORY_LEAKS 00035 #include <foreign/nvwa/debug_new.h> 00036 #endif // CHECK_MEMORY_LEAKS 00037 00038 //#define DEBUG_VEHICLE_GUI_SELECTION 1 00039 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00040 #include <utils/gui/div/GUIGlobalSelection.h> 00041 #include <guisim/GUIVehicle.h> 00042 #include <guisim/GUILane.h> 00043 #endif 00044 00045 00046 00047 // =========================================================================== 00048 // variable definitions 00049 // =========================================================================== 00050 // 80km/h will be the threshold for dividing between long/short foresight 00051 #define LOOK_FORWARD_SPEED_DIVIDER 14. 00052 00053 #define LOOK_FORWARD_FAR 15. 00054 #define LOOK_FORWARD_NEAR 5. 00055 00056 00057 00058 #define JAM_FACTOR 2. 00059 #define JAM_FACTOR2 1. 00060 00061 00062 // =========================================================================== 00063 // member method definitions 00064 // =========================================================================== 00065 MSLCM_DK2004::MSLCM_DK2004(MSVehicle& v) 00066 : MSAbstractLaneChangeModel(v), 00067 myChangeProbability(0), 00068 myLeadingBlockerLength(0), myLeftSpace(0) {} 00069 00070 MSLCM_DK2004::~MSLCM_DK2004() { 00071 changed(); 00072 } 00073 00074 00075 int 00076 MSLCM_DK2004::wantsChangeToRight(MSAbstractLaneChangeModel::MSLCMessager& msgPass, 00077 int blocked, 00078 const std::pair<MSVehicle*, SUMOReal> &leader, 00079 const std::pair<MSVehicle*, SUMOReal> &neighLead, 00080 const std::pair<MSVehicle*, SUMOReal> &neighFollow, 00081 const MSLane& neighLane, 00082 const std::vector<MSVehicle::LaneQ> &preb, 00083 MSVehicle** lastBlocked) { 00084 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00085 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(&myVehicle)->getGlID())) { 00086 int bla = 0; 00087 } 00088 #endif 00089 MSVehicle::LaneQ curr, best; 00090 int bestLaneOffset = 0; 00091 SUMOReal currentDist = 0; 00092 SUMOReal neighDist = 0; 00093 SUMOReal neighExtDist = 0; 00094 SUMOReal currExtDist = 0; 00095 int currIdx = 0; 00096 for (int p=0; p<(int) preb.size(); ++p) { 00097 if (preb[p].lane==myVehicle.getLane()) { 00098 curr = preb[p]; 00099 bestLaneOffset = curr.bestLaneOffset; 00100 currentDist = curr.length; 00101 currExtDist = curr.lane->getLength(); 00102 neighDist = preb[p-1].length; 00103 neighExtDist = preb[p-1].lane->getLength(); 00104 best = preb[p+bestLaneOffset]; 00105 currIdx = p; 00106 } 00107 } 00108 00109 // keep information about being a leader/follower 00110 int ret = (myOwnState&0x00ffff00); 00111 00112 if (leader.first!=0 00113 && 00114 (myOwnState&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)!=0 00115 && 00116 (leader.first->getLaneChangeModel().getOwnState()&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)!=0) { 00117 00118 myOwnState &= (0xffffffff-LCA_AMBLOCKINGFOLLOWER_DONTBRAKE); 00119 if (myVehicle.getSpeed()>0.1) { 00120 myOwnState |= LCA_AMBACKBLOCKER; 00121 } else { 00122 ret |= LCA_AMBACKBLOCKER; 00123 myDontBrake = true; 00124 } 00125 } 00126 00127 // process information about the last blocked vehicle 00128 // if this vehicle is blocking someone in front, we maybe decelerate to let him in 00129 if ((*lastBlocked)!=0) { 00130 SUMOReal gap = (*lastBlocked)->getPositionOnLane()-(*lastBlocked)->getVehicleType().getLengthWithGap()-myVehicle.getPositionOnLane(); 00131 if (gap>0.1) { 00132 if (myVehicle.getSpeed()<ACCEL2SPEED(myVehicle.getCarFollowModel().getMaxDecel())) { 00133 if ((*lastBlocked)->getSpeed()<0.1) { 00134 ret |= LCA_AMBACKBLOCKER_STANDING; 00135 } else { 00136 ret |= LCA_AMBACKBLOCKER; 00137 } 00138 myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), (SUMOReal)(gap-0.1), (*lastBlocked)->getSpeed(), (*lastBlocked)->getCarFollowModel().getMaxDecel())); 00139 (*lastBlocked) = 0; 00140 } 00141 return ret; 00142 } 00143 } 00144 00145 // we try to estimate the distance which is necessary to get on a lane 00146 // we have to get on in order to keep our route 00147 // we assume we need something that depends on our velocity 00148 // and compare this with the free space on our wished lane 00149 // 00150 // if the free space is somehow less than the space we need, we should 00151 // definitely try to get to the desired lane 00152 // 00153 // this rule forces our vehicle to change the lane if a lane changing is necessary soon 00154 SUMOReal rv = myVehicle.getSpeed() > LOOK_FORWARD_SPEED_DIVIDER 00155 ? myVehicle.getSpeed() * (SUMOReal) LOOK_FORWARD_FAR 00156 : myVehicle.getSpeed() * (SUMOReal) LOOK_FORWARD_NEAR; 00157 rv += myVehicle.getVehicleType().getLengthWithGap() * (SUMOReal) 2.; 00158 00159 SUMOReal tdist = currentDist-myVehicle.getPositionOnLane() - best.occupation * (SUMOReal) JAM_FACTOR2; 00160 00161 if (fabs(best.length-curr.length)>MIN2((SUMOReal) .1, best.lane->getLength()) && bestLaneOffset<0&¤tDistDisallows(tdist/*currentDist*/, bestLaneOffset, rv)) { 00162 informBlocker(msgPass, blocked, LCA_MRIGHT, neighLead, neighFollow); 00163 if (neighLead.second>0&&neighLead.second>leader.second) { 00164 myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()) - (SUMOReal) 0.5); 00165 } 00166 00167 // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1, right 00168 // if there is a leader and he wants to change to left (we want to change to right) 00169 if (neighLead.first!=0&&(neighLead.first->getLaneChangeModel().getOwnState()&LCA_LEFT)!=0) { 00170 // save at least his length in myLeadingBlockerLength 00171 myLeadingBlockerLength = MAX2(neighLead.first->getVehicleType().getLengthWithGap(), myLeadingBlockerLength); 00172 // save the left space 00173 myLeftSpace = currentDist-myVehicle.getPositionOnLane(); 00174 } 00175 // 00176 00177 return ret|LCA_RIGHT|LCA_URGENT; 00178 } 00179 00180 00181 // the opposite lane-changing direction should be done than the one examined herein 00182 // we'll check whether we assume we could change anyhow and get back in time... 00183 // 00184 // this rule prevents the vehicle from moving in opposite direction of the best lane 00185 // unless the way till the end where the vehicle has to be on the best lane 00186 // is long enough 00187 SUMOReal maxJam = MAX2(preb[currIdx-1].occupation, preb[currIdx].occupation); 00188 SUMOReal neighLeftPlace = MAX2((SUMOReal) 0, neighDist-myVehicle.getPositionOnLane()-maxJam); 00189 if (bestLaneOffset>=0&&(currentDistDisallows(neighLeftPlace, bestLaneOffset+2, rv))) { 00190 // ...we will not change the lane if not 00191 return ret; 00192 } 00193 00194 00195 // if the current lane is the best and a lane-changing would cause a situation 00196 // of which we assume we will not be able to return to the lane we have to be on... 00197 // 00198 // this rule prevents the vehicle from leaving the current, best lane when it is 00199 // close to this lane's end 00200 if (currExtDist>neighExtDist&&(neighLeftPlace*2.<rv/*||currE[currIdx+1].length<currentDist*/)) { 00201 return ret; 00202 } 00203 00204 // let's also regard the case where the vehicle is driving on a highway... 00205 // in this case, we do not want to get to the dead-end of an on-ramp 00206 // 00207 // THIS RULE APPLIES ONLY TO CHANGING TO THE RIGHT LANE 00208 if (bestLaneOffset==0&&preb[currIdx-1].bestLaneOffset!=0&&myVehicle.getLane()->getMaxSpeed()>80./3.6) { 00209 return ret; 00210 } 00211 // -------- 00212 00213 // -------- make place on current lane if blocking follower 00214 if (amBlockingFollowerPlusNB() 00215 && 00216 (currentDistAllows(neighDist, bestLaneOffset, rv)||neighDist>=currentDist)) { 00217 00218 return ret|LCA_RIGHT|LCA_URGENT; 00219 } 00220 // -------- 00221 00222 00223 // -------- security checks for krauss 00224 // (vsafe fails when gap<0) 00225 if ((blocked&LCA_BLOCKED)!=0) { 00226 return ret; 00227 } 00228 // -------- 00229 00230 // -------- higher speed 00231 if ((congested(neighLead.first) && neighLead.second<20)||predInteraction(leader.first)) { 00232 return ret; 00233 } 00234 SUMOReal thisLaneVSafe = myVehicle.getLane()->getMaxSpeed(); 00235 SUMOReal neighLaneVSafe = neighLane.getMaxSpeed(); 00236 if (neighLead.first == 0) { 00237 neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighDist, 0, 0)); 00238 } else { 00239 // @todo: what if leader is below safe gap?!!! 00240 neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())); 00241 } 00242 if (leader.first==0) { 00243 thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), currentDist, 0, 0)); 00244 } else { 00245 // @todo: what if leader is below safe gap?!!! 00246 thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel())); 00247 } 00248 00249 thisLaneVSafe = MIN2(thisLaneVSafe, myVehicle.getVehicleType().getMaxSpeed()); 00250 neighLaneVSafe = MIN2(neighLaneVSafe, myVehicle.getVehicleType().getMaxSpeed()); 00251 if (thisLaneVSafe-neighLaneVSafe>5./3.6) { 00252 // ok, the current lane is faster than the right one... 00253 if (myChangeProbability<0) { 00254 myChangeProbability /= 2.0; 00255 } 00256 } else { 00257 // ok, the right lane is faster than the current 00258 myChangeProbability -= (SUMOReal)((neighLaneVSafe-thisLaneVSafe) / (myVehicle.getLane()->getMaxSpeed())); 00259 } 00260 00261 // let's recheck the "Rechtsfahrgebot" 00262 SUMOReal vmax = MIN2(myVehicle.getLane()->getMaxSpeed(), myVehicle.getVehicleType().getMaxSpeed()); 00263 vmax -= (SUMOReal)(5./2.6); 00264 if (neighLaneVSafe>=vmax) { 00265 #ifndef NO_TRACI 00266 /* if there was a request by TraCI for changing to this lane 00267 and holding it, this rule is ignored */ 00268 if (myChangeRequest != MSVehicle::REQUEST_HOLD) { 00269 #endif 00270 myChangeProbability -= (SUMOReal)((neighLaneVSafe-vmax) / (vmax)); 00271 #ifndef NO_TRACI 00272 } 00273 #endif 00274 } 00275 00276 if (myChangeProbability<-2&&neighDist/MAX2((SUMOReal) .1, myVehicle.getSpeed())>20.) {//./MAX2((SUMOReal) .1, myVehicle.getSpeed())) { // -.1 00277 return ret | LCA_RIGHT|LCA_SPEEDGAIN; 00278 } 00279 // -------- 00280 00281 #ifndef NO_TRACI 00282 // If there is a request by TraCI, try to change the lane 00283 if (myChangeRequest == MSVehicle::REQUEST_RIGHT) { 00284 return ret | LCA_RIGHT; 00285 } 00286 #endif 00287 00288 return ret; 00289 } 00290 00291 00292 int 00293 MSLCM_DK2004::wantsChangeToLeft(MSAbstractLaneChangeModel::MSLCMessager& msgPass, 00294 int blocked, 00295 const std::pair<MSVehicle*, SUMOReal> &leader, 00296 const std::pair<MSVehicle*, SUMOReal> &neighLead, 00297 const std::pair<MSVehicle*, SUMOReal> &neighFollow, 00298 const MSLane& neighLane, 00299 const std::vector<MSVehicle::LaneQ> &preb, 00300 MSVehicle** lastBlocked) { 00301 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00302 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(&myVehicle)->getGlID())) { 00303 int bla = 0; 00304 } 00305 #endif 00306 MSVehicle::LaneQ curr, best; 00307 int bestLaneOffset = 0; 00308 SUMOReal currentDist = 0; 00309 SUMOReal neighDist = 0; 00310 SUMOReal neighExtDist = 0; 00311 SUMOReal currExtDist = 0; 00312 int currIdx = 0; 00313 for (int p=0; p<(int) preb.size(); ++p) { 00314 if (preb[p].lane==myVehicle.getLane()) { 00315 curr = preb[p]; 00316 bestLaneOffset = curr.bestLaneOffset; 00317 currentDist = curr.length; 00318 currExtDist = curr.lane->getLength(); 00319 neighDist = preb[p+1].length; 00320 neighExtDist = preb[p+1].lane->getLength(); 00321 best = preb[p+bestLaneOffset]; 00322 currIdx = p; 00323 } 00324 } 00325 // keep information about being a leader/follower 00326 int ret = (myOwnState&0x00ffff00); 00327 00328 // ?!!! 00329 if (leader.first!=0 00330 && 00331 (myOwnState&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)!=0 00332 && 00333 (leader.first->getLaneChangeModel().getOwnState()&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)!=0) { 00334 00335 myOwnState &= (0xffffffff-LCA_AMBLOCKINGFOLLOWER_DONTBRAKE); 00336 if (myVehicle.getSpeed()>0.1) { 00337 myOwnState |= LCA_AMBACKBLOCKER; 00338 } else { 00339 ret |= LCA_AMBACKBLOCKER; 00340 myDontBrake = true; 00341 } 00342 } 00343 00344 // process information about the last blocked vehicle 00345 // if this vehicle is blocking someone in front, we maybe decelerate to let him in 00346 if ((*lastBlocked)!=0) { 00347 SUMOReal gap = (*lastBlocked)->getPositionOnLane()-(*lastBlocked)->getVehicleType().getLengthWithGap()-myVehicle.getPositionOnLane(); 00348 if (gap>0.1) { 00349 if (myVehicle.getSpeed()<ACCEL2SPEED(myVehicle.getCarFollowModel().getMaxDecel())) { 00350 if ((*lastBlocked)->getSpeed()<0.1) { 00351 ret |= LCA_AMBACKBLOCKER_STANDING; 00352 } else { 00353 ret |= LCA_AMBACKBLOCKER; 00354 } 00355 myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), (SUMOReal)(gap-0.1), (*lastBlocked)->getSpeed(), (*lastBlocked)->getCarFollowModel().getMaxDecel())); 00356 (*lastBlocked) = 0; 00357 } 00358 return ret; 00359 } 00360 } 00361 00362 // we try to estimate the distance which is necessary to get on a lane 00363 // we have to get on in order to keep our route 00364 // we assume we need something that depends on our velocity 00365 // and compare this with the free space on our wished lane 00366 // 00367 // if the free space is somehow less than the space we need, we should 00368 // definitely try to get to the desired lane 00369 // 00370 // this rule forces our vehicle to change the lane if a lane changing is necessary soon 00371 SUMOReal lv = myVehicle.getSpeed() > LOOK_FORWARD_SPEED_DIVIDER 00372 ? myVehicle.getSpeed() * (SUMOReal) LOOK_FORWARD_FAR 00373 : myVehicle.getSpeed() * (SUMOReal) LOOK_FORWARD_NEAR; 00374 lv += myVehicle.getVehicleType().getLengthWithGap() * (SUMOReal) 2.; 00375 00376 00377 SUMOReal tdist = currentDist-myVehicle.getPositionOnLane() - best.occupation * (SUMOReal) JAM_FACTOR2; 00378 if (fabs(best.length-curr.length)>MIN2((SUMOReal) .1, best.lane->getLength()) && bestLaneOffset>0 00379 && 00380 currentDistDisallows(tdist/*currentDist*/, bestLaneOffset, lv)) { 00381 informBlocker(msgPass, blocked, LCA_MLEFT, neighLead, neighFollow); 00382 if (neighLead.second>0&&neighLead.second>leader.second) { 00383 myVSafes.push_back(myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel()) - (SUMOReal) 0.5); 00384 } 00385 00386 // letting vehicles merge in at the end of the lane in case of counter-lane change, step#1, left 00387 // if there is a leader and he wants to change to right (we want to change to left) 00388 if (neighLead.first!=0&&(neighLead.first->getLaneChangeModel().getOwnState()&LCA_RIGHT)!=0) { 00389 // save at least his length in myLeadingBlockerLength 00390 myLeadingBlockerLength = MAX2(neighLead.first->getVehicleType().getLengthWithGap(), myLeadingBlockerLength); 00391 // save the left space 00392 myLeftSpace = currentDist-myVehicle.getPositionOnLane(); 00393 } 00394 // 00395 00396 return ret|LCA_LEFT|LCA_URGENT; 00397 } 00398 00399 // the opposite lane-changing direction should be rather done, not 00400 // the one examined herein 00401 // we'll check whether we assume we could change anyhow and get back in time... 00402 // 00403 // this rule prevents the vehicle from moving in opposite direction of the best lane 00404 // unless the way till the end where the vehicle has to be on the best lane 00405 // is long enough 00406 SUMOReal maxJam = MAX2(preb[currIdx+1].occupation, preb[currIdx].occupation); 00407 SUMOReal neighLeftPlace = MAX2((SUMOReal) 0, neighDist-myVehicle.getPositionOnLane()-maxJam); 00408 if (bestLaneOffset<=0&&(currentDistDisallows(neighLeftPlace, bestLaneOffset-2, lv))) { 00409 // ...we will not change the lane if not 00410 return ret; 00411 } 00412 00413 00414 // if the current lane is the best and a lane-changing would cause a situation 00415 // of which we assume we will not be able to return to the lane we have to be on... 00416 // 00417 // this rule prevents the vehicle from leaving the current, best lane when it is 00418 // close to this lane's end 00419 if (currExtDist>neighExtDist&&(neighLeftPlace*2.<lv/*||currE[currIdx+1].length<currentDist*/)) { 00420 // ... let's not change the lane 00421 return ret; 00422 } 00423 00424 /* 00425 // let's also regard the case where the vehicle is driving on a highway... 00426 // in this case, we do not want to get to the dead-end of an on-ramp 00427 if(bestLaneOffset==0&&myVehicle.getLane().getMaxSpeed()>80./3.6) { 00428 return ret; 00429 } 00430 */ 00431 00432 00433 /* 00434 // if the current lane is the 00435 if(bestLaneOffset==0&&(neighDist==0||curr.seenVehicles2*JAM_FACTOR>=neighExtDist-curr.length)) { 00436 return ret; 00437 } 00438 */ 00439 // -------- 00440 00441 // -------- make place on current lane if blocking follower 00442 if (amBlockingFollowerPlusNB() 00443 && 00444 (currentDistAllows(neighDist, bestLaneOffset, lv)||neighDist>=currentDist)) { 00445 00446 return ret|LCA_LEFT|LCA_URGENT; 00447 } 00448 // -------- 00449 00450 // -------- security checks for krauss 00451 // (vsafe fails when gap<0) 00452 if ((blocked&LCA_BLOCKED)!=0) { 00453 return ret; 00454 } 00455 00456 // -------- higher speed 00457 if ((congested(neighLead.first) && neighLead.second<20)||predInteraction(leader.first)) { 00458 return ret; 00459 } 00460 SUMOReal neighLaneVSafe = neighLane.getMaxSpeed(); 00461 SUMOReal thisLaneVSafe = myVehicle.getLane()->getMaxSpeed(); 00462 if (neighLead.first == 0) { 00463 neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighDist, 0, 0)); // !!! warum nicht die Folgesgeschw.? 00464 } else { 00465 // @todo: what if leader is below safe gap?!!! 00466 neighLaneVSafe = MIN2(neighLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighLead.second, neighLead.first->getSpeed(), neighLead.first->getCarFollowModel().getMaxDecel())); 00467 } 00468 if (leader.first==0) { 00469 thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), currentDist, 0, 0)); 00470 } else { 00471 // @todo: what if leader is below safe gap?!!! 00472 thisLaneVSafe = MIN2(thisLaneVSafe, myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), leader.second, leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel())); 00473 } 00474 thisLaneVSafe = MIN2(thisLaneVSafe, myVehicle.getVehicleType().getMaxSpeed()); 00475 neighLaneVSafe = MIN2(neighLaneVSafe, myVehicle.getVehicleType().getMaxSpeed()); 00476 if (thisLaneVSafe>neighLaneVSafe) { 00477 // this lane is better 00478 if (myChangeProbability>0) { 00479 myChangeProbability /= 2.0; 00480 } 00481 } else { 00482 // right lane is better 00483 myChangeProbability += (SUMOReal)((neighLaneVSafe-thisLaneVSafe) / (myVehicle.getLane()->getMaxSpeed())); // !!! Fahrzeuggeschw.! 00484 } 00485 if (myChangeProbability>.2&&neighDist/MAX2((SUMOReal) .1, myVehicle.getSpeed())>20.) { // .1 00486 return ret | LCA_LEFT|LCA_SPEEDGAIN|LCA_URGENT; 00487 } 00488 // -------- 00489 00490 #ifndef NO_TRACI 00491 // If there is a request by TraCI, try to change the lane 00492 if (myChangeRequest == MSVehicle::REQUEST_LEFT) { 00493 return ret | LCA_LEFT; 00494 } 00495 #endif 00496 00497 return ret; 00498 } 00499 00500 00501 SUMOReal 00502 MSLCM_DK2004::patchSpeed(const SUMOReal min, const SUMOReal wanted, const SUMOReal max, const MSCFModel& cfModel) { 00503 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00504 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(&myVehicle)->getGlID())) { 00505 int bla = 0; 00506 } 00507 #endif 00508 int state = myOwnState; 00509 myOwnState = 0; 00510 00511 // letting vehicles merge in at the end of the lane in case of counter-lane change, step#2 00512 SUMOReal MAGIC_offset = 1.; 00513 // if we want to change and have a blocking leader and there is enough room for him in front of us 00514 if (myLeadingBlockerLength!=0) { 00515 SUMOReal space = myLeftSpace-myLeadingBlockerLength-MAGIC_offset; 00516 if (space>0) { 00517 // compute speed for decelerating towards a place which allows the blocking leader to merge in in front 00518 SUMOReal safe = cfModel.stopSpeed(&myVehicle, space); 00519 // if we are approaching this place 00520 if (safe<wanted) { 00521 // return this speed as the speed to use 00522 return MAX2(min, safe); 00523 } 00524 } 00525 } 00526 00527 // just to make sure to be notified about lane chaning end 00528 if (myVehicle.getLane()->getEdge().getLanes().size()==1) { 00529 // remove chaning information if on a road with a single lane 00530 changed(); 00531 return wanted; 00532 } 00533 00534 SUMOReal nVSafe = wanted; 00535 bool gotOne = false; 00536 for (std::vector<SUMOReal>::const_iterator i=myVSafes.begin(); i!=myVSafes.end(); ++i) { 00537 SUMOReal v = (*i); 00538 if (v>=min && v<=max) { 00539 nVSafe = MIN2(v, nVSafe); 00540 gotOne = true; 00541 } 00542 } 00543 00544 // check whether the vehicle is blocked 00545 if ((state&LCA_WANTS_LANECHANGE)!=0) { 00546 if (gotOne&&!myDontBrake) { 00547 return nVSafe; 00548 } 00549 // check whether the vehicle maybe has to be swapped with one of 00550 // the blocking vehicles 00551 if ((state&LCA_BLOCKED)!=0) { 00552 if ((state&LCA_BLOCKED_BY_LEADER)!=0) { 00553 // if interacting with leader and not too slow 00554 return (min+wanted)/(SUMOReal) 2.0; 00555 } 00556 if ((state&LCA_BLOCKED_BY_FOLLOWER)!=0) { 00557 return (max+wanted)/(SUMOReal) 2.0; 00558 } 00559 return (min+wanted)/(SUMOReal) 2.0; 00560 } 00561 } 00562 00563 00564 // decelerate if being a blocking follower 00565 // (and does not have to change lanes) 00566 if ((state&LCA_AMBLOCKINGFOLLOWER)!=0) { 00567 if (fabs(max-myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed()))<0.001&&min==0) { // !!! was standing 00568 return 0; 00569 } 00570 return (min+wanted)/(SUMOReal) 2.0; 00571 } 00572 if ((state&LCA_AMBACKBLOCKER)!=0) { 00573 if (max<=myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed())&&min==0) {// !!! was standing 00574 return min; 00575 } 00576 } 00577 if ((state&LCA_AMBACKBLOCKER_STANDING)!=0) { 00578 return min; 00579 } 00580 // accelerate if being a blocking leader or blocking follower not able to brake 00581 // (and does not have to change lanes) 00582 if ((state&LCA_AMBLOCKINGLEADER)!=0) { 00583 return (max+wanted)/(SUMOReal) 2.0; 00584 } 00585 if ((state&LCA_AMBLOCKINGFOLLOWER_DONTBRAKE)!=0) { 00586 if (max<=myVehicle.getCarFollowModel().maxNextSpeed(myVehicle.getSpeed())&&min==0) {// !!! was standing 00587 return wanted; 00588 } 00589 return (min+wanted)/(SUMOReal) 2.0; 00590 } 00591 return wanted; 00592 } 00593 00594 00595 void* 00596 MSLCM_DK2004::inform(void* info, MSVehicle* /*sender*/) { 00597 Info* pinfo = (Info*) info; 00598 myOwnState &= 0xffffffff; 00599 myOwnState |= pinfo->second; 00600 delete pinfo; 00601 return (void*) true; 00602 } 00603 00604 00605 void 00606 MSLCM_DK2004::changed() { 00607 myChangeProbability = 0; 00608 myOwnState = 0; 00609 myLeadingBlockerLength = 0; 00610 myLeftSpace = 0; 00611 myVSafes.clear(); 00612 myDontBrake = false; 00613 } 00614 00615 00616 void 00617 MSLCM_DK2004::informBlocker(MSAbstractLaneChangeModel::MSLCMessager& msgPass, 00618 int& blocked, 00619 int dir, 00620 const std::pair<MSVehicle*, SUMOReal> &neighLead, 00621 const std::pair<MSVehicle*, SUMOReal> &neighFollow) { 00622 if ((blocked&LCA_BLOCKED_BY_FOLLOWER)!=0) { 00623 assert(neighFollow.first!=0); 00624 MSVehicle* nv = neighFollow.first; 00625 SUMOReal decelGap = 00626 neighFollow.second 00627 + SPEED2DIST(myVehicle.getSpeed()) * (SUMOReal) 2.0 00628 - MAX2(nv->getSpeed() - (SUMOReal) ACCEL2DIST(nv->getCarFollowModel().getMaxDecel()) * (SUMOReal) 2.0, (SUMOReal) 0); 00629 if (neighFollow.second>0&&decelGap>0&&decelGap>=nv->getCarFollowModel().getSecureGap(nv->getSpeed(), myVehicle.getSpeed(), myVehicle.getCarFollowModel().getMaxDecel())) { 00630 SUMOReal vsafe = myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel()); 00631 msgPass.informNeighFollower(new Info(vsafe, dir|LCA_AMBLOCKINGFOLLOWER), &myVehicle); 00632 } else { 00633 SUMOReal vsafe = neighFollow.second<=0 ? 0 : myCarFollowModel.followSpeed(&myVehicle, myVehicle.getSpeed(), neighFollow.second, neighFollow.first->getSpeed(), neighFollow.first->getCarFollowModel().getMaxDecel()); 00634 msgPass.informNeighFollower(new Info(vsafe, dir|LCA_AMBLOCKINGFOLLOWER_DONTBRAKE), &myVehicle); 00635 } 00636 } 00637 if ((blocked&LCA_BLOCKED_BY_LEADER)!=0) { 00638 if (neighLead.first!=0&&neighLead.second>0) { 00639 msgPass.informNeighLeader(new Info(0, dir|LCA_AMBLOCKINGLEADER), &myVehicle); 00640 } 00641 } 00642 } 00643 00644 00645 void 00646 MSLCM_DK2004::prepareStep() { 00647 myLeadingBlockerLength = 0; 00648 myLeftSpace = 0; 00649 myVSafes.clear(); 00650 myDontBrake = false; 00651 } 00652 00653 00654 SUMOReal 00655 MSLCM_DK2004::getProb() const { 00656 return myChangeProbability; 00657 } 00658 00659 00660 /****************************************************************************/ 00661