MSLCM_DK2004.cpp

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

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