|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Representation of a vehicle in the micro simulation 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 // =========================================================================== 00021 // included modules 00022 // =========================================================================== 00023 #ifdef _MSC_VER 00024 #include <windows_config.h> 00025 #else 00026 #include <config.h> 00027 #endif 00028 00029 #include "MSLane.h" 00030 #include "MSVehicle.h" 00031 #include "MSEdge.h" 00032 #include "MSVehicleType.h" 00033 #include "MSNet.h" 00034 #include "MSRoute.h" 00035 #include "MSLinkCont.h" 00036 #include <utils/common/StringUtils.h> 00037 #include <utils/common/StdDefs.h> 00038 #include <microsim/MSVehicleControl.h> 00039 #include <microsim/MSGlobals.h> 00040 #include <iostream> 00041 #include <cassert> 00042 #include <cmath> 00043 #include <cstdlib> 00044 #include <algorithm> 00045 #include <map> 00046 #include "MSMoveReminder.h" 00047 #include <utils/options/OptionsCont.h> 00048 #include "MSLCM_DK2004.h" 00049 #include <utils/common/ToString.h> 00050 #include <utils/common/FileHelpers.h> 00051 #include <utils/iodevices/OutputDevice.h> 00052 #include <utils/iodevices/BinaryInputDevice.h> 00053 #include "trigger/MSBusStop.h" 00054 #include <utils/common/DijkstraRouterTT.h> 00055 #include "MSPerson.h" 00056 #include "MSPersonControl.h" 00057 #include <utils/common/RandHelper.h> 00058 #include "devices/MSDevice_Person.h" 00059 #include "MSEdgeWeightsStorage.h" 00060 #include <utils/common/HelpersHBEFA.h> 00061 #include <utils/common/HelpersHarmonoise.h> 00062 00063 #ifdef _MESSAGES 00064 #include "MSMessageEmitter.h" 00065 #endif 00066 00067 #ifdef HAVE_MESOSIM 00068 #include <mesosim/MESegment.h> 00069 #include <mesosim/MELoop.h> 00070 #include "MSGlobals.h" 00071 #endif 00072 00073 #ifdef CHECK_MEMORY_LEAKS 00074 #include <foreign/nvwa/debug_new.h> 00075 #endif // CHECK_MEMORY_LEAKS 00076 00077 //#define DEBUG_VEHICLE_GUI_SELECTION 1 00078 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00079 #include <utils/gui/div/GUIGlobalSelection.h> 00080 #include <guisim/GUIVehicle.h> 00081 #include <guisim/GUILane.h> 00082 #endif 00083 00084 #define BUS_STOP_OFFSET 0.5 00085 00086 00087 // =========================================================================== 00088 // static value definitions 00089 // =========================================================================== 00090 std::vector<MSLane*> MSVehicle::myEmptyLaneVector; 00091 00092 00093 // =========================================================================== 00094 // method definitions 00095 // =========================================================================== 00096 /* ------------------------------------------------------------------------- 00097 * methods of MSVehicle::State 00098 * ----------------------------------------------------------------------- */ 00099 MSVehicle::State::State(const State& state) { 00100 myPos = state.myPos; 00101 mySpeed = state.mySpeed; 00102 } 00103 00104 00105 MSVehicle::State& 00106 MSVehicle::State::operator=(const State& state) { 00107 myPos = state.myPos; 00108 mySpeed = state.mySpeed; 00109 return *this; 00110 } 00111 00112 00113 bool 00114 MSVehicle::State::operator!=(const State& state) { 00115 return (myPos != state.myPos || 00116 mySpeed != state.mySpeed); 00117 } 00118 00119 00120 SUMOReal 00121 MSVehicle::State::pos() const { 00122 return myPos; 00123 } 00124 00125 00126 MSVehicle::State::State(SUMOReal pos, SUMOReal speed) : 00127 myPos(pos), mySpeed(speed) {} 00128 00129 00130 /* ------------------------------------------------------------------------- 00131 * methods of MSVehicle::Influencer 00132 * ----------------------------------------------------------------------- */ 00133 MSVehicle::Influencer::Influencer() 00134 : mySpeedAdaptationStarted(true), myConsiderSafeVelocity(true), 00135 myConsiderMaxAcceleration(true), myConsiderMaxDeceleration(true) {} 00136 00137 00138 MSVehicle::Influencer::~Influencer() {} 00139 00140 00141 void 00142 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> > &speedTimeLine) { 00143 mySpeedAdaptationStarted = true; 00144 mySpeedTimeLine = speedTimeLine; 00145 } 00146 00147 00148 void 00149 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> > &laneTimeLine) { 00150 myLaneTimeLine = laneTimeLine; 00151 } 00152 00153 00154 SUMOReal 00155 MSVehicle::Influencer::influenceSpeed(SUMOTime currentTime, SUMOReal speed, SUMOReal vSafe, SUMOReal vMin, SUMOReal vMax) { 00156 // keep original speed 00157 myOriginalSpeed = speed; 00158 // remove leading commands which are no longer valid 00159 while (mySpeedTimeLine.size()==1 || (mySpeedTimeLine.size()>1&¤tTime>mySpeedTimeLine[1].first)) { 00160 mySpeedTimeLine.erase(mySpeedTimeLine.begin()); 00161 } 00162 // do nothing if the time line does not apply for the current time 00163 if (mySpeedTimeLine.size()<2||currentTime<mySpeedTimeLine[0].first) { 00164 return speed; 00165 } 00166 // compute and set new speed 00167 if (!mySpeedAdaptationStarted) { 00168 mySpeedTimeLine[0].second = speed; 00169 mySpeedAdaptationStarted = true; 00170 } 00171 currentTime += DELTA_T; 00172 const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first); 00173 speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second-mySpeedTimeLine[1].second) * td; 00174 if (myConsiderSafeVelocity) { 00175 speed = MIN2(speed, vSafe); 00176 } 00177 if (myConsiderMaxAcceleration) { 00178 speed = MIN2(speed, vMax); 00179 } 00180 if (myConsiderMaxDeceleration) { 00181 speed = MAX2(speed, vMin); 00182 } 00183 return speed; 00184 } 00185 00186 00187 MSVehicle::ChangeRequest 00188 MSVehicle::Influencer::checkForLaneChanges(SUMOTime currentTime, const MSEdge& currentEdge, unsigned int currentLaneIndex) { 00189 // remove leading commands which are no longer valid 00190 while (myLaneTimeLine.size()==1 || (myLaneTimeLine.size()>1&¤tTime>myLaneTimeLine[1].first)) { 00191 myLaneTimeLine.erase(myLaneTimeLine.begin()); 00192 } 00193 // do nothing if the time line does not apply for the current time 00194 if (myLaneTimeLine.size()<2||currentTime<myLaneTimeLine[0].first) { 00195 return REQUEST_NONE; 00196 } 00197 unsigned int destinationLaneIndex = myLaneTimeLine[1].second; 00198 if ((unsigned int)currentEdge.getLanes().size() <= destinationLaneIndex) { 00199 return REQUEST_NONE; 00200 } 00201 if (currentLaneIndex > destinationLaneIndex) { 00202 return REQUEST_RIGHT; 00203 } else if (currentLaneIndex < destinationLaneIndex) { 00204 return REQUEST_LEFT; 00205 } else { 00206 return REQUEST_HOLD; 00207 } 00208 } 00209 00210 00211 void 00212 MSVehicle::Influencer::setConsiderSafeVelocity(bool value) { 00213 myConsiderSafeVelocity = value; 00214 } 00215 00216 00217 void 00218 MSVehicle::Influencer::setConsiderMaxAcceleration(bool value) { 00219 myConsiderMaxAcceleration = value; 00220 } 00221 00222 00223 void 00224 MSVehicle::Influencer::setConsiderMaxDeceleration(bool value) { 00225 myConsiderMaxDeceleration = value; 00226 } 00227 00228 00229 00230 /* ------------------------------------------------------------------------- 00231 * MSVehicle-methods 00232 * ----------------------------------------------------------------------- */ 00233 MSVehicle::~MSVehicle() throw() { 00234 delete myLaneChangeModel; 00235 // other 00236 delete myEdgeWeights; 00237 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) { 00238 (*i)->resetPartialOccupation(this); 00239 } 00240 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) { 00241 if ((*i).myLink!=0) { 00242 (*i).myLink->removeApproaching(this); 00243 } 00244 } 00245 myFurtherLanes.clear(); 00246 // 00247 if (myType->amVehicleSpecific()) { 00248 delete myType; 00249 } 00250 } 00251 00252 00253 MSVehicle::MSVehicle(SUMOVehicleParameter* pars, 00254 const MSRoute* route, 00255 const MSVehicleType* type, 00256 int /*vehicleIndex*/) throw(ProcessError) : 00257 MSBaseVehicle(pars, route, type), 00258 myLastLaneChangeOffset(0), 00259 myWaitingTime(0), 00260 myState(0, 0), // 00261 myLane(0), 00262 myLastBestLanesEdge(0), 00263 myPersonDevice(0), 00264 myPreDawdleAcceleration(0), 00265 mySignals(0), 00266 myAmOnNet(false), 00267 myAmRegisteredAsWaitingForPerson(false), 00268 myEdgeWeights(0), 00269 myHaveToWaitOnNextLink(false) 00270 #ifndef NO_TRACI 00271 ,myInfluencer(0) 00272 #endif 00273 { 00274 for (std::vector<SUMOVehicleParameter::Stop>::iterator i=pars->stops.begin(); i!=pars->stops.end(); ++i) { 00275 if (!addStop(*i)) { 00276 throw ProcessError("Stop for vehicle '" + pars->id + 00277 "' on lane '" + i->lane + "' is not downstream the current route."); 00278 } 00279 } 00280 for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i=route->getStops().begin(); i!=route->getStops().end(); ++i) { 00281 if (!addStop(*i)) { 00282 throw ProcessError("Stop for vehicle '" + pars->id + 00283 "' on lane '" + i->lane + "' is not downstream the current route."); 00284 } 00285 } 00286 const MSLane* const depLane = (*myCurrEdge)->getDepartLane(*this); 00287 if (depLane == 0) { 00288 throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'."); 00289 } 00290 if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > depLane->getMaxSpeed()) { 00291 throw ProcessError("Departure speed for vehicle '" + pars->id + 00292 "' is too high for the departure lane '" + depLane->getID() + "'."); 00293 } 00294 #ifdef _MESSAGES 00295 myLCMsgEmitter = MSNet::getInstance()->getMsgEmitter("lanechange"); 00296 myBMsgEmitter = MSNet::getInstance()->getMsgEmitter("break"); 00297 myHBMsgEmitter = MSNet::getInstance()->getMsgEmitter("heartbeat"); 00298 #endif 00299 myLaneChangeModel = new MSLCM_DK2004(*this); 00300 myCFVariables = type->getCarFollowModel().createVehicleVariables(); 00301 } 00302 00303 00304 void 00305 MSVehicle::onRemovalFromNet(const MSMoveReminder::Notification reason) throw() { 00306 workOnMoveReminders(myState.myPos - SPEED2DIST(myState.mySpeed), myState.myPos, myState.mySpeed); 00307 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) { 00308 if ((*i).myLink!=0) { 00309 (*i).myLink->removeApproaching(this); 00310 } 00311 } 00312 leaveLane(reason); 00313 } 00314 00315 00316 // ------------ interaction with the route 00317 bool 00318 MSVehicle::ends() const throw() { 00319 return myCurrEdge==myRoute->end()-1 && myState.myPos > myArrivalPos - POSITION_EPS; 00320 } 00321 00322 00323 bool 00324 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit) throw() { 00325 const MSEdgeVector& edges = newRoute->getEdges(); 00326 // assert the vehicle may continue (must not be "teleported" or whatever to another position) 00327 if (!onInit && !newRoute->contains(*myCurrEdge)) { 00328 return false; 00329 } 00330 00331 // rebuild in-vehicle route information 00332 if (onInit) { 00333 myCurrEdge = newRoute->begin(); 00334 } else { 00335 myCurrEdge = find(edges.begin(), edges.end(), *myCurrEdge); 00336 } 00337 // check whether the old route may be deleted (is not used by anyone else) 00338 newRoute->addReference(); 00339 myRoute->release(); 00340 // assign new route 00341 myRoute = newRoute; 00342 myLastBestLanesEdge = 0; 00343 // update arrival definition 00344 calculateArrivalPos(); 00345 // save information that the vehicle was rerouted 00346 myNumberReroutes++; 00347 MSNet::getInstance()->informVehicleStateListener(this, MSNet::VEHICLE_STATE_NEWROUTE); 00348 // recheck stops 00349 for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) { 00350 if (find(edges.begin(), edges.end(), &iter->lane->getEdge())==edges.end()) { 00351 iter = myStops.erase(iter); 00352 } else { 00353 iter->edge = find(edges.begin(), edges.end(), &iter->lane->getEdge()); 00354 ++iter; 00355 } 00356 } 00357 return true; 00358 } 00359 00360 00361 bool 00362 MSVehicle::willPass(const MSEdge* const edge) const throw() { 00363 return find(myCurrEdge, myRoute->end(), edge)!=myRoute->end(); 00364 } 00365 00366 00367 MSEdgeWeightsStorage& 00368 MSVehicle::getWeightsStorage() throw() { 00369 if (myEdgeWeights==0) { 00370 myEdgeWeights = new MSEdgeWeightsStorage(); 00371 } 00372 return *myEdgeWeights; 00373 } 00374 00375 00376 // ------------ Interaction with move reminders 00377 void 00378 MSVehicle::workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed) throw() { 00379 // This erasure-idiom works for all stl-sequence-containers 00380 // See Meyers: Effective STL, Item 9 00381 for (MoveReminderCont::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) { 00382 if (!rem->first->notifyMove(*this, oldPos+rem->second, newPos+rem->second, newSpeed)) { 00383 rem = myMoveReminders.erase(rem); 00384 } else { 00385 ++rem; 00386 } 00387 } 00388 } 00389 00390 00391 void 00392 MSVehicle::adaptLaneEntering2MoveReminder(const MSLane& enteredLane) throw() { 00393 // save the old work reminders, patching the position information 00394 // add the information about the new offset to the old lane reminders 00395 const SUMOReal oldLaneLength = myLane->getLength(); 00396 for (MoveReminderCont::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end(); ++rem) { 00397 rem->second += oldLaneLength; 00398 } 00399 for (std::vector< MSMoveReminder* >::const_iterator rem=enteredLane.getMoveReminders().begin(); rem!=enteredLane.getMoveReminders().end(); ++rem) { 00400 addReminder(*rem); 00401 } 00402 } 00403 00404 00405 // ------------ Other getter methods 00406 Position 00407 MSVehicle::getPosition() const throw() { 00408 if (myLane==0) { 00409 return Position(-1000, -1000); 00410 } 00411 return myLane->getShape().positionAtLengthPosition(myState.pos()); 00412 } 00413 00414 00415 SUMOReal 00416 MSVehicle::getAngle() const throw() { 00417 Position p1 = myLane->getShape().positionAtLengthPosition(myState.pos()); 00418 Position p2 = myFurtherLanes.size()>0 00419 ? myFurtherLanes.front()->getShape().positionAtLengthPosition(myFurtherLanes.front()->getPartialOccupatorEnd()) 00420 : myLane->getShape().positionAtLengthPosition(myState.pos()-myType->getLengthWithGap()); 00421 if (p1!=p2) { 00422 return atan2(p1.x()-p2.x(), p2.y()-p1.y())*180./PI; 00423 } else { 00424 return -myLane->getShape().rotationDegreeAtLengthPosition(getPositionOnLane()); 00425 } 00426 } 00427 00428 00429 // ------------ 00430 bool 00431 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, SUMOTime untilOffset) throw() { 00432 Stop stop; 00433 stop.lane = MSLane::dictionary(stopPar.lane); 00434 stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop); 00435 stop.startPos = stopPar.startPos; 00436 stop.endPos = stopPar.endPos; 00437 stop.duration = stopPar.duration; 00438 stop.until = stopPar.until; 00439 if (stop.until != -1) { 00440 stop.until += untilOffset; 00441 } 00442 stop.triggered = stopPar.triggered; 00443 stop.parking = stopPar.parking; 00444 stop.reached = false; 00445 if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) { 00446 return false; 00447 } 00448 stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge()); 00449 MSRouteIterator prevStopEdge = myCurrEdge; 00450 SUMOReal prevStopPos = myState.myPos; 00451 // where to insert the stop 00452 std::list<Stop>::iterator iter = myStops.begin(); 00453 if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) { 00454 if (myStops.size() > 0) { 00455 prevStopEdge = myStops.back().edge; 00456 prevStopPos = myStops.back().endPos; 00457 iter = myStops.end(); 00458 stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge()); 00459 } 00460 } else { 00461 if (stopPar.index == STOP_INDEX_FIT) { 00462 while (iter != myStops.end() && (iter->edge < stop.edge || 00463 (iter->endPos < stop.endPos && iter->edge == stop.edge))) { 00464 prevStopEdge = iter->edge; 00465 prevStopPos = iter->endPos; 00466 ++iter; 00467 } 00468 } else { 00469 int index = stopPar.index; 00470 while (index > 0) { 00471 prevStopEdge = iter->edge; 00472 prevStopPos = iter->endPos; 00473 ++iter; 00474 --index; 00475 } 00476 stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge()); 00477 } 00478 } 00479 if (stop.edge == myRoute->end() || prevStopEdge > stop.edge || prevStopEdge == stop.edge && prevStopPos > stop.endPos) { 00480 return false; 00481 } 00482 if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) { 00483 return false; 00484 } 00485 myStops.insert(iter, stop); 00486 return true; 00487 } 00488 00489 00490 bool 00491 MSVehicle::isStopped() const { 00492 return !myStops.empty() && myStops.begin()->reached; 00493 } 00494 00495 00496 bool 00497 MSVehicle::isParking() const { 00498 return isStopped() && myStops.begin()->parking; 00499 } 00500 00501 00502 SUMOReal 00503 MSVehicle::processNextStop(SUMOReal currentVelocity) throw() { 00504 if (myStops.empty()) { 00505 // no stops; pass 00506 return currentVelocity; 00507 } 00508 Stop& stop = myStops.front(); 00509 if (stop.reached) { 00510 // ok, we have already reached the next stop 00511 // any waiting persons may board now 00512 bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this); 00513 if (boarded) { 00514 // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling) 00515 stop.triggered = false; 00516 if (myAmRegisteredAsWaitingForPerson) { 00517 MSNet::getInstance()->getVehicleControl().unregisterOneWaitingForPerson(); 00518 myAmRegisteredAsWaitingForPerson = false; 00519 } 00520 } 00521 if (stop.duration<=0 && !stop.triggered) { 00522 // we have waited long enough and fulfilled any passenger-requirements 00523 if (stop.busstop!=0) { 00524 // inform bus stop about leaving it 00525 stop.busstop->leaveFrom(this); 00526 } 00527 // the current stop is no longer valid 00528 MSNet::getInstance()->getVehicleControl().removeWaiting(&myLane->getEdge(), this); 00529 myStops.pop_front(); 00530 // do not count the stopping time towards gridlock time. 00531 // Other outputs use an independent counter and are not affected. 00532 myWaitingTime = 0; 00533 // maybe the next stop is on the same edge; let's rebuild best lanes 00534 getBestLanes(true); 00535 // continue as wished... 00536 } else { 00537 // we have to wait some more time 00538 if (stop.triggered && !myAmRegisteredAsWaitingForPerson) { 00539 // we can only register after waiting for one step. otherwise we might falsely signal a deadlock 00540 MSNet::getInstance()->getVehicleControl().registerOneWaitingForPerson(); 00541 myAmRegisteredAsWaitingForPerson = true; 00542 } 00543 stop.duration -= DELTA_T; 00544 return 0; 00545 } 00546 } else { 00547 // is the next stop on the current lane? 00548 if (stop.edge==myCurrEdge) { 00549 // get the stopping position 00550 SUMOReal endPos = stop.endPos; 00551 bool busStopsMustHaveSpace = true; 00552 if (stop.busstop!=0) { 00553 // on bus stops, we have to wait for free place if they are in use... 00554 endPos = stop.busstop->getLastFreePos(); 00555 if (endPos-5.<stop.busstop->getBeginLanePosition()) { // !!! explicit offset 00556 busStopsMustHaveSpace = false; 00557 } 00558 } 00559 if (myState.pos()>=endPos-BUS_STOP_OFFSET && busStopsMustHaveSpace) { 00560 // ok, we may stop (have reached the stop) 00561 stop.reached = true; 00562 MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this); 00563 // compute stopping time 00564 if (stop.until>=0) { 00565 if (stop.duration==-1) { 00566 stop.duration = stop.until - MSNet::getInstance()->getCurrentTimeStep(); 00567 } else { 00568 stop.duration = MAX2(stop.duration, stop.until - MSNet::getInstance()->getCurrentTimeStep()); 00569 } 00570 } 00571 if (stop.busstop!=0) { 00572 // let the bus stop know the vehicle 00573 stop.busstop->enter(this, myState.pos(), myState.pos()-myType->getLengthWithGap()); 00574 } 00575 } 00576 // decelerate 00577 // !!! should not v be 0 when we have reached the stop? 00578 return getCarFollowModel().stopSpeed(this, endPos-myState.pos()); 00579 } 00580 } 00581 return currentVelocity; 00582 } 00583 00584 00585 bool 00586 MSVehicle::moveRegardingCritical(SUMOTime t, const MSLane* const lane, 00587 const MSVehicle* const pred, 00588 const MSVehicle* const neigh, 00589 SUMOReal lengthsInFront) throw() { 00590 #ifdef _MESSAGES 00591 if (myHBMsgEmitter != 0) { 00592 if (isOnRoad()) { 00593 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep(); 00594 myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y()); 00595 } 00596 } 00597 #endif 00598 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00599 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 00600 int bla = 0; 00601 } 00602 #endif 00603 // remove information about approaching links, will be reset later in this step 00604 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) { 00605 if ((*i).myLink!=0) { 00606 (*i).myLink->removeApproaching(this); 00607 } 00608 } 00609 myLFLinkLanes.clear(); 00610 // 00611 const MSCFModel& cfModel = getCarFollowModel(); 00612 SUMOReal vBeg = MIN2(cfModel.maxNextSpeed(myState.mySpeed), lane->getMaxSpeed()); 00613 // check whether the vehicle is not on an appropriate lane 00614 bool onAppropriateLane = myLane->appropriate(this); 00615 if (!onAppropriateLane) { 00616 // decelerate to lane end when yes 00617 vBeg = MIN2(cfModel.stopSpeed(this, myLane->getLength() - myState.myPos), myLane->getMaxSpeed()); 00618 } 00619 if (myCurrEdge == myRoute->end() - 1) { 00620 if (myParameter->arrivalSpeedProcedure == ARRIVAL_SPEED_GIVEN) { 00621 vBeg = MIN2(cfModel.freeSpeed(this, getSpeed(), myArrivalPos - myState.myPos, myParameter->arrivalSpeed), myLane->getMaxSpeed()); 00622 } else { 00623 vBeg = myLane->getMaxSpeed(); 00624 } 00625 } 00626 // interaction with leader 00627 if (pred!=0) { 00628 // interaction with leader if one exists on same lane 00629 SUMOReal gap = gap2pred(*pred); 00630 if (MSGlobals::gCheck4Accidents && gap < 0) { 00631 // collision occured! 00632 return true; 00633 } 00634 vBeg = MIN2(vBeg, cfModel.followSpeed(this, getSpeed(), gap2pred(*pred), pred->getSpeed(), pred->getCarFollowModel().getMaxDecel())); 00635 } else { 00636 // (potential) interaction with a vehicle extending partially into this lane 00637 MSVehicle* predP = myLane->getPartialOccupator(); 00638 if (predP!=0) { 00639 SUMOReal gap = myLane->getPartialOccupatorEnd() - myState.myPos; 00640 if (MSGlobals::gCheck4Accidents && gap < 0) { 00641 // collision occured! 00642 return true; 00643 } 00644 vBeg = MIN2(vBeg, cfModel.followSpeed(this, getSpeed(), gap, predP->getSpeed(), predP->getCarFollowModel().getMaxDecel())); 00645 } 00646 } 00647 // interaction with left-lane leader (do not overtake right) 00648 cfModel.leftVehicleVsafe(this, neigh, vBeg); 00649 // check whether the vehicle wants to stop somewhere 00650 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&lane->getEdge()) { 00651 const Stop& stop = *myStops.begin(); 00652 SUMOReal stopPos = stop.busstop==0 ? stop.endPos : stop.busstop->getLastFreePos()-POSITION_EPS; 00653 SUMOReal seen = lane->getLength() - myState.pos(); 00654 SUMOReal vsafeStop = cfModel.stopSpeed(this, seen-(lane->getLength()-stopPos)); 00655 vBeg = MIN2(vBeg, vsafeStop); 00656 } 00657 vBeg = MAX2((SUMOReal) 0, vBeg); 00658 #ifdef _DEBUG 00659 if (vBeg < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) { 00660 WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#1; is: " + toString(myState.mySpeed-vBeg) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")"); 00661 } 00662 #endif 00663 if (!onAppropriateLane) { 00664 myLFLinkLanes.push_back(DriveProcessItem(0, vBeg, vBeg, false, 0, 0, myLane->getLength()-myState.myPos)); 00665 } else { 00666 // check whether the driver wants to let someone in 00667 vsafeCriticalCont(t, vBeg); 00668 checkRewindLinkLanes(lengthsInFront); 00669 } 00670 return false; 00671 } 00672 00673 00674 bool 00675 MSVehicle::moveChecked() { 00676 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00677 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 00678 int bla = 0; 00679 } 00680 #endif 00681 // get vsafe 00682 SUMOReal vSafe = 0; 00683 myHaveToWaitOnNextLink = false; 00684 00685 assert(myLFLinkLanes.size()!=0); 00686 DriveItemVector::iterator i; 00687 bool braking = false; 00688 bool lastWasGreenCont = false; 00689 for (i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) { 00690 MSLink* link = (*i).myLink; 00691 // the vehicle must change the lane on one of the next lanes 00692 if (link!=0&&(*i).mySetRequest) { 00693 const LinkState ls = link->getState(); 00694 // vehicles should brake when running onto a yellow light if the distance allows to halt in front 00695 const bool yellow = ls==LINKSTATE_TL_YELLOW_MAJOR||ls==LINKSTATE_TL_YELLOW_MINOR; 00696 if (yellow&&(*i).myDistance>getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed)) { 00697 vSafe = (*i).myVLinkWait; 00698 braking = true; 00699 lastWasGreenCont = false; 00700 link->removeApproaching(this); 00701 break; 00702 } 00703 // 00704 const bool opened = link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, getVehicleType().getLengthWithGap()); 00705 // vehicles should decelerate when approaching a minor link 00706 if (opened&&!lastWasGreenCont&&!link->havePriority()&&(*i).myDistance>getCarFollowModel().getMaxDecel()) { 00707 vSafe = (*i).myVLinkWait; 00708 braking = true; 00709 lastWasGreenCont = false; 00710 if (ls==LINKSTATE_EQUAL) { 00711 link->removeApproaching(this); 00712 } 00713 break; // could be revalidated 00714 } 00715 // have waited; may pass if opened... 00716 if (opened) { 00717 vSafe = (*i).myVLinkPass; 00718 lastWasGreenCont = link->isCont()&&(ls==LINKSTATE_TL_GREEN_MAJOR); 00719 } else { 00720 lastWasGreenCont = false; 00721 vSafe = (*i).myVLinkWait; 00722 braking = true; 00723 if (ls==LINKSTATE_EQUAL) { 00724 link->removeApproaching(this); 00725 } 00726 break; 00727 } 00728 } else { 00729 vSafe = (*i).myVLinkWait; 00730 braking = true; 00731 break; 00732 } 00733 } 00734 00735 if (braking) { 00736 myHaveToWaitOnNextLink = true; 00737 } 00738 00739 SUMOReal vNext = getCarFollowModel().moveHelper(this, vSafe); 00740 vNext = MAX2(vNext, (SUMOReal) 0.); 00741 #ifndef NO_TRACI 00742 if (myInfluencer!=0) { 00743 SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed)); 00744 SUMOReal vMax = getVehicleType().getCarFollowModel().maxNextSpeed(myState.mySpeed); 00745 vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax); 00746 } 00747 #endif 00748 // visit waiting time 00749 if (vNext<=0.1) { 00750 myWaitingTime += DELTA_T; 00751 braking = true; 00752 } else { 00753 myWaitingTime = 0; 00754 } 00755 if (myState.mySpeed<vNext) { 00756 braking = false; 00757 } 00758 if (braking) { 00759 switchOnSignal(VEH_SIGNAL_BRAKELIGHT); 00760 } else { 00761 switchOffSignal(VEH_SIGNAL_BRAKELIGHT); 00762 } 00763 // call reminders after vNext is set 00764 SUMOReal pos = myState.myPos; 00765 vNext = MIN2(vNext, getMaxSpeed()); 00766 00767 #ifdef _MESSAGES 00768 if (myHBMsgEmitter != 0) { 00769 if (isOnRoad()) { 00770 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep(); 00771 myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y()); 00772 } 00773 } 00774 if (myBMsgEmitter!=0) { 00775 if (vNext < myState.mySpeed) { 00776 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep(); 00777 myBMsgEmitter->writeBreakEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y()); 00778 } 00779 } 00780 #endif 00781 // update position and speed 00782 myState.myPos += SPEED2DIST(vNext); 00783 myState.mySpeed = vNext; 00784 std::vector<MSLane*> passedLanes; 00785 for (std::vector<MSLane*>::reverse_iterator i=myFurtherLanes.rbegin(); i!=myFurtherLanes.rend(); ++i) { 00786 passedLanes.push_back(*i); 00787 } 00788 if (passedLanes.size()==0||passedLanes.back()!=myLane) { 00789 passedLanes.push_back(myLane); 00790 } 00791 bool moved = true; 00792 // move on lane(s) 00793 if (myState.myPos<=myLane->getLength()) { 00794 // we are staying at our lane 00795 // there is no need to go over succeeding lanes 00796 workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext); 00797 moved = false; 00798 } else { 00799 // we are moving at least to the next lane (maybe pass even more than one) 00800 if (myCurrEdge != myRoute->end() - 1) { 00801 MSLane* approachedLane = myLane; 00802 // move the vehicle forward 00803 for (i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end() && approachedLane!=0 && myState.myPos>approachedLane->getLength(); ++i) { 00804 leaveLane(MSMoveReminder::NOTIFICATION_JUNCTION); 00805 MSLink* link = (*i).myLink; 00806 // check whether the vehicle was allowed to enter lane 00807 // otherwise it is decelareted and we do not need to test for it's 00808 // approach on the following lanes when a lane changing is performed 00809 myState.myPos -= approachedLane->getLength(); 00810 assert(myState.myPos>0); 00811 // proceed to the next lane 00812 if (link!=0) { 00813 #ifdef HAVE_INTERNAL_LANES 00814 approachedLane = link->getViaLane(); 00815 if (approachedLane==0) { 00816 approachedLane = link->getLane(); 00817 } 00818 #else 00819 approachedLane = link->getLane(); 00820 #endif 00821 } else { 00822 approachedLane = 0; 00823 } 00824 if (approachedLane!=myLane&&approachedLane!=0) { 00825 enterLaneAtMove(approachedLane); 00826 myLane = approachedLane; 00827 if (approachedLane->getEdge().isVaporizing()) { 00828 break; 00829 } 00830 } 00831 passedLanes.push_back(approachedLane); 00832 } 00833 } 00834 } 00835 // clear previously set information 00836 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) { 00837 (*i)->resetPartialOccupation(this); 00838 } 00839 myFurtherLanes.clear(); 00840 if (!ends()) { 00841 if (myState.myPos-getVehicleType().getLengthWithGap()<0&&passedLanes.size()>0) { 00842 SUMOReal leftLength = getVehicleType().getLengthWithGap()-myState.myPos; 00843 std::vector<MSLane*>::reverse_iterator i=passedLanes.rbegin() + 1; 00844 while (leftLength>0&&i!=passedLanes.rend()) { 00845 myFurtherLanes.push_back(*i); 00846 leftLength -= (*i)->setPartialOccupation(this, leftLength); 00847 ++i; 00848 } 00849 } 00850 setBlinkerInformation(); 00851 } 00852 return moved; 00853 } 00854 00855 00856 SUMOReal 00857 MSVehicle::getSpaceTillLastStanding(MSLane* l, bool& foundStopped) throw() { 00858 SUMOReal lengths = 0; 00859 const MSLane::VehCont& vehs = l->getVehiclesSecure(); 00860 for (MSLane::VehCont::const_iterator i=vehs.begin(); i!=vehs.end(); ++i) { 00861 if ((*i)->getSpeed()<.1) { 00862 foundStopped = true; 00863 SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths; 00864 l->releaseVehicles(); 00865 return ret; 00866 } 00867 lengths += (*i)->getVehicleType().getLengthWithGap(); 00868 } 00869 l->releaseVehicles(); 00870 return l->getLength() - lengths; 00871 } 00872 00873 00874 void 00875 MSVehicle::checkRewindLinkLanes(SUMOReal lengthsInFront) throw() { 00876 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00877 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 00878 int bla = 0; 00879 if (MSNet::getInstance()->getCurrentTimeStep()==152000) { 00880 bla = 0; 00881 } 00882 } 00883 #endif 00884 #ifdef HAVE_INTERNAL_LANES 00885 if (MSGlobals::gUsingInternalLanes) { 00886 int removalBegin = -1; 00887 bool hadVehicle = false; 00888 SUMOReal seenSpace = -lengthsInFront; 00889 00890 std::vector<SUMOReal> availableSpace; 00891 std::vector<bool> hadVehicles; 00892 bool foundStopped = false; 00893 00894 for (unsigned int i=0; i<myLFLinkLanes.size(); ++i) { 00895 // skip unset links 00896 DriveProcessItem& item = myLFLinkLanes[i]; 00897 if (item.myLink==0||foundStopped) { 00898 availableSpace.push_back(seenSpace); 00899 hadVehicles.push_back(hadVehicle); 00900 continue; 00901 } 00902 // get the next lane, determine whether it is an internal lane 00903 MSLane* approachedLane = item.myLink->getViaLane(); 00904 if (approachedLane!=0) { 00905 if (item.myLink->isCrossing()&&item.myLink->willHaveBlockedFoe()) { 00906 seenSpace = seenSpace - approachedLane->getVehLenSum(); 00907 hadVehicle |= approachedLane->getVehicleNumber()!=0; 00908 } else { 00909 seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength(); 00910 hadVehicle |= approachedLane->getVehicleNumber()!=0; 00911 } 00912 availableSpace.push_back(seenSpace); 00913 hadVehicles.push_back(hadVehicle); 00914 continue; 00915 } 00916 approachedLane = item.myLink->getLane(); 00917 MSVehicle* last = approachedLane->getLastVehicle(); 00918 if (last==0) { 00919 last = approachedLane->getPartialOccupator(); 00920 if (last!=0) { 00921 SUMOReal m = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed())); 00922 availableSpace.push_back(m); 00923 hadVehicle = true; 00924 seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength(); 00925 if (last->myHaveToWaitOnNextLink) { 00926 foundStopped = true; 00927 } 00928 } else { 00929 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength(); 00930 // availableSpace.push_back(seenSpace); 00931 availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped)); 00932 if (!foundStopped) { 00933 seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength(); 00934 } else { 00935 seenSpace = availableSpace.back(); 00936 } 00937 } 00938 } else { 00939 if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) { 00940 SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed()); 00941 SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed()*last->getCarFollowModel().getHeadwayTime(); 00942 SUMOReal m = MAX2(seenSpace, seenSpace + lastGap); 00943 availableSpace.push_back(m); 00944 seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength(); 00945 } else { 00946 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength(); 00947 // availableSpace.push_back(seenSpace); 00948 availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped)); 00949 if (!foundStopped) { 00950 seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength(); 00951 } else { 00952 seenSpace = availableSpace.back(); 00953 } 00954 } 00955 if (last->myHaveToWaitOnNextLink) { 00956 foundStopped = true; 00957 } 00958 hadVehicle = true; 00959 } 00960 hadVehicles.push_back(hadVehicle); 00961 } 00962 #ifdef DEBUG_VEHICLE_GUI_SELECTION 00963 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 00964 int bla = 0; 00965 } 00966 #endif 00967 SUMOTime t = MSNet::getInstance()->getCurrentTimeStep(); 00968 for (int i= (int)(myLFLinkLanes.size()-1); i>0; --i) { 00969 DriveProcessItem& item = myLFLinkLanes[i-1]; 00970 bool opened = item.myLink!=0&&item.myLink->opened(t, .1, getVehicleType().getLengthWithGap()); 00971 bool check1 = item.myLink==0||item.myLink->isCont()||!hadVehicles[i]; 00972 bool allowsContinuation = check1||opened; 00973 if (!opened&&item.myLink!=0) { 00974 if (i>1) { 00975 DriveProcessItem& item2 = myLFLinkLanes[i-2]; 00976 if (item2.myLink!=0&&item2.myLink->isCont()) { 00977 allowsContinuation = true; 00978 } 00979 } 00980 } 00981 if (allowsContinuation) { 00982 availableSpace[i-1] = availableSpace[i]; 00983 } 00984 } 00985 00986 for (unsigned int i=0; hadVehicle&&i<myLFLinkLanes.size()&&removalBegin<0; ++i) { 00987 // skip unset links 00988 DriveProcessItem& item = myLFLinkLanes[i]; 00989 if (item.myLink==0) { 00990 continue; 00991 } 00992 /* 00993 SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime))); 00994 if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) { 00995 removalBegin = lastLinkToInternal; 00996 } 00997 */ 00998 00999 SUMOReal leftSpace = availableSpace[i]-getVehicleType().getLengthWithGap(); 01000 if (leftSpace<0&&item.myLink->willHaveBlockedFoe()) { 01001 SUMOReal impatienceCorrection = 0; 01002 /* 01003 if(item.myLink->getState()==LINKSTATE_MINOR) { 01004 impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime)); 01005 } 01006 */ 01007 if (leftSpace<-impatienceCorrection/10.) { 01008 removalBegin = i; 01009 } 01010 //removalBegin = i; 01011 } 01012 } 01013 if (removalBegin!=-1&&!(removalBegin==0&&myLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL)) { 01014 while (removalBegin< (int)(myLFLinkLanes.size())) { 01015 myLFLinkLanes[removalBegin].myVLinkPass = myLFLinkLanes[removalBegin].myVLinkWait; 01016 myLFLinkLanes[removalBegin].mySetRequest = false; 01017 ++removalBegin; 01018 } 01019 } 01020 } 01021 #endif 01022 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) { 01023 if ((*i).myLink!=0) { 01024 (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).mySetRequest); 01025 } 01026 } 01027 } 01028 01029 01030 01031 void 01032 MSVehicle::vsafeCriticalCont(SUMOTime t, SUMOReal boundVSafe) { 01033 if (myInfluencer!=0) { 01034 SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed)); 01035 SUMOReal vMax = getVehicleType().getCarFollowModel().maxNextSpeed(myState.mySpeed); 01036 boundVSafe = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), boundVSafe, boundVSafe, vMin, vMax); 01037 } 01038 #ifdef DEBUG_VEHICLE_GUI_SELECTION 01039 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 01040 int bla = 0; 01041 } 01042 #endif 01043 const MSCFModel& cfModel = getCarFollowModel(); 01044 // the vehicle may have just to look into the next lane 01045 // compute this information and use it only once in the next loop 01046 SUMOReal seen = myLane->getLength() - myState.myPos; 01047 SUMOReal seenNonInternal = 0; 01048 // 01049 if (this!=myLane->getFirstVehicle() && seen - cfModel.brakeGap(myState.mySpeed) > 0 && seen - SPEED2DIST(boundVSafe) - ACCEL2DIST(cfModel.getMaxAccel()) > 0) { 01050 // not "reaching critical" 01051 myLFLinkLanes.push_back(DriveProcessItem(0, boundVSafe, boundVSafe, false, 0, 0, seen)); 01052 return; 01053 } 01054 01055 MSLane* nextLane = myLane; 01056 // compute the way the vehicle would drive if it would use the current speed and then 01057 // decelerate 01058 SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed); 01059 SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV); 01060 SUMOReal vLinkPass = boundVSafe; 01061 SUMOReal vLinkWait = vLinkPass; 01062 const std::vector<MSLane*> &bestLaneConts = getBestLanesContinuation(); 01063 #ifdef HAVE_INTERNAL_LANES 01064 bool hadNonInternal = false; 01065 #else 01066 bool hadNonInternal = true; 01067 #endif 01068 01069 unsigned int view = 1; 01070 // loop over following lanes 01071 while (true) { 01072 // process stops 01073 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&nextLane->getEdge()) { 01074 SUMOReal vsafeStop = cfModel.stopSpeed(this, seen-(nextLane->getLength()-myStops.begin()->endPos)); 01075 vLinkPass = MIN2(vLinkPass, vsafeStop); 01076 vLinkWait = MIN2(vLinkWait, vsafeStop); 01077 } 01078 01079 // get the next link used 01080 MSLinkCont::const_iterator link = myLane->succLinkSec(*this, view, *nextLane, bestLaneConts); 01081 01082 // check whether the lane is a dead end 01083 // (should be valid only on further loop iterations 01084 if (nextLane->isLinkEnd(link)) { 01085 SUMOReal laneEndVSafe = cfModel.stopSpeed(this, seen); 01086 if (myCurrEdge + view == myRoute->end()) { 01087 if (myParameter->arrivalSpeedProcedure == ARRIVAL_SPEED_GIVEN) { 01088 laneEndVSafe = cfModel.freeSpeed(this, getSpeed(), seen, myParameter->arrivalSpeed); 01089 } else { 01090 laneEndVSafe = vLinkPass; 01091 } 01092 } 01093 // the vehicle will not drive further 01094 assert(MIN2(vLinkPass, laneEndVSafe) >= cfModel.getSpeedAfterMaxDecel(myState.mySpeed)); 01095 myLFLinkLanes.push_back(DriveProcessItem(0, MIN2(vLinkPass, laneEndVSafe), MIN2(vLinkPass, laneEndVSafe), false, 0, 0, seen)); 01096 return; 01097 } 01098 // the link was passed 01099 vLinkWait = vLinkPass; 01100 01101 01102 // get the following lane 01103 #ifdef HAVE_INTERNAL_LANES 01104 nextLane = (*link)->getViaLane(); 01105 if (nextLane==0) { 01106 nextLane = (*link)->getLane(); 01107 hadNonInternal = true; 01108 view++; 01109 } 01110 #else 01111 nextLane = (*link)->getLane(); 01112 view++; 01113 #endif 01114 01115 // compute the velocity to use when the link is not blocked by other vehicles 01116 // the vehicle shall be not faster when reaching the next lane than allowed 01117 SUMOReal vmaxNextLane = MAX2(cfModel.freeSpeed(this, getSpeed(), seen, nextLane->getMaxSpeed()), nextLane->getMaxSpeed()); 01118 01119 // the vehicle shall keep a secure distance to its predecessor 01120 // (or approach the lane end if the predeccessor is too near) 01121 SUMOReal vsafePredNextLane = 100000; 01122 std::pair<MSVehicle*, SUMOReal> lastOnNext = nextLane->getLastVehicleInformation(); 01123 if (lastOnNext.first!=0) { 01124 if (seen+lastOnNext.second>=0) { 01125 vsafePredNextLane = cfModel.followSpeed(this, getSpeed(), seen+lastOnNext.second, lastOnNext.first->getSpeed(), lastOnNext.first->getCarFollowModel().getMaxDecel()); 01126 } else { 01127 vsafePredNextLane = cfModel.stopSpeed(this, seen); 01128 } 01129 } 01130 #ifdef DEBUG_VEHICLE_GUI_SELECTION 01131 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 01132 int bla = 0; 01133 } 01134 #endif 01135 // compute the velocity to use when the link may be used 01136 vLinkPass = MIN3(vLinkPass, vmaxNextLane, vsafePredNextLane); 01137 01138 // if the link may not be used (is blocked by another vehicle) then let the 01139 // vehicle decelerate until the end of the street 01140 vLinkWait = MIN3(vLinkPass, vLinkWait, cfModel.stopSpeed(this, seen)); 01141 #ifdef _DEBUG 01142 if (vLinkWait < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) { 01143 WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#2; is: " + toString(myState.mySpeed-vLinkWait) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")"); 01144 } 01145 #endif 01146 01147 // behaviour in front of not priorised intersections (waiting for priorised foe vehicles) 01148 bool setRequest = false; 01149 // process stops 01150 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&nextLane->getEdge()) { 01151 const Stop& stop = *myStops.begin(); 01152 const SUMOReal vsafeStop = stop.busstop==0 01153 ? cfModel.stopSpeed(this, seen+stop.endPos) 01154 : cfModel.stopSpeed(this, seen+stop.busstop->getLastFreePos()-POSITION_EPS); 01155 vLinkPass = MIN2(vLinkPass, vsafeStop); 01156 vLinkWait = MIN2(vLinkWait, vsafeStop); 01157 } 01158 // check whether we approach the final edge 01159 if (myCurrEdge + view == myRoute->end()) { 01160 if (myParameter->arrivalSpeedProcedure == ARRIVAL_SPEED_GIVEN) { 01161 const SUMOReal vsafe = cfModel.freeSpeed(this, getSpeed(), seen + myArrivalPos, myParameter->arrivalSpeed); 01162 vLinkPass = MIN2(vLinkPass, vsafe); 01163 vLinkWait = MIN2(vLinkWait, vsafe); 01164 } 01165 } 01166 01167 setRequest |= ((*link)->getState()!=LINKSTATE_TL_RED&&(vLinkPass>0&&dist-seen>0)); 01168 bool yellow = (*link)->getState()==LINKSTATE_TL_YELLOW_MAJOR||(*link)->getState()==LINKSTATE_TL_YELLOW_MINOR; 01169 bool red = (*link)->getState()==LINKSTATE_TL_RED; 01170 if ((yellow||red)&&seen>cfModel.brakeGap(myState.mySpeed)-SPEED2DIST(myState.mySpeed)*cfModel.getHeadwayTime()) { // !!! we should reuse brakeGap with no reaction time... 01171 vLinkPass = vLinkWait; 01172 setRequest = false; 01173 assert(vLinkWait >= cfModel.getSpeedAfterMaxDecel(myState.mySpeed)); 01174 myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t+TIME2STEPS(seen / vLinkPass), vLinkPass, seen)); 01175 } 01176 // the next condition matches the previously one used for determining the difference 01177 // between critical/non-critical vehicles. Though, one should assume that a vehicle 01178 // should want to move over an intersection even though it could brake before it!? 01179 setRequest &= dist-seen>0; 01180 #ifdef _DEBUG 01181 if (MIN2(vLinkPass, vLinkWait) < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) { 01182 WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#3; is: " + toString(myState.mySpeed-MIN2(vLinkPass, vLinkWait)) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")"); 01183 } 01184 #endif 01185 myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkPass, vLinkWait, setRequest, t + TIME2STEPS(seen / vLinkPass), vLinkPass, seen)); 01186 seen += nextLane->getLength(); 01187 seenNonInternal += nextLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL ? 0 : nextLane->getLength(); 01188 if ((vLinkPass<=0||seen>dist)&&hadNonInternal&&seenNonInternal>50) { 01189 return; 01190 } 01191 } 01192 } 01193 01194 01195 void 01196 MSVehicle::activateReminders(const MSMoveReminder::Notification reason) throw() { 01197 for (MoveReminderCont::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) { 01198 if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) { 01199 ++rem; 01200 } else { 01201 if (rem->first->notifyEnter(*this, reason)) { 01202 ++rem; 01203 } else { 01204 rem = myMoveReminders.erase(rem); 01205 } 01206 } 01207 } 01208 } 01209 01210 01211 bool 01212 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) { 01213 myAmOnNet = true; 01214 // vaporizing edge? 01215 /* 01216 if (enteredLane->getEdge().isVaporizing()) { 01217 // yep, let's do the vaporization... 01218 myLane = enteredLane; 01219 return true; 01220 } 01221 */ 01222 if (!onTeleporting) { 01223 // move mover reminder one lane further 01224 adaptLaneEntering2MoveReminder(*enteredLane); 01225 // set the entered lane as the current lane 01226 myLane = enteredLane; 01227 } 01228 01229 // internal edges are not a part of the route... 01230 if (enteredLane->getEdge().getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) { 01231 assert(&enteredLane->getEdge() == *(myCurrEdge+1)); 01232 ++myCurrEdge; 01233 } 01234 if (!onTeleporting) { 01235 // may be optimized: compute only, if the current or the next have more than one lane...!!! 01236 getBestLanes(true); 01237 activateReminders(MSMoveReminder::NOTIFICATION_JUNCTION); 01238 #ifndef NO_TRACI 01239 if (myInfluencer!=0) { 01240 myLaneChangeModel->requestLaneChange(myInfluencer->checkForLaneChanges(MSNet::getInstance()->getCurrentTimeStep(), **myCurrEdge, getLaneIndex())); 01241 } 01242 #endif 01243 } 01244 return ends(); 01245 } 01246 01247 01248 void 01249 MSVehicle::enterLaneAtLaneChange(MSLane* enteredLane) { 01250 myAmOnNet = true; 01251 #ifdef _MESSAGES 01252 if (myLCMsgEmitter!=0) { 01253 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep(); 01254 myLCMsgEmitter->writeLaneChangeEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), enteredLane, getPosition().x(), getPosition().y()); 01255 } 01256 #endif 01257 myLane = enteredLane; 01258 // switch to and activate the new lane's reminders 01259 // keep OldLaneReminders 01260 for (std::vector< MSMoveReminder* >::const_iterator rem=enteredLane->getMoveReminders().begin(); rem!=enteredLane->getMoveReminders().end(); ++rem) { 01261 addReminder(*rem); 01262 } 01263 activateReminders(MSMoveReminder::NOTIFICATION_LANE_CHANGE); 01264 SUMOReal leftLength = myState.myPos-getVehicleType().getLengthWithGap(); 01265 if (leftLength<0) { 01266 // we have to rebuild "further lanes" 01267 const MSRoute& route = getRoute(); 01268 MSRouteIterator i = myCurrEdge; 01269 MSLane* lane = myLane; 01270 while (i!=route.begin()&&leftLength>0) { 01271 const MSEdge* const prev = *(--i); 01272 const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes(); 01273 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j=incomingLanes.begin(); j!=incomingLanes.end(); ++j) { 01274 if (&(*j).lane->getEdge()==prev) { 01275 #ifdef HAVE_INTERNAL_LANES 01276 (*j).lane->setPartialOccupation(this, leftLength); 01277 #else 01278 leftLength -= (*j).length; 01279 (*j).lane->setPartialOccupation(this, leftLength); 01280 #endif 01281 leftLength -= (*j).lane->getLength(); 01282 break; 01283 } 01284 } 01285 } 01286 } 01287 #ifndef NO_TRACI 01288 // check if further changes are necessary 01289 if (myInfluencer!=0) { 01290 myLaneChangeModel->requestLaneChange(myInfluencer->checkForLaneChanges(MSNet::getInstance()->getCurrentTimeStep(), **myCurrEdge, getLaneIndex())); 01291 } 01292 #endif 01293 } 01294 01295 01296 void 01297 MSVehicle::enterLaneAtInsertion(MSLane* enteredLane, SUMOReal pos, SUMOReal speed, MSMoveReminder::Notification notification) throw(ProcessError) { 01298 myState = State(pos, speed); 01299 assert(myState.myPos >= 0); 01300 assert(myState.mySpeed >= 0); 01301 myWaitingTime = 0; 01302 myLane = enteredLane; 01303 // set and activate the new lane's reminders 01304 for (std::vector< MSMoveReminder* >::const_iterator rem=enteredLane->getMoveReminders().begin(); rem!=enteredLane->getMoveReminders().end(); ++rem) { 01305 addReminder(*rem); 01306 } 01307 activateReminders(notification); 01308 std::string msg; 01309 if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) { 01310 throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg); 01311 } 01312 myAmOnNet = true; 01313 // build the list of lanes the vehicle is lapping into 01314 SUMOReal leftLength = myType->getLengthWithGap() - pos; 01315 MSLane* clane = enteredLane; 01316 while (leftLength>0) { 01317 clane = clane->getLogicalPredecessorLane(); 01318 if (clane==0) { 01319 break; 01320 } 01321 myFurtherLanes.push_back(clane); 01322 leftLength -= (clane)->setPartialOccupation(this, leftLength); 01323 } 01324 } 01325 01326 01327 void 01328 MSVehicle::leaveLane(const MSMoveReminder::Notification reason) { 01329 for (MoveReminderCont::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) { 01330 if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) { 01331 ++rem; 01332 } else { 01333 rem = myMoveReminders.erase(rem); 01334 } 01335 } 01336 if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) { 01337 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) { 01338 (*i)->resetPartialOccupation(this); 01339 } 01340 myFurtherLanes.clear(); 01341 } 01342 if (reason>=MSMoveReminder::NOTIFICATION_TELEPORT) { 01343 myAmOnNet = false; 01344 } 01345 } 01346 01347 01348 MSAbstractLaneChangeModel& 01349 MSVehicle::getLaneChangeModel() { 01350 return *myLaneChangeModel; 01351 } 01352 01353 01354 const MSAbstractLaneChangeModel& 01355 MSVehicle::getLaneChangeModel() const { 01356 return *myLaneChangeModel; 01357 } 01358 01359 01360 const std::vector<MSVehicle::LaneQ> & 01361 MSVehicle::getBestLanes(bool forceRebuild, MSLane* startLane) const throw() { 01362 #ifdef DEBUG_VEHICLE_GUI_SELECTION 01363 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) { 01364 int bla = 0; 01365 myLastBestLanesEdge = 0; 01366 } 01367 #endif 01368 01369 if (startLane==0) { 01370 startLane = myLane; 01371 } 01372 // update occupancy and current lane index, only, if the vehicle has not moved to a new lane 01373 if (myLastBestLanesEdge==&startLane->getEdge()&&!forceRebuild) { 01374 std::vector<LaneQ> &lanes = *myBestLanes.begin(); 01375 std::vector<LaneQ>::iterator i; 01376 for (i=lanes.begin(); i!=lanes.end(); ++i) { 01377 SUMOReal nextOccupation = 0; 01378 for (std::vector<MSLane*>::const_iterator j=(*i).bestContinuations.begin()+1; j!=(*i).bestContinuations.end(); ++j) { 01379 nextOccupation += (*j)->getVehLenSum(); 01380 } 01381 (*i).nextOccupation = nextOccupation; 01382 if ((*i).lane==startLane) { 01383 myCurrentLaneInBestLanes = i; 01384 } 01385 } 01386 return *myBestLanes.begin(); 01387 } 01388 // start rebuilding 01389 myLastBestLanesEdge = &startLane->getEdge(); 01390 myBestLanes.clear(); 01391 01392 // get information about the next stop 01393 const MSEdge* nextStopEdge = 0; 01394 const MSLane* nextStopLane = 0; 01395 SUMOReal nextStopPos = 0; 01396 if (!myStops.empty()) { 01397 const Stop& nextStop = myStops.front(); 01398 nextStopLane = nextStop.lane; 01399 nextStopEdge = &nextStopLane->getEdge(); 01400 nextStopPos = nextStop.startPos; 01401 } 01402 if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) { 01403 nextStopEdge = *(myRoute->end() - 1); 01404 nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane]; 01405 nextStopPos = myArrivalPos; 01406 } 01407 01408 // go forward along the next lanes; 01409 int seen = 0; 01410 SUMOReal seenLength = 0; 01411 bool progress = true; 01412 for (MSRouteIterator ce = myCurrEdge; progress;) { 01413 std::vector<LaneQ> currentLanes; 01414 const std::vector<MSLane*> *allowed = 0; 01415 const MSEdge* nextEdge = 0; 01416 if (ce!=myRoute->end()&&ce+1!=myRoute->end()) { 01417 nextEdge = *(ce+1); 01418 allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass()); 01419 } 01420 const std::vector<MSLane*> &lanes = (*ce)->getLanes(); 01421 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) { 01422 LaneQ q; 01423 MSLane* cl = *i; 01424 q.lane = cl; 01425 q.bestContinuations.push_back(cl); 01426 q.bestLaneOffset = 0; 01427 q.length = cl->getLength(); 01428 q.allowsContinuation = allowed==0||find(allowed->begin(), allowed->end(), cl)!=allowed->end(); 01429 currentLanes.push_back(q); 01430 } 01431 // 01432 if (nextStopEdge==*ce) { 01433 progress = false; 01434 for (std::vector<LaneQ>::iterator q=currentLanes.begin(); q!=currentLanes.end(); ++q) { 01435 if (nextStopLane!=(*q).lane) { 01436 (*q).allowsContinuation = false; 01437 (*q).length = nextStopPos; 01438 } 01439 } 01440 } 01441 01442 myBestLanes.push_back(currentLanes); 01443 ++seen; 01444 seenLength += currentLanes[0].lane->getLength(); 01445 ++ce; 01446 progress &= (seen<=4 || seenLength<3000); 01447 progress &= seen<=8; 01448 progress &= ce!=myRoute->end(); 01449 /* 01450 if(progress) { 01451 progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1); 01452 } 01453 */ 01454 } 01455 01456 // we are examining the last lane explicitly 01457 if (myBestLanes.size()!=0) { 01458 SUMOReal bestLength = -1; 01459 int bestThisIndex = 0; 01460 int index = 0; 01461 std::vector<LaneQ> &last = myBestLanes.back(); 01462 for (std::vector<LaneQ>::iterator j=last.begin(); j!=last.end(); ++j, ++index) { 01463 if ((*j).length>bestLength) { 01464 bestLength = (*j).length; 01465 bestThisIndex = index; 01466 } 01467 } 01468 index = 0; 01469 for (std::vector<LaneQ>::iterator j=last.begin(); j!=last.end(); ++j, ++index) { 01470 if ((*j).length<bestLength) { 01471 (*j).bestLaneOffset = bestThisIndex - index; 01472 } 01473 } 01474 } 01475 01476 // go backward through the lanes 01477 // track back best lane and compute the best prior lane(s) 01478 for (std::vector<std::vector<LaneQ> >::reverse_iterator i=myBestLanes.rbegin()+1; i!=myBestLanes.rend(); ++i) { 01479 std::vector<LaneQ> &nextLanes = (*(i-1)); 01480 std::vector<LaneQ> &clanes = (*i); 01481 MSEdge& cE = clanes[0].lane->getEdge(); 01482 int index = 0; 01483 SUMOReal bestConnectedLength = -1; 01484 SUMOReal bestLength = -1; 01485 for (std::vector<LaneQ>::iterator j=nextLanes.begin(); j!=nextLanes.end(); ++j, ++index) { 01486 if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength<(*j).length) { 01487 bestConnectedLength = (*j).length; 01488 } 01489 if (bestLength<(*j).length) { 01490 bestLength = (*j).length; 01491 } 01492 } 01493 if (bestConnectedLength>0) { 01494 int bestThisIndex = 0; 01495 index = 0; 01496 for (std::vector<LaneQ>::iterator j=clanes.begin(); j!=clanes.end(); ++j, ++index) { 01497 LaneQ bestConnectedNext; 01498 bestConnectedNext.length = -1; 01499 if ((*j).allowsContinuation) { 01500 for (std::vector<LaneQ>::const_iterator m=nextLanes.begin(); m!=nextLanes.end(); ++m) { 01501 if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) { 01502 if (bestConnectedNext.length<(*m).length || (bestConnectedNext.length==(*m).length&&abs(bestConnectedNext.bestLaneOffset)>abs((*m).bestLaneOffset))) { 01503 bestConnectedNext = *m; 01504 } 01505 } 01506 } 01507 if (bestConnectedNext.length==bestConnectedLength&&abs(bestConnectedNext.bestLaneOffset)<2) { 01508 (*j).length += bestLength; 01509 } else { 01510 (*j).length += bestConnectedNext.length; 01511 } 01512 } 01513 if (clanes[bestThisIndex].length<(*j).length || (clanes[bestThisIndex].length==(*j).length&&abs(abs(clanes[bestThisIndex].bestLaneOffset>(*j).bestLaneOffset)))) { 01514 bestThisIndex = index; 01515 } 01516 copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations)); 01517 } 01518 01519 index = 0; 01520 for (std::vector<LaneQ>::iterator j=clanes.begin(); j!=clanes.end(); ++j, ++index) { 01521 if ((*j).length<clanes[bestThisIndex].length || ((*j).length==clanes[bestThisIndex].length&&abs((*j).bestLaneOffset)<abs(clanes[bestThisIndex].bestLaneOffset))) { 01522 (*j).bestLaneOffset = bestThisIndex - index; 01523 } else { 01524 (*j).bestLaneOffset = 0; 01525 } 01526 } 01527 01528 } else { 01529 01530 int bestThisIndex = 0; 01531 int bestNextIndex = 0; 01532 int bestDistToNeeded = (int) clanes.size(); 01533 index = 0; 01534 for (std::vector<LaneQ>::iterator j=clanes.begin(); j!=clanes.end(); ++j,++index) { 01535 if ((*j).allowsContinuation) { 01536 int nextIndex = 0; 01537 for (std::vector<LaneQ>::const_iterator m=nextLanes.begin(); m!=nextLanes.end(); ++m, ++nextIndex) { 01538 if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) { 01539 if (bestDistToNeeded>abs((*m).bestLaneOffset)) { 01540 bestDistToNeeded = abs((*m).bestLaneOffset); 01541 bestThisIndex = index; 01542 bestNextIndex = nextIndex; 01543 } 01544 } 01545 } 01546 } 01547 } 01548 clanes[bestThisIndex].length += nextLanes[bestNextIndex].length; 01549 copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations)); 01550 index = 0; 01551 for (std::vector<LaneQ>::iterator j=clanes.begin(); j!=clanes.end(); ++j, ++index) { 01552 if ((*j).length<clanes[bestThisIndex].length || ((*j).length==clanes[bestThisIndex].length&&abs((*j).bestLaneOffset)<abs(clanes[bestThisIndex].bestLaneOffset))) { 01553 (*j).bestLaneOffset = bestThisIndex - index; 01554 } else { 01555 (*j).bestLaneOffset = 0; 01556 } 01557 } 01558 01559 } 01560 01561 } 01562 01563 // update occupancy and current lane index 01564 std::vector<LaneQ> &currLanes = *myBestLanes.begin(); 01565 std::vector<LaneQ>::iterator i; 01566 for (i=currLanes.begin(); i!=currLanes.end(); ++i) { 01567 SUMOReal nextOccupation = 0; 01568 for (std::vector<MSLane*>::const_iterator j=(*i).bestContinuations.begin()+1; j!=(*i).bestContinuations.end(); ++j) { 01569 nextOccupation += (*j)->getVehLenSum(); 01570 } 01571 (*i).nextOccupation = nextOccupation; 01572 if ((*i).lane==startLane) { 01573 myCurrentLaneInBestLanes = i; 01574 } 01575 } 01576 return *myBestLanes.begin(); 01577 } 01578 01579 01580 const std::vector<MSLane*> & 01581 MSVehicle::getBestLanesContinuation() const throw() { 01582 if (myBestLanes.empty()||myBestLanes[0].empty()||myLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) { 01583 return myEmptyLaneVector; 01584 } 01585 return (*myCurrentLaneInBestLanes).bestContinuations; 01586 } 01587 01588 01589 const std::vector<MSLane*> & 01590 MSVehicle::getBestLanesContinuation(const MSLane* const l) const throw() { 01591 for (std::vector<std::vector<LaneQ> >::const_iterator i=myBestLanes.begin(); i!=myBestLanes.end(); ++i) { 01592 if ((*i).size()!=0&&(*i)[0].lane==l) { 01593 return (*i)[0].bestContinuations; 01594 } 01595 } 01596 return myEmptyLaneVector; 01597 } 01598 01599 01600 01601 SUMOReal 01602 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) { 01603 #ifdef DEBUG_VEHICLE_GUI_SELECTION 01604 SUMOReal distance = 1000000.; 01605 #else 01606 SUMOReal distance = std::numeric_limits<SUMOReal>::max(); 01607 #endif 01608 if (isOnRoad() && destEdge != NULL) { 01609 if (&myLane->getEdge() == *myCurrEdge) { 01610 // vehicle is on a normal edge 01611 distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge); 01612 } else { 01613 // vehicle is on inner junction edge 01614 distance = myLane->getLength() - getPositionOnLane(); 01615 distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge+1), destEdge); 01616 } 01617 } 01618 return distance; 01619 } 01620 01621 01622 SUMOReal 01623 MSVehicle::getHBEFA_CO2Emissions() const throw() { 01624 return HelpersHBEFA::computeCO2(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01625 } 01626 01627 01628 SUMOReal 01629 MSVehicle::getHBEFA_COEmissions() const throw() { 01630 return HelpersHBEFA::computeCO(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01631 } 01632 01633 01634 SUMOReal 01635 MSVehicle::getHBEFA_HCEmissions() const throw() { 01636 return HelpersHBEFA::computeHC(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01637 } 01638 01639 01640 SUMOReal 01641 MSVehicle::getHBEFA_NOxEmissions() const throw() { 01642 return HelpersHBEFA::computeNOx(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01643 } 01644 01645 01646 SUMOReal 01647 MSVehicle::getHBEFA_PMxEmissions() const throw() { 01648 return HelpersHBEFA::computePMx(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01649 } 01650 01651 01652 SUMOReal 01653 MSVehicle::getHBEFA_FuelConsumption() const throw() { 01654 return HelpersHBEFA::computeFuel(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01655 } 01656 01657 01658 SUMOReal 01659 MSVehicle::getHarmonoise_NoiseEmissions() const throw() { 01660 return HelpersHarmonoise::computeNoise(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration); 01661 } 01662 01663 01664 void 01665 MSVehicle::addPerson(MSPerson* person) throw() { 01666 if (myPersonDevice == 0) { 01667 myPersonDevice = MSDevice_Person::buildVehicleDevices(*this, myDevices); 01668 myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.)); 01669 } 01670 myPersonDevice->addPerson(person); 01671 if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) { 01672 myStops.front().duration = 0; 01673 } 01674 } 01675 01676 01677 void 01678 MSVehicle::setBlinkerInformation() throw() { 01679 switchOffSignal(VEH_SIGNAL_BLINKER_RIGHT|VEH_SIGNAL_BLINKER_LEFT); 01680 int state = getLaneChangeModel().getOwnState(); 01681 if ((state&LCA_LEFT)!=0) { 01682 switchOnSignal(VEH_SIGNAL_BLINKER_LEFT); 01683 } else if ((state&LCA_RIGHT)!=0) { 01684 switchOnSignal(VEH_SIGNAL_BLINKER_RIGHT); 01685 } else { 01686 const MSLane* lane = getLane(); 01687 MSLinkCont::const_iterator link = lane->succLinkSec(*this, 1, *lane, getBestLanesContinuation()); 01688 if (link!=lane->getLinkCont().end()&&lane->getLength()-getPositionOnLane()<lane->getMaxSpeed()*(SUMOReal) 7.) { 01689 switch ((*link)->getDirection()) { 01690 case LINKDIR_TURN: 01691 case LINKDIR_LEFT: 01692 case LINKDIR_PARTLEFT: 01693 switchOnSignal(VEH_SIGNAL_BLINKER_LEFT); 01694 break; 01695 case LINKDIR_RIGHT: 01696 case LINKDIR_PARTRIGHT: 01697 switchOnSignal(VEH_SIGNAL_BLINKER_RIGHT); 01698 break; 01699 default: 01700 break; 01701 } 01702 } 01703 } 01704 01705 } 01706 01707 01708 void 01709 MSVehicle::replaceVehicleType(MSVehicleType* type) throw() { 01710 if (myType->amVehicleSpecific()) { 01711 delete myType; 01712 } 01713 myType = type; 01714 } 01715 01716 unsigned int 01717 MSVehicle::getLaneIndex() const { 01718 std::vector<MSLane*>::const_iterator laneP = std::find((*myCurrEdge)->getLanes().begin(), (*myCurrEdge)->getLanes().end(), myLane); 01719 return (unsigned int) std::distance((*myCurrEdge)->getLanes().begin(), laneP); 01720 } 01721 01722 01723 #ifndef NO_TRACI 01724 bool 01725 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal /*radius*/, SUMOTime duration) { 01726 //if the stop exists update the duration 01727 for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) { 01728 if (iter->lane == lane && fabs(iter->endPos - pos) < POSITION_EPS) { 01729 if (duration == 0 && !iter->reached) { 01730 myStops.erase(iter); 01731 } else { 01732 iter->duration = duration; 01733 } 01734 return true; 01735 } 01736 } 01737 01738 SUMOVehicleParameter::Stop newStop; 01739 newStop.lane = lane->getID(); 01740 newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos); 01741 newStop.startPos = pos - POSITION_EPS; 01742 newStop.endPos = pos; 01743 newStop.duration = duration; 01744 newStop.until = -1; 01745 newStop.triggered = false; 01746 newStop.parking = false; 01747 newStop.index = STOP_INDEX_END; 01748 return addStop(newStop); 01749 } 01750 01751 01752 MSVehicle::Influencer& 01753 MSVehicle::getInfluencer() { 01754 if (myInfluencer==0) { 01755 myInfluencer = new Influencer(); 01756 } 01757 return *myInfluencer; 01758 } 01759 01760 01761 SUMOReal 01762 MSVehicle::getSpeedWithoutTraciInfluence() const { 01763 if (myInfluencer!=0) { 01764 return myInfluencer->getOriginalSpeed(); 01765 } 01766 return myState.mySpeed; 01767 } 01768 01769 01770 #endif 01771 01772 01773 /****************************************************************************/