00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 "MSVehicleQuitReminded.h"
00037 #include <utils/common/StringUtils.h>
00038 #include <utils/common/StdDefs.h>
00039 #include <microsim/MSVehicleControl.h>
00040 #include <microsim/MSGlobals.h>
00041 #include <iostream>
00042 #include <cassert>
00043 #include <cmath>
00044 #include <cstdlib>
00045 #include <algorithm>
00046 #include <map>
00047 #include "MSMoveReminder.h"
00048 #include <utils/options/OptionsCont.h>
00049 #include "MSLCM_DK2004.h"
00050 #include <utils/common/ToString.h>
00051 #include <utils/common/FileHelpers.h>
00052 #include <utils/iodevices/OutputDevice.h>
00053 #include <utils/iodevices/BinaryInputDevice.h>
00054 #include "trigger/MSBusStop.h"
00055 #include <utils/common/DijkstraRouterTT.h>
00056 #include "MSPerson.h"
00057 #include <utils/common/RandHelper.h>
00058 #include "devices/MSDevice_Routing.h"
00059 #include <microsim/devices/MSDevice_HBEFA.h>
00060 #include "MSEdgeWeightsStorage.h"
00061 #include <utils/common/HelpersHBEFA.h>
00062 #include <utils/common/HelpersHarmonoise.h>
00063
00064 #ifdef _MESSAGES
00065 #include "MSMessageEmitter.h"
00066 #endif
00067
00068 #ifdef HAVE_MESOSIM
00069 #include <mesosim/MESegment.h>
00070 #include <mesosim/MELoop.h>
00071 #include "MSGlobals.h"
00072 #endif
00073
00074 #ifdef CHECK_MEMORY_LEAKS
00075 #include <foreign/nvwa/debug_new.h>
00076 #endif // CHECK_MEMORY_LEAKS
00077
00078
00079 #ifdef DEBUG_VEHICLE_GUI_SELECTION
00080 #include <utils/gui/div/GUIGlobalSelection.h>
00081 #include <guisim/GUIVehicle.h>
00082 #include <guisim/GUILane.h>
00083 #endif
00084
00085 #define BUS_STOP_OFFSET 0.5
00086
00087
00088
00089
00090
00091 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
00092
00093
00094
00095
00096
00097
00098
00099
00100 MSVehicle::State::State(const State& state) {
00101 myPos = state.myPos;
00102 mySpeed = state.mySpeed;
00103 }
00104
00105
00106 MSVehicle::State&
00107 MSVehicle::State::operator=(const State& state) {
00108 myPos = state.myPos;
00109 mySpeed = state.mySpeed;
00110 return *this;
00111 }
00112
00113
00114 bool
00115 MSVehicle::State::operator!=(const State& state) {
00116 return (myPos != state.myPos ||
00117 mySpeed != state.mySpeed);
00118 }
00119
00120
00121 SUMOReal
00122 MSVehicle::State::pos() const {
00123 return myPos;
00124 }
00125
00126
00127 MSVehicle::State::State(SUMOReal pos, SUMOReal speed) :
00128 myPos(pos), mySpeed(speed) {}
00129
00130
00131
00132
00133
00134 MSVehicle::~MSVehicle() throw() {
00135
00136 for (QuitRemindedVector::iterator i=myQuitReminded.begin(); i!=myQuitReminded.end(); ++i) {
00137 (*i)->removeOnTripEnd(this);
00138 }
00139
00140 if (!myRoute->inFurtherUse()) {
00141 MSRoute::erase(myRoute->getID());
00142 }
00143
00144 if (myPointerCORNMap.find(MSCORN::CORN_P_VEH_OLDROUTE)!=myPointerCORNMap.end()) {
00145 ReplacedRoutesVector *v = (ReplacedRoutesVector*) myPointerCORNMap[MSCORN::CORN_P_VEH_OLDROUTE];
00146 for (ReplacedRoutesVector::iterator i=v->begin(); i!=v->end(); ++i) {
00147 delete(*i).route;
00148 }
00149 delete v;
00150 }
00151 if (myPointerCORNMap.find(MSCORN::CORN_P_VEH_DEPART_INFO)!=myPointerCORNMap.end()) {
00152 DepartArrivalInformation *i = (DepartArrivalInformation*) myPointerCORNMap[MSCORN::CORN_P_VEH_DEPART_INFO];
00153 delete i;
00154 }
00155 if (myPointerCORNMap.find(MSCORN::CORN_P_VEH_ARRIVAL_INFO)!=myPointerCORNMap.end()) {
00156 DepartArrivalInformation *i = (DepartArrivalInformation*) myPointerCORNMap[MSCORN::CORN_P_VEH_ARRIVAL_INFO];
00157 delete i;
00158 }
00159
00160 delete myParameter;
00161 delete myLaneChangeModel;
00162 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
00163 delete(*dev);
00164 }
00165 myDevices.clear();
00166
00167 if (hasCORNPointerValue(MSCORN::CORN_P_VEH_PASSENGER)) {
00168 std::vector<MSPerson*> *persons = (std::vector<MSPerson*>*) myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER];
00169 for (std::vector<MSPerson*>::iterator i=persons->begin(); i!=persons->end(); ++i) {
00170 (*i)->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep());
00171 }
00172 delete persons;
00173 }
00174
00175 delete myEdgeWeights;
00176 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) {
00177 (*i)->resetPartialOccupation(this);
00178 }
00179 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) {
00180 if ((*i).myLink!=0) {
00181 (*i).myLink->removeApproaching(this);
00182 }
00183 }
00184 myFurtherLanes.clear();
00185 }
00186
00187
00188 MSVehicle::MSVehicle(SUMOVehicleParameter* pars,
00189 const MSRoute* route,
00190 const MSVehicleType* type,
00191 int vehicleIndex) throw(ProcessError) :
00192 myLastLaneChangeOffset(0),
00193 myTarget(0),
00194 myWaitingTime(0),
00195 myParameter(pars),
00196 myRoute(route),
00197 myState(0, 0),
00198 myIndividualMaxSpeed(0.0),
00199 myHasIndividualMaxSpeed(false),
00200 myReferenceSpeed(-1.0),
00201 myLane(0),
00202 myType(type),
00203 myLastBestLanesEdge(0),
00204 myCurrEdge(myRoute->begin()),
00205 myMoveReminders(0),
00206 myOldLaneMoveReminders(0),
00207 myOldLaneMoveReminderOffsets(0),
00208 myArrivalPos(pars->arrivalPos),
00209 myPreDawdleAcceleration(0),
00210 myEdgeWeights(0)
00211 #ifndef NO_TRACI
00212 ,adaptingSpeed(false),
00213 isLastAdaption(false),
00214 speedBeforeAdaption(0),
00215 speedWithoutTraciInfluence(0),
00216 timeBeforeAdaption(0),
00217 speedReduction(0),
00218 adaptDuration(0),
00219 timeBeforeLaneChange(0),
00220 laneChangeStickyTime(0),
00221 laneChangeConstraintActive(false),
00222 myDestinationLane(0)
00223 #endif
00224 {
00225 for (std::vector<SUMOVehicleParameter::Stop>::iterator i=pars->stops.begin(); i!=pars->stops.end(); ++i) {
00226 if (!addStop(*i)) {
00227 throw ProcessError("Stop for vehicle '" + pars->id +
00228 "' on lane '" + i->lane + "' is not downstream the current route.");
00229 }
00230 }
00231 for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i=route->getStops().begin(); i!=route->getStops().end(); ++i) {
00232 if (!addStop(*i)) {
00233 throw ProcessError("Stop for vehicle '" + pars->id +
00234 "' on lane '" + i->lane + "' is not downstream the current route.");
00235 }
00236 }
00237 #ifdef _MESSAGES
00238 myLCMsgEmitter = MSNet::getInstance()->getMsgEmitter("lanechange");
00239 myBMsgEmitter = MSNet::getInstance()->getMsgEmitter("break");
00240 myHBMsgEmitter = MSNet::getInstance()->getMsgEmitter("heartbeat");
00241 #endif
00242
00243 SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
00244 if (myArrivalPos < 0) {
00245 myArrivalPos += lastLaneLength;
00246 }
00247 if (myArrivalPos<0) {
00248 myArrivalPos = 0;
00249 }
00250 if (myArrivalPos>lastLaneLength) {
00251 myArrivalPos = lastLaneLength;
00252 }
00253 MSDevice_Routing::buildVehicleDevices(*this, myDevices);
00254 myLaneChangeModel = new MSLCM_DK2004(*this);
00255
00256 MSDevice_HBEFA::buildVehicleDevices(*this, myDevices);
00257
00258 if (MSCORN::wished(MSCORN::CORN_VEH_WAITINGTIME)) {
00259 myIntCORNMap[MSCORN::CORN_VEH_WAITINGTIME] = 0;
00260 }
00261 if ((*myCurrEdge)->getDepartLane(*this) == 0) {
00262 throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'");
00263 }
00264 }
00265
00266
00267
00268 void
00269 MSVehicle::onTryEmit() throw() {
00270 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
00271 (*dev)->onTryEmit();
00272 }
00273 }
00274
00275
00276 void
00277 MSVehicle::onDepart() throw() {
00278
00279 if (MSCORN::wished(MSCORN::CORN_VEH_DEPART_TIME)) {
00280 myIntCORNMap[MSCORN::CORN_VEH_DEPART_TIME] = (int) MSNet::getInstance()->getCurrentTimeStep();
00281 }
00282
00283 if (MSCORN::wished(MSCORN::CORN_VEH_DEPART_INFO)) {
00284 DepartArrivalInformation *i = new DepartArrivalInformation();
00285 i->time = MSNet::getInstance()->getCurrentTimeStep();
00286 i->lane = myLane;
00287 i->pos = myState.pos();
00288 i->speed = myState.speed();
00289 myPointerCORNMap[MSCORN::CORN_P_VEH_DEPART_INFO] = (void*) i;
00290 }
00291 if (hasCORNPointerValue(MSCORN::CORN_P_VEH_PASSENGER)) {
00292 std::vector<MSPerson*> *persons = (std::vector<MSPerson*>*) myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER];
00293 for (std::vector<MSPerson*>::iterator i=persons->begin(); i!=persons->end(); ++i) {
00294 (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep());
00295 }
00296 }
00297
00298 MSNet::getInstance()->getVehicleControl().vehicleEmitted(*this);
00299 }
00300
00301
00302 void
00303 MSVehicle::onRemovalFromNet(bool forTeleporting) throw() {
00304
00305 if (!forTeleporting && MSCORN::wished(MSCORN::CORN_VEH_ARRIVAL_INFO)) {
00306 DepartArrivalInformation *i = new DepartArrivalInformation();
00307 i->time = MSNet::getInstance()->getCurrentTimeStep();
00308 i->lane = myLane;
00309 i->pos = myState.pos();
00310 i->speed = myState.speed();
00311 myPointerCORNMap[MSCORN::CORN_P_VEH_ARRIVAL_INFO] = (void*) i;
00312 }
00313 SUMOReal pspeed = myState.mySpeed;
00314 SUMOReal pos = myState.myPos;
00315 SUMOReal oldPos = pos - SPEED2DIST(pspeed);
00316
00317 workOnMoveReminders(oldPos, pos, pspeed);
00318
00319 for (QuitRemindedVector::iterator i=myQuitReminded.begin(); i!=myQuitReminded.end(); ++i) {
00320 (*i)->removeOnTripEnd(this);
00321 }
00322 myQuitReminded.clear();
00323 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
00324 (*dev)->onRemovalFromNet();
00325 }
00326 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) {
00327 if ((*i).myLink!=0) {
00328 (*i).myLink->removeApproaching(this);
00329 }
00330 }
00331 leaveLane(true);
00332 }
00333
00334
00335
00336 const MSEdge*
00337 MSVehicle::succEdge(unsigned int nSuccs) const throw() {
00338 if (hasSuccEdge(nSuccs)) {
00339 return *(myCurrEdge + nSuccs);
00340 } else {
00341 return 0;
00342 }
00343 }
00344
00345
00346 bool
00347 MSVehicle::moveRoutePointer(const MSEdge* targetEdge) throw() {
00348
00349 if (targetEdge->isVaporizing()) {
00350
00351 setWasVaporized(false);
00352 return true;
00353 }
00354
00355 if (targetEdge->getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
00356
00357 return false;
00358 }
00359 if (MSCORN::wished(MSCORN::CORN_VEH_SAVE_EDGE_EXIT)) {
00360 if (myPointerCORNMap.find(MSCORN::CORN_P_VEH_EXIT_TIMES)==myPointerCORNMap.end()) {
00361 myPointerCORNMap[MSCORN::CORN_P_VEH_EXIT_TIMES] = new std::vector<SUMOTime>();
00362 }
00363 ((std::vector<SUMOTime>*) myPointerCORNMap[MSCORN::CORN_P_VEH_EXIT_TIMES])->push_back(MSNet::getInstance()->getCurrentTimeStep());
00364 }
00365
00366
00367
00368 MSRouteIterator edgeIt = myCurrEdge;
00369 while (*edgeIt != targetEdge) {
00370 ++edgeIt;
00371 assert(edgeIt != myRoute->end());
00372 }
00373 myCurrEdge = edgeIt;
00374
00375
00376 MSRouteIterator destination = myRoute->end() - 1;
00377 return myCurrEdge == destination && getPositionOnLane() > myArrivalPos - POSITION_EPS;
00378 }
00379
00380
00381 bool
00382 MSVehicle::ends() const throw() {
00383 return myCurrEdge==myRoute->end()-1 && myState.myPos > myArrivalPos - POSITION_EPS;
00384 }
00385
00386
00387 const MSRoute &
00388 MSVehicle::getRoute(int index) const throw() {
00389 if (index==0) {
00390 return *myRoute;
00391 }
00392 --index;
00393 std::map<MSCORN::Pointer, void*>::const_iterator i = myPointerCORNMap.find(MSCORN::CORN_P_VEH_OLDROUTE);
00394 assert(i!=myPointerCORNMap.end());
00395 const ReplacedRoutesVector * const v = (const ReplacedRoutesVector * const)(*i).second;
00396 assert((int) v->size()>index);
00397 return *((*v)[index].route);
00398 }
00399
00400
00401 bool
00402 MSVehicle::replaceRoute(const MSEdgeVector &edges, SUMOTime simTime, bool onInit) throw() {
00403
00404 if (!onInit && find(edges.begin(), edges.end(), *myCurrEdge)==edges.end()) {
00405 return false;
00406 }
00407
00408
00409
00410 std::string id = getID();
00411 if (id[0]!='!') {
00412 id = "!" + id;
00413 }
00414 if (myRoute->getID().find("!var#")!=std::string::npos) {
00415 id = myRoute->getID().substr(0, myRoute->getID().rfind("!var#")+4) + toString(myIntCORNMap[MSCORN::CORN_VEH_NUMBERROUTE] + 1);
00416 } else {
00417 id = id + "!var#1";
00418 }
00419
00420 MSRoute *newRoute = new MSRoute(id, edges, false, myRoute->getColor(), myRoute->getStops());
00421
00422 if (!MSRoute::dictionary(id, newRoute)) {
00423 delete newRoute;
00424 return false;
00425 }
00426
00427
00428 const MSEdge *currentEdge = *myCurrEdge;
00429
00430
00431 if (MSCORN::wished(MSCORN::CORN_VEH_SAVEREROUTING)) {
00432 RouteReplaceInfo rri(*myCurrEdge, simTime, new MSRoute(*myRoute));
00433 if (myPointerCORNMap.find(MSCORN::CORN_P_VEH_OLDROUTE)==myPointerCORNMap.end()) {
00434 myPointerCORNMap[MSCORN::CORN_P_VEH_OLDROUTE] = new ReplacedRoutesVector();
00435 }
00436 ((ReplacedRoutesVector*) myPointerCORNMap[MSCORN::CORN_P_VEH_OLDROUTE])->push_back(rri);
00437 }
00438
00439
00440 if (!myRoute->inFurtherUse()) {
00441 MSRoute::erase(myRoute->getID());
00442 }
00443
00444
00445 myRoute = newRoute;
00446
00447 if (onInit) {
00448 myCurrEdge = myRoute->begin();
00449 } else {
00450 myCurrEdge = myRoute->find(currentEdge);
00451 }
00452 myLastBestLanesEdge = 0;
00453
00454 myArrivalPos = myParameter->arrivalPos;
00455 SUMOReal lastLaneLength = (myRoute->getLastEdge()->getLanes())[0]->getLength();
00456 if (myArrivalPos < 0) {
00457 myArrivalPos += lastLaneLength;
00458 }
00459 if (myArrivalPos<0) {
00460 myArrivalPos = 0;
00461 }
00462 if (myArrivalPos>lastLaneLength) {
00463 myArrivalPos = lastLaneLength;
00464 }
00465
00466
00467 myIntCORNMap[MSCORN::CORN_VEH_LASTREROUTEOFFSET] = 0;
00468 myIntCORNMap[MSCORN::CORN_VEH_NUMBERROUTE] = myIntCORNMap[MSCORN::CORN_VEH_NUMBERROUTE] + 1;
00469
00470 for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
00471 if (find(edges.begin(), edges.end(), &iter->lane->getEdge())==edges.end()) {
00472 iter = myStops.erase(iter);
00473 } else {
00474 ++iter;
00475 }
00476 }
00477 return true;
00478 }
00479
00480
00481 bool
00482 MSVehicle::willPass(const MSEdge * const edge) const throw() {
00483 return find(myCurrEdge, myRoute->end(), edge)!=myRoute->end();
00484 }
00485
00486
00487 void
00488 MSVehicle::reroute(SUMOTime t, SUMOAbstractRouter<MSEdge, SUMOVehicle> &router, bool withTaz) throw() {
00489
00490 std::vector<const MSEdge*> edges;
00491 if (withTaz && MSEdge::dictionary(myParameter->fromTaz+"-source") && MSEdge::dictionary(myParameter->toTaz)) {
00492 router.compute(MSEdge::dictionary(myParameter->fromTaz+"-source"), MSEdge::dictionary(myParameter->toTaz), (const MSVehicle * const) this, t, edges);
00493 if (edges.size() >= 2) {
00494 edges.erase(edges.begin());
00495 edges.pop_back();
00496 }
00497 } else {
00498 router.compute(*myCurrEdge, myRoute->getLastEdge(), (const MSVehicle * const) this, t, edges);
00499 }
00500 if (edges.empty()) {
00501 WRITE_WARNING("No route for vehicle '" + getID() + "' found.");
00502 return;
00503 }
00504
00505 MSRouteIterator ri = myCurrEdge;
00506 std::vector<const MSEdge*>::iterator ri2 = edges.begin();
00507 while (ri!=myRoute->end()&&ri2!=edges.end()&&*ri==*ri2) {
00508 ++ri;
00509 ++ri2;
00510 }
00511 if (ri!=myRoute->end()||ri2!=edges.end()) {
00512 replaceRoute(edges, MSNet::getInstance()->getCurrentTimeStep(), withTaz);
00513 }
00514 }
00515
00516
00517 MSEdgeWeightsStorage &
00518 MSVehicle::getWeightsStorage() throw() {
00519 if (myEdgeWeights==0) {
00520 myEdgeWeights = new MSEdgeWeightsStorage();
00521 }
00522 return *myEdgeWeights;
00523 }
00524
00525
00526 bool
00527 MSVehicle::hasValidRoute(std::string &msg) const throw() {
00528 MSRouteIterator last = myRoute->end() - 1;
00529
00530 for (MSRouteIterator e=myCurrEdge; e!=last; ++e) {
00531 if ((*e)->allowedLanes(**(e+1), myType->getVehicleClass())==0) {
00532 msg = "No connection between '" + (*e)->getID() + "' and '" + (*(e+1))->getID() + "'.";
00533 return false;
00534 }
00535 }
00536 last = myRoute->end();
00537
00538 for (MSRouteIterator e=myCurrEdge; e!=last; ++e) {
00539 if ((*e)->prohibits(this)) {
00540 msg = "Edge '" + (*e)->getID() + "' prohibits.";
00541 return false;
00542 }
00543 }
00544 return true;
00545 }
00546
00547
00548
00549 int
00550 MSVehicle::getCORNIntValue(MSCORN::Function f) const throw() {
00551 return myIntCORNMap.find(f)->second;
00552 }
00553
00554
00555 void *
00556 MSVehicle::getCORNPointerValue(MSCORN::Pointer p) const throw() {
00557 return myPointerCORNMap.find(p)->second;
00558 }
00559
00560
00561 bool
00562 MSVehicle::hasCORNIntValue(MSCORN::Function f) const throw() {
00563 return myIntCORNMap.find(f)!=myIntCORNMap.end();
00564 }
00565
00566
00567 bool
00568 MSVehicle::hasCORNPointerValue(MSCORN::Pointer p) const throw() {
00569 return myPointerCORNMap.find(p)!=myPointerCORNMap.end();
00570 }
00571
00572
00573
00574
00575
00576 SUMOReal
00577 MSVehicle::getPositionOnActiveMoveReminderLane(const MSLane * const searchedLane) const throw() {
00578 if (searchedLane==myLane) {
00579 return myState.myPos;
00580 }
00581 std::vector< MSMoveReminder* >::const_iterator rem = myOldLaneMoveReminders.begin();
00582 std::vector<SUMOReal>::const_iterator off = myOldLaneMoveReminderOffsets.begin();
00583 for (; rem!=myOldLaneMoveReminders.end()&&off!=myOldLaneMoveReminderOffsets.end(); ++rem, ++off) {
00584 if ((*rem)->getLane()==searchedLane) {
00585 return (*off) + myState.myPos;
00586 }
00587 }
00588 return -1;
00589 }
00590
00591
00592 void
00593 MSVehicle::workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed) throw() {
00594
00595
00596 for (std::vector< MSMoveReminder* >::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) {
00597 if (!(*rem)->isStillActive(*this, oldPos, newPos, newSpeed)) {
00598 rem = myMoveReminders.erase(rem);
00599 } else {
00600 ++rem;
00601 }
00602 }
00603 OffsetVector::iterator off=myOldLaneMoveReminderOffsets.begin();
00604 for (std::vector< MSMoveReminder* >::iterator rem=myOldLaneMoveReminders.begin(); rem!=myOldLaneMoveReminders.end();) {
00605 SUMOReal oldLaneLength = *off;
00606 if (!(*rem)->isStillActive(*this, oldLaneLength+oldPos, oldLaneLength+newPos, newSpeed)) {
00607 rem = myOldLaneMoveReminders.erase(rem);
00608 off = myOldLaneMoveReminderOffsets.erase(off);
00609 } else {
00610 ++rem;
00611 ++off;
00612 }
00613 }
00614 }
00615
00616
00617 void
00618 MSVehicle::adaptLaneEntering2MoveReminder(const MSLane &enteredLane) throw() {
00619
00620
00621 SUMOReal oldLaneLength = myLane->getLength();
00622 OffsetVector::iterator i;
00623 for (i=myOldLaneMoveReminderOffsets.begin(); i!=myOldLaneMoveReminderOffsets.end(); ++i) {
00624 (*i) += oldLaneLength;
00625 }
00626 for (size_t j=0; j<myMoveReminders.size(); j++) {
00627 myOldLaneMoveReminderOffsets.push_back(oldLaneLength);
00628 }
00629 copy(myMoveReminders.begin(), myMoveReminders.end(), back_inserter(myOldLaneMoveReminders));
00630 assert(myOldLaneMoveReminders.size()==myOldLaneMoveReminderOffsets.size());
00631
00632 myMoveReminders = enteredLane.getMoveReminders();
00633 }
00634
00635
00636 void
00637 MSVehicle::activateReminders(bool isEmit, bool isLaneChange) throw() {
00638
00639
00640 for (std::vector< MSMoveReminder* >::iterator rem=myMoveReminders.begin(); rem!=myMoveReminders.end();) {
00641 if (!(*rem)->notifyEnter(*this, isEmit, isLaneChange)) {
00642 rem = myMoveReminders.erase(rem);
00643 } else {
00644 ++rem;
00645 }
00646 }
00647 }
00648
00649
00650
00651 bool
00652 MSVehicle::addStop(const SUMOVehicleParameter::Stop &stopPar, SUMOTime untilOffset) throw() {
00653 Stop stop;
00654 stop.lane = MSLane::dictionary(stopPar.lane);
00655 stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
00656 stop.pos = stopPar.pos;
00657 stop.duration = stopPar.duration;
00658 stop.until = stopPar.until;
00659 if (stop.until != -1) {
00660 stop.until += untilOffset;
00661 }
00662 stop.reached = false;
00663 MSRouteIterator stopEdge = myRoute->find(&stop.lane->getEdge(), myCurrEdge);
00664 if (myCurrEdge > stopEdge || (myCurrEdge == stopEdge && myState.myPos > stop.pos - getCarFollowModel().brakeGap(myState.mySpeed))) {
00665
00666 return false;
00667 }
00668
00669 std::list<Stop>::iterator iter = myStops.begin();
00670 MSRouteIterator last = myRoute->begin();
00671 if (myStops.size()>0) {
00672 last = myRoute->find(&myStops.back().lane->getEdge());
00673 last = myRoute->find(&stop.lane->getEdge(), last);
00674 if (last!=myRoute->end()) {
00675 iter = myStops.end();
00676 stopEdge = last;
00677 }
00678 }
00679 while ((iter != myStops.end()) && (myRoute->find(&iter->lane->getEdge()) <= stopEdge)) {
00680 iter++;
00681 }
00682 while ((iter != myStops.end())
00683 && (stop.pos > iter->pos)
00684 && (myRoute->find(&iter->lane->getEdge()) == stopEdge)) {
00685 iter++;
00686 }
00687 myStops.insert(iter, stop);
00688 return true;
00689 }
00690
00691
00692 bool
00693 MSVehicle::isStopped() {
00694 return !myStops.empty() && myStops.begin()->reached && myStops.begin()->duration>0;
00695 }
00696
00697
00698 SUMOReal
00699 MSVehicle::processNextStop(SUMOReal currentVelocity) throw() {
00700 if (myStops.empty()) {
00701
00702 return currentVelocity;
00703 }
00704 if (myStops.begin()->reached) {
00705
00706 if (myStops.begin()->duration==0) {
00707
00708 if (myStops.begin()->busstop!=0) {
00709
00710 myStops.begin()->busstop->leaveFrom(this);
00711 }
00712
00713 MSNet::getInstance()->getVehicleControl().removeWaiting(&myLane->getEdge(), this);
00714 if (hasCORNPointerValue(MSCORN::CORN_P_VEH_PASSENGER)) {
00715 std::vector<MSPerson*> *persons = (std::vector<MSPerson*>*) myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER];
00716 for (std::vector<MSPerson*>::iterator i=persons->begin(); i!=persons->end(); ++i) {
00717 (*i)->setDeparted(MSNet::getInstance()->getCurrentTimeStep());
00718 }
00719 }
00720 myStops.pop_front();
00721
00722 getBestLanes(true);
00723
00724 } else {
00725
00726 myStops.begin()->duration -= DELTA_T;
00727 return 0;
00728 }
00729 } else {
00730
00731 if (myStops.begin()->lane==myLane) {
00732 Stop &bstop = *myStops.begin();
00733
00734 SUMOReal endPos = bstop.pos;
00735
00736 bool busStopsMustHaveSpace = true;
00737 if (bstop.busstop!=0) {
00738
00739
00740 endPos = bstop.busstop->getLastFreePos();
00741 if (endPos-5.<bstop.busstop->getBeginLanePosition()) {
00742 busStopsMustHaveSpace = false;
00743 }
00744 }
00745
00746 if (myState.pos()>=endPos-BUS_STOP_OFFSET&&busStopsMustHaveSpace) {
00747
00748 MSNet::getInstance()->getPersonControl().checkWaiting(&myLane->getEdge(), this);
00749 MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
00750 if (hasCORNPointerValue(MSCORN::CORN_P_VEH_PASSENGER)) {
00751 std::vector<MSPerson*> *persons = (std::vector<MSPerson*>*) myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER];
00752 for (std::vector<MSPerson*>::iterator i=persons->begin(); i!=persons->end();) {
00753 if (&(*i)->getDestination() == &myLane->getEdge()) {
00754 (*i)->proceed(MSNet::getInstance(), MSNet::getInstance()->getCurrentTimeStep());
00755 i = persons->erase(i);
00756 } else {
00757 ++i;
00758 }
00759 }
00760 }
00761 bstop.reached = true;
00762
00763 if (bstop.until>=0) {
00764 if (bstop.duration==-1) {
00765 bstop.duration = bstop.until - MSNet::getInstance()->getCurrentTimeStep();
00766 } else {
00767 bstop.duration = MAX2(bstop.duration, bstop.until - MSNet::getInstance()->getCurrentTimeStep());
00768 }
00769 }
00770 if (bstop.busstop!=0) {
00771
00772 bstop.busstop->enter(this, myState.pos(), myState.pos()-myType->getLength());
00773 }
00774 }
00775
00776
00777 return getCarFollowModel().ffeS(this, endPos-myState.pos());
00778 }
00779 }
00780 return currentVelocity;
00781 }
00782
00783
00784 bool
00785 MSVehicle::moveRegardingCritical(SUMOTime t, const MSLane* const lane,
00786 const MSVehicle * const pred,
00787 const MSVehicle * const neigh,
00788 SUMOReal lengthsInFront) throw() {
00789 #ifdef _MESSAGES
00790 if (myHBMsgEmitter != 0) {
00791 if (isOnRoad()) {
00792 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep();
00793 myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
00794 }
00795 }
00796 #endif
00797 #ifdef DEBUG_VEHICLE_GUI_SELECTION
00798 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
00799 int bla = 0;
00800 }
00801 #endif
00802 myTarget = 0;
00803 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) {
00804 if ((*i).myLink!=0) {
00805 (*i).myLink->removeApproaching(this);
00806 }
00807 }
00808 myLFLinkLanes.clear();
00809 const MSCFModel &cfModel = getCarFollowModel();
00810
00811 if (!myLane->appropriate(this)) {
00812
00813 SUMOReal vWish = MIN2(cfModel.ffeS(this, myLane->getLength()-myState.myPos), myLane->getMaxSpeed());
00814 if (pred!=0) {
00815
00816 SUMOReal gap = gap2pred(*pred);
00817 if (MSGlobals::gCheck4Accidents && gap<0) {
00818
00819 return true;
00820 }
00821 vWish = MIN2(vWish, cfModel.ffeV(this, pred));
00822 } else {
00823
00824 MSVehicle *predP = myLane->getPartialOccupator();
00825 if (predP!=0) {
00826 SUMOReal gap = myLane->getPartialOccupatorEnd() - myState.myPos;
00827 if (MSGlobals::gCheck4Accidents && gap<0) {
00828
00829 return true;
00830 }
00831 vWish = MIN2(vWish, cfModel.ffeV(this, gap, predP->getSpeed()));
00832 }
00833 }
00834
00835 cfModel.leftVehicleVsafe(this, neigh, vWish);
00836
00837 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&lane->getEdge()) {
00838 SUMOReal seen = lane->getLength() - myState.pos();
00839 SUMOReal vsafeStop = cfModel.ffeS(this, seen-(lane->getLength()-myStops.begin()->pos));
00840 vWish = MIN2(vWish, vsafeStop);
00841 }
00842 vWish = MAX2((SUMOReal) 0, vWish);
00843 myLFLinkLanes.push_back(DriveProcessItem(0, vWish, vWish, false, 0, 0));
00844 } else {
00845
00846 SUMOReal vBeg = MIN2(cfModel.maxNextSpeed(myState.mySpeed), lane->getMaxSpeed());
00847 if (pred!=0) {
00848 SUMOReal gap = gap2pred(*pred);
00849 if (MSGlobals::gCheck4Accidents && gap<0) {
00850
00851 return true;
00852 }
00853 SUMOReal vSafe = cfModel.ffeV(this, gap, pred->getSpeed());
00854
00855
00856 vBeg = MIN2(vBeg, vSafe);
00857 } else {
00858
00859 MSVehicle *predP = myLane->getPartialOccupator();
00860 if (predP!=0) {
00861 SUMOReal gap = myLane->getPartialOccupatorEnd() - myState.myPos;
00862 if (MSGlobals::gCheck4Accidents && gap<0) {
00863
00864 return true;
00865 }
00866 vBeg = MIN2(vBeg, cfModel.ffeV(this, gap, predP->getSpeed()));
00867 }
00868 }
00869 cfModel.leftVehicleVsafe(this, neigh, vBeg);
00870
00871
00872 vsafeCriticalCont(t, vBeg, lengthsInFront);
00873 }
00874
00875 if (hasCORNIntValue(MSCORN::CORN_VEH_LASTREROUTEOFFSET)) {
00876 myIntCORNMap[MSCORN::CORN_VEH_LASTREROUTEOFFSET] = myIntCORNMap[MSCORN::CORN_VEH_LASTREROUTEOFFSET] + 1;
00877 }
00878
00879 checkRewindLinkLanes(lengthsInFront);
00880 return false;
00881 }
00882
00883
00884 void
00885 MSVehicle::moveFirstChecked() {
00886 #ifdef DEBUG_VEHICLE_GUI_SELECTION
00887 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
00888 int bla = 0;
00889 }
00890 #endif
00891 myTarget = 0;
00892
00893 SUMOReal oldV = myState.mySpeed;
00894
00895 SUMOReal vSafe = 0;
00896
00897 assert(myLFLinkLanes.size()!=0);
00898 DriveItemVector::iterator i;
00899 bool cont = true;
00900 SUMOTime t = MSNet::getInstance()->getCurrentTimeStep();
00901 for (i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end()&&cont; ++i) {
00902 MSLink *link = (*i).myLink;
00903 bool onLinkEnd = link==0;
00904
00905 if (!onLinkEnd) {
00906 if (link->opened((*i).myArrivalTime, (*i).myArrivalSpeed)) {
00907 vSafe = (*i).myVLinkPass;
00908 } else {
00909 bool yellow = link->getState()==MSLink::LINKSTATE_TL_YELLOW_MAJOR||link->getState()==MSLink::LINKSTATE_TL_YELLOW_MINOR;
00910 if (vSafe<getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed)&&yellow) {
00911 vSafe = (*i).myVLinkPass;
00912 } else {
00913 vSafe = (*i).myVLinkWait;
00914 cont = false;
00915 }
00916 }
00917 } else {
00918 vSafe = (*i).myVLinkWait;
00919 cont = false;
00920 break;
00921 }
00922 }
00923
00924 SUMOReal vNext = getCarFollowModel().moveHelper(this, myLane, vSafe);
00925 vNext = MAX2(vNext, (SUMOReal) 0.);
00926
00927 if (vNext<=0.1) {
00928 myWaitingTime += DELTA_T;
00929 if (MSCORN::wished(MSCORN::CORN_VEH_WAITINGTIME)) {
00930 myIntCORNMap[MSCORN::CORN_VEH_WAITINGTIME]++;
00931 }
00932 } else {
00933 myWaitingTime = 0;
00934 }
00935
00936 SUMOReal pos = myState.myPos;
00937 #ifndef NO_TRACI
00938 speedWithoutTraciInfluence = MIN2(vNext, myType->getMaxSpeed());
00939 #endif
00940 vNext = MIN2(vNext, getMaxSpeed());
00941
00942 #ifdef _MESSAGES
00943 if (myHBMsgEmitter != 0) {
00944 if (isOnRoad()) {
00945 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep();
00946 myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
00947 }
00948 }
00949 if (myBMsgEmitter!=0) {
00950 if (vNext < oldV) {
00951 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep();
00952 myBMsgEmitter->writeBreakEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
00953 }
00954 }
00955 #endif
00956
00957 myState.myPos += SPEED2DIST(vNext);
00958 myState.mySpeed = vNext;
00959 myTarget = 0;
00960 std::vector<MSLane*> passedLanes;
00961 for (std::vector<MSLane*>::reverse_iterator i=myFurtherLanes.rbegin(); i!=myFurtherLanes.rend(); ++i) {
00962 passedLanes.push_back(*i);
00963 }
00964 if (passedLanes.size()==0||passedLanes.back()!=myLane) {
00965 passedLanes.push_back(myLane);
00966 }
00967
00968 if (myState.myPos<=myLane->getLength()) {
00969
00970
00971 workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
00972 } else {
00973
00974 MSLane *approachedLane = myLane;
00975
00976 SUMOReal driven = myState.myPos>approachedLane->getLength()
00977 ? approachedLane->getLength() - pos
00978 : myState.myPos - pos;
00979 for (i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end() && myState.myPos>approachedLane->getLength(); ++i) {
00980 if (approachedLane!=myLane) {
00981 leaveLaneAtMove(driven);
00982 }
00983 MSLink *link = (*i).myLink;
00984
00985
00986
00987 assert(approachedLane!=0);
00988 myState.myPos -= approachedLane->getLength();
00989 assert(myState.myPos>0);
00990 if (approachedLane!=myLane) {
00991 enterLaneAtMove(approachedLane, driven);
00992 driven += approachedLane->getLength();
00993 }
00994
00995 if (link!=0) {
00996 #ifdef HAVE_INTERNAL_LANES
00997 approachedLane = link->getViaLane();
00998 if (approachedLane==0) {
00999 approachedLane = link->getLane();
01000 }
01001 #else
01002 approachedLane = link->getLane();
01003 #endif
01004 }
01005 passedLanes.push_back(approachedLane);
01006 }
01007 myTarget = approachedLane;
01008 }
01009
01010 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) {
01011 (*i)->resetPartialOccupation(this);
01012 }
01013 myFurtherLanes.clear();
01014 if (myState.myPos-getVehicleType().getLength()<0&&passedLanes.size()>0) {
01015 SUMOReal leftLength = getVehicleType().getLength()-myState.myPos;
01016 std::vector<MSLane*>::reverse_iterator i=passedLanes.rbegin() + 1;
01017 while (leftLength>0&&i!=passedLanes.rend()) {
01018 myFurtherLanes.push_back(*i);
01019 leftLength -= (*i)->setPartialOccupation(this, leftLength);
01020 ++i;
01021 }
01022 }
01023 assert(myTarget==0||myTarget->getLength()>=myState.myPos);
01024 setBlinkerInformation();
01025 }
01026
01027 void
01028 MSVehicle::checkRewindLinkLanes(SUMOReal lengthsInFront) throw() {
01029 #ifdef DEBUG_VEHICLE_GUI_SELECTION
01030 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
01031 int bla = 0;
01032 }
01033 #endif
01034 #ifdef HAVE_INTERNAL_LANES
01035 if (MSGlobals::gUsingInternalLanes) {
01036 int removalBegin = -1;
01037 bool hadVehicle = false;
01038 SUMOReal seenLanes = 0;
01039 SUMOReal seenSpace = -lengthsInFront;
01040 MSLane *nextSeenNonInternal = 0;
01041 MSLane *approachedLane = myLane;
01042 int lastLinkToInternal = -1;
01043 MSVehicle *leader = 0;
01044
01045 for (unsigned int i=0; i<myLFLinkLanes.size()&&removalBegin<0; ++i) {
01046
01047 DriveProcessItem &item = myLFLinkLanes[i];
01048 if (item.myLink==0) {
01049 continue;
01050 }
01051 if (approachedLane->getEdge().getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) {
01052 lastLinkToInternal = i;
01053 }
01054
01055
01056
01057
01058 approachedLane = item.myLink->getViaLane();
01059 bool nextIsInternal = true;
01060 if (approachedLane==0) {
01061 approachedLane = item.myLink->getLane();
01062 nextIsInternal = false;
01063 }
01064 MSEdge::EdgeBasicFunction ef = approachedLane->getEdge().getPurpose();
01065 hadVehicle |= approachedLane->getVehicleNumber()!=0;
01066 nextIsInternal &= item.myLink->isCrossing();
01067
01068 if (nextIsInternal) {
01069
01070 seenSpace = seenSpace - approachedLane->getVehLenSum();
01071 if (leader==0&&approachedLane->getLastVehicle()!=0) {
01072 leader = approachedLane->getLastVehicle();
01073 seenSpace += leader->getCarFollowModel().brakeGap(leader->getSpeed());
01074 }
01075 } else {
01076 MSVehicle *pred = approachedLane->getLastVehicle();
01077 bool nextDisallows1 = pred!=0 && seenSpace<.1;
01078 if (nextDisallows1) {
01079 SUMOReal brakeGap = pred->getVehicleType().getCarFollowModel().brakeGap(pred->getSpeed());
01080 nextDisallows1 &= pred->getPositionOnLane()+brakeGap < pred->getVehicleType().getLength();
01081 }
01082
01083
01084 seenSpace = seenSpace + approachedLane->getLength() - approachedLane->getVehLenSum();
01085 if (leader==0&&approachedLane->getLastVehicle()!=0) {
01086 leader = approachedLane->getLastVehicle();
01087 seenSpace += leader->getCarFollowModel().brakeGap(leader->getSpeed());
01088 }
01089 seenLanes += approachedLane->getLength();
01090
01091
01092 bool nextDisallows2 = approachedLane->getLastVehicle()!=0 && approachedLane->getLastVehicle()->getSpeed()<.1;
01093 if (nextDisallows2) {
01094 nextDisallows2 &= approachedLane->getLastVehicle()->getPositionOnLane() < approachedLane->getLastVehicle()->getVehicleType().getLength();
01095 }
01096 if ((nextDisallows1||nextDisallows2)&&lastLinkToInternal>=0) {
01097 removalBegin = lastLinkToInternal;
01098 }
01099 nextSeenNonInternal = approachedLane;
01100 }
01101
01102
01103
01104
01105
01106
01107 SUMOReal impatienceCorrection = MAX2(0, myWaitingTime);
01108 if (hadVehicle&&seenLanes>getVehicleType().getLength()&&seenSpace<getVehicleType().getLength()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
01109 removalBegin = lastLinkToInternal;
01110 }
01111 }
01112 if (removalBegin!=-1) {
01113 myLFLinkLanes[removalBegin].myVLinkPass = myLFLinkLanes[removalBegin].myVLinkWait;
01114 myLFLinkLanes[removalBegin].mySetRequest = false;
01115 if (removalBegin+1<(int)myLFLinkLanes.size()) {
01116 myLFLinkLanes.erase(myLFLinkLanes.begin()+removalBegin+1, myLFLinkLanes.end());
01117 }
01118 }
01119 }
01120 #endif
01121 for (DriveItemVector::iterator i=myLFLinkLanes.begin(); i!=myLFLinkLanes.end(); ++i) {
01122 if ((*i).myLink!=0&&(*i).mySetRequest) {
01123 (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed);
01124 }
01125 }
01126 }
01127
01128
01129
01130 void
01131 MSVehicle::vsafeCriticalCont(SUMOTime t, SUMOReal boundVSafe, SUMOReal lengthsInFront) {
01132 #ifdef DEBUG_VEHICLE_GUI_SELECTION
01133 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
01134 int bla = 0;
01135 }
01136 #endif
01137 const MSCFModel &cfModel = getCarFollowModel();
01138
01139
01140 SUMOReal seen = myLane->getLength() - myState.myPos;
01141
01142 if (this!=myLane->getFirstVehicle() && seen - cfModel.brakeGap(myState.mySpeed) > 0) {
01143
01144 myLFLinkLanes.push_back(DriveProcessItem(0, boundVSafe, boundVSafe, false, 0, 0));
01145 return;
01146 }
01147
01148 MSLane *nextLane = myLane;
01149
01150
01151 SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed);
01152 SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
01153 SUMOReal vLinkPass = boundVSafe;
01154 SUMOReal vLinkWait = vLinkPass;
01155 const std::vector<MSLane*> &bestLaneConts = getBestLanesContinuation();
01156 #ifdef HAVE_INTERNAL_LANES
01157 bool hadNonInternal = false;
01158 bool lastInnerHadPriority = false;
01159 bool passingInner = false;
01160 #endif
01161
01162 unsigned int view = 1;
01163
01164 while (true) {
01165
01166 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&nextLane->getEdge()) {
01167 SUMOReal vsafeStop = cfModel.ffeS(this, seen-(nextLane->getLength()-myStops.begin()->pos));
01168 vLinkPass = MIN2(vLinkPass, vsafeStop);
01169 vLinkWait = MIN2(vLinkWait, vsafeStop);
01170 }
01171
01172
01173 MSLinkCont::const_iterator link = myLane->succLinkSec(*this, view, *nextLane, bestLaneConts);
01174
01175 SUMOReal laneLength = nextLane->getLength();
01176
01177
01178
01179 if (nextLane->isLinkEnd(link)) {
01180
01181 SUMOReal laneEndVSafe = cfModel.ffeS(this, seen);
01182 myLFLinkLanes.push_back(DriveProcessItem(0, MIN2(vLinkPass, laneEndVSafe), MIN2(vLinkPass, laneEndVSafe), false, 0, 0));
01183 return;
01184 }
01185
01186 vLinkWait = vLinkPass;
01187
01188
01189
01190 const MSLinkCont &lc = nextLane->getLinkCont();
01191
01192
01193 #ifdef HAVE_INTERNAL_LANES
01194 passingInner = nextLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL;
01195 bool nextInternal = false;
01196 nextLane = (*link)->getViaLane();
01197 if (nextLane==0) {
01198 nextLane = (*link)->getLane();
01199 hadNonInternal = true;
01200 passingInner = false;
01201 } else {
01202 nextInternal = true;
01203 passingInner &= nextLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL;
01204 }
01205 #else
01206 nextLane = (*link)->getLane();
01207 #endif
01208
01209
01210
01211 SUMOReal vmaxNextLane = MAX2(cfModel.ffeV(this, seen, nextLane->getMaxSpeed()), nextLane->getMaxSpeed());
01212
01213
01214
01215 SUMOReal vsafePredNextLane = 100000;
01216 std::pair<MSVehicle*, SUMOReal> lastOnNext = nextLane->getLastVehicleInformation();
01217 if (lastOnNext.first!=0) {
01218 if (seen+lastOnNext.second>0) {
01219 vsafePredNextLane = cfModel.ffeV(this, seen+lastOnNext.second, lastOnNext.first->getSpeed());
01220 }
01221 }
01222 #ifdef DEBUG_VEHICLE_GUI_SELECTION
01223 if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
01224 int bla = 0;
01225 }
01226 #endif
01227
01228 vLinkPass = MIN3(vLinkPass, vmaxNextLane, vsafePredNextLane);
01229
01230
01231
01232 vLinkWait = MIN3(vLinkPass, vLinkWait, cfModel.ffeS(this, seen));
01233
01234 bool yellow = (*link)->getState()==MSLink::LINKSTATE_TL_YELLOW_MAJOR||(*link)->getState()==MSLink::LINKSTATE_TL_YELLOW_MINOR;
01235 if (yellow&&SPEED2DIST(vLinkWait)+myState.myPos<laneLength) {
01236 myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, 0, 0));
01237 return;
01238 }
01239
01240 bool setRequest = false;
01241 bool mayPass = (*link)->havePriority() || (passingInner&&lastInnerHadPriority);
01242 if (!mayPass) {
01243
01244 if ((*link)->getState()==MSLink::LINKSTATE_TL_RED) {
01245 vLinkPass = vLinkWait;
01246 }
01247
01248
01249
01250 if (seen>cfModel.getMaxDecel()) {
01251 vLinkPass = vLinkWait;
01252
01253
01254
01255 }
01256 }
01257 lastInnerHadPriority = (*link)->havePriority();
01258
01259 if (!myStops.empty()&& &myStops.begin()->lane->getEdge()==&nextLane->getEdge()) {
01260 SUMOReal vsafeStop = cfModel.ffeS(this, seen+myStops.begin()->pos);
01261 vLinkPass = MIN2(vLinkPass, vsafeStop);
01262 vLinkWait = MIN2(vLinkWait, vsafeStop);
01263 setRequest = false;
01264 } else {
01265 setRequest |= ((*link)->getState()!=MSLink::LINKSTATE_TL_RED&&(vLinkPass>0&&dist-seen>0));
01266 }
01267
01268
01269
01270 setRequest &= dist-seen>0;
01271 SUMOTime arrivalTime = 0;
01272 SUMOTime leaveTime = 0;
01273 if (setRequest) {
01274 arrivalTime = t + TIME2STEPS(seen / vLinkPass);
01275 }
01276 myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkPass, vLinkWait, setRequest, arrivalTime, vLinkPass));
01277 seen += nextLane->getLength();
01278 if ((vLinkPass<=0||seen>dist)&&hadNonInternal) {
01279 return;
01280 }
01281 #ifdef HAVE_INTERNAL_LANES
01282 if (!nextInternal) {
01283 view++;
01284 }
01285 #else
01286 view++;
01287 #endif
01288 }
01289 }
01290
01291
01292 Position2D
01293 MSVehicle::getPosition() const {
01294 if (myLane==0) {
01295 return Position2D(-1000, -1000);
01296 }
01297 return myLane->getShape().positionAtLengthPosition(myState.pos());
01298 }
01299
01300
01301 const std::string &
01302 MSVehicle::getID() const throw() {
01303 return myParameter->id;
01304 }
01305
01306
01307 void
01308 MSVehicle::enterLaneAtMove(MSLane* enteredLane, SUMOReal driven) {
01309 #ifndef NO_TRACI
01310
01311 while (!myStops.empty()&&myStops.begin()->lane==myLane) {
01312 myStops.pop_front();
01313 }
01314 #endif
01315
01316 adaptLaneEntering2MoveReminder(*enteredLane);
01317
01318 myLane = enteredLane;
01319
01320 MSEdge &enteredEdge = enteredLane->getEdge();
01321
01322 if (enteredEdge.getPurpose()!=MSEdge::EDGEFUNCTION_INTERNAL) {
01323
01324
01325 MSRouteIterator edgeIt = myCurrEdge;
01326 while (*edgeIt != &enteredEdge) {
01327 ++edgeIt;
01328 assert(edgeIt != myRoute->end());
01329 }
01330 myCurrEdge = edgeIt;
01331 }
01332
01333
01334 getBestLanes(true);
01335 activateReminders(false, false);
01336 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
01337 (*dev)->enterLaneAtMove(enteredLane, driven);
01338 }
01339
01340 #ifndef NO_TRACI
01341 checkForLaneChanges();
01342 #endif
01343 }
01344
01345
01346 void
01347 MSVehicle::enterLaneAtLaneChange(MSLane* enteredLane) {
01348 #ifdef _MESSAGES
01349 if (myLCMsgEmitter!=0) {
01350 SUMOReal timeStep = MSNet::getInstance()->getCurrentTimeStep();
01351 myLCMsgEmitter->writeLaneChangeEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), enteredLane, getPosition().x(), getPosition().y());
01352 }
01353 #endif
01354 MSLane *myPriorLane = myLane;
01355 myLane = enteredLane;
01356
01357
01358 myMoveReminders = enteredLane->getMoveReminders();
01359 activateReminders(false, true);
01360 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
01361 (*dev)->enterLaneAtLaneChange(enteredLane);
01362 }
01363 SUMOReal leftLength = myState.myPos-getVehicleType().getLength();
01364 if (leftLength<0) {
01365
01366 const MSRoute &route = getRoute();
01367 MSRouteIterator i = myCurrEdge;
01368 MSLane *lane = myLane;
01369 while (i!=route.begin()&&leftLength>0) {
01370 const MSEdge * const prev = *(--i);
01371 const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes();
01372 for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j=incomingLanes.begin(); j!=incomingLanes.end(); ++j) {
01373 if (&(*j).lane->getEdge()==prev) {
01374 #ifdef HAVE_INTERNAL_LANES
01375 (*j).lane->setPartialOccupation(this, leftLength);
01376 #else
01377 leftLength -= (*j).length;
01378 (*j).lane->setPartialOccupation(this, leftLength);
01379 #endif
01380 leftLength -= (*j).lane->getLength();
01381 break;
01382 }
01383 }
01384 }
01385 }
01386 #ifndef NO_TRACI
01387
01388 checkForLaneChanges();
01389 #endif
01390 }
01391
01392
01393 void
01394 MSVehicle::enterLaneAtEmit(MSLane* enteredLane, SUMOReal pos, SUMOReal speed) {
01395 myState = State(pos, speed);
01396 assert(myState.myPos >= 0);
01397 assert(myState.mySpeed >= 0);
01398 myWaitingTime = 0;
01399 myLane = enteredLane;
01400
01401 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
01402 (*dev)->enterLaneAtEmit(enteredLane, myState);
01403 }
01404 std::string msg;
01405 if (!hasValidRoute(msg)) {
01406 throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
01407 }
01408 myMoveReminders = enteredLane->getMoveReminders();
01409 activateReminders(true, false);
01410
01411 SUMOReal leftLength = myType->getLength() - pos;
01412 MSLane *clane = enteredLane;
01413 while (leftLength>0) {
01414 const std::vector<MSLane::IncomingLaneInfo> &incoming = clane->getIncomingLanes();
01415 if (incoming.size()==0) {
01416 break;
01417 }
01418 clane = incoming[0].lane;
01419 myFurtherLanes.push_back(clane);
01420 leftLength -= (clane)->setPartialOccupation(this, leftLength);
01421 }
01422 }
01423
01424
01425 void
01426 MSVehicle::leaveLaneAtMove(SUMOReal driven) {
01427 std::vector< MSMoveReminder* >::iterator rem;
01428 for (rem=myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
01429 (*rem)->notifyLeave(*this, false, false);
01430 }
01431 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
01432 (*dev)->leaveLaneAtMove(driven);
01433 }
01434 }
01435
01436
01437 void
01438 MSVehicle::leaveLane(bool isArrival) {
01439 for (std::vector< MSDevice* >::iterator dev=myDevices.begin(); dev != myDevices.end(); ++dev) {
01440 (*dev)->leaveLane();
01441 }
01442
01443 SUMOReal savePos = myState.myPos;
01444 std::vector< MSMoveReminder* >::iterator rem;
01445 for (rem=myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
01446 (*rem)->notifyLeave(*this, isArrival, !isArrival);
01447 }
01448 std::vector<SUMOReal>::iterator off = myOldLaneMoveReminderOffsets.begin();
01449 for (rem=myOldLaneMoveReminders.begin(); rem!=myOldLaneMoveReminders.end(); ++rem, ++off) {
01450 myState.myPos += (*off);
01451 (*rem)->notifyLeave(*this, isArrival, !isArrival);
01452 myState.myPos -= (*off);
01453 }
01454 myState.myPos = savePos;
01455 myMoveReminders.clear();
01456 myOldLaneMoveReminders.clear();
01457 myOldLaneMoveReminderOffsets.clear();
01458 for (std::vector<MSLane*>::iterator i=myFurtherLanes.begin(); i!=myFurtherLanes.end(); ++i) {
01459 (*i)->resetPartialOccupation(this);
01460 }
01461 myFurtherLanes.clear();
01462 }
01463
01464
01465 const MSEdge * const
01466 MSVehicle::getEdge() const {
01467 return *myCurrEdge;
01468 }
01469
01470
01471 MSLane *
01472 MSVehicle::getTargetLane() const {
01473 return myTarget;
01474 }
01475
01476
01477 const MSLane &
01478 MSVehicle::getLane() const {
01479 return *myLane;
01480 }
01481
01482
01483 MSAbstractLaneChangeModel &
01484 MSVehicle::getLaneChangeModel() {
01485 return *myLaneChangeModel;
01486 }
01487
01488
01489 const MSAbstractLaneChangeModel &
01490 MSVehicle::getLaneChangeModel() const {
01491 return *myLaneChangeModel;
01492 }
01493
01494
01495 void
01496 MSVehicle::quitRemindedEntered(MSVehicleQuitReminded *r) {
01497 myQuitReminded.push_back(r);
01498 }
01499
01500
01501 void
01502 MSVehicle::quitRemindedLeft(MSVehicleQuitReminded *r) {
01503 QuitRemindedVector::iterator i = find(myQuitReminded.begin(), myQuitReminded.end(), r);
01504 if (i!=myQuitReminded.end()) {
01505 myQuitReminded.erase(i);
01506 }
01507 }
01508
01509
01510 void
01511 MSVehicle::rebuildContinuationsFor(LaneQ &oq, MSLane *l, MSRouteIterator ce, int seen) const {
01512
01513 ++ce;
01514
01515
01516
01517
01518
01519 if ((seen>4 && oq.length+l->getLength()>3000) || seen>8 || ce==myRoute->end()) {
01520
01521 return;
01522 }
01523
01524
01525 const std::vector<MSLane*> *allowed = 0;
01526 if (ce!=myRoute->end()&&ce+1!=myRoute->end()) {
01527 allowed = (*ce)->allowedLanes(**(ce+1), myType->getVehicleClass());
01528 }
01529
01530
01531 LaneQ best;
01532 best.length = 0;
01533 const std::vector<MSLane*> &lanes = (*ce)->getLanes();
01534 const MSLinkCont &lc = l->getLinkCont();
01535 bool gotOne = false;
01536
01537 for (MSLinkCont::const_iterator k=lc.begin(); k!=lc.end(); ++k) {
01538
01539 LaneQ q;
01540 MSLane *qqq = (*k)->getLane();
01541 if (qqq==0) {
01542 q.occupied = 0;
01543 q.length = 0;
01544 continue;
01545 }
01546 q.occupied = qqq->getVehLenSum();
01547 q.length = qqq->getLength();
01548 q.joined.push_back(qqq);
01549
01550
01551 if (!myStops.empty()&& &(myStops.front().lane->getEdge())==&qqq->getEdge()) {
01552 if (myStops.front().lane==qqq) {
01553 gotOne = true;
01554 if (allowed==0||find(allowed->begin(), allowed->end(), (*k)->getLane())!=allowed->end()) {
01555 rebuildContinuationsFor(q, qqq, ce, seen+1);
01556 }
01557 } else {
01558 q.occupied = qqq->getVehLenSum();
01559 const Stop &s = myStops.front();
01560 SUMOReal endPos = s.pos;
01561 if (s.busstop!=0) {
01562
01563 endPos = s.busstop->getLastFreePos();
01564 }
01565 q.length = endPos;
01566 }
01567 } else {
01568
01569
01570 if (allowed==0||find(allowed->begin(), allowed->end(), (*k)->getLane())!=allowed->end()) {
01571
01572 gotOne = true;
01573 rebuildContinuationsFor(q, qqq, ce, seen+1);
01574 } else {
01575
01576
01577
01578 if (&(*k)->getLane()->getEdge()!=*ce) {
01579 q.occupied = 0;
01580 q.length = 0;
01581 }
01582 }
01583 }
01584
01585 if (q.length>best.length) {
01586 best = q;
01587 }
01588 }
01589
01590 if (!gotOne) {
01591
01592
01593
01594
01595
01596
01597
01598 const std::vector<MSLane*> &lanes = (*ce)->getLanes();
01599 bool oneFound = false;
01600 int bestPos = 0;
01601 MSLane *next = 0;
01602
01603 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); !oneFound&&i!=lanes.end();) {
01604 if (allowed!=0 && find(allowed->begin(), allowed->end(), *i)!=allowed->end()) {
01605 oneFound = true;
01606 next = *i;
01607 } else {
01608 ++i;
01609 ++bestPos;
01610 }
01611 }
01612
01613 if (oneFound) {
01614
01615
01616
01617 int bestDistance = -100;
01618 MSLane *bestL = 0;
01619
01620 const std::vector<MSLane*> &clanes = l->getEdge().getLanes();
01621 for (std::vector<MSLane*>::const_iterator i=clanes.begin(); i!=clanes.end(); ++i) {
01622
01623 for (MSLinkCont::const_iterator k=lc.begin(); k!=lc.end(); ++k) {
01624 if ((*k)->getLane()==0) {
01625 continue;
01626 }
01627
01628 if (&(*k)->getLane()->getEdge()==*ce) {
01629 std::vector<MSLane*>::const_iterator l=find(lanes.begin(), lanes.end(), (*k)->getLane());
01630 if (l!=lanes.end()) {
01631 int pos = (int)distance(lanes.begin(), l);
01632 int cdist = abs(pos-bestPos);
01633 if (bestDistance==-100||bestDistance>cdist) {
01634 bestDistance = cdist;
01635 bestL = *i;
01636 }
01637 }
01638 }
01639 }
01640 }
01641 if (bestL==l) {
01642 best.occupied = next->getVehLenSum();
01643 best.length = next->getLength();
01644 } else {
01645 best.occupied = 0;
01646 best.length = 0;
01647 best.joined.clear();
01648 }
01649 }
01650 }
01651 oq.length += best.length;
01652 oq.occupied += best.occupied;
01653 copy(best.joined.begin(), best.joined.end(), back_inserter(oq.joined));
01654 }
01655
01656
01657
01658 const std::vector<MSVehicle::LaneQ> &
01659 MSVehicle::getBestLanes(bool forceRebuild, MSLane *startLane) const throw() {
01660 if (startLane==0) {
01661 startLane = myLane;
01662 }
01663 if (myLastBestLanesEdge==&startLane->getEdge()&&!forceRebuild) {
01664 std::vector<LaneQ> &lanes = *myBestLanes.begin();
01665 std::vector<LaneQ>::iterator i;
01666 for (i=lanes.begin(); i!=lanes.end(); ++i) {
01667 SUMOReal v = 0;
01668 for (std::vector<MSLane*>::const_iterator j=(*i).joined.begin(); j!=(*i).joined.end(); ++j) {
01669 v += (*j)->getVehLenSum();
01670 }
01671 (*i).v = v;
01672 if ((*i).lane==startLane) {
01673 myCurrentLaneInBestLanes = i;
01674 }
01675 }
01676 return *myBestLanes.begin();
01677 }
01678 myLastBestLanesEdge = &startLane->getEdge();
01679 myBestLanes.clear();
01680 myBestLanes.push_back(std::vector<LaneQ>());
01681 const std::vector<MSLane*> &lanes = (*myCurrEdge)->getLanes();
01682 MSRouteIterator ce = myCurrEdge;
01683 int seen = 0;
01684 const std::vector<MSLane*> *allowed = 0;
01685 if (ce!=myRoute->end()&&ce+1!=myRoute->end()) {
01686 allowed = (*ce)->allowedLanes(**(ce+1), myType->getVehicleClass());
01687 }
01688 for (std::vector<MSLane*>::const_iterator i=lanes.begin(); i!=lanes.end(); ++i) {
01689 LaneQ q;
01690 q.lane = *i;
01691 q.length = 0;
01692 q.occupied = 0;
01693 if (!myStops.empty()&& &myStops.front().lane->getEdge()==&q.lane->getEdge()) {
01694 if (myStops.front().lane==q.lane) {
01695 q.allowsContinuation = allowed==0||find(allowed->begin(), allowed->end(), q.lane)!=allowed->end();
01696 q.length += q.lane->getLength();
01697 q.occupied += q.lane->getVehLenSum();
01698 } else {
01699 q.allowsContinuation = false;
01700 q.occupied = q.lane->getVehLenSum();
01701 const Stop &s = myStops.front();
01702 SUMOReal endPos = s.pos;
01703 if (s.busstop!=0) {
01704
01705 endPos = s.busstop->getLastFreePos();
01706 }
01707 q.length = endPos;
01708 }
01709 } else {
01710 q.allowsContinuation = allowed==0||find(allowed->begin(), allowed->end(), q.lane)!=allowed->end();
01711 }
01712 myBestLanes[0].push_back(q);
01713 }
01714 if (ce!=myRoute->end()) {
01715 for (std::vector<MSVehicle::LaneQ>::iterator i=myBestLanes.begin()->begin(); i!=myBestLanes.begin()->end(); ++i) {
01716 if ((*i).allowsContinuation) {
01717 rebuildContinuationsFor((*i), (*i).lane, ce, seen);
01718 (*i).length += (*i).lane->getLength();
01719 (*i).occupied += (*i).lane->getVehLenSum();
01720 }
01721 }
01722 }
01723 SUMOReal best = 0;
01724 int index = 0;
01725 int run = 0;
01726 for (std::vector<MSVehicle::LaneQ>::iterator i=myBestLanes.begin()->begin(); i!=myBestLanes.begin()->end(); ++i, ++run) {
01727 if (best<(*i).length) {
01728 best = (*i).length;
01729 index = run;
01730 }
01731 if ((*i).lane==startLane) {
01732 myCurrentLaneInBestLanes = i;
01733 }
01734 }
01735 run = 0;
01736 for (std::vector<MSVehicle::LaneQ>::iterator i=myBestLanes.begin()->begin(); i!=myBestLanes.begin()->end(); ++i, ++run) {
01737 (*i).bestLaneOffset = index - run;
01738 }
01739
01740 return *myBestLanes.begin();
01741 }
01742
01743
01744 void
01745 MSVehicle::writeXMLRoute(OutputDevice &os, int index) const {
01746
01747 os.openTag("route");
01748 if (index>=0) {
01749 std::map<MSCORN::Pointer, void*>::const_iterator i = myPointerCORNMap.find(MSCORN::CORN_P_VEH_OLDROUTE);
01750 assert(i!=myPointerCORNMap.end());
01751 const ReplacedRoutesVector *v = (const ReplacedRoutesVector *)(*i).second;
01752 assert((int) v->size()>index);
01753
01754 os << " replacedOnEdge=\"" << (*v)[index].edge->getID();
01755
01756 os << "\" replacedAtTime=\"" << time2string((*v)[index].time) << "\" probability=\"0\" edges=\"";
01757
01758 for (int i=0; i<index; ++i) {
01759 (*v)[i].route->writeEdgeIDs(os, (*v)[i].edge);
01760 }
01761 (*v)[index].route->writeEdgeIDs(os);
01762 } else {
01763 os << " edges=\"";
01764 if (hasCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE)) {
01765 int noReroutes = getCORNIntValue(MSCORN::CORN_VEH_NUMBERROUTE);
01766 std::map<MSCORN::Pointer, void*>::const_iterator it = myPointerCORNMap.find(MSCORN::CORN_P_VEH_OLDROUTE);
01767 assert(it!=myPointerCORNMap.end());
01768 const ReplacedRoutesVector *v = (const ReplacedRoutesVector *)(*it).second;
01769 assert((int) v->size()==noReroutes);
01770 for (int i=0; i<noReroutes; ++i) {
01771 (*v)[i].route->writeEdgeIDs(os, (*v)[i].edge);
01772 }
01773 }
01774 myRoute->writeEdgeIDs(os);
01775 if (hasCORNPointerValue(MSCORN::CORN_P_VEH_EXIT_TIMES)) {
01776 os << "\" exitTimes=\"";
01777 const std::vector<SUMOTime> *exits = (const std::vector<SUMOTime> *)getCORNPointerValue(MSCORN::CORN_P_VEH_EXIT_TIMES);
01778 for (std::vector<SUMOTime>::const_iterator it = exits->begin(); it != exits->end(); ++it) {
01779 if (it != exits->begin()) {
01780 os << " ";
01781 }
01782 os << time2string(*it);
01783 }
01784 }
01785 }
01786 (os << "\"").closeTag(true);
01787 }
01788
01789
01790 void
01791 MSVehicle::saveState(std::ostream &os) {
01792 FileHelpers::writeString(os, myParameter->id);
01793 FileHelpers::writeFloat(os, myLastLaneChangeOffset);
01794 FileHelpers::writeFloat(os, myWaitingTime);
01795 FileHelpers::writeInt(os, myParameter->repetitionNumber);
01796 FileHelpers::writeFloat(os, myParameter->repetitionOffset);
01797 FileHelpers::writeString(os, myRoute->getID());
01798 FileHelpers::writeTime(os, myParameter->depart);
01799 FileHelpers::writeString(os, myType->getID());
01800 FileHelpers::writeUInt(os, myRoute->posInRoute(myCurrEdge));
01801 if (hasCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME)) {
01802 FileHelpers::writeInt(os, getCORNIntValue(MSCORN::CORN_VEH_DEPART_TIME));
01803 } else {
01804 FileHelpers::writeInt(os, -1);
01805 }
01806 #ifdef HAVE_MESOSIM
01807
01808 if (mySegment==0) {
01809 FileHelpers::writeUInt(os, 0);
01810 } else {
01811 FileHelpers::writeUInt(os, mySegment->getIndex());
01812 }
01813 FileHelpers::writeUInt(os, getQueIndex());
01814 FileHelpers::writeTime(os, myEventTime);
01815 FileHelpers::writeTime(os, myLastEntryTime);
01816 #endif
01817 }
01818
01819
01820
01821
01822 void
01823 MSVehicle::removeOnTripEnd(MSVehicle *veh) throw() {
01824 quitRemindedLeft(veh);
01825 }
01826
01827
01828
01829 const std::vector<MSLane*> &
01830 MSVehicle::getBestLanesContinuation() const throw() {
01831 if (myBestLanes.empty()||myBestLanes[0].empty()||myLane->getEdge().getPurpose()==MSEdge::EDGEFUNCTION_INTERNAL) {
01832 return myEmptyLaneVector;
01833 }
01834 return (*myCurrentLaneInBestLanes).joined;
01835 }
01836
01837
01838 const std::vector<MSLane*> &
01839 MSVehicle::getBestLanesContinuation(const MSLane * const l) const throw() {
01840 for (std::vector<std::vector<LaneQ> >::const_iterator i=myBestLanes.begin(); i!=myBestLanes.end(); ++i) {
01841 if ((*i).size()!=0&&(*i)[0].lane==l) {
01842 return (*i)[0].joined;
01843 }
01844 }
01845 return myEmptyLaneVector;
01846 }
01847
01848
01849
01850 SUMOReal
01851 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) {
01852 #ifdef DEBUG_VEHICLE_GUI_SELECTION
01853 SUMOReal distance = 1000000.;
01854 #else
01855 SUMOReal distance = std::numeric_limits<SUMOReal>::max();
01856 #endif
01857 if (isOnRoad() && destEdge != NULL) {
01858 if (&myLane->getEdge() == *myCurrEdge) {
01859
01860 distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
01861 } else {
01862
01863 distance = myLane->getLength() - getPositionOnLane();
01864 distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge+1), destEdge);
01865 }
01866 }
01867 return distance;
01868 }
01869
01870 void
01871 MSVehicle::setWasVaporized(bool onDepart) {
01872 if (MSCORN::wished(MSCORN::CORN_VEH_VAPORIZED)) {
01873 myIntCORNMap[MSCORN::CORN_VEH_VAPORIZED] = onDepart ? 1 : 0;
01874 }
01875 }
01876
01877
01878 SUMOReal
01879 MSVehicle::getHBEFA_CO2Emissions() const throw() {
01880 return HelpersHBEFA::computeCO2(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01881 }
01882
01883
01884 SUMOReal
01885 MSVehicle::getHBEFA_COEmissions() const throw() {
01886 return HelpersHBEFA::computeCO(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01887 }
01888
01889
01890 SUMOReal
01891 MSVehicle::getHBEFA_HCEmissions() const throw() {
01892 return HelpersHBEFA::computeHC(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01893 }
01894
01895
01896 SUMOReal
01897 MSVehicle::getHBEFA_NOxEmissions() const throw() {
01898 return HelpersHBEFA::computeNOx(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01899 }
01900
01901
01902 SUMOReal
01903 MSVehicle::getHBEFA_PMxEmissions() const throw() {
01904 return HelpersHBEFA::computePMx(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01905 }
01906
01907
01908 SUMOReal
01909 MSVehicle::getHBEFA_FuelConsumption() const throw() {
01910 return HelpersHBEFA::computeFuel(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01911 }
01912
01913
01914 SUMOReal
01915 MSVehicle::getHarmonoise_NoiseEmissions() const throw() {
01916 return HelpersHarmonoise::computeNoise(myType->getEmissionClass(), myState.speed(), myPreDawdleAcceleration);
01917 }
01918
01919
01920 void
01921 MSVehicle::addPerson(MSPerson* person) throw() {
01922 if (!hasCORNPointerValue(MSCORN::CORN_P_VEH_PASSENGER)) {
01923 myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER] = new std::vector<MSPerson*>();
01924 }
01925 ((std::vector<MSPerson*>*) myPointerCORNMap[MSCORN::CORN_P_VEH_PASSENGER])->push_back(person);
01926 }
01927
01928
01929 #ifndef NO_TRACI
01930
01931 bool
01932 MSVehicle::startSpeedAdaption(float newSpeed, SUMOTime duration, SUMOTime currentTime) {
01933 if (newSpeed < 0 || duration <= 0/* || newSpeed >= getSpeed()*/) {
01934 return false;
01935 }
01936 speedBeforeAdaption = getSpeed();
01937 timeBeforeAdaption = currentTime;
01938 adaptDuration = duration;
01939 speedReduction = MAX2((SUMOReal) 0.0f, (SUMOReal)(speedBeforeAdaption - newSpeed));
01940 adaptingSpeed = true;
01941 return true;
01942 }
01943
01944
01945 void
01946 MSVehicle::adaptSpeed() {
01947 SUMOReal maxSpeed = 0;
01948 SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
01949 if (!adaptingSpeed) {
01950 return;
01951 }
01952 if (isLastAdaption) {
01953 unsetIndividualMaxSpeed();
01954 adaptingSpeed = false;
01955 isLastAdaption = false;
01956 return;
01957 }
01958 if (currentTime <= timeBeforeAdaption + adaptDuration) {
01959 maxSpeed = speedBeforeAdaption - (speedReduction / adaptDuration)
01960 * (currentTime - timeBeforeAdaption);
01961 } else {
01962 maxSpeed = speedBeforeAdaption - speedReduction;
01963 isLastAdaption = true;
01964 }
01965 setIndividualMaxSpeed(maxSpeed);
01966 }
01967
01968
01969 void
01970 MSVehicle::checkLaneChangeConstraint(SUMOTime time) {
01971 if (!laneChangeConstraintActive) {
01972 return;
01973 }
01974 if ((time - timeBeforeLaneChange) >= laneChangeStickyTime) {
01975 laneChangeConstraintActive = false;
01976 }
01977 }
01978
01979
01980 void
01981 MSVehicle::startLaneChange(unsigned lane, SUMOTime stickyTime) {
01982 if (lane < 0) {
01983 return;
01984 }
01985 timeBeforeLaneChange = MSNet::getInstance()->getCurrentTimeStep();
01986 laneChangeStickyTime = stickyTime;
01987 myDestinationLane = lane;
01988 laneChangeConstraintActive = true;
01989 checkForLaneChanges();
01990 }
01991
01992
01993 void
01994 MSVehicle::checkForLaneChanges() {
01995 MSLane* tmpLane;
01996 unsigned currentLaneIndex = 0;
01997 if (!laneChangeConstraintActive) {
01998 myLaneChangeModel->requestLaneChange(REQUEST_NONE);
01999 return;
02000 }
02001 if ((unsigned int)(*myCurrEdge)->getLanes().size() <= myDestinationLane) {
02002 laneChangeConstraintActive = false;
02003 return;
02004 }
02005 tmpLane = myLane;
02006 while ((tmpLane =tmpLane->getRightLane()) != NULL) {
02007 currentLaneIndex++;
02008 }
02009 if (currentLaneIndex > myDestinationLane) {
02010 myLaneChangeModel->requestLaneChange(REQUEST_RIGHT);
02011 } else if (currentLaneIndex < myDestinationLane) {
02012 myLaneChangeModel->requestLaneChange(REQUEST_LEFT);
02013 } else {
02014 myLaneChangeModel->requestLaneChange(REQUEST_HOLD);
02015 }
02016 }
02017
02018
02019 void
02020 MSVehicle::processTraCICommands(SUMOTime time) {
02021
02022 checkLaneChangeConstraint(time);
02023
02024 adaptSpeed();
02025 }
02026
02027
02028 bool
02029 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal radius, SUMOTime duration) {
02030
02031 for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
02032 if (iter->lane == lane && fabs(iter->pos - pos) < POSITION_EPS) {
02033 if (duration == 0 && !iter->reached) {
02034 myStops.erase(iter);
02035 } else {
02036 iter->duration = duration;
02037 }
02038 return true;
02039 }
02040 }
02041
02042 SUMOVehicleParameter::Stop newStop;
02043 newStop.lane = lane->getID();
02044 newStop.pos = pos;
02045 newStop.duration = duration;
02046 newStop.until = -1;
02047 newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos);
02048 return addStop(newStop);
02049 }
02050
02051
02052 #endif
02053
02054
02055