SUMO - Simulation of Urban MObility

MSVehicle.cpp

Go to the documentation of this file.
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 /****************************************************************************/
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines