SUMO - Simulation of Urban MObility
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
17 // Representation of a vehicle in the micro simulation
18 /****************************************************************************/
19 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
20 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
21 /****************************************************************************/
22 //
23 // This file is part of SUMO.
24 // SUMO is free software: you can redistribute it and/or modify
25 // it under the terms of the GNU General Public License as published by
26 // the Free Software Foundation, either version 3 of the License, or
27 // (at your option) any later version.
28 //
29 /****************************************************************************/
30 
31 // ===========================================================================
32 // included modules
33 // ===========================================================================
34 #ifdef _MSC_VER
35 #include <windows_config.h>
36 #else
37 #include <config.h>
38 #endif
39 
40 #include <iostream>
41 #include <cassert>
42 #include <cmath>
43 #include <cstdlib>
44 #include <algorithm>
45 #include <map>
46 #include <utils/common/ToString.h>
53 #include <utils/common/StdDefs.h>
54 #include <utils/geom/GeomHelper.h>
61 #include "MSVehicleControl.h"
62 #include "MSVehicleTransfer.h"
63 #include "MSGlobals.h"
64 #include "MSStoppingPlace.h"
65 #include "MSEdgeWeightsStorage.h"
66 #include "MSMoveReminder.h"
67 #include "MSTransportableControl.h"
68 #include "MSLane.h"
69 #include "MSJunction.h"
70 #include "MSVehicle.h"
71 #include "MSEdge.h"
72 #include "MSVehicleType.h"
73 #include "MSNet.h"
74 #include "MSRoute.h"
75 #include "MSLinkCont.h"
76 #include "MSLeaderInfo.h"
77 
78 #ifdef CHECK_MEMORY_LEAKS
79 #include <foreign/nvwa/debug_new.h>
80 #endif // CHECK_MEMORY_LEAKS
81 
82 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
83 //#define DEBUG_VEHICLE_GUI_SELECTION 1
84 
85 //#define DEBUG_PLAN_MOVE
86 //#define DEBUG_EXEC_MOVE
87 //#define DEBUG_FURTHER
88 //#define DEBUG_BESTLANES
89 #define DEBUG_COND (getID() == "disabled")
90 
91 #define STOPPING_PLACE_OFFSET 0.5
92 
93 #define CRLL_LOOK_AHEAD 5
94 
95 // @todo Calibrate with real-world values / make configurable
96 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
97 
98 // ===========================================================================
99 // static value definitions
100 // ===========================================================================
101 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
102 std::vector<MSTransportable*> MSVehicle::myEmptyTransportableVector;
103 
104 
105 // ===========================================================================
106 // method definitions
107 // ===========================================================================
108 /* -------------------------------------------------------------------------
109  * methods of MSVehicle::State
110  * ----------------------------------------------------------------------- */
112  myPos = state.myPos;
113  mySpeed = state.mySpeed;
114  myPosLat = state.myPosLat;
115  myBackPos = state.myBackPos;
116 }
117 
118 
121  myPos = state.myPos;
122  mySpeed = state.mySpeed;
123  myPosLat = state.myPosLat;
124  myBackPos = state.myBackPos;
125  return *this;
126 }
127 
128 
129 bool
131  return (myPos != state.myPos ||
132  mySpeed != state.mySpeed ||
133  myPosLat != state.myPosLat ||
134  myBackPos != state.myBackPos);
135 }
136 
137 
139  myPos(pos), mySpeed(speed), myPosLat(posLat), myBackPos(backPos) {}
140 
141 
142 
143 /* -------------------------------------------------------------------------
144  * methods of MSVehicle::WaitingTimeCollector
145  * ----------------------------------------------------------------------- */
146 
148 
150 
155  return *this;
156 }
157 
160  myWaitingIntervals.clear();
161  passTime(t, true);
162  return *this;
163 }
164 
165 SUMOTime
167  assert(memorySpan <= myMemorySize);
168  if (memorySpan == -1) {
169  memorySpan = myMemorySize;
170  }
171  SUMOTime totalWaitingTime = 0;
172  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
173  if (i->second >= memorySpan) {
174  if (i->first >= memorySpan) {
175  break;
176  } else {
177  totalWaitingTime += memorySpan - i->first;
178  }
179  } else {
180  totalWaitingTime += i->second - i->first;
181  }
182  }
183  return totalWaitingTime;
184 }
185 
186 void
188  waitingIntervalList::iterator i = myWaitingIntervals.begin();
189  waitingIntervalList::iterator end = myWaitingIntervals.end();
190  bool startNewInterval = i == end || (i->first != 0);
191  while (i != end) {
192  i->first += dt;
193  if (i->first >= myMemorySize) {
194  break;
195  }
196  i->second += dt;
197  i++;
198  }
199 
200  // remove intervals beyond memorySize
201  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
202  while (d > 0) {
203  myWaitingIntervals.pop_back();
204  d--;
205  }
206 
207  if (!waiting) {
208  return;
209  } else if (!startNewInterval) {
210  myWaitingIntervals.begin()->first = 0;
211  } else {
212  myWaitingIntervals.push_front(std::make_pair(0, dt));
213  }
214  return;
215 }
216 
217 
218 
219 
220 
221 /* -------------------------------------------------------------------------
222  * methods of MSVehicle::Influencer
223  * ----------------------------------------------------------------------- */
224 #ifndef NO_TRACI
226  mySpeedAdaptationStarted(true),
227  myConsiderSafeVelocity(true),
228  myConsiderMaxAcceleration(true),
229  myConsiderMaxDeceleration(true),
230  myRespectJunctionPriority(true),
231  myEmergencyBrakeRedLight(true),
232  myLastVTDAccess(-TIME2STEPS(20)),
233  myStrategicLC(LC_NOCONFLICT),
234  myCooperativeLC(LC_NOCONFLICT),
235  mySpeedGainLC(LC_NOCONFLICT),
236  myRightDriveLC(LC_NOCONFLICT),
237  mySublaneLC(LC_NOCONFLICT),
238  myTraciLaneChangePriority(LCP_URGENT) {
239 }
240 
241 
243 
244 
245 void
246 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
248  mySpeedTimeLine = speedTimeLine;
249 }
250 
251 
252 void
253 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine) {
254  myLaneTimeLine = laneTimeLine;
255 }
256 
257 
258 int
260  return (1 * myConsiderSafeVelocity +
265 }
266 
267 
268 SUMOReal
270  // keep original speed
271  myOriginalSpeed = speed;
272  // remove leading commands which are no longer valid
273  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
274  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
275  }
276  // do nothing if the time line does not apply for the current time
277  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
278  return speed;
279  }
280  // compute and set new speed
282  mySpeedTimeLine[0].second = speed;
284  }
285  currentTime += DELTA_T;
286  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
287  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
289  speed = MIN2(speed, vSafe);
290  }
292  speed = MIN2(speed, vMax);
293  }
295  speed = MAX2(speed, vMin);
296  }
297  return speed;
298 }
299 
300 
301 int
302 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state) {
303  // remove leading commands which are no longer valid
304  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
305  myLaneTimeLine.erase(myLaneTimeLine.begin());
306  }
307  ChangeRequest changeRequest = REQUEST_NONE;
308  // do nothing if the time line does not apply for the current time
309  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
310  const int destinationLaneIndex = myLaneTimeLine[1].second;
311  if (destinationLaneIndex < (int)currentEdge.getLanes().size()) {
312  if (currentLaneIndex > destinationLaneIndex) {
313  changeRequest = REQUEST_RIGHT;
314  } else if (currentLaneIndex < destinationLaneIndex) {
315  changeRequest = REQUEST_LEFT;
316  } else {
317  changeRequest = REQUEST_HOLD;
318  }
319  }
320  }
321  // check whether the current reason shall be canceled / overridden
322  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
323  // flags for the current reason
324  LaneChangeMode mode = LC_NEVER;
325  if ((state & LCA_STRATEGIC) != 0) {
326  mode = myStrategicLC;
327  } else if ((state & LCA_COOPERATIVE) != 0) {
328  mode = myCooperativeLC;
329  } else if ((state & LCA_SPEEDGAIN) != 0) {
330  mode = mySpeedGainLC;
331  } else if ((state & LCA_KEEPRIGHT) != 0) {
332  mode = myRightDriveLC;
333  } else if ((state & LCA_SUBLANE) != 0) {
334  mode = mySublaneLC;
335  } else if ((state & LCA_TRACI) != 0) {
336  mode = LC_NEVER;
337  } else {
338  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
339  }
340  if (mode == LC_NEVER) {
341  // cancel all lcModel requests
342  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
343  state &= ~LCA_URGENT;
344  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
345  if (
346  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
347  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
348  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
349  // cancel conflicting lcModel request
350  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
351  state &= ~LCA_URGENT;
352  }
353  } else if (mode == LC_ALWAYS) {
354  // ignore any TraCI requests
355  return state;
356  }
357  }
358  // apply traci requests
359  if (changeRequest == REQUEST_NONE) {
360  return state;
361  } else {
362  state |= LCA_TRACI;
363  // security checks
365  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
366  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
367  }
368  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
369  state |= LCA_URGENT;
370  }
371  switch (changeRequest) {
372  case REQUEST_HOLD:
373  return state | LCA_STAY;
374  case REQUEST_LEFT:
375  return state | LCA_LEFT;
376  case REQUEST_RIGHT:
377  return state | LCA_RIGHT;
378  default:
379  throw ProcessError("should not happen");
380  }
381  }
382 }
383 
384 
385 SUMOReal
387  assert(myLaneTimeLine.size() >= 2);
388  assert(currentTime >= myLaneTimeLine[0].first);
389  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
390 }
391 
392 
393 void
395  myConsiderSafeVelocity = value;
396 }
397 
398 
399 void
402 }
403 
404 
405 void
408 }
409 
410 
411 void
414 }
415 
416 
417 void
419  myEmergencyBrakeRedLight = value;
420 }
421 
422 
423 void
425  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
426  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
427  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
428  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
429  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
430  mySublaneLC = (LaneChangeMode)((value & (1024 + 2048)) >> 10);
431 }
432 
433 
434 void
435 MSVehicle::Influencer::setVTDControlled(Position xyPos, MSLane* l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
436  myVTDXYPos = xyPos;
437  myVTDLane = l;
438  myVTDPos = pos;
439  myVTDPosLat = posLat;
440  myVTDAngle = angle;
441  myVTDEdgeOffset = edgeOffset;
442  myVTDRoute = route;
443  myLastVTDAccess = t;
444 }
445 
446 
447 bool
450 }
451 
452 
453 bool
455  return myLastVTDAccess >= t - TIME2STEPS(10);
456 }
457 
458 void
460  const bool wasOnRoad = v->isOnRoad();
461  if (v->isOnRoad()) {
464  }
465  if (myVTDRoute.size() != 0) {
466  v->replaceRouteEdges(myVTDRoute, true);
467  }
469  if (myVTDLane != 0 && myVTDPos > myVTDLane->getLength()) {
471  }
472  if (myVTDLane != 0 && fabs(myVTDPosLat) < 0.5 * (myVTDLane->getWidth() + v->getVehicleType().getWidth())) {
474  v->updateBestLanes();
475  if (!wasOnRoad) {
476  v->drawOutsideNetwork(false);
477  }
478  } else {
480  v->drawOutsideNetwork(true);
481  }
482  // inverse of GeomHelper::naviDegree
483  v->setAngle(M_PI / 2. - DEG2RAD(myVTDAngle));
484 }
485 
486 
487 SUMOReal
489  SUMOReal dist = 0;
490  if (myVTDLane == 0) {
491  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
492  } else {
494  }
495  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
496  return oldSpeed;
497  } else {
498  return DIST2SPEED(dist);
499  }
500 }
501 
502 SUMOReal
504  SUMOReal dist = 0;
505  if (myVTDLane == 0) {
506  dist = veh->getPosition().distanceTo2D(myVTDXYPos);
507  } else {
509  }
510  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
511  return 0;
512  } else {
513  return dist;
514  }
515 }
516 
517 #endif
518 
519 
520 /* -------------------------------------------------------------------------
521  * MSVehicle-methods
522  * ----------------------------------------------------------------------- */
524  const MSVehicleType* type, const SUMOReal speedFactor) :
525  MSBaseVehicle(pars, route, type, speedFactor),
526  myWaitingTime(0),
528  myState(0, 0, 0, 0), //
529  myLane(0),
532  myPersonDevice(0),
534  myAcceleration(0),
535  mySignals(0),
536  myAmOnNet(false),
539  myHaveToWaitOnNextLink(false),
540  myAngle(0),
541  myStopDist(std::numeric_limits<SUMOReal>::max()),
542  myCachedPosition(Position::INVALID),
543  myEdgeWeights(0)
544 #ifndef NO_TRACI
545  , myInfluencer(0)
546 #endif
547 {
548  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
549  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
550  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
551  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
552  }
553  } else {
554  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
555  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
556  }
557  }
558  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
559  throw ProcessError("Departure speed for vehicle '" + pars->id +
560  "' is too high for the vehicle type '" + type->getID() + "'.");
561  }
562  }
565 }
566 
567 
569  delete myEdgeWeights;
570  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
571  (*i)->resetPartialOccupation(this);
572  }
575  // still needed when calling resetPartialOccupation (getShadowLane) and when removing
576  // approach information from parallel links
577  delete myLaneChangeModel;
578  myFurtherLanes.clear();
579  myFurtherLanesPosLat.clear();
580  //
581  if (myType->amVehicleSpecific()) {
582  delete myType;
583  }
584 #ifndef NO_TRACI
585  delete myInfluencer;
586 #endif
587 }
588 
589 
590 void
595  leaveLane(reason);
596 }
597 
598 
599 // ------------ interaction with the route
600 bool
602  return (myCurrEdge == myRoute->end() - 1
603  && (myStops.empty() || myStops.front().edge != myCurrEdge)
605  && !isRemoteControlled());
606 }
607 
608 
609 bool
610 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
611  const ConstMSEdgeVector& edges = newRoute->getEdges();
612  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
613  if (!onInit && !newRoute->contains(*myCurrEdge)) {
614  return false;
615  }
616 
617  // rebuild in-vehicle route information
618  if (onInit) {
619  myCurrEdge = newRoute->begin();
620  } else {
621  MSRouteIterator newCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);;
622  if (myLane->getEdge().isInternal() && (
623  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(myLane->getOutgoingLanes()[0]->getEdge()))) {
624  return false;
625  }
626  myCurrEdge = newCurrEdge;
627  }
628  // check whether the old route may be deleted (is not used by anyone else)
629  newRoute->addReference();
630  myRoute->release();
631  // assign new route
632  myRoute = newRoute;
635  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
636  // update arrival definition
638  // save information that the vehicle was rerouted
641  // recheck old stops
642  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
643  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
644  iter = myStops.erase(iter);
645  } else {
646  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
647  ++iter;
648  }
649  }
650  // add new stops
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  return true;
659 }
660 
661 
662 bool
663 MSVehicle::willPass(const MSEdge* const edge) const {
664  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
665 }
666 
667 
668 int
670  return (int) std::distance(myRoute->begin(), myCurrEdge);
671 }
672 
673 
674 void
676  myCurrEdge = myRoute->begin() + index;
677  // !!! hack
678  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
679 }
680 
681 
682 
685  return _getWeightsStorage();
686 }
687 
688 
691  return _getWeightsStorage();
692 }
693 
694 
697  if (myEdgeWeights == 0) {
699  }
700  return *myEdgeWeights;
701 }
702 
703 
704 // ------------ Interaction with move reminders
705 void
707  // This erasure-idiom works for all stl-sequence-containers
708  // See Meyers: Effective STL, Item 9
709  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
710  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
711 #ifdef _DEBUG
712  if (myTraceMoveReminders) {
713  traceMoveReminder("notifyMove", rem->first, rem->second, false);
714  }
715 #endif
716  rem = myMoveReminders.erase(rem);
717  } else {
718 #ifdef _DEBUG
719  if (myTraceMoveReminders) {
720  traceMoveReminder("notifyMove", rem->first, rem->second, true);
721  }
722 #endif
723  ++rem;
724  }
725  }
726 }
727 
728 
729 void
731  // save the old work reminders, patching the position information
732  // add the information about the new offset to the old lane reminders
733  const SUMOReal oldLaneLength = myLane->getLength();
734  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
735  rem->second += oldLaneLength;
736 #ifdef _DEBUG
737  if (myTraceMoveReminders) {
738  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
739  }
740 #endif
741  }
742  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
743  addReminder(*rem);
744  }
745 }
746 
747 
748 // ------------ Other getter methods
749 SUMOReal
751  if (myLane == 0) {
752  return 0;
753  }
754  const SUMOReal lp = getPositionOnLane();
756  return myLane->getShape().slopeDegreeAtOffset(gp);
757 }
758 
759 
760 Position
761 MSVehicle::getPosition(const SUMOReal offset) const {
762  if (myLane == 0) {
763  if (isRemoteControlled()) {
764  return myCachedPosition;
765  } else {
766  return Position::INVALID;
767  }
768  }
769  if (isParking()) {
770  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
773  }
774  const bool changingLanes = getLaneChangeModel().isChangingLanes();
775  if (offset == 0. && !changingLanes) {
778  }
779  return myCachedPosition;
780  }
782  return result;
783 }
784 
785 
786 const MSEdge*
788  // too close to the next junction, so avoid an emergency brake here
789  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
791  return *(myCurrEdge + 1);
792  }
793 #ifdef HAVE_INTERNAL_LANES
794  if (myLane != 0) {
795  return myLane->getInternalFollower();
796  }
797 #endif
798  return *myCurrEdge;
799 }
800 
801 void
803  myAngle = angle;
804 }
805 
806 
807 SUMOReal
809  Position p1;
810  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
811  if (isParking()) {
813  }
815  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
817  } else {
818  p1 = getPosition();
819  }
820  const Position p2 = getBackPosition();
821  SUMOReal result = (p1 != p2 ? p2.angleTo2D(p1) :
824  result += DEG2RAD(getLaneChangeModel().getAngleOffset());
825  }
826 #ifdef DEBUG_FURTHER
827  if (DEBUG_COND) {
828  std::cout << SIMTIME << " computeAngle veh=" << getID() << " p1=" << p1 << " p2=" << p2 << " angle=" << result << "\n";
829  }
830 #endif
831  return result;
832 }
833 
834 
835 const Position
837  const SUMOReal posLat = -myState.myPosLat; // @todo get rid of the '-'
838  if (myState.myPos >= myType->getLength()) {
839  // vehicle is fully on the new lane
841  } else {
843  // special case where the target lane has no predecessor
844  return myLane->geometryPositionAtOffset(0, posLat);
845  } else {
846 #ifdef DEBUG_FURTHER
847  if (DEBUG_COND) {
848  std::cout << " getBackPosition veh=" << getID() << " myLane=" << myLane->getID() << " further=" << toString(myFurtherLanes) << " myFurtherLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
849  }
850 #endif
851  return myFurtherLanes.size() > 0 && !getLaneChangeModel().isChangingLanes()
852  ? myFurtherLanes.back()->geometryPositionAtOffset(getBackPositionOnLane(myFurtherLanes.back()), -myFurtherLanesPosLat.back())
853  : myLane->geometryPositionAtOffset(0, posLat);
854  }
855  }
856 }
857 
858 // ------------
859 bool
860 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
861  Stop stop;
862  stop.lane = MSLane::dictionary(stopPar.lane);
864  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
865  return false;
866  }
867  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
869  stop.startPos = stopPar.startPos;
870  stop.endPos = stopPar.endPos;
871  stop.duration = stopPar.duration;
872  stop.until = stopPar.until;
873  stop.timeToBoardNextPerson = 0;
874  stop.timeToLoadNextContainer = 0;
875  stop.awaitedPersons = stopPar.awaitedPersons;
876  stop.awaitedContainers = stopPar.awaitedContainers;
877  if (stop.until != -1) {
878  stop.until += untilOffset;
879  }
880  stop.triggered = stopPar.triggered;
881  stop.containerTriggered = stopPar.containerTriggered;
882  stop.parking = stopPar.parking;
883  stop.reached = false;
884  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
885  if (stop.busstop != 0) {
886  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
887  } else {
888  errorMsg = "Stop";
889  }
890  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
891  return false;
892  }
893  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
894  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
895  }
896  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
897  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
898  }
899  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
900  MSRouteIterator prevStopEdge = myCurrEdge;
901  SUMOReal prevStopPos = myState.myPos;
902  // where to insert the stop
903  std::list<Stop>::iterator iter = myStops.begin();
904  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
905  if (myStops.size() > 0) {
906  prevStopEdge = myStops.back().edge;
907  prevStopPos = myStops.back().endPos;
908  iter = myStops.end();
909  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
910  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
911  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
912  }
913  }
914  } else {
915  if (stopPar.index == STOP_INDEX_FIT) {
916  while (iter != myStops.end() && (iter->edge < stop.edge ||
917  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
918  prevStopEdge = iter->edge;
919  prevStopPos = iter->endPos;
920  ++iter;
921  }
922  } else {
923  int index = stopPar.index;
924  while (index > 0) {
925  prevStopEdge = iter->edge;
926  prevStopPos = iter->endPos;
927  ++iter;
928  --index;
929  }
930  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
931  }
932  }
933  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
934  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
935  if (stop.busstop != 0) {
936  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
937  } else {
938  errorMsg = "Stop";
939  }
940  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
941  return false;
942  }
943  // David.C:
944  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
945  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
946  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
947  return false;
948  }
949  if (!hasDeparted() && myCurrEdge == stop.edge) {
950  SUMOReal pos = -1;
952  pos = myParameter->departPos;
953  if (pos < 0.) {
954  pos += (*myCurrEdge)->getLength();
955  }
956  }
958  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
959  }
960  if (pos > stop.endPos) {
961  if (stop.busstop != 0) {
962  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
963  } else {
964  errorMsg = "Stop";
965  }
966  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
967  return false;
968  }
969  }
970  if (iter != myStops.begin()) {
971  std::list<Stop>::iterator iter2 = iter;
972  iter2--;
973  if (stop.until >= 0 && iter2->until > stop.until) {
974  if (stop.busstop != 0) {
975  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
976  } else {
977  errorMsg = "Stop";
978  }
979  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
980  }
981  }
982  myStops.insert(iter, stop);
983  return true;
984 }
985 
986 
987 bool
989  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
990 }
991 
992 
993 bool
995  return isStopped() && myStops.begin()->parking;
996 }
997 
998 
999 bool
1001  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
1002 }
1003 
1004 
1005 bool
1007  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
1008 }
1009 
1010 
1011 SUMOReal
1013  if (myStops.empty()) {
1014  // no stops; pass
1015  return currentVelocity;
1016  }
1017  Stop& stop = myStops.front();
1018  if (stop.reached) {
1019  // ok, we have already reached the next stop
1020  // any waiting persons may board now
1021  MSNet* const net = MSNet::getInstance();
1022  bool boarded = net->hasPersons() && net->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
1023  boarded &= stop.awaitedPersons.size() == 0;
1024  // load containers
1025  bool loaded = net->hasContainers() && net->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
1026  loaded &= stop.awaitedContainers.size() == 0;
1027  if (boarded) {
1028  if (stop.busstop != 0) {
1029  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
1030  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
1031  stop.busstop->removeTransportable(*i);
1032  }
1033  }
1034  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
1035  stop.triggered = false;
1039  }
1040  }
1041  if (loaded) {
1042  if (stop.containerstop != 0) {
1043  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
1044  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
1046  }
1047  }
1048  // the triggering condition has been fulfilled
1049  stop.containerTriggered = false;
1053  }
1054  }
1055  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
1057  } else {
1059  if (getVehicleType().getPersonCapacity() == getPersonNumber()) {
1060  WRITE_WARNING("Vehicle '" + getID() + "' ignores triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1061  stop.triggered = false;
1062  }
1063  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1066  }
1068  if (getVehicleType().getContainerCapacity() == getContainerNumber()) {
1069  WRITE_WARNING("Vehicle '" + getID() + "' ignores container triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1070  stop.containerTriggered = false;
1071  }
1072  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1075  }
1076  // we have to wait some more time
1077  stop.duration -= DELTA_T;
1078  return 0;
1079  }
1080  } else {
1081  // is the next stop on the current lane?
1082  if (stop.edge == myCurrEdge) {
1083  // get the stopping position
1084  SUMOReal endPos = stop.endPos;
1085  bool useStoppingPlace = false;
1086  bool fitsOnStoppingPlace = true;
1087  if (stop.busstop != 0) {
1088  useStoppingPlace = true;
1089  // on bus stops, we have to wait for free place if they are in use...
1090  endPos = stop.busstop->getLastFreePos(*this);
1091  // at least half the bus has to fit on non-empty bus stops
1092  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
1093  fitsOnStoppingPlace = false;
1094  }
1095  }
1096  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
1097  if (stop.containerstop != 0) {
1098  useStoppingPlace = true;
1099  // on container stops, we have to wait for free place if they are in use...
1100  endPos = stop.containerstop->getLastFreePos(*this);
1101  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
1102  fitsOnStoppingPlace = false;
1103  }
1104  }
1105  const SUMOReal reachedThreshold = (useStoppingPlace ? endPos - STOPPING_PLACE_OFFSET : stop.startPos) - NUMERICAL_EPS;
1106  if (myState.pos() >= reachedThreshold && fitsOnStoppingPlace && currentVelocity <= SUMO_const_haltingSpeed && myLane == stop.lane) {
1107  // ok, we may stop (have reached the stop)
1108  stop.reached = true;
1109  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
1111  // compute stopping time
1112  if (stop.until >= 0) {
1113  if (stop.duration == -1) {
1115  } else {
1117  }
1118  }
1119  if (stop.busstop != 0) {
1120  // let the bus stop know the vehicle
1121  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
1122  }
1123  if (stop.containerstop != 0) {
1124  // let the container stop know the vehicle
1126  }
1127  }
1128  // decelerate
1129  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos() + NUMERICAL_EPS);
1130  }
1131  }
1132  return currentVelocity;
1133 }
1134 
1135 
1136 const ConstMSEdgeVector
1138  ConstMSEdgeVector result;
1139  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
1140  result.push_back(*iter->edge);
1141  }
1142  return result;
1143 }
1144 
1145 
1146 void
1147 MSVehicle::planMove(const SUMOTime t, const MSLeaderInfo& ahead, const SUMOReal lengthsInFront) {
1148 
1149 #ifdef DEBUG_PLAN_MOVE
1150  if (DEBUG_COND) {
1151  std::cout
1152  << "\n\n"
1153  << STEPS2TIME(t)
1154  << " veh=" << getID()
1155  << " lane=" << myLane->getID()
1156  << " pos=" << getPositionOnLane()
1157  << " posLat=" << getLateralPositionOnLane()
1158  << " speed=" << getSpeed()
1159  << "\n";
1160  }
1161 #endif
1163 #ifdef DEBUG_PLAN_MOVE
1164  if (DEBUG_COND) {
1165  DriveItemVector::iterator i;
1166  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1167  std::cout
1168  << " vPass=" << (*i).myVLinkPass
1169  << " vWait=" << (*i).myVLinkWait
1170  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1171  << " request=" << (*i).mySetRequest
1172  << "\n";
1173  }
1174  }
1175 #endif
1176  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
1177 #ifdef DEBUG_PLAN_MOVE
1178  if (DEBUG_COND) {
1179  std::cout << " after checkRewindLinkLanes\n";
1180  DriveItemVector::iterator i;
1181  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1182  std::cout
1183  << " vPass=" << (*i).myVLinkPass
1184  << " vWait=" << (*i).myVLinkWait
1185  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
1186  << " request=" << (*i).mySetRequest
1187  << " atime=" << (*i).myArrivalTime
1188  << " atimeB=" << (*i).myArrivalTimeBraking
1189  << "\n";
1190  }
1191  }
1192 #endif
1194 }
1195 
1196 
1197 void
1199 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1200  if (gDebugSelectedVehicle == getID()) {
1201  int bla = 0;
1202  }
1203 #endif
1204  // remove information about approaching links, will be reset later in this step
1206  lfLinks.clear();
1207  myStopDist = std::numeric_limits<SUMOReal>::max();
1208  //
1209  const MSCFModel& cfModel = getCarFollowModel();
1210  const SUMOReal vehicleLength = getVehicleType().getLength();
1211  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1212  const bool opposite = getLaneChangeModel().isOpposite();
1213  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
1214  // vBeg is the initial maximum velocity of this vehicle in this step
1215  SUMOReal v = MIN2(maxV, laneMaxV);
1216 #ifndef NO_TRACI
1217  if (myInfluencer != 0) {
1218  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1219  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1220  }
1221 #endif
1222 
1223  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1224  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1225 #ifdef DEBUG_PLAN_MOVE
1226  if (DEBUG_COND) {
1227  std::cout << " bestLaneConts=" << toString(bestLaneConts) << "\n";
1228  }
1229 #endif
1230  assert(bestLaneConts.size() > 0);
1231 #ifdef HAVE_INTERNAL_LANES
1232  bool hadNonInternal = false;
1233 #else
1234  bool hadNonInternal = true;
1235 #endif
1236  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"
1237  SUMOReal seenNonInternal = 0;
1238  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1239  int view = 0;
1240  DriveProcessItem* lastLink = 0;
1241  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1242  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1243  const MSLane* lane = opposite ? myLane->getOpposite() : myLane;
1244  const MSLane* leaderLane = myLane;
1245  while (true) {
1246  // check leader on lane
1247  // leader is given for the first edge only
1248  adaptToLeaders(ahead, 0, seen, lastLink, leaderLane, v, vLinkPass);
1249  // XXX efficiently adapt to shadow leaders using neighAhead by iteration over the whole edge in parallel (lanechanger-style)
1250  if (getLaneChangeModel().getShadowLane() != 0) {
1251  // also slow down for leaders on the shadowLane relative to the current lane
1252  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1253  if (shadowLane != 0) {
1255  adaptToLeaders(shadowLane->getLastVehicleInformation(this, latOffset, lane->getLength() - seen),
1256  latOffset,
1257  seen, lastLink, shadowLane, v, vLinkPass);
1258  }
1259  }
1260 
1261  // process stops
1262  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge() && !myStops.begin()->reached) {
1263  // we are approaching a stop on the edge; must not drive further
1264  const Stop& stop = *myStops.begin();
1265  const SUMOReal endPos = (stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this)) + NUMERICAL_EPS;
1266  myStopDist = seen + endPos - lane->getLength();
1267  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), myStopDist);
1268  if (lastLink != 0) {
1269  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1270  }
1271  v = MIN2(v, stopSpeed);
1272  lfLinks.push_back(DriveProcessItem(v, myStopDist));
1273  break;
1274  }
1275 
1276  // move to next lane
1277  // get the next link used
1278  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1279  // check whether the vehicle is on its final edge
1280  if (myCurrEdge + view + 1 == myRoute->end()) {
1282  myParameter->arrivalSpeed : laneMaxV);
1283  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1284  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1285  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1286  v = MIN2(v, va);
1287  if (lastLink != 0) {
1288  lastLink->adaptLeaveSpeed(va);
1289  }
1290  lfLinks.push_back(DriveProcessItem(v, seen));
1291  break;
1292  }
1293  // check whether the lane or the shadowLane is a dead end
1294  if (lane->isLinkEnd(link) ||
1296  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1297  if (lastLink != 0) {
1298  lastLink->adaptLeaveSpeed(va);
1299  }
1300  v = MIN2(va, v);
1301  lfLinks.push_back(DriveProcessItem(v, seen));
1302  break;
1303  }
1304  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1305  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1306  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1307  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1308  // We distinguish 3 cases when determining the point at which a vehicle stops:
1309  // - links that require stopping: here the vehicle needs to stop close to the stop line
1310  // to ensure it gets onto the junction in the next step. Othwise the vehicle would 'forget'
1311  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1312  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1313  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1314  // to minimize the time window for passing the junction. If the
1315  // vehicle 'decides' to accelerate and cannot enter the junction in
1316  // the next step, new foes may appear and cause a collision (see #1096)
1317  // - major links: stopping point is irrelevant
1318  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1319  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1320  // check whether we need to slow down in order to finish a continuous lane change
1321  if (getLaneChangeModel().isChangingLanes()) {
1322  if ( // slow down to finish lane change before a turn lane
1323  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1324  // slow down to finish lane change before the shadow lane ends
1325  (getLaneChangeModel().getShadowLane() != 0 &&
1326  (*link)->getViaLaneOrLane()->getParallelLane(getLaneChangeModel().getShadowDirection()) == 0)) {
1327  // XXX maybe this is too harsh. Vehicles could cut some corners here
1328  const SUMOReal timeRemaining = STEPS2TIME(getLaneChangeModel().remainingTime());
1329  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1330 #ifdef DEBUG_PLAN_MOVE
1331  if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " slowing down to finish continuous change before"
1332  << " link=" << (*link)->getViaLaneOrLane()->getID()
1333  << " timeRemaining=" << timeRemaining
1334  << " v=" << v
1335  << " va=" << va
1336  << "\n";
1337 #endif
1338  v = MIN2(va, v);
1339  }
1340  }
1341 
1342  // - always issue a request to leave the intersection we are currently on
1343  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1344  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1345  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1346  // - even if red, if we cannot break we should issue a request
1347  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1348 
1349  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1350  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime();
1351  if (yellowOrRed && seen >= brakeDist) {
1352  // the vehicle is able to brake in front of a yellow/red traffic light
1353  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1354  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1355  break;
1356  }
1357 
1358 #ifdef HAVE_INTERNAL_LANES
1360  // we want to pass the link but need to check for foes on internal lanes
1361  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1362  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1363  // the vehicle to enter the junction first has priority
1364  const MSVehicle* leader = (*it).vehAndGap.first;
1365  if (leader == 0) {
1366  // leader is a pedestrian. Passing 'this' as a dummy.
1367  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1368  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1369  } else if ((*link)->isLeader(this, leader)) {
1370  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1371  if (lastLink != 0) {
1372  // we are not yet on the junction with this linkLeader.
1373  // at least we can drive up to the previous link and stop there
1374  v = MAX2(v, lastLink->myVLinkWait);
1375  }
1376  // if blocked by a leader from the same lane we must yield our request
1377  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1378  setRequest = false;
1379  }
1380  }
1381  }
1382  // if this is the link between two internal lanes we may have to slow down for pedestrians
1383  vLinkWait = MIN2(vLinkWait, v);
1384  }
1385 #endif
1386 
1387  if (lastLink != 0) {
1388  lastLink->adaptLeaveSpeed(laneMaxV);
1389  }
1390  SUMOReal arrivalSpeed = vLinkPass;
1391  // vehicles should decelerate when approaching a minor link
1392  // - unless they are close enough to have clear visibility and may start to accelerate again
1393  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1394  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel() && brakeDist < seen) {
1395  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1396  arrivalSpeed = MIN2(vLinkPass, cfModel.getMaxDecel() + cfModel.getMaxAccel());
1397  slowedDownForMinor = true;
1398  }
1399  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1400  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1401  const SUMOReal accel = (arrivalSpeed >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
1402  const SUMOReal accelTime = (arrivalSpeed - v) / accel;
1403  const SUMOReal accelWay = accelTime * (arrivalSpeed + v) * 0.5;
1404  const SUMOReal nonAccelWay = MAX2(SUMOReal(0), seen - accelWay);
1405  // will either drive as fast as possible and decelerate as late as possible
1406  // or accelerate as fast as possible and then hold that speed
1407  const SUMOReal nonAccelSpeed = MAX3(v, arrivalSpeed, SUMO_const_haltingSpeed);
1408  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1409  const SUMOTime arrivalTime = t - DELTA_T + TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
1410 
1411  // compute speed, time if vehicle starts braking now
1412  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1413  SUMOReal arrivalSpeedBraking = 0;
1414  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1415  if (seen < cfModel.brakeGap(v)) {
1416  // vehicle cannot come to a complete stop in time
1417  // Because we use a continuous formula for computiing the possible slow-down
1418  // we need to handle the mismatch with the discrete dynamics
1419  if (seen < v) {
1420  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1421  } else if (2 * (seen - v * cfModel.getHeadwayTime()) * -cfModel.getMaxDecel() + v * v >= 0) {
1422  arrivalSpeedBraking = estimateSpeedAfterDistance(seen - v * cfModel.getHeadwayTime(), v, -cfModel.getMaxDecel());
1423  } else {
1424  arrivalSpeedBraking = cfModel.getMaxDecel();
1425  }
1426  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1427  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1428  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1429  }
1430  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1431  arrivalTime, arrivalSpeed,
1432  arrivalTimeBraking, arrivalSpeedBraking,
1433  seen,
1434  estimateLeaveSpeed(*link, arrivalSpeed)));
1435 #ifdef HAVE_INTERNAL_LANES
1436  if ((*link)->getViaLane() == 0) {
1437  hadNonInternal = true;
1438  ++view;
1439  }
1440 #else
1441  ++view;
1442 #endif
1443  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1444  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1445  break;
1446  }
1447  // get the following lane
1448  lane = (*link)->getViaLaneOrLane();
1449  laneMaxV = lane->getVehicleMaxSpeed(this);
1450  // the link was passed
1451  // compute the velocity to use when the link is not blocked by other vehicles
1452  // the vehicle shall be not faster when reaching the next lane than allowed
1453  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1454  v = MIN2(va, v);
1455  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1456  // do not restrict results to the current vehicle to allow caching for the current time step
1457  leaderLane = lane; // (opposite && lane->getOpposite() != 0) ? lane->getOpposite() : lane;
1458  // ignore leaders while overtaking through the opposite direction lane
1459  ahead = opposite ? MSLeaderInfo(leaderLane) : leaderLane->getLastVehicleInformation(0, 0);
1460  seen += lane->getLength();
1461  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, cfModel.getMaxAccel()), laneMaxV); // upper bound
1462  lastLink = &lfLinks.back();
1463  }
1464 
1465 }
1466 
1467 
1468 void
1470  const SUMOReal seen, DriveProcessItem* const lastLink,
1471  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass) const {
1472  int rightmost;
1473  int leftmost;
1474  ahead.getSubLanes(this, latOffset, rightmost, leftmost);
1475 #ifdef DEBUG_PLAN_MOVE
1476  if (DEBUG_COND) std::cout << SIMTIME
1477  << " adaptToLeaders veh=" << getID()
1478  << " lane=" << lane->getID()
1479  << " rm=" << rightmost
1480  << " lm=" << leftmost
1481  << " ahead=" << ahead.toString()
1482  << "\n";
1483 #endif
1484  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
1485  const MSVehicle* pred = ahead[sublane];
1486  if (pred != 0) {
1487  // @todo avoid multiple adaptations to the same leader
1488  const SUMOReal predBack = pred->getBackPositionOnLane(lane);
1489  const SUMOReal gap = (lastLink == 0
1490  ? predBack - myState.myPos - getVehicleType().getMinGap()
1491  : predBack + seen - lane->getLength() - getVehicleType().getMinGap());
1492 #ifdef DEBUG_PLAN_MOVE
1493  if (DEBUG_COND) {
1494  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";
1495  }
1496 #endif
1497  adaptToLeader(std::make_pair(pred, gap), seen, lastLink, lane, v, vLinkPass);
1498  }
1499  }
1500 }
1501 
1502 
1503 void
1504 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1505  const SUMOReal seen, DriveProcessItem* const lastLink,
1506  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1507  SUMOReal distToCrossing) const {
1508  if (leaderInfo.first != 0) {
1509  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1510  if (lastLink != 0) {
1511  lastLink->adaptLeaveSpeed(vsafeLeader);
1512  }
1513  v = MIN2(v, vsafeLeader);
1514  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1515 
1516 #ifdef DEBUG_PLAN_MOVE
1517  if (DEBUG_COND) std::cout
1518  << SIMTIME
1519  //std::cout << std::setprecision(10);
1520  << " veh=" << getID()
1521  << " lead=" << leaderInfo.first->getID()
1522  << " gap=" << leaderInfo.second
1523  << " leadLane=" << leaderInfo.first->getLane()->getID()
1524  << " predPos=" << leaderInfo.first->getPositionOnLane()
1525  << " seen=" << seen
1526  << " lane=" << lane->getID()
1527  << " myLane=" << myLane->getID()
1528  << " dTC=" << distToCrossing
1529  << " v=" << v
1530  << " vLinkPass=" << vLinkPass
1531  << "\n";
1532 #endif
1533  }
1534 }
1535 
1536 
1537 SUMOReal
1538 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1539  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1540  assert(leaderInfo.first != 0);
1541  const MSCFModel& cfModel = getCarFollowModel();
1542  SUMOReal vsafeLeader = 0;
1543  if (leaderInfo.second >= 0) {
1544  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1545  } else {
1546  // the leading, in-lapping vehicle is occupying the complete next lane
1547  // stop before entering this lane
1548  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1549  }
1550  if (distToCrossing >= 0) {
1551  // drive up to the crossing point with the current link leader
1552  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1553  }
1554  return vsafeLeader;
1555 }
1556 
1557 
1558 bool
1560 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1561  if (gDebugSelectedVehicle == getID()) {
1562  int bla = 0;
1563  }
1564 #endif
1565  // get safe velocities from DriveProcessItems
1566  SUMOReal vSafe = 0; // maximum safe velocity
1567  SUMOReal vSafeZipper = std::numeric_limits<SUMOReal>::max(); // speed limit due to zipper merging
1568  SUMOReal vSafeMin = 0; // minimum safe velocity
1569  // the distance to a link which should either be crossed this step or in
1570  // front of which we need to stop
1571  SUMOReal vSafeMinDist = 0;
1572  myHaveToWaitOnNextLink = false;
1573 
1574  assert(myLFLinkLanes.size() != 0 || isRemoteControlled());
1575  DriveItemVector::iterator i;
1576  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1577  MSLink* link = (*i).myLink;
1578 
1579 #ifdef DEBUG_EXEC_MOVE
1580  if (DEBUG_COND) std::cout
1581  << SIMTIME
1582  << " veh=" << getID()
1583  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
1584  << " req=" << (*i).mySetRequest
1585  << " vP=" << (*i).myVLinkPass
1586  << " vW=" << (*i).myVLinkWait
1587  << " d=" << (*i).myDistance
1588  << "\n";
1589 #endif
1590 
1591  // the vehicle must change the lane on one of the next lanes
1592  if (link != 0 && (*i).mySetRequest) {
1593 
1594 
1595  const LinkState ls = link->getState();
1596  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1597  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1599  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1600  vSafe = (*i).myVLinkWait;
1601  myHaveToWaitOnNextLink = true;
1602  link->removeApproaching(this);
1603  break;
1604  }
1605  //
1606 #ifdef NO_TRACI
1607  const bool influencerPrio = false;
1608 #else
1609  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1610 #endif
1611  std::vector<const SUMOVehicle*> collectFoes;
1612  bool opened = yellow || influencerPrio ||
1613  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1617  ls == LINKSTATE_ZIPPER ? &collectFoes : 0);
1618  if (opened && getLaneChangeModel().getShadowLane() != 0) {
1619  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
1620  if (parallelLink != 0) {
1621  const SUMOReal shadowLatPos = getLateralPositionOnLane() - getLaneChangeModel().getShadowDirection() * 0.5 * (
1623  opened &= parallelLink->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1626  getWaitingTime(), shadowLatPos, 0);
1627 #ifdef DEBUG_EXEC_MOVE
1628  if (DEBUG_COND) std::cout
1629  << SIMTIME
1630  << " veh=" << getID()
1631  << " shadowLane=" << getLaneChangeModel().getShadowLane()->getID()
1632  << " shadowDir=" << getLaneChangeModel().getShadowDirection()
1633  << " parallelLink=" << (parallelLink == 0 ? "NULL" : parallelLink->getViaLaneOrLane()->getID())
1634  << " opened=" << opened
1635  << "\n";
1636 #endif
1637  }
1638  }
1639  // vehicles should decelerate when approaching a minor link
1640  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1641  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1642  vSafe = (*i).myVLinkWait;
1643  myHaveToWaitOnNextLink = true;
1644  if (ls == LINKSTATE_EQUAL) {
1645  link->removeApproaching(this);
1646  }
1647  break; // could be revalidated
1648  } else {
1649  // past the point of no return. we need to drive fast enough
1650  // to make it across the link. However, minor slowdowns
1651  // should be permissible to follow leading traffic safely
1652  // There is a problem in subsecond simulation: If we cannot
1653  // make it across the minor link in one step, new traffic
1654  // could appear on a major foe link and cause a collision
1655  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1656  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1657  }
1658  }
1659  // have waited; may pass if opened...
1660  if (opened) {
1661  vSafe = (*i).myVLinkPass;
1662  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1663  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1664  myHaveToWaitOnNextLink = true;
1665  }
1666  } else if (link->getState() == LINKSTATE_ZIPPER) {
1667  vSafeZipper = MIN2(vSafeZipper,
1668  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
1669  } else {
1670  vSafe = (*i).myVLinkWait;
1671  myHaveToWaitOnNextLink = true;
1672  if (ls == LINKSTATE_EQUAL) {
1673  link->removeApproaching(this);
1674  }
1675 #ifdef DEBUG_EXEC_MOVE
1676  if (DEBUG_COND) {
1677  std::cout << SIMTIME << " braking for closed link=" << link->getViaLaneOrLane()->getID() << "\n";
1678  }
1679 #endif
1680  break;
1681  }
1682  } else {
1683  vSafe = (*i).myVLinkWait;
1684  if (vSafe < getSpeed()) {
1685  myHaveToWaitOnNextLink = true;
1686  }
1687  break;
1688  }
1689  }
1690  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1691  // cannot drive across a link so we need to stop before it
1692  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1693  vSafeMin = 0;
1694  myHaveToWaitOnNextLink = true;
1695  }
1696  // vehicles inside a roundabout should maintain their requests
1697  if (myLane->getEdge().isRoundabout()) {
1698  myHaveToWaitOnNextLink = false;
1699  }
1700  vSafe = MIN2(vSafe, vSafeZipper);
1701 
1702  // XXX braking due to lane-changing is not registered and due to processing stops is not registered
1703  // To avoid casual blinking brake lights at high speeds due to dawdling of the
1704  // leading vehicle, we don't show brake lights when the deceleration could be caused
1705  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
1706  SUMOReal pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
1707  bool brakelightsOn = vSafe < getSpeed() - ACCEL2SPEED(pseudoFriction);
1708  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
1709  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1710 #ifdef DEBUG_EXEC_MOVE
1711  if (DEBUG_COND) {
1712  std::cout << SIMTIME << " moveHelper vSafe=" << vSafe << " vSafeMin=" << vSafeMin << " vNext=" << vNext << "\n";
1713  }
1714 #endif
1715 
1716  // vNext may be higher than vSafe without implying a bug:
1717  // - when approaching a green light that suddenly switches to yellow
1718  // - when using unregulated junctions
1719  // - when using tau < step-size
1720  // - when using unsafe car following models
1721  // - when using TraCI and some speedMode / laneChangeMode settings
1722  //if (vNext > vSafe + NUMERICAL_EPS) {
1723  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1724  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
1725  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1726  //}
1727  vNext = MAX2(vNext, (SUMOReal) 0.);
1728 #ifndef NO_TRACI
1729  if (myInfluencer != 0) {
1730  if (myInfluencer->isVTDControlled()) {
1731  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
1732  }
1734  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1735  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1736  }
1737 #endif
1738  // visit waiting time
1739  if (vNext <= SUMO_const_haltingSpeed && !isStopped()) {
1742  brakelightsOn = true;
1743  } else {
1744  myWaitingTime = 0;
1746  }
1747 
1748  if (brakelightsOn) {
1750  } else {
1752  }
1753  // call reminders after vNext is set
1754  const SUMOReal pos = myState.myPos;
1755 
1756  // update position and speed
1758  SUMOReal deltaPos = SPEED2DIST(vNext);
1759 #ifndef NO_TRACI
1760  if (isRemoteControlled()) {
1761  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
1762  }
1763 #endif
1764  if (getLaneChangeModel().isOpposite()) {
1765  // transform to the forward-direction lane, move and then transform back
1767  myLane = myLane->getOpposite();
1768  }
1769  myState.myPos += deltaPos;
1770  myState.mySpeed = vNext;
1772  std::vector<MSLane*> passedLanes;
1773  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1774  passedLanes.push_back(*i);
1775  }
1776  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1777  passedLanes.push_back(myLane);
1778  }
1779  bool moved = false;
1780  std::string emergencyReason = " for unknown reasons";
1781  // move on lane(s)
1782  if (myState.myPos <= myLane->getLength()) {
1783  // we are staying at our lane
1784  // there is no need to go over succeeding lanes
1785  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1786  } else {
1787  // we are moving at least to the next lane (maybe pass even more than one)
1788  if (myCurrEdge != myRoute->end() - 1) {
1789  MSLane* approachedLane = myLane;
1790  // move the vehicle forward
1791  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1793  MSLink* link = (*i).myLink;
1794  // check whether the vehicle was allowed to enter lane
1795  // otherwise it is decelareted and we do not need to test for it's
1796  // approach on the following lanes when a lane changing is performed
1797  // proceed to the next lane
1798  if (link != 0) {
1799  approachedLane = link->getViaLaneOrLane();
1800 #ifndef NO_TRACI
1802 #endif
1803  if (link->getState() == LINKSTATE_TL_RED) {
1804  emergencyReason = " because of a red traffic light";
1805  break;
1806  }
1807 #ifndef NO_TRACI
1808  }
1809 #endif
1810  } else {
1811  emergencyReason = " because there is no connection to the next edge";
1812  approachedLane = 0;
1813  break;
1814  }
1815  if (approachedLane != myLane && approachedLane != 0) {
1816  myState.myPos -= myLane->getLength();
1817  assert(myState.myPos > 0);
1818  enterLaneAtMove(approachedLane);
1819  myLane = approachedLane;
1820 #ifdef HAVE_INTERNAL_LANES
1822  // erase leaders when past the junction
1823  if (link->getViaLane() == 0) {
1824  link->passedJunction(this);
1825  }
1826  }
1827 #endif
1828  if (hasArrived()) {
1829  break;
1830  }
1831  if (getLaneChangeModel().isChangingLanes()) {
1832  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1833  // abort lane change
1834  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1835  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1837  }
1838  }
1839  moved = true;
1840  if (approachedLane->getEdge().isVaporizing()) {
1842  break;
1843  }
1844  }
1845  passedLanes.push_back(approachedLane);
1846  }
1847  }
1848  }
1849 
1850  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1851  if (myState.myPos > myLane->getLength()) {
1852  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
1853  + "'" + emergencyReason
1854  + " (decel=" + toString(myAcceleration - myState.mySpeed)
1855  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1858  myState.mySpeed = 0;
1859  }
1860  const MSLane* oldBackLane = getBackLane();
1861  if (getLaneChangeModel().isOpposite()) {
1862  passedLanes.clear(); // ignore back occupation
1863  }
1865  updateBestLanes();
1866  // bestLanes need to be updated before lane changing starts
1867  if (getLaneChangeModel().getShadowLane() != 0 && (moved || oldBackLane != getBackLane())) {
1869  }
1870  setBlinkerInformation(); // needs updated bestLanes
1871  //change the blue light only for emergency vehicles SUMOVehicleClass
1872  if (myType->getVehicleClass() == SVC_EMERGENCY) {
1873  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
1874  }
1875  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1877  myAngle = computeAngle();
1878  }
1879 #ifdef DEBUG_EXEC_MOVE
1880  if (DEBUG_COND) {
1881  std::cout << SIMTIME << " executeMove finished veh=" << getID() << " lane=" << myLane->getID() << " myPos=" << getPositionOnLane() << " myPosLat=" << getLateralPositionOnLane() << "\n";
1882  }
1883 #endif
1884  if (getLaneChangeModel().isOpposite()) {
1885  // transform back to the opposite-direction lane
1886  if (myLane->getOpposite() == 0) {
1887  WRITE_WARNING("Unexpected end of opposite lane for vehicle '" + getID() + " at lane '" + myLane->getID() + "', time=" +
1888  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1890  } else {
1892  myLane = myLane->getOpposite();
1894  }
1895  }
1896  return moved;
1897 }
1898 
1899 
1900 const MSLane*
1902  if (myFurtherLanes.size() > 0) {
1903  return myFurtherLanes.back();
1904  } else {
1905  return myLane;
1906  }
1907 }
1908 
1909 
1910 SUMOReal
1911 MSVehicle::updateFurtherLanes(std::vector<MSLane*>& furtherLanes, std::vector<SUMOReal>& furtherLanesPosLat,
1912  const std::vector<MSLane*>& passedLanes) {
1913 
1914  // XXX only reset / set the values that were changed
1915 #ifdef DEBUG_FURTHER
1916  if (DEBUG_COND) std::cout << SIMTIME
1917  << " updateFurtherLanes oldFurther=" << toString(furtherLanes)
1918  << " oldFurtherPosLat=" << toString(furtherLanesPosLat)
1919  << " passed=" << toString(passedLanes)
1920  << "\n";
1921 #endif
1922  for (std::vector<MSLane*>::iterator i = furtherLanes.begin(); i != furtherLanes.end(); ++i) {
1923  (*i)->resetPartialOccupation(this);
1924  }
1925  const MSLane* firstOldFurther = furtherLanes.size() > 0 ? furtherLanes.front() : 0;
1926  // update furtherLanes
1928  furtherLanes.clear();
1929  if (passedLanes.size() > 0) {
1930  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1931  std::vector<MSLane*>::const_reverse_iterator i = passedLanes.rbegin() + 1;
1932  while (leftLength > 0 && i != passedLanes.rend()) {
1933  furtherLanes.push_back(*i);
1934  if (*i != firstOldFurther) {
1935  furtherLanesPosLat.insert(furtherLanesPosLat.begin(), myState.myPosLat);
1936  }
1937 #ifdef DEBUG_FURTHER
1938  if (DEBUG_COND) {
1939  std::cout << SIMTIME << " updateFurtherLanes \n";
1940  }
1941 #endif
1942  leftLength -= (*i)->setPartialOccupation(this);
1943  ++i;
1944  }
1945  result = -leftLength;
1946  }
1947  assert(furtherLanesPosLat.size() >= furtherLanes.size());
1948  furtherLanesPosLat.erase(furtherLanesPosLat.begin() + furtherLanes.size(), furtherLanesPosLat.end());
1949  assert(furtherLanesPosLat.size() == furtherLanes.size());
1950 #ifdef DEBUG_FURTHER
1951  if (DEBUG_COND) std::cout
1952  << " newFurther=" << toString(furtherLanes)
1953  << " newFurtherPosLat=" << toString(furtherLanesPosLat)
1954  << " newBackPos=" << result
1955  << "\n";
1956 #endif
1957  return result;
1958 }
1959 
1960 
1961 SUMOReal
1963 #ifdef DEBUG_FURTHER
1964  //if (DEBUG_COND) std::cout << SIMTIME
1965  // << " getBackPositionOnLane veh=" << getID()
1966  // << " lane=" << Named::getIDSecure(lane)
1967  // << " myLane=" << myLane->getID()
1968  // << " further=" << toString(myFurtherLanes)
1969  // << " furtherPosLat=" << toString(myFurtherLanesPosLat)
1970  // << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
1971  // << " shadowFurther=" << toString(getLaneChangeModel().getShadowFurtherLanes())
1972  // << " shadowFurtherPosLat=" << toString(getLaneChangeModel().getShadowFurtherLanesPosLat())
1973  // << "\n";
1974 #endif
1975  if (lane == myLane
1976  || lane == getLaneChangeModel().getShadowLane()) {
1977  if (getLaneChangeModel().isOpposite()) {
1978  return myState.myPos + myType->getLength();
1979  } else {
1980  return myState.myPos - myType->getLength();
1981  }
1982  } else if ((myFurtherLanes.size() > 0 && lane == myFurtherLanes.back())
1983  || (getLaneChangeModel().getShadowFurtherLanes().size() > 0 && lane == getLaneChangeModel().getShadowFurtherLanes().back())
1984  ) {
1985  return myState.myBackPos;
1986  } else {
1987  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherLanes=" << toString(myFurtherLanes) << "\n";
1988  SUMOReal leftLength = myType->getLength() - myState.myPos;
1989  std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin();
1990  while (leftLength > 0 && i != myFurtherLanes.end()) {
1991  leftLength -= (*i)->getLength();
1992  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
1993  if (*i == lane) {
1994  return -leftLength;
1995  }
1996  ++i;
1997  }
1998  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
1999  leftLength = myType->getLength() - myState.myPos;
2000  i = getLaneChangeModel().getShadowFurtherLanes().begin();
2001  while (leftLength > 0 && i != getLaneChangeModel().getShadowFurtherLanes().end()) {
2002  leftLength -= (*i)->getLength();
2003  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
2004  if (*i == lane) {
2005  return -leftLength;
2006  }
2007  ++i;
2008  }
2009  assert(false);
2010  throw ProcessError("Request backPos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
2011  }
2012 }
2013 
2014 
2015 SUMOReal
2017  return getBackPositionOnLane(lane) + myType->getLength();
2018 }
2019 
2020 
2021 bool
2022 MSVehicle::isFrontOnLane(const MSLane* lane) const {
2023  return lane == myLane || lane == getLaneChangeModel().getShadowLane();
2024 }
2025 
2026 
2027 SUMOReal
2028 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
2029  SUMOReal lengths = 0;
2030  const MSLane::VehCont& vehs = l->getVehiclesSecure();
2031  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
2032  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()
2033  // @todo recheck
2034  && (*i)->isFrontOnLane(l)) {
2035  foundStopped = true;
2036  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
2037  l->releaseVehicles();
2038  return ret;
2039  }
2040  lengths += (*i)->getVehicleType().getLengthWithGap();
2041  }
2042  l->releaseVehicles();
2043  return l->getLength() - lengths;
2044 }
2045 
2046 
2047 void
2048 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
2049 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2050  if (gDebugSelectedVehicle == getID()) {
2051  int bla = 0;
2052  }
2053 #endif
2054 #ifdef HAVE_INTERNAL_LANES
2056  bool hadVehicle = false;
2057  SUMOReal seenSpace = -lengthsInFront;
2058 
2059  bool foundStopped = false;
2060  // compute available space until a stopped vehicle is found
2061  // this is the sum of non-interal lane length minus in-between vehicle lenghts
2062  for (int i = 0; i < (int)lfLinks.size(); ++i) {
2063  // skip unset links
2064  DriveProcessItem& item = lfLinks[i];
2065  if (item.myLink == 0 || foundStopped) {
2066  item.availableSpace = seenSpace;
2067  item.hadVehicle = hadVehicle;
2068  continue;
2069  }
2070  // get the next lane, determine whether it is an internal lane
2071  const MSLane* approachedLane = item.myLink->getViaLane();
2072  if (approachedLane != 0) {
2073  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
2074  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
2075  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2076  } else {
2077  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2078  hadVehicle |= approachedLane->getVehicleNumber() != 0;
2079  }
2080  item.availableSpace = seenSpace;
2081  item.hadVehicle = hadVehicle;
2082 #ifdef DEBUG_PLAN_MOVE
2083  if (DEBUG_COND) std::cout
2084  << SIMTIME
2085  << " veh=" << getID()
2086  << " approached=" << approachedLane->getID()
2087  << " approachedBrutto=" << approachedLane->getBruttoVehLenSum()
2088  << " avail=" << item.availableSpace
2089  << " seenSpace=" << seenSpace
2090  << " hadVehicle=" << item.hadVehicle
2091  << " lengthsInFront=" << lengthsInFront
2092  << "\n";
2093 #endif
2094  continue;
2095  }
2096  approachedLane = item.myLink->getLane();
2097  const MSVehicle* last = approachedLane->getLastAnyVehicle();
2098  if (last == 0) {
2099  seenSpace += approachedLane->getLength();
2100  item.availableSpace = seenSpace;
2101  } else if (!last->isFrontOnLane(approachedLane)) {
2104  item.availableSpace = MAX2(seenSpace, seenSpace + last->getBackPositionOnLane(approachedLane) + last->getCarFollowModel().brakeGap(last->getSpeed()));
2105  hadVehicle = true;
2107  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2109  if (last->myHaveToWaitOnNextLink) {
2110  foundStopped = true;
2111  }
2112 #ifdef DEBUG_PLAN_MOVE
2113  if (DEBUG_COND) std::cout
2114  << SIMTIME
2115  << " veh=" << getID()
2116  << " approached=" << approachedLane->getID()
2117  << " lastPoc=" << last->getID()
2118  << " avail=" << item.availableSpace
2119  << " seenSpace=" << seenSpace
2120  << " foundStopped=" << foundStopped
2121  << "\n";
2122 #endif
2123  } else {
2124 
2125  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
2126  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(last->getSpeed());
2127  const SUMOReal lastGap = last->getBackPositionOnLane(approachedLane) + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime()
2128  // gap of last up to the next intersection
2129  - last->getVehicleType().getMinGap();
2130  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
2131  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
2132  } else {
2133  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
2134  item.availableSpace = seenSpace;
2135  }
2136  if (last->myHaveToWaitOnNextLink) {
2137  foundStopped = true;
2138  }
2139  hadVehicle = true;
2140 #ifdef DEBUG_PLAN_MOVE
2141  if (DEBUG_COND) std::cout
2142  << SIMTIME
2143  << " veh=" << getID()
2144  << " approached=" << approachedLane->getID()
2145  << " last=" << last->getID()
2146  << " avail=" << item.availableSpace
2147  << " seenSpace=" << seenSpace
2148  << " foundStopped=" << foundStopped
2149  << "\n";
2150 #endif
2151  }
2152  item.hadVehicle = hadVehicle;
2153  }
2154 
2155 
2156 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2157  if (gDebugSelectedVehicle == getID()) {
2158  int bla = 0;
2159  }
2160 #endif
2161  // check which links allow continuation and add pass available to the previous item
2162  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
2163  DriveProcessItem& item = lfLinks[i - 1];
2164  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
2165  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
2166 #ifndef NO_TRACI
2168 #endif
2169  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
2172  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
2173  if (!opened && item.myLink != 0) {
2174  if (i > 1) {
2175  DriveProcessItem& item2 = lfLinks[i - 2];
2176  if (item2.myLink != 0 && item2.myLink->isCont()) {
2177  allowsContinuation = true;
2178  }
2179  }
2180  }
2181  if (allowsContinuation) {
2182  item.availableSpace = lfLinks[i].availableSpace;
2183  }
2184  }
2185 
2186  // find removalBegin
2187  int removalBegin = -1;
2188  for (int i = 0; hadVehicle && i < (int)lfLinks.size() && removalBegin < 0; ++i) {
2189  // skip unset links
2190  const DriveProcessItem& item = lfLinks[i];
2191  if (item.myLink == 0) {
2192  continue;
2193  }
2194  /*
2195  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
2196  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
2197  removalBegin = lastLinkToInternal;
2198  }
2199  */
2200 
2201  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
2202  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
2203  SUMOReal impatienceCorrection = 0;
2204  /*
2205  if(item.myLink->getState()==LINKSTATE_MINOR) {
2206  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
2207  }
2208  */
2209  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
2210  removalBegin = i;
2211  }
2212  //removalBegin = i;
2213  }
2214  }
2215  // abort requests
2216  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
2217  while (removalBegin < (int)(lfLinks.size())) {
2219  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
2220  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
2221  lfLinks[removalBegin].mySetRequest = false;
2222  }
2223  ++removalBegin;
2224  }
2225  }
2226  }
2227 #else
2228  UNUSED_PARAMETER(lengthsInFront);
2229 #endif
2230  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2231  if ((*i).myLink != 0) {
2232  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
2233  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((int)2); // tie braker
2234  }
2235  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2236  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2237  }
2238  }
2239  if (getLaneChangeModel().getShadowLane() != 0) {
2240  // register on all shadow links
2241  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
2242  if ((*i).myLink != 0) {
2243  MSLink* parallelLink = (*i).myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
2244  if (parallelLink != 0) {
2245  parallelLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
2246  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
2248  }
2249  }
2250  }
2251  }
2252 }
2253 
2254 
2255 void
2257  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2258  // skip the reminder if it is a lane reminder but not for my lane
2259  if (rem->first->getLane() != 0 && rem->second > 0.) {
2260 #ifdef _DEBUG
2261  if (myTraceMoveReminders) {
2262  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
2263  }
2264 #endif
2265  ++rem;
2266  } else {
2267  if (rem->first->notifyEnter(*this, reason)) {
2268 #ifdef _DEBUG
2269  if (myTraceMoveReminders) {
2270  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
2271  }
2272 #endif
2273  ++rem;
2274  } else {
2275 #ifdef _DEBUG
2276  if (myTraceMoveReminders) {
2277  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
2278  }
2279 #endif
2280  rem = myMoveReminders.erase(rem);
2281  }
2282  }
2283  }
2284 }
2285 
2286 
2287 bool
2288 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
2289  myAmOnNet = !onTeleporting;
2290  // vaporizing edge?
2291  /*
2292  if (enteredLane->getEdge().isVaporizing()) {
2293  // yep, let's do the vaporization...
2294  myLane = enteredLane;
2295  return true;
2296  }
2297  */
2298  // move mover reminder one lane further
2299  adaptLaneEntering2MoveReminder(*enteredLane);
2300  // set the entered lane as the current lane
2301  myLane = enteredLane;
2302  myLastBestLanesEdge = 0;
2303 
2304  // internal edges are not a part of the route...
2305  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
2306  ++myCurrEdge;
2307  }
2308  if (!onTeleporting) {
2310  } else {
2312  // normal move() isn't called so reset position here
2313  myState.myPos = 0;
2315  }
2316  return hasArrived();
2317 }
2318 
2319 
2320 void
2322  myAmOnNet = true;
2323  myLane = enteredLane;
2325  // need to update myCurrentLaneInBestLanes
2326  updateBestLanes();
2327  // switch to and activate the new lane's reminders
2328  // keep OldLaneReminders
2329  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2330  addReminder(*rem);
2331  }
2333  MSLane* lane = myLane;
2334  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
2335  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
2336  if (lane != 0) {
2337  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
2338  }
2339  if (lane != 0) {
2340 #ifdef DEBUG_FURTHER
2341  if (DEBUG_COND) {
2342  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2343  }
2344 #endif
2345  myFurtherLanes[i]->resetPartialOccupation(this);
2346  myFurtherLanes[i] = lane;
2348 #ifdef DEBUG_FURTHER
2349  if (DEBUG_COND) {
2350  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
2351  }
2352 #endif
2353  leftLength -= (lane)->setPartialOccupation(this);
2354  } else {
2355  // keep the old values, but ensure there is no shadow
2358  }
2359  }
2360  }
2361 #ifdef DEBUG_FURTHER
2362  if (DEBUG_COND) {
2363  std::cout << SIMTIME << " enterLaneAtLaneChange new furtherLanes=" << toString(myFurtherLanes) << "\n";
2364  }
2365 #endif
2366  myAngle = computeAngle();
2367 }
2368 
2369 
2370 void
2372  myState = State(pos, speed, posLat, pos - getVehicleType().getLength());
2373  if (myDeparture == NOT_YET_DEPARTED) {
2374  onDepart();
2375  }
2377  assert(myState.myPos >= 0);
2378  assert(myState.mySpeed >= 0);
2379  myWaitingTime = 0;
2380  myLane = enteredLane;
2381  myAmOnNet = true;
2382  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
2383  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
2384  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
2385  addReminder(*rem);
2386  }
2387  activateReminders(notification);
2388  }
2389  // build the list of lanes the vehicle is lapping into
2390  SUMOReal leftLength = myType->getLength() - pos;
2391  MSLane* clane = enteredLane;
2392  while (leftLength > 0) {
2393  clane = clane->getLogicalPredecessorLane();
2394  if (clane == 0 || clane == myLane) {
2395  break;
2396  }
2397  myFurtherLanes.push_back(clane);
2399  leftLength -= (clane)->setPartialOccupation(this);
2400  }
2401  myState.myBackPos = -leftLength;
2404  }
2405  myAngle = computeAngle();
2406  if (getLaneChangeModel().isOpposite()) {
2407  myAngle += M_PI;
2408  }
2409 }
2410 
2411 
2412 void
2414  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
2415  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
2416 #ifdef _DEBUG
2417  if (myTraceMoveReminders) {
2418  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
2419  }
2420 #endif
2421  ++rem;
2422  } else {
2423 #ifdef _DEBUG
2424  if (myTraceMoveReminders) {
2425  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
2426  }
2427 #endif
2428  rem = myMoveReminders.erase(rem);
2429  }
2430  }
2432  // @note. In case of lane change, myFurtherLanes and partial occupation
2433  // are handled in enterLaneAtLaneChange()
2434  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
2435 #ifdef DEBUG_FURTHER
2436  if (DEBUG_COND) {
2437  std::cout << SIMTIME << " leaveLane \n";
2438  }
2439 #endif
2440  (*i)->resetPartialOccupation(this);
2441  }
2442  myFurtherLanes.clear();
2443  myFurtherLanesPosLat.clear();
2444  }
2445  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
2446  myAmOnNet = false;
2447  }
2449  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
2450  }
2452  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
2453  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
2454  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
2455  myStops.pop_front();
2456  }
2457  }
2458 }
2459 
2460 
2463  return *myLaneChangeModel;
2464 }
2465 
2466 
2469  return *myLaneChangeModel;
2470 }
2471 
2472 
2473 const std::vector<MSVehicle::LaneQ>&
2475  return *myBestLanes.begin();
2476 }
2477 
2478 
2479 void
2480 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
2481 #ifdef DEBUG_BESTLANES
2482  if (DEBUG_COND) {
2483  std::cout << SIMTIME << " updateBestLanes veh=" << getID() << " startLane1=" << Named::getIDSecure(startLane) << " myLane=" << Named::getIDSecure(myLane) << "\n";
2484  }
2485 #endif
2486 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2487  if (gDebugSelectedVehicle == getID()) {
2488  int bla = 0;
2489  myLastBestLanesEdge = 0;
2490  }
2491 #endif
2492  if (startLane == 0) {
2493  startLane = myLane;
2494  }
2495  assert(startLane != 0);
2496  if (getLaneChangeModel().isOpposite()) {
2497  return;
2498  }
2499  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
2501  return;
2502  }
2503  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
2504  if (myBestLanes.size() == 0 || forceRebuild) {
2505  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
2506  updateBestLanes(true, startLane->getLogicalPredecessorLane());
2507  }
2508  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
2509  return;
2510  }
2511  // adapt best lanes to fit the current internal edge:
2512  // keep the entries that are reachable from this edge
2513  const MSEdge* nextEdge = startLane->getInternalFollower();
2514  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
2515  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
2516  std::vector<LaneQ>& lanes = *it;
2517  assert(lanes.size() > 0);
2518  if (&(lanes[0].lane->getEdge()) == nextEdge) {
2519  // keep those lanes which are successors of internal lanes from the edge of startLane
2520  std::vector<LaneQ> oldLanes = lanes;
2521  lanes.clear();
2522  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
2523  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
2524  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
2525  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
2526  lanes.push_back(*it_lane);
2527  break;
2528  }
2529  }
2530  }
2531  assert(lanes.size() == startLane->getEdge().getLanes().size());
2532  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
2533  for (int i = 0; i < (int)lanes.size(); ++i) {
2534  if (i + lanes[i].bestLaneOffset < 0) {
2535  lanes[i].bestLaneOffset = -i;
2536  }
2537  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
2538  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
2539  }
2540  assert(i + lanes[i].bestLaneOffset >= 0);
2541  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
2542  if (lanes[i].bestContinuations[0] != 0) {
2543  // patch length of bestContinuation to match expectations (only once)
2544  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
2545  }
2546  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
2547  myCurrentLaneInBestLanes = lanes.begin() + i;
2548  }
2549  assert(&(lanes[i].lane->getEdge()) == nextEdge);
2550  }
2551  myLastBestLanesInternalLane = startLane;
2553  return;
2554  } else {
2555  // remove passed edges
2556  it = myBestLanes.erase(it);
2557  }
2558  }
2559  assert(false); // should always find the next edge
2560  }
2561  // start rebuilding
2562  myLastBestLanesEdge = &startLane->getEdge();
2563  myBestLanes.clear();
2564 
2565  // get information about the next stop
2566  const MSEdge* nextStopEdge = 0;
2567  const MSLane* nextStopLane = 0;
2568  SUMOReal nextStopPos = 0;
2569  if (!myStops.empty()) {
2570  const Stop& nextStop = myStops.front();
2571  nextStopLane = nextStop.lane;
2572  nextStopEdge = &nextStopLane->getEdge();
2573  nextStopPos = nextStop.startPos;
2574  }
2575  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
2576  nextStopEdge = *(myRoute->end() - 1);
2577  nextStopLane = nextStopEdge->getLanes()[myArrivalLane];
2578  nextStopPos = myArrivalPos;
2579  }
2580  if (nextStopEdge != 0) {
2581  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
2582  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
2583  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
2584  }
2585 
2586  // go forward along the next lanes;
2587  int seen = 0;
2588  SUMOReal seenLength = 0;
2589  bool progress = true;
2590  for (MSRouteIterator ce = myCurrEdge; progress;) {
2591  std::vector<LaneQ> currentLanes;
2592  const std::vector<MSLane*>* allowed = 0;
2593  const MSEdge* nextEdge = 0;
2594  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
2595  nextEdge = *(ce + 1);
2596  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
2597  }
2598  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
2599  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
2600  LaneQ q;
2601  MSLane* cl = *i;
2602  q.lane = cl;
2603  q.bestContinuations.push_back(cl);
2604  q.bestLaneOffset = 0;
2605  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
2606  q.currentLength = q.length;
2607  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
2608  q.occupation = 0;
2609  q.nextOccupation = 0;
2610  currentLanes.push_back(q);
2611  }
2612  //
2613  if (nextStopEdge == *ce) {
2614  progress = false;
2615  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
2616  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
2617  (*q).allowsContinuation = false;
2618  (*q).length = nextStopPos;
2619  (*q).currentLength = (*q).length;
2620  }
2621  }
2622  }
2623 
2624  myBestLanes.push_back(currentLanes);
2625  ++seen;
2626  seenLength += currentLanes[0].lane->getLength();
2627  ++ce;
2628  progress &= (seen <= 4 || seenLength < 3000);
2629  progress &= seen <= 8;
2630  progress &= ce != myRoute->end();
2631  /*
2632  if(progress) {
2633  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
2634  }
2635  */
2636  }
2637 
2638  // we are examining the last lane explicitly
2639  if (myBestLanes.size() != 0) {
2640  SUMOReal bestLength = -1;
2641  int bestThisIndex = 0;
2642  int index = 0;
2643  std::vector<LaneQ>& last = myBestLanes.back();
2644  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2645  if ((*j).length > bestLength) {
2646  bestLength = (*j).length;
2647  bestThisIndex = index;
2648  }
2649  }
2650  index = 0;
2651  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2652  if ((*j).length < bestLength) {
2653  (*j).bestLaneOffset = bestThisIndex - index;
2654  }
2655  }
2656  }
2657 #ifdef DEBUG_BESTLANES
2658  if (DEBUG_COND) {
2659  std::cout << " last edge:\n";
2660  std::vector<LaneQ>& laneQs = myBestLanes.back();
2661  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
2662  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
2663  }
2664  }
2665 #endif
2666  // go backward through the lanes
2667  // track back best lane and compute the best prior lane(s)
2668  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
2669  std::vector<LaneQ>& nextLanes = (*(i - 1));
2670  std::vector<LaneQ>& clanes = (*i);
2671  MSEdge& cE = clanes[0].lane->getEdge();
2672  int index = 0;
2673  SUMOReal bestConnectedLength = -1;
2674  SUMOReal bestLength = -1;
2675  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
2676  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
2677  bestConnectedLength = (*j).length;
2678  }
2679  if (bestLength < (*j).length) {
2680  bestLength = (*j).length;
2681  }
2682  }
2683  // compute index of the best lane (highest length and least offset from the best next lane)
2684  int bestThisIndex = 0;
2685  if (bestConnectedLength > 0) {
2686  index = 0;
2687  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2688  LaneQ bestConnectedNext;
2689  bestConnectedNext.length = -1;
2690  if ((*j).allowsContinuation) {
2691  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
2692  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2693  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
2694  bestConnectedNext = *m;
2695  }
2696  }
2697  }
2698  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
2699  (*j).length += bestLength;
2700  } else {
2701  (*j).length += bestConnectedNext.length;
2702  }
2703  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
2704  }
2705  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
2706  if (clanes[bestThisIndex].length < (*j).length
2707  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
2708  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
2709  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
2710  ) {
2711  bestThisIndex = index;
2712  }
2713  }
2714 #ifdef DEBUG_BESTLANES
2715  if (DEBUG_COND) {
2716  std::cout << " edge=" << cE.getID() << "\n";
2717  std::vector<LaneQ>& laneQs = clanes;
2718  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
2719  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
2720  }
2721  }
2722 #endif
2723 
2724  } else {
2725  // only needed in case of disconnected routes
2726  int bestNextIndex = 0;
2727  int bestDistToNeeded = (int) clanes.size();
2728  index = 0;
2729  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2730  if ((*j).allowsContinuation) {
2731  int nextIndex = 0;
2732  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
2733  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2734  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
2735  bestDistToNeeded = abs((*m).bestLaneOffset);
2736  bestThisIndex = index;
2737  bestNextIndex = nextIndex;
2738  }
2739  }
2740  }
2741  }
2742  }
2743  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
2744  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
2745 
2746  }
2747  // set bestLaneOffset for all lanes
2748  index = 0;
2749  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2750  if ((*j).length < clanes[bestThisIndex].length
2751  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
2752  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
2753  ) {
2754  (*j).bestLaneOffset = bestThisIndex - index;
2755  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
2756  // try to move away from the lower-priority lane before it ends
2757  (*j).length = (*j).currentLength;
2758  }
2759  } else {
2760  (*j).bestLaneOffset = 0;
2761  }
2762  }
2763  }
2765 #ifdef DEBUG_BESTLANES
2766  if (DEBUG_COND) {
2767  std::cout << SIMTIME << " veh=" << getID() << " bestCont=" << toString(getBestLanesContinuation()) << "\n";
2768  }
2769 #endif
2770  return;
2771 }
2772 
2773 
2774 int
2775 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
2776  if (conts.size() < 2) {
2777  return -1;
2778  } else {
2779  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
2780  if (link != 0) {
2781  return link->havePriority() ? 1 : 0;
2782  } else {
2783  // disconnected route
2784  return -1;
2785  }
2786  }
2787 }
2788 
2789 
2790 void
2792  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
2793  std::vector<LaneQ>::iterator i;
2794  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
2795  SUMOReal nextOccupation = 0;
2796  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
2797  nextOccupation += (*j)->getBruttoVehLenSum();
2798  }
2799  (*i).nextOccupation = nextOccupation;
2800  if ((*i).lane == startLane) {
2802  }
2803  }
2804 }
2805 
2806 
2807 const std::vector<MSLane*>&
2809  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2810  return myEmptyLaneVector;
2811  }
2812  return (*myCurrentLaneInBestLanes).bestContinuations;
2813 }
2814 
2815 
2816 const std::vector<MSLane*>&
2818  const MSLane* lane = l;
2820  // internal edges are not kept inside the bestLanes structure
2821  lane = lane->getLinkCont()[0]->getLane();
2822  }
2823  if (myBestLanes.size() == 0) {
2824  return myEmptyLaneVector;
2825  }
2826  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
2827  if ((*i).lane == lane) {
2828  return (*i).bestContinuations;
2829  }
2830  }
2831  return myEmptyLaneVector;
2832 }
2833 
2834 
2835 int
2837  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2838  return 0;
2839  } else {
2840  return (*myCurrentLaneInBestLanes).bestLaneOffset;
2841  }
2842 }
2843 
2844 
2845 void
2847  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
2848  assert(laneIndex < (int)preb.size());
2849  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
2850 }
2851 
2852 
2853 void
2855  if (MSGlobals::gLaneChangeDuration > 0 && !getLaneChangeModel().isChangingLanes()) {
2856  myState.myPosLat = 0;
2857  }
2858 }
2859 
2860 
2861 SUMOReal
2862 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) const {
2864  if (isOnRoad() && destEdge != NULL) {
2865  if (&myLane->getEdge() == *myCurrEdge) {
2866  // vehicle is on a normal edge
2867  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2868  } else {
2869  // vehicle is on inner junction edge
2870  distance = myLane->getLength() - getPositionOnLane();
2871  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2872  }
2873  }
2874  return distance;
2875 }
2876 
2877 
2878 std::pair<const MSVehicle* const, SUMOReal>
2880  if (myLane == 0) {
2881  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
2882  }
2883  if (dist == 0) {
2885  }
2886  const MSVehicle* lead = 0;
2887  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
2888  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
2889  if (it != vehs.end() && it + 1 != vehs.end()) {
2890  lead = *(it + 1);
2891  }
2892  if (lead != 0) {
2893  std::pair<const MSVehicle* const, SUMOReal> result(
2896  return result;
2897  }
2898  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
2899  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
2900  std::pair<const MSVehicle* const, SUMOReal> result = myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
2902  return result;
2903 }
2904 
2905 
2906 SUMOReal
2908  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
2909  if (leaderInfo.first == 0 || getSpeed() == 0) {
2910  return -1;
2911  }
2912  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
2913 }
2914 
2915 
2916 SUMOReal
2919 }
2920 
2921 
2922 SUMOReal
2925 }
2926 
2927 
2928 SUMOReal
2931 }
2932 
2933 
2934 SUMOReal
2937 }
2938 
2939 
2940 SUMOReal
2943 }
2944 
2945 
2946 SUMOReal
2949 }
2950 
2951 
2952 SUMOReal
2955 }
2956 
2957 
2958 SUMOReal
2961 }
2962 
2963 
2964 void
2966  if (myPersonDevice == 0) {
2968  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2969  }
2971  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2972  int numExpected = (int) myStops.front().awaitedPersons.size();
2973  if (numExpected != 0) {
2974  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2975  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2976  // Bus drivers usually do not know the names of the passengers.
2977  myStops.front().awaitedPersons.erase(person->getID());
2978  numExpected = (int) myStops.front().awaitedPersons.size();
2979  }
2980  if (numExpected == 0) {
2981  myStops.front().duration = 0;
2982  }
2983  }
2984 }
2985 
2986 void
2988  if (myContainerDevice == 0) {
2990  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
2991  }
2992  myContainerDevice->addTransportable(container);
2993  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
2994  int numExpected = (int) myStops.front().awaitedContainers.size();
2995  if (numExpected != 0) {
2996  myStops.front().awaitedContainers.erase(container->getID());
2997  numExpected = (int) myStops.front().awaitedContainers.size();
2998  }
2999  if (numExpected == 0) {
3000  myStops.front().duration = 0;
3001  }
3002  }
3003 }
3004 
3005 
3006 const std::vector<MSTransportable*>&
3008  if (myPersonDevice == 0) {
3010  } else {
3012  }
3013 }
3014 
3015 
3016 const std::vector<MSTransportable*>&
3018  if (myContainerDevice == 0) {
3020  } else {
3022  }
3023 }
3024 
3025 
3026 int
3028  int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
3029  return boarded + myParameter->personNumber;
3030 }
3031 
3032 int
3034  int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
3035  return loaded + myParameter->containerNumber;
3036 }
3037 
3038 
3039 void
3042  int state = getLaneChangeModel().getOwnState();
3043  if ((state & LCA_LEFT) != 0 && (state & LCA_SUBLANE) == 0) {
3045  } else if ((state & LCA_RIGHT) != 0 && (state & LCA_SUBLANE) == 0) {
3047  } else if (getLaneChangeModel().isChangingLanes()) {
3048  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
3050  } else {
3052  }
3053  } else {
3054  const MSLane* lane = getLane();
3055  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
3056  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
3057  switch ((*link)->getDirection()) {
3058  case LINKDIR_TURN:
3059  case LINKDIR_LEFT:
3060  case LINKDIR_PARTLEFT:
3062  break;
3063  case LINKDIR_RIGHT:
3064  case LINKDIR_PARTRIGHT:
3066  break;
3067  default:
3068  break;
3069  }
3070  }
3071  }
3072 
3073 }
3074 
3075 void
3077  if (currentTime % 1000 == 0) {
3080  } else {
3082  }
3083  }
3084 }
3085 
3086 
3087 void
3089  if (myType->amVehicleSpecific()) {
3090  delete myType;
3091  }
3092  myType = type;
3093 }
3094 
3095 int
3097  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
3098  return (int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
3099 }
3100 
3101 
3102 void
3104  assert(lane != 0);
3105  myLane = lane;
3106  myState.myPos = pos;
3107  myState.myPosLat = posLat;
3109 }
3110 
3111 
3112 SUMOReal
3114  return myState.myPosLat + 0.5 * myLane->getWidth() - 0.5 * getVehicleType().getWidth();
3115 }
3116 
3117 
3118 SUMOReal
3120  return getCenterOnEdge(lane) - 0.5 * getVehicleType().getWidth();
3121 }
3122 
3123 
3124 SUMOReal
3126  if (lane == 0 || &lane->getEdge() == &myLane->getEdge()) {
3127  return myLane->getRightSideOnEdge() + myState.myPosLat + 0.5 * myLane->getWidth();
3128  } else {
3129  assert(myFurtherLanes.size() == myFurtherLanesPosLat.size());
3130  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3131  if (myFurtherLanes[i] == lane) {
3132 #ifdef DEBUG_FURTHER
3133  if (DEBUG_COND) std::cout << " getCenterOnEdge veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " furtherLat=" << myFurtherLanesPosLat[i]
3134  << " result=" << lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth()
3135  << "\n";
3136 #endif
3137  return lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth();
3138  }
3139  }
3140  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3141  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3142  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3143  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
3144  if (shadowFurther[i] == lane) {
3145  assert(getLaneChangeModel().getShadowLane() != 0);
3146  return (lane->getRightSideOnEdge() + getLaneChangeModel().getShadowFurtherLanesPosLat()[i] + 0.5 * lane->getWidth()
3148  }
3149  }
3150  assert(false);
3151  throw ProcessError("Request lateral pos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3152  }
3153 }
3154 
3155 
3156 SUMOReal
3157 MSVehicle::getLatOffset(const MSLane* lane) const {
3158  assert(lane != 0);
3159  if (&lane->getEdge() == &myLane->getEdge()) {
3160  return myLane->getRightSideOnEdge() - lane->getRightSideOnEdge();
3161  } else {
3162  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
3163  if (myFurtherLanes[i] == lane) {
3164 #ifdef DEBUG_FURTHER
3165  if (DEBUG_COND) {
3166  std::cout << " getLatOffset veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " posLat=" << myState.myPosLat << " furtherLat=" << myFurtherLanesPosLat[i] << "\n";
3167  }
3168 #endif
3170  }
3171  }
3172 #ifdef DEBUG_FURTHER
3173  if (DEBUG_COND) {
3174  std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
3175  }
3176 #endif
3177  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
3178  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
3179  if (shadowFurther[i] == lane) {
3180 #ifdef DEBUG_FURTHER
3181  if (DEBUG_COND) std::cout << " getLatOffset veh=" << getID()
3182  << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
3183  << " lane=" << lane->getID()
3184  << " i=" << i
3185  << " posLat=" << myState.myPosLat
3186  << " shadowPosLat=" << getLatOffset(getLaneChangeModel().getShadowLane())
3187  << " shadowFurtherLat=" << getLaneChangeModel().getShadowFurtherLanesPosLat()[i]
3188  << "\n";
3189 #endif
3191  }
3192  }
3193  assert(false);
3194  throw ProcessError("Request lateral offset of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
3195  }
3196 }
3197 
3198 
3199 SUMOReal
3201  return (fabs(getLateralPositionOnLane()) + 0.5 * getVehicleType().getWidth()
3202  - 0.5 * myLane->getWidth());
3203 }
3204 
3205 
3206 void
3208  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
3209  if ((*i).myLink != 0) {
3210  (*i).myLink->removeApproaching(this);
3211  }
3212  }
3213  // unregister on all shadow links
3215 }
3216 
3217 
3218 bool
3220  // the following links are unsafe:
3221  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
3222  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
3224  const SUMOReal dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
3225  if (seen < dist) {
3226  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
3227  int view = 1;
3228  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3229  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
3230  while (!lane->isLinkEnd(link) && seen <= dist) {
3231  if (!lane->getEdge().isInternal()
3232  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
3233  || !(*link)->havePriority())) {
3234  // find the drive item corresponding to this link
3235  bool found = false;
3236  while (di != myLFLinkLanes.end() && !found) {
3237  if ((*di).myLink != 0) {
3238  const MSLane* diPredLane = (*di).myLink->getApproachingLane();
3239  if (diPredLane != 0) {
3240  if (&diPredLane->getEdge() == &lane->getEdge()) {
3241  found = true;
3242  }
3243  }
3244  }
3245  if (!found) {
3246  di++;
3247  }
3248  }
3249  if (found) {
3250  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
3251  (*di).getLeaveSpeed(), getVehicleType().getLength());
3252  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
3253  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
3254  return true;
3255  }
3256  }
3257  // no drive item is found if the vehicle aborts it's request within dist
3258  }
3259  lane = (*link)->getViaLaneOrLane();
3260  if (!lane->getEdge().isInternal()) {
3261  view++;
3262  }
3263  seen += lane->getLength();
3264  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
3265  }
3266  }
3267  return false;
3268 }
3269 
3270 
3273  PositionVector centerLine;
3274  centerLine.push_back(getPosition());
3275  centerLine.push_back(getBackPosition());
3276  centerLine.move2side(0.5 * myType->getWidth());
3277  PositionVector result = centerLine;
3278  centerLine.move2side(-myType->getWidth());
3279  result.append(centerLine.reverse(), POSITION_EPS);
3280  return result;
3281 }
3282 
3283 
3286  // XXX implement more types
3287  switch (myType->getGuiShape()) {
3288  case SVS_PASSENGER:
3289  case SVS_PASSENGER_SEDAN:
3291  case SVS_PASSENGER_WAGON:
3292  case SVS_PASSENGER_VAN: {
3293  PositionVector result;
3294  PositionVector centerLine;
3295  centerLine.push_back(getPosition());
3296  centerLine.push_back(getBackPosition());
3297  PositionVector line1 = centerLine;
3298  PositionVector line2 = centerLine;
3299  line1.move2side(0.3 * myType->getWidth());
3300  line2.move2side(0.5 * myType->getWidth());
3301  line2.scaleRelative(0.8);
3302  result.push_back(line1[0]);
3303  result.push_back(line2[0]);
3304  result.push_back(line2[1]);
3305  result.push_back(line1[1]);
3306  line1.move2side(-0.6 * myType->getWidth());
3307  line2.move2side(-1.0 * myType->getWidth());
3308  result.push_back(line1[1]);
3309  result.push_back(line2[1]);
3310  result.push_back(line2[0]);
3311  result.push_back(line1[0]);
3312  return result;
3313  }
3314  default:
3315  return getBoundingBox();
3316  }
3317 }
3318 
3319 
3320 #ifndef NO_TRACI
3321 bool
3322 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
3323  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
3324  //if the stop exists update the duration
3325  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3326  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
3327  if (duration == 0 && !iter->reached) {
3328  myStops.erase(iter);
3329  } else {
3330  iter->duration = duration;
3331  }
3332  return true;
3333  }
3334  }
3335 
3337  newStop.lane = lane->getID();
3338  newStop.startPos = startPos;
3339  newStop.endPos = endPos;
3340  newStop.duration = duration;
3341  newStop.until = until;
3342  newStop.triggered = triggered;
3343  newStop.containerTriggered = containerTriggered;
3344  newStop.parking = parking;
3345  newStop.index = STOP_INDEX_FIT;
3346  const bool result = addStop(newStop, errorMsg);
3347  if (myLane != 0) {
3348  updateBestLanes(true);
3349  }
3350  return result;
3351 }
3352 
3353 
3354 bool
3355 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
3356  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
3357  //if the stop exists update the duration
3358  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
3359  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
3360  if (stop != 0 && stop->getID() == stopId) {
3361  if (duration == 0 && !iter->reached) {
3362  myStops.erase(iter);
3363  } else {
3364  iter->duration = duration;
3365  }
3366  return true;
3367  }
3368  }
3369 
3371  MSStoppingPlace* bs = 0;
3372  if (isContainerStop) {
3373  newStop.containerstop = stopId;
3374  bs = MSNet::getInstance()->getContainerStop(stopId);
3375  if (bs == 0) {
3376  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3377  return false;
3378  }
3379  } else {
3380  newStop.busstop = stopId;
3381  bs = MSNet::getInstance()->getBusStop(stopId);
3382  if (bs == 0) {
3383  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
3384  return false;
3385  }
3386  }
3387  newStop.duration = duration;
3388  newStop.until = until;
3389  newStop.triggered = triggered;
3390  newStop.containerTriggered = containerTriggered;
3391  newStop.parking = parking;
3392  newStop.index = STOP_INDEX_FIT;
3393  newStop.lane = bs->getLane().getID();
3394  newStop.endPos = bs->getEndLanePosition();
3395  newStop.startPos = bs->getBeginLanePosition();
3396  const bool result = addStop(newStop, errorMsg);
3397  if (myLane != 0) {
3398  updateBestLanes(true);
3399  }
3400  return result;
3401 }
3402 
3403 
3404 bool
3406  if (isStopped()) {
3410  }
3414  }
3415  // we have waited long enough and fulfilled any passenger-requirements
3416  if (myStops.front().busstop != 0) {
3417  // inform bus stop about leaving it
3418  myStops.front().busstop->leaveFrom(this);
3419  }
3420  // we have waited long enough and fulfilled any container-requirements
3421  if (myStops.front().containerstop != 0) {
3422  // inform container stop about leaving it
3423  myStops.front().containerstop->leaveFrom(this);
3424  }
3425  // the current stop is no longer valid
3427  myStops.pop_front();
3428  // do not count the stopping time towards gridlock time.
3429  // Other outputs use an independent counter and are not affected.
3430  myWaitingTime = 0;
3431  // maybe the next stop is on the same edge; let's rebuild best lanes
3432  updateBestLanes(true);
3433  // continue as wished...
3435  return true;
3436  }
3437  return false;
3438 }
3439 
3440 
3443  return myStops.front();
3444 }
3445 
3446 
3449  if (myInfluencer == 0) {
3450  myInfluencer = new Influencer();
3451  }
3452  return *myInfluencer;
3453 }
3454 
3455 
3456 const MSVehicle::Influencer*
3458  return myInfluencer;
3459 }
3460 
3461 
3462 SUMOReal
3464  if (myInfluencer != 0) {
3465  return myInfluencer->getOriginalSpeed();
3466  }
3467  return myState.mySpeed;
3468 }
3469 
3470 
3471 int
3473  if (hasInfluencer()) {
3475  MSNet::getInstance()->getCurrentTimeStep(),
3476  myLane->getEdge(),
3477  getLaneIndex(),
3478  state);
3479  }
3480  return state;
3481 }
3482 
3483 
3484 void
3486  myCachedPosition = xyPos;
3487 }
3488 
3489 #endif
3490 
3491 bool
3493  return myInfluencer != 0 && myInfluencer->isVTDControlled();
3494 }
3495 
3496 
3497 
3498 void
3501  // here starts the vehicle internal part (see loading)
3502  std::vector<SUMOTime> internals;
3503  internals.push_back(myDeparture);
3504  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
3505  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
3509  out.closeTag();
3510 }
3511 
3512 
3513 void
3514 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
3515  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
3516  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
3517  }
3518  int routeOffset;
3519  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
3520  bis >> myDeparture;
3521  bis >> routeOffset;
3522  if (hasDeparted()) {
3523  myDeparture -= offset;
3524  myCurrEdge += routeOffset;
3525  }
3529  // no need to reset myCachedPosition here since state loading happens directly after creation
3530 }
3531 
3532 /****************************************************************************/
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1020
void setAngle(SUMOReal angle)
Set a custom vehicle angle in rad.
Definition: MSVehicle.cpp:802
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1387
The link is a partial left direction.
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
Definition: MSVehicle.cpp:3492
#define DIST2SPEED(x)
Definition: SUMOTime.h:57
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:257
const MSVehicleType * myType
This Vehicle&#39;s type.
void replaceVehicleType(MSVehicleType *type)
Replaces the current vehicle type by the one given.
Definition: MSVehicle.cpp:3088
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:285
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:2288
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:567
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:2775
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:81
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1334
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:1368
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:1147
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:116
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:752
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1396
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:348
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:49
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1558
SUMOReal backPos() const
back Position of this state
Definition: MSVehicle.h:126
MoveReminderCont myMoveReminders
Current lane&#39;s move reminder.
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:1386
std::string containerstop
(Optional) container stop if one is assigned to the stop
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:976
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1384
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1414
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1282
const MSEdge * getInternalFollower() const
Returns the lane&#39;s follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1215
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1389
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:402
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:700
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1407
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1379
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:3103
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:3119
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:3442
A lane area vehicles can halt at.
const std::vector< SUMOReal > & getShadowFurtherLanesPosLat() const
SUMOReal getMaxSpeed() const
Returns the maximum speed.
DriveItemVector myLFLinkLanes
Definition: MSVehicle.h:1487
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.h:111
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:2371
bool resumeFromStopping()
Definition: MSVehicle.cpp:3405
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1417
bool hasInfluencer() const
Definition: MSVehicle.h:1301
SUMOTime duration
The stopping duration.
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.
SUMOTime myLastVTDAccess
Definition: MSVehicle.h:1271
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:626
SUMOReal getImpatience() const
Returns this vehicles impatience.
void setBlinkerInformation()
Definition: MSVehicle.cpp:3040
#define M_PI
Definition: angles.h:37
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:2429
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:2987
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1480
virtual void drawOutsideNetwork(bool) const
register vehicle for drawing while outside the network
Definition: MSVehicle.h:1372
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links ...
Definition: MSVehicle.cpp:3219
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1404
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:324
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:3463
The vehicle arrived at a junction.
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:412
bool isVTDControlled() const
Definition: MSVehicle.cpp:448
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:481
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)
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:475
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:761
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:89
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:601
The position is given.
The car-following model abstraction.
Definition: MSCFModel.h:59
bool myConsiderMaxAcceleration
Whether the maximum acceleration shall be regarded.
Definition: MSVehicle.h:1253
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
int getShadowDirection() const
return the direction in which the current shadow lane lies
The link is a 180 degree turn.
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:59
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:1476
SUMOReal currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:620
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1398
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:610
#define STOPPING_PLACE_OFFSET
Definition: MSVehicle.cpp:91
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1105
SUMOReal implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:503
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2929
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1259
SUMOReal getWidth() const
Returns the lane&#39;s width.
Definition: MSLane.h:491
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:746
const MSLane * getBackLane() const
Definition: MSVehicle.cpp:1901
void registerEmergencyStop()
register emergency stop
SUMOReal getEndLanePosition() const
Returns the end position of this stop.
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:120
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:159
T MAX2(T a, T b)
Definition: StdDefs.h:75
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:89
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:208
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:984
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
#define DEBUG_COND
Definition: MSVehicle.cpp:89
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:894
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:459
SUMOReal estimateLeaveSpeed(const MSLink *const link, const SUMOReal vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1497
SUMOTime until
The time at which the vehicle may continue its journey.
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1376
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:136
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:720
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:2917
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:1559
int getLaneIndex() const
Definition: MSVehicle.cpp:3096
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:191
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:2879
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle&#39;s end speed shall be chosen.
SUMOReal getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MSVehicle.h:350
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
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1422
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:1469
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1012
A storage for edge travel times and efforts.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
Wants go to the left.
const Position geometryPositionAtOffset(SUMOReal offset, SUMOReal lateralOffset=0) const
Definition: MSLane.h:439
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:618
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:828
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:63
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
T MAX3(T a, T b, T c)
Definition: StdDefs.h:89
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
#define abs(a)
Definition: polyfonts.c:67
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:2321
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
SUMOReal myStopDist
distance to the next stop or -1 if there is none
Definition: MSVehicle.h:1428
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The simulated network and simulation perfomer.
Definition: MSNet.h:93
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:1911
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:740
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:147
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:2462
#define SIMTIME
Definition: SUMOTime.h:70
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1561
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:375
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:95
The lane is given.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
Right blinker lights are switched on.
Definition: MSVehicle.h:942
PositionVector reverse() const
reverse position vector
SUMOReal nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:624
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:707
SUMOReal getLateralPositionOnLane() const
Get the vehicle&#39;s lateral position on the lane.
Definition: MSVehicle.h:375
SUMOReal getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:2953
The vehicles starts to stop.
Definition: MSNet.h:555
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
SUMOTime getMemorySize() const
Definition: MSVehicle.h:180
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:1241
The state of a link.
int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:3033
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:152
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:269
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:130
static std::vector< MSTransportable * > myEmptyTransportableVector
Definition: MSVehicle.h:1392
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)
MSLane * lane
The described lane.
Definition: MSVehicle.h:616
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:2048
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:585
Left blinker lights are switched on.
Definition: MSVehicle.h:944
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1883
#define max(a, b)
Definition: polyfonts.c:65
void setEmergencyBrakeRedLight(bool value)
Sets whether red lights shall be a reason to brake.
Definition: MSVehicle.cpp:418
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time.
Definition: MSCFModel.h:234
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:808
SUMOReal implicitSpeedVTD(const MSVehicle *veh, SUMOReal oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:488
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:684
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:3200
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:1722
The vehicle got a new route.
Definition: MSNet.h:549
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:706
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:789
vehicle want&#39;s to change to right lane
Definition: MSVehicle.h:212
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:96
void removeApproachingInformation(DriveItemVector &lfLinks) const
unregister approach from all upcoming links
Definition: MSVehicle.cpp:3207
The action is urgent (to be defined by lc-model)
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:728
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:152
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:3272
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Encapsulated SAX-Attributes.
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:699
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:206
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the subpart of best lanes that describes the vehicle&#39;s current lane and their successors...
Definition: MSVehicle.cpp:2808
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:1287
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:663
SUMOReal myAngle
the angle (
Definition: MSVehicle.h:1425
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:2480
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:705
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:754
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
Position myCachedPosition
Definition: MSVehicle.h:1430
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:307
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:1494
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:724
SUMOReal myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1244
std::vector< SUMOReal > myFurtherLanesPosLat
Definition: MSVehicle.h:1408
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:860
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1395
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:65
const int STOP_INDEX_END
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:3285
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:988
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:1006
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1256
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:1473
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1382
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1186
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1420
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:771
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:1565
void resetRoutePosition(int index)
Definition: MSVehicle.cpp:675
const std::vector< MSTransportable * > & getContainers() const
retrieve riding containers
Definition: MSVehicle.cpp:3017
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1390
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:2862
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:1538
Position positionAtOffset(SUMOReal pos, SUMOReal lateralOffset=0) const
Returns the position at the given length.
SUMOReal getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:2028
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:736
bool isRoundabout() const
Definition: MSEdge.h:632
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:402
T MIN2(T a, T b)
Definition: StdDefs.h:69
The link is a (hard) right direction.
The action is needed to follow the route (navigational lc)
virtual SUMOReal stopSpeed(const MSVehicle *const veh, const SUMOReal speed, SUMOReal gap2pred) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...
#define POSITION_EPS
Definition: config.h:187
The brake lights are on.
Definition: MSVehicle.h:948
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSVehicle.h:1511
void addTransportable(MSTransportable *transportable)
Add a passenger.
A blue emergency light is on.
Definition: MSVehicle.h:964
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:614
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:3514
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:591
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:750
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
render as a van
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:186
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:386
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:340
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:2854
void getSubLanes(const MSVehicle *veh, SUMOReal latOffset, int &rightmost, int &leftmost) const
#define DEG2RAD(x)
Definition: GeomHelper.h:45
render as a passenger vehicle
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1372
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:55
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1280
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:95
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:93
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:1198
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:205
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:994
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1278
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:2474
int getRoutePosition() const
Definition: MSVehicle.cpp:669
void setVTDControlled(Position xyPos, MSLane *l, SUMOReal pos, SUMOReal posLat, SUMOReal angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:435
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:138
int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:3027
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:628
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2959
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSVehicle.cpp:3007
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:91
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:3499
SUMOVehicleShape getGuiShape() const
Get this vehicle type&#39;s shape.
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:1214
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2935
SUMOReal getRightSideOnLane() const
Get the vehicle&#39;s lateral position on the lane:
Definition: MSVehicle.cpp:3113
std::string lane
The lane to stop at.
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1262
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:696
Influencer()
Constructor.
Definition: MSVehicle.cpp:225
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
ConstMSEdgeVector myVTDRoute
Definition: MSVehicle.h:1270
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:2413
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos, MSMoveReminder::Notification notification, SUMOReal posLat=0)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:743
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:178
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:2941
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2923
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:2791
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:3076
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:3157
std::vector< const MSLane * > getOutgoingLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:1934
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1226
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:210
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:242
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:246
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:249
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:3448
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:1200
LaneChangeMode mySublaneLC
changing to the prefered lateral alignment
Definition: MSVehicle.h:1284
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:169
std::vector< std::pair< SUMOTime, SUMOReal > > mySpeedTimeLine
The velocity time line to apply.
Definition: MSVehicle.h:1238
SUMOReal getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:750
void setNoShadowPartialOccupator(MSLane *lane)
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:742
The link has yellow light, may pass.
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:406
void setVTDState(Position xyPos)
sets position outside the road network
Definition: MSVehicle.cpp:3485
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:187
SUMOReal occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:622
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:3125
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1411
void resetChanged()
reset the flag whether a vehicle already moved to false
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:630
SUMOReal interpolateLanePosToGeometryPos(SUMOReal lanePos) const
Definition: MSLane.h:433
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:301
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:748
void onDepart()
Called when the vehicle is inserted into the network.
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2947
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:1504
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:97
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:738
static SUMOReal gLateralResolution
Definition: MSGlobals.h:84
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:394
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:813
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false, bool check=false)
Replaces the current route by the given edges.
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:1137
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:722
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:185
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:3355
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
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:557
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:410
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:2022
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:773
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:424
SUMOReal myPos
the stored position
Definition: MSVehicle.h:133
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:1000
SUMOReal getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MSVehicle.cpp:1962
waitingIntervalList myWaitingIntervals
Definition: MSVehicle.h:196
std::vector< DriveProcessItem > DriveItemVector
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1486
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:422
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:734
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:232
SUMOReal getOppositePos(SUMOReal pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:2438
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:787
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:214
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
SUMOReal myPosLat
the stored lateral position
Definition: MSVehicle.h:139
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:213
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1003
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:995
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:2965
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1391
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2846
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:160
SUMOReal myBackPos
the stored back position
Definition: MSVehicle.h:144
int getSpeedMode() const
return the current speed mode
Definition: MSVehicle.cpp:259
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:166
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:253
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:568
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:1445
No information given; use default.
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:453
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:455
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1247
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:447
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:3472
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:2256
The edge is an internal edge.
Definition: MSEdge.h:97
public emergency vehicles
render as a wagon passenger vehicle ("Combi")
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2907
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
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:302
SUMOReal getBackPositionOnLane() const
Get the vehicle&#39;s position relative to its current lane.
Definition: MSVehicle.h:367
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:3322
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:732
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:726
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:684
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:730
Back-at-zero position.
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1276
The link has red light (must brake) but indicates upcoming green.
bool isVTDAffected(SUMOTime t) const
Definition: MSVehicle.cpp:454
Interface for lane-change models.
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2836
SUMOReal posLat() const
Lateral Position of this state (m relative to the centerline of the lane).
Definition: MSVehicle.h:121
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:243
bool myConsiderSafeVelocity
Whether the safe velocity shall be regarded.
Definition: MSVehicle.h:1250
void append(const PositionVector &v, SUMOReal sameThreshold=2.0)
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:400
SUMOTime myDeparture
The real departure time.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:78
static const SUMOTime NOT_YET_DEPARTED
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
Definition: MSVehicle.h:1401
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:744
static const Position INVALID
Definition: Position.h:261
The vehicle is being teleported.
SUMOReal getRightSideOnEdge() const
Definition: MSLane.h:886
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:836