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-2015 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>
60 #include <microsim/MSGlobals.h>
61 #include "MSStoppingPlace.h"
64 #include "MSEdgeWeightsStorage.h"
66 #include "MSMoveReminder.h"
68 #include "MSPersonControl.h"
69 #include "MSContainer.h"
70 #include "MSContainerControl.h"
71 #include "MSLane.h"
72 #include "MSJunction.h"
73 #include "MSVehicle.h"
74 #include "MSEdge.h"
75 #include "MSVehicleType.h"
76 #include "MSNet.h"
77 #include "MSRoute.h"
78 #include "MSLinkCont.h"
79 
80 #ifdef HAVE_INTERNAL
81 #include <mesosim/MESegment.h>
82 #include <mesosim/MELoop.h>
83 #include "MSGlobals.h"
84 #endif
85 
86 #ifdef CHECK_MEMORY_LEAKS
87 #include <foreign/nvwa/debug_new.h>
88 #endif // CHECK_MEMORY_LEAKS
89 
90 // enable here and in utils/gui/globjects/GUIGLObjectPopupMenu.cpp
91 //#define DEBUG_VEHICLE_GUI_SELECTION 1
92 
93 #define BUS_STOP_OFFSET 0.5
94 
95 #define CRLL_LOOK_AHEAD 5
96 
97 // @todo Calibrate with real-world values / make configurable
98 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
99 
100 // ===========================================================================
101 // static value definitions
102 // ===========================================================================
103 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
104 
105 
106 // ===========================================================================
107 // method definitions
108 // ===========================================================================
109 /* -------------------------------------------------------------------------
110  * methods of MSVehicle::State
111  * ----------------------------------------------------------------------- */
113  myPos = state.myPos;
114  mySpeed = state.mySpeed;
115 }
116 
117 
120  myPos = state.myPos;
121  mySpeed = state.mySpeed;
122  return *this;
123 }
124 
125 
126 bool
128  return (myPos != state.myPos ||
129  mySpeed != state.mySpeed);
130 }
131 
132 
133 SUMOReal
135  return myPos;
136 }
137 
138 
140  myPos(pos), mySpeed(speed) {}
141 
142 
143 /* -------------------------------------------------------------------------
144  * methods of MSVehicle::Influencer
145  * ----------------------------------------------------------------------- */
146 #ifndef NO_TRACI
148  mySpeedAdaptationStarted(true),
149  myConsiderSafeVelocity(true),
150  myConsiderMaxAcceleration(true),
151  myConsiderMaxDeceleration(true),
152  myRespectJunctionPriority(true),
153  myEmergencyBrakeRedLight(true),
154  myAmVTDControlled(false),
155  myLastVTDAccess(-TIME2STEPS(20)),
156  myStrategicLC(LC_NOCONFLICT),
157  myCooperativeLC(LC_NOCONFLICT),
158  mySpeedGainLC(LC_NOCONFLICT),
159  myRightDriveLC(LC_NOCONFLICT),
160  myTraciLaneChangePriority(LCP_URGENT)
161 {}
162 
163 
165 
166 
167 void
168 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, SUMOReal> >& speedTimeLine) {
170  mySpeedTimeLine = speedTimeLine;
171 }
172 
173 
174 void
175 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, unsigned int> >& laneTimeLine) {
176  myLaneTimeLine = laneTimeLine;
177 }
178 
179 
180 SUMOReal
182  // keep original speed
183  myOriginalSpeed = speed;
184  // remove leading commands which are no longer valid
185  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
186  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
187  }
188  // do nothing if the time line does not apply for the current time
189  if (mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first) {
190  return speed;
191  }
192  // compute and set new speed
194  mySpeedTimeLine[0].second = speed;
196  }
197  currentTime += DELTA_T;
198  const SUMOReal td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
199  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
201  speed = MIN2(speed, vSafe);
202  }
204  speed = MIN2(speed, vMax);
205  }
207  speed = MAX2(speed, vMin);
208  }
209  return speed;
210 }
211 
212 
213 int
214 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const unsigned int currentLaneIndex, int state) {
215  // remove leading commands which are no longer valid
216  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
217  myLaneTimeLine.erase(myLaneTimeLine.begin());
218  }
219  ChangeRequest changeRequest = REQUEST_NONE;
220  // do nothing if the time line does not apply for the current time
221  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
222  const unsigned int destinationLaneIndex = myLaneTimeLine[1].second;
223  if (destinationLaneIndex < (unsigned int)currentEdge.getLanes().size()) {
224  if (currentLaneIndex > destinationLaneIndex) {
225  changeRequest = REQUEST_RIGHT;
226  } else if (currentLaneIndex < destinationLaneIndex) {
227  changeRequest = REQUEST_LEFT;
228  } else {
229  changeRequest = REQUEST_HOLD;
230  }
231  }
232  }
233  // check whether the current reason shall be canceled / overridden
234  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
235  // flags for the current reason
236  LaneChangeMode mode = LC_NEVER;
237  if ((state & LCA_STRATEGIC) != 0) {
238  mode = myStrategicLC;
239  } else if ((state & LCA_COOPERATIVE) != 0) {
240  mode = myCooperativeLC;
241  } else if ((state & LCA_SPEEDGAIN) != 0) {
242  mode = mySpeedGainLC;
243  } else if ((state & LCA_KEEPRIGHT) != 0) {
244  mode = myRightDriveLC;
245  } else if ((state & LCA_TRACI) != 0) {
246  mode = LC_NEVER;
247  } else {
248  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
249  }
250  if (mode == LC_NEVER) {
251  // cancel all lcModel requests
252  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
253  state &= ~LCA_URGENT;
254  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
255  if (
256  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
257  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
258  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
259  // cancel conflicting lcModel request
260  state &= ~LCA_WANTS_LANECHANGE_OR_STAY;
261  state &= ~LCA_URGENT;
262  }
263  } else if (mode == LC_ALWAYS) {
264  // ignore any TraCI requests
265  return state;
266  }
267  }
268  // apply traci requests
269  if (changeRequest == REQUEST_NONE) {
270  return state;
271  } else {
272  state |= LCA_TRACI;
273  // security checks
275  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
276  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
277  }
278  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
279  state |= LCA_URGENT;
280  }
281  switch (changeRequest) {
282  case REQUEST_HOLD:
283  return state | LCA_STAY;
284  case REQUEST_LEFT:
285  return state | LCA_LEFT;
286  case REQUEST_RIGHT:
287  return state | LCA_RIGHT;
288  default:
289  throw ProcessError("should not happen");
290  }
291  }
292 }
293 
294 
295 SUMOReal
297  assert(myLaneTimeLine.size() >= 2);
298  assert(currentTime >= myLaneTimeLine[0].first);
299  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
300 }
301 
302 
303 void
305  myConsiderSafeVelocity = value;
306 }
307 
308 
309 void
312 }
313 
314 
315 void
318 }
319 
320 
321 void
324 }
325 
326 
327 void
329  myEmergencyBrakeRedLight = value;
330 }
331 
332 
333 void
335  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
336  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
337  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
338  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
339  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
340 }
341 
342 
343 void
347  if (myVTDRoute.size() != 0) {
348  v->replaceRouteEdges(myVTDRoute, true);
349  }
351  if (myVTDPos > myVTDLane->getLength()) {
353  }
355  v->updateBestLanes();
356  myAmVTDControlled = false;
357 }
358 
359 SUMOReal
361  const SUMOReal dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
362  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
363  return oldSpeed;
364  } else {
365  return DIST2SPEED(dist);
366  }
367 }
368 
369 SUMOReal
371  const SUMOReal dist = veh->getDistanceToPosition(myVTDPos, &myVTDLane->getEdge());
372  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
373  return 0;
374  } else {
375  return dist;
376  }
377 }
378 
379 #endif
380 
381 
382 /* -------------------------------------------------------------------------
383  * MSVehicle-methods
384  * ----------------------------------------------------------------------- */
386  delete myEdgeWeights;
387  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
388  (*i)->resetPartialOccupation(this);
389  }
390  delete myLaneChangeModel; // still needed when calling resetPartialOccupation (getShadowLane)
391  myFurtherLanes.clear();
392  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
393  if ((*i).myLink != 0) {
394  (*i).myLink->removeApproaching(this);
395  }
396  }
397  //
398  if (myType->amVehicleSpecific()) {
399  delete myType;
400  }
401 #ifndef NO_TRACI
402  delete myInfluencer;
403 #endif
404 }
405 
406 
408  const MSVehicleType* type, const SUMOReal speedFactor) :
409  MSBaseVehicle(pars, route, type, speedFactor),
410  myWaitingTime(0),
411  myState(0, 0), //
412  myLane(0),
415  myPersonDevice(0),
417  myAcceleration(0),
418  mySignals(0),
419  myAmOnNet(false),
422  myHaveToWaitOnNextLink(false),
423  myCachedPosition(Position::INVALID),
424  myEdgeWeights(0)
425 #ifndef NO_TRACI
426  , myInfluencer(0)
427 #endif
428 {
429  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
430  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
431  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
432  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
433  }
434  } else {
435  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
436  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
437  }
438  }
439  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
440  throw ProcessError("Departure speed for vehicle '" + pars->id +
441  "' is too high for the vehicle type '" + type->getID() + "'.");
442  }
443  }
446 }
447 
448 
449 void
453  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
454  if ((*i).myLink != 0) {
455  (*i).myLink->removeApproaching(this);
456  }
457  }
458  leaveLane(reason);
459 }
460 
461 
462 // ------------ interaction with the route
463 bool
465  return myCurrEdge == myRoute->end() - 1 && (myStops.empty() || myStops.front().edge != myCurrEdge)
467 }
468 
469 
470 bool
471 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
472  const ConstMSEdgeVector& edges = newRoute->getEdges();
473  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
474  if (!onInit && !newRoute->contains(*myCurrEdge)) {
475  return false;
476  }
477 
478  // rebuild in-vehicle route information
479  if (onInit) {
480  myCurrEdge = newRoute->begin();
481  } else {
482  myCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);
483  }
484  // check whether the old route may be deleted (is not used by anyone else)
485  newRoute->addReference();
486  myRoute->release();
487  // assign new route
488  myRoute = newRoute;
491  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
492  // update arrival definition
494  // save information that the vehicle was rerouted
497  // recheck old stops
498  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
499  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
500  iter = myStops.erase(iter);
501  } else {
502  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
503  ++iter;
504  }
505  }
506  // add new stops
507  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
508  std::string error;
509  addStop(*i, error);
510  if (error != "") {
511  WRITE_WARNING(error);
512  }
513  }
514  return true;
515 }
516 
517 
518 bool
519 MSVehicle::willPass(const MSEdge* const edge) const {
520  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
521 }
522 
523 
524 unsigned int
526  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
527 }
528 
529 
530 void
531 MSVehicle::resetRoutePosition(unsigned int index) {
532  myCurrEdge = myRoute->begin() + index;
533  // !!! hack
534  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
535 }
536 
537 
538 
541  return _getWeightsStorage();
542 }
543 
544 
547  return _getWeightsStorage();
548 }
549 
550 
553  if (myEdgeWeights == 0) {
555  }
556  return *myEdgeWeights;
557 }
558 
559 
560 // ------------ Interaction with move reminders
561 void
563  // This erasure-idiom works for all stl-sequence-containers
564  // See Meyers: Effective STL, Item 9
565  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
566  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
567 #ifdef _DEBUG
568  if (myTraceMoveReminders) {
569  traceMoveReminder("notifyMove", rem->first, rem->second, false);
570  }
571 #endif
572  rem = myMoveReminders.erase(rem);
573  } else {
574 #ifdef _DEBUG
575  if (myTraceMoveReminders) {
576  traceMoveReminder("notifyMove", rem->first, rem->second, true);
577  }
578 #endif
579  ++rem;
580  }
581  }
582 }
583 
584 
585 void
587  // save the old work reminders, patching the position information
588  // add the information about the new offset to the old lane reminders
589  const SUMOReal oldLaneLength = myLane->getLength();
590  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
591  rem->second += oldLaneLength;
592 #ifdef _DEBUG
593  if (myTraceMoveReminders) {
594  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
595  }
596 #endif
597  }
598  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
599  addReminder(*rem);
600  }
601 }
602 
603 
604 // ------------ Other getter methods
605 SUMOReal
607  if (myLane == 0) {
608  return 0;
609  }
610  const SUMOReal lp = getPositionOnLane();
612  return myLane->getShape().slopeDegreeAtOffset(gp);
613 }
614 
615 
616 Position
617 MSVehicle::getPosition(const SUMOReal offset) const {
618  if (myLane == 0) {
619  return Position::INVALID;
620  }
621  if (isParking()) {
622  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
625  }
626  const bool changingLanes = getLaneChangeModel().isChangingLanes();
627  if (offset == 0. && !changingLanes) {
630  }
631  return myCachedPosition;
632  }
634  if (changingLanes) {
636  const SUMOReal dist = getLaneChangeModel().getLaneChangeCompletion() * result.distanceTo(other);
637  if (getLaneChangeModel().isLaneChangeMidpointPassed()) {
638  return PositionVector::positionAtOffset(other, result, dist);
639  }
640  return PositionVector::positionAtOffset(result, other, dist);
641  }
642  return result;
643 }
644 
645 
646 const MSEdge*
648  // too close to the next junction, so avoid an emergency brake here
649  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
651  return *(myCurrEdge + 1);
652  }
653 #ifdef HAVE_INTERNAL_LANES
654  if (myLane != 0) {
655  return myLane->getInternalFollower();
656  }
657 #endif
658  return *myCurrEdge;
659 }
660 
661 
662 SUMOReal
664  Position p1;
665  Position p2;
666  if (isParking()) {
668  }
670  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
672  } else {
673  p1 = getPosition();
674  }
675  if (myState.myPos >= myType->getLength()) {
676  // vehicle is fully on the new lane
678  } else {
679  p2 = myFurtherLanes.size() > 0
680  ? myFurtherLanes.back()->geometryPositionAtOffset(myFurtherLanes.back()->getPartialOccupatorEnd())
681  : myLane->getShape().front();
682  if (getLaneChangeModel().isChangingLanes() && myFurtherLanes.size() > 0 && getLaneChangeModel().getShadowLane(myFurtherLanes.back()) == 0) {
683  // special case where the target lane has no predecessor
684  p2 = myLane->getShape().front();
685  }
686  }
687  SUMOReal result = (p1 != p2 ? p2.angleTo2D(p1) :
691  result += getLaneChangeModel().getLaneChangeDirection() * DEG2RAD(angleOffset);
692  }
693  return result;
694 }
695 
696 
697 // ------------
698 bool
699 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
700  Stop stop;
701  stop.lane = MSLane::dictionary(stopPar.lane);
703  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
704  return false;
705  }
706  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
708  stop.startPos = stopPar.startPos;
709  stop.endPos = stopPar.endPos;
710  stop.duration = stopPar.duration;
711  stop.until = stopPar.until;
712  stop.timeToBoardNextPerson = 0;
713  stop.timeToLoadNextContainer = 0;
714  stop.awaitedPersons = stopPar.awaitedPersons;
715  stop.awaitedContainers = stopPar.awaitedContainers;
716  if (stop.until != -1) {
717  stop.until += untilOffset;
718  }
719  stop.triggered = stopPar.triggered;
720  stop.containerTriggered = stopPar.containerTriggered;
721  stop.parking = stopPar.parking;
722  stop.reached = false;
723  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
724  if (stop.busstop != 0) {
725  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
726  } else {
727  errorMsg = "Stop";
728  }
729  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
730  return false;
731  }
732  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
733  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
734  }
735  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
736  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
737  }
738  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
739  MSRouteIterator prevStopEdge = myCurrEdge;
740  SUMOReal prevStopPos = myState.myPos;
741  // where to insert the stop
742  std::list<Stop>::iterator iter = myStops.begin();
743  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
744  if (myStops.size() > 0) {
745  prevStopEdge = myStops.back().edge;
746  prevStopPos = myStops.back().endPos;
747  iter = myStops.end();
748  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
749  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
750  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
751  }
752  }
753  } else {
754  if (stopPar.index == STOP_INDEX_FIT) {
755  while (iter != myStops.end() && (iter->edge < stop.edge ||
756  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
757  prevStopEdge = iter->edge;
758  prevStopPos = iter->endPos;
759  ++iter;
760  }
761  } else {
762  int index = stopPar.index;
763  while (index > 0) {
764  prevStopEdge = iter->edge;
765  prevStopPos = iter->endPos;
766  ++iter;
767  --index;
768  }
769  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
770  }
771  }
772  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
773  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
774  if (stop.busstop != 0) {
775  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
776  } else {
777  errorMsg = "Stop";
778  }
779  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
780  return false;
781  }
782  // David.C:
783  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
784  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
785  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
786  return false;
787  }
788  if (!hasDeparted() && myCurrEdge == stop.edge) {
789  SUMOReal pos = -1;
791  pos = myParameter->departPos;
792  if (pos < 0.) {
793  pos += (*myCurrEdge)->getLength();
794  }
795  }
797  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
798  }
799  if (pos > stop.endPos) {
800  if (stop.busstop != 0) {
801  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
802  } else {
803  errorMsg = "Stop";
804  }
805  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
806  return false;
807  }
808  }
809  if (iter != myStops.begin()) {
810  std::list<Stop>::iterator iter2 = iter;
811  iter2--;
812  if (stop.until >= 0 && iter2->until > stop.until) {
813  if (stop.busstop != 0) {
814  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
815  } else {
816  errorMsg = "Stop";
817  }
818  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
819  }
820  }
821  myStops.insert(iter, stop);
822  return true;
823 }
824 
825 
826 bool
828  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
829 }
830 
831 
832 bool
834  return isStopped() && myStops.begin()->parking;
835 }
836 
837 
838 bool
840  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
841 }
842 
843 
844 bool
846  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
847 }
848 
849 
850 SUMOReal
852  if (myStops.empty()) {
853  // no stops; pass
854  return currentVelocity;
855  }
856  Stop& stop = myStops.front();
857  if (stop.reached) {
858  // ok, we have already reached the next stop
859  // any waiting persons may board now
860  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
861  boarded &= stop.awaitedPersons.size() == 0;
862  // load containers
863  bool loaded = MSNet::getInstance()->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
864  loaded &= stop.awaitedContainers.size() == 0;
865  if (boarded) {
866  if (stop.busstop != 0) {
867  const std::vector<MSTransportable*>& persons = myPersonDevice->getPersons();
868  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
869  stop.busstop->removeTransportable(*i);
870  }
871  }
872  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
873  stop.triggered = false;
877  }
878  }
879  if (loaded) {
880  if (stop.containerstop != 0) {
881  const std::vector<MSTransportable*>& containers = myContainerDevice->getContainers();
882  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
884  }
885  }
886  // the triggering condition has been fulfilled
887  stop.containerTriggered = false;
891  }
892  }
893  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
895  } else {
896  // we have to wait some more time
898  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
901  }
903  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
906  }
907  stop.duration -= DELTA_T;
908  return 0;
909  }
910  } else {
911  // is the next stop on the current lane?
912  if (stop.edge == myCurrEdge) {
913  // get the stopping position
914  SUMOReal endPos = stop.endPos;
915  bool busStopsMustHaveSpace = true;
916  if (stop.busstop != 0) {
917  // on bus stops, we have to wait for free place if they are in use...
918  endPos = stop.busstop->getLastFreePos(*this);
919  // at least half the bus has to fit on non-empty bus stops
920  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
921  busStopsMustHaveSpace = false;
922  }
923  }
924  bool containerStopsMustHaveSpace = true;
925  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
926  if (stop.containerstop != 0) {
927  // on container stops, we have to wait for free place if they are in use...
928  endPos = stop.containerstop->getLastFreePos(*this);
929  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
930  containerStopsMustHaveSpace = false;
931  }
932  }
933  // we use the same offset for container stops as for bus stops. we might have to change it at some point!
934  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace
935  && containerStopsMustHaveSpace && myLane == stop.lane) {
936  // ok, we may stop (have reached the stop)
937  stop.reached = true;
938  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
940  // compute stopping time
941  if (stop.until >= 0) {
942  if (stop.duration == -1) {
944  } else {
946  }
947  }
948  if (stop.busstop != 0) {
949  // let the bus stop know the vehicle
951  }
952  if (stop.containerstop != 0) {
953  // let the container stop know the vehicle
955  }
956  }
957  // decelerate
958  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos());
959  }
960  }
961  return currentVelocity;
962 }
963 
964 
965 const ConstMSEdgeVector
967  ConstMSEdgeVector result;
968  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
969  result.push_back(*iter->edge);
970  }
971  return result;
972 }
973 
974 
975 void
976 MSVehicle::planMove(const SUMOTime t, const MSVehicle* pred, const SUMOReal lengthsInFront) {
978  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
980 }
981 
982 
983 void
984 MSVehicle::planMoveInternal(const SUMOTime t, const MSVehicle* pred, DriveItemVector& lfLinks) const {
985 #ifdef DEBUG_VEHICLE_GUI_SELECTION
986  if (gDebugSelectedVehicle == getID()) {
987  int bla = 0;
988  }
989 #endif
990  // remove information about approaching links, will be reset later in this step
991  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
992  if ((*i).myLink != 0) {
993  (*i).myLink->removeApproaching(this);
994  }
995  }
996  lfLinks.clear();
997  //
998  const MSCFModel& cfModel = getCarFollowModel();
999  const SUMOReal vehicleLength = getVehicleType().getLength();
1000  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
1001  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
1002  // vBeg is the initial maximum velocity of this vehicle in this step
1003  SUMOReal v = MIN2(maxV, laneMaxV);
1004 #ifndef NO_TRACI
1005  if (myInfluencer != 0) {
1006  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
1007  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
1008  }
1009 #endif
1010 
1011  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
1012  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
1013  assert(bestLaneConts.size() > 0);
1014 #ifdef HAVE_INTERNAL_LANES
1015  bool hadNonInternal = false;
1016 #else
1017  bool hadNonInternal = true;
1018 #endif
1019  SUMOReal seen = myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1020  SUMOReal seenNonInternal = 0;
1021  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1022  unsigned int view = 0;
1023  DriveProcessItem* lastLink = 0;
1024  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
1025  SUMOReal gap = 0;
1026  if (pred != 0) {
1027  if (pred == myLane->getPartialOccupator()) {
1029  } else {
1031  }
1032  }
1033  std::pair<const MSVehicle*, SUMOReal> leaderInfo = std::make_pair(pred, gap);
1034  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1035  const MSLane* lane = myLane;
1036  while (true) {
1037  // check leader on lane
1038  // leader is given for the first edge only
1039  adaptToLeader(leaderInfo, seen, lastLink, lane, v, vLinkPass);
1040  if (getLaneChangeModel().hasShadowVehicle()) {
1041  // also slow down for leaders on the shadowLane
1042  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1043  if (shadowLane != 0) {
1044  std::pair<const MSVehicle*, SUMOReal> shadowLeaderInfo = shadowLane->getLeader(this, lane->getLength() - seen, false);
1045  adaptToLeader(shadowLeaderInfo, seen, lastLink, shadowLane, v, vLinkPass);
1046  }
1047  }
1048 
1049  // process stops
1050  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
1051  // we are approaching a stop on the edge; must not drive further
1052  const Stop& stop = *myStops.begin();
1053  const SUMOReal endPos = stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this);
1054  const SUMOReal stopDist = seen + endPos - lane->getLength();
1055  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), stopDist);
1056  if (lastLink != 0) {
1057  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1058  }
1059  v = MIN2(v, stopSpeed);
1060  lfLinks.push_back(DriveProcessItem(v, stopDist));
1061  break;
1062  }
1063 
1064  // move to next lane
1065  // get the next link used
1066  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1067  // check whether the vehicle is on its final edge
1068  if (myCurrEdge + view + 1 == myRoute->end()) {
1070  myParameter->arrivalSpeed : laneMaxV);
1071  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1072  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1073  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1074  v = MIN2(v, va);
1075  if (lastLink != 0) {
1076  lastLink->adaptLeaveSpeed(va);
1077  }
1078  lfLinks.push_back(DriveProcessItem(v, seen));
1079  break;
1080  }
1081  // check whether the lane is a dead end
1082  if (lane->isLinkEnd(link)) {
1083  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1084  if (lastLink != 0) {
1085  lastLink->adaptLeaveSpeed(va);
1086  }
1087  v = MIN2(va, v);
1088  lfLinks.push_back(DriveProcessItem(v, seen));
1089  break;
1090  }
1091  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1092  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1093  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1094  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1095  // We distinguish 3 cases when determining the point at which a vehicle stops:
1096  // - links that require stopping: here the vehicle needs to stop close to the stop line
1097  // to ensure it gets onto the junction in the next step. Othwise the vehicle would 'forget'
1098  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1099  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1100  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1101  // to minimize the time window for passing the junction. If the
1102  // vehicle 'decides' to accelerate and cannot enter the junction in
1103  // the next step, new foes may appear and cause a collision (see #1096)
1104  // - major links: stopping point is irrelevant
1105  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1106  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1107  // check whether we need to slow down in order to finish a continuous lane change
1108  if (getLaneChangeModel().isChangingLanes()) {
1109  if ( // slow down to finish lane change before a turn lane
1110  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1111  // slow down to finish lane change before the shadow lane ends
1113  (*link)->getViaLaneOrLane()->getParallelLane(-getLaneChangeModel().getLaneChangeDirection()) == 0)) {
1114  // XXX maybe this is too harsh. Vehicles could cut some corners here
1115  const SUMOReal timeRemaining = STEPS2TIME((1 - getLaneChangeModel().getLaneChangeCompletion()) * MSGlobals::gLaneChangeDuration);
1116  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1117  v = MIN2(va, v);
1118  }
1119  }
1120 
1121  // - always issue a request to leave the intersection we are currently on
1122  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == 0;
1123  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
1124  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == 0;
1125  // - even if red, if we cannot break we should issue a request
1126  bool setRequest = (v > 0 && !abortRequestAfterMinor) || (leavingCurrentIntersection);
1127 
1128  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1129  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime();
1130  if (yellowOrRed && seen >= brakeDist) {
1131  // the vehicle is able to brake in front of a yellow/red traffic light
1132  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1133  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1134  break;
1135  }
1136 
1137 #ifdef HAVE_INTERNAL_LANES
1139  // we want to pass the link but need to check for foes on internal lanes
1140  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1141  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1142  // the vehicle to enter the junction first has priority
1143  const MSVehicle* leader = (*it).vehAndGap.first;
1144  if (leader == 0) {
1145  // leader is a pedestrian. Passing 'this' as a dummy.
1146  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1147  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1148  } else if ((*link)->isLeader(this, leader)) {
1149  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1150  if (lastLink != 0) {
1151  // we are not yet on the junction with this linkLeader.
1152  // at least we can drive up to the previous link and stop there
1153  v = MAX2(v, lastLink->myVLinkWait);
1154  }
1155  // if blocked by a leader from the same lane we must yield our request
1156  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1157  setRequest = false;
1158  }
1159  }
1160  }
1161  // if this is the link between two internal lanes we may have to slow down for pedestrians
1162  vLinkWait = MIN2(vLinkWait, v);
1163  }
1164 #endif
1165 
1166  if (lastLink != 0) {
1167  lastLink->adaptLeaveSpeed(laneMaxV);
1168  }
1169  SUMOReal arrivalSpeed = vLinkPass;
1170  // vehicles should decelerate when approaching a minor link
1171  // - unless they are close enough to have clear visibility and may start to accelerate again
1172  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1173  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel() && brakeDist < seen) {
1174  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1175  arrivalSpeed = cfModel.getMaxDecel() + cfModel.getMaxAccel();
1176  slowedDownForMinor = true;
1177  }
1178  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1179  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1180  const SUMOReal accel = (arrivalSpeed >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
1181  const SUMOReal accelTime = (arrivalSpeed - v) / accel;
1182  const SUMOReal accelWay = accelTime * (arrivalSpeed + v) * 0.5;
1183  const SUMOReal nonAccelWay = MAX2(SUMOReal(0), seen - accelWay);
1184  // will either drive as fast as possible and decelerate as late as possible
1185  // or accelerate as fast as possible and then hold that speed
1186  const SUMOReal nonAccelSpeed = MAX3(v, arrivalSpeed, SUMO_const_haltingSpeed);
1187  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1188  const SUMOTime arrivalTime = t - DELTA_T + TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
1189 
1190  // compute speed, time if vehicle starts braking now
1191  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1192  SUMOReal arrivalSpeedBraking = 0;
1193  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1194  if (seen < cfModel.brakeGap(v)) {
1195  // vehicle cannot come to a complete stop in time
1196  // Because we use a continuous formula for computiing the possible slow-down
1197  // we need to handle the mismatch with the discrete dynamics
1198  if (seen < v) {
1199  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1200  } else if (2 * (seen - v * cfModel.getHeadwayTime()) * -cfModel.getMaxDecel() + v * v >= 0) {
1201  arrivalSpeedBraking = estimateSpeedAfterDistance(seen - v * cfModel.getHeadwayTime(), v, -cfModel.getMaxDecel());
1202  } else {
1203  arrivalSpeedBraking = cfModel.getMaxDecel();
1204  }
1205  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1206  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1207  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1208  }
1209  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1210  arrivalTime, arrivalSpeed,
1211  arrivalTimeBraking, arrivalSpeedBraking,
1212  seen,
1213  estimateLeaveSpeed(*link, vLinkPass)));
1214 #ifdef HAVE_INTERNAL_LANES
1215  if ((*link)->getViaLane() == 0) {
1216  hadNonInternal = true;
1217  ++view;
1218  }
1219 #else
1220  ++view;
1221 #endif
1222  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1223  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD) {
1224  break;
1225  }
1226  // get the following lane
1227  lane = (*link)->getViaLaneOrLane();
1228  laneMaxV = lane->getVehicleMaxSpeed(this);
1229  // the link was passed
1230  // compute the velocity to use when the link is not blocked by other vehicles
1231  // the vehicle shall be not faster when reaching the next lane than allowed
1232  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1233  v = MIN2(va, v);
1234  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1235  seen += lane->getLength();
1236  leaderInfo = lane->getLastVehicleInformation();
1237  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
1238  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1239  lastLink = &lfLinks.back();
1240  }
1241 
1242 }
1243 
1244 
1245 void
1246 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1247  const SUMOReal seen, DriveProcessItem* const lastLink,
1248  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1249  SUMOReal distToCrossing) const {
1250  if (leaderInfo.first != 0) {
1251  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1252  if (lastLink != 0) {
1253  lastLink->adaptLeaveSpeed(vsafeLeader);
1254  }
1255  v = MIN2(v, vsafeLeader);
1256  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1257  }
1258 }
1259 
1260 
1261 SUMOReal
1262 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1263  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1264  assert(leaderInfo.first != 0);
1265  const MSCFModel& cfModel = getCarFollowModel();
1266  SUMOReal vsafeLeader = 0;
1267  if (leaderInfo.second >= 0) {
1268  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1269  } else {
1270  // the leading, in-lapping vehicle is occupying the complete next lane
1271  // stop before entering this lane
1272  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1273  }
1274  if (distToCrossing >= 0) {
1275  // drive up to the crossing point with the current link leader
1276  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1277  }
1278  return vsafeLeader;
1279 }
1280 
1281 
1282 bool
1284 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1285  if (gDebugSelectedVehicle == getID()) {
1286  int bla = 0;
1287  }
1288 #endif
1289  // get safe velocities from DriveProcessItems
1290  SUMOReal vSafe = 0; // maximum safe velocity
1291  SUMOReal vSafeZipper = std::numeric_limits<SUMOReal>::max(); // speed limit due to zipper merging
1292  SUMOReal vSafeMin = 0; // minimum safe velocity
1293  // the distance to a link which should either be crossed this step or in
1294  // front of which we need to stop
1295  SUMOReal vSafeMinDist = 0;
1296  myHaveToWaitOnNextLink = false;
1297 
1298  assert(myLFLinkLanes.size() != 0 || (myInfluencer != 0 && myInfluencer->isVTDControlled()));
1299  DriveItemVector::iterator i;
1300  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1301  MSLink* link = (*i).myLink;
1302  // the vehicle must change the lane on one of the next lanes
1303  if (link != 0 && (*i).mySetRequest) {
1304  const LinkState ls = link->getState();
1305  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1306  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1308  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1309  vSafe = (*i).myVLinkWait;
1310  myHaveToWaitOnNextLink = true;
1311  link->removeApproaching(this);
1312  break;
1313  }
1314  //
1315 #ifdef NO_TRACI
1316  const bool influencerPrio = false;
1317 #else
1318  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1319 #endif
1320  std::vector<const SUMOVehicle*> collectFoes;
1321  const bool opened = yellow || influencerPrio ||
1322  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1325  ls == LINKSTATE_ZIPPER ? &collectFoes : 0);
1326  // vehicles should decelerate when approaching a minor link
1327  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1328  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1329  vSafe = (*i).myVLinkWait;
1330  myHaveToWaitOnNextLink = true;
1331  if (ls == LINKSTATE_EQUAL) {
1332  link->removeApproaching(this);
1333  }
1334  break; // could be revalidated
1335  } else {
1336  // past the point of no return. we need to drive fast enough
1337  // to make it across the link. However, minor slowdowns
1338  // should be permissible to follow leading traffic safely
1339  // There is a problem in subsecond simulation: If we cannot
1340  // make it across the minor link in one step, new traffic
1341  // could appear on a major foe link and cause a collision
1342  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1343  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1344  }
1345  }
1346  // have waited; may pass if opened...
1347  if (opened) {
1348  vSafe = (*i).myVLinkPass;
1349  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1350  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1351  myHaveToWaitOnNextLink = true;
1352  }
1353  } else if (link->getState() == LINKSTATE_ZIPPER) {
1354  vSafeZipper = MIN2(vSafeZipper,
1355  link->getZipperSpeed(this, (*i).myDistance, (*i).myVLinkPass, (*i).myArrivalTime, &collectFoes));
1356  } else {
1357  vSafe = (*i).myVLinkWait;
1358  myHaveToWaitOnNextLink = true;
1359  if (ls == LINKSTATE_EQUAL) {
1360  link->removeApproaching(this);
1361  }
1362  break;
1363  }
1364  } else {
1365  vSafe = (*i).myVLinkWait;
1366  if (vSafe < getSpeed()) {
1367  myHaveToWaitOnNextLink = true;
1368  }
1369  break;
1370  }
1371  }
1372  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1373  // cannot drive across a link so we need to stop before it
1374  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1375  vSafeMin = 0;
1376  myHaveToWaitOnNextLink = true;
1377  }
1378  // vehicles inside a roundabout should maintain their requests
1379  if (myLane->getEdge().isRoundabout()) {
1380  myHaveToWaitOnNextLink = false;
1381  }
1382  vSafe = MIN2(vSafe, vSafeZipper);
1383 
1384  // XXX braking due to lane-changing is not registered
1385  bool braking = vSafe < getSpeed();
1386  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
1387  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1388 
1389  // vNext may be higher than vSafe without implying a bug:
1390  // - when approaching a green light that suddenly switches to yellow
1391  // - when using unregulated junctions
1392  // - when using tau < step-size
1393  // - when using unsafe car following models
1394  // - when using TraCI and some speedMode / laneChangeMode settings
1395  //if (vNext > vSafe + NUMERICAL_EPS) {
1396  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1397  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
1398  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1399  //}
1400  vNext = MAX2(vNext, (SUMOReal) 0.);
1401 #ifndef NO_TRACI
1402  if (myInfluencer != 0) {
1403  if (myInfluencer->isVTDControlled()) {
1404  vNext = myInfluencer->implicitSpeedVTD(this, myState.mySpeed);
1405  }
1407  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1408  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1409  }
1410 #endif
1411  // visit waiting time
1412  if (vNext <= SUMO_const_haltingSpeed) {
1414  braking = true;
1415  } else {
1416  myWaitingTime = 0;
1417  }
1418  if (braking) {
1420  } else {
1422  }
1423  // call reminders after vNext is set
1424  const SUMOReal pos = myState.myPos;
1425 
1426  // update position and speed
1428 
1429  SUMOReal deltaPos = SPEED2DIST(vNext);
1430 #ifndef NO_TRACI
1431  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
1432  deltaPos = myInfluencer->implicitDeltaPosVTD(this);
1433  }
1434 #endif
1435  myState.myPos += deltaPos;
1436  myState.mySpeed = vNext;
1438  std::vector<MSLane*> passedLanes;
1439  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1440  passedLanes.push_back(*i);
1441  }
1442  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1443  passedLanes.push_back(myLane);
1444  }
1445  bool moved = false;
1446  std::string emergencyReason = " for unknown reasons";
1447  // move on lane(s)
1448  if (myState.myPos <= myLane->getLength()) {
1449  // we are staying at our lane
1450  // there is no need to go over succeeding lanes
1451  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1452  } else {
1453  // we are moving at least to the next lane (maybe pass even more than one)
1454  if (myCurrEdge != myRoute->end() - 1) {
1455  MSLane* approachedLane = myLane;
1456  // move the vehicle forward
1457  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1459  MSLink* link = (*i).myLink;
1460  // check whether the vehicle was allowed to enter lane
1461  // otherwise it is decelareted and we do not need to test for it's
1462  // approach on the following lanes when a lane changing is performed
1463  // proceed to the next lane
1464  if (link != 0) {
1465  approachedLane = link->getViaLaneOrLane();
1466 #ifndef NO_TRACI
1468 #endif
1469  if (link->getState() == LINKSTATE_TL_RED) {
1470  emergencyReason = " because of a red traffic light";
1471  break;
1472  }
1473 #ifndef NO_TRACI
1474  }
1475 #endif
1476  } else {
1477  emergencyReason = " because there is no connection to the next edge";
1478  approachedLane = 0;
1479  break;
1480  }
1481  if (approachedLane != myLane && approachedLane != 0) {
1482  myState.myPos -= myLane->getLength();
1483  assert(myState.myPos > 0);
1484  enterLaneAtMove(approachedLane);
1485  myLane = approachedLane;
1486 #ifdef HAVE_INTERNAL_LANES
1488  // erase leaders when past the junction
1489  if (link->getViaLane() == 0) {
1490  link->passedJunction(this);
1491  }
1492  }
1493 #endif
1494  if (hasArrived()) {
1495  break;
1496  }
1497  if (getLaneChangeModel().isChangingLanes()) {
1498  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1499  // abort lane change
1500  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1501  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1503  }
1504  }
1505  moved = true;
1506  if (approachedLane->getEdge().isVaporizing()) {
1508  break;
1509  }
1510  }
1511  passedLanes.push_back(approachedLane);
1512  }
1513  }
1514  }
1515  // clear previously set information
1516  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1517  (*i)->resetPartialOccupation(this);
1518  }
1519  myFurtherLanes.clear();
1520 
1521  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1522  if (myState.myPos > myLane->getLength()) {
1523  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
1524  + "'" + emergencyReason
1525  + " (decel=" + toString(myAcceleration - myState.mySpeed)
1526  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1529  myState.mySpeed = 0;
1530  }
1531  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
1532  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1533  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
1534  while (leftLength > 0 && i != passedLanes.rend()) {
1535  myFurtherLanes.push_back(*i);
1536  leftLength -= (*i)->setPartialOccupation(this, leftLength);
1537  ++i;
1538  }
1539  }
1540  updateBestLanes();
1541  // bestLanes need to be updated before lane changing starts
1542  if (getLaneChangeModel().isChangingLanes()) {
1544  }
1545  setBlinkerInformation(); // needs updated bestLanes
1546  //change the blue light only for emergency vehicles SUMOVehicleClass
1547  if (myType->getVehicleClass() == SVC_EMERGENCY) {
1548  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
1549  }
1550  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1552  }
1553  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1554  return moved;
1555 }
1556 
1557 
1558 SUMOReal
1559 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
1560  SUMOReal lengths = 0;
1561  const MSLane::VehCont& vehs = l->getVehiclesSecure();
1562  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1563  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()) {
1564  foundStopped = true;
1565  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1566  l->releaseVehicles();
1567  return ret;
1568  }
1569  lengths += (*i)->getVehicleType().getLengthWithGap();
1570  }
1571  l->releaseVehicles();
1572  return l->getLength() - lengths;
1573 }
1574 
1575 
1576 void
1577 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
1578 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1579  if (gDebugSelectedVehicle == getID()) {
1580  int bla = 0;
1581  }
1582 #endif
1583 #ifdef HAVE_INTERNAL_LANES
1585  bool hadVehicle = false;
1586  SUMOReal seenSpace = -lengthsInFront;
1587 
1588  bool foundStopped = false;
1589  // compute available space until a stopped vehicle is found
1590  // this is the sum of non-interal lane length minus in-between vehicle lenghts
1591  for (unsigned int i = 0; i < lfLinks.size(); ++i) {
1592  // skip unset links
1593  DriveProcessItem& item = lfLinks[i];
1594  if (item.myLink == 0 || foundStopped) {
1595  item.availableSpace = seenSpace;
1596  item.hadVehicle = hadVehicle;
1597  continue;
1598  }
1599  // get the next lane, determine whether it is an internal lane
1600  const MSLane* approachedLane = item.myLink->getViaLane();
1601  if (approachedLane != 0) {
1602  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
1603  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
1604  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1605  } else {
1606  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1607  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1608  }
1609  item.availableSpace = seenSpace;
1610  item.hadVehicle = hadVehicle;
1611  continue;
1612  }
1613  approachedLane = item.myLink->getLane();
1614  const MSVehicle* last = approachedLane->getLastVehicle();
1615  if (last == 0) {
1616  last = approachedLane->getPartialOccupator();
1617  if (last != 0) {
1619  item.availableSpace = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1620  hadVehicle = true;
1622  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1624  if (last->myHaveToWaitOnNextLink) {
1625  foundStopped = true;
1626  }
1627  } else {
1628  seenSpace += approachedLane->getLength();
1629  item.availableSpace = seenSpace;
1630  }
1631  } else {
1632  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1633  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1634  const SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1635  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
1636  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1637  } else {
1638  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
1639  item.availableSpace = seenSpace;
1640  }
1641  if (last->myHaveToWaitOnNextLink) {
1642  foundStopped = true;
1643  }
1644  hadVehicle = true;
1645  }
1646  item.hadVehicle = hadVehicle;
1647  }
1648 
1649 
1650 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1651  if (gDebugSelectedVehicle == getID()) {
1652  int bla = 0;
1653  }
1654 #endif
1655  // check which links allow continuation and add pass available to the previous item
1656  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
1657  DriveProcessItem& item = lfLinks[i - 1];
1658  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
1659  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
1660 #ifndef NO_TRACI
1662 #endif
1663  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1666  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
1667  if (!opened && item.myLink != 0) {
1668  if (i > 1) {
1669  DriveProcessItem& item2 = lfLinks[i - 2];
1670  if (item2.myLink != 0 && item2.myLink->isCont()) {
1671  allowsContinuation = true;
1672  }
1673  }
1674  }
1675  if (allowsContinuation) {
1676  item.availableSpace = lfLinks[i].availableSpace;
1677  }
1678  }
1679 
1680  // find removalBegin
1681  int removalBegin = -1;
1682  for (unsigned int i = 0; hadVehicle && i < lfLinks.size() && removalBegin < 0; ++i) {
1683  // skip unset links
1684  const DriveProcessItem& item = lfLinks[i];
1685  if (item.myLink == 0) {
1686  continue;
1687  }
1688  /*
1689  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1690  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1691  removalBegin = lastLinkToInternal;
1692  }
1693  */
1694 
1695  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
1696  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1697  SUMOReal impatienceCorrection = 0;
1698  /*
1699  if(item.myLink->getState()==LINKSTATE_MINOR) {
1700  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1701  }
1702  */
1703  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
1704  removalBegin = i;
1705  }
1706  //removalBegin = i;
1707  }
1708  }
1709  // abort requests
1710  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1711  while (removalBegin < (int)(lfLinks.size())) {
1713  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
1714  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1715  lfLinks[removalBegin].mySetRequest = false;
1716  }
1717  ++removalBegin;
1718  }
1719  }
1720  }
1721 #else
1722  UNUSED_PARAMETER(lengthsInFront);
1723 #endif
1724  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1725  if ((*i).myLink != 0) {
1726  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
1727  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((size_t)2); // tie braker
1728  }
1729  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1730  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime(), (*i).myDistance);
1731  }
1732  }
1733 }
1734 
1735 
1736 void
1738  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1739  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1740 #ifdef _DEBUG
1741  if (myTraceMoveReminders) {
1742  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
1743  }
1744 #endif
1745  ++rem;
1746  } else {
1747  if (rem->first->notifyEnter(*this, reason)) {
1748 #ifdef _DEBUG
1749  if (myTraceMoveReminders) {
1750  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
1751  }
1752 #endif
1753  ++rem;
1754  } else {
1755 #ifdef _DEBUG
1756  if (myTraceMoveReminders) {
1757  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
1758  }
1759 #endif
1760  rem = myMoveReminders.erase(rem);
1761  }
1762  }
1763  }
1764 }
1765 
1766 
1767 bool
1768 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1769  myAmOnNet = !onTeleporting;
1770  // vaporizing edge?
1771  /*
1772  if (enteredLane->getEdge().isVaporizing()) {
1773  // yep, let's do the vaporization...
1774  myLane = enteredLane;
1775  return true;
1776  }
1777  */
1778  // move mover reminder one lane further
1779  adaptLaneEntering2MoveReminder(*enteredLane);
1780  // set the entered lane as the current lane
1781  myLane = enteredLane;
1782 
1783  // internal edges are not a part of the route...
1784  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1785  ++myCurrEdge;
1786  }
1787  if (!onTeleporting) {
1789  } else {
1791  // normal move() isn't called so reset position here
1792  myState.myPos = 0;
1794  }
1795  return hasArrived();
1796 }
1797 
1798 
1799 void
1801  myAmOnNet = true;
1802  myLane = enteredLane;
1804  // need to update myCurrentLaneInBestLanes
1805  updateBestLanes();
1806  // switch to and activate the new lane's reminders
1807  // keep OldLaneReminders
1808  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1809  addReminder(*rem);
1810  }
1812  MSLane* lane = myLane;
1813  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1814  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
1815  if (lane != 0) {
1816  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
1817  }
1818  if (lane != 0) {
1819  myFurtherLanes[i]->resetPartialOccupation(this);
1820  myFurtherLanes[i] = lane;
1821  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1822  } else {
1823  // keep the old values, but ensure there is no shadow
1826  }
1827  }
1828  }
1829 }
1830 
1831 
1832 void
1834  myState = State(pos, speed);
1836  assert(myState.myPos >= 0);
1837  assert(myState.mySpeed >= 0);
1838  myWaitingTime = 0;
1839  myLane = enteredLane;
1840  myAmOnNet = true;
1841  // set and activate the new lane's reminders
1842  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1843  addReminder(*rem);
1844  }
1845  activateReminders(notification);
1846  // build the list of lanes the vehicle is lapping into
1847  SUMOReal leftLength = myType->getLength() - pos;
1848  MSLane* clane = enteredLane;
1849  while (leftLength > 0) {
1850  clane = clane->getLogicalPredecessorLane();
1851  if (clane == 0) {
1852  break;
1853  }
1854  myFurtherLanes.push_back(clane);
1855  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1856  }
1857 }
1858 
1859 
1860 void
1862  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1863  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1864 #ifdef _DEBUG
1865  if (myTraceMoveReminders) {
1866  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
1867  }
1868 #endif
1869  ++rem;
1870  } else {
1871 #ifdef _DEBUG
1872  if (myTraceMoveReminders) {
1873  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
1874  }
1875 #endif
1876  rem = myMoveReminders.erase(rem);
1877  }
1878  }
1880  // @note. In case of lane change, myFurtherLanes and partial occupation
1881  // are handled in enterLaneAtLaneChange()
1882  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1883  (*i)->resetPartialOccupation(this);
1884  }
1885  myFurtherLanes.clear();
1886  }
1887  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1888  myAmOnNet = false;
1889  }
1891  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
1892  }
1894  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
1895  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
1896  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
1897  myStops.pop_front();
1898  }
1899  }
1900 }
1901 
1902 
1905  return *myLaneChangeModel;
1906 }
1907 
1908 
1911  return *myLaneChangeModel;
1912 }
1913 
1914 
1915 const std::vector<MSVehicle::LaneQ>&
1917  return *myBestLanes.begin();
1918 }
1919 
1920 
1921 void
1922 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
1923 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1924  if (gDebugSelectedVehicle == getID()) {
1925  int bla = 0;
1926  myLastBestLanesEdge = 0;
1927  }
1928 #endif
1929  if (startLane == 0) {
1930  startLane = myLane;
1931  }
1932  assert(startLane != 0);
1933  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
1935  return;
1936  }
1937  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1938  if (myBestLanes.size() == 0 || forceRebuild) {
1939  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
1940  updateBestLanes(true, startLane->getLogicalPredecessorLane());
1941  }
1942  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
1943  return;
1944  }
1945  // adapt best lanes to fit the current internal edge:
1946  // keep the entries that are reachable from this edge
1947  const MSEdge* nextEdge = startLane->getInternalFollower();
1948  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
1949  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
1950  std::vector<LaneQ>& lanes = *it;
1951  assert(lanes.size() > 0);
1952  if (&(lanes[0].lane->getEdge()) == nextEdge) {
1953  // keep those lanes which are successors of internal lanes from the edge of startLane
1954  std::vector<LaneQ> oldLanes = lanes;
1955  lanes.clear();
1956  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
1957  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
1958  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
1959  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
1960  lanes.push_back(*it_lane);
1961  break;
1962  }
1963  }
1964  }
1965  assert(lanes.size() == startLane->getEdge().getLanes().size());
1966  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
1967  for (int i = 0; i < (int)lanes.size(); ++i) {
1968  if (i + lanes[i].bestLaneOffset < 0) {
1969  lanes[i].bestLaneOffset = -i;
1970  }
1971  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
1972  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
1973  }
1974  assert(i + lanes[i].bestLaneOffset >= 0);
1975  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
1976  if (lanes[i].bestContinuations[0] != 0) {
1977  // patch length of bestContinuation to match expectations (only once)
1978  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
1979  }
1980  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
1981  myCurrentLaneInBestLanes = lanes.begin() + i;
1982  }
1983  assert(&(lanes[i].lane->getEdge()) == nextEdge);
1984  }
1985  myLastBestLanesInternalLane = startLane;
1987  return;
1988  } else {
1989  // remove passed edges
1990  it = myBestLanes.erase(it);
1991  }
1992  }
1993  assert(false); // should always find the next edge
1994  }
1995  // start rebuilding
1996  myLastBestLanesEdge = &startLane->getEdge();
1997  myBestLanes.clear();
1998 
1999  // get information about the next stop
2000  const MSEdge* nextStopEdge = 0;
2001  const MSLane* nextStopLane = 0;
2002  SUMOReal nextStopPos = 0;
2003  if (!myStops.empty()) {
2004  const Stop& nextStop = myStops.front();
2005  nextStopLane = nextStop.lane;
2006  nextStopEdge = &nextStopLane->getEdge();
2007  nextStopPos = nextStop.startPos;
2008  }
2009  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
2010  nextStopEdge = *(myRoute->end() - 1);
2011  nextStopLane = nextStopEdge->getLanes()[myArrivalLane];
2012  nextStopPos = myArrivalPos;
2013  }
2014  if (nextStopEdge != 0) {
2015  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
2016  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
2017  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
2018  }
2019 
2020  // go forward along the next lanes;
2021  int seen = 0;
2022  SUMOReal seenLength = 0;
2023  bool progress = true;
2024  for (MSRouteIterator ce = myCurrEdge; progress;) {
2025  std::vector<LaneQ> currentLanes;
2026  const std::vector<MSLane*>* allowed = 0;
2027  const MSEdge* nextEdge = 0;
2028  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
2029  nextEdge = *(ce + 1);
2030  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
2031  }
2032  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
2033  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
2034  LaneQ q;
2035  MSLane* cl = *i;
2036  q.lane = cl;
2037  q.bestContinuations.push_back(cl);
2038  q.bestLaneOffset = 0;
2039  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
2040  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
2041  currentLanes.push_back(q);
2042  }
2043  //
2044  if (nextStopEdge == *ce) {
2045  progress = false;
2046  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
2047  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
2048  (*q).allowsContinuation = false;
2049  (*q).length = nextStopPos;
2050  }
2051  }
2052  }
2053 
2054  myBestLanes.push_back(currentLanes);
2055  ++seen;
2056  seenLength += currentLanes[0].lane->getLength();
2057  ++ce;
2058  progress &= (seen <= 4 || seenLength < 3000);
2059  progress &= seen <= 8;
2060  progress &= ce != myRoute->end();
2061  /*
2062  if(progress) {
2063  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
2064  }
2065  */
2066  }
2067 
2068  // we are examining the last lane explicitly
2069  if (myBestLanes.size() != 0) {
2070  SUMOReal bestLength = -1;
2071  int bestThisIndex = 0;
2072  int index = 0;
2073  std::vector<LaneQ>& last = myBestLanes.back();
2074  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2075  if ((*j).length > bestLength) {
2076  bestLength = (*j).length;
2077  bestThisIndex = index;
2078  }
2079  }
2080  index = 0;
2081  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2082  if ((*j).length < bestLength) {
2083  (*j).bestLaneOffset = bestThisIndex - index;
2084  }
2085  }
2086  }
2087 
2088  // go backward through the lanes
2089  // track back best lane and compute the best prior lane(s)
2090  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
2091  std::vector<LaneQ>& nextLanes = (*(i - 1));
2092  std::vector<LaneQ>& clanes = (*i);
2093  MSEdge& cE = clanes[0].lane->getEdge();
2094  int index = 0;
2095  SUMOReal bestConnectedLength = -1;
2096  SUMOReal bestLength = -1;
2097  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
2098  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
2099  bestConnectedLength = (*j).length;
2100  }
2101  if (bestLength < (*j).length) {
2102  bestLength = (*j).length;
2103  }
2104  }
2105  // compute index of the best lane (highest length and least offset from the best next lane)
2106  int bestThisIndex = 0;
2107  if (bestConnectedLength > 0) {
2108  index = 0;
2109  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2110  LaneQ bestConnectedNext;
2111  bestConnectedNext.length = -1;
2112  if ((*j).allowsContinuation) {
2113  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
2114  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2115  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
2116  bestConnectedNext = *m;
2117  }
2118  }
2119  }
2120  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
2121  (*j).length += bestLength;
2122  } else {
2123  (*j).length += bestConnectedNext.length;
2124  }
2125  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
2126  }
2127  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))) {
2128  bestThisIndex = index;
2129  }
2130  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
2131  }
2132 
2133  } else {
2134  int bestNextIndex = 0;
2135  int bestDistToNeeded = (int) clanes.size();
2136  index = 0;
2137  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2138  if ((*j).allowsContinuation) {
2139  int nextIndex = 0;
2140  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
2141  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2142  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
2143  bestDistToNeeded = abs((*m).bestLaneOffset);
2144  bestThisIndex = index;
2145  bestNextIndex = nextIndex;
2146  }
2147  }
2148  }
2149  }
2150  }
2151  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
2152  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
2153 
2154  }
2155  // set bestLaneOffset for all lanes
2156  index = 0;
2157  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2158  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))) {
2159  (*j).bestLaneOffset = bestThisIndex - index;
2160  } else {
2161  (*j).bestLaneOffset = 0;
2162  }
2163  }
2164  }
2166  return;
2167 }
2168 
2169 
2170 void
2172  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
2173  std::vector<LaneQ>::iterator i;
2174  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
2175  SUMOReal nextOccupation = 0;
2176  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
2177  nextOccupation += (*j)->getBruttoVehLenSum();
2178  }
2179  (*i).nextOccupation = nextOccupation;
2180  if ((*i).lane == startLane) {
2182  }
2183  }
2184 }
2185 
2186 
2187 const std::vector<MSLane*>&
2189  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2190  return myEmptyLaneVector;
2191  }
2192  return (*myCurrentLaneInBestLanes).bestContinuations;
2193 }
2194 
2195 
2196 const std::vector<MSLane*>&
2198  const MSLane* lane = l;
2200  // internal edges are not kept inside the bestLanes structure
2201  lane = lane->getLinkCont()[0]->getLane();
2202  }
2203  if (myBestLanes.size() == 0) {
2204  return myEmptyLaneVector;
2205  }
2206  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
2207  if ((*i).lane == lane) {
2208  return (*i).bestContinuations;
2209  }
2210  }
2211  return myEmptyLaneVector;
2212 }
2213 
2214 
2215 int
2217  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2218  return 0;
2219  } else {
2220  return (*myCurrentLaneInBestLanes).bestLaneOffset;
2221  }
2222 }
2223 
2224 
2225 void
2227  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
2228  assert(laneIndex < (int)preb.size());
2229  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
2230 }
2231 
2232 
2233 bool
2235  if (getPositionOnLane() > myLane->getLength()) {
2238  return true;
2239  }
2240  return false;
2241 }
2242 
2243 
2244 SUMOReal
2245 MSVehicle::getDistanceToPosition(SUMOReal destPos, const MSEdge* destEdge) const {
2247  if (isOnRoad() && destEdge != NULL) {
2248  if (&myLane->getEdge() == *myCurrEdge) {
2249  // vehicle is on a normal edge
2250  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2251  } else {
2252  // vehicle is on inner junction edge
2253  distance = myLane->getLength() - getPositionOnLane();
2254  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2255  }
2256  }
2257  return distance;
2258 }
2259 
2260 
2261 std::pair<const MSVehicle* const, SUMOReal>
2263  if (myLane == 0) {
2264  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
2265  }
2266  if (dist == 0) {
2268  }
2269  const MSVehicle* lead = 0;
2270  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
2271  MSLane::VehCont::const_iterator pred = std::find(vehs.begin(), vehs.end(), this) + 1;
2272  if (pred != vehs.end()) {
2273  lead = *pred;
2274  }
2276  if (lead != 0) {
2277  return std::make_pair(lead, lead->getPositionOnLane() - lead->getVehicleType().getLength() - getPositionOnLane() - getVehicleType().getMinGap());
2278  }
2279  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
2280  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
2281  return myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
2282 }
2283 
2284 
2285 SUMOReal
2287  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
2288  if (leaderInfo.first == 0 || getSpeed() == 0) {
2289  return -1;
2290  }
2291  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
2292 }
2293 
2294 
2295 SUMOReal
2298 }
2299 
2300 
2301 SUMOReal
2304 }
2305 
2306 
2307 SUMOReal
2310 }
2311 
2312 
2313 SUMOReal
2316 }
2317 
2318 
2319 SUMOReal
2322 }
2323 
2324 
2325 SUMOReal
2328 }
2329 
2330 
2331 SUMOReal
2334 }
2335 
2336 
2337 void
2339  if (myPersonDevice == 0) {
2341  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2342  }
2343  myPersonDevice->addPerson(person);
2344  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2345  unsigned int numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2346  if (numExpected != 0) {
2347  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2348  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2349  // Bus drivers usually do not know the names of the passengers.
2350  myStops.front().awaitedPersons.erase(person->getID());
2351  numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2352  }
2353  if (numExpected == 0) {
2354  myStops.front().duration = 0;
2355  }
2356  }
2357 }
2358 
2359 void
2361  if (myContainerDevice == 0) {
2363  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
2364  }
2365  myContainerDevice->addContainer(container);
2366  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
2367  unsigned int numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2368  if (numExpected != 0) {
2369  myStops.front().awaitedContainers.erase(container->getID());
2370  numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2371  }
2372  if (numExpected == 0) {
2373  myStops.front().duration = 0;
2374  }
2375  }
2376 }
2377 
2378 
2379 unsigned int
2381  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
2382  return boarded + myParameter->personNumber;
2383 }
2384 
2385 unsigned int
2387  unsigned int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
2388  return loaded + myParameter->containerNumber;
2389 }
2390 
2391 
2392 void
2395  int state = getLaneChangeModel().getOwnState();
2396  if ((state & LCA_LEFT) != 0) {
2398  } else if ((state & LCA_RIGHT) != 0) {
2400  } else if (getLaneChangeModel().isChangingLanes()) {
2401  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
2403  } else {
2405  }
2406  } else {
2407  const MSLane* lane = getLane();
2408  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
2409  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
2410  switch ((*link)->getDirection()) {
2411  case LINKDIR_TURN:
2412  case LINKDIR_LEFT:
2413  case LINKDIR_PARTLEFT:
2415  break;
2416  case LINKDIR_RIGHT:
2417  case LINKDIR_PARTRIGHT:
2419  break;
2420  default:
2421  break;
2422  }
2423  }
2424  }
2425 
2426 }
2427 
2428 void
2430  if (currentTime % 1000 == 0) {
2433  } else {
2435  }
2436  }
2437 }
2438 
2439 
2440 void
2442  if (myType->amVehicleSpecific()) {
2443  delete myType;
2444  }
2445  myType = type;
2446 }
2447 
2448 unsigned int
2450  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
2451  return (unsigned int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
2452 }
2453 
2454 
2455 void
2457  assert(lane != 0);
2458  myLane = lane;
2459  myState.myPos = pos;
2460 }
2461 
2462 
2463 #ifndef NO_TRACI
2464 bool
2465 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
2466  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
2467  //if the stop exists update the duration
2468  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2469  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
2470  if (duration == 0 && !iter->reached) {
2471  myStops.erase(iter);
2472  } else {
2473  iter->duration = duration;
2474  }
2475  return true;
2476  }
2477  }
2478 
2480  newStop.lane = lane->getID();
2481  newStop.startPos = startPos;
2482  newStop.endPos = endPos;
2483  newStop.duration = duration;
2484  newStop.until = until;
2485  newStop.triggered = triggered;
2486  newStop.containerTriggered = containerTriggered;
2487  newStop.parking = parking;
2488  newStop.index = STOP_INDEX_FIT;
2489  const bool result = addStop(newStop, errorMsg);
2490  if (myLane != 0) {
2491  updateBestLanes(true);
2492  }
2493  return result;
2494 }
2495 
2496 
2497 bool
2498 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
2499  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
2500  //if the stop exists update the duration
2501  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2502  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
2503  if (stop != 0 && stop->getID() == stopId) {
2504  if (duration == 0 && !iter->reached) {
2505  myStops.erase(iter);
2506  } else {
2507  iter->duration = duration;
2508  }
2509  return true;
2510  }
2511  }
2512 
2514  MSStoppingPlace* bs = 0;
2515  if (isContainerStop) {
2516  newStop.containerstop = stopId;
2517  bs = MSNet::getInstance()->getContainerStop(stopId);
2518  if (bs == 0) {
2519  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2520  return false;
2521  }
2522  } else {
2523  newStop.busstop = stopId;
2524  bs = MSNet::getInstance()->getBusStop(stopId);
2525  if (bs == 0) {
2526  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2527  return false;
2528  }
2529  }
2530  newStop.duration = duration;
2531  newStop.until = until;
2532  newStop.triggered = triggered;
2533  newStop.containerTriggered = containerTriggered;
2534  newStop.parking = parking;
2535  newStop.index = STOP_INDEX_FIT;
2536  newStop.lane = bs->getLane().getID();
2537  newStop.endPos = bs->getEndLanePosition();
2538  newStop.startPos = bs->getBeginLanePosition();
2539  const bool result = addStop(newStop, errorMsg);
2540  if (myLane != 0) {
2541  updateBestLanes(true);
2542  }
2543  return result;
2544 }
2545 
2546 
2547 bool
2549  if (isStopped()) {
2553  }
2557  }
2558  // we have waited long enough and fulfilled any passenger-requirements
2559  if (myStops.front().busstop != 0) {
2560  // inform bus stop about leaving it
2561  myStops.front().busstop->leaveFrom(this);
2562  }
2563  // we have waited long enough and fulfilled any container-requirements
2564  if (myStops.front().containerstop != 0) {
2565  // inform container stop about leaving it
2566  myStops.front().containerstop->leaveFrom(this);
2567  }
2568  // the current stop is no longer valid
2570  myStops.pop_front();
2571  // do not count the stopping time towards gridlock time.
2572  // Other outputs use an independent counter and are not affected.
2573  myWaitingTime = 0;
2574  // maybe the next stop is on the same edge; let's rebuild best lanes
2575  updateBestLanes(true);
2576  // continue as wished...
2578  return true;
2579  }
2580  return false;
2581 }
2582 
2583 
2586  return myStops.front();
2587 }
2588 
2589 
2592  if (myInfluencer == 0) {
2593  myInfluencer = new Influencer();
2594  }
2595  return *myInfluencer;
2596 }
2597 
2598 
2599 SUMOReal
2601  if (myInfluencer != 0) {
2602  return myInfluencer->getOriginalSpeed();
2603  }
2604  return myState.mySpeed;
2605 }
2606 
2607 
2608 int
2610  if (hasInfluencer()) {
2612  MSNet::getInstance()->getCurrentTimeStep(),
2613  myLane->getEdge(),
2614  getLaneIndex(),
2615  state);
2616  }
2617  return state;
2618 }
2619 #endif
2620 
2621 
2622 void
2625  // here starts the vehicle internal part (see loading)
2626  std::vector<SUMOTime> internals;
2627  internals.push_back(myDeparture);
2628  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
2629  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
2632  out.closeTag();
2633 }
2634 
2635 
2636 void
2637 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
2638  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
2639  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
2640  }
2641  unsigned int routeOffset;
2642  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
2643  bis >> myDeparture;
2644  bis >> routeOffset;
2645  if (hasDeparted()) {
2646  myDeparture -= offset;
2647  myCurrEdge += routeOffset;
2648  }
2651  // no need to reset myCachedPosition here since state loading happens directly after creation
2652 }
2653 
2654 
2655 /****************************************************************************/
void forceVehicleInsertion(MSVehicle *veh, SUMOReal pos)
Inserts the given vehicle at the given position.
Definition: MSLane.cpp:633
void resetRoutePosition(unsigned int index)
Definition: MSVehicle.cpp:531
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:844
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1191
The link is a partial left direction.
#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:2441
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) const
Returns the velocity after maximum deceleration.
Definition: MSCFModel.h:283
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:1768
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:461
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:80
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:976
SUMOReal getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
long long int SUMOTime
Definition: SUMOTime.h:43
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:111
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:596
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
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:1329
MoveReminderCont myMoveReminders
Current lane&#39;s move reminder.
SUMOReal myArrivalPos
the position on the destination lane where the vehicle stops
#define SPEED2DIST(x)
Definition: SUMOTime.h:55
const MSEdge * myLastBestLanesEdge
Definition: MSVehicle.h:1190
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:800
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1188
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1216
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1099
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:873
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1193
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:303
const MSCFModel & getCarFollowModel() const
Returns the vehicle&#39;s car following model definition.
Definition: MSVehicle.h:544
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1210
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1183
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:2585
A lane area vehicles can halt at.
const Position geometryPositionAtOffset(SUMOReal offset) const
Definition: MSLane.h:340
SUMOReal getMaxSpeed() const
Returns the maximum speed.
DriveItemVector myLFLinkLanes
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1283
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.cpp:134
bool resumeFromStopping()
Definition: MSVehicle.cpp:2548
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1219
bool hasInfluencer() const
Definition: MSVehicle.h:1114
SUMOTime duration
The stopping duration.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:186
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
The action is done to help someone else.
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:470
SUMOReal getImpatience() const
Returns this vehicles impatience.
void setBlinkerInformation()
Definition: MSVehicle.cpp:2393
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:2360
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1275
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1207
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2600
The vehicle arrived at a junction.
void setRespectJunctionPriority(bool value)
Sets whether junction priority rules shall be respected.
Definition: MSVehicle.cpp:322
bool isVTDControlled() const
Definition: MSVehicle.h:1046
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:359
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:376
Position getPosition(const SUMOReal offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:617
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:86
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MSVehicle.cpp:464
static MSDevice_Person * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
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:1072
SUMOReal arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
The link is a 180 degree turn.
State(SUMOReal pos, SUMOReal speed)
Constructor.
Definition: MSVehicle.cpp:139
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:88
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:61
SUMOReal getLength() const
Get vehicle&#39;s length [m].
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:1086
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:471
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:914
SUMOReal implicitDeltaPosVTD(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new VTD position ...
Definition: MSVehicle.cpp:370
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2308
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1078
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:590
void registerEmergencyStop()
register emergency stop
SUMOReal getEndLanePosition() const
Returns the end position of this stop.
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:119
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:162
T MAX2(T a, T b)
Definition: StdDefs.h:79
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:130
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2380
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:808
const MSRoute * myRoute
This Vehicle&#39;s route.
const std::string & getID() const
returns the id of the transportable
unsigned int myNumberReroutes
The number of reroutings.
bool hasDeparted() const
Returns whether this vehicle has already departed.
The vehicle got vaporized.
void postProcessVTD(MSVehicle *v)
Definition: MSVehicle.cpp:344
SUMOReal estimateLeaveSpeed(const MSLink *const link, const SUMOReal vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:1289
SUMOTime until
The time at which the vehicle may continue its journey.
SUMOReal mySpeed
the stored speed
Definition: MSVehicle.h:120
const int STOP_INDEX_FIT
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:564
This is an uncontrolled, right-before-left link.
SUMOReal getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:2296
void removeWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
Removes a vehicle from the list of waiting vehicles to a given edge.
unsigned int personNumber
The static number of persons in the vehicle when it departs (not including boarding persons) ...
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:1283
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:79
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
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:2262
SUMOReal distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
Definition: Position.h:221
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:286
int myArrivalLane
the position on 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:337
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:52
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1224
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:851
The action is due to a TraCI request.
A storage for edge travel times and efforts.
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:255
This is an uncontrolled, all-way stop link.
SUMOReal length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:464
SUMOReal getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.cpp:1537
The action is urgent (to be defined by lc-model)
#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:93
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const unsigned int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:214
#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:1800
This is an uncontrolled, zipper-merge link.
The link is a (hard) left direction.
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, unsigned int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:1010
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:584
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:1904
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1332
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:296
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
std::string gDebugSelectedVehicle
Definition: StdDefs.cpp:104
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:766
SUMOReal getPartialOccupatorEnd() const
Returns the position of the in-lapping vehicle&#39;s end.
Definition: MSLane.h:261
The vehicles starts to stop.
Definition: MSNet.h:544
void unregisterOneWaitingForContainer()
decreases the count of vehicles waiting for a container to allow recogniztion of container related de...
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
The state of a link.
void enterLaneAtInsertion(MSLane *enteredLane, SUMOReal pos, SUMOReal speed, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:1833
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:181
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:127
const std::vector< MSTransportable * > & getPersons() const
Returns the list of persons using this vehicle.
const std::string & getID() const
Returns the id.
Definition: Named.h:65
A road/street connecting two junctions.
Definition: MSEdge.h:81
void addContainer(MSTransportable *container)
Add a container.
The vehicle changes lanes (micro only)
Wants go to the left.
MSLane * lane
The described lane.
Definition: MSVehicle.h:462
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:1577
SUMOReal getLength() const
return the length of the edge
Definition: MSEdge.h:535
Left blinker lights are switched on.
Definition: MSVehicle.h:768
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:1420
#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:328
SUMOReal brakeGap(const SUMOReal speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time.
Definition: MSCFModel.h:232
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.
unsigned int getContainerNumber() const
Returns the number of containers.
Definition: MSVehicle.cpp:2386
static MSDevice_Container * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
SUMOReal implicitSpeedVTD(const MSVehicle *veh, SUMOReal oldSpeed)
return the speed that is implicit in the new VTD position
Definition: MSVehicle.cpp:360
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:577
SUMOReal startPos
The stopping position start.
The edge is a district edge.
Definition: MSEdge.h:100
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:1278
The vehicle got a new route.
Definition: MSNet.h:538
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:562
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:786
vehicle want&#39;s to change to right lane
Definition: MSVehicle.h:134
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:98
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:572
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:255
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, unsigned int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:175
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:128
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:2188
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:1102
SUMOReal endPos
The stopping position end.
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...
bool willPass(const MSEdge *const edge) const
Returns whether the vehicle wil pass the given edge.
Definition: MSVehicle.cpp:519
virtual MSContainerControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:704
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:1922
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:625
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:598
virtual SUMOReal getFloat(int id) const =0
Returns the SUMOReal-value of the named (by its enum-value) attribute.
Position myCachedPosition
Definition: MSVehicle.h:1226
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:308
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:568
static SUMOReal gap(SUMOReal predPos, SUMOReal predLength, SUMOReal pos)
Uses the given values to compute the brutto-gap.
Definition: MSVehicle.h:215
SUMOReal myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1063
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:699
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1198
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:61
const int STOP_INDEX_END
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:106
unsigned int size() const
Return the number of containers.
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:827
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:845
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:675
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1075
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:1268
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1186
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:993
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition) ...
Definition: MSVehicle.h:1222
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:1336
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1194
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:2245
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
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:1262
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:1559
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:580
bool isRoundabout() const
Definition: MSEdge.h:578
MSVehicle()
invalidated default constructor
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:368
T MIN2(T a, T b)
Definition: StdDefs.h:73
The link is a (hard) right direction.
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:188
The brake lights are on.
Definition: MSVehicle.h:772
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSVehicle.h:1303
A blue emergency light is on.
Definition: MSVehicle.h:788
A structure representing the best lanes for continuing the route.
Definition: MSVehicle.h:460
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:2637
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:450
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: MSVehicle.h:594
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:71
std::pair< MSVehicle *const, SUMOReal > getLeader(const MSVehicle *veh, const SUMOReal vehPos, bool checkNext) const
Returns the immediate leader of veh and the distance to veh starting on this lane.
Definition: MSLane.cpp:1247
SUMOReal getMaxDecel() const
Get the vehicle type&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:184
SUMOReal changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:296
MSVehicle * getLastVehicle() const
returns the last vehicle
Definition: MSLane.cpp:992
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
MSLane * getShadowLane() const
Returns the lane the vehicles shadow is on during continuouss lane change.
#define DEG2RAD(x)
Definition: GeomHelper.h:45
const std::vector< MSTransportable * > & getContainers() const
Returns the list of containers using this vehicle.
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1180
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1097
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:92
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:95
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:240
The link is a partial right direction.
virtual SUMOReal getHeadwayTime() const
Get the driver&#39;s reaction time [s].
Definition: MSCFModel.h:203
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:100
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:833
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1095
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1916
SUMOReal getLaneChangeCompletion() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
bool containerTriggered
whether an arriving container lets the vehicle continue
Wants go to the right.
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:472
SUMOReal getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:2332
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:89
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:45
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:2623
void planMoveInternal(const SUMOTime t, const MSVehicle *pred, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:984
SUMOReal getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.h:1021
SUMOReal getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:2314
std::string lane
The lane to stop at.
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1081
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:552
Influencer()
Constructor.
Definition: MSVehicle.cpp:147
bool replaceRouteEdges(ConstMSEdgeVector &edges, bool onInit=false)
Replaces the current route by the given edges.
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
ConstMSEdgeVector myVTDRoute
Definition: MSVehicle.h:1087
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:1861
SUMOReal getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:176
unsigned int getVehicleNumber() const
Returns the number of vehicles on this lane.
Definition: MSLane.h:285
SUMOReal getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:2320
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2302
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:2171
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:2429
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:884
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:132
The action is needed to follow the route (navigational lc)
The vehicle starts or ends parking.
~Influencer()
Destructor.
Definition: MSVehicle.cpp:164
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, SUMOReal > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:168
EdgeBasicFunction getPurpose() const
Returns the edge type (EdgeBasicFunction)
Definition: MSEdge.h:235
LaneChangeModel getLaneChangeModel() const
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:2591
#define BUS_STOP_OFFSET
Definition: MSVehicle.cpp:93
void setTentativeLaneAndPosition(MSLane *lane, const SUMOReal pos)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:2456
Structure representing possible vehicle parameter.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:81
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:1007
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:167
std::vector< std::pair< SUMOTime, SUMOReal > > mySpeedTimeLine
The velocity time line to apply.
Definition: MSVehicle.h:1057
SUMOReal getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:606
void setNoShadowPartialOccupator(MSLane *lane)
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:586
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:696
The link has yellow light, may pass.
void setConsiderMaxDeceleration(bool value)
Sets whether the maximum deceleration shall be regarded.
Definition: MSVehicle.cpp:316
bool fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:2234
bool isLaneChangeMidpointPassed() const
return whether the vehicle passed the midpoint of a continuous lane change maneuver ...
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1213
std::vector< MSLane * > bestContinuations
Consecutive lane that can be followed without a lane change (contribute to length and occupation) ...
Definition: MSVehicle.h:474
SUMOReal interpolateLanePosToGeometryPos(SUMOReal lanePos) const
Definition: MSLane.h:334
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:224
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:592
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2326
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:1246
The action is due to the default of keeping right "Rechtsfahrgebot".
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:93
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: MSVehicle.h:582
void setConsiderSafeVelocity(bool value)
Sets whether the safe velocity shall be regarded.
Definition: MSVehicle.cpp:304
MSStoppingPlace * getContainerStop(const std::string &id) const
Returns the named container stop.
Definition: MSNet.cpp:810
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:966
int index
at which position in the stops list
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:566
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:2498
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:57
The arrival lane is given.
Needs to stay on the current lane.
const std::string & getID() const
Returns the name of the vehicle type.
The vehicle ends to stop.
Definition: MSNet.h:546
SUMOReal getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:294
void resetMoved()
reset the flag whether a vehicle already moved to false
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:770
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:334
SUMOReal myPos
the stored position
Definition: MSVehicle.h:113
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:839
std::vector< DriveProcessItem > DriveItemVector
Definition: MSVehicle.h:1280
std::vector< std::pair< SUMOTime, unsigned int > > myLaneTimeLine
The lane usage time line to apply.
Definition: MSVehicle.h:1060
void planMove(const SUMOTime t, const MSVehicle *pred, const SUMOReal lengthsInFront)
Compute safe velocities for the upcoming lanes based on positions and speeds from the last time step...
Definition: MSVehicle.cpp:976
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:323
SUMOReal endPos
The stopping position end.
Definition: MSVehicle.h:578
void move2side(SUMOReal amount)
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:647
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:136
MSVehicle * getPartialOccupator() const
Returns the vehicle which laps into this lane.
Definition: MSLane.h:253
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
#define SUMOReal
Definition: config.h:214
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:827
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:819
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:2338
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1195
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2226
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:161
#define DELTA_T
Definition: SUMOTime.h:50
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:385
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:1059
No information given; use default.
void addPerson(MSTransportable *person)
Add a passenger.
The link has yellow light, has to brake anyway.
unsigned int containerNumber
The static number of containers in the vehicle when it departs.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:106
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:354
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:339
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1066
SUMOEmissionClass getEmissionClass() const
Get this vehicle type&#39;s emission class.
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:331
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:2609
void activateReminders(const MSMoveReminder::Notification reason)
"Activates" all current move reminder
Definition: MSVehicle.cpp:1737
The edge is an internal edge.
Definition: MSEdge.h:98
public emergency vehicles
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2286
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:83
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane&#39;s move reminders.
Definition: MSLane.h:150
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:2465
SUMOReal startPos
The stopping position start.
Definition: MSVehicle.h:576
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:570
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
MSDevice_Container * myContainerDevice
The containers this vehicle may have.
Definition: MSVehicle.h:1204
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:540
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:586
unsigned int size() const
Return the number of passengers.
Back-at-zero position.
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1093
The link has red light (must brake) but indicates upcoming green.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:525
Interface for lane-change models.
MSDevice_Person * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1201
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2216
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:1069
void setConsiderMaxAcceleration(bool value)
Sets whether the maximum acceleration shall be regarded.
Definition: MSVehicle.cpp:310
SUMOTime myDeparture
The real departure time.
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:75
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...
std::string id
The vehicle&#39;s id.
bool parking
whether the vehicle is removed from the net while stopping
Definition: MSVehicle.h:588
static const Position INVALID
Definition: Position.h:261
The vehicle is being teleported.
int getLaneChangeDirection() const
return the direction of the current lane change maneuver
SUMOReal getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MSVehicle.cpp:663
const std::string & getID() const
Returns the name of the vehicle.
The action is due to the wish to be faster (tactical lc)
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
unsigned int getLaneIndex() const
Definition: MSVehicle.cpp:2449