SUMO - Simulation of Urban MObility
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
18 // Representation of a vehicle in the micro simulation
19 /****************************************************************************/
20 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
21 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
22 /****************************************************************************/
23 //
24 // This file is part of SUMO.
25 // SUMO is free software: you can redistribute it and/or modify
26 // it under the terms of the GNU General Public License as published by
27 // the Free Software Foundation, either version 3 of the License, or
28 // (at your option) any later version.
29 //
30 /****************************************************************************/
31 
32 // ===========================================================================
33 // included modules
34 // ===========================================================================
35 #ifdef _MSC_VER
36 #include <windows_config.h>
37 #else
38 #include <config.h>
39 #endif
40 
41 #include <iostream>
42 #include <cassert>
43 #include <cmath>
44 #include <cstdlib>
45 #include <algorithm>
46 #include <map>
47 #include <utils/common/ToString.h>
54 #include <utils/common/StdDefs.h>
55 #include <utils/geom/GeomHelper.h>
63 #include "MSVehicleControl.h"
64 #include "MSVehicleTransfer.h"
65 #include "MSGlobals.h"
66 #include "MSStoppingPlace.h"
67 #include "MSParkingArea.h"
69 #include "MSEdgeWeightsStorage.h"
71 #include "MSMoveReminder.h"
72 #include "MSTransportableControl.h"
73 #include "MSLane.h"
74 #include "MSJunction.h"
75 #include "MSVehicle.h"
76 #include "MSEdge.h"
77 #include "MSVehicleType.h"
78 #include "MSNet.h"
79 #include "MSRoute.h"
80 #include "MSLinkCont.h"
81 #include "MSLeaderInfo.h"
82 
83 #ifdef CHECK_MEMORY_LEAKS
84 #include <foreign/nvwa/debug_new.h>
85 #endif // CHECK_MEMORY_LEAKS
86 
87 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
88 //#define DEBUG_VEHICLE_GUI_SELECTION 1
89 
90 //#define DEBUG_PLAN_MOVE
91 //#define DEBUG_EXEC_MOVE
92 //#define DEBUG_FURTHER
93 //#define DEBUG_STOPS
94 //#define DEBUG_BESTLANES
95 #define DEBUG_COND (getID() == "disabled")
96 
97 #define STOPPING_PLACE_OFFSET 0.5
98 
99 #define CRLL_LOOK_AHEAD 5
100 
101 // @todo Calibrate with real-world values / make configurable
102 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
103 
104 // ===========================================================================
105 // static value definitions
106 // ===========================================================================
107 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
108 std::vector<MSTransportable*> MSVehicle::myEmptyTransportableVector;
109 
110 
111 // ===========================================================================
112 // method definitions
113 // ===========================================================================
114 /* -------------------------------------------------------------------------
115  * methods of MSVehicle::State
116  * ----------------------------------------------------------------------- */
118  myPos = state.myPos;
119  mySpeed = state.mySpeed;
120  myPosLat = state.myPosLat;
121  myBackPos = state.myBackPos;
124 }
125 
126 
129  myPos = state.myPos;
130  mySpeed = state.mySpeed;
131  myPosLat = state.myPosLat;
132  myBackPos = state.myBackPos;
135  return *this;
136 }
137 
138 
139 bool
141  return (myPos != state.myPos ||
142  mySpeed != state.mySpeed ||
143  myPosLat != state.myPosLat ||
145  myPreviousSpeed != state.myPreviousSpeed ||
146  myBackPos != state.myBackPos);
147 }
148 
149 
151  myPos(pos), mySpeed(speed), myPosLat(posLat), myBackPos(backPos), myPreviousSpeed(speed), myLastCoveredDist(SPEED2DIST(speed)) {}
152 
153 
154 
155 /* -------------------------------------------------------------------------
156  * methods of MSVehicle::WaitingTimeCollector
157  * ----------------------------------------------------------------------- */
158 
160 
162 
167  return *this;
168 }
169 
172  myWaitingIntervals.clear();
173  passTime(t, true);
174  return *this;
175 }
176 
177 SUMOTime
179  assert(memorySpan <= myMemorySize);
180  if (memorySpan == -1) {
181  memorySpan = myMemorySize;
182  }
183  SUMOTime totalWaitingTime = 0;
184  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
185  if (i->second >= memorySpan) {
186  if (i->first >= memorySpan) {
187  break;
188  } else {
189  totalWaitingTime += memorySpan - i->first;
190  }
191  } else {
192  totalWaitingTime += i->second - i->first;
193  }
194  }
195  return totalWaitingTime;
196 }
197 
198 void
200  waitingIntervalList::iterator i = myWaitingIntervals.begin();
201  waitingIntervalList::iterator end = myWaitingIntervals.end();
202  bool startNewInterval = i == end || (i->first != 0);
203  while (i != end) {
204  i->first += dt;
205  if (i->first >= myMemorySize) {
206  break;
207  }
208  i->second += dt;
209  i++;
210  }
211 
212  // remove intervals beyond memorySize
213  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
214  while (d > 0) {
215  myWaitingIntervals.pop_back();
216  d--;
217  }
218 
219  if (!waiting) {
220  return;
221  } else if (!startNewInterval) {
222  myWaitingIntervals.begin()->first = 0;
223  } else {
224  myWaitingIntervals.push_front(std::make_pair(0, dt));
225  }
226  return;
227 }
228 
229 
230 
231 
232 
233 /* -------------------------------------------------------------------------
234  * methods of MSVehicle::Influencer
235  * ----------------------------------------------------------------------- */
236 #ifndef NO_TRACI
238  mySpeedAdaptationStarted(true),
239  myConsiderSafeVelocity(true),
240  myConsiderMaxAcceleration(true),
241  myConsiderMaxDeceleration(true),
242  myRespectJunctionPriority(true),
243  myEmergencyBrakeRedLight(true),
244  myLastVTDAccess(-TIME2STEPS(20)),
245  myStrategicLC(LC_NOCONFLICT),
246  myCooperativeLC(LC_NOCONFLICT),
247  mySpeedGainLC(LC_NOCONFLICT),
248  myRightDriveLC(LC_NOCONFLICT),
249  mySublaneLC(LC_NOCONFLICT),
250  myTraciLaneChangePriority(LCP_URGENT),
251  myTraCISignals(-1) {
252 }
253 
254 
256 
257 
258 void
259 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
261  mySpeedTimeLine = speedTimeLine;
262 }
263 
264 
265 void
266 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine) {
267  myLaneTimeLine = laneTimeLine;
268 }
269 
270 
271 int
273  return (1 * myConsiderSafeVelocity +
278 }
279 
280 
281 SUMOReal
283  // keep original speed
284  myOriginalSpeed = speed;
285  // remove leading commands which are no longer valid
286  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
287  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
288  }
289  // do nothing if the time line does not apply for the current time
290  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
291  return speed;
292  }
293  // compute and set new speed
295  mySpeedTimeLine[0].second = speed;
297  }
298  currentTime += DELTA_T;
299  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
300  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
302  speed = MIN2(speed, vSafe);
303  }
305  speed = MIN2(speed, vMax);
306  }
308  speed = MAX2(speed, vMin);
309  }
310  return speed;
311 }
312 
313 
314 int
315 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state) {
316  // remove leading commands which are no longer valid
317  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
318  myLaneTimeLine.erase(myLaneTimeLine.begin());
319  }
320  ChangeRequest changeRequest = REQUEST_NONE;
321  // do nothing if the time line does not apply for the current time
322  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
323  const int destinationLaneIndex = myLaneTimeLine[1].second;
324  if (destinationLaneIndex < (int)currentEdge.getLanes().size()) {
325  if (currentLaneIndex > destinationLaneIndex) {
326  changeRequest = REQUEST_RIGHT;
327  } else if (currentLaneIndex < destinationLaneIndex) {
328  changeRequest = REQUEST_LEFT;
329  } else {
330  changeRequest = REQUEST_HOLD;
331  }
332  }
333  }
334  // check whether the current reason shall be canceled / overridden
335  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
336  // flags for the current reason
337  LaneChangeMode mode = LC_NEVER;
338  if ((state & LCA_STRATEGIC) != 0) {
339  mode = myStrategicLC;
340  } else if ((state & LCA_COOPERATIVE) != 0) {
341  mode = myCooperativeLC;
342  } else if ((state & LCA_SPEEDGAIN) != 0) {
343  mode = mySpeedGainLC;
344  } else if ((state & LCA_KEEPRIGHT) != 0) {
345  mode = myRightDriveLC;
346  } else if ((state & LCA_SUBLANE) != 0) {
347  mode = mySublaneLC;
348  } else if ((state & LCA_TRACI) != 0) {
349  mode = LC_NEVER;
350  } else {
351  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
352  }
353  if (mode == LC_NEVER) {
354  // cancel all lcModel requests
355  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
356  state &= ~LCA_URGENT;
357  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
358  if (
359  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
360  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
361  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
362  // cancel conflicting lcModel request
363  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
364  state &= ~LCA_URGENT;
365  }
366  } else if (mode == LC_ALWAYS) {
367  // ignore any TraCI requests
368  return state;
369  }
370  }
371  // apply traci requests
372  if (changeRequest == REQUEST_NONE) {
373  return state;
374  } else {
375  state |= LCA_TRACI;
376  // security checks
378  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
379  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
380  }
381  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
382  state |= LCA_URGENT;
383  }
384  switch (changeRequest) {
385  case REQUEST_HOLD:
386  return state | LCA_STAY;
387  case REQUEST_LEFT:
388  return state | LCA_LEFT;
389  case REQUEST_RIGHT:
390  return state | LCA_RIGHT;
391  default:
392  throw ProcessError("should not happen");
393  }
394  }
395 }
396 
397 
398 SUMOReal
400  assert(myLaneTimeLine.size() >= 2);
401  assert(currentTime >= myLaneTimeLine[0].first);
402  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
403 }
404 
405 
406 void
408  myConsiderSafeVelocity = ((speedMode & 1) != 0);
409  myConsiderMaxAcceleration = ((speedMode & 2) != 0);
410  myConsiderMaxDeceleration = ((speedMode & 4) != 0);
411  myRespectJunctionPriority = ((speedMode & 8) != 0);
412  myEmergencyBrakeRedLight = ((speedMode & 16) != 0);
413 }
414 
415 
416 void
418  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
419  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
420  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
421  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
422  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
423  mySublaneLC = (LaneChangeMode)((value & (1024 + 2048)) >> 10);
424 }
425 
426 
427 void
428 MSVehicle::Influencer::setVTDControlled(Position xyPos, MSLane* l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
429  myVTDXYPos = xyPos;
430  myVTDLane = l;
431  myVTDPos = pos;
432  myVTDPosLat = posLat;
433  myVTDAngle = angle;
434  myVTDEdgeOffset = edgeOffset;
435  myVTDRoute = route;
436  myLastVTDAccess = t;
437 }
438 
439 
440 bool
443 }
444 
445 
446 bool
448  return myLastVTDAccess >= t - TIME2STEPS(10);
449 }
450 
451 void
453  const bool wasOnRoad = v->isOnRoad();
454  if (v->isOnRoad()) {
457  }
458  if (myVTDRoute.size() != 0) {
459  v->replaceRouteEdges(myVTDRoute, true);
460  }
462  if (myVTDLane != 0 && myVTDPos > myVTDLane->getLength()) {
464  }
465  if (myVTDLane != 0 && fabs(myVTDPosLat) < 0.5 * (myVTDLane->getWidth() + v->getVehicleType().getWidth())) {
467  v->updateBestLanes();
468  if (!wasOnRoad) {
469  v->drawOutsideNetwork(false);
470  }
471  //std::cout << "on road network p=" << myVTDXYPos << " a=" << myVTDAngle << " l=" << Named::getIDSecure(myVTDLane) << "\n";
472  } else {
473  if (v->getDeparture() == NOT_YET_DEPARTED) {
474  v->onDepart();
475  }
477  v->drawOutsideNetwork(true);
478  //std::cout << "outside network p=" << myVTDXYPos << " a=" << myVTDAngle << " l=" << Named::getIDSecure(myVTDLane) << "\n";
479  }
480  // inverse of GeomHelper::naviDegree
481  v->setAngle(M_PI / 2. - DEG2RAD(myVTDAngle));
482 }
483 
484 
485 SUMOReal
487  SUMOReal dist = 0;
488  if (myVTDLane == 0) {
489  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
490  } else {
492  }
493  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
494  return oldSpeed;
495  } else {
496  return DIST2SPEED(dist);
497  }
498 }
499 
500 SUMOReal
502  SUMOReal dist = 0;
503  if (myVTDLane == 0) {
504  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
505  } else {
507  }
508  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
509  return 0;
510  } else {
511  return dist;
512  }
513 }
514 
515 #endif
516 
517 
518 /* -------------------------------------------------------------------------
519  * MSVehicle-methods
520  * ----------------------------------------------------------------------- */
522  const MSVehicleType* type, const SUMOReal speedFactor) :
523  MSBaseVehicle(pars, route, type, speedFactor),
524  myWaitingTime(0),
526  myTimeLoss(0),
527  myState(0, 0, 0, 0), //
528  myLane(0),
531  myPersonDevice(0),
533  myAcceleration(0),
534  mySignals(0),
535  myAmOnNet(false),
538  myHaveToWaitOnNextLink(false),
539  myAngle(0),
540  myStopDist(std::numeric_limits<SUMOReal>::max()),
541  myCachedPosition(Position::INVALID),
542  myEdgeWeights(0)
543 #ifndef NO_TRACI
544  , myInfluencer(0)
545 #endif
546 {
547  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
548  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
549  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
550  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
551  }
552  } else {
553  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
554  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
555  }
556  }
557  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
558  throw ProcessError("Departure speed for vehicle '" + pars->id +
559  "' is too high for the vehicle type '" + type->getID() + "'.");
560  }
561  }
564 }
565 
566 
568  delete myEdgeWeights;
569  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
570  (*i)->resetPartialOccupation(this);
571  }
574  // still needed when calling resetPartialOccupation (getShadowLane) and when removing
575  // approach information from parallel links
576  delete myLaneChangeModel;
577  myFurtherLanes.clear();
578  myFurtherLanesPosLat.clear();
579  //
580  if (myType->amVehicleSpecific()) {
581  delete myType;
582  }
583 #ifndef NO_TRACI
584  delete myInfluencer;
585 #endif
586 }
587 
588 
589 void
593  leaveLane(reason);
594 }
595 
596 
597 // ------------ interaction with the route
598 bool
600  return (myCurrEdge == myRoute->end() - 1
601  && (myStops.empty() || myStops.front().edge != myCurrEdge)
603  && !isRemoteControlled());
604 }
605 
606 
607 bool
608 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset, bool addStops) {
609  const ConstMSEdgeVector& edges = newRoute->getEdges();
610  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
611  if (!onInit && !newRoute->contains(*myCurrEdge)) {
612  return false;
613  }
614 
615  // rebuild in-vehicle route information
616  if (onInit) {
617  myCurrEdge = newRoute->begin();
618  } else {
619  MSRouteIterator newCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);;
620  if (myLane->getEdge().isInternal() && (
621  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(myLane->getOutgoingLanes()[0]->getEdge()))) {
622  return false;
623  }
624  myCurrEdge = newCurrEdge;
625  }
626  // check whether the old route may be deleted (is not used by anyone else)
627  newRoute->addReference();
628  myRoute->release();
629  // assign new route
630  myRoute = newRoute;
631  // update arrival definition
633  // update best lanes
636  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
637  // save information that the vehicle was rerouted
640  // recheck old stops
641  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
642  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
643  iter = myStops.erase(iter);
644  } else {
645  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
646  ++iter;
647  }
648  }
649  // add new stops
650  if (addStops) {
651  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
652  std::string error;
653  addStop(*i, error);
654  if (error != "") {
655  WRITE_WARNING(error);
656  }
657  }
658  }
659  return true;
660 }
661 
662 
663 bool
664 MSVehicle::willPass(const MSEdge* const edge) const {
665  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
666 }
667 
668 
669 int
671  return (int) std::distance(myRoute->begin(), myCurrEdge);
672 }
673 
674 
675 void
677  myCurrEdge = myRoute->begin() + index;
678  // !!! hack
679  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
680 }
681 
682 
683 
686  return _getWeightsStorage();
687 }
688 
689 
692  return _getWeightsStorage();
693 }
694 
695 
698  if (myEdgeWeights == 0) {
700  }
701  return *myEdgeWeights;
702 }
703 
704 
705 // ------------ Interaction with move reminders
706 void
708  // This erasure-idiom works for all stl-sequence-containers
709  // See Meyers: Effective STL, Item 9
710  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
711  // XXX: calling notifyMove with newSpeed seems not the best choice. For the ballistic update, the average speed is calculated and used
712  // although a higher order quadrature-formula might be more adequate.
713  // For the euler case (where the speed is considered constant for each time step) it is conceivable that
714  // the current calculations may lead to systematic errors for large time steps (compared to reality). Refs. #2579
715  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, MAX2((SUMOReal)0., newSpeed))) {
716 #ifdef _DEBUG
717  if (myTraceMoveReminders) {
718  traceMoveReminder("notifyMove", rem->first, rem->second, false);
719  }
720 #endif
721  rem = myMoveReminders.erase(rem);
722  } else {
723 #ifdef _DEBUG
724  if (myTraceMoveReminders) {
725  traceMoveReminder("notifyMove", rem->first, rem->second, true);
726  }
727 #endif
728  ++rem;
729  }
730  }
731 }
732 
733 
734 // XXX: consider renaming...
735 void
737  // save the old work reminders, patching the position information
738  // add the information about the new offset to the old lane reminders
739  const SUMOReal oldLaneLength = myLane->getLength();
740  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
741  rem->second += oldLaneLength;
742 #ifdef _DEBUG
743  if (myTraceMoveReminders) {
744  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
745  }
746 #endif
747  }
748  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
749  addReminder(*rem);
750  }
751 }
752 
753 
754 // ------------ Other getter methods
755 SUMOReal
757  if (myLane == 0) {
758  return 0;
759  }
760  const SUMOReal lp = getPositionOnLane();
762  return myLane->getShape().slopeDegreeAtOffset(gp);
763 }
764 
765 
766 Position
767 MSVehicle::getPosition(const SUMOReal offset) const {
768  if (myLane == 0) {
769  // when called in the context of GUI-Drawing, the simulation step is already incremented
771  return myCachedPosition;
772  } else {
773  return Position::INVALID;
774  }
775  }
776  if (isParking()) {
777  if (myStops.begin()->parkingarea != 0) {
778  return myStops.begin()->parkingarea->getVehiclePosition(*this);
779  } else {
780  // position beside the road
781  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
784  }
785  }
786  const bool changingLanes = getLaneChangeModel().isChangingLanes();
787  if (offset == 0. && !changingLanes) {
790  }
791  return myCachedPosition;
792  }
794  return result;
795 }
796 
797 
798 const MSEdge*
800  // too close to the next junction, so avoid an emergency brake here
801  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
803  return *(myCurrEdge + 1);
804  }
805 #ifdef HAVE_INTERNAL_LANES
806  if (myLane != 0) {
807  return myLane->getNextNormal();
808  }
809 #endif
810  return *myCurrEdge;
811 }
812 
813 void
815  myAngle = angle;
816 }
817 
818 
819 SUMOReal
821  Position p1;
822  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
823  if (isParking()) {
824  if (myStops.begin()->parkingarea != 0) {
825  return myStops.begin()->parkingarea->getVehicleAngle(*this);
826  } else {
828  }
829  }
831  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
833  } else {
834  p1 = getPosition();
835  }
836 
837  Position p2 = getBackPosition();
838  if (p2 == Position::INVALID) {
839  // Handle special case of vehicle's back reaching out of the network
840  if (myFurtherLanes.size() > 0) {
841  p2 = myFurtherLanes.back()->geometryPositionAtOffset(0, -myFurtherLanesPosLat.back());
842  } else {
843  p2 = myLane->geometryPositionAtOffset(0, posLat);
844  }
845  }
846  SUMOReal result = (p1 != p2 ? p2.angleTo2D(p1) :
849  result += DEG2RAD(getLaneChangeModel().getAngleOffset());
850  }
851 #ifdef DEBUG_FURTHER
852  if (DEBUG_COND) {
853  std::cout << SIMTIME << " computeAngle veh=" << getID() << " p1=" << p1 << " p2=" << p2 << " angle=" << result << "\n";
854  }
855 #endif
856  return result;
857 }
858 
859 
860 const Position
862  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
863  if (myState.myPos >= myType->getLength()) {
864  // vehicle is fully on the new lane
866  } else {
868  // special case where the target lane has no predecessor
869  return myLane->geometryPositionAtOffset(0, posLat);
870  } else {
871 #ifdef DEBUG_FURTHER
872  if (DEBUG_COND) {
873  std::cout << " getBackPosition veh=" << getID() << " myLane=" << myLane->getID() << " further=" << toString(myFurtherLanes) << " myFurtherLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
874  }
875 #endif
876  return myFurtherLanes.size() > 0 && !getLaneChangeModel().isChangingLanes()
877  ? myFurtherLanes.back()->geometryPositionAtOffset(getBackPositionOnLane(myFurtherLanes.back()), -myFurtherLanesPosLat.back())
878  : myLane->geometryPositionAtOffset(0, posLat);
879  }
880  }
881 }
882 
883 // ------------
884 bool
885 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
886  Stop stop;
887  stop.lane = MSLane::dictionary(stopPar.lane);
889  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
890  return false;
891  }
892  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
896  stop.startPos = stopPar.startPos;
897  stop.endPos = stopPar.endPos;
898  stop.duration = stopPar.duration;
899  stop.until = stopPar.until;
900  stop.timeToBoardNextPerson = 0;
901  stop.timeToLoadNextContainer = 0;
902  stop.awaitedPersons = stopPar.awaitedPersons;
903  stop.awaitedContainers = stopPar.awaitedContainers;
904  if (stop.until != -1) {
905  stop.until += untilOffset;
906  }
907  stop.triggered = stopPar.triggered;
908  stop.containerTriggered = stopPar.containerTriggered;
909  stop.parking = stopPar.parking;
910  stop.reached = false;
911  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
912  if (stop.busstop != 0) {
913  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
914  } else {
915  errorMsg = "Stop";
916  }
917  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
918  return false;
919  }
920  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
921  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
922  }
923  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
924  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
925  }
926  if (stop.parkingarea != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
927  errorMsg = "Parking area '" + stop.parkingarea->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
928  }
929  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
930  MSRouteIterator prevStopEdge = myCurrEdge;
931  SUMOReal prevStopPos = myState.myPos;
932  // where to insert the stop
933  std::list<Stop>::iterator iter = myStops.begin();
934  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
935  if (myStops.size() > 0) {
936  prevStopEdge = myStops.back().edge;
937  prevStopPos = myStops.back().endPos;
938  iter = myStops.end();
939  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
940  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
941  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
942  }
943  }
944  } else {
945  if (stopPar.index == STOP_INDEX_FIT) {
946  while (iter != myStops.end() && (iter->edge < stop.edge ||
947  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
948  prevStopEdge = iter->edge;
949  prevStopPos = iter->endPos;
950  ++iter;
951  }
952  } else {
953  int index = stopPar.index;
954  while (index > 0) {
955  prevStopEdge = iter->edge;
956  prevStopPos = iter->endPos;
957  ++iter;
958  --index;
959  }
960  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
961  }
962  }
963  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
964  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
965  if (stop.busstop != 0) {
966  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
967  } else {
968  errorMsg = "Stop";
969  }
970  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
971  return false;
972  }
973  // David.C:
974  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
975  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
976  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
977  return false;
978  }
979  if (!hasDeparted() && myCurrEdge == stop.edge) {
980  SUMOReal pos = -1;
982  pos = myParameter->departPos;
983  if (pos < 0.) {
984  pos += (*myCurrEdge)->getLength();
985  }
986  }
988  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
989  }
990  if (pos > stop.endPos) {
991  if (stop.busstop != 0) {
992  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
993  } else {
994  errorMsg = "Stop";
995  }
996  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
997  return false;
998  }
999  }
1000  if (iter != myStops.begin()) {
1001  std::list<Stop>::iterator iter2 = iter;
1002  iter2--;
1003  if (stop.until >= 0 && iter2->until > stop.until) {
1004  if (stop.busstop != 0) {
1005  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
1006  } else {
1007  errorMsg = "Stop";
1008  }
1009  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
1010  }
1011  }
1012  myStops.insert(iter, stop);
1013  return true;
1014 }
1015 
1016 
1017 bool
1018 MSVehicle::replaceParkingArea(MSParkingArea* parkingArea, std::string& errorMsg) {
1019  // Check if there is a parking area to be replaced
1020  assert(parkingArea != 0);
1021  if (myStops.empty()) {
1022  errorMsg = "Vehicle '" + myParameter->id + "' has no stops.";
1023  return false;
1024  }
1026  Stop stop = myStops.front();
1027  if (stop.reached) {
1028  errorMsg = "current stop already reached";
1029  return false;
1030  }
1031  if (stop.parkingarea == 0) {
1032  errorMsg = "current stop is not a parkingArea";
1033  return false;
1034  }
1035  if (stop.parkingarea == parkingArea) {
1036  errorMsg = "current stop is the same as the new parking area";
1037  return false;
1038  }
1039  stopPar.lane = parkingArea->getLane().getID();
1040 
1041  // merge duplicated stops equals to parking area
1042  int removeStops = 0;
1043  SUMOTime duration = 0;
1044 
1045  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1046  if (duration == 0) {
1047  duration = iter->duration;
1048  ++removeStops;
1049  } else {
1050  if (iter->parkingarea != 0 && iter->parkingarea == parkingArea) {
1051  duration += iter->duration;
1052  ++removeStops;
1053  } else {
1054  break;
1055  }
1056  }
1057  }
1058 
1059  stopPar.index = 0;
1060  stopPar.busstop = "";
1061  stopPar.chargingStation = "";
1062  stopPar.containerstop = "";
1063  stopPar.parkingarea = parkingArea->getID();
1064  stopPar.startPos = parkingArea->getBeginLanePosition();
1065  stopPar.endPos = parkingArea->getEndLanePosition();
1066  stopPar.duration = duration;
1067  stopPar.until = stop.until;
1068  stopPar.awaitedPersons = stop.awaitedPersons;
1069  stopPar.awaitedContainers = stop.awaitedContainers;
1070  stopPar.triggered = stop.triggered;
1071  stopPar.containerTriggered = stop.containerTriggered;
1072  stopPar.parking = stop.parking;
1073 
1074  // remove stops equals to parking area
1075  while (removeStops > 0) {
1076  myStops.pop_front();
1077  --removeStops;
1078  }
1079  const bool result = addStop(stopPar, errorMsg);
1080  if (myLane != 0) {
1081  updateBestLanes(true);
1082  }
1083  return result;
1084 }
1085 
1086 
1089  MSParkingArea* nextParkingArea = 0;
1090  if (!myStops.empty()) {
1092  Stop stop = myStops.front();
1093  if (!stop.reached && stop.parkingarea != 0) {
1094  nextParkingArea = stop.parkingarea;
1095  }
1096  }
1097  return nextParkingArea;
1098 }
1099 
1100 
1101 bool
1103  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
1104 }
1105 
1106 
1107 bool
1109  return isStopped() && myStops.begin()->parking;
1110 }
1111 
1112 
1113 bool
1115  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
1116 }
1117 
1118 
1119 bool
1121  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
1122 }
1123 
1124 
1125 SUMOReal
1127  if (myStops.empty()) {
1128  // no stops; pass
1129  return currentVelocity;
1130  }
1131 
1132 #ifdef DEBUG_STOPS
1133  if (DEBUG_COND) {
1134  std::cout << "\nPROCESS_NEXT_STOP\n" << SIMTIME << " vehicle '" << getID() << "'" << std::endl;
1135  }
1136 #endif
1137 
1138  Stop& stop = myStops.front();
1139  if (stop.reached) {
1140 
1141 #ifdef DEBUG_STOPS
1142  if (DEBUG_COND) {
1143  std::cout << SIMTIME << " vehicle '" << getID() << "' reached stop." << std::endl;
1144  }
1145 #endif
1146  // ok, we have already reached the next stop
1147  // any waiting persons may board now
1148  MSNet* const net = MSNet::getInstance();
1149  bool boarded = net->hasPersons() && net->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
1150  boarded &= stop.awaitedPersons.size() == 0;
1151  // load containers
1152  bool loaded = net->hasContainers() && net->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
1153  loaded &= stop.awaitedContainers.size() == 0;
1154  if (boarded) {
1155  if (stop.busstop != 0) {
1156  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
1157  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
1158  stop.busstop->removeTransportable(*i);
1159  }
1160  }
1161  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
1162  stop.triggered = false;
1166 #ifdef DEBUG_STOPS
1167  if (DEBUG_COND) {
1168  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for person." << std::endl;
1169  }
1170 #endif
1171  }
1172  }
1173  if (loaded) {
1174  if (stop.containerstop != 0) {
1175  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
1176  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
1178  }
1179  }
1180  // the triggering condition has been fulfilled
1181  stop.containerTriggered = false;
1185 #ifdef DEBUG_STOPS
1186  if (DEBUG_COND) {
1187  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for container." << std::endl;
1188  }
1189 #endif
1190  }
1191  }
1192  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
1193 #ifdef DEBUG_STOPS
1194  if (DEBUG_COND) {
1195  std::cout << SIMTIME << " vehicle '" << getID() << "' resumes from stopping." << std::endl;
1196  }
1197 #endif
1199  } else {
1201  if (getVehicleType().getPersonCapacity() == getPersonNumber()) {
1202  WRITE_WARNING("Vehicle '" + getID() + "' ignores triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1203  stop.triggered = false;
1204  }
1205  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1208 #ifdef DEBUG_STOPS
1209  if (DEBUG_COND) {
1210  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for person." << std::endl;
1211  }
1212 #endif
1213  }
1215  if (getVehicleType().getContainerCapacity() == getContainerNumber()) {
1216  WRITE_WARNING("Vehicle '" + getID() + "' ignores container triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1217  stop.containerTriggered = false;
1218  }
1219  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1222 #ifdef DEBUG_STOPS
1223  if (DEBUG_COND) {
1224  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for container." << std::endl;
1225  }
1226 #endif
1227  }
1228  // we have to wait some more time
1229  stop.duration -= DELTA_T;
1230 
1232  // euler
1233  return 0;
1234  } else {
1235  // ballistic:
1236  return getCarFollowModel().stopSpeed(this, getSpeed(), stop.getEndPos(*this) - myState.pos());
1237  }
1238  }
1239  } else {
1240 
1241 #ifdef DEBUG_STOPS
1242  if (DEBUG_COND) {
1243  std::cout << SIMTIME << " vehicle '" << getID() << "' hasn't reached next stop." << std::endl;
1244  }
1245 #endif
1246 
1247  // is the next stop on the current lane?
1248  if (stop.edge == myCurrEdge) {
1249  // get the stopping position
1250  SUMOReal endPos = stop.endPos;
1251  bool useStoppingPlace = false;
1252  bool fitsOnStoppingPlace = true;
1253  if (stop.busstop != 0) {
1254  useStoppingPlace = true;
1255  // on bus stops, we have to wait for free place if they are in use...
1256  endPos = stop.busstop->getLastFreePos(*this);
1257  // at least half the bus has to fit on non-empty bus stops
1258  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
1259  fitsOnStoppingPlace = false;
1260  }
1261  }
1262  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
1263  if (stop.containerstop != 0) {
1264  useStoppingPlace = true;
1265  // on container stops, we have to wait for free place if they are in use...
1266  endPos = stop.containerstop->getLastFreePos(*this);
1267  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
1268  fitsOnStoppingPlace = false;
1269  }
1270  }
1271  // if the stop is a parking area we check if there is a free position on the area
1272  if (stop.parkingarea != 0) {
1273  endPos = stop.parkingarea->getLastFreePos(*this);
1274  if (stop.parkingarea->getOccupancy() == stop.parkingarea->getCapacity()) {
1275  fitsOnStoppingPlace = false;
1276  // trigger potential parkingZoneReroute
1277  for (std::vector< MSMoveReminder* >::const_iterator rem = myLane->getMoveReminders().begin(); rem != myLane->getMoveReminders().end(); ++rem) {
1278  addReminder(*rem);
1279  }
1280  MSParkingArea* oldParkingArea = stop.parkingarea;
1282  if (myStops.empty() || myStops.front().parkingarea != oldParkingArea) {
1283  // rerouted, keep driving
1284  return currentVelocity;
1285  }
1286  }
1287  }
1288 
1289  const SUMOReal reachedThreshold = (useStoppingPlace ? endPos - STOPPING_PLACE_OFFSET : stop.startPos) - NUMERICAL_EPS;
1290  if (myState.pos() >= reachedThreshold && fitsOnStoppingPlace && currentVelocity <= SUMO_const_haltingSpeed && myLane == stop.lane) {
1291  // ok, we may stop (have reached the stop)
1292  stop.reached = true;
1293  if (MSStopOut::active()) {
1295  }
1296  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
1298  // compute stopping time
1299  if (stop.until >= 0) {
1300  if (stop.duration == -1) {
1302  } else {
1304  }
1305  }
1306  if (stop.busstop != 0) {
1307  // let the bus stop know the vehicle
1308  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
1309  }
1310  if (stop.containerstop != 0) {
1311  // let the container stop know the vehicle
1313  }
1314  if (stop.parkingarea != 0) {
1315  // let the parking area know the vehicle
1317  }
1318  }
1319  // decelerate
1321  // euler
1322  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos() + NUMERICAL_EPS);
1323  } else {
1324  // ballistic
1325  return getCarFollowModel().stopSpeed(this, myState.mySpeed, endPos - myState.myPos);
1326  }
1327  }
1328  }
1329  return currentVelocity;
1330 }
1331 
1332 
1333 const ConstMSEdgeVector
1335  ConstMSEdgeVector result;
1336  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1337  result.push_back(*iter->edge);
1338  }
1339  return result;
1340 }
1341 
1342 
1343 void
1344 MSVehicle::planMove(const SUMOTime t, const MSLeaderInfo& ahead, const SUMOReal lengthsInFront) {
1345 
1346 #ifdef DEBUG_PLAN_MOVE
1347  if (DEBUG_COND) {
1348  std::cout
1349  << "\nPLAN_MOVE\n"
1350  << STEPS2TIME(t)
1351  << " veh=" << getID()
1352  << " lane=" << myLane->getID()
1353  << " pos=" << getPositionOnLane()
1354  << " posLat=" << getLateralPositionOnLane()
1355  << " speed=" << getSpeed()
1356  << "\n";
1357  }
1358 #endif
1359  planMoveInternal(t, ahead, myLFLinkLanes, myStopDist); // XXX: Why do we reach over myLFLinkLanes and myStopDist as arguments?! That only seems to obscure things (Leo). Refs. #2575
1360 #ifdef DEBUG_PLAN_MOVE
1361  if (DEBUG_COND) {
1362  DriveItemVector::iterator i;
1363  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1364  std::cout
1365  << " vPass=" << (*i).myVLinkPass
1366  << " vWait=" << (*i).myVLinkWait
1367  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1368  << " request=" << (*i).mySetRequest
1369  << "\n";
1370  }
1371  }
1372 #endif
1373  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
1374 #ifdef DEBUG_PLAN_MOVE
1375  if (DEBUG_COND) {
1376  std::cout << " after checkRewindLinkLanes\n";
1377  DriveItemVector::iterator i;
1378  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1379  std::cout
1380  << " vPass=" << (*i).myVLinkPass
1381  << " vWait=" << (*i).myVLinkWait
1382  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1383  << " request=" << (*i).mySetRequest
1384  << " atime=" << (*i).myArrivalTime
1385  << " atimeB=" << (*i).myArrivalTimeBraking
1386  << "\n";
1387  }
1388  }
1389 #endif
1391 }
1392 
1393 
1394 void
1396 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1397  if (gDebugSelectedVehicle == getID()) {
1398  int bla = 0;
1399  }
1400 #endif
1401 
1402  // remove information about approaching links, will be reset later in this step
1404  lfLinks.clear();
1405  myStopDist = std::numeric_limits<SUMOReal>::max();
1406  //
1407  const MSCFModel& cfModel = getCarFollowModel();
1408  const SUMOReal vehicleLength = getVehicleType().getLength();
1409  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1410  const bool opposite = getLaneChangeModel().isOpposite();
1411  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
1412  // v is the initial maximum velocity of this vehicle in this step
1413  SUMOReal v = MIN2(maxV, laneMaxV);
1414 #ifndef NO_TRACI
1415  if (myInfluencer != 0) {
1416  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1417  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1418  }
1419 #endif
1420  // all links within dist are taken into account (potentially)
1421  // the distance already "seen"; in the following always up to the end of the current "lane"
1422  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1423 
1424  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1425 #ifdef DEBUG_PLAN_MOVE
1426  if (DEBUG_COND) {
1427  std::cout << " bestLaneConts=" << toString(bestLaneConts) << "\n";
1428  }
1429 #endif
1430  assert(bestLaneConts.size() > 0);
1431 #ifdef HAVE_INTERNAL_LANES
1432  bool hadNonInternal = false;
1433 #else
1434  bool hadNonInternal = true;
1435 #endif
1436  SUMOReal seen = opposite ? myState.myPos : myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1437  SUMOReal seenNonInternal = 0;
1438  SUMOReal vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(seen, v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1439  int view = 0;
1440  DriveProcessItem* lastLink = 0;
1441  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1442  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1443  const MSLane* lane = opposite ? myLane->getOpposite() : myLane;
1444  assert(lane != 0);
1445  const MSLane* leaderLane = myLane;
1446  while (true) {
1447  // check leader on lane
1448  // leader is given for the first edge only
1449  if (opposite &&
1450  (leaderLane->getVehicleNumber() > 1
1451  || (leaderLane != myLane && leaderLane->getVehicleNumber() > 0))) {
1452  // find opposite-driving leader that must be respected on the currently looked at lane
1453  // XXX make sure to look no further than leaderLane
1454  CLeaderDist leader = leaderLane->getOppositeLeader(this, getPositionOnLane(), true);
1455  ahead.clear();
1456  if (leader.first != 0 && leader.first->getLane() == leaderLane && leader.first->getLaneChangeModel().isOpposite()) {
1457  ahead.addLeader(leader.first, true);
1458  }
1459  }
1460  adaptToLeaders(ahead, 0, seen, lastLink, leaderLane, v, vLinkPass);
1461 #ifdef DEBUG_PLAN_MOVE
1462  if (DEBUG_COND) {
1463  std::cout << "\nv = " << v << "\n";
1464 
1465  }
1466 #endif
1467  // XXX efficiently adapt to shadow leaders using neighAhead by iteration over the whole edge in parallel (lanechanger-style)
1468  if (getLaneChangeModel().getShadowLane() != 0) {
1469  // also slow down for leaders on the shadowLane relative to the current lane
1470  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1471  if (shadowLane != 0) {
1473  adaptToLeaders(shadowLane->getLastVehicleInformation(this, latOffset, lane->getLength() - seen),
1474  latOffset,
1475  seen, lastLink, shadowLane, v, vLinkPass);
1476  }
1477  }
1478 
1479  // process stops
1480  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge() && !myStops.begin()->reached) {
1481  // we are approaching a stop on the edge; must not drive further
1482  const Stop& stop = *myStops.begin();
1483  const SUMOReal endPos = stop.getEndPos(*this) + NUMERICAL_EPS;
1484  myStopDist = seen + endPos - lane->getLength();
1485  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), myStopDist);
1486  if (lastLink != 0) {
1487  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1488  }
1489  v = MIN2(v, stopSpeed);
1490  lfLinks.push_back(DriveProcessItem(v, myStopDist));
1491 
1492 #ifdef DEBUG_PLAN_MOVE
1493  if (DEBUG_COND) {
1494  std::cout << "\n" << SIMTIME << " next stop: distance = " << myStopDist << " requires stopSpeed = " << stopSpeed << "\n";
1495 
1496  }
1497 #endif
1498 
1499  break;
1500  }
1501 
1502  // move to next lane
1503  // get the next link used
1504  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1505  // check whether the vehicle is on its final edge
1506  if (myCurrEdge + view + 1 == myRoute->end()) {
1508  myParameter->arrivalSpeed : laneMaxV);
1509  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1510  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1511  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1512  v = MIN2(v, va);
1513  if (lastLink != 0) {
1514  lastLink->adaptLeaveSpeed(va);
1515  }
1516  lfLinks.push_back(DriveProcessItem(v, seen));
1517  break;
1518  }
1519  // check whether the lane or the shadowLane is a dead end
1520  if (lane->isLinkEnd(link) ||
1522  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1523  if (lastLink != 0) {
1524  lastLink->adaptLeaveSpeed(va);
1525  }
1526  v = MIN2(va, v);
1527  lfLinks.push_back(DriveProcessItem(v, seen));
1528  break;
1529  }
1530  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1531  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1532  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1533  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1534  // We distinguish 3 cases when determining the point at which a vehicle stops:
1535  // - links that require stopping: here the vehicle needs to stop close to the stop line
1536  // to ensure it gets onto the junction in the next step. Otherwise the vehicle would 'forget'
1537  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1538  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1539  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1540  // to minimize the time window for passing the junction. If the
1541  // vehicle 'decides' to accelerate and cannot enter the junction in
1542  // the next step, new foes may appear and cause a collision (see #1096)
1543  // - major links: stopping point is irrelevant
1544  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1545  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1546  // check whether we need to slow down in order to finish a continuous lane change
1547  if (getLaneChangeModel().isChangingLanes()) {
1548  if ( // slow down to finish lane change before a turn lane
1549  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1550  // slow down to finish lane change before the shadow lane ends
1551  (getLaneChangeModel().getShadowLane() != 0 &&
1552  (*link)->getViaLaneOrLane()->getParallelLane(getLaneChangeModel().getShadowDirection()) == 0)) {
1553  // XXX maybe this is too harsh. Vehicles could cut some corners here
1554  const SUMOReal timeRemaining = STEPS2TIME(getLaneChangeModel().remainingTime());
1555  assert(timeRemaining != 0); // we seem to suppose that isChangingLanes() implies this (Leo)
1556  // XXX: Euler-logic (#860), but I couldn't identify problems from this yet (Leo). Refs. #2575
1557  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1558 #ifdef DEBUG_PLAN_MOVE
1559  if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " slowing down to finish continuous change before"
1560  << " link=" << (*link)->getViaLaneOrLane()->getID()
1561  << " timeRemaining=" << timeRemaining
1562  << " v=" << v
1563  << " va=" << va
1564  << "\n";
1565 #endif
1566  v = MIN2(va, v);
1567  }
1568  }
1569 
1570  // - always issue a request to leave the intersection we are currently on
1571  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1572  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1573  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1574  // - even if red, if we cannot break we should issue a request
1575  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1576 
1577  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1578  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed, cfModel.getMaxDecel(), 0.);
1579 #ifdef DEBUG_PLAN_MOVE
1581  if (DEBUG_COND) std::cout
1582  << " stopDist=" << stopDist
1583  << " vLinkWait=" << vLinkWait
1584  << " brakeDist=" << brakeDist
1585  << "\n";
1586 #endif
1587  if (yellowOrRed && seen >= brakeDist) {
1588  // the vehicle is able to brake in front of a yellow/red traffic light
1589  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1590  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1591  break;
1592  }
1593 
1594 #ifdef HAVE_INTERNAL_LANES
1596  // we want to pass the link but need to check for foes on internal lanes
1597  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(this, seen);
1598  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1599  // the vehicle to enter the junction first has priority
1600  const MSVehicle* leader = (*it).vehAndGap.first;
1601  if (leader == 0) {
1602  // leader is a pedestrian. Passing 'this' as a dummy.
1603  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1604  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1605  } else if ((*link)->isLeader(this, leader)) {
1606  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1607  if (lastLink != 0) {
1608  // we are not yet on the junction with this linkLeader.
1609  // at least we can drive up to the previous link and stop there
1610  v = MAX2(v, lastLink->myVLinkWait);
1611  }
1612  // if blocked by a leader from the same lane we must yield our request
1613  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1614  setRequest = false;
1615  }
1616  }
1617  }
1618  // if this is the link between two internal lanes we may have to slow down for pedestrians
1619  vLinkWait = MIN2(vLinkWait, v);
1620  }
1621 #endif
1622 
1623  if (lastLink != 0) {
1624  lastLink->adaptLeaveSpeed(laneMaxV);
1625  }
1626  SUMOReal arrivalSpeed = vLinkPass;
1627  // vehicles should decelerate when approaching a minor link
1628  // - unless they are close enough to have clear visibility of all relevant foe lanes and may start to accelerate again
1629  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1630 
1631  // whether the vehicle/driver is close enough to the link to see all possible foes #2123
1632  SUMOReal visibilityDistance = (*link)->getFoeVisibilityDistance();
1633  SUMOReal determinedFoePresence = seen < visibilityDistance;
1634 // // VARIANT: account for time needed to recognize whether relevant vehicles are on the foe lanes. (Leo)
1635 // SUMOReal foeRecognitionTime = 0.0;
1636 // SUMOReal determinedFoePresence = seen < visibilityDistance - myState.mySpeed*foeRecognitionTime;
1637 
1638 #ifdef DEBUG_PLAN_MOVE
1639  if (DEBUG_COND) {
1640  std::cout << " approaching link=" << (*link)->getViaLaneOrLane()->getID() << " prio=" << (*link)->havePriority() << " seen=" << seen << " visibilityDistance=" << visibilityDistance << " brakeDist=" << brakeDist << "\n";
1641  }
1642 #endif
1643 
1644  if (!(*link)->havePriority() && !determinedFoePresence && brakeDist < seen) {
1645  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1646  SUMOReal maxSpeedAtVisibilityDist = cfModel.maximumSafeStopSpeed(visibilityDistance, myState.mySpeed, false, 0.);
1647  // XXX: estimateSpeedAfterDistance does not use euler-logic (thus returns a lower value than possible here...)
1648  SUMOReal maxArrivalSpeed = cfModel.estimateSpeedAfterDistance(visibilityDistance, maxSpeedAtVisibilityDist, cfModel.getMaxAccel());
1649  arrivalSpeed = MIN2(vLinkPass, maxArrivalSpeed);
1650  slowedDownForMinor = true;
1651 #ifdef DEBUG_PLAN_MOVE
1652  if (DEBUG_COND) {
1653  std::cout << " slowedDownForMinor maxArrivalSpeed=" << maxArrivalSpeed << " arrivalSpeed=" << arrivalSpeed << "\n";
1654  }
1655 #endif
1656  }
1657 
1658  SUMOTime arrivalTime;
1660  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1661  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1662  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1663  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, v, arrivalSpeed);
1664  } else {
1665  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, myState.mySpeed, arrivalSpeed);
1666  }
1667 
1668  // compute arrival speed and arrival time if vehicle starts braking now
1669  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1670  SUMOReal arrivalSpeedBraking = 0;
1671  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1672  if (seen < cfModel.brakeGap(v)) { // XXX: should this use the current speed (at least for the ballistic case)? (Leo) Refs. #2575
1673  // vehicle cannot come to a complete stop in time
1675  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeedEuler(seen, v);
1676  // due to discrete/continuous mismatch (when using Euler update) we have to ensure that braking actually helps
1677  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1678  } else {
1679  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeed(seen, myState.mySpeed);
1680  }
1681  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1682  }
1683  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1684  arrivalTime, arrivalSpeed,
1685  arrivalTimeBraking, arrivalSpeedBraking,
1686  seen,
1687  estimateLeaveSpeed(*link, arrivalSpeed)));
1688 #ifdef HAVE_INTERNAL_LANES
1689  if ((*link)->getViaLane() == 0) {
1690  hadNonInternal = true;
1691  ++view;
1692  }
1693 #else
1694  ++view;
1695 #endif
1696  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1697  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1698  break;
1699  }
1700  // get the following lane
1701  lane = (*link)->getViaLaneOrLane();
1702  laneMaxV = lane->getVehicleMaxSpeed(this);
1703  // the link was passed
1704  // compute the velocity to use when the link is not blocked by other vehicles
1705  // the vehicle shall be not faster when reaching the next lane than allowed
1706  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1707  v = MIN2(va, v);
1708  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1709  // do not restrict results to the current vehicle to allow caching for the current time step
1710  leaderLane = opposite ? lane->getOpposite() : lane;
1711  if (leaderLane == 0) {
1712  break;
1713  }
1714  ahead = opposite ? MSLeaderInfo(leaderLane) : leaderLane->getLastVehicleInformation(0, 0);
1715  seen += lane->getLength();
1716  vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(lane->getLength(), v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1717  lastLink = &lfLinks.back();
1718  }
1719 
1720 //#ifdef DEBUG_PLAN_MOVE
1721 // if(DEBUG_COND){
1722 // std::cout << "planMoveInternal found safe speed v = " << v << std::endl;
1723 // }
1724 //#endif
1725 
1726 }
1727 
1728 
1729 void
1731  const SUMOReal seen, DriveProcessItem* const lastLink,
1732  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass) const {
1733  int rightmost;
1734  int leftmost;
1735  ahead.getSubLanes(this, latOffset, rightmost, leftmost);
1736 #ifdef DEBUG_PLAN_MOVE
1737  if (DEBUG_COND) std::cout << SIMTIME
1738  << "\nADAPT_TO_LEADERS\nveh=" << getID()
1739  << " lane=" << lane->getID()
1740  << " rm=" << rightmost
1741  << " lm=" << leftmost
1742  << " ahead=" << ahead.toString()
1743  << "\n";
1744 #endif
1745  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
1746  const MSVehicle* pred = ahead[sublane];
1747  if (pred != 0) {
1748  // @todo avoid multiple adaptations to the same leader
1749  const SUMOReal predBack = pred->getBackPositionOnLane(lane);
1750  const SUMOReal gap = (lastLink == 0
1751  ? predBack - myState.myPos - getVehicleType().getMinGap()
1752  : predBack + seen - lane->getLength() - getVehicleType().getMinGap());
1753 #ifdef DEBUG_PLAN_MOVE
1754  if (DEBUG_COND) {
1755  std::cout << " pred=" << pred->getID() << " predLane=" << pred->getLane()->getID() << " predPos=" << pred->getPositionOnLane() << " gap=" << gap << " predBack=" << predBack << " seen=" << seen << " lane=" << lane->getID() << " myLane=" << myLane->getID() << "\n";
1756  }
1757 #endif
1758  adaptToLeader(std::make_pair(pred, gap), seen, lastLink, lane, v, vLinkPass);
1759  }
1760  }
1761 }
1762 
1763 
1764 void
1765 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1766  const SUMOReal seen, DriveProcessItem* const lastLink,
1767  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1768  SUMOReal distToCrossing) const {
1769  if (leaderInfo.first != 0) {
1770  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1771  if (lastLink != 0) {
1772  lastLink->adaptLeaveSpeed(vsafeLeader);
1773  }
1774  v = MIN2(v, vsafeLeader);
1775  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1776 
1777 #ifdef DEBUG_PLAN_MOVE
1778  if (DEBUG_COND) std::cout
1779  << SIMTIME
1780  //std::cout << std::setprecision(10);
1781  << " veh=" << getID()
1782  << " lead=" << leaderInfo.first->getID()
1783  << " leadSpeed=" << leaderInfo.first->getSpeed()
1784  << " gap=" << leaderInfo.second
1785  << " leadLane=" << leaderInfo.first->getLane()->getID()
1786  << " predPos=" << leaderInfo.first->getPositionOnLane()
1787  << " seen=" << seen
1788  << " lane=" << lane->getID()
1789  << " myLane=" << myLane->getID()
1790  << " dTC=" << distToCrossing
1791  << " v=" << v
1792  << " vSafeLeader=" << vsafeLeader
1793  << " vLinkPass=" << vLinkPass
1794  << "\n";
1795 #endif
1796  }
1797 }
1798 
1799 
1800 SUMOReal
1801 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1802  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1803  assert(leaderInfo.first != 0);
1804  const MSCFModel& cfModel = getCarFollowModel();
1805  SUMOReal vsafeLeader = 0;
1806  if (leaderInfo.second >= 0) {
1807  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1808  } else {
1809  // the leading, in-lapping vehicle is occupying the complete next lane
1810  // stop before entering this lane
1811  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1812  }
1813  if (distToCrossing >= 0) {
1814  // drive up to the crossing point with the current link leader
1815  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1816  }
1817  return vsafeLeader;
1818 }
1819 
1820 SUMOReal
1822  SUMOReal vNext = myState.mySpeed + ACCEL2SPEED(accel);
1824  // apply implicit Euler positional update
1825  return SPEED2DIST(MAX2(vNext, (SUMOReal)0.));
1826  } else {
1827  // apply ballistic update
1828  if (vNext >= 0) {
1829  // assume constant acceleration during this time step
1830  return SPEED2DIST(myState.mySpeed + 0.5 * ACCEL2SPEED(accel));
1831  } else {
1832  // negative vNext indicates a stop within the middle of time step
1833  // The corresponding stop time is s = mySpeed/deceleration \in [0,dt], and the
1834  // covered distance is therefore deltaPos = mySpeed*s - 0.5*deceleration*s^2.
1835  // Here, deceleration = (myState.mySpeed - vNext)/dt is the constant deceleration
1836  // until the vehicle stops.
1837  return -SPEED2DIST(0.5 * myState.mySpeed * myState.mySpeed / ACCEL2SPEED(accel));
1838  }
1839  }
1840 }
1841 
1842 bool
1844 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1845  if (gDebugSelectedVehicle == getID()) {
1846  int bla = 0;
1847  }
1848 #endif
1849 
1850 #ifdef DEBUG_EXEC_MOVE
1851  if (DEBUG_COND) std::cout << "\nEXECUTE_MOVE\n"
1852  << SIMTIME
1853  << " veh=" << getID()
1854  << " speed=" << getSpeed() // toString(getSpeed(), 24)
1855  << std::endl;
1856 #endif
1857 
1858  // get safe velocities from DriveProcessItems
1859  SUMOReal vSafe = 0; // maximum safe velocity (XXX: why init this as 0 !? Confusing... (Leo)) Refs. #2575
1860  SUMOReal vSafeZipper = std::numeric_limits<SUMOReal>::max(); // speed limit due to zipper merging
1861  SUMOReal vSafeMin = 0; // minimum safe velocity
1862  // the distance to a link which should either be crossed this step or in
1863  // front of which we need to stop
1864  SUMOReal vSafeMinDist = 0;
1865  myHaveToWaitOnNextLink = false;
1866 
1867  assert(myLFLinkLanes.size() != 0 || isRemoteControlled());
1868  DriveItemVector::iterator i;
1869  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1870  MSLink* link = (*i).myLink;
1871 
1872 #ifdef DEBUG_EXEC_MOVE
1873  if (DEBUG_COND) std::cout
1874  << SIMTIME
1875  << " veh=" << getID()
1876  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
1877  << " req=" << (*i).mySetRequest
1878  << " vP=" << (*i).myVLinkPass
1879  << " vW=" << (*i).myVLinkWait
1880  << " d=" << (*i).myDistance
1881  << "\n";
1882 #endif
1883 
1884  // the vehicle must change the lane on one of the next lanes (XXX: refs to code further below???, Leo)
1885  if (link != 0 && (*i).mySetRequest) {
1886 
1887  const LinkState ls = link->getState();
1888  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1889  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1890  const SUMOReal brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
1891  if (yellow && ((*i).myDistance > brakeGap || (MSGlobals::gSemiImplicitEulerUpdate && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel())))) {
1892  vSafe = (*i).myVLinkWait;
1893  myHaveToWaitOnNextLink = true;
1894  link->removeApproaching(this);
1895  break;
1896  }
1897  //
1898 #ifdef NO_TRACI
1899  const bool influencerPrio = false;
1900 #else
1901  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1902 #endif
1903  std::vector<const SUMOVehicle*> collectFoes;
1904  bool opened = yellow || influencerPrio ||
1905  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1909  ls == LINKSTATE_ZIPPER ? &collectFoes : 0);
1910  if (opened && getLaneChangeModel().getShadowLane() != 0) {
1911  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
1912  if (parallelLink != 0) {
1913  const SUMOReal shadowLatPos = getLateralPositionOnLane() - getLaneChangeModel().getShadowDirection() * 0.5 * (
1915  opened &= parallelLink->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1918  getWaitingTime(), shadowLatPos, 0);
1919 #ifdef DEBUG_EXEC_MOVE
1920  if (DEBUG_COND) std::cout
1921  << SIMTIME
1922  << " veh=" << getID()
1923  << " shadowLane=" << getLaneChangeModel().getShadowLane()->getID()
1924  << " shadowDir=" << getLaneChangeModel().getShadowDirection()
1925  << " parallelLink=" << (parallelLink == 0 ? "NULL" : parallelLink->getViaLaneOrLane()->getID())
1926  << " opened=" << opened
1927  << "\n";
1928 #endif
1929  }
1930  }
1931  // vehicles should decelerate when approaching a minor link
1932  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1933  SUMOReal visibilityDistance = link->getFoeVisibilityDistance();
1934  SUMOReal determinedFoePresence = i->myDistance <= visibilityDistance;
1935  if (!determinedFoePresence) {
1936  vSafe = (*i).myVLinkWait;
1937  myHaveToWaitOnNextLink = true;
1938  if (ls == LINKSTATE_EQUAL) {
1939  link->removeApproaching(this);
1940  }
1941  break;
1942  } else {
1943  // past the point of no return. we need to drive fast enough
1944  // to make it across the link. However, minor slowdowns
1945  // should be permissible to follow leading traffic safely
1946  // XXX: There is a problem in subsecond simulation: If we cannot
1947  // make it across the minor link in one step, new traffic
1948  // could appear on a major foe link and cause a collision. Refs. #1845, #2123
1949  vSafeMinDist = myLane->getLength() - getPositionOnLane(); // distance that must be covered
1951  vSafeMin = MIN2((SUMOReal) DIST2SPEED(vSafeMinDist + POSITION_EPS), (*i).myVLinkPass);
1952  } else {
1953  vSafeMin = MIN2((SUMOReal) DIST2SPEED(2 * vSafeMinDist + NUMERICAL_EPS) - getSpeed(), (*i).myVLinkPass);
1954  }
1955  }
1956  }
1957  // have waited; may pass if opened...
1958  if (opened) {
1959  vSafe = (*i).myVLinkPass;
1960  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1961  // this vehicle is probably not gonna drive across the next junction (heuristic)
1962  myHaveToWaitOnNextLink = true;
1963  }
1964  } else if (link->getState() == LINKSTATE_ZIPPER) {
1965  vSafeZipper = MIN2(vSafeZipper,
1966  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
1967  } else {
1968  vSafe = (*i).myVLinkWait;
1969  myHaveToWaitOnNextLink = true;
1970  if (ls == LINKSTATE_EQUAL) {
1971  link->removeApproaching(this);
1972  }
1973 #ifdef DEBUG_EXEC_MOVE
1974  if (DEBUG_COND) {
1975  std::cout << SIMTIME << " braking for closed link=" << link->getViaLaneOrLane()->getID() << "\n";
1976  }
1977 #endif
1978  break;
1979  }
1980  } else {
1981  // we have: i->link == 0 || !i->setRequest
1982  vSafe = (*i).myVLinkWait;
1983  if (vSafe < getSpeed()) {
1984  myHaveToWaitOnNextLink = true;
1985  }
1986  break;
1987  }
1988  }
1989 
1990 //#ifdef DEBUG_EXEC_MOVE
1991 // if (DEBUG_COND) {
1992 // std::cout << "\nvCurrent = " << toString(getSpeed(), 24) << "" << std::endl;
1993 // std::cout << "vSafe = " << toString(vSafe, 24) << "" << std::endl;
1994 // std::cout << "vSafeMin = " << toString(vSafeMin, 24) << "" << std::endl;
1995 // std::cout << "vSafeMinDist = " << toString(vSafeMinDist, 24) << "" << std::endl;
1996 //
1997 // SUMOReal gap = getLeader().second;
1998 // std::cout << "gap = " << toString(gap, 24) << std::endl;
1999 // std::cout << "vSafeStoppedLeader = " << toString(getCarFollowModel().stopSpeed(this, getSpeed(), gap), 24)
2000 // << "\n" << std::endl;
2001 // }
2002 //#endif
2003 
2004  if ((MSGlobals::gSemiImplicitEulerUpdate && vSafe + NUMERICAL_EPS < vSafeMin)
2005  || (!MSGlobals::gSemiImplicitEulerUpdate && (vSafe + NUMERICAL_EPS < vSafeMin && vSafeMin != 0))) { // this might be good for the euler case as well
2006  // cannot drive across a link so we need to stop before it
2007  // XXX: (Leo) This often called stopSpeed with vSafeMinDist==0 (for the ballistic update), since vSafe can become negative
2008  // For the Euler update the term '+ NUMERICAL_EPS' prevented a call here... Recheck, consider of -INVALID_SPEED instead of 0 to indicate absence of vSafeMin restrictions. Refs. #2577
2009  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
2010  vSafeMin = 0;
2011  myHaveToWaitOnNextLink = true;
2012 
2013 #ifdef DEBUG_EXEC_MOVE
2014  if (DEBUG_COND) {
2015  std::cout << "vSafeMin Problem?" << std::endl;
2016  }
2017 #endif
2018 
2019  }
2020 
2021  // vehicles inside a roundabout should maintain their requests
2022  if (myLane->getEdge().isRoundabout()) {
2023  myHaveToWaitOnNextLink = false;
2024  }
2025 
2026  vSafe = MIN2(vSafe, vSafeZipper);
2027 
2028 //#ifdef DEBUG_EXEC_MOVE
2029 // if (DEBUG_COND) {
2030 // std::cout << "vSafe = " << toString(vSafe,12) << "\n" << std::endl;
2031 // }
2032 //#endif
2033 
2034  // XXX braking due to lane-changing and processing stops is not registered
2035  // To avoid casual blinking brake lights at high speeds due to dawdling of the
2036  // leading vehicle, we don't show brake lights when the deceleration could be caused
2037  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
2038  SUMOReal pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
2039  bool brakelightsOn = vSafe < getSpeed() - ACCEL2SPEED(pseudoFriction);
2040 
2041  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
2042  SUMOReal vNext;
2044  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
2045  } else {
2046  // in case of ballistic position update, negative speeds can indicate desired stops within next timestep.
2047  if (vSafeMin == 0) {
2048  // (Leo) This should be an indication that it would even be safe to stop immediately ("implicit Euler logic")
2049  // Hence, stopping within next the timestep (negative vNext) is tolerated.
2050  vNext = getCarFollowModel().moveHelper(this, vSafe);
2051  } else {
2052  vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
2053  }
2054  // (Leo) to avoid oscillations (< 1e-10) of vNext in a standing vehicle column, we cap off vNext
2055  if (fabs(vNext) < NUMERICAL_EPS) {
2056  vNext = 0.;
2057  }
2058  }
2059 #ifdef DEBUG_EXEC_MOVE
2060  if (DEBUG_COND) {
2061  std::cout << SIMTIME << " moveHelper vSafe=" << vSafe << " vSafeMin=" << vSafeMin << " vNext=" << vNext << "\n";
2062  }
2063 #endif
2064 
2065  // vNext may be higher than vSafe without implying a bug:
2066  // - when approaching a green light that suddenly switches to yellow
2067  // - when using unregulated junctions
2068  // - when using tau < step-size
2069  // - when using unsafe car following models
2070  // - when using TraCI and some speedMode / laneChangeMode settings
2071  //if (vNext > vSafe + NUMERICAL_EPS) {
2072  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
2073  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
2074  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2075  //}
2076 
2078  vNext = MAX2(vNext, (SUMOReal) 0.);
2079  } else {
2080  // (Leo) Ballistic: negative vNext can be used to indicate a stop within next step.
2081  // moveHelper() should take care of any bounds on the possible deceleration and
2082  // restrict negativity of vNext, e.g., vNext = MAX2(vNext, myState.mySpeed - ACCEL2SPEED(getCarFollowModel().getMaxDecel()));
2083  }
2084 
2085 #ifndef NO_TRACI
2086  if (myInfluencer != 0) {
2087  if (myInfluencer->isVTDControlled()) {
2088  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
2089  }
2091  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
2092  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
2093  }
2094 #endif
2095  // visit waiting time
2096  if (vNext <= SUMO_const_haltingSpeed && !isStopped()) {
2099  brakelightsOn = true;
2100  } else {
2101  myWaitingTime = 0;
2103  }
2104 
2105  if (brakelightsOn) {
2107  } else {
2109  }
2110 
2111  // update position and speed
2112  updateState(vNext);
2113  std::vector<MSLane*> passedLanes;
2114  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
2115  passedLanes.push_back(*i);
2116  }
2117  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
2118  passedLanes.push_back(myLane);
2119  }
2120  bool moved = false; // whether this veh moves to another lane
2121  std::string emergencyReason = " for unknown reasons";
2122  // move on lane(s)
2123  if (myState.myPos > myLane->getLength()) {
2124  // we are moving at least to the next lane (maybe pass even more than one)
2125  if (myCurrEdge != myRoute->end() - 1) {
2126  MSLane* approachedLane = myLane;
2127  // move the vehicle forward
2128  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
2129  MSLink* link = (*i).myLink;
2130  // check whether the vehicle was allowed to enter lane
2131  // otherwise it is decelerated and we do not need to test for it's
2132  // approach on the following lanes when a lane changing is performed
2133  // proceed to the next lane
2134  if (link != 0) {
2135  approachedLane = link->getViaLaneOrLane();
2136 #ifndef NO_TRACI
2138 #endif
2139  if (link->getState() == LINKSTATE_TL_RED) {
2140  emergencyReason = " because of a red traffic light";
2141  break;
2142  }
2143 #ifndef NO_TRACI
2144  }
2145 #endif
2146  } else if (myState.myPos < myLane->getLength() + NUMERICAL_EPS) {
2147  approachedLane = myLane;
2149  } else {
2150  emergencyReason = " because there is no connection to the next edge";
2151  approachedLane = 0;
2152  break;
2153  }
2154  if (approachedLane != myLane && approachedLane != 0) {
2156  myState.myPos -= myLane->getLength();
2157  assert(myState.myPos > 0);
2158  enterLaneAtMove(approachedLane);
2159  myLane = approachedLane;
2160 #ifdef HAVE_INTERNAL_LANES
2162  // erase leaders when past the junction
2163  if (link->getViaLane() == 0) {
2164  link->passedJunction(this);
2165  }
2166  }
2167 #endif
2168  if (hasArrived()) {
2169  break;
2170  }
2171  if (getLaneChangeModel().isChangingLanes()) {
2172  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
2173  // abort lane change
2174  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
2175  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2177  }
2178  }
2179  moved = true;
2180  if (approachedLane->getEdge().isVaporizing()) {
2182  break;
2183  }
2184  }
2185  passedLanes.push_back(approachedLane);
2186  }
2187  }
2188  }
2189  // update time loss (depends on the updated edge)
2190  if (!isStopped()) {
2191  const SUMOReal vmax = myLane->getVehicleMaxSpeed(this);
2192  if (vmax > 0) {
2193  myTimeLoss += TIME2STEPS(TS * (vmax - vNext) / vmax);
2194  }
2195  }
2196 
2197  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
2198  if (myState.myPos > myLane->getLength()) {
2199  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
2200  + "'" + emergencyReason
2201  + " (decel=" + toString(myAcceleration - myState.mySpeed)
2202  + ", offset = " + toString(myState.myPos - myLane->getLength())
2203  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2206  myState.mySpeed = 0;
2207  }
2208  const MSLane* oldBackLane = getBackLane();
2209  if (getLaneChangeModel().isOpposite()) {
2210  passedLanes.clear(); // ignore back occupation
2211  }
2213  updateBestLanes();
2214  // bestLanes need to be updated before lane changing starts
2215  if (getLaneChangeModel().getShadowLane() != 0 && (moved || oldBackLane != getBackLane())) {
2217  }
2218  setBlinkerInformation(); // needs updated bestLanes
2219  //change the blue light only for emergency vehicles SUMOVehicleClass
2220  if (myType->getVehicleClass() == SVC_EMERGENCY) {
2221  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
2222  }
2223  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
2225  myAngle = computeAngle();
2226  }
2227 
2228 #ifdef DEBUG_EXEC_MOVE
2229  if (DEBUG_COND) {
2230  std::cout << SIMTIME << " executeMove finished veh=" << getID() << " lane=" << myLane->getID() << " myPos=" << getPositionOnLane() << " myPosLat=" << getLateralPositionOnLane() << "\n";
2231  }
2232 #endif
2233  if (getLaneChangeModel().isOpposite()) {
2234  // transform back to the opposite-direction lane
2235  if (myLane->getOpposite() == 0) {
2236  WRITE_WARNING("Unexpected end of opposite lane for vehicle '" + getID() + " at lane '" + myLane->getID() + "', time=" +
2237  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
2239  } else {
2241  myLane = myLane->getOpposite();
2243  }
2244  }
2246  return moved;
2247 }
2248 
2249 
2250 void
2252  // update position and speed
2253  SUMOReal deltaPos; // positional change
2255  deltaPos = SPEED2DIST(vNext);
2256  } else {
2257  // ballistic
2258  // XXX: this is ok for the euler update, too. However, small differences
2259  // will to the above formula result from rounding. (introduced this too have
2260  // exact cooincidence of test results, refactor after merge to trunk)
2261  deltaPos = getDeltaPos(SPEED2ACCEL(vNext - myState.mySpeed));
2262  }
2263 
2264  // the *mean* acceleration during the next step (probably most appropriate for emission calculation)
2265  // TODO: recheck, approve, refs. #2579
2266  // NOTE: for the ballistic update this is in general
2267  // not equal to vNext - myState.mySpeed
2269 
2270 //#ifdef DEBUG_EXEC_MOVE
2271 // if (DEBUG_COND) {
2272 // std::cout << "deltaPos = " << deltaPos << std::endl;
2273 // }
2274 //#endif
2275 
2277  myState.mySpeed = MAX2(vNext, (SUMOReal)0.);
2278 
2279 #ifndef NO_TRACI
2280  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
2281  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
2282  }
2283 #endif
2284 
2285  if (getLaneChangeModel().isOpposite()) {
2286  // transform to the forward-direction lane, move and then transform back
2288  myLane = myLane->getOpposite();
2289  }
2290  myState.myPos += deltaPos;
2291  myState.myLastCoveredDist = deltaPos;
2292 
2294 }
2295 
2296 
2297 const MSLane*
2299  if (myFurtherLanes.size() > 0) {
2300  return myFurtherLanes.back();
2301  } else {
2302  return myLane;
2303  }
2304 }
2305 
2306 
2307 SUMOReal
2308 MSVehicle::updateFurtherLanes(std::vector<MSLane*>& furtherLanes, std::vector<SUMOReal>& furtherLanesPosLat,
2309  const std::vector<MSLane*>& passedLanes) {
2310 
2311  // XXX only reset / set the values that were changed
2312 #ifdef DEBUG_FURTHER
2313  if (DEBUG_COND) std::cout << SIMTIME
2314  << " updateFurtherLanes oldFurther=" << toString(furtherLanes)
2315  << " oldFurtherPosLat=" << toString(furtherLanesPosLat)
2316  << " passed=" << toString(passedLanes)
2317  << "\n";
2318 #endif
2319  for (std::vector<MSLane*>::iterator i = furtherLanes.begin(); i != furtherLanes.end(); ++i) {
2320  (*i)->resetPartialOccupation(this);
2321  }
2322  const MSLane* firstOldFurther = furtherLanes.size() > 0 ? furtherLanes.front() : 0;
2323  // update furtherLanes
2325  furtherLanes.clear();
2326  if (passedLanes.size() > 0) {
2327  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
2328  std::vector<MSLane*>::const_reverse_iterator i = passedLanes.rbegin() + 1;
2329  while (leftLength > 0 && i != passedLanes.rend()) {
2330  furtherLanes.push_back(*i);
2331  if (*i != firstOldFurther) {
2332  furtherLanesPosLat.insert(furtherLanesPosLat.begin(), myState.myPosLat);
2333  }
2334 #ifdef DEBUG_FURTHER
2335  if (DEBUG_COND) {
2336  std::cout << SIMTIME << " updateFurtherLanes \n";
2337  }
2338 #endif
2339  leftLength -= (*i)->setPartialOccupation(this);
2340  ++i;
2341  }
2342  result = -leftLength;
2343  }
2344  assert(furtherLanesPosLat.size() >= furtherLanes.size());
2345  furtherLanesPosLat.erase(furtherLanesPosLat.begin() + furtherLanes.size(), furtherLanesPosLat.end());
2346  assert(furtherLanesPosLat.size() == furtherLanes.size());
2347 #ifdef DEBUG_FURTHER
2348  if (DEBUG_COND) std::cout
2349  << " newFurther=" << toString(furtherLanes)
2350  << " newFurtherPosLat=" << toString(furtherLanesPosLat)
2351  << " newBackPos=" << result
2352  << "\n";
2353 #endif
2354  return result;
2355 }
2356 
2357 
2358 SUMOReal
2360 #ifdef DEBUG_FURTHER
2361  //if (DEBUG_COND) std::cout << SIMTIME
2362  // << " getBackPositionOnLane veh=" << getID()
2363  // << " lane=" << Named::getIDSecure(lane)
2364  // << " myLane=" << myLane->getID()
2365  // << " further=" << toString(myFurtherLanes)
2366  // << " furtherPosLat=" << toString(myFurtherLanesPosLat)
2367  // << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
2368  // << " shadowFurther=" << toString(getLaneChangeModel().getShadowFurtherLanes())
2369  // << " shadowFurtherPosLat=" << toString(getLaneChangeModel().getShadowFurtherLanesPosLat())
2370  // << "\n";
2371 #endif
2372  if (lane == myLane
2373  || lane == getLaneChangeModel().getShadowLane()) {
2374  if (getLaneChangeModel().isOpposite()) {
2375  return myState.myPos + myType->getLength();
2376  } else {
2377  return myState.myPos - myType->getLength();
2378  }
2379  } else if ((myFurtherLanes.size() > 0 && lane == myFurtherLanes.back())
2380  || (getLaneChangeModel().getShadowFurtherLanes().size() > 0 && lane == getLaneChangeModel().getShadowFurtherLanes().back())
2381  ) {
2382  return myState.myBackPos;
2383  } else {
2384  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherLanes=" << toString(myFurtherLanes) << "\n";
2385  SUMOReal leftLength = myType->getLength() - myState.myPos;
2386  std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin();
2387  while (leftLength > 0 && i != myFurtherLanes.end()) {
2388  leftLength -= (*i)->getLength();
2389  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2390  if (*i == lane) {
2391  return -leftLength;
2392  }
2393  ++i;
2394  }
2395  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
2396  leftLength = myType->getLength() - myState.myPos;
2397  i = getLaneChangeModel().getShadowFurtherLanes().begin();
2398  while (leftLength > 0 && i != getLaneChangeModel().getShadowFurtherLanes().end()) {
2399  leftLength -= (*i)->getLength();
2400  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2401  if (*i == lane) {
2402  return -leftLength;
2403  }
2404  ++i;
2405  }
2406  assert(false);
2407  throw ProcessError("Request backPos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
2408  }
2409 }
2410 
2411 
2412 SUMOReal
2414  return getBackPositionOnLane(lane) + myType->getLength();
2415 }
2416 
2417 
2418 bool
2419 MSVehicle::isFrontOnLane(const MSLane* lane) const {
2420  return lane == myLane || lane == getLaneChangeModel().getShadowLane();
2421 }
2422 
2423 
2424 SUMOReal
2425 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
2426  SUMOReal lengths = 0;
2427  const MSLane::VehCont& vehs = l->getVehiclesSecure();
2428  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2429  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()
2430  && (*i) != this
2431  // @todo recheck
2432  && (*i)->isFrontOnLane(l)) {
2433  foundStopped = true;
2434  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
2435  l->releaseVehicles();
2436  return ret;
2437  }
2438  lengths += (*i)->getVehicleType().getLengthWithGap();
2439  }
2440  l->releaseVehicles();
2441  return l->getLength() - lengths;
2442 }
2443 
2444 
2445 void
2446 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
2447 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2448  if (gDebugSelectedVehicle == getID()) {
2449  int bla = 0;
2450  }
2451 #endif
2452 #ifdef HAVE_INTERNAL_LANES
2454  bool hadVehicle = false;
2455  SUMOReal seenSpace = -lengthsInFront;
2456 
2457  bool foundStopped = false;
2458  // compute available space until a stopped vehicle is found
2459  // this is the sum of non-interal lane length minus in-between vehicle lenghts
2460  for (int i = 0; i < (int)lfLinks.size(); ++i) {
2461  // skip unset links
2462  DriveProcessItem& item = lfLinks[i];
2463  if (item.myLink == 0 || foundStopped) {
2464  item.availableSpace = seenSpace;
2465  item.hadVehicle = hadVehicle;
2466  continue;
2467  }
2468  // get the next lane, determine whether it is an internal lane
2469  const MSLane* approachedLane = item.myLink->getViaLane();
2470  if (approachedLane != 0) {
2471  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
2472  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
2473  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2474  if (approachedLane == myLane) {
2475  seenSpace += getVehicleType().getLengthWithGap();
2476  }
2477  } else {
2478  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2479  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2480  }
2481  item.availableSpace = seenSpace;
2482  item.hadVehicle = hadVehicle;
2483 #ifdef DEBUG_PLAN_MOVE
2484  if (DEBUG_COND) std::cout
2485  << SIMTIME
2486  << " veh=" << getID()
2487  << " approached=" << approachedLane->getID()
2488  << " approachedBrutto=" << approachedLane->getBruttoVehLenSum()
2489  << " avail=" << item.availableSpace
2490  << " seenSpace=" << seenSpace
2491  << " hadVehicle=" << item.hadVehicle
2492  << " lengthsInFront=" << lengthsInFront
2493  << "\n";
2494 #endif
2495  continue;
2496  }
2497  approachedLane = item.myLink->getLane();
2498  const MSVehicle* last = approachedLane->getLastAnyVehicle();
2499  if (last == 0 || last == this) {
2500  seenSpace += approachedLane->getLength();
2501  item.availableSpace = seenSpace;
2502  } else if (!last->isFrontOnLane(approachedLane)) {
2505  item.availableSpace = MAX2(seenSpace, seenSpace + last->getBackPositionOnLane(approachedLane) + last->getCarFollowModel().brakeGap(last->getSpeed()));
2506  hadVehicle = true;
2508  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2510  if (last->myHaveToWaitOnNextLink) {
2511  foundStopped = true;
2512  }
2513 #ifdef DEBUG_PLAN_MOVE
2514  if (DEBUG_COND) std::cout
2515  << SIMTIME
2516  << " veh=" << getID()
2517  << " approached=" << approachedLane->getID()
2518  << " lastPoc=" << last->getID()
2519  << " avail=" << item.availableSpace
2520  << " seenSpace=" << seenSpace
2521  << " foundStopped=" << foundStopped
2522  << "\n";
2523 #endif
2524  } else {
2525 
2526  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
2527  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(last->getSpeed());
2528  const SUMOReal lastGap = last->getBackPositionOnLane(approachedLane) + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime()
2529  // gap of last up to the next intersection
2530  - last->getVehicleType().getMinGap();
2531  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
2532  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2533  } else {
2534  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
2535  item.availableSpace = seenSpace;
2536  }
2537  if (last->myHaveToWaitOnNextLink) {
2538  foundStopped = true;
2539  }
2540  hadVehicle = true;
2541 #ifdef DEBUG_PLAN_MOVE
2542  if (DEBUG_COND) std::cout
2543  << SIMTIME
2544  << " veh=" << getID()
2545  << " approached=" << approachedLane->getID()
2546  << " last=" << last->getID()
2547  << " avail=" << item.availableSpace
2548  << " seenSpace=" << seenSpace
2549  << " foundStopped=" << foundStopped
2550  << "\n";
2551 #endif
2552  }
2553  item.hadVehicle = hadVehicle;
2554  }
2555 
2556 
2557 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2558  if (gDebugSelectedVehicle == getID()) {
2559  int bla = 0;
2560  }
2561 #endif
2562  // check which links allow continuation and add pass available to the previous item
2563  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
2564  DriveProcessItem& item = lfLinks[i - 1];
2565  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
2566  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
2567 #ifndef NO_TRACI
2569 #endif
2570  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
2573  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
2574  if (!opened && item.myLink != 0) {
2575  if (i > 1) {
2576  DriveProcessItem& item2 = lfLinks[i - 2];
2577  if (item2.myLink != 0 && item2.myLink->isCont()) {
2578  allowsContinuation = true;
2579  }
2580  }
2581  }
2582  if (allowsContinuation) {
2583  item.availableSpace = lfLinks[i].availableSpace;
2584  }
2585  }
2586 
2587  // find removalBegin
2588  int removalBegin = -1;
2589  for (int i = 0; hadVehicle && i < (int)lfLinks.size() && removalBegin < 0; ++i) {
2590  // skip unset links
2591  const DriveProcessItem& item = lfLinks[i];
2592  if (item.myLink == 0) {
2593  continue;
2594  }
2595  /*
2596  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
2597  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
2598  removalBegin = lastLinkToInternal;
2599  }
2600  */
2601 
2602  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
2603  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
2604  SUMOReal impatienceCorrection = 0;
2605  /*
2606  if(item.myLink->getState()==LINKSTATE_MINOR) {
2607  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
2608  }
2609  */
2610  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
2611  removalBegin = i;
2612  }
2613  //removalBegin = i;
2614  }
2615  }
2616  // abort requests
2617  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
2618  while (removalBegin < (int)(lfLinks.size())) {
2619  const SUMOReal brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
2620  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
2621  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
2622  lfLinks[removalBegin].mySetRequest = false;
2623  }
2624  ++removalBegin;
2625  }
2626  }
2627  }
2628 #else
2629  UNUSED_PARAMETER(lengthsInFront);
2630 #endif
2631  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2632  if ((*i).myLink != 0) {
2633  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
2634  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((int)2); // tie braker
2635  }
2636  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2637  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2638  }
2639  }
2640  if (getLaneChangeModel().getShadowLane() != 0) {
2641  // register on all shadow links
2642  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2643  if ((*i).myLink != 0) {
2644  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
2645  if (parallelLink != 0) {
2646  parallelLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2647  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2649  }
2650  }
2651  }
2652  }
2653 }
2654 
2655 
2656 void
2658  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2659  // skip the reminder if it is a lane reminder but not for my lane
2660  if (rem->first->getLane() != 0 && rem->second > 0.) {
2661 #ifdef _DEBUG
2662  if (myTraceMoveReminders) {
2663  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
2664  }
2665 #endif
2666  ++rem;
2667  } else {
2668  if (rem->first->notifyEnter(*this, reason)) {
2669 #ifdef _DEBUG
2670  if (myTraceMoveReminders) {
2671  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
2672  }
2673 #endif
2674  ++rem;
2675  } else {
2676 #ifdef _DEBUG
2677  if (myTraceMoveReminders) {
2678  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
2679  }
2680 #endif
2681  rem = myMoveReminders.erase(rem);
2682  }
2683  }
2684  }
2685 }
2686 
2687 
2688 bool
2689 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
2690  myAmOnNet = !onTeleporting;
2691  // vaporizing edge?
2692  /*
2693  if (enteredLane->getEdge().isVaporizing()) {
2694  // yep, let's do the vaporization...
2695  myLane = enteredLane;
2696  return true;
2697  }
2698  */
2699  // move mover reminder one lane further
2700  adaptLaneEntering2MoveReminder(*enteredLane);
2701  // set the entered lane as the current lane
2702  myLane = enteredLane;
2703  myLastBestLanesEdge = 0;
2704 
2705  // internal edges are not a part of the route...
2706  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
2707  ++myCurrEdge;
2708  }
2709  if (!onTeleporting) {
2711  } else {
2712  // normal move() isn't called so reset position here. must be done
2713  // before calling reminders
2714  // XXX: This seems strange to me since in activateReminders, which (e.g. for induction loops)
2715  // may call notifyEnter making use of the stored position to decide whether or not to add the vehicle...
2716  // Please recheck (Leo), refs. #2579
2717  myState.myPos = 0;
2720  }
2721  return hasArrived();
2722 }
2723 
2724 
2725 void
2727  myAmOnNet = true;
2728  myLane = enteredLane;
2730  // need to update myCurrentLaneInBestLanes
2731  updateBestLanes();
2732  // switch to and activate the new lane's reminders
2733  // keep OldLaneReminders
2734  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2735  addReminder(*rem);
2736  }
2738  MSLane* lane = myLane;
2739  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
2740  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
2741  if (lane != 0) {
2742  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
2743  }
2744  if (lane != 0) {
2745 #ifdef DEBUG_FURTHER
2746  if (DEBUG_COND) {
2747  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2748  }
2749 #endif
2750  myFurtherLanes[i]->resetPartialOccupation(this);
2751  myFurtherLanes[i] = lane;
2753 #ifdef DEBUG_FURTHER
2754  if (DEBUG_COND) {
2755  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2756  }
2757 #endif
2758  leftLength -= (lane)->setPartialOccupation(this);
2759  } else {
2760  // keep the old values, but ensure there is no shadow
2763  }
2764  }
2765  }
2766 #ifdef DEBUG_FURTHER
2767  if (DEBUG_COND) {
2768  std::cout << SIMTIME << " enterLaneAtLaneChange new furtherLanes=" << toString(myFurtherLanes) << "\n";
2769  }
2770 #endif
2771  myAngle = computeAngle();
2772 }
2773 
2774 
2775 void
2777  myState = State(pos, speed, posLat, pos - getVehicleType().getLength());
2778  if (myDeparture == NOT_YET_DEPARTED) {
2779  onDepart();
2780  }
2782  assert(myState.myPos >= 0);
2783  assert(myState.mySpeed >= 0);
2784  myWaitingTime = 0;
2785  myLane = enteredLane;
2786  myAmOnNet = true;
2787  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
2788  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
2789  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2790  addReminder(*rem);
2791  }
2792  activateReminders(notification);
2793  }
2794  // build the list of lanes the vehicle is lapping into
2795  if (!myLaneChangeModel->isOpposite()) {
2796  SUMOReal leftLength = myType->getLength() - pos;
2797  MSLane* clane = enteredLane;
2798  while (leftLength > 0) {
2799  clane = clane->getLogicalPredecessorLane();
2800  if (clane == 0 || clane == myLane) {
2801  break;
2802  }
2803  myFurtherLanes.push_back(clane);
2805  leftLength -= (clane)->setPartialOccupation(this);
2806  }
2807  myState.myBackPos = -leftLength;
2808  } else {
2809  // clear partial occupation
2810  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
2811 #ifdef DEBUG_FURTHER
2812  if (DEBUG_COND) {
2813  std::cout << SIMTIME << " enterLaneAtInsertion \n";
2814  }
2815 #endif
2816  (*i)->resetPartialOccupation(this);
2817  }
2818  myFurtherLanes.clear();
2819  myFurtherLanesPosLat.clear();
2820  }
2823  }
2824  myAngle = computeAngle();
2825  if (getLaneChangeModel().isOpposite()) {
2826  myAngle += M_PI;
2827  }
2828 }
2829 
2830 
2831 void
2833  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2834  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
2835 #ifdef _DEBUG
2836  if (myTraceMoveReminders) {
2837  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
2838  }
2839 #endif
2840  ++rem;
2841  } else {
2842 #ifdef _DEBUG
2843  if (myTraceMoveReminders) {
2844  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
2845  }
2846 #endif
2847  rem = myMoveReminders.erase(rem);
2848  }
2849  }
2851  // @note. In case of lane change, myFurtherLanes and partial occupation
2852  // are handled in enterLaneAtLaneChange()
2853  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
2854 #ifdef DEBUG_FURTHER
2855  if (DEBUG_COND) {
2856  std::cout << SIMTIME << " leaveLane \n";
2857  }
2858 #endif
2859  (*i)->resetPartialOccupation(this);
2860  }
2861  myFurtherLanes.clear();
2862  myFurtherLanesPosLat.clear();
2863  }
2864  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
2865  myAmOnNet = false;
2866  }
2868  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
2869  }
2871  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
2872  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
2873  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
2874  myStops.pop_front();
2875  }
2876  }
2877 }
2878 
2879 
2882  return *myLaneChangeModel;
2883 }
2884 
2885 
2888  return *myLaneChangeModel;
2889 }
2890 
2891 
2892 const std::vector<MSVehicle::LaneQ>&
2894  return *myBestLanes.begin();
2895 }
2896 
2897 
2898 void
2899 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
2900 #ifdef DEBUG_BESTLANES
2901  if (DEBUG_COND) {
2902  std::cout << SIMTIME << " updateBestLanes veh=" << getID() << " startLane1=" << Named::getIDSecure(startLane) << " myLane=" << Named::getIDSecure(myLane) << "\n";
2903  }
2904 #endif
2905 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2906  if (gDebugSelectedVehicle == getID()) {
2907  int bla = 0;
2908  myLastBestLanesEdge = 0;
2909  }
2910 #endif
2911  if (startLane == 0) {
2912  startLane = myLane;
2913  }
2914  assert(startLane != 0);
2915  if (getLaneChangeModel().isOpposite()) {
2916  // depending on the calling context, startLane might be the forward lane
2917  // or the reverse-direction lane. In the latter case we need to
2918  // transform it to the forward lane.
2919  bool startLaneIsOpposite = (startLane->isInternal()
2920  ? & (startLane->getLinkCont()[0]->getLane()->getEdge()) != *(myCurrEdge + 1)
2921  : &startLane->getEdge() != *myCurrEdge);
2922  if (startLaneIsOpposite) {
2923  startLane = startLane->getOpposite();
2924  assert(startLane != 0);
2925  }
2926  }
2927  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
2929  return;
2930  }
2931  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
2932  if (myBestLanes.size() == 0 || forceRebuild) {
2933  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
2934  updateBestLanes(true, startLane->getLogicalPredecessorLane());
2935  }
2936  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
2937  return;
2938  }
2939  // adapt best lanes to fit the current internal edge:
2940  // keep the entries that are reachable from this edge
2941  const MSEdge* nextEdge = startLane->getNextNormal();
2942  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
2943  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
2944  std::vector<LaneQ>& lanes = *it;
2945  assert(lanes.size() > 0);
2946  if (&(lanes[0].lane->getEdge()) == nextEdge) {
2947  // keep those lanes which are successors of internal lanes from the edge of startLane
2948  std::vector<LaneQ> oldLanes = lanes;
2949  lanes.clear();
2950  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
2951  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
2952  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
2953  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
2954  lanes.push_back(*it_lane);
2955  break;
2956  }
2957  }
2958  }
2959  assert(lanes.size() == startLane->getEdge().getLanes().size());
2960  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
2961  for (int i = 0; i < (int)lanes.size(); ++i) {
2962  if (i + lanes[i].bestLaneOffset < 0) {
2963  lanes[i].bestLaneOffset = -i;
2964  }
2965  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
2966  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
2967  }
2968  assert(i + lanes[i].bestLaneOffset >= 0);
2969  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
2970  if (lanes[i].bestContinuations[0] != 0) {
2971  // patch length of bestContinuation to match expectations (only once)
2972  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
2973  }
2974  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
2975  myCurrentLaneInBestLanes = lanes.begin() + i;
2976  }
2977  assert(&(lanes[i].lane->getEdge()) == nextEdge);
2978  }
2979  myLastBestLanesInternalLane = startLane;
2981  return;
2982  } else {
2983  // remove passed edges
2984  it = myBestLanes.erase(it);
2985  }
2986  }
2987  assert(false); // should always find the next edge
2988  }
2989  // start rebuilding
2990  myLastBestLanesEdge = &startLane->getEdge();
2991  myBestLanes.clear();
2992 
2993  // get information about the next stop
2994  const MSEdge* nextStopEdge = 0;
2995  const MSLane* nextStopLane = 0;
2996  SUMOReal nextStopPos = 0;
2997  if (!myStops.empty()) {
2998  const Stop& nextStop = myStops.front();
2999  nextStopLane = nextStop.lane;
3000  nextStopEdge = &nextStopLane->getEdge();
3001  nextStopPos = nextStop.startPos;
3002  }
3003  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
3004  nextStopEdge = *(myRoute->end() - 1);
3005  nextStopLane = nextStopEdge->getLanes()[myArrivalLane];
3006  nextStopPos = myArrivalPos;
3007  }
3008  if (nextStopEdge != 0) {
3009  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
3010  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
3011  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
3012  }
3013 
3014  // go forward along the next lanes;
3015  int seen = 0;
3016  SUMOReal seenLength = 0;
3017  bool progress = true;
3018  for (MSRouteIterator ce = myCurrEdge; progress;) {
3019  std::vector<LaneQ> currentLanes;
3020  const std::vector<MSLane*>* allowed = 0;
3021  const MSEdge* nextEdge = 0;
3022  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
3023  nextEdge = *(ce + 1);
3024  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
3025  }
3026  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
3027  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
3028  LaneQ q;
3029  MSLane* cl = *i;
3030  q.lane = cl;
3031  q.bestContinuations.push_back(cl);
3032  q.bestLaneOffset = 0;
3033  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
3034  q.currentLength = q.length;
3035  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
3036  q.occupation = 0;
3037  q.nextOccupation = 0;
3038  currentLanes.push_back(q);
3039  }
3040  //
3041  if (nextStopEdge == *ce) {
3042  progress = false;
3043  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
3044  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
3045  (*q).allowsContinuation = false;
3046  (*q).length = nextStopPos;
3047  (*q).currentLength = (*q).length;
3048  }
3049  }
3050  }
3051 
3052  myBestLanes.push_back(currentLanes);
3053  ++seen;
3054  seenLength += currentLanes[0].lane->getLength();
3055  ++ce;
3056  progress &= (seen <= 4 || seenLength < 3000);
3057  progress &= seen <= 8;
3058  progress &= ce != myRoute->end();
3059  /*
3060  if(progress) {
3061  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
3062  }
3063  */
3064  }
3065 
3066  // we are examining the last lane explicitly
3067  if (myBestLanes.size() != 0) {
3068  SUMOReal bestLength = -1;
3069  int bestThisIndex = 0;
3070  int index = 0;
3071  std::vector<LaneQ>& last = myBestLanes.back();
3072  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
3073  if ((*j).length > bestLength) {
3074  bestLength = (*j).length;
3075  bestThisIndex = index;
3076  }
3077  }
3078  index = 0;
3079  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
3080  if ((*j).length < bestLength) {
3081  (*j).bestLaneOffset = bestThisIndex - index;
3082  }
3083  }
3084  }
3085 #ifdef DEBUG_BESTLANES
3086  if (DEBUG_COND) {
3087  std::cout << " last edge:\n";
3088  std::vector<LaneQ>& laneQs = myBestLanes.back();
3089  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
3090  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
3091  }
3092  }
3093 #endif
3094  // go backward through the lanes
3095  // track back best lane and compute the best prior lane(s)
3096  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
3097  std::vector<LaneQ>& nextLanes = (*(i - 1));
3098  std::vector<LaneQ>& clanes = (*i);
3099  MSEdge& cE = clanes[0].lane->getEdge();
3100  int index = 0;
3101  SUMOReal bestConnectedLength = -1;
3102  SUMOReal bestLength = -1;
3103  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
3104  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
3105  bestConnectedLength = (*j).length;
3106  }
3107  if (bestLength < (*j).length) {
3108  bestLength = (*j).length;
3109  }
3110  }
3111  // compute index of the best lane (highest length and least offset from the best next lane)
3112  int bestThisIndex = 0;
3113  if (bestConnectedLength > 0) {
3114  index = 0;
3115  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3116  LaneQ bestConnectedNext;
3117  bestConnectedNext.length = -1;
3118  if ((*j).allowsContinuation) {
3119  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
3120  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
3121  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
3122  bestConnectedNext = *m;
3123  }
3124  }
3125  }
3126  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
3127  (*j).length += bestLength;
3128  } else {
3129  (*j).length += bestConnectedNext.length;
3130  }
3131  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
3132  }
3133  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
3134  if (clanes[bestThisIndex].length < (*j).length
3135  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
3136  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
3137  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
3138  ) {
3139  bestThisIndex = index;
3140  }
3141  }
3142 #ifdef DEBUG_BESTLANES
3143  if (DEBUG_COND) {
3144  std::cout << " edge=" << cE.getID() << "\n";
3145  std::vector<LaneQ>& laneQs = clanes;
3146  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
3147  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
3148  }
3149  }
3150 #endif
3151 
3152  } else {
3153  // only needed in case of disconnected routes
3154  int bestNextIndex = 0;
3155  int bestDistToNeeded = (int) clanes.size();
3156  index = 0;
3157  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3158  if ((*j).allowsContinuation) {
3159  int nextIndex = 0;
3160  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
3161  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
3162  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
3163  bestDistToNeeded = abs((*m).bestLaneOffset);
3164  bestThisIndex = index;
3165  bestNextIndex = nextIndex;
3166  }
3167  }
3168  }
3169  }
3170  }
3171  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
3172  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
3173 
3174  }
3175  // set bestLaneOffset for all lanes
3176  index = 0;
3177  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
3178  if ((*j).length < clanes[bestThisIndex].length
3179  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
3180  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
3181  ) {
3182  (*j).bestLaneOffset = bestThisIndex - index;
3183  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
3184  // try to move away from the lower-priority lane before it ends
3185  (*j).length = (*j).currentLength;
3186  }
3187  } else {
3188  (*j).bestLaneOffset = 0;
3189  }
3190  }
3191  }
3193 #ifdef DEBUG_BESTLANES
3194  if (DEBUG_COND) {
3195  std::cout << SIMTIME << " veh=" << getID() << " bestCont=" << toString(getBestLanesContinuation()) << "\n";
3196  }
3197 #endif
3198  return;
3199 }
3200 
3201 
3202 int
3203 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
3204  if (conts.size() < 2) {
3205  return -1;
3206  } else {
3207  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
3208  if (link != 0) {
3209  return link->havePriority() ? 1 : 0;
3210  } else {
3211  // disconnected route
3212  return -1;
3213  }
3214  }
3215 }
3216 
3217 
3218 void
3220  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
3221  std::vector<LaneQ>::iterator i;
3222  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
3223  SUMOReal nextOccupation = 0;
3224  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
3225  nextOccupation += (*j)->getBruttoVehLenSum();
3226  }
3227  (*i).nextOccupation = nextOccupation;
3228  if ((*i).lane == startLane) {
3230  }
3231  }
3232 }
3233 
3234 
3235 const std::vector<MSLane*>&
3237  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3238  return myEmptyLaneVector;
3239  }
3240  return (*myCurrentLaneInBestLanes).bestContinuations;
3241 }
3242 
3243 
3244 const std::vector<MSLane*>&
3246  const MSLane* lane = l;
3247  // XXX: shouldn't this be a "while" to cover more than one internal lane? (Leo) Refs. #2575
3249  // internal edges are not kept inside the bestLanes structure
3250  lane = lane->getLinkCont()[0]->getLane();
3251  }
3252  if (myBestLanes.size() == 0) {
3253  return myEmptyLaneVector;
3254  }
3255  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
3256  if ((*i).lane == lane) {
3257  return (*i).bestContinuations;
3258  }
3259  }
3260  return myEmptyLaneVector;
3261 }
3262 
3263 
3264 int
3266  if (myBestLanes.empty() || myBestLanes[0].empty()) {
3267  return 0;
3268  } else {
3269  return (*myCurrentLaneInBestLanes).bestLaneOffset;
3270  }
3271 }
3272 
3273 
3274 void
3276  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
3277  assert(laneIndex < (int)preb.size());
3278  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
3279 }
3280 
3281 
3282 void
3284  if (MSGlobals::gLaneChangeDuration > 0 && !getLaneChangeModel().isChangingLanes()) {
3285  myState.myPosLat = 0;
3286  }
3287 }
3288 
3289 
3290 SUMOReal
3291 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) const {
3293  if (isOnRoad() && destEdge != NULL) {
3294  if (&myLane->getEdge() == *myCurrEdge) {
3295  // vehicle is on a normal edge
3296  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
3297  } else {
3298  // vehicle is on inner junction edge
3299  distance = myLane->getLength() - getPositionOnLane();
3300  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
3301  }
3302  }
3303  return distance;
3304 }
3305 
3306 
3307 std::pair<const MSVehicle* const, SUMOReal>
3309  if (myLane == 0) {
3310  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
3311  }
3312  if (dist == 0) {
3314  }
3315  const MSVehicle* lead = 0;
3316  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
3317  // vehicle might be outside the road network
3318  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
3319  if (it != vehs.end() && it + 1 != vehs.end()) {
3320  lead = *(it + 1);
3321  }
3322  if (lead != 0) {
3323  std::pair<const MSVehicle* const, SUMOReal> result(
3326  return result;
3327  }
3328  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
3329  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
3330  std::pair<const MSVehicle* const, SUMOReal> result = myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
3332  return result;
3333 }
3334 
3335 
3336 SUMOReal
3338  // calling getLeader with 0 would induce a dist calculation but we only want to look for the leaders on the current lane
3339  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader(-1);
3340  if (leaderInfo.first == 0 || getSpeed() == 0) {
3341  return -1;
3342  }
3343  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
3344 }
3345 
3346 
3347 SUMOReal
3350 }
3351 
3352 
3353 SUMOReal
3356 }
3357 
3358 
3359 SUMOReal
3362 }
3363 
3364 
3365 SUMOReal
3368 }
3369 
3370 
3371 SUMOReal
3374 }
3375 
3376 
3377 SUMOReal
3380 }
3381 
3382 
3383 SUMOReal
3386 }
3387 
3388 
3389 SUMOReal
3392 }
3393 
3394 
3395 void
3397  if (myPersonDevice == 0) {
3399  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
3400  }
3402  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
3403  int numExpected = (int) myStops.front().awaitedPersons.size();
3404  if (numExpected != 0) {
3405  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
3406  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
3407  // Bus drivers usually do not know the names of the passengers.
3408  myStops.front().awaitedPersons.erase(person->getID());
3409  numExpected = (int) myStops.front().awaitedPersons.size();
3410  }
3411  if (numExpected == 0) {
3412  myStops.front().duration = 0;
3413  }
3414  }
3415 }
3416 
3417 void
3419  if (myContainerDevice == 0) {
3421  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
3422  }
3423  myContainerDevice->addTransportable(container);
3424  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
3425  int numExpected = (int) myStops.front().awaitedContainers.size();
3426  if (numExpected != 0) {
3427  myStops.front().awaitedContainers.erase(container->getID());
3428  numExpected = (int) myStops.front().awaitedContainers.size();
3429  }
3430  if (numExpected == 0) {
3431  myStops.front().duration = 0;
3432  }
3433  }
3434 }
3435 
3436 
3437 void
3439  const bool isPerson = dynamic_cast<MSPerson*>(t) != 0;
3441  if (device != 0) {
3442  device->removeTransportable(t);
3443  }
3444 }
3445 
3446 
3447 const std::vector<MSTransportable*>&
3449  if (myPersonDevice == 0) {
3451  } else {
3453  }
3454 }
3455 
3456 
3457 const std::vector<MSTransportable*>&
3459  if (myContainerDevice == 0) {
3461  } else {
3463  }
3464 }
3465 
3466 
3467 int
3469  int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
3470  return boarded + myParameter->personNumber;
3471 }
3472 
3473 int
3475  int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
3476  return loaded + myParameter->containerNumber;
3477 }
3478 
3479 
3480 void
3483  int state = getLaneChangeModel().getOwnState();
3484  if ((state & LCA_LEFT) != 0 && (state & LCA_SUBLANE) == 0) {
3486  } else if ((state & LCA_RIGHT) != 0 && (state & LCA_SUBLANE) == 0) {
3488  } else if (getLaneChangeModel().isChangingLanes()) {
3489  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
3491  } else {
3493  }
3494  } else {
3495  const MSLane* lane = getLane();
3496  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
3497  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
3498  switch ((*link)->getDirection()) {
3499  case LINKDIR_TURN:
3500  case LINKDIR_LEFT:
3501  case LINKDIR_PARTLEFT:
3503  break;
3504  case LINKDIR_RIGHT:
3505  case LINKDIR_PARTRIGHT:
3507  break;
3508  default:
3509  break;
3510  }
3511  }
3512  }
3513  if (myInfluencer != 0 && myInfluencer->getSignals() >= 0) {
3515  myInfluencer->setSignals(-1); // overwrite computed signals only once
3516  }
3517 }
3518 
3519 void
3521  if (currentTime % 1000 == 0) {
3524  } else {
3526  }
3527  }
3528 }
3529 
3530 
3531 void
3533  if (myType->amVehicleSpecific()) {
3534  delete myType;
3535  }
3536  myType = type;
3537 }
3538 
3539 int
3541  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
3542  return (int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
3543 }
3544 
3545 
3546 void
3548  assert(lane != 0);
3549  myLane = lane;
3550  myState.myPos = pos;
3551  myState.myPosLat = posLat;
3553 }
3554 
3555 
3556 SUMOReal
3558  return myState.myPosLat + 0.5 * myLane->getWidth() - 0.5 * getVehicleType().getWidth();
3559 }
3560 
3561 
3562 SUMOReal
3564  return getCenterOnEdge(lane) - 0.5 * getVehicleType().getWidth();
3565 }
3566 
3567 
3568 SUMOReal
3570  if (lane == 0 || &lane->getEdge() == &myLane->getEdge()) {
3571  return myLane->getRightSideOnEdge() + myState.myPosLat + 0.5 * myLane->getWidth();
3572  } else {
3573  assert(myFurtherLanes.size() == myFurtherLanesPosLat.size());
3574  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3575  if (myFurtherLanes[i] == lane) {
3576 #ifdef DEBUG_FURTHER
3577  if (DEBUG_COND) std::cout << " getCenterOnEdge veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " furtherLat=" << myFurtherLanesPosLat[i]
3578  << " result=" << lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth()
3579  << "\n";
3580 #endif
3581  return lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth();
3582  }
3583  }
3584  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3585  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3586  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3587  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
3588  if (shadowFurther[i] == lane) {
3589  assert(getLaneChangeModel().getShadowLane() != 0);
3590  return (lane->getRightSideOnEdge() + getLaneChangeModel().getShadowFurtherLanesPosLat()[i] + 0.5 * lane->getWidth()
3592  }
3593  }
3594  assert(false);
3595  throw ProcessError("Request lateral pos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3596  }
3597 }
3598 
3599 
3600 SUMOReal
3601 MSVehicle::getLatOffset(const MSLane* lane) const {
3602  assert(lane != 0);
3603  if (&lane->getEdge() == &myLane->getEdge()) {
3604  return myLane->getRightSideOnEdge() - lane->getRightSideOnEdge();
3605  } else {
3606  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3607  if (myFurtherLanes[i] == lane) {
3608 #ifdef DEBUG_FURTHER
3609  if (DEBUG_COND) {
3610  std::cout << " getLatOffset veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " posLat=" << myState.myPosLat << " furtherLat=" << myFurtherLanesPosLat[i] << "\n";
3611  }
3612 #endif
3614  }
3615  }
3616 #ifdef DEBUG_FURTHER
3617  if (DEBUG_COND) {
3618  std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3619  }
3620 #endif
3621  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3622  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3623  if (shadowFurther[i] == lane) {
3624 #ifdef DEBUG_FURTHER
3625  if (DEBUG_COND) std::cout << " getLatOffset veh=" << getID()
3626  << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
3627  << " lane=" << lane->getID()
3628  << " i=" << i
3629  << " posLat=" << myState.myPosLat
3630  << " shadowPosLat=" << getLatOffset(getLaneChangeModel().getShadowLane())
3631  << " shadowFurtherLat=" << getLaneChangeModel().getShadowFurtherLanesPosLat()[i]
3632  << "\n";
3633 #endif
3635  }
3636  }
3637  assert(false);
3638  throw ProcessError("Request lateral offset of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3639  }
3640 }
3641 
3642 
3643 SUMOReal
3645  return (fabs(getLateralPositionOnLane()) + 0.5 * getVehicleType().getWidth()
3646  - 0.5 * myLane->getWidth());
3647 }
3648 
3649 
3650 void
3652  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
3653  if ((*i).myLink != 0) {
3654  (*i).myLink->removeApproaching(this);
3655  }
3656  }
3657  // unregister on all shadow links
3659 }
3660 
3661 
3662 bool
3664  // the following links are unsafe:
3665  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
3666  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
3668  const SUMOReal dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
3669  if (seen < dist) {
3670  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
3671  int view = 1;
3672  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3673  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
3674  while (!lane->isLinkEnd(link) && seen <= dist) {
3675  if (!lane->getEdge().isInternal()
3676  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
3677  || !(*link)->havePriority())) {
3678  // find the drive item corresponding to this link
3679  bool found = false;
3680  while (di != myLFLinkLanes.end() && !found) {
3681  if ((*di).myLink != 0) {
3682  const MSLane* diPredLane = (*di).myLink->getLaneBefore();
3683  if (diPredLane != 0) {
3684  if (&diPredLane->getEdge() == &lane->getEdge()) {
3685  found = true;
3686  }
3687  }
3688  }
3689  if (!found) {
3690  di++;
3691  }
3692  }
3693  if (found) {
3694  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
3695  (*di).getLeaveSpeed(), getVehicleType().getLength());
3696  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
3697  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
3698  return true;
3699  }
3700  }
3701  // no drive item is found if the vehicle aborts it's request within dist
3702  }
3703  lane = (*link)->getViaLaneOrLane();
3704  if (!lane->getEdge().isInternal()) {
3705  view++;
3706  }
3707  seen += lane->getLength();
3708  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3709  }
3710  }
3711  return false;
3712 }
3713 
3714 
3717  PositionVector centerLine;
3718  centerLine.push_back(getPosition());
3719  centerLine.push_back(getBackPosition());
3720  centerLine.move2side(0.5 * myType->getWidth());
3721  PositionVector result = centerLine;
3722  centerLine.move2side(-myType->getWidth());
3723  result.append(centerLine.reverse(), POSITION_EPS);
3724  return result;
3725 }
3726 
3727 
3730  // XXX implement more types
3731  switch (myType->getGuiShape()) {
3732  case SVS_PASSENGER:
3733  case SVS_PASSENGER_SEDAN:
3735  case SVS_PASSENGER_WAGON:
3736  case SVS_PASSENGER_VAN: {
3737  PositionVector result;
3738  PositionVector centerLine;
3739  centerLine.push_back(getPosition());
3740  centerLine.push_back(getBackPosition());
3741  PositionVector line1 = centerLine;
3742  PositionVector line2 = centerLine;
3743  line1.move2side(0.3 * myType->getWidth());
3744  line2.move2side(0.5 * myType->getWidth());
3745  line2.scaleRelative(0.8);
3746  result.push_back(line1[0]);
3747  result.push_back(line2[0]);
3748  result.push_back(line2[1]);
3749  result.push_back(line1[1]);
3750  line1.move2side(-0.6 * myType->getWidth());
3751  line2.move2side(-1.0 * myType->getWidth());
3752  result.push_back(line1[1]);
3753  result.push_back(line2[1]);
3754  result.push_back(line2[0]);
3755  result.push_back(line1[0]);
3756  return result;
3757  }
3758  default:
3759  return getBoundingBox();
3760  }
3761 }
3762 
3763 
3764 #ifndef NO_TRACI
3765 bool
3766 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
3767  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
3768  //if the stop exists update the duration
3769  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3770  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
3771  if (duration == 0 && !iter->reached) {
3772  myStops.erase(iter);
3773  } else {
3774  iter->duration = duration;
3775  }
3776  return true;
3777  }
3778  }
3779 
3781  newStop.lane = lane->getID();
3782  newStop.startPos = startPos;
3783  newStop.endPos = endPos;
3784  newStop.duration = duration;
3785  newStop.until = until;
3786  newStop.triggered = triggered;
3787  newStop.containerTriggered = containerTriggered;
3788  newStop.parking = parking;
3789  newStop.index = STOP_INDEX_FIT;
3790  const bool result = addStop(newStop, errorMsg);
3791  if (result) {
3792  myParameter->stops.push_back(newStop);
3793  }
3794  if (myLane != 0) {
3795  updateBestLanes(true);
3796  }
3797  return result;
3798 }
3799 
3800 
3801 bool
3802 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
3803  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
3804  //if the stop exists update the duration
3805  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3806  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
3807  if (stop != 0 && stop->getID() == stopId) {
3808  if (duration == 0 && !iter->reached) {
3809  myStops.erase(iter);
3810  } else {
3811  iter->duration = duration;
3812  }
3813  return true;
3814  }
3815  }
3816 
3818  MSStoppingPlace* bs = 0;
3819  if (isContainerStop) {
3820  newStop.containerstop = stopId;
3821  bs = MSNet::getInstance()->getContainerStop(stopId);
3822  if (bs == 0) {
3823  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3824  return false;
3825  }
3826  } else {
3827  newStop.busstop = stopId;
3828  bs = MSNet::getInstance()->getBusStop(stopId);
3829  if (bs == 0) {
3830  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3831  return false;
3832  }
3833  }
3834  newStop.duration = duration;
3835  newStop.until = until;
3836  newStop.triggered = triggered;
3837  newStop.containerTriggered = containerTriggered;
3838  newStop.parking = parking;
3839  newStop.index = STOP_INDEX_FIT;
3840  newStop.lane = bs->getLane().getID();
3841  newStop.endPos = bs->getEndLanePosition();
3842  newStop.startPos = bs->getBeginLanePosition();
3843  const bool result = addStop(newStop, errorMsg);
3844  if (result) {
3845  myParameter->stops.push_back(newStop);
3846  }
3847  if (myLane != 0) {
3848  updateBestLanes(true);
3849  }
3850  return result;
3851 }
3852 
3853 
3854 bool
3856  if (isStopped()) {
3860  }
3864  }
3865  // we have waited long enough and fulfilled any passenger-requirements
3866  if (myStops.front().busstop != 0) {
3867  // inform bus stop about leaving it
3868  myStops.front().busstop->leaveFrom(this);
3869  }
3870  // we have waited long enough and fulfilled any container-requirements
3871  if (myStops.front().containerstop != 0) {
3872  // inform container stop about leaving it
3873  myStops.front().containerstop->leaveFrom(this);
3874  }
3875  if (myStops.front().parkingarea != 0) {
3876  // inform parking area about leaving it
3877  myStops.front().parkingarea->leaveFrom(this);
3878  }
3879  // the current stop is no longer valid
3881  if (MSStopOut::active()) {
3882  MSStopOut::getInstance()->stopEnded(this, myStops.front());
3883  }
3884  myStops.pop_front();
3885  // do not count the stopping time towards gridlock time.
3886  // Other outputs use an independent counter and are not affected.
3887  myWaitingTime = 0;
3888  // maybe the next stop is on the same edge; let's rebuild best lanes
3889  updateBestLanes(true);
3890  // continue as wished...
3892  return true;
3893  }
3894  return false;
3895 }
3896 
3897 
3900  return myStops.front();
3901 }
3902 
3903 
3906  if (myInfluencer == 0) {
3907  myInfluencer = new Influencer();
3908  }
3909  return *myInfluencer;
3910 }
3911 
3912 
3913 const MSVehicle::Influencer*
3915  return myInfluencer;
3916 }
3917 
3918 
3919 SUMOReal
3921  if (myInfluencer != 0) {
3922  return myInfluencer->getOriginalSpeed();
3923  }
3924  return myState.mySpeed;
3925 }
3926 
3927 
3928 int
3930  if (hasInfluencer()) {
3932  MSNet::getInstance()->getCurrentTimeStep(),
3933  myLane->getEdge(),
3934  getLaneIndex(),
3935  state);
3936  }
3937  return state;
3938 }
3939 
3940 
3941 void
3943  myCachedPosition = xyPos;
3944 }
3945 
3946 #endif
3947 
3948 bool
3950  return myInfluencer != 0 && myInfluencer->isVTDControlled();
3951 }
3952 
3953 
3954 void
3956  // lots of duplication with SUMOVehicleParameter::Stop::write()
3957  dev.openTag(SUMO_TAG_STOP);
3958  if (busstop != 0) {
3959  dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop->getID());
3960  }
3961  if (containerstop != 0) {
3962  dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop->getID());
3963  }
3964  if (busstop == 0 && containerstop == 0) {
3965  dev.writeAttr(SUMO_ATTR_LANE, lane->getID());
3966  dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
3967  dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
3968  }
3969  if (duration >= 0) {
3970  dev.writeAttr(SUMO_ATTR_DURATION, STEPS2TIME(duration));
3971  }
3972  if (until >= 0) {
3973  dev.writeAttr(SUMO_ATTR_UNTIL, STEPS2TIME(until));
3974  }
3975  if (triggered) {
3976  dev.writeAttr(SUMO_ATTR_TRIGGERED, triggered);
3977  }
3978  if (containerTriggered) {
3979  dev.writeAttr(SUMO_ATTR_CONTAINER_TRIGGERED, containerTriggered);
3980  }
3981  if (parking) {
3982  dev.writeAttr(SUMO_ATTR_PARKING, parking);
3983  }
3984  if (awaitedPersons.size() > 0) {
3985  dev.writeAttr(SUMO_ATTR_EXPECTED, joinToString(awaitedPersons, " "));
3986  }
3987  if (awaitedContainers.size() > 0) {
3988  dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, joinToString(awaitedContainers, " "));
3989  }
3990  dev.closeTag();
3991 }
3992 
3993 
3994 SUMOReal
3996  if (busstop != 0) {
3997  return busstop->getLastFreePos(veh);
3998  } else if (containerstop != 0) {
3999  return containerstop->getLastFreePos(veh);
4000  } else if (parkingarea != 0) {
4001  return parkingarea->getLastFreePos(veh);
4002  } else if (chargingStation != 0) {
4003  return chargingStation->getLastFreePos(veh);
4004  }
4005  return endPos;
4006 }
4007 
4008 
4009 void
4012  // here starts the vehicle internal part (see loading)
4013  std::vector<SUMOTime> internals;
4014  internals.push_back(myDeparture);
4015  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
4016  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
4020  // save stops and parameters
4021  for (std::list<Stop>::iterator it = myStops.begin(); it != myStops.end(); ++it) {
4022  (*it).write(out);
4023  }
4024  myParameter->writeParams(out);
4025  out.closeTag();
4026 }
4027 
4028 
4029 void
4030 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
4031  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
4032  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
4033  }
4034  int routeOffset;
4035  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
4036  bis >> myDeparture;
4037  bis >> routeOffset;
4038  if (hasDeparted()) {
4039  myDeparture -= offset;
4040  myCurrEdge += routeOffset;
4041  }
4045  // no need to reset myCachedPosition here since state loading happens directly after creation
4046 }
4047 
4048 /****************************************************************************/
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:37
A lane area vehicles can halt at.
Definition: MSParkingArea.h:66
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1120
void setAngle(SUMOReal angle)
Set a custom vehicle angle in rad.
Definition: MSVehicle.cpp:814
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1475
int getCapacity() const
Returns the area capacity.
The link is a partial left direction.
int getOccupancy() const
Returns the area occupancy.
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
Definition: MSVehicle.cpp:3949
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
const MSVehicleType * myType
This Vehicle&#39;s type.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:3532
static bool active()
Definition: MSStopOut.h:64
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:302
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Adds a vehicle to the list of waiting vehiclse to a given edge.
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:2689
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:571
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:3203
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:83
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1427
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1466
SUMOReal getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
void planMove(const SUMOTime t, const MSLeaderInfo &ahead, const SUMOReal lengthsInFront)
Compute safe velocities for the upcoming lanes based on positions and speeds from the last time step...
Definition: MSVehicle.cpp:1344
bool amVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
SUMOReal speed() const
Speed of this state.
Definition: MSVehicle.h:118
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:837
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1494
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
int getVehicleNumber() const
Returns the number of vehicles on this lane (for which this lane is responsible)
Definition: MSLane.h:353
virtual std::string toString() const
print a debugging representation
SUMOReal rotationAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
void remove(MSVehicle *veh)
Remove a vehicle from this transfer object.
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:48
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1656
SUMOReal backPos() const
back Position of this state
Definition: MSVehicle.h:128
MoveReminderCont myMoveReminders
Currently relevant move reminders.
SUMOReal myArrivalPos
The position on the destination lane where the vehicle stops.
The action is due to the default of keeping right "Rechtsfahrgebot".
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
The action is done to help someone else.
const MSEdge * myLastBestLanesEdge
Definition: MSVehicle.h:1474
std::string containerstop
(Optional) container stop if one is assigned to the stop
const MSEdge * getNextNormal() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1306
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:1076
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1472
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1512
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1364
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1482
bool parking
whether the vehicle is removed from the net while stopping
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:407
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:783
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1505
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1467
void setTentativeLaneAndPosition(MSLane *lane, SUMOReal pos, SUMOReal posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:3547
MSParkingArea * getParkingArea(const std::string &id) const
Returns the named parking area.
Definition: MSNet.cpp:854
SUMOReal getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3563
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:61
Stop & getNextStop()
Definition: MSVehicle.cpp:3899
A lane area vehicles can halt at.
const std::vector< SUMOReal > & getShadowFurtherLanesPosLat() const
bool replaceParkingArea(MSParkingArea *parkingArea, std::string &errorMsg)
replace the current parking area stop with a new stop with merge duration
Definition: MSVehicle.cpp:1018
SUMOReal getMaxSpeed() const
Returns the maximum speed.
DriveItemVector myLFLinkLanes
Definition: MSVehicle.h:1585
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.h:113
void enterLaneAtInsertion(MSLane *enteredLane, SUMOReal pos, SUMOReal speed, SUMOReal posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:2776
bool resumeFromStopping()
Definition: MSVehicle.cpp:3855
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1515
bool hasInfluencer() const
Definition: MSVehicle.h:1386
SUMOTime duration
The stopping duration.
void enter(SUMOVehicle *what, SUMOReal beg, SUMOReal end)
Called if a vehicle enters this stop.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
SUMOReal maximumSafeStopSpeed(SUMOReal gap, SUMOReal currentSpeed, bool onInsertion=false, SUMOReal headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:477
SUMOTime myLastVTDAccess
Definition: MSVehicle.h:1353
The speed is given.
SUMOReal getLengthWithGap() const
Get vehicle&#39;s length including the minimum gap [m].
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive...
Definition: MSVehicle.h:701
SUMOReal getImpatience() const
Returns this vehicles impatience.
void setBlinkerInformation()
Definition: MSVehicle.cpp:3481
#define M_PI
Definition: angles.h:37
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2542
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:3418
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1578
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:3663
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1502
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:325
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:3920
The vehicle arrived at a junction.
bool isVTDControlled() const
Definition: MSVehicle.cpp:441
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:536
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
SUMOReal getLength() const
Returns the lane&#39;s length.
Definition: MSLane.h:480
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:767
SUMOReal departSpeed
(optional) The initial speed of the vehicle
virtual SUMOReal maxNextSpeed(SUMOReal speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:190
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:599
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:60
bool myConsiderMaxAcceleration
Whether the maximum acceleration shall be regarded.
Definition: MSVehicle.h:1335
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
void updateState(SUMOReal vNext)
updates the vehicles state, given a next value for its speed. This value can be negative in case of t...
Definition: MSVehicle.cpp:2251
int getShadowDirection() const
return the direction in which the current shadow lane lies
The link is a 180 degree turn.
virtual void clear()
discard all information
Notification
Definition of a vehicle state.
static SUMOReal rand()
Returns a random real number in [0, 1)
Definition: RandHelper.h:62
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
Wants go to the right.
SUMOReal getLength() const
Get vehicle&#39;s length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1576
SUMOReal currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:695
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1496
#define STOPPING_PLACE_OFFSET
Definition: MSVehicle.cpp:97
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1205
SUMOReal implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:501
lane can change or stay
std::pair< const MSVehicle *, SUMOReal > CLeaderDist
Definition: MSLeaderInfo.h:42
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:3360
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1341
SUMOReal getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:496
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:831
const MSLane * getBackLane() const
Definition: MSVehicle.cpp:2298
void registerEmergencyStop()
register emergency stop
SUMOReal getEndLanePosition() const
Returns the end position of this stop.
MSChargingStation * getChargingStation(const std::string &id) const
Returns the named charging station.
Definition: MSNet.cpp:877
void scaleRelative(SUMOReal factor)
enlarges/shrinks the polygon by a factor based at the centroid
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:128
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0, bool addStops=true)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:608
T MAX2(T a, T b)
Definition: StdDefs.h:70
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:97
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:224
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:1084
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
void write(OutputDevice &dev) const
Definition: MSVehicle.cpp:3955
#define DEBUG_COND
Definition: MSVehicle.cpp:95
const MSRoute * myRoute
This Vehicle&#39;s route.
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:59
const std::string & getID() const
returns the id of the transportable
bool hasDeparted() const
Returns whether this vehicle has already departed.
SUMOReal getCenterOnEdge() const
Definition: MSLane.h:905
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:452
SUMOReal estimateLeaveSpeed(const MSLink *const link, const SUMOReal vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1598
SUMOTime until
The time at which the vehicle may continue its journey.
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1461
SUMOReal mySpeed
the stored speed (should be >=0 at any time)
Definition: MSVehicle.h:143
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:803
This is an uncontrolled, right-before-left link.
render as a sedan passenger vehicle ("Stufenheck")
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:3348
void removeWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Removes a vehicle from the list of waiting vehicles to a given edge.
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1843
int getLaneIndex() const
Definition: MSVehicle.cpp:3540
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
SUMOTime myMemorySize
the maximal memory to store
Definition: MSVehicle.h:207
std::pair< const MSVehicle *const, SUMOReal > getLeader(SUMOReal dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:3308
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
bool isInternal() const
Definition: MSLane.cpp:1443
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:375
int myArrivalLane
The destination lane where the vehicle stops.
const SUMOVehicleParameter * myParameter
This Vehicle&#39;s parameter.
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:358
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:56
#define TS
Definition: SUMOTime.h:52
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1520
void adaptToLeaders(const MSLeaderInfo &ahead, SUMOReal latOffset, const SUMOReal seen, DriveProcessItem *const lastLink, const MSLane *const lane, SUMOReal &v, SUMOReal &vLinkPass) const
Definition: MSVehicle.cpp:1730
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1126
A storage for edge travel times and efforts.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
Wants go to the left.
const Position geometryPositionAtOffset(SUMOReal offset, SUMOReal lateralOffset=0) const
Definition: MSLane.h:444
This is an uncontrolled, all-way stop link.
The action is due to the wish to be faster (tactical lc)
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:693
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:839
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:63
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
#define abs(a)
Definition: polyfonts.c:67
used by the sublane model
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:2726
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
std::string parkingarea
(Optional) parking area if one is assigned to the stop
SUMOReal myStopDist
distance to the next stop or -1 if there is none
Definition: MSVehicle.h:1526
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The simulated network and simulation perfomer.
Definition: MSNet.h:94
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false, bool check=false, bool addStops=true)
Replaces the current route by the given edges.
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
SUMOReal updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< SUMOReal > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:2308
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:825
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:159
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2881
#define SIMTIME
Definition: SUMOTime.h:70
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1659
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:380
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:41
SUMOTime getMinimalArrivalTime(SUMOReal dist, SUMOReal currentSpeed, SUMOReal arrivalSpeed) const
Computes the minimal time needed to cover a distance given the desired speed at arrival.
Definition: MSCFModel.cpp:234
The lane is given.
Right blinker lights are switched on.
Definition: MSVehicle.h:1042
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
MSChargingStation * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSVehicle.h:815
PositionVector reverse() const
reverse position vector
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:699
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:718
SUMOReal getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:407
SUMOReal getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:3384
The vehicles starts to stop.
Definition: MSNet.h:586
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
SUMOTime getMemorySize() const
Definition: MSVehicle.h:196
Needs to stay on the current lane.
SUMOReal slopeDegreeAtOffset(SUMOReal pos) const
Returns the slope at the given length.
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
std::vector< std::pair< SUMOTime, int > > myLaneTimeLine
The lane usage time line to apply.
Definition: MSVehicle.h:1323
The state of a link.
int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:3474
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:164
static SUMOReal computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed. ...
std::string busstop
(Optional) bus stop if one is assigned to the stop
SUMOReal influenceSpeed(SUMOTime currentTime, SUMOReal speed, SUMOReal vSafe, SUMOReal vMin, SUMOReal vMax)
Applies stored velocity information on the speed to use.
Definition: MSVehicle.cpp:282
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:140
static std::vector< MSTransportable * > myEmptyTransportableVector
Definition: MSVehicle.h:1490
const std::string & getID() const
Returns the id.
Definition: Named.h:66
A road/street connecting two junctions.
Definition: MSEdge.h:80
The vehicle changes lanes (micro only) XXX: What if a vehicle changes lanes and passes a junction sim...
MSLane * lane
The described lane.
Definition: MSVehicle.h:691
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:407
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:2446
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:580
Left blinker lights are switched on.
Definition: MSVehicle.h:1044
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1994
#define max(a, b)
Definition: polyfonts.c:65
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time, assuming that during...
Definition: MSCFModel.h:263
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
const MSLane & getLane() const
Returns the lane this stop is located at.
SUMOReal computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:820
SUMOReal implicitSpeedVTD(const MSVehicle *veh, SUMOReal oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:486
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:695
SUMOReal startPos
The stopping position start.
SUMOReal getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it&#39;s primary lane ...
Definition: MSVehicle.cpp:3644
blocked in all directions
The edge is a district edge.
Definition: MSEdge.h:99
std::pair< MSVehicle *const, SUMOReal > getLeaderOnConsecutive(SUMOReal dist, SUMOReal seen, SUMOReal speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:1833
The vehicle got a new route.
Definition: MSNet.h:580
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:707
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:807
vehicle want&#39;s to change to right lane
Definition: MSVehicle.h:228
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:55
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:102
void removeApproachingInformation(DriveItemVector &lfLinks) const
unregister approach from all upcoming links
Definition: MSVehicle.cpp:3651
The action is urgent (to be defined by lc-model)
Representation of a vehicle.
Definition: SUMOVehicle.h:67
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:811
render as a hatchback passenger vehicle ("Fliessheck")
Stores the waiting intervals over the previous seconds (memory is to be specified in ms...
Definition: MSVehicle.h:168
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3716
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Encapsulated SAX-Attributes.
virtual int addLeader(const MSVehicle *veh, bool beyond, SUMOReal latOffset=0)
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
SUMOReal getDistanceBetween(SUMOReal fromPos, SUMOReal toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:285
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:710
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:222
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:3236
std::string chargingStation
(Optional) charging station if one is assigned to the stop
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
TraciLaneChangePriority myTraciLaneChangePriority
flags for determining the priority of traci lane change requests
Definition: MSVehicle.h:1369
SUMOReal endPos
The stopping position end.
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:664
SUMOReal myAngle
the angle in radians (
Definition: MSVehicle.h:1523
A list of positions.
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:2899
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:732
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:839
SUMOReal getMinimalArrivalSpeed(SUMOReal dist, SUMOReal currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
Definition: MSCFModel.cpp:247
Position myCachedPosition
Definition: MSVehicle.h:1528
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:308
MSLane * getParallelLane(int offset) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:1594
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:807
SUMOReal getEndPos(const SUMOVehicle &veh) const
return halting position for upcoming stop;
Definition: MSVehicle.cpp:3995
SUMOReal myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1326
std::vector< SUMOReal > myFurtherLanesPosLat
Definition: MSVehicle.h:1506
const std::vector< MSLane * > & getShadowFurtherLanes() const
bool triggered
whether an arriving person lets the vehicle continue
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0)
Adds a stop.
Definition: MSVehicle.cpp:885
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1493
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
const int STOP_INDEX_END
SUMOTime myTimeLoss
the time loss due to writing with less than maximum speed
Definition: MSVehicle.h:1464
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3729
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
const std::vector< MSTransportable * > & getTransportables() const
Returns the list of transportables using this vehicle.
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1102
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:1120
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1338
SUMOReal getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
void adaptLeaveSpeed(const SUMOReal v)
Definition: MSVehicle.h:1571
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1470
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1262
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1518
bool loadAnyWaiting(MSEdge *edge, MSVehicle *vehicle, MSVehicle::Stop *stop)
load any applicable containers Loads any container that is waiting on that edge for the given vehicle...
const MSLeaderInfo & getLastVehicleInformation(const MSVehicle *ego, SUMOReal latOffset, SUMOReal minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:854
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
Influencer * myInfluencer
An instance of a velocity/lane influencing instance; built in "getInfluencer".
Definition: MSVehicle.h:1663
void resetRoutePosition(int index)
Definition: MSVehicle.cpp:676
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
Definition: MSVehicle.cpp:3458
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1487
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:3291
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
SUMOReal getSafeFollowSpeed(const std::pair< const MSVehicle *, SUMOReal > leaderInfo, const SUMOReal seen, const MSLane *const lane, SUMOReal distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:1801
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
virtual SUMOReal followSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal predMaxDecel) const =0
Computes the vehicle&#39;s follow speed (no dawdling)
SUMOReal getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:2425
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:821
bool isRoundabout() const
Definition: MSEdge.h:627
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:392
T MIN2(T a, T b)
Definition: StdDefs.h:64
SUMOReal myLastCoveredDist
Definition: MSVehicle.h:160
The link is a (hard) right direction.
The action is needed to follow the route (navigational lc)
#define POSITION_EPS
Definition: config.h:182
The brake lights are on.
Definition: MSVehicle.h:1048
SUMOReal getTimeGapOnLane() const
Returns the time gap in seconds to the leader of the vehicle on the same lane.
Definition: MSVehicle.cpp:3337
void addTransportable(MSTransportable *transportable)
Add a passenger.
A blue emergency light is on.
Definition: MSVehicle.h:1064
A structure representing the best lanes for continuing the current route starting at &#39;lane&#39;...
Definition: MSVehicle.h:689
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:4030
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:590
void stopStarted(const SUMOVehicle *veh, int numPersons, int numContainers)
Definition: MSStopOut.cpp:65
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:835
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:73
render as a van
int getSignals() const
Definition: MSVehicle.h:1314
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:201
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:399
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:341
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuous/sublane lane change. ...
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:3283
void getSubLanes(const MSVehicle *veh, SUMOReal latOffset, int &rightmost, int &leftmost) const
#define DEG2RAD(x)
Definition: GeomHelper.h:45
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
render as a passenger vehicle
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSVehicle.h:813
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1457
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1362
virtual SUMOReal freeSpeed(const MSVehicle *const veh, SUMOReal speed, SUMOReal seen, SUMOReal maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:206
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:99
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:254
void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector &lfLinks, SUMOReal &myStopDist) const
Definition: MSVehicle.cpp:1395
The link is a partial right direction.
int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
virtual SUMOReal getHeadwayTime() const
Get the driver&#39;s reaction time [s].
Definition: MSCFModel.h:220
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:103
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1108
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1360
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2893
int getRoutePosition() const
Definition: MSVehicle.cpp:670
void setVTDControlled(Position xyPos, MSLane *l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:428
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:91
bool containerTriggered
whether an arriving container lets the vehicle continue
State(SUMOReal pos, SUMOReal speed, SUMOReal posLat, SUMOReal backPos)
Constructor.
Definition: MSVehicle.cpp:150
int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:3468
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:703
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:3390
void stopEnded(const SUMOVehicle *veh, const MSVehicle::Stop &stop)
Definition: MSStopOut.cpp:95
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSVehicle.cpp:3448
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:93
void unregisterOneWaitingForPerson()
decreases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
Base class for objects which have an id.
Definition: Named.h:46
void registerOneWaitingForPerson()
increases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
void saveState(OutputDevice &out)
Saves the states of a vehicle.
Definition: MSVehicle.cpp:4010
SUMOVehicleShape getGuiShape() const
Get this vehicle type&#39;s shape.
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:1288
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
virtual SUMOReal moveHelper(MSVehicle *const veh, SUMOReal vPos) const
Applies interaction with stops and lane changing model influences.
Definition: MSCFModel.cpp:144
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:3366
SUMOReal getRightSideOnLane() const
Get the vehicle&#39;s lateral position on the lane:
Definition: MSVehicle.cpp:3557
std::string lane
The lane to stop at.
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1344
SUMOReal getLastFreePos(const SUMOVehicle &forVehicle) const
Returns the last free position on this stop.
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:697
Influencer()
Constructor.
Definition: MSVehicle.cpp:237
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
ConstMSEdgeVector myVTDRoute
Definition: MSVehicle.h:1352
void enter(SUMOVehicle *what, SUMOReal beg, SUMOReal end)
Called if a vehicle enters this stop.
void leaveLane(const MSMoveReminder::Notification reason)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:2832
virtual void drawOutsideNetwork(bool)
register vehicle for drawing while outside the network
Definition: MSVehicle.h:1457
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos, MSMoveReminder::Notification notification, SUMOReal posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:826
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
SUMOReal getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:193
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:3372
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:3354
bool boardAnyWaiting(MSEdge *edge, MSVehicle *vehicle, MSVehicle::Stop *stop)
board any applicable persons Boards any people who wait on that edge for the given vehicle and remove...
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:3219
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:3520
SUMOReal getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOReal getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane...
Definition: MSVehicle.cpp:3601
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2045
stop for vehicles
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1317
void registerOneWaitingForContainer()
increases the count of vehicles waiting for a container to allow recogniztion of container related de...
vehicle want&#39;s to change to left lane
Definition: MSVehicle.h:226
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:255
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:259
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3905
static MSDevice_Transportable * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into, const bool isContainer)
Build devices for the given vehicle, if needed.
Structure representing possible vehicle parameter.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:84
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:1270
LaneChangeMode mySublaneLC
changing to the prefered lateral alignment
Definition: MSVehicle.h:1366
static SUMOReal compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
virtual VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting...
Definition: MSCFModel.h:184
std::vector< std::pair< SUMOTime, SUMOReal > > mySpeedTimeLine
The velocity time line to apply.
Definition: MSVehicle.h:1320
SUMOReal getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:756
void setNoShadowPartialOccupator(MSLane *lane)
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:827
The link has yellow light, may pass.
void setVTDState(Position xyPos)
sets position outside the road network
Definition: MSVehicle.cpp:3942
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:199
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:697
The vehicle is blocked being overlapping.
SUMOReal getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle&#39;s lateral position on the edge of the given lane (or its current edge if lane == 0) ...
Definition: MSVehicle.cpp:3569
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1509
void resetChanged()
reset the flag whether a vehicle already moved to false
std::vector< MSLane * > bestContinuations
Definition: MSVehicle.h:709
SUMOReal interpolateLanePosToGeometryPos(SUMOReal lanePos) const
Definition: MSLane.h:438
Definition of vehicle stop (position and duration)
SUMOReal getBeginLanePosition() const
Returns the begin position of this stop.
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:299
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:833
SUMOReal myPreviousSpeed
the speed at the begin of the previous time step
Definition: MSVehicle.h:154
void onDepart()
Called when the vehicle is inserted into the network.
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:3378
void adaptToLeader(const std::pair< const MSVehicle *, SUMOReal > leaderInfo, const SUMOReal seen, DriveProcessItem *const lastLink, const MSLane *const lane, SUMOReal &v, SUMOReal &vLinkPass, SUMOReal distToCrossing=-1) const
Definition: MSVehicle.cpp:1765
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:823
static SUMOReal gLateralResolution
Definition: MSGlobals.h:89
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:831
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:1334
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:805
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:201
std::pair< MSVehicle *const, SUMOReal > getOppositeLeader(const MSVehicle *ego, SUMOReal dist, bool oppositeDir) const
Definition: MSLane.cpp:2582
bool addTraciBusOrContainerStop(const std::string &stopId, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string &errorMsg)
Definition: MSVehicle.cpp:3802
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:56
The arrival lane is given.
int containerNumber
The static number of containers in the vehicle when it departs.
const std::string & getID() const
Returns the name of the vehicle type.
The vehicle ends to stop.
Definition: MSNet.h:588
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:442
int myNumberReroutes
The number of reroutings.
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:2419
SUMOReal departPos
(optional) The position the vehicle shall depart from
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:791
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:417
SUMOReal myPos
the stored position
Definition: MSVehicle.h:140
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:1114
static MSStopOut * getInstance()
Definition: MSStopOut.h:68
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:2359
waitingIntervalList myWaitingIntervals
Definition: MSVehicle.h:212
std::vector< DriveProcessItem > DriveItemVector
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1584
void setSignals(int signals)
Definition: MSVehicle.h:1310
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:427
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:819
The action is due to a TraCI request.
SUMOReal distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:250
SUMOReal getOppositePos(SUMOReal pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2551
void move2side(SUMOReal amount)
move position vector to side using certain ammount
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:799
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:230
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
SUMOReal myPosLat
the stored lateral position
Definition: MSVehicle.h:146
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
The vehicle needs another parking area.
SUMOReal getMinimalArrivalSpeedEuler(SUMOReal dist, SUMOReal currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update...
Definition: MSCFModel.cpp:254
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:208
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1103
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:63
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1095
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSCFModel.cpp:468
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:3396
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1489
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:3275
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:158
SUMOReal myBackPos
the stored back position
Definition: MSVehicle.h:151
int getSpeedMode() const
return the current speed mode
Definition: MSVehicle.cpp:272
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:178
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:266
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:567
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:1545
No information given; use default.
SUMOTime getDeparture() const
Returns this vehicle&#39;s real departure time.
MSParkingArea * getNextParkingArea()
get the current parking area stop
Definition: MSVehicle.cpp:1088
The link has yellow light, has to brake anyway.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:109
SUMOReal getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:458
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:510
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1329
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:488
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:3929
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:2657
The edge is an internal edge.
Definition: MSEdge.h:97
public emergency vehicles
render as a wagon passenger vehicle ("Combi")
void removeTransportable(MSTransportable *transportable)
Remove a passenger (TraCI)
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:86
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane&#39;s move reminders.
Definition: MSLane.h:228
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:315
SUMOReal getBackPositionOnLane() const
Get the vehicle&#39;s position relative to its current lane.
Definition: MSVehicle.h:399
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
bool addTraciStop(MSLane *const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, std::string &errorMsg)
Definition: MSVehicle.cpp:3766
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:817
void writeParams(OutputDevice &out) const
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:809
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:685
std::vector< MSDevice * > myDevices
The devices this vehicle has.
void adaptLaneEntering2MoveReminder(const MSLane &enteredLane)
Adapts the vehicle&#39;s entering of a new lane.
Definition: MSVehicle.cpp:736
Back-at-zero position.
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1358
The link has red light (must brake) but indicates upcoming green.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:447
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:188
Interface for lane-change models.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
int getBestLaneOffset() const
Definition: MSVehicle.cpp:3265
SUMOReal posLat() const
Lateral Position of this state (m relative to the centerline of the lane).
Definition: MSVehicle.h:123
SUMOReal angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
Definition: Position.h:260
bool myConsiderSafeVelocity
Whether the safe velocity shall be regarded.
Definition: MSVehicle.h:1332
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
SUMOTime myDeparture
The real departure time.
void removeTransportable(MSTransportable *t)
removes a person or container
Definition: MSVehicle.cpp:3438
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
Definition: MSVehicle.h:1499
static const SUMOTime NOT_YET_DEPARTED
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:829
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:278
The vehicle is being teleported.
SUMOReal getRightSideOnEdge() const
Definition: MSLane.h:897
const std::string & getID() const
Returns the name of the vehicle.
int size() const
Return the number of passengers / containers.
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
const Position getBackPosition() const
Definition: MSVehicle.cpp:861
SUMOReal getDeltaPos(SUMOReal accel)
calculates the distance covered in the next integration step given an acceleration and assuming the c...
Definition: MSVehicle.cpp:1821