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