#include <MSLaneChanger.h>
Definition at line 51 of file MSLaneChanger.h.
Public Types | |
| typedef std::vector< ChangeElem > | Changer |
| The list of changers; For each lane, a ChangeElem is being build. | |
| typedef Changer::iterator | ChangerIt |
| the iterator moving over the ChangeElems | |
| typedef Changer::const_iterator | ConstChangerIt |
| the iterator moving over the ChangeElems | |
Public Member Functions | |
| void | laneChange (SUMOTime t) |
| Start lane-change-process for all vehicles on the edge'e lanes. | |
| MSLaneChanger (std::vector< MSLane * > *lanes) | |
| Constructor. | |
| ~MSLaneChanger () | |
| Destructor. | |
Protected Member Functions | |
| int | advan2left (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, int blocked, const std::vector< MSVehicle::LaneQ > &preb) const throw () |
| int | advan2right (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, int blocked, const std::vector< MSVehicle::LaneQ > &preb) const throw () |
| bool | change () |
| int | change2left (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, const std::vector< MSVehicle::LaneQ > &preb) const throw () |
| int | change2right (const std::pair< MSVehicle *const, SUMOReal > &leader, const std::pair< MSVehicle *const, SUMOReal > &rLead, const std::pair< MSVehicle *const, SUMOReal > &rFollow, const std::vector< MSVehicle::LaneQ > &preb) const throw () |
| ChangerIt | findCandidate () |
| Find current candidate. If there is none, myChanger.end() is returned. | |
| std::pair< MSVehicle *const, SUMOReal > | getRealFollower (const ChangerIt &target) const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealLeader (const ChangerIt &target) const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealLeftFollower () const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealLeftLeader () const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealRightFollower () const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealRightLeader () const throw () |
| std::pair< MSVehicle *const, SUMOReal > | getRealThisLeader (const ChangerIt &target) const throw () |
| void | initChanger () |
| Initialize the changer before looping over all vehicles. | |
| bool | overlapWithHopped (ChangerIt target) const throw () |
| void | setIsSafeChange (const std::pair< MSVehicle *const, SUMOReal > &neighLead, const std::pair< MSVehicle *const, SUMOReal > &neighFollow, const ChangerIt &target, int &blocked) const throw () |
| void | setOverlap (const std::pair< MSVehicle *const, SUMOReal > &neighLead, const std::pair< MSVehicle *const, SUMOReal > &neighFollow, int &blocked) const throw () |
| void | updateChanger (bool vehHasChanged) |
| void | updateLanes (SUMOTime t) |
| MSVehicle * | veh (ConstChangerIt ce) const throw () |
| bool | vehInChanger () const throw () |
| Check if there is a single change-candidate in the changer. Returns true if there is one. | |
Protected Attributes | |
| ChangerIt | myCandi |
| Changer | myChanger |
| Container for ChangeElemements, one for every lane in the edge. | |
Private Member Functions | |
| MSLaneChanger (const MSLaneChanger &) | |
| Copy constructor. | |
| MSLaneChanger () | |
| Default constructor. | |
| MSLaneChanger & | operator= (const MSLaneChanger &) |
| Assignment operator. | |
Data Structures | |
| struct | ChangeElem |
| typedef std::vector< ChangeElem > MSLaneChanger::Changer |
The list of changers; For each lane, a ChangeElem is being build.
Definition at line 88 of file MSLaneChanger.h.
| typedef Changer::iterator MSLaneChanger::ChangerIt |
| typedef Changer::const_iterator MSLaneChanger::ConstChangerIt |
| MSLaneChanger::MSLaneChanger | ( | std::vector< MSLane * > * | lanes | ) |
Constructor.
Definition at line 49 of file MSLaneChanger.cpp.
References MSLaneChanger::ChangeElem::follow, MSLaneChanger::ChangeElem::hoppedVeh, MSLaneChanger::ChangeElem::lane, MSLaneChanger::ChangeElem::lastBlocked, MSLaneChanger::ChangeElem::lead, myChanger, and MSLaneChanger::ChangeElem::veh.
00049 { 00050 assert(lanes->size() > 1); 00051 00052 // Fill the changer with the lane-data. 00053 myChanger.reserve(lanes->size()); 00054 for (std::vector<MSLane*>::iterator lane = lanes->begin(); lane != lanes->end(); ++lane) { 00055 ChangeElem ce; 00056 ce.follow = 0; 00057 ce.lead = 0; 00058 ce.lane = *lane; 00059 ce.veh = (*lane)->myVehicles.rbegin(); 00060 ce.hoppedVeh = 0; 00061 ce.lastBlocked = 0; 00062 myChanger.push_back(ce); 00063 } 00064 }
| MSLaneChanger::~MSLaneChanger | ( | ) |
| MSLaneChanger::MSLaneChanger | ( | ) | [private] |
Default constructor.
| MSLaneChanger::MSLaneChanger | ( | const MSLaneChanger & | ) | [private] |
Copy constructor.
| int MSLaneChanger::advan2left | ( | const std::pair< MSVehicle *const, SUMOReal > & | leader, | |
| const std::pair< MSVehicle *const, SUMOReal > & | rLead, | |||
| const std::pair< MSVehicle *const, SUMOReal > & | rFollow, | |||
| int | blocked, | |||
| const std::vector< MSVehicle::LaneQ > & | preb | |||
| ) | const throw () [protected] |
Returns true, if candidate has an advantage by changing to the left.
Definition at line 636 of file MSLaneChanger.cpp.
References MSVehicle::getLaneChangeModel(), myCandi, veh(), and MSAbstractLaneChangeModel::wantsChangeToLeft().
Referenced by change2left().
00640 { 00641 MSAbstractLaneChangeModel::MSLCMessager 00642 msg(leader.first, neighLead.first, neighFollow.first); 00643 return veh(myCandi)->getLaneChangeModel().wantsChangeToLeft( 00644 msg, blocked, 00645 leader, neighLead, neighFollow, *(myCandi+1)->lane, 00646 preb, 00647 &(myCandi->lastBlocked)); 00648 }
| int MSLaneChanger::advan2right | ( | const std::pair< MSVehicle *const, SUMOReal > & | leader, | |
| const std::pair< MSVehicle *const, SUMOReal > & | rLead, | |||
| const std::pair< MSVehicle *const, SUMOReal > & | rFollow, | |||
| int | blocked, | |||
| const std::vector< MSVehicle::LaneQ > & | preb | |||
| ) | const throw () [protected] |
Returns true, if candidate has an advantage by changing to the right.
Definition at line 620 of file MSLaneChanger.cpp.
References MSVehicle::getLaneChangeModel(), myCandi, veh(), and MSAbstractLaneChangeModel::wantsChangeToRight().
Referenced by change2right().
00624 { 00625 MSAbstractLaneChangeModel::MSLCMessager 00626 msg(leader.first, neighLead.first, neighFollow.first); 00627 return veh(myCandi)->getLaneChangeModel().wantsChangeToRight( 00628 msg, blocked, 00629 leader, neighLead, neighFollow, *(myCandi-1)->lane, 00630 preb, 00631 &(myCandi->lastBlocked)); 00632 }
| bool MSLaneChanger::change | ( | ) | [protected] |
Find a new candidate and try to change it.
Definition at line 112 of file MSLaneChanger.cpp.
References bla, change2left(), change2right(), MSAbstractLaneChangeModel::changed(), DELTA_T, MSVehicle::enterLaneAtLaneChange(), findCandidate(), MSAbstractLaneChangeModel::fulfillChangeRequest(), MSVehicle::getBestLanes(), MSVehicle::getLaneChangeModel(), MSVehicleType::getLength(), MSVehicle::getPositionOnLane(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), getRealThisLeader(), MSVehicle::getSpeed(), MSAbstractLaneChangeModel::getState(), MSVehicle::getVehicleType(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, LCA_LEFT, LCA_RIGHT, LCA_SPEEDGAIN, LCA_URGENT, MSVehicle::leaveLane(), myCandi, myChanger, MSVehicle::myLastLaneChangeOffset, MSVehicle::myState, MSAbstractLaneChangeModel::prepareStep(), REQUEST_LEFT, REQUEST_RIGHT, MSAbstractLaneChangeModel::setState(), SUMOReal, and veh().
Referenced by laneChange().
00112 { 00113 // Find change-candidate. If it is on an allowed lane, try to change 00114 // to the right (there is a rule in Germany that you have to change 00115 // to the right, unless you are overtaking). If change to the right 00116 // isn't possible, check if there is a possibility to overtake (on the 00117 // left. 00118 // If candidate isn't on an allowed lane, changing to an allowed has 00119 // priority. 00120 myCandi = findCandidate(); 00121 MSVehicle* vehicle = veh(myCandi); 00122 const std::vector<MSVehicle::LaneQ> &preb = vehicle->getBestLanes(); 00123 assert(preb.size()==myChanger.size()); 00124 for (int i=0; i<(int) myChanger.size(); ++i) { 00125 ((std::vector<MSVehicle::LaneQ>&) preb)[i].occupied = myChanger[i].dens + preb[i].v; 00126 } 00127 00128 vehicle->getLaneChangeModel().prepareStep(); 00129 // check whether the vehicle wants and is able to change to right lane 00130 std::pair<MSVehicle * const, SUMOReal> rLead = getRealRightLeader(); 00131 std::pair<MSVehicle * const, SUMOReal> lLead = getRealLeftLeader(); 00132 std::pair<MSVehicle * const, SUMOReal> rFollow = getRealRightFollower(); 00133 std::pair<MSVehicle * const, SUMOReal> lFollow = getRealLeftFollower(); 00134 std::pair<MSVehicle * const, SUMOReal> leader = getRealThisLeader(myCandi); 00135 int state1 = change2right(leader, rLead, rFollow, preb); 00136 bool changingAllowed = 00137 (state1&(LCA_BLOCKEDBY_LEADER|LCA_BLOCKEDBY_FOLLOWER))==0; 00138 if ((state1&LCA_URGENT)!=0||(state1&LCA_SPEEDGAIN)!=0) { 00139 state1 |= LCA_RIGHT; 00140 } 00141 // change if the vehicle wants to and is allowed to change 00142 if ((state1&LCA_RIGHT)!=0&&changingAllowed) { 00143 #ifndef NO_TRACI 00144 // inform lane change model about this change 00145 vehicle->getLaneChangeModel().fulfillChangeRequest(REQUEST_RIGHT); 00146 /*std::cout << "TraCI: lane changer fulfilled request for RIGHT |time " << MSNet::getInstance()->getCurrentTimeStep() << "s" << std::endl;*/ 00147 #endif 00148 (myCandi - 1)->hoppedVeh = vehicle; 00149 (myCandi - 1)->lane->myTmpVehicles.push_front(vehicle); 00150 vehicle->leaveLane(false); 00151 myCandi->lane->leftByLaneChange(vehicle); 00152 vehicle->enterLaneAtLaneChange((myCandi - 1)->lane); 00153 (myCandi - 1)->lane->enteredByLaneChange(vehicle); 00154 vehicle->myLastLaneChangeOffset = 0; 00155 vehicle->getLaneChangeModel().changed(); 00156 (myCandi - 1)->dens += (myCandi - 1)->hoppedVeh->getVehicleType().getLength(); 00157 return true; 00158 } 00159 if ((state1&LCA_RIGHT)!=0&&(state1&LCA_URGENT)!=0) { 00160 (myCandi - 1)->lastBlocked = vehicle; 00161 } 00162 00163 // check whether the vehicle wants and is able to change to left lane 00164 int state2 = 00165 change2left(leader, lLead, lFollow,preb); 00166 if ((state2&LCA_URGENT)!=0||(state2&LCA_SPEEDGAIN)!=0) { 00167 state2 |= LCA_LEFT; 00168 } 00169 changingAllowed = 00170 (state2&(LCA_BLOCKEDBY_LEADER|LCA_BLOCKEDBY_FOLLOWER))==0; 00171 vehicle->getLaneChangeModel().setState(state2|state1); 00172 // change if the vehicle wants to and is allowed to change 00173 if ((state2&LCA_LEFT)!=0&&changingAllowed) { 00174 #ifndef NO_TRACI 00175 // inform lane change model about this change 00176 vehicle->getLaneChangeModel().fulfillChangeRequest(REQUEST_LEFT); 00177 /*std::cout << "TraCI: lane changer fulfilled request for LEFT |time " << MSNet::getInstance()->getCurrentTimeStep() << "s" << std::endl;*/ 00178 #endif 00179 (myCandi + 1)->hoppedVeh = veh(myCandi); 00180 (myCandi + 1)->lane->myTmpVehicles.push_front(veh(myCandi)); 00181 vehicle->leaveLane(false); 00182 myCandi->lane->leftByLaneChange(vehicle); 00183 vehicle->enterLaneAtLaneChange((myCandi + 1)->lane); 00184 (myCandi + 1)->lane->enteredByLaneChange(vehicle); 00185 vehicle->myLastLaneChangeOffset = 0; 00186 vehicle->getLaneChangeModel().changed(); 00187 (myCandi + 1)->dens += (myCandi + 1)->hoppedVeh->getVehicleType().getLength(); 00188 return true; 00189 } 00190 if ((state2&LCA_LEFT)!=0&&(state2&LCA_URGENT)!=0) { 00191 (myCandi + 1)->lastBlocked = vehicle; 00192 } 00193 00194 if ((state1&(LCA_URGENT))!=0&&(state2&(LCA_URGENT))!=0) { 00195 // ... wants to go to the left AND to the right 00196 // just let them go to the right lane... 00197 state2 = 0; 00198 vehicle->getLaneChangeModel().setState(state1); 00199 } 00200 // check whether the vehicles should be swapped 00201 if (false&&((state1&(LCA_URGENT))!=0||(state2&(LCA_URGENT))!=0)) { 00202 // get the direction ... 00203 ChangerIt target; 00204 int dir; 00205 if ((state1&(LCA_URGENT))!=0) { 00206 // ... wants to go right 00207 target = myCandi - 1; 00208 dir = -1; 00209 } 00210 if ((state2&(LCA_URGENT))!=0) { 00211 // ... wants to go left 00212 target = myCandi + 1; 00213 dir = 1; 00214 } 00215 MSVehicle *prohibitor = target->lead; 00216 if (target->hoppedVeh!=0) { 00217 SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane(); 00218 if (prohibitor==0||( 00219 hoppedPos>vehicle->getPositionOnLane() && prohibitor->getPositionOnLane()>hoppedPos)) { 00220 00221 prohibitor = 0;// !!! vehicles should not jump over more than one lanetarget->hoppedVeh; 00222 } 00223 } 00224 if (prohibitor!=0 00225 && 00226 ((prohibitor->getLaneChangeModel().getState()&(LCA_URGENT/*|LCA_SPEEDGAIN*/))!=0 00227 && 00228 (prohibitor->getLaneChangeModel().getState()&(LCA_LEFT|LCA_RIGHT)) 00229 != 00230 (vehicle->getLaneChangeModel().getState()&(LCA_LEFT|LCA_RIGHT)) 00231 ) 00232 ) { 00233 00234 // check for position and speed 00235 if (prohibitor->getVehicleType().getLength()-vehicle->getVehicleType().getLength()==0) { 00236 // ok, may be swapped 00237 // remove vehicle to swap with 00238 MSLane::VehCont::iterator i = 00239 find( 00240 target->lane->myTmpVehicles.begin(), 00241 target->lane->myTmpVehicles.end(), 00242 prohibitor); 00243 if (i!=target->lane->myTmpVehicles.end()) { 00244 MSVehicle *bla = *i; 00245 assert(bla==prohibitor); 00246 target->lane->myTmpVehicles.erase(i); 00247 // set this vehicle 00248 target->hoppedVeh = vehicle; 00249 target->lane->myTmpVehicles.push_front(vehicle); 00250 myCandi->hoppedVeh = prohibitor; 00251 myCandi->lane->myTmpVehicles.push_front(prohibitor); 00252 00253 // leave lane and detectors 00254 vehicle->leaveLane(false); 00255 prohibitor->leaveLane(false); 00256 // patch position and speed 00257 SUMOReal p1 = vehicle->getPositionOnLane(); 00258 vehicle->myState.myPos = prohibitor->myState.myPos; 00259 prohibitor->myState.myPos = p1; 00260 p1 = vehicle->getSpeed(); 00261 vehicle->myState.mySpeed = prohibitor->myState.mySpeed; 00262 prohibitor->myState.mySpeed = p1; 00263 // enter lane and detectors 00264 vehicle->enterLaneAtLaneChange(target->lane); 00265 prohibitor->enterLaneAtLaneChange(myCandi->lane); 00266 // mark lane change 00267 vehicle->getLaneChangeModel().changed(); 00268 vehicle->myLastLaneChangeOffset = 0; 00269 prohibitor->getLaneChangeModel().changed(); 00270 prohibitor->myLastLaneChangeOffset = 0; 00271 (myCandi)->dens += prohibitor->getVehicleType().getLength(); 00272 (target)->dens += vehicle->getVehicleType().getLength(); 00273 return true; 00274 } 00275 } 00276 } 00277 } 00278 // Candidate didn't change lane. 00279 myCandi->lane->myTmpVehicles.push_front(veh(myCandi)); 00280 vehicle->myLastLaneChangeOffset += DELTA_T; 00281 (myCandi)->dens += vehicle->getVehicleType().getLength(); 00282 return false; 00283 }
| int MSLaneChanger::change2left | ( | const std::pair< MSVehicle *const, SUMOReal > & | leader, | |
| const std::pair< MSVehicle *const, SUMOReal > & | rLead, | |||
| const std::pair< MSVehicle *const, SUMOReal > & | rFollow, | |||
| const std::vector< MSVehicle::LaneQ > & | preb | |||
| ) | const throw () [protected] |
Definition at line 534 of file MSLaneChanger.cpp.
References advan2left(), MSVehicle::getPositionOnLane(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, myChanger, overlapWithHopped(), setIsSafeChange(), setOverlap(), and veh().
Referenced by change().
00537 { 00538 // Try to change to the left-lane, if there is one. If this lane isn't 00539 // an allowed one, cancel the try. Otherwise, check some conditions. 00540 // If they are simultaniously fulfilled, a change is possible. 00541 00542 // no left lane, overlapping or left lane not allowed -> exit 00543 ChangerIt target = myCandi + 1; 00544 if (target == myChanger.end()) { 00545 return 0; 00546 } 00547 if (!target->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) { 00548 return 0; 00549 } 00550 int blocked = overlapWithHopped(target) 00551 ? target->hoppedVeh->getPositionOnLane()<veh(myCandi)->getPositionOnLane() 00552 ? LCA_BLOCKEDBY_FOLLOWER 00553 : LCA_BLOCKEDBY_LEADER 00554 : 0; 00555 setOverlap(rLead, rFollow, blocked); 00556 setIsSafeChange(rLead, rFollow, target, blocked); 00557 return blocked 00558 | 00559 advan2left(leader, rLead, rFollow, 00560 blocked, preb); 00561 }
| int MSLaneChanger::change2right | ( | const std::pair< MSVehicle *const, SUMOReal > & | leader, | |
| const std::pair< MSVehicle *const, SUMOReal > & | rLead, | |||
| const std::pair< MSVehicle *const, SUMOReal > & | rFollow, | |||
| const std::vector< MSVehicle::LaneQ > & | preb | |||
| ) | const throw () [protected] |
Definition at line 502 of file MSLaneChanger.cpp.
References advan2right(), MSVehicle::getPositionOnLane(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, myChanger, overlapWithHopped(), setIsSafeChange(), setOverlap(), and veh().
Referenced by change().
00505 { 00506 // Try to change to the right-lane if there is one. If this lane isn't 00507 // an allowed one, cancel the try. Otherwise, check some conditions. If 00508 // they are simultaniously fulfilled, a change is possible. 00509 00510 // no right lane -> exit 00511 if (myCandi == myChanger.begin()) { 00512 return 0; 00513 } 00514 00515 ChangerIt target = myCandi - 1; 00516 if (!target->lane->allowsVehicleClass(veh(myCandi)->getVehicleType().getVehicleClass())) { 00517 return 0; 00518 } 00519 int blocked = overlapWithHopped(target) 00520 ? target->hoppedVeh->getPositionOnLane()<veh(myCandi)->getPositionOnLane() 00521 ? LCA_BLOCKEDBY_FOLLOWER 00522 : LCA_BLOCKEDBY_LEADER 00523 : 0; 00524 setOverlap(rLead, rFollow, blocked); 00525 setIsSafeChange(rLead, rFollow, target, blocked); 00526 return blocked 00527 | 00528 advan2right(leader, rLead, rFollow, 00529 blocked, preb); 00530 }
| MSLaneChanger::ChangerIt MSLaneChanger::findCandidate | ( | ) | [protected] |
Find current candidate. If there is none, myChanger.end() is returned.
Definition at line 476 of file MSLaneChanger.cpp.
References max, myChanger, and veh().
Referenced by change().
00476 { 00477 // Find the vehicle in myChanger with the smallest position. If there 00478 // is no vehicle in myChanger (shouldn't happen) , return 00479 // myChanger.end(). 00480 ChangerIt max = myChanger.end(); 00481 for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { 00482 if (veh(ce) == 0) { 00483 continue; 00484 } 00485 if (max == myChanger.end()) { 00486 max = ce; 00487 continue; 00488 } 00489 assert(veh(ce) != 0); 00490 assert(veh(max) != 0); 00491 if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) { 00492 max = ce; 00493 } 00494 } 00495 assert(max != myChanger.end()); 00496 assert(veh(max) != 0); 00497 return max; 00498 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealFollower | ( | const ChangerIt & | target | ) | const throw () [protected] |
Definition at line 380 of file MSLaneChanger.cpp.
References MSVehicleType::getLength(), MSVehicle::getPositionOnLane(), MSVehicle::getSpeed(), MSVehicle::getVehicleType(), MIN2(), myCandi, SPEED2DIST, SUMOReal, and veh().
Referenced by getRealLeftFollower(), and getRealRightFollower().
00380 { 00381 MSVehicle* neighFollow = veh(target); 00382 // check whether the hopped vehicle got the follower 00383 if (target->hoppedVeh!=0) { 00384 SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane(); 00385 if (hoppedPos<=veh(myCandi)->getPositionOnLane() && 00386 (neighFollow==0 || neighFollow->getPositionOnLane()>hoppedPos)) { 00387 00388 neighFollow = target->hoppedVeh; 00389 } 00390 } 00391 if (neighFollow==0) { 00392 SUMOReal speed = target->lane->getMaxSpeed(); 00393 // in order to look back, we'd need the minimum braking ability of vehicles in the net... 00394 // we'll assume it to be 4m/s^2 00395 // !!!revisit 00396 SUMOReal dist = speed * speed * SUMOReal(1./2.*4.) + SPEED2DIST(speed); 00397 dist = MIN2(dist, (SUMOReal) 500.); 00398 MSVehicle *candi = veh(myCandi); 00399 SUMOReal seen = candi->getPositionOnLane()-candi->getVehicleType().getLength(); 00400 return target->lane->getFollowerOnConsecutive(dist, seen, candi->getSpeed(), candi->getPositionOnLane() - candi->getVehicleType().getLength()); 00401 } else { 00402 MSVehicle *candi = veh(myCandi); 00403 return std::pair<MSVehicle * const, SUMOReal>(neighFollow, 00404 candi->getPositionOnLane()-candi->getVehicleType().getLength()-neighFollow->getPositionOnLane()); 00405 } 00406 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeader | ( | const ChangerIt & | target | ) | const throw () [protected] |
Definition at line 323 of file MSLaneChanger.cpp.
References MSCFModel::brakeGap(), MSVehicle::getBestLanesContinuation(), MSVehicle::getCarFollowModel(), MSLane::getPartialOccupator(), MSLane::getPartialOccupatorEnd(), MSVehicle::getPositionOnLane(), MSVehicle::getSpeed(), myCandi, SUMOReal, and veh().
Referenced by getRealLeftLeader(), and getRealRightLeader().
00323 { 00324 // get the leading vehicle on the lane to change to 00325 MSVehicle* neighLead = target->lead; 00326 // check whether the hopped vehicle got the leader 00327 if (target->hoppedVeh!=0) { 00328 SUMOReal hoppedPos = target->hoppedVeh->getPositionOnLane(); 00329 if (hoppedPos>veh(myCandi)->getPositionOnLane() && 00330 (neighLead==0 || neighLead->getPositionOnLane()>hoppedPos)) { 00331 00332 neighLead = target->hoppedVeh; 00333 } 00334 } 00335 if (neighLead==0) { 00336 MSLane* targetLane = target->lane; 00337 MSVehicle *predP = targetLane->getPartialOccupator(); 00338 if (predP!=0) { 00339 return std::pair<MSVehicle *, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane()); 00340 } 00341 const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation(myCandi->lane); 00342 SUMOReal seen = myCandi->lane->getLength() - veh(myCandi)->getPositionOnLane(); 00343 SUMOReal speed = veh(myCandi)->getSpeed(); 00344 SUMOReal dist = veh(myCandi)->getCarFollowModel().brakeGap(speed); 00345 if (seen>dist) { 00346 return std::pair<MSVehicle * const, SUMOReal>(0, -1); 00347 } 00348 return target->lane->getLeaderOnConsecutive(dist, seen, speed, *veh(myCandi), bestLaneConts); 00349 } else { 00350 MSVehicle *candi = veh(myCandi); 00351 return std::pair<MSVehicle * const, SUMOReal>(neighLead, 00352 neighLead->getPositionOnLane()-neighLead->getVehicleType().getLength()-candi->getPositionOnLane()); 00353 } 00354 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeftFollower | ( | ) | const throw () [protected] |
Definition at line 421 of file MSLaneChanger.cpp.
References getRealFollower(), myCandi, and myChanger.
Referenced by change().
00421 { 00422 // there is no left lane 00423 if ((myCandi+1) == myChanger.end()) { 00424 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00425 } 00426 ChangerIt target = myCandi + 1; 00427 return getRealFollower(target); 00428 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealLeftLeader | ( | ) | const throw () [protected] |
Definition at line 369 of file MSLaneChanger.cpp.
References getRealLeader(), myCandi, and myChanger.
Referenced by change().
00369 { 00370 // there is no left lane 00371 if ((myCandi+1) == myChanger.end()) { 00372 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00373 } 00374 ChangerIt target = myCandi + 1; 00375 return getRealLeader(target); 00376 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealRightFollower | ( | ) | const throw () [protected] |
Definition at line 410 of file MSLaneChanger.cpp.
References getRealFollower(), myCandi, and myChanger.
Referenced by change().
00410 { 00411 // there is no right lane 00412 if (myCandi == myChanger.begin()) { 00413 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00414 } 00415 ChangerIt target = myCandi - 1; 00416 return getRealFollower(target); 00417 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealRightLeader | ( | ) | const throw () [protected] |
Definition at line 358 of file MSLaneChanger.cpp.
References getRealLeader(), myCandi, and myChanger.
Referenced by change().
00358 { 00359 // there is no right lane 00360 if (myCandi == myChanger.begin()) { 00361 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00362 } 00363 ChangerIt target = myCandi - 1; 00364 return getRealLeader(target); 00365 }
| std::pair< MSVehicle *const, SUMOReal > MSLaneChanger::getRealThisLeader | ( | const ChangerIt & | target | ) | const throw () [protected] |
Definition at line 287 of file MSLaneChanger.cpp.
References MSVehicle::getBestLanesContinuation(), MSLane::getLastVehicle(), MSVehicleType::getLength(), MSLane::getPartialOccupator(), MSLane::getPartialOccupatorEnd(), MSVehicle::getPositionOnLane(), MSVehicle::getVehicleType(), MSLane::isLinkEnd(), MAX2(), myCandi, MSLane::succLinkSec(), SUMOReal, and veh().
Referenced by change().
00287 { 00288 // get the leading vehicle on the lane to change to 00289 MSVehicle* leader = target->lead; 00290 if (leader==0) { 00291 MSLane* targetLane = target->lane; 00292 MSVehicle *predP = targetLane->getPartialOccupator(); 00293 if (predP!=0) { 00294 return std::pair<MSVehicle *, SUMOReal>(predP, targetLane->getPartialOccupatorEnd() - veh(myCandi)->getPositionOnLane()); 00295 } 00296 const std::vector<MSLane*> &bestLaneConts = veh(myCandi)->getBestLanesContinuation(); 00297 MSLinkCont::const_iterator link = targetLane->succLinkSec(*veh(myCandi), 1, *targetLane, bestLaneConts); 00298 if (targetLane->isLinkEnd(link)) { 00299 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00300 } 00301 MSLane *nextLane = (*link)->getLane(); 00302 if (nextLane==0) { 00303 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00304 } 00305 leader = nextLane->getLastVehicle(); 00306 if (leader==0) { 00307 return std::pair<MSVehicle *, SUMOReal>(0, -1); 00308 } 00309 SUMOReal gap = 00310 leader->getPositionOnLane()-leader->getVehicleType().getLength() 00311 + 00312 (myCandi->lane->getLength()-veh(myCandi)->getPositionOnLane()); 00313 return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap)); 00314 } else { 00315 MSVehicle *candi = veh(myCandi); 00316 SUMOReal gap = leader->getPositionOnLane()-leader->getVehicleType().getLength()-candi->getPositionOnLane(); 00317 return std::pair<MSVehicle * const, SUMOReal>(leader, MAX2((SUMOReal) 0, gap)); 00318 } 00319 }
| void MSLaneChanger::initChanger | ( | ) | [protected] |
Initialize the changer before looping over all vehicles.
Definition at line 87 of file MSLaneChanger.cpp.
References myChanger.
Referenced by laneChange().
00087 { 00088 // Prepare myChanger with a safe state. 00089 for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { 00090 ce->lead = 0; 00091 ce->hoppedVeh = 0; 00092 ce->lastBlocked = 0; 00093 ce->dens = 0; 00094 00095 MSLane::VehCont& vehicles = ce->lane->myVehicles; 00096 if (vehicles.empty()) { 00097 ce->veh = vehicles.rend(); 00098 ce->follow = 0; 00099 continue; 00100 } 00101 ce->veh = vehicles.rbegin(); 00102 if (vehicles.size() == 1) { 00103 ce->follow = 0; 00104 continue; 00105 } 00106 ce->follow = *(vehicles.rbegin() + 1); 00107 } 00108 }
| void MSLaneChanger::laneChange | ( | SUMOTime | t | ) |
Start lane-change-process for all vehicles on the edge'e lanes.
Definition at line 71 of file MSLaneChanger.cpp.
References change(), initChanger(), updateChanger(), updateLanes(), and vehInChanger().
Referenced by MSEdge::changeLanes().
00071 { 00072 // This is what happens in one timestep. After initialization of the 00073 // changer, each vehicle will try to change. After that the changer 00074 // nedds an update to prevent multiple changes of one vehicle. 00075 // Finally, the change-result has to be given back to the lanes. 00076 initChanger(); 00077 while (vehInChanger()) { 00078 00079 bool haveChanged = change(); 00080 updateChanger(haveChanged); 00081 } 00082 updateLanes(t); 00083 }
| MSLaneChanger& MSLaneChanger::operator= | ( | const MSLaneChanger & | ) | [private] |
Assignment operator.
Returns true if candidate overlaps with a vehicle, that already changed the lane.
Definition at line 179 of file MSLaneChanger.h.
References myCandi, MSVehicle::overlap(), and veh().
Referenced by change2left(), and change2right().
00179 { 00180 MSVehicle *v1 = target->hoppedVeh; 00181 MSVehicle *v2 = veh(myCandi); 00182 if (v1!=0 && v2!=0) { 00183 return MSVehicle::overlap(v1, v2); 00184 } 00185 return false; 00186 }
| void MSLaneChanger::setIsSafeChange | ( | const std::pair< MSVehicle *const, SUMOReal > & | neighLead, | |
| const std::pair< MSVehicle *const, SUMOReal > & | neighFollow, | |||
| const ChangerIt & | target, | |||
| int & | blocked | |||
| ) | const throw () [protected] |
Definition at line 584 of file MSLaneChanger.cpp.
References MSVehicle::getCarFollowModel(), MSLane::getMaxSpeed(), MSVehicle::getSpeed(), MSCFModel::hasSafeGap(), LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, myCandi, and veh().
Referenced by change2left(), and change2right().
00586 { 00587 // Check if candidate's change to target-lane will be safe, i.e. is there 00588 // enough back-gap to the neighFollow to drive collision-free (if there is 00589 // no neighFollow, keep a safe-gap to the beginning of the lane) and is 00590 // there enough gap for the candidate to neighLead to drive collision- 00591 // free (if there is no neighLead, be sure that candidate is able to slow- 00592 // down towards the lane end). 00593 MSVehicle* vehicle = veh(myCandi); 00594 00595 // check back gap 00596 if ((blocked&LCA_BLOCKEDBY_FOLLOWER)==0) { 00597 if (neighFollow.first!=0) { 00598 MSLane* targetLane = target->lane; 00599 // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren 00600 if (!neighFollow.first->getCarFollowModel().hasSafeGap(neighFollow.first->getSpeed(), neighFollow.second, vehicle->getSpeed(), targetLane->getMaxSpeed())) { 00601 blocked |= LCA_BLOCKEDBY_FOLLOWER; 00602 } 00603 } 00604 } 00605 00606 // check front gap 00607 if ((blocked&LCA_BLOCKEDBY_LEADER)==0) { 00608 if (neighLead.first!=0) { 00609 MSLane* targetLane = target->lane; 00610 // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren 00611 if (!vehicle->getCarFollowModel().hasSafeGap(vehicle->getSpeed(), neighLead.second, neighLead.first->getSpeed(), targetLane->getMaxSpeed())) { 00612 blocked |= LCA_BLOCKEDBY_LEADER; 00613 } 00614 } 00615 } 00616 }
| void MSLaneChanger::setOverlap | ( | const std::pair< MSVehicle *const, SUMOReal > & | neighLead, | |
| const std::pair< MSVehicle *const, SUMOReal > & | neighFollow, | |||
| int & | blocked | |||
| ) | const throw () [protected] |
Definition at line 565 of file MSLaneChanger.cpp.
References LCA_BLOCKEDBY_FOLLOWER, LCA_BLOCKEDBY_LEADER, and LCA_OVERLAPPING.
Referenced by change2left(), and change2right().
00567 { 00568 // check the follower only if not already known that... 00569 if ((blocked&LCA_BLOCKEDBY_FOLLOWER)==0) { 00570 if (rFollow.first!=0&&rFollow.second<0) { 00571 blocked |= (LCA_BLOCKEDBY_FOLLOWER|LCA_OVERLAPPING); 00572 } 00573 } 00574 // check the leader only if not already known that... 00575 if ((blocked&LCA_BLOCKEDBY_LEADER)==0) { 00576 if (rLead.first!=0&&rLead.second<0) { 00577 blocked |= (LCA_BLOCKEDBY_LEADER|LCA_OVERLAPPING); 00578 } 00579 } 00580 }
| void MSLaneChanger::updateChanger | ( | bool | vehHasChanged | ) | [protected] |
After the possible change, update the changer.
Definition at line 433 of file MSLaneChanger.cpp.
References myCandi, and veh().
Referenced by laneChange().
00433 { 00434 assert(myCandi->veh != myCandi->lane->myVehicles.rend()); 00435 00436 // "Push" the vehicles to the back, i.e. follower becomes vehicle, 00437 // vehicle becomes leader, and leader becomes predecessor of vehicle, 00438 // if it exists. 00439 if (!vehHasChanged) { 00440 myCandi->lead = veh(myCandi); 00441 } 00442 myCandi->veh = myCandi->veh + 1; 00443 00444 if (veh(myCandi) == 0) { 00445 assert(myCandi->follow == 0); 00446 // leader already 0. 00447 return; 00448 } 00449 if (myCandi->veh + 1 == myCandi->lane->myVehicles.rend()) { 00450 myCandi->follow = 0; 00451 } else { 00452 myCandi->follow = *(myCandi->veh + 1) ; 00453 } 00454 return; 00455 }
| void MSLaneChanger::updateLanes | ( | SUMOTime | t | ) | [protected] |
During lane-change a temporary vehicle container is filled within the lanes (bad pratice to modify foreign members, I know). Swap this container with the real one.
Definition at line 459 of file MSLaneChanger.cpp.
References myChanger.
Referenced by laneChange().
00459 { 00460 00461 // Update the lane's vehicle-container. 00462 // First: it is bad style to change other classes members, but for 00463 // this release, other attempts were too time-consuming. In a next 00464 // release we will change from this lane-centered design to a vehicle- 00465 // centered. This will solve many problems. 00466 // Second: this swap would be faster if vehicle-containers would have 00467 // been pointers, but then I had to change too much of the MSLane code. 00468 for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { 00469 00470 ce->lane->swapAfterLaneChange(t); 00471 } 00472 }
| MSVehicle* MSLaneChanger::veh | ( | ConstChangerIt | ce | ) | const throw () [inline, protected] |
Returns a pointer to the changer-element-iterator vehicle, or 0 if there is none.
Definition at line 115 of file MSLaneChanger.h.
Referenced by advan2left(), advan2right(), change(), change2left(), change2right(), findCandidate(), getRealFollower(), getRealLeader(), getRealThisLeader(), overlapWithHopped(), setIsSafeChange(), updateChanger(), and vehInChanger().
00115 { 00116 // If ce has a valid vehicle, return it. Otherwise return 0. 00117 if (ce->veh != ce->lane->myVehicles.rend()) { 00118 return *(ce->veh); 00119 } 00120 return 0; 00121 }
| bool MSLaneChanger::vehInChanger | ( | ) | const throw () [inline, protected] |
Check if there is a single change-candidate in the changer. Returns true if there is one.
Definition at line 102 of file MSLaneChanger.h.
References myChanger, and veh().
Referenced by laneChange().
00102 { 00103 // If there is at least one valid vehicle under the veh's in myChanger 00104 // return true. 00105 for (ConstChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) { 00106 if (veh(ce) != 0) { 00107 return true; 00108 } 00109 } 00110 return false; 00111 }
ChangerIt MSLaneChanger::myCandi [protected] |
Change-candidate. Last of the vehicles in changer. Only this one will try to change. Every vehicle on the edge will be a candidate once in the change-process.
Definition at line 205 of file MSLaneChanger.h.
Referenced by advan2left(), advan2right(), change(), change2left(), change2right(), getRealFollower(), getRealLeader(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), getRealThisLeader(), overlapWithHopped(), setIsSafeChange(), and updateChanger().
Changer MSLaneChanger::myChanger [protected] |
Container for ChangeElemements, one for every lane in the edge.
Definition at line 200 of file MSLaneChanger.h.
Referenced by change(), change2left(), change2right(), findCandidate(), getRealLeftFollower(), getRealLeftLeader(), getRealRightFollower(), getRealRightLeader(), initChanger(), MSLaneChanger(), updateLanes(), and vehInChanger().
1.5.6