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