SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
17 // Representation of a vehicle in the micro simulation
18 /****************************************************************************/
19 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
20 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
21 /****************************************************************************/
22 //
23 // This file is part of SUMO.
24 // SUMO is free software: you can redistribute it and/or modify
25 // it under the terms of the GNU General Public License as published by
26 // the Free Software Foundation, either version 3 of the License, or
27 // (at your option) any later version.
28 //
29 /****************************************************************************/
30 
31 // ===========================================================================
32 // included modules
33 // ===========================================================================
34 #ifdef _MSC_VER
35 #include <windows_config.h>
36 #else
37 #include <config.h>
38 #endif
39 
40 #include "MSLane.h"
41 #include "MSVehicle.h"
42 #include "MSEdge.h"
43 #include "MSVehicleType.h"
44 #include "MSNet.h"
45 #include "MSRoute.h"
46 #include "MSLinkCont.h"
48 #include <utils/common/StdDefs.h>
50 #include <microsim/MSGlobals.h>
51 #include <iostream>
52 #include <cassert>
53 #include <cmath>
54 #include <cstdlib>
55 #include <algorithm>
56 #include <map>
57 #include "MSMoveReminder.h"
59 #include "MSLCM_DK2004.h"
60 #include <utils/common/ToString.h>
64 #include "trigger/MSBusStop.h"
66 #include "MSPerson.h"
67 #include "MSPersonControl.h"
70 #include "MSEdgeWeightsStorage.h"
73 
74 #ifdef _MESSAGES
75 #include "MSMessageEmitter.h"
76 #endif
77 
78 #ifdef HAVE_MESOSIM
79 #include <mesosim/MESegment.h>
80 #include <mesosim/MELoop.h>
81 #include "MSGlobals.h"
82 #endif
83 
84 #ifdef CHECK_MEMORY_LEAKS
85 #include <foreign/nvwa/debug_new.h>
86 #endif // CHECK_MEMORY_LEAKS
87 
88 //#define DEBUG_VEHICLE_GUI_SELECTION 1
89 #ifdef DEBUG_VEHICLE_GUI_SELECTION
90 #undef ID_LIST
92 #include <guisim/GUIVehicle.h>
93 #include <guisim/GUILane.h>
94 #endif
95 
96 #define BUS_STOP_OFFSET 0.5
97 
98 
99 // ===========================================================================
100 // static value definitions
101 // ===========================================================================
102 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
103 
104 
105 // ===========================================================================
106 // method definitions
107 // ===========================================================================
108 /* -------------------------------------------------------------------------
109  * methods of MSVehicle::State
110  * ----------------------------------------------------------------------- */
112  myPos = state.myPos;
113  mySpeed = state.mySpeed;
114 }
115 
116 
119  myPos = state.myPos;
120  mySpeed = state.mySpeed;
121  return *this;
122 }
123 
124 
125 bool
127  return (myPos != state.myPos ||
128  mySpeed != state.mySpeed);
129 }
130 
131 
132 SUMOReal
134  return myPos;
135 }
136 
137 
139  myPos(pos), mySpeed(speed) {}
140 
141 
142 /* -------------------------------------------------------------------------
143  * methods of MSVehicle::Influencer
144  * ----------------------------------------------------------------------- */
145 #ifndef NO_TRACI
147  : mySpeedAdaptationStarted(true), myConsiderSafeVelocity(true),
148  myConsiderMaxAcceleration(true), myConsiderMaxDeceleration(true) {}
149 
150 
152 
153 
154 void
155 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> > &speedTimeLine) {
156  mySpeedAdaptationStarted = true;
157  mySpeedTimeLine = speedTimeLine;
158 }
159 
160 
161 void
162 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> > &laneTimeLine) {
163  myLaneTimeLine = laneTimeLine;
164 }
165 
166 
167 SUMOReal
169  // keep original speed
170  myOriginalSpeed = speed;
171  // remove leading commands which are no longer valid
172  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
173  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
174  }
175  // do nothing if the time line does not apply for the current time
176  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
177  return speed;
178  }
179  // compute and set new speed
180  if (!mySpeedAdaptationStarted) {
181  mySpeedTimeLine[0].second = speed;
182  mySpeedAdaptationStarted = true;
183  }
184  currentTime += DELTA_T;
185  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
186  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
187  if (myConsiderSafeVelocity) {
188  speed = MIN2(speed, vSafe);
189  }
190  if (myConsiderMaxAcceleration) {
191  speed = MIN2(speed, vMax);
192  }
193  if (myConsiderMaxDeceleration) {
194  speed = MAX2(speed, vMin);
195  }
196  return speed;
197 }
198 
199 
201 MSVehicle::Influencer::checkForLaneChanges(SUMOTime currentTime, const MSEdge& currentEdge, unsigned int currentLaneIndex) {
202  // remove leading commands which are no longer valid
203  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
204  myLaneTimeLine.erase(myLaneTimeLine.begin());
205  }
206  // do nothing if the time line does not apply for the current time
207  if (myLaneTimeLine.size() < 2 || currentTime < myLaneTimeLine[0].first) {
208  return REQUEST_NONE;
209  }
210  unsigned int destinationLaneIndex = myLaneTimeLine[1].second;
211  if ((unsigned int)currentEdge.getLanes().size() <= destinationLaneIndex) {
212  return REQUEST_NONE;
213  }
214  if (currentLaneIndex > destinationLaneIndex) {
215  return REQUEST_RIGHT;
216  } else if (currentLaneIndex < destinationLaneIndex) {
217  return REQUEST_LEFT;
218  } else {
219  return REQUEST_HOLD;
220  }
221 }
222 
223 
224 void
226  myConsiderSafeVelocity = value;
227 }
228 
229 
230 void
232  myConsiderMaxAcceleration = value;
233 }
234 
235 
236 void
238  myConsiderMaxDeceleration = value;
239 }
240 #endif
241 
242 
243 /* -------------------------------------------------------------------------
244  * MSVehicle-methods
245  * ----------------------------------------------------------------------- */
247  delete myLaneChangeModel;
248  // other
249  delete myEdgeWeights;
250  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
251  (*i)->resetPartialOccupation(this);
252  }
253  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
254  if ((*i).myLink != 0) {
255  (*i).myLink->removeApproaching(this);
256  }
257  }
258  myFurtherLanes.clear();
259  //
260  if (myType->amVehicleSpecific()) {
261  delete myType;
262  }
263 #ifndef NO_TRACI
264  delete myInfluencer;
265 #endif
266 }
267 
268 
270  const MSRoute* route,
271  const MSVehicleType* type,
272  int /*vehicleIndex*/) :
273  MSBaseVehicle(pars, route, type),
275  myWaitingTime(0),
276  myState(0, 0), //
277  myLane(0),
279  myPersonDevice(0),
281  mySignals(0),
282  myAmOnNet(false),
284  myEdgeWeights(0),
286 #ifndef NO_TRACI
287  , myInfluencer(0)
288 #endif
289 {
290  for (std::vector<SUMOVehicleParameter::Stop>::iterator i = pars->stops.begin(); i != pars->stops.end(); ++i) {
291  if (!addStop(*i)) {
292  throw ProcessError("Stop for vehicle '" + pars->id +
293  "' on lane '" + i->lane + "' is not downstream the current route.");
294  }
295  }
296  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = route->getStops().begin(); i != route->getStops().end(); ++i) {
297  if (!addStop(*i)) {
298  throw ProcessError("Stop for vehicle '" + pars->id +
299  "' on lane '" + i->lane + "' is not downstream the current route.");
300  }
301  }
302  const MSLane* const depLane = (*myCurrEdge)->getDepartLane(*this);
303  if (depLane == 0) {
304  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
305  }
306  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > depLane->getMaxSpeed()) {
307  throw ProcessError("Departure speed for vehicle '" + pars->id +
308  "' is too high for the departure lane '" + depLane->getID() + "'.");
309  }
310  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
311  throw ProcessError("Departure speed for vehicle '" + pars->id +
312  "' is too high for the vehicle type '" + type->getID() + "'.");
313  }
314 #ifdef _MESSAGES
315  myLCMsgEmitter = MSNet::getInstance()->getMsgEmitter("lanechange");
316  myBMsgEmitter = MSNet::getInstance()->getMsgEmitter("break");
317  myHBMsgEmitter = MSNet::getInstance()->getMsgEmitter("heartbeat");
318 #endif
319  myLaneChangeModel = new MSLCM_DK2004(*this);
321 }
322 
323 
324 void
327  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
328  if ((*i).myLink != 0) {
329  (*i).myLink->removeApproaching(this);
330  }
331  }
332  leaveLane(reason);
333 }
334 
335 
336 // ------------ interaction with the route
337 bool
339  return myCurrEdge == myRoute->end() - 1 && myState.myPos > myArrivalPos - POSITION_EPS;
340 }
341 
342 
343 bool
344 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit) {
345  const MSEdgeVector& edges = newRoute->getEdges();
346  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
347  if (!onInit && !newRoute->contains(*myCurrEdge)) {
348  return false;
349  }
350 
351  // rebuild in-vehicle route information
352  if (onInit) {
353  myCurrEdge = newRoute->begin();
354  } else {
355  myCurrEdge = find(edges.begin(), edges.end(), *myCurrEdge);
356  }
357  // check whether the old route may be deleted (is not used by anyone else)
358  newRoute->addReference();
359  myRoute->release();
360  // assign new route
361  myRoute = newRoute;
363  // update arrival definition
365  // save information that the vehicle was rerouted
368  // recheck stops
369  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
370  if (find(edges.begin(), edges.end(), &iter->lane->getEdge()) == edges.end()) {
371  iter = myStops.erase(iter);
372  } else {
373  iter->edge = find(edges.begin(), edges.end(), &iter->lane->getEdge());
374  ++iter;
375  }
376  }
377  return true;
378 }
379 
380 
381 bool
382 MSVehicle::willPass(const MSEdge* const edge) const {
383  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
384 }
385 
386 
389  if (myEdgeWeights == 0) {
391  }
392  return *myEdgeWeights;
393 }
394 
395 
396 // ------------ Interaction with move reminders
397 void
399  // This erasure-idiom works for all stl-sequence-containers
400  // See Meyers: Effective STL, Item 9
401  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
402  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
403  rem = myMoveReminders.erase(rem);
404  } else {
405  ++rem;
406  }
407  }
408 }
409 
410 
411 void
413  // save the old work reminders, patching the position information
414  // add the information about the new offset to the old lane reminders
415  const SUMOReal oldLaneLength = myLane->getLength();
416  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
417  rem->second += oldLaneLength;
418  }
419  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
420  addReminder(*rem);
421  }
422 }
423 
424 
425 // ------------ Other getter methods
426 Position
428  if (myLane == 0) {
429  return Position(-1000, -1000);
430  }
432 }
433 
434 
435 SUMOReal
438  Position p2 = myFurtherLanes.size() > 0
439  ? myFurtherLanes.front()->getShape().positionAtLengthPosition(myFurtherLanes.front()->getPartialOccupatorEnd())
441  if (p1 != p2) {
442  return atan2(p1.x() - p2.x(), p2.y() - p1.y()) * 180. / PI;
443  } else {
445  }
446 }
447 
448 
449 // ------------
450 bool
452  Stop stop;
453  stop.lane = MSLane::dictionary(stopPar.lane);
454  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
455  stop.startPos = stopPar.startPos;
456  stop.endPos = stopPar.endPos;
457  stop.duration = stopPar.duration;
458  stop.until = stopPar.until;
459  if (stop.until != -1) {
460  stop.until += untilOffset;
461  }
462  stop.triggered = stopPar.triggered;
463  stop.parking = stopPar.parking;
464  stop.reached = false;
465  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
466  return false;
467  }
468  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
469  MSRouteIterator prevStopEdge = myCurrEdge;
470  SUMOReal prevStopPos = myState.myPos;
471  // where to insert the stop
472  std::list<Stop>::iterator iter = myStops.begin();
473  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
474  if (myStops.size() > 0) {
475  prevStopEdge = myStops.back().edge;
476  prevStopPos = myStops.back().endPos;
477  iter = myStops.end();
478  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
479  }
480  } else {
481  if (stopPar.index == STOP_INDEX_FIT) {
482  while (iter != myStops.end() && (iter->edge < stop.edge ||
483  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
484  prevStopEdge = iter->edge;
485  prevStopPos = iter->endPos;
486  ++iter;
487  }
488  } else {
489  int index = stopPar.index;
490  while (index > 0) {
491  prevStopEdge = iter->edge;
492  prevStopPos = iter->endPos;
493  ++iter;
494  --index;
495  }
496  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
497  }
498  }
499  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge || prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
500  return false;
501  }
503  return false;
504  }
505  myStops.insert(iter, stop);
506  return true;
507 }
508 
509 
510 bool
512  return !myStops.empty() && myStops.begin()->reached;
513 }
514 
515 
516 bool
518  return isStopped() && myStops.begin()->parking;
519 }
520 
521 
522 SUMOReal
524  if (myStops.empty()) {
525  // no stops; pass
526  return currentVelocity;
527  }
528  Stop& stop = myStops.front();
529  if (stop.reached) {
530  // ok, we have already reached the next stop
531  // any waiting persons may board now
532  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this);
533  if (boarded) {
534  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
535  stop.triggered = false;
539  }
540  }
541  if (stop.duration <= 0 && !stop.triggered) {
542  // we have waited long enough and fulfilled any passenger-requirements
543  if (stop.busstop != 0) {
544  // inform bus stop about leaving it
545  stop.busstop->leaveFrom(this);
546  }
547  // the current stop is no longer valid
549  myStops.pop_front();
550  // do not count the stopping time towards gridlock time.
551  // Other outputs use an independent counter and are not affected.
552  myWaitingTime = 0;
553  // maybe the next stop is on the same edge; let's rebuild best lanes
554  getBestLanes(true);
555  // continue as wished...
556  } else {
557  // we have to wait some more time
559  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
562  }
563  stop.duration -= DELTA_T;
564  return 0;
565  }
566  } else {
567  // is the next stop on the current lane?
568  if (stop.edge == myCurrEdge) {
569  // get the stopping position
570  SUMOReal endPos = stop.endPos;
571  bool busStopsMustHaveSpace = true;
572  if (stop.busstop != 0) {
573  // on bus stops, we have to wait for free place if they are in use...
574  endPos = stop.busstop->getLastFreePos(*this);
575  if (endPos - 5. < stop.busstop->getBeginLanePosition()) { // !!! explicit offset
576  busStopsMustHaveSpace = false;
577  }
578  }
579  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace) {
580  // ok, we may stop (have reached the stop)
581  stop.reached = true;
583  // compute stopping time
584  if (stop.until >= 0) {
585  if (stop.duration == -1) {
587  } else {
589  }
590  }
591  if (stop.busstop != 0) {
592  // let the bus stop know the vehicle
594  }
595  }
596  // decelerate
597  return getCarFollowModel().stopSpeed(this, endPos - myState.pos());
598  }
599  }
600  return currentVelocity;
601 }
602 
603 
604 bool
606  const MSVehicle* const pred,
607  const MSVehicle* const neigh,
608  SUMOReal lengthsInFront) {
609 #ifdef _MESSAGES
610  if (myHBMsgEmitter != 0) {
611  if (isOnRoad()) {
613  myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
614  }
615  }
616 #endif
617 #ifdef DEBUG_VEHICLE_GUI_SELECTION
618  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
619  int bla = 0;
620  }
621 #endif
622  // remove information about approaching links, will be reset later in this step
623  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
624  if ((*i).myLink != 0) {
625  (*i).myLink->removeApproaching(this);
626  }
627  }
628  myLFLinkLanes.clear();
629  //
630  const MSCFModel& cfModel = getCarFollowModel();
631  SUMOReal vBeg = MIN2(cfModel.maxNextSpeed(myState.mySpeed), lane->getMaxSpeed());
632  // check whether the vehicle is not on an appropriate lane
633  bool onAppropriateLane = myLane->appropriate(this);
634  if (!onAppropriateLane) {
635  // decelerate to lane end when yes
637  vBeg = MIN2(cfModel.stopSpeed(this, myLane->getLength() - myState.myPos - place), myLane->getMaxSpeed());
638  }
639  if (myCurrEdge == myRoute->end() - 1) {
642  } else {
643  vBeg = myLane->getMaxSpeed();
644  }
645  }
646  // interaction with leader
647  if (pred != 0) {
648  // interaction with leader if one exists on same lane
649  SUMOReal gap = gap2pred(*pred);
650  if (MSGlobals::gCheck4Accidents && gap < 0) {
651  // collision occured!
652  return true;
653  }
654  vBeg = MIN2(vBeg, cfModel.followSpeed(this, getSpeed(), gap2pred(*pred), pred->getSpeed(), pred->getCarFollowModel().getMaxDecel()));
655  } else {
656  // (potential) interaction with a vehicle extending partially into this lane
658  if (predP != 0 && predP != this) {
660  if (MSGlobals::gCheck4Accidents && gap < 0) {
661  // collision occured!
662  return true;
663  }
664  vBeg = MIN2(vBeg, cfModel.followSpeed(this, getSpeed(), gap, predP->getSpeed(), predP->getCarFollowModel().getMaxDecel()));
665  }
666  }
667  // interaction with left-lane leader (do not overtake right)
668  cfModel.leftVehicleVsafe(this, neigh, vBeg);
669  // check whether the vehicle wants to stop somewhere
670  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
671  const Stop& stop = *myStops.begin();
672  SUMOReal stopPos = stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this) - POSITION_EPS;
673  SUMOReal seen = lane->getLength() - myState.pos();
674  SUMOReal vsafeStop = cfModel.stopSpeed(this, seen - (lane->getLength() - stopPos));
675  vBeg = MIN2(vBeg, vsafeStop);
676  }
677  vBeg = MAX2((SUMOReal) 0, vBeg);
678 #ifdef _DEBUG
679  if (vBeg < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) {
680  WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#1; is: " + toString(myState.mySpeed - vBeg) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")");
681  }
682 #endif
683  if (!onAppropriateLane) {
684  myLFLinkLanes.push_back(DriveProcessItem(0, vBeg, vBeg, false, 0, 0, myLane->getLength() - myState.myPos - getVehicleType().getMinGap()));
685  } else {
686  // check whether the driver wants to let someone in
687  vsafeCriticalCont(t, vBeg);
688  checkRewindLinkLanes(lengthsInFront);
689  }
690  return false;
691 }
692 
693 
694 bool
696 #ifdef DEBUG_VEHICLE_GUI_SELECTION
697  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
698  int bla = 0;
699  }
700 #endif
701  // get vsafe
702  SUMOReal vSafe = 0;
703  myHaveToWaitOnNextLink = false;
704 
705  assert(myLFLinkLanes.size() != 0);
706  DriveItemVector::iterator i;
707  bool braking = false;
708  bool lastWasGreenCont = false;
709  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
710  MSLink* link = (*i).myLink;
711  // the vehicle must change the lane on one of the next lanes
712  if (link != 0 && (*i).mySetRequest) {
713  const LinkState ls = link->getState();
714  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
715  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
717  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
718  vSafe = (*i).myVLinkWait;
719  braking = true;
720  lastWasGreenCont = false;
721  link->removeApproaching(this);
722  break;
723  }
724  //
725  const bool opened = yellow || link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, getVehicleType().getLengthWithGap());
726  // vehicles should decelerate when approaching a minor link
727  if (opened && !lastWasGreenCont && !link->havePriority() && (*i).myDistance > getCarFollowModel().getMaxDecel()) {
728  vSafe = (*i).myVLinkWait;
729  braking = true;
730  lastWasGreenCont = false;
731  if (ls == LINKSTATE_EQUAL) {
732  link->removeApproaching(this);
733  }
734  break; // could be revalidated
735  }
736  // have waited; may pass if opened...
737  if (opened) {
738  vSafe = (*i).myVLinkPass;
739  lastWasGreenCont = link->isCont() && (ls == LINKSTATE_TL_GREEN_MAJOR);
740  } else {
741  lastWasGreenCont = false;
742  vSafe = (*i).myVLinkWait;
743  braking = true;
744  if (ls == LINKSTATE_EQUAL) {
745  link->removeApproaching(this);
746  }
747  break;
748  }
749  } else {
750  vSafe = (*i).myVLinkWait;
751  braking = true;
752  break;
753  }
754  }
755 
756  if (braking) {
757  myHaveToWaitOnNextLink = true;
758  }
759 
760  SUMOReal vNext = getCarFollowModel().moveHelper(this, vSafe);
761  vNext = MAX2(vNext, (SUMOReal) 0.);
762 #ifndef NO_TRACI
763  if (myInfluencer != 0) {
764  SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
766  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
767  }
768 #endif
769  // visit waiting time
770  if (vNext <= 0.1) {
772  braking = true;
773  } else {
774  myWaitingTime = 0;
775  }
776  if (myState.mySpeed < vNext) {
777  braking = false;
778  }
779  if (braking) {
781  } else {
783  }
784  // call reminders after vNext is set
785  SUMOReal pos = myState.myPos;
786  vNext = MIN2(vNext, getMaxSpeed());
787 
788 #ifdef _MESSAGES
789  if (myHBMsgEmitter != 0) {
790  if (isOnRoad()) {
792  myHBMsgEmitter->writeHeartBeatEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
793  }
794  }
795  if (myBMsgEmitter != 0) {
796  if (vNext < myState.mySpeed) {
798  myBMsgEmitter->writeBreakEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), getPosition().x(), getPosition().y());
799  }
800  }
801 #endif
802  // update position and speed
803  myState.myPos += SPEED2DIST(vNext);
804  myState.mySpeed = vNext;
805  std::vector<MSLane*> passedLanes;
806  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
807  passedLanes.push_back(*i);
808  }
809  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
810  passedLanes.push_back(myLane);
811  }
812  bool moved = true;
813  // move on lane(s)
814  if (myState.myPos <= myLane->getLength()) {
815  // we are staying at our lane
816  // there is no need to go over succeeding lanes
817  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
818  moved = false;
819  } else {
820  // we are moving at least to the next lane (maybe pass even more than one)
821  if (myCurrEdge != myRoute->end() - 1) {
822  MSLane* approachedLane = myLane;
823  // move the vehicle forward
824  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
826  MSLink* link = (*i).myLink;
827  // check whether the vehicle was allowed to enter lane
828  // otherwise it is decelareted and we do not need to test for it's
829  // approach on the following lanes when a lane changing is performed
830  myState.myPos -= approachedLane->getLength();
831  assert(myState.myPos > 0);
832  // proceed to the next lane
833  if (link != 0) {
834 #ifdef HAVE_INTERNAL_LANES
835  approachedLane = link->getViaLane();
836  if (approachedLane == 0) {
837  approachedLane = link->getLane();
838  }
839 #else
840  approachedLane = link->getLane();
841 #endif
842  } else {
843  approachedLane = 0;
844  }
845  if (approachedLane != myLane && approachedLane != 0) {
846  enterLaneAtMove(approachedLane);
847  myLane = approachedLane;
848  if (approachedLane->getEdge().isVaporizing()) {
849  break;
850  }
851  }
852  passedLanes.push_back(approachedLane);
853  }
854  }
855  }
856  // clear previously set information
857  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
858  (*i)->resetPartialOccupation(this);
859  }
860  myFurtherLanes.clear();
861  if (!ends()) {
862  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
863  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
864  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
865  while (leftLength > 0 && i != passedLanes.rend()) {
866  myFurtherLanes.push_back(*i);
867  leftLength -= (*i)->setPartialOccupation(this, leftLength);
868  ++i;
869  }
870  }
872  }
873  return moved;
874 }
875 
876 
877 SUMOReal
879  SUMOReal lengths = 0;
880  const MSLane::VehCont& vehs = l->getVehiclesSecure();
881  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
882  if ((*i)->getSpeed() < .1) {
883  foundStopped = true;
884  SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
885  l->releaseVehicles();
886  return ret;
887  }
888  lengths += (*i)->getVehicleType().getLengthWithGap();
889  }
890  l->releaseVehicles();
891  return l->getLength() - lengths;
892 }
893 
894 
895 void
897 #ifdef DEBUG_VEHICLE_GUI_SELECTION
898  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
899  int bla = 0;
900  if (MSNet::getInstance()->getCurrentTimeStep() == 152000) {
901  bla = 0;
902  }
903  }
904 #endif
905 #ifdef HAVE_INTERNAL_LANES
907  int removalBegin = -1;
908  bool hadVehicle = false;
909  SUMOReal seenSpace = -lengthsInFront;
910 
911  std::vector<SUMOReal> availableSpace;
912  std::vector<bool> hadVehicles;
913  bool foundStopped = false;
914 
915  for (unsigned int i = 0; i < myLFLinkLanes.size(); ++i) {
916  // skip unset links
917  DriveProcessItem& item = myLFLinkLanes[i];
918  if (item.myLink == 0 || foundStopped) {
919  availableSpace.push_back(seenSpace);
920  hadVehicles.push_back(hadVehicle);
921  continue;
922  }
923  // get the next lane, determine whether it is an internal lane
924  MSLane* approachedLane = item.myLink->getViaLane();
925  if (approachedLane != 0) {
926  if (item.myLink->isCrossing()/* && item.myLink->willHaveBlockedFoe()*/) {
927  seenSpace = seenSpace - approachedLane->getVehLenSum();
928  hadVehicle |= approachedLane->getVehicleNumber() != 0;
929  } else {
930  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
931  hadVehicle |= approachedLane->getVehicleNumber() != 0;
932  }
933  availableSpace.push_back(seenSpace);
934  hadVehicles.push_back(hadVehicle);
935  continue;
936  }
937  approachedLane = item.myLink->getLane();
938  MSVehicle* last = approachedLane->getLastVehicle();
939  if (last == 0) {
940  last = approachedLane->getPartialOccupator();
941  if (last != 0) {
942  SUMOReal m = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
943  availableSpace.push_back(m);
944  hadVehicle = true;
945  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
946  if (last->myHaveToWaitOnNextLink) {
947  foundStopped = true;
948  }
949  } else {
950 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
951 // availableSpace.push_back(seenSpace);
952  availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped));
953  if (!foundStopped) {
954  seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
955  } else {
956  seenSpace = availableSpace.back();
957  }
958  }
959  } else {
960  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
961  SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
962  SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
963  SUMOReal m = MAX2(seenSpace, seenSpace + lastGap);
964  availableSpace.push_back(m);
965  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getVehLenSum() + approachedLane->getLength();
966  } else {
967 // seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
968 // availableSpace.push_back(seenSpace);
969  availableSpace.push_back(seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped));
970  if (!foundStopped) {
971  seenSpace = seenSpace - approachedLane->getVehLenSum() + approachedLane->getLength();
972  } else {
973  seenSpace = availableSpace.back();
974  }
975  }
976  if (last->myHaveToWaitOnNextLink) {
977  foundStopped = true;
978  }
979  hadVehicle = true;
980  }
981  hadVehicles.push_back(hadVehicle);
982  }
983 #ifdef DEBUG_VEHICLE_GUI_SELECTION
984  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
985  int bla = 0;
986  }
987 #endif
989  for (int i = (int)(myLFLinkLanes.size() - 1); i > 0; --i) {
990  DriveProcessItem& item = myLFLinkLanes[i - 1];
991  bool opened = item.myLink != 0 && (item.myLink->havePriority() || item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,/*t, .1,*/ getVehicleType().getLengthWithGap()));
992  bool check1 = item.myLink == 0 || item.myLink->isCont() || !hadVehicles[i];
993  bool allowsContinuation = check1 || opened;
994  if (!opened && item.myLink != 0) {
995  if (i > 1) {
996  DriveProcessItem& item2 = myLFLinkLanes[i - 2];
997  if (item2.myLink != 0 && item2.myLink->isCont()) {
998  allowsContinuation = true;
999  }
1000  }
1001  }
1002  if (allowsContinuation) {
1003  availableSpace[i - 1] = availableSpace[i];
1004  }
1005  }
1006 
1007  for (unsigned int i = 0; hadVehicle && i < myLFLinkLanes.size() && removalBegin < 0; ++i) {
1008  // skip unset links
1009  DriveProcessItem& item = myLFLinkLanes[i];
1010  if (item.myLink == 0) {
1011  continue;
1012  }
1013  /*
1014  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1015  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1016  removalBegin = lastLinkToInternal;
1017  }
1018  */
1019 
1020  SUMOReal leftSpace = availableSpace[i] - getVehicleType().getLengthWithGap();
1021  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1022  SUMOReal impatienceCorrection = 0;
1023  /*
1024  if(item.myLink->getState()==LINKSTATE_MINOR) {
1025  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1026  }
1027  */
1028  if (leftSpace < -impatienceCorrection / 10.) {
1029  removalBegin = i;
1030  }
1031  //removalBegin = i;
1032  }
1033  }
1034  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1035  while (removalBegin < (int)(myLFLinkLanes.size())) {
1037  myLFLinkLanes[removalBegin].myVLinkPass = myLFLinkLanes[removalBegin].myVLinkWait;
1038  if(myLFLinkLanes[removalBegin].myDistance>=brakeGap||(myLFLinkLanes[removalBegin].myDistance>0&&myState.mySpeed<ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1039  myLFLinkLanes[removalBegin].mySetRequest = false;
1040  }
1041  ++removalBegin;
1042  }
1043  }
1044  }
1045 #endif
1046  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1047  if ((*i).myLink != 0) {
1048  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).mySetRequest);
1049  }
1050  }
1051 }
1052 
1053 
1054 
1055 void
1057 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1058  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1059  int bla = 0;
1060  }
1061 #endif
1062 #ifndef NO_TRACI
1063  if (myInfluencer != 0) {
1064  SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1066  boundVSafe = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), boundVSafe, boundVSafe, vMin, vMax);
1067  }
1068 #endif
1069  const MSCFModel& cfModel = getCarFollowModel();
1070  // the vehicle may have just to look into the next lane
1071  // compute this information and use it only once in the next loop
1072  SUMOReal seen = myLane->getLength() - myState.myPos;
1073  SUMOReal seenNonInternal = 0;
1074  //
1075  if (this != myLane->getFirstVehicle() && seen - cfModel.brakeGap(myState.mySpeed) > 0 && seen - SPEED2DIST(boundVSafe) - ACCEL2DIST(cfModel.getMaxAccel()) > 0) {
1076  // not "reaching critical"
1078  myLFLinkLanes.push_back(DriveProcessItem(0, boundVSafe, boundVSafe, false, 0, 0, seen - place));
1079  return;
1080  }
1081 
1082  MSLane* nextLane = myLane;
1083  // compute the way the vehicle would drive if it would use the current speed and then
1084  // decelerate
1085  SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed);
1086  SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1087  SUMOReal vLinkPass = boundVSafe;
1088  SUMOReal vLinkWait = vLinkPass;
1089  const std::vector<MSLane*> &bestLaneConts = getBestLanesContinuation();
1090 #ifdef HAVE_INTERNAL_LANES
1091  bool hadNonInternal = false;
1092 #else
1093  bool hadNonInternal = true;
1094 #endif
1095 
1096  unsigned int view = 1;
1097  // loop over following lanes
1098  while (true) {
1099  // process stops
1100  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &nextLane->getEdge()) {
1101  const Stop& stop = *myStops.begin();
1102  const SUMOReal vsafeStop = stop.busstop == 0
1103  ? cfModel.stopSpeed(this, seen + stop.endPos)
1104  : cfModel.stopSpeed(this, seen + stop.busstop->getLastFreePos(*this) - POSITION_EPS);
1105  vLinkPass = MIN2(vLinkPass, vsafeStop);
1106  vLinkWait = MIN2(vLinkWait, vsafeStop);
1107  }
1108 
1109  // get the next link used
1110  MSLinkCont::const_iterator link = myLane->succLinkSec(*this, view, *nextLane, bestLaneConts);
1111 
1112  // check whether the lane is a dead end
1113  // (should be valid only on further loop iterations
1114  SUMOReal place = MIN2(nextLane->getLength() - (SUMOReal)POSITION_EPS, getVehicleType().getMinGap());
1115  if (nextLane->isLinkEnd(link)) {
1116  SUMOReal laneEndVSafe = cfModel.stopSpeed(this, seen - place);
1117  if (myCurrEdge + view == myRoute->end()) {
1119  laneEndVSafe = cfModel.freeSpeed(this, getSpeed(), seen, myParameter->arrivalSpeed);
1120  } else {
1121  laneEndVSafe = vLinkPass;
1122  }
1123  }
1124  // the vehicle will not drive further
1125  assert(MIN2(vLinkPass, laneEndVSafe) >= cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1126  myLFLinkLanes.push_back(DriveProcessItem(0, MIN2(vLinkPass, laneEndVSafe), MIN2(vLinkPass, laneEndVSafe), false, 0, 0, seen));
1127  return;
1128  }
1129  // the link was passed
1130  vLinkWait = vLinkPass;
1131 
1132 
1133  // get the following lane
1134 #ifdef HAVE_INTERNAL_LANES
1135  nextLane = (*link)->getViaLane();
1136  if (nextLane == 0) {
1137  nextLane = (*link)->getLane();
1138  hadNonInternal = true;
1139  view++;
1140  }
1141 #else
1142  nextLane = (*link)->getLane();
1143  view++;
1144 #endif
1145 
1146  // compute the velocity to use when the link is not blocked by other vehicles
1147  // the vehicle shall be not faster when reaching the next lane than allowed
1148  SUMOReal vmaxNextLane = MAX2(cfModel.freeSpeed(this, getSpeed(), seen, nextLane->getMaxSpeed()), nextLane->getMaxSpeed());
1149 
1150  // the vehicle shall keep a secure distance to its predecessor
1151  // (or approach the lane end if the predeccessor is too near)
1152  SUMOReal vsafePredNextLane = 100000;
1153  std::pair<MSVehicle*, SUMOReal> lastOnNext = nextLane->getLastVehicleInformation();
1154  if (lastOnNext.first != 0) {
1155  if (seen + lastOnNext.second >= 0) {
1156  vsafePredNextLane = cfModel.followSpeed(this, getSpeed(), seen + lastOnNext.second - getVehicleType().getMinGap(), lastOnNext.first->getSpeed(), lastOnNext.first->getCarFollowModel().getMaxDecel());
1157  } else {
1158  vsafePredNextLane = cfModel.stopSpeed(this, seen - place);
1159  }
1160  }
1161 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1162  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1163  int bla = 0;
1164  }
1165 #endif
1166  // compute the velocity to use when the link may be used
1167  vLinkPass = MIN3(vLinkPass, vmaxNextLane, vsafePredNextLane);
1168 
1169  // if the link may not be used (is blocked by another vehicle) then let the
1170  // vehicle decelerate until the end of the street
1171  vLinkWait = MIN3(vLinkPass, vLinkWait, cfModel.stopSpeed(this, seen - place));
1172 #ifdef _DEBUG
1173  if (vLinkWait < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) {
1174  WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#2; is: " + toString(myState.mySpeed - vLinkWait) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")");
1175  }
1176 #endif
1177 
1178  // behaviour in front of not priorised intersections (waiting for priorised foe vehicles)
1179  bool setRequest = false;
1180  // process stops
1181  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &nextLane->getEdge()) {
1182  const Stop& stop = *myStops.begin();
1183  const SUMOReal vsafeStop = stop.busstop == 0
1184  ? cfModel.stopSpeed(this, seen + stop.endPos)
1185  : cfModel.stopSpeed(this, seen + stop.busstop->getLastFreePos(*this) - POSITION_EPS);
1186  vLinkPass = MIN2(vLinkPass, vsafeStop);
1187  vLinkWait = MIN2(vLinkWait, vsafeStop);
1188  }
1189  // check whether we approach the final edge
1190  if (myCurrEdge + view == myRoute->end()) {
1192  const SUMOReal vsafe = cfModel.freeSpeed(this, getSpeed(), seen + myArrivalPos, myParameter->arrivalSpeed);
1193  vLinkPass = MIN2(vLinkPass, vsafe);
1194  vLinkWait = MIN2(vLinkWait, vsafe);
1195  }
1196  }
1197 
1198  setRequest |= ((*link)->getState() != LINKSTATE_TL_RED && vLinkPass > 0);
1199 // setRequest |= (seen < cfModel.brakeGap(myState.mySpeed) + SPEED2DIST(myState.mySpeed)*cfModel.getHeadwayTime());
1200  bool yellow = (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR || (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1201  bool red = (*link)->getState() == LINKSTATE_TL_RED;
1202  if ((yellow || red) && seen > cfModel.brakeGap(myState.mySpeed) - myState.mySpeed*cfModel.getHeadwayTime()) {
1203  vLinkPass = vLinkWait;
1204  setRequest = false;
1205  assert(vLinkWait >= cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1206  myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / vLinkPass), vLinkPass, seen));
1207  }
1208  // the next condition matches the previously one used for determining the difference
1209  // between critical/non-critical vehicles. Though, one should assume that a vehicle
1210  // should want to move over an intersection even though it could brake before it!?
1211  //setRequest &= dist - seen > 0;
1212 #ifdef _DEBUG
1213  if (MIN2(vLinkPass, vLinkWait) < cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) {
1214  WRITE_WARNING("Vehicle '" + getID() + "' is decelerating too much (#3; is: " + toString(myState.mySpeed - MIN2(vLinkPass, vLinkWait)) + ", may: " + toString(cfModel.getSpeedAfterMaxDecel(myState.mySpeed)) + ")");
1215  }
1216 #endif
1217  myLFLinkLanes.push_back(DriveProcessItem(*link, vLinkPass, vLinkWait, setRequest, t + TIME2STEPS(seen / vLinkPass), vLinkPass, seen));
1218  seen += nextLane->getLength();
1219  seenNonInternal += nextLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : nextLane->getLength();
1220  if (!setRequest || ((vLinkPass <= 0 || seen > dist) && hadNonInternal && seenNonInternal > 50)) {
1221  return;
1222  }
1223  }
1224 }
1225 
1226 
1227 void
1229  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1230  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1231  ++rem;
1232  } else {
1233  if (rem->first->notifyEnter(*this, reason)) {
1234  ++rem;
1235  } else {
1236  rem = myMoveReminders.erase(rem);
1237  }
1238  }
1239  }
1240 }
1241 
1242 
1243 bool
1244 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1245  myAmOnNet = true;
1246  // vaporizing edge?
1247  /*
1248  if (enteredLane->getEdge().isVaporizing()) {
1249  // yep, let's do the vaporization...
1250  myLane = enteredLane;
1251  return true;
1252  }
1253  */
1254  if (!onTeleporting) {
1255  // move mover reminder one lane further
1256  adaptLaneEntering2MoveReminder(*enteredLane);
1257  // set the entered lane as the current lane
1258  myLane = enteredLane;
1259  }
1260 
1261  // internal edges are not a part of the route...
1262  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1263  assert(&enteredLane->getEdge() == *(myCurrEdge + 1));
1264  ++myCurrEdge;
1265  }
1266  if (!onTeleporting) {
1267  // may be optimized: compute only, if the current or the next have more than one lane...!!!
1268  getBestLanes(true);
1270 #ifndef NO_TRACI
1271  if (myInfluencer != 0) {
1273  }
1274 #endif
1275  }
1276  return ends();
1277 }
1278 
1279 
1280 void
1282  myAmOnNet = true;
1283 #ifdef _MESSAGES
1284  if (myLCMsgEmitter != 0) {
1286  myLCMsgEmitter->writeLaneChangeEvent(myParameter->id, timeStep, myLane, myState.pos(), myState.speed(), enteredLane, getPosition().x(), getPosition().y());
1287  }
1288 #endif
1289  myLane = enteredLane;
1290  // switch to and activate the new lane's reminders
1291  // keep OldLaneReminders
1292  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1293  addReminder(*rem);
1294  }
1296  SUMOReal leftLength = myState.myPos - getVehicleType().getLength();
1297  if (leftLength < 0) {
1298  // we have to rebuild "further lanes"
1299  const MSRoute& route = getRoute();
1301  MSLane* lane = myLane;
1302  while (i != route.begin() && leftLength > 0) {
1303  const MSEdge* const prev = *(--i);
1304  const std::vector<MSLane::IncomingLaneInfo> &incomingLanes = lane->getIncomingLanes();
1305  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = incomingLanes.begin(); j != incomingLanes.end(); ++j) {
1306  if (&(*j).lane->getEdge() == prev) {
1307 #ifdef HAVE_INTERNAL_LANES
1308  (*j).lane->setPartialOccupation(this, leftLength);
1309 #else
1310  leftLength -= (*j).length;
1311  (*j).lane->setPartialOccupation(this, leftLength);
1312 #endif
1313  leftLength -= (*j).lane->getLength();
1314  break;
1315  }
1316  }
1317  }
1318  }
1319 #ifndef NO_TRACI
1320  // check if further changes are necessary
1321  if (myInfluencer != 0) {
1323  }
1324 #endif
1325 }
1326 
1327 
1328 void
1330  myState = State(pos, speed);
1331  assert(myState.myPos >= 0);
1332  assert(myState.mySpeed >= 0);
1333  myWaitingTime = 0;
1334  myLane = enteredLane;
1335  // set and activate the new lane's reminders
1336  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1337  addReminder(*rem);
1338  }
1339  activateReminders(notification);
1340  std::string msg;
1341  if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) {
1342  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
1343  }
1344  myAmOnNet = true;
1345  // build the list of lanes the vehicle is lapping into
1346  SUMOReal leftLength = myType->getLength() - pos;
1347  MSLane* clane = enteredLane;
1348  while (leftLength > 0) {
1349  clane = clane->getLogicalPredecessorLane();
1350  if (clane == 0) {
1351  break;
1352  }
1353  myFurtherLanes.push_back(clane);
1354  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1355  }
1356 }
1357 
1358 
1359 void
1361  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1362  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1363  ++rem;
1364  } else {
1365  rem = myMoveReminders.erase(rem);
1366  }
1367  }
1368  if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
1369  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1370  (*i)->resetPartialOccupation(this);
1371  }
1372  myFurtherLanes.clear();
1373  }
1374  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1375  myAmOnNet = false;
1376  }
1377 }
1378 
1379 
1382  return *myLaneChangeModel;
1383 }
1384 
1385 
1388  return *myLaneChangeModel;
1389 }
1390 
1391 
1392 const std::vector<MSVehicle::LaneQ> &
1393 MSVehicle::getBestLanes(bool forceRebuild, MSLane* startLane) const {
1394 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1395  if (gSelected.isSelected(GLO_VEHICLE, static_cast<const GUIVehicle*>(this)->getGlID())) {
1396  int bla = 0;
1397  myLastBestLanesEdge = 0;
1398  }
1399 #endif
1400 
1401  if (startLane == 0) {
1402  startLane = myLane;
1403  }
1404  // update occupancy and current lane index, only, if the vehicle has not moved to a new lane
1405  if (myLastBestLanesEdge == &startLane->getEdge() && !forceRebuild) {
1406  std::vector<LaneQ> &lanes = *myBestLanes.begin();
1407  std::vector<LaneQ>::iterator i;
1408  for (i = lanes.begin(); i != lanes.end(); ++i) {
1409  SUMOReal nextOccupation = 0;
1410  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1411  nextOccupation += (*j)->getVehLenSum();
1412  }
1413  (*i).nextOccupation = nextOccupation;
1414  if ((*i).lane == startLane) {
1416  }
1417  }
1418  return *myBestLanes.begin();
1419  }
1420  // start rebuilding
1421  myLastBestLanesEdge = &startLane->getEdge();
1422  myBestLanes.clear();
1423 
1424  // get information about the next stop
1425  const MSEdge* nextStopEdge = 0;
1426  const MSLane* nextStopLane = 0;
1427  SUMOReal nextStopPos = 0;
1428  if (!myStops.empty()) {
1429  const Stop& nextStop = myStops.front();
1430  nextStopLane = nextStop.lane;
1431  nextStopEdge = &nextStopLane->getEdge();
1432  nextStopPos = nextStop.startPos;
1433  }
1434  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
1435  nextStopEdge = *(myRoute->end() - 1);
1436  nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane];
1437  nextStopPos = myArrivalPos;
1438  }
1439 
1440  // go forward along the next lanes;
1441  int seen = 0;
1442  SUMOReal seenLength = 0;
1443  bool progress = true;
1444  for (MSRouteIterator ce = myCurrEdge; progress;) {
1445  std::vector<LaneQ> currentLanes;
1446  const std::vector<MSLane*> *allowed = 0;
1447  const MSEdge* nextEdge = 0;
1448  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
1449  nextEdge = *(ce + 1);
1450  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
1451  }
1452  const std::vector<MSLane*> &lanes = (*ce)->getLanes();
1453  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
1454  LaneQ q;
1455  MSLane* cl = *i;
1456  q.lane = cl;
1457  q.bestContinuations.push_back(cl);
1458  q.bestLaneOffset = 0;
1459  q.length = cl->getLength();
1460  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
1461  currentLanes.push_back(q);
1462  }
1463  //
1464  if (nextStopEdge == *ce) {
1465  progress = false;
1466  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
1467  if (nextStopLane != (*q).lane) {
1468  (*q).allowsContinuation = false;
1469  (*q).length = nextStopPos;
1470  }
1471  }
1472  }
1473 
1474  myBestLanes.push_back(currentLanes);
1475  ++seen;
1476  seenLength += currentLanes[0].lane->getLength();
1477  ++ce;
1478  progress &= (seen <= 4 || seenLength < 3000);
1479  progress &= seen <= 8;
1480  progress &= ce != myRoute->end();
1481  /*
1482  if(progress) {
1483  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
1484  }
1485  */
1486  }
1487 
1488  // we are examining the last lane explicitly
1489  if (myBestLanes.size() != 0) {
1490  SUMOReal bestLength = -1;
1491  int bestThisIndex = 0;
1492  int index = 0;
1493  std::vector<LaneQ> &last = myBestLanes.back();
1494  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1495  if ((*j).length > bestLength) {
1496  bestLength = (*j).length;
1497  bestThisIndex = index;
1498  }
1499  }
1500  index = 0;
1501  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
1502  if ((*j).length < bestLength) {
1503  (*j).bestLaneOffset = bestThisIndex - index;
1504  }
1505  }
1506  }
1507 
1508  // go backward through the lanes
1509  // track back best lane and compute the best prior lane(s)
1510  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
1511  std::vector<LaneQ> &nextLanes = (*(i - 1));
1512  std::vector<LaneQ> &clanes = (*i);
1513  MSEdge& cE = clanes[0].lane->getEdge();
1514  int index = 0;
1515  SUMOReal bestConnectedLength = -1;
1516  SUMOReal bestLength = -1;
1517  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
1518  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
1519  bestConnectedLength = (*j).length;
1520  }
1521  if (bestLength < (*j).length) {
1522  bestLength = (*j).length;
1523  }
1524  }
1525  if (bestConnectedLength > 0) {
1526  int bestThisIndex = 0;
1527  index = 0;
1528  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1529  LaneQ bestConnectedNext;
1530  bestConnectedNext.length = -1;
1531  if ((*j).allowsContinuation) {
1532  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
1533  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1534  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
1535  bestConnectedNext = *m;
1536  }
1537  }
1538  }
1539  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
1540  (*j).length += bestLength;
1541  } else {
1542  (*j).length += bestConnectedNext.length;
1543  }
1544  }
1545  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(abs(clanes[bestThisIndex].bestLaneOffset > (*j).bestLaneOffset)))) {
1546  bestThisIndex = index;
1547  }
1548  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
1549  }
1550 
1551  index = 0;
1552  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1553  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) < abs(clanes[bestThisIndex].bestLaneOffset))) {
1554  (*j).bestLaneOffset = bestThisIndex - index;
1555  } else {
1556  (*j).bestLaneOffset = 0;
1557  }
1558  }
1559 
1560  } else {
1561 
1562  int bestThisIndex = 0;
1563  int bestNextIndex = 0;
1564  int bestDistToNeeded = (int) clanes.size();
1565  index = 0;
1566  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1567  if ((*j).allowsContinuation) {
1568  int nextIndex = 0;
1569  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
1570  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
1571  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
1572  bestDistToNeeded = abs((*m).bestLaneOffset);
1573  bestThisIndex = index;
1574  bestNextIndex = nextIndex;
1575  }
1576  }
1577  }
1578  }
1579  }
1580  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
1581  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
1582  index = 0;
1583  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
1584  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) < abs(clanes[bestThisIndex].bestLaneOffset))) {
1585  (*j).bestLaneOffset = bestThisIndex - index;
1586  } else {
1587  (*j).bestLaneOffset = 0;
1588  }
1589  }
1590 
1591  }
1592 
1593  }
1594 
1595  // update occupancy and current lane index
1596  std::vector<LaneQ> &currLanes = *myBestLanes.begin();
1597  std::vector<LaneQ>::iterator i;
1598  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
1599  SUMOReal nextOccupation = 0;
1600  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
1601  nextOccupation += (*j)->getVehLenSum();
1602  }
1603  (*i).nextOccupation = nextOccupation;
1604  if ((*i).lane == startLane) {
1606  }
1607  }
1608  return *myBestLanes.begin();
1609 }
1610 
1611 
1612 const std::vector<MSLane*> &
1614  if (myBestLanes.empty() || myBestLanes[0].empty() || myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1615  return myEmptyLaneVector;
1616  }
1617  return (*myCurrentLaneInBestLanes).bestContinuations;
1618 }
1619 
1620 
1621 const std::vector<MSLane*> &
1623  for (std::vector<std::vector<LaneQ> >::const_iterator i = myBestLanes.begin(); i != myBestLanes.end(); ++i) {
1624  if ((*i).size() != 0 && (*i)[0].lane == l) {
1625  return (*i)[0].bestContinuations;
1626  }
1627  }
1628  return myEmptyLaneVector;
1629 }
1630 
1631 
1632 
1633 SUMOReal
1635 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1636  SUMOReal distance = 1000000.;
1637 #else
1639 #endif
1640  if (isOnRoad() && destEdge != NULL) {
1641  if (&myLane->getEdge() == *myCurrEdge) {
1642  // vehicle is on a normal edge
1643  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
1644  } else {
1645  // vehicle is on inner junction edge
1646  distance = myLane->getLength() - getPositionOnLane();
1647  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
1648  }
1649  }
1650  return distance;
1651 }
1652 
1653 
1654 SUMOReal
1657 }
1658 
1659 
1660 SUMOReal
1663 }
1664 
1665 
1666 SUMOReal
1669 }
1670 
1671 
1672 SUMOReal
1675 }
1676 
1677 
1678 SUMOReal
1681 }
1682 
1683 
1684 SUMOReal
1687 }
1688 
1689 
1690 SUMOReal
1693 }
1694 
1695 
1696 void
1698  if (myPersonDevice == 0) {
1700  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
1701  }
1702  myPersonDevice->addPerson(person);
1703  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
1704  myStops.front().duration = 0;
1705  }
1706 }
1707 
1708 
1709 void
1712  int state = getLaneChangeModel().getOwnState();
1713  if ((state & LCA_LEFT) != 0) {
1715  } else if ((state & LCA_RIGHT) != 0) {
1717  } else {
1718  const MSLane* lane = getLane();
1719  MSLinkCont::const_iterator link = lane->succLinkSec(*this, 1, *lane, getBestLanesContinuation());
1720  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getMaxSpeed() * (SUMOReal) 7.) {
1721  switch ((*link)->getDirection()) {
1722  case LINKDIR_TURN:
1723  case LINKDIR_LEFT:
1724  case LINKDIR_PARTLEFT:
1726  break;
1727  case LINKDIR_RIGHT:
1728  case LINKDIR_PARTRIGHT:
1730  break;
1731  default:
1732  break;
1733  }
1734  }
1735  }
1736 
1737 }
1738 
1739 
1740 void
1742  if (myType->amVehicleSpecific()) {
1743  delete myType;
1744  }
1745  myType = type;
1746 }
1747 
1748 unsigned int
1750  std::vector<MSLane*>::const_iterator laneP = std::find((*myCurrEdge)->getLanes().begin(), (*myCurrEdge)->getLanes().end(), myLane);
1751  return (unsigned int) std::distance((*myCurrEdge)->getLanes().begin(), laneP);
1752 }
1753 
1754 
1755 #ifndef NO_TRACI
1756 bool
1757 MSVehicle::addTraciStop(MSLane* lane, SUMOReal pos, SUMOReal /*radius*/, SUMOTime duration) {
1758  //if the stop exists update the duration
1759  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
1760  if (iter->lane == lane && fabs(iter->endPos - pos) < POSITION_EPS) {
1761  if (duration == 0 && !iter->reached) {
1762  myStops.erase(iter);
1763  } else {
1764  iter->duration = duration;
1765  }
1766  return true;
1767  }
1768  }
1769 
1771  newStop.lane = lane->getID();
1772  newStop.busstop = MSNet::getInstance()->getBusStopID(lane, pos);
1773  newStop.startPos = pos - POSITION_EPS;
1774  newStop.endPos = pos;
1775  newStop.duration = duration;
1776  newStop.until = -1;
1777  newStop.triggered = false;
1778  newStop.parking = false;
1779  newStop.index = STOP_INDEX_END;
1780  return addStop(newStop);
1781 }
1782 
1783 
1786  if (myInfluencer == 0) {
1787  myInfluencer = new Influencer();
1788  }
1789  return *myInfluencer;
1790 }
1791 
1792 
1793 SUMOReal
1795  if (myInfluencer != 0) {
1796  return myInfluencer->getOriginalSpeed();
1797  }
1798  return myState.mySpeed;
1799 }
1800 
1801 
1802 #endif
1803 
1804 
1805 /****************************************************************************/