SUMO - Simulation of Urban MObility

MSVehicle.cpp

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