SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
17 // Representation of a vehicle in the micro simulation
18 /****************************************************************************/
19 // SUMO, Simulation of Urban MObility; see http://sumo.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>
55 #include <utils/geom/Line.h>
61 #include <microsim/MSGlobals.h>
62 #include "MSStoppingPlace.h"
65 #include "MSEdgeWeightsStorage.h"
67 #include "MSMoveReminder.h"
69 #include "MSPersonControl.h"
70 #include "MSContainer.h"
71 #include "MSContainerControl.h"
72 #include "MSLane.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) {
169  mySpeedAdaptationStarted = true;
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
193  if (!mySpeedAdaptationStarted) {
194  mySpeedTimeLine[0].second = speed;
195  mySpeedAdaptationStarted = true;
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;
200  if (myConsiderSafeVelocity) {
201  speed = MIN2(speed, vSafe);
202  }
203  if (myConsiderMaxAcceleration) {
204  speed = MIN2(speed, vMax);
205  }
206  if (myConsiderMaxDeceleration) {
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
274  if ((myTraciLaneChangePriority == LCP_ALWAYS)
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
311  myConsiderMaxAcceleration = value;
312 }
313 
314 
315 void
317  myConsiderMaxDeceleration = value;
318 }
319 
320 
321 void
323  myRespectJunctionPriority = value;
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  }
350  v->myCurrEdge += myVTDEdgeOffset;
351  if (myVTDPos > myVTDLane->getLength()) {
352  myVTDPos = myVTDLane->getLength();
353  }
354  myVTDLane->forceVehicleInsertion(v, myVTDPos);
355  v->updateBestLanes();
356  myAmVTDControlled = false;
357 }
358 
359 #endif
360 
361 
362 /* -------------------------------------------------------------------------
363  * MSVehicle-methods
364  * ----------------------------------------------------------------------- */
366  delete myEdgeWeights;
367  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
368  (*i)->resetPartialOccupation(this);
369  }
370  delete myLaneChangeModel; // still needed when calling resetPartialOccupation (getShadowLane)
371  myFurtherLanes.clear();
372  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
373  if ((*i).myLink != 0) {
374  (*i).myLink->removeApproaching(this);
375  }
376  }
377  //
378  if (myType->amVehicleSpecific()) {
379  delete myType;
380  }
381 #ifndef NO_TRACI
382  delete myInfluencer;
383 #endif
384 }
385 
386 
388  const MSVehicleType* type, const SUMOReal speedFactor) :
389  MSBaseVehicle(pars, route, type, speedFactor),
390  myWaitingTime(0),
391  myState(0, 0), //
392  myLane(0),
395  myPersonDevice(0),
397  myAcceleration(0),
398  mySignals(0),
399  myAmOnNet(false),
402  myHaveToWaitOnNextLink(false),
403  myCachedPosition(Position::INVALID),
404  myEdgeWeights(0)
405 #ifndef NO_TRACI
406  , myInfluencer(0)
407 #endif
408 {
409  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
410  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
411  if ((*myCurrEdge)->getDepartLane(*this) == 0) {
412  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
413  }
414  } else {
415  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
416  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
417  }
418  }
419  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
420  throw ProcessError("Departure speed for vehicle '" + pars->id +
421  "' is too high for the vehicle type '" + type->getID() + "'.");
422  }
423  }
426 }
427 
428 
429 void
433  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
434  if ((*i).myLink != 0) {
435  (*i).myLink->removeApproaching(this);
436  }
437  }
438  leaveLane(reason);
439 }
440 
441 
442 // ------------ interaction with the route
443 bool
445  return myCurrEdge == myRoute->end() - 1 && (myStops.empty() || myStops.front().edge != myCurrEdge)
447 }
448 
449 
450 bool
451 MSVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset) {
452  const ConstMSEdgeVector& edges = newRoute->getEdges();
453  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
454  if (!onInit && !newRoute->contains(*myCurrEdge)) {
455  return false;
456  }
457 
458  // rebuild in-vehicle route information
459  if (onInit) {
460  myCurrEdge = newRoute->begin();
461  } else {
462  myCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);
463  }
464  // check whether the old route may be deleted (is not used by anyone else)
465  newRoute->addReference();
466  myRoute->release();
467  // assign new route
468  myRoute = newRoute;
471  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
472  // update arrival definition
474  // save information that the vehicle was rerouted
477  // recheck old stops
478  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
479  if (find(myCurrEdge, edges.end(), &iter->lane->getEdge()) == edges.end()) {
480  iter = myStops.erase(iter);
481  } else {
482  iter->edge = find(myCurrEdge, edges.end(), &iter->lane->getEdge());
483  ++iter;
484  }
485  }
486  // add new stops
487  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
488  std::string error;
489  addStop(*i, error);
490  if (error != "") {
491  WRITE_WARNING(error);
492  }
493  }
494  return true;
495 }
496 
497 
498 bool
499 MSVehicle::willPass(const MSEdge* const edge) const {
500  return find(myCurrEdge, myRoute->end(), edge) != myRoute->end();
501 }
502 
503 
504 unsigned int
506  return (unsigned int) std::distance(myRoute->begin(), myCurrEdge);
507 }
508 
509 
510 void
511 MSVehicle::resetRoutePosition(unsigned int index) {
512  myCurrEdge = myRoute->begin() + index;
513  // !!! hack
514  myArrivalPos = (*(myRoute->end() - 1))->getLanes()[0]->getLength();
515 }
516 
517 
518 
521  return _getWeightsStorage();
522 }
523 
524 
527  return _getWeightsStorage();
528 }
529 
530 
533  if (myEdgeWeights == 0) {
535  }
536  return *myEdgeWeights;
537 }
538 
539 
540 // ------------ Interaction with move reminders
541 void
543  // This erasure-idiom works for all stl-sequence-containers
544  // See Meyers: Effective STL, Item 9
545  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
546  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, newSpeed)) {
547 #ifdef _DEBUG
548  if (myTraceMoveReminders) {
549  traceMoveReminder("notifyMove", rem->first, rem->second, false);
550  }
551 #endif
552  rem = myMoveReminders.erase(rem);
553  } else {
554 #ifdef _DEBUG
555  if (myTraceMoveReminders) {
556  traceMoveReminder("notifyMove", rem->first, rem->second, true);
557  }
558 #endif
559  ++rem;
560  }
561  }
562 }
563 
564 
565 void
567  // save the old work reminders, patching the position information
568  // add the information about the new offset to the old lane reminders
569  const SUMOReal oldLaneLength = myLane->getLength();
570  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
571  rem->second += oldLaneLength;
572 #ifdef _DEBUG
573  if (myTraceMoveReminders) {
574  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
575  }
576 #endif
577  }
578  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
579  addReminder(*rem);
580  }
581 }
582 
583 
584 // ------------ Other getter methods
585 SUMOReal
587  if (myLane == 0) {
588  return 0;
589  }
590  const SUMOReal lp = getPositionOnLane();
592  return myLane->getShape().slopeDegreeAtOffset(gp);
593 }
594 
595 
596 Position
597 MSVehicle::getPosition(const SUMOReal offset) const {
598  if (myLane == 0) {
599  return Position::INVALID;
600  }
601  if (isParking()) {
602  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
605  }
606  const bool changingLanes = getLaneChangeModel().isChangingLanes();
607  if (offset == 0. && !changingLanes) {
610  }
611  return myCachedPosition;
612  }
614  if (changingLanes) {
616  Line line = getLaneChangeModel().isLaneChangeMidpointPassed() ? Line(other, result) : Line(result, other);
617  return line.getPositionAtDistance(getLaneChangeModel().getLaneChangeCompletion() * line.length());
618  }
619  return result;
620 }
621 
622 
623 const MSEdge*
625  // too close to the next junction, so avoid an emergency brake here
626  if (myLane != 0 && (myCurrEdge + 1) != myRoute->end() &&
628  return *(myCurrEdge + 1);
629  }
630 #ifdef HAVE_INTERNAL_LANES
631  if (myLane != 0) {
632  return myLane->getInternalFollower();
633  }
634 #endif
635  return *myCurrEdge;
636 }
637 
638 
639 SUMOReal
641  Position p1;
642  Position p2;
643  if (isParking()) {
645  }
647  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
649  } else {
650  p1 = getPosition();
651  }
652  if (myState.myPos >= myType->getLength()) {
653  // vehicle is fully on the new lane
655  } else {
656  p2 = myFurtherLanes.size() > 0
657  ? myFurtherLanes.back()->geometryPositionAtOffset(myFurtherLanes.back()->getPartialOccupatorEnd())
658  : myLane->getShape().front();
659  if (getLaneChangeModel().isChangingLanes() && myFurtherLanes.size() > 0 && getLaneChangeModel().getShadowLane(myFurtherLanes.back()) == 0) {
660  // special case where there target lane has no predecessor
661  p2 = myLane->getShape().front();
662  }
663  }
664  SUMOReal result = (p1 != p2 ?
665  atan2(p1.x() - p2.x(), p2.y() - p1.y()) * 180. / M_PI :
669  result += getLaneChangeModel().getLaneChangeDirection() * angleOffset;
670  }
671  return result;
672 }
673 
674 
675 // ------------
676 bool
677 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset) {
678  Stop stop;
679  stop.lane = MSLane::dictionary(stopPar.lane);
681  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
682  return false;
683  }
684  stop.busstop = MSNet::getInstance()->getBusStop(stopPar.busstop);
686  stop.startPos = stopPar.startPos;
687  stop.endPos = stopPar.endPos;
688  stop.duration = stopPar.duration;
689  stop.until = stopPar.until;
690  stop.timeToBoardNextPerson = 0;
691  stop.timeToLoadNextContainer = 0;
692  stop.awaitedPersons = stopPar.awaitedPersons;
693  stop.awaitedContainers = stopPar.awaitedContainers;
694  if (stop.until != -1) {
695  stop.until += untilOffset;
696  }
697  stop.triggered = stopPar.triggered;
698  stop.containerTriggered = stopPar.containerTriggered;
699  stop.parking = stopPar.parking;
700  stop.reached = false;
701  if (stop.startPos < 0 || stop.endPos > stop.lane->getLength()) {
702  if (stop.busstop != 0) {
703  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
704  } else {
705  errorMsg = "Stop";
706  }
707  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
708  return false;
709  }
710  if (stop.busstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
711  errorMsg = "Bus stop '" + stop.busstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
712  }
713  if (stop.containerstop != 0 && myType->getLength() / 2. > stop.endPos - stop.startPos) {
714  errorMsg = "Container stop '" + stop.containerstop->getID() + "' on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
715  }
716  stop.edge = find(myCurrEdge, myRoute->end(), &stop.lane->getEdge());
717  MSRouteIterator prevStopEdge = myCurrEdge;
718  SUMOReal prevStopPos = myState.myPos;
719  // where to insert the stop
720  std::list<Stop>::iterator iter = myStops.begin();
721  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
722  if (myStops.size() > 0) {
723  prevStopEdge = myStops.back().edge;
724  prevStopPos = myStops.back().endPos;
725  iter = myStops.end();
726  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
727  if (prevStopEdge == stop.edge && prevStopPos > stop.endPos) {
728  stop.edge = find(prevStopEdge + 1, myRoute->end(), &stop.lane->getEdge());
729  }
730  }
731  } else {
732  if (stopPar.index == STOP_INDEX_FIT) {
733  while (iter != myStops.end() && (iter->edge < stop.edge ||
734  (iter->endPos < stop.endPos && iter->edge == stop.edge))) {
735  prevStopEdge = iter->edge;
736  prevStopPos = iter->endPos;
737  ++iter;
738  }
739  } else {
740  int index = stopPar.index;
741  while (index > 0) {
742  prevStopEdge = iter->edge;
743  prevStopPos = iter->endPos;
744  ++iter;
745  --index;
746  }
747  stop.edge = find(prevStopEdge, myRoute->end(), &stop.lane->getEdge());
748  }
749  }
750  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
751  (prevStopEdge == stop.edge && prevStopPos > stop.endPos)) {
752  if (stop.busstop != 0) {
753  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
754  } else {
755  errorMsg = "Stop";
756  }
757  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
758  return false;
759  }
760  // David.C:
761  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
762  if (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed)) {
763  errorMsg = "Stop for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
764  return false;
765  }
766  if (!hasDeparted() && myCurrEdge == stop.edge) {
767  SUMOReal pos = -1;
769  pos = myParameter->departPos;
770  if (pos < 0.) {
771  pos += (*myCurrEdge)->getLength();
772  }
773  }
775  pos = MIN2(static_cast<SUMOReal>(getVehicleType().getLength() + POSITION_EPS), (*myCurrEdge)->getLength());
776  }
777  if (pos > stop.endPos) {
778  if (stop.busstop != 0) {
779  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
780  } else {
781  errorMsg = "Stop";
782  }
783  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
784  return false;
785  }
786  }
787  if (iter != myStops.begin()) {
788  std::list<Stop>::iterator iter2 = iter;
789  iter2--;
790  if (stop.until >= 0 && iter2->until > stop.until) {
791  if (stop.busstop != 0) {
792  errorMsg = "Bus stop '" + stop.busstop->getID() + "'";
793  } else {
794  errorMsg = "Stop";
795  }
796  errorMsg += " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
797  }
798  }
799  myStops.insert(iter, stop);
800  return true;
801 }
802 
803 
804 bool
806  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
807 }
808 
809 
810 bool
812  return isStopped() && myStops.begin()->parking;
813 }
814 
815 
816 bool
818  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
819 }
820 
821 
822 bool
824  return isStopped() && myStops.begin()->startPos <= pos && myStops.begin()->endPos >= pos;
825 }
826 
827 
828 SUMOReal
830  if (myStops.empty()) {
831  // no stops; pass
832  return currentVelocity;
833  }
834  Stop& stop = myStops.front();
835  if (stop.reached) {
836  // ok, we have already reached the next stop
837  // any waiting persons may board now
838  bool boarded = MSNet::getInstance()->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, &stop);
839  boarded &= stop.awaitedPersons.size() == 0;
840  // load containers
841  bool loaded = MSNet::getInstance()->getContainerControl().loadAnyWaiting(&myLane->getEdge(), this, &stop);
842  loaded &= stop.awaitedContainers.size() == 0;
843  if (boarded) {
844  if (stop.busstop != 0) {
845  const std::vector<MSTransportable*>& persons = myPersonDevice->getPersons();
846  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
847  stop.busstop->removeTransportable(*i);
848  }
849  }
850  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
851  stop.triggered = false;
855  }
856  }
857  if (loaded) {
858  if (stop.containerstop != 0) {
859  const std::vector<MSTransportable*>& containers = myContainerDevice->getContainers();
860  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
862  }
863  }
864  // the triggering condition has been fulfilled
865  stop.containerTriggered = false;
869  }
870  }
871  if (stop.duration <= 0 && !stop.triggered && !stop.containerTriggered) {
873  } else {
874  // we have to wait some more time
876  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
879  }
881  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
884  }
885  stop.duration -= DELTA_T;
886  return 0;
887  }
888  } else {
889  // is the next stop on the current lane?
890  if (stop.edge == myCurrEdge) {
891  // get the stopping position
892  SUMOReal endPos = stop.endPos;
893  bool busStopsMustHaveSpace = true;
894  if (stop.busstop != 0) {
895  // on bus stops, we have to wait for free place if they are in use...
896  endPos = stop.busstop->getLastFreePos(*this);
897  // at least half the bus has to fit on non-empty bus stops
898  if (endPos != stop.busstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.busstop->getBeginLanePosition()) {
899  busStopsMustHaveSpace = false;
900  }
901  }
902  bool containerStopsMustHaveSpace = true;
903  // if the stop is a container stop we check if the vehicle fits into the last free position of the stop
904  if (stop.containerstop != 0) {
905  // on container stops, we have to wait for free place if they are in use...
906  endPos = stop.containerstop->getLastFreePos(*this);
907  if (endPos != stop.containerstop->getEndLanePosition() && endPos - myType->getLength() / 2. < stop.containerstop->getBeginLanePosition()) {
908  containerStopsMustHaveSpace = false;
909  }
910  }
911  // we use the same offset for container stops as for bus stops. we might have to change it at some point!
912  if (myState.pos() + getVehicleType().getMinGap() >= endPos - BUS_STOP_OFFSET && busStopsMustHaveSpace
913  && containerStopsMustHaveSpace && myLane == stop.lane) {
914  // ok, we may stop (have reached the stop)
915  stop.reached = true;
916  MSNet::getInstance()->getVehicleControl().addWaiting(&myLane->getEdge(), this);
918  // compute stopping time
919  if (stop.until >= 0) {
920  if (stop.duration == -1) {
922  } else {
924  }
925  }
926  if (stop.busstop != 0) {
927  // let the bus stop know the vehicle
929  }
930  if (stop.containerstop != 0) {
931  // let the container stop know the vehicle
933  }
934  }
935  // decelerate
936  return getCarFollowModel().stopSpeed(this, getSpeed(), endPos - myState.pos());
937  }
938  }
939  return currentVelocity;
940 }
941 
942 
943 const ConstMSEdgeVector
945  ConstMSEdgeVector result;
946  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
947  result.push_back(*iter->edge);
948  }
949  return result;
950 }
951 
952 
953 void
954 MSVehicle::planMove(const SUMOTime t, const MSVehicle* pred, const SUMOReal lengthsInFront) {
956  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
958 }
959 
960 
961 void
962 MSVehicle::planMoveInternal(const SUMOTime t, const MSVehicle* pred, DriveItemVector& lfLinks) const {
963 #ifdef DEBUG_VEHICLE_GUI_SELECTION
964  if (gDebugSelectedVehicle == getID()) {
965  int bla = 0;
966  }
967 #endif
968  // remove information about approaching links, will be reset later in this step
969  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
970  if ((*i).myLink != 0) {
971  (*i).myLink->removeApproaching(this);
972  }
973  }
974  lfLinks.clear();
975  //
976  const MSCFModel& cfModel = getCarFollowModel();
977  const SUMOReal vehicleLength = getVehicleType().getLength();
978  const SUMOReal maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
979  SUMOReal laneMaxV = myLane->getVehicleMaxSpeed(this);
980  // vBeg is the initial maximum velocity of this vehicle in this step
981  SUMOReal v = MIN2(maxV, laneMaxV);
982 #ifndef NO_TRACI
983  if (myInfluencer != 0) {
984  const SUMOReal vMin = MAX2(SUMOReal(0), cfModel.getSpeedAfterMaxDecel(myState.mySpeed));
985  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
986  // !!! recheck - why is it done, here?
987  if (myInfluencer->isVTDControlled()) {
988  return; // !!! temporary
989  }
990  }
991 #endif
992 
993  const SUMOReal dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
994  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
995  assert(bestLaneConts.size() > 0);
996 #ifdef HAVE_INTERNAL_LANES
997  bool hadNonInternal = false;
998 #else
999  bool hadNonInternal = true;
1000 #endif
1001  SUMOReal seen = myLane->getLength() - myState.myPos; // the distance already "seen"; in the following always up to the end of the current "lane"
1002  SUMOReal seenNonInternal = 0;
1003  SUMOReal vLinkPass = MIN2(estimateSpeedAfterDistance(seen, v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1004  unsigned int view = 0;
1005  DriveProcessItem* lastLink = 0;
1006  SUMOReal gap = 0;
1007  if (pred != 0) {
1008  if (pred == myLane->getPartialOccupator()) {
1010  } else {
1012  }
1013  }
1014  std::pair<const MSVehicle*, SUMOReal> leaderInfo = std::make_pair(pred, gap);
1015  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
1016  const MSLane* lane = myLane;
1017  while (true) {
1018  // check leader on lane
1019  // leader is given for the first edge only
1020  adaptToLeader(leaderInfo, seen, lastLink, lane, v, vLinkPass);
1021  if (getLaneChangeModel().hasShadowVehicle()) {
1022  // also slow down for leaders on the shadowLane
1023  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
1024  if (shadowLane != 0) {
1025  std::pair<const MSVehicle*, SUMOReal> shadowLeaderInfo = shadowLane->getLeader(this, lane->getLength() - seen, false);
1026  adaptToLeader(shadowLeaderInfo, seen, lastLink, shadowLane, v, vLinkPass);
1027  }
1028  }
1029 
1030  // process stops
1031  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()) {
1032  // we are approaching a stop on the edge; must not drive further
1033  const Stop& stop = *myStops.begin();
1034  const SUMOReal endPos = stop.busstop == 0 ? stop.endPos : stop.busstop->getLastFreePos(*this);
1035  const SUMOReal stopDist = seen + endPos - lane->getLength();
1036  const SUMOReal stopSpeed = cfModel.stopSpeed(this, getSpeed(), stopDist);
1037  if (lastLink != 0) {
1038  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
1039  }
1040  v = MIN2(v, stopSpeed);
1041  lfLinks.push_back(DriveProcessItem(v, stopDist));
1042  break;
1043  }
1044 
1045  // move to next lane
1046  // get the next link used
1047  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
1048  // check whether the vehicle is on its final edge
1049  if (myCurrEdge + view + 1 == myRoute->end()) {
1051  myParameter->arrivalSpeed : laneMaxV);
1052  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
1053  const SUMOReal distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
1054  const SUMOReal va = cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed);
1055  v = MIN2(v, va);
1056  if (lastLink != 0) {
1057  lastLink->adaptLeaveSpeed(va);
1058  }
1059  lfLinks.push_back(DriveProcessItem(v, seen));
1060  break;
1061  }
1062  // check whether the lane is a dead end
1063  if (lane->isLinkEnd(link)) {
1064  SUMOReal va = MIN2(cfModel.stopSpeed(this, getSpeed(), seen), laneMaxV);
1065  if (lastLink != 0) {
1066  lastLink->adaptLeaveSpeed(va);
1067  }
1068  v = MIN2(va, v);
1069  lfLinks.push_back(DriveProcessItem(v, seen));
1070  break;
1071  }
1072  const bool yellowOrRed = (*link)->getState() == LINKSTATE_TL_RED ||
1073  (*link)->getState() == LINKSTATE_TL_REDYELLOW ||
1074  (*link)->getState() == LINKSTATE_TL_YELLOW_MAJOR ||
1075  (*link)->getState() == LINKSTATE_TL_YELLOW_MINOR;
1076  // We distinguish 3 cases when determining the point at which a vehicle stops:
1077  // - links that require stopping: here the vehicle needs to stop close to the stop line
1078  // to ensure it gets onto the junction in the next step. Othwise the vehicle would 'forget'
1079  // that it already stopped and need to stop again. This is necessary pending implementation of #999
1080  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
1081  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
1082  // to minimize the time window for passing the junction. If the
1083  // vehicle 'decides' to accelerate and cannot enter the junction in
1084  // the next step, new foes may appear and cause a collision (see #1096)
1085  // - major links: stopping point is irrelevant
1086  const SUMOReal laneStopOffset = yellowOrRed || (*link)->havePriority() ? DIST_TO_STOPLINE_EXPECT_PRIORITY : POSITION_EPS;
1087  const SUMOReal stopDist = MAX2(SUMOReal(0), seen - laneStopOffset);
1088  // check whether we need to slow down in order to finish a continuous lane change
1089  if (getLaneChangeModel().isChangingLanes()) {
1090  if ( // slow down to finish lane change before a turn lane
1091  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
1092  // slow down to finish lane change before the shadow lane ends
1094  (*link)->getViaLaneOrLane()->getParallelLane(-getLaneChangeModel().getLaneChangeDirection()) == 0)) {
1095  // XXX maybe this is too harsh. Vehicles could cut some corners here
1096  const SUMOReal timeRemaining = STEPS2TIME((1 - getLaneChangeModel().getLaneChangeCompletion()) * MSGlobals::gLaneChangeDuration);
1097  const SUMOReal va = MAX2((SUMOReal)0, (seen - POSITION_EPS) / timeRemaining);
1098  v = MIN2(va, v);
1099  }
1100  }
1101 
1102  // - even if red, if we cannot break we should issue a request
1103  // - always issue a request to leave the intersection we are currently on
1104  bool setRequest = v > 0 || (myLane->getEdge().isInternal() && lastLink == 0);
1105  SUMOReal vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
1106  const SUMOReal brakeDist = cfModel.brakeGap(myState.mySpeed) - myState.mySpeed * cfModel.getHeadwayTime();
1107  if (yellowOrRed && seen >= brakeDist) {
1108  // the vehicle is able to brake in front of a yellow/red traffic light
1109  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
1110  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
1111  break;
1112  }
1113 
1114 #ifdef HAVE_INTERNAL_LANES
1115  // we want to pass the link but need to check for foes on internal lanes
1116  const MSLink::LinkLeaders linkLeaders = (*link)->getLeaderInfo(seen, getVehicleType().getMinGap());
1117  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
1118  // the vehicle to enter the junction first has priority
1119  const MSVehicle* leader = (*it).vehAndGap.first;
1120  if (leader == 0) {
1121  // leader is a pedestrian. Passing 'this' as a dummy.
1122  //std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << (*link)->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
1123  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1124  } else if (leader->myLinkLeaders[(*link)->getJunction()].count(getID()) == 0) {
1125  // leader isn't already following us, now we follow it
1126  myLinkLeaders[(*link)->getJunction()].insert(leader->getID());
1127  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
1128  if (lastLink != 0) {
1129  // we are not yet on the junction with this linkLeader.
1130  // at least we can drive up to the previous link and stop there
1131  v = MAX2(v, lastLink->myVLinkWait);
1132  }
1133  // if blocked by a leader from the same lane we must yield our request
1134  if (v < SUMO_const_haltingSpeed && leader->getLane()->getLogicalPredecessorLane() == myLane->getLogicalPredecessorLane()) {
1135  setRequest = false;
1136  }
1137  }
1138  }
1139  // if this is the link between two internal lanes we may have to slow down for pedestrians
1140  vLinkWait = MIN2(vLinkWait, v);
1141 #endif
1142 
1143  if (lastLink != 0) {
1144  lastLink->adaptLeaveSpeed(laneMaxV);
1145  }
1146  SUMOReal arrivalSpeed = vLinkPass;
1147  // vehicles should decelerate when approaching a minor link
1148  // - unless they are close enough to have clear visibility and may start to accelerate again
1149  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
1150  if (!(*link)->havePriority() && stopDist > cfModel.getMaxDecel() && brakeDist < seen) {
1151  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
1152  arrivalSpeed = cfModel.getMaxDecel() + cfModel.getMaxAccel();
1153  }
1154  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
1155  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
1156  const SUMOReal accel = (arrivalSpeed >= v) ? cfModel.getMaxAccel() : -cfModel.getMaxDecel();
1157  const SUMOReal accelTime = (arrivalSpeed - v) / accel;
1158  const SUMOReal accelWay = accelTime * (arrivalSpeed + v) * 0.5;
1159  const SUMOReal nonAccelWay = MAX2(SUMOReal(0), seen - accelWay);
1160  // will either drive as fast as possible and decelerate as late as possible
1161  // or accelerate as fast as possible and then hold that speed
1162  const SUMOReal nonAccelSpeed = MAX3(v, arrivalSpeed, SUMO_const_haltingSpeed);
1163  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
1164  const SUMOTime arrivalTime = t - DELTA_T + TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
1165 
1166  // compute speed, time if vehicle starts braking now
1167  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
1168  SUMOReal arrivalSpeedBraking = 0;
1169  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
1170  if (seen < cfModel.brakeGap(v)) {
1171  // vehicle cannot come to a complete stop in time
1172  // Because we use a continuous formula for computiing the possible slow-down
1173  // we need to handle the mismatch with the discrete dynamics
1174  if (seen < v) {
1175  arrivalSpeedBraking = arrivalSpeed; // no time left for braking after this step
1176  } else if (2 * (seen - v * cfModel.getHeadwayTime()) * -cfModel.getMaxDecel() + v * v >= 0) {
1177  arrivalSpeedBraking = estimateSpeedAfterDistance(seen - v * cfModel.getHeadwayTime(), v, -cfModel.getMaxDecel());
1178  } else {
1179  arrivalSpeedBraking = cfModel.getMaxDecel();
1180  }
1181  // due to discrecte/continuous mismatch we have to ensure that braking actually helps
1182  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
1183  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
1184  }
1185  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
1186  arrivalTime, arrivalSpeed,
1187  arrivalTimeBraking, arrivalSpeedBraking,
1188  seen,
1189  estimateLeaveSpeed(*link, vLinkPass)));
1190 #ifdef HAVE_INTERNAL_LANES
1191  if ((*link)->getViaLane() == 0) {
1192  hadNonInternal = true;
1193  ++view;
1194  }
1195 #else
1196  ++view;
1197 #endif
1198  // we need to look ahead far enough to see available space for checkRewindLinkLanes
1199  if (!setRequest || ((v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > vehicleLength * CRLL_LOOK_AHEAD)) {
1200  break;
1201  }
1202  // get the following lane
1203  lane = (*link)->getViaLaneOrLane();
1204  laneMaxV = lane->getVehicleMaxSpeed(this);
1205  // the link was passed
1206  // compute the velocity to use when the link is not blocked by other vehicles
1207  // the vehicle shall be not faster when reaching the next lane than allowed
1208  const SUMOReal va = MAX2(laneMaxV, cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV));
1209  v = MIN2(va, v);
1210  seenNonInternal += lane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL ? 0 : lane->getLength();
1211  seen += lane->getLength();
1212  leaderInfo = lane->getLastVehicleInformation();
1213  leaderInfo.second = leaderInfo.second + seen - lane->getLength() - getVehicleType().getMinGap();
1214  vLinkPass = MIN2(estimateSpeedAfterDistance(lane->getLength(), v, getVehicleType().getCarFollowModel().getMaxAccel()), laneMaxV); // upper bound
1215  lastLink = &lfLinks.back();
1216  }
1217 
1218 }
1219 
1220 
1221 void
1222 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1223  const SUMOReal seen, DriveProcessItem* const lastLink,
1224  const MSLane* const lane, SUMOReal& v, SUMOReal& vLinkPass,
1225  SUMOReal distToCrossing) const {
1226  if (leaderInfo.first != 0) {
1227  const SUMOReal vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
1228  if (lastLink != 0) {
1229  lastLink->adaptLeaveSpeed(vsafeLeader);
1230  }
1231  v = MIN2(v, vsafeLeader);
1232  vLinkPass = MIN2(vLinkPass, vsafeLeader);
1233  }
1234 }
1235 
1236 
1237 SUMOReal
1238 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, SUMOReal> leaderInfo,
1239  const SUMOReal seen, const MSLane* const lane, SUMOReal distToCrossing) const {
1240  assert(leaderInfo.first != 0);
1241  const MSCFModel& cfModel = getCarFollowModel();
1242  SUMOReal vsafeLeader = 0;
1243  if (leaderInfo.second >= 0) {
1244  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCarFollowModel().getMaxDecel());
1245  } else {
1246  // the leading, in-lapping vehicle is occupying the complete next lane
1247  // stop before entering this lane
1248  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
1249  }
1250  if (distToCrossing >= 0) {
1251  // drive up to the crossing point with the current link leader
1252  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing));
1253  }
1254  return vsafeLeader;
1255 }
1256 
1257 
1258 bool
1260 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1261  if (gDebugSelectedVehicle == getID()) {
1262  int bla = 0;
1263  }
1264 #endif
1265  // get safe velocities from DriveProcessItems
1266  SUMOReal vSafe = 0; // maximum safe velocity
1267  SUMOReal vSafeMin = 0; // minimum safe velocity
1268  // the distance to a link which should either be crossed this step or in
1269  // front of which we need to stop
1270  SUMOReal vSafeMinDist = 0;
1271  myHaveToWaitOnNextLink = false;
1272 #ifndef NO_TRACI
1273  if (myInfluencer != 0) {
1274  if (myInfluencer->isVTDControlled()) {
1275  return false;
1276  }
1277  }
1278 #endif
1279 
1280  assert(myLFLinkLanes.size() != 0 || (myInfluencer != 0 && myInfluencer->isVTDControlled()));
1281  DriveItemVector::iterator i;
1282  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
1283  MSLink* link = (*i).myLink;
1284  // the vehicle must change the lane on one of the next lanes
1285  if (link != 0 && (*i).mySetRequest) {
1286  const LinkState ls = link->getState();
1287  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
1288  const bool yellow = ls == LINKSTATE_TL_YELLOW_MAJOR || ls == LINKSTATE_TL_YELLOW_MINOR;
1290  if (yellow && ((*i).myDistance > brakeGap || myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1291  vSafe = (*i).myVLinkWait;
1292  myHaveToWaitOnNextLink = true;
1293  link->removeApproaching(this);
1294  break;
1295  }
1296  //
1297 #ifdef NO_TRACI
1298  const bool influencerPrio = false;
1299 #else
1300  const bool influencerPrio = (myInfluencer != 0 && !myInfluencer->getRespectJunctionPriority());
1301 #endif
1302  const bool opened = yellow || influencerPrio ||
1303  link->opened((*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1306  // vehicles should decelerate when approaching a minor link
1307  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont()) {
1308  if ((*i).myDistance > getCarFollowModel().getMaxDecel()) {
1309  vSafe = (*i).myVLinkWait;
1310  myHaveToWaitOnNextLink = true;
1311  if (ls == LINKSTATE_EQUAL) {
1312  link->removeApproaching(this);
1313  }
1314  break; // could be revalidated
1315  } else {
1316  // past the point of no return. we need to drive fast enough
1317  // to make it across the link. However, minor slowdowns
1318  // should be permissible to follow leading traffic safely
1319  // There is a problem in subsecond simulation: If we cannot
1320  // make it across the minor link in one step, new traffic
1321  // could appear on a major foe link and cause a collision
1322  vSafeMin = MIN2((SUMOReal) DIST2SPEED(myLane->getLength() - getPositionOnLane() + POSITION_EPS), (*i).myVLinkPass);
1323  vSafeMinDist = myLane->getLength() - getPositionOnLane();
1324  }
1325  }
1326  // have waited; may pass if opened...
1327  if (opened) {
1328  vSafe = (*i).myVLinkPass;
1329  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= (*i).myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
1330  // this vehicle is probably not gonna drive accross the next junction (heuristic)
1331  myHaveToWaitOnNextLink = true;
1332  }
1333  } else {
1334  vSafe = (*i).myVLinkWait;
1335  myHaveToWaitOnNextLink = true;
1336  if (ls == LINKSTATE_EQUAL) {
1337  link->removeApproaching(this);
1338  }
1339  break;
1340  }
1341  } else {
1342  vSafe = (*i).myVLinkWait;
1343  if (vSafe < getSpeed()) {
1344  myHaveToWaitOnNextLink = true;
1345  }
1346  break;
1347  }
1348  }
1349  if (vSafe + NUMERICAL_EPS < vSafeMin) {
1350  // cannot drive across a link so we need to stop before it
1351  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
1352  vSafeMin = 0;
1353  myHaveToWaitOnNextLink = true;
1354  }
1355  // vehicles inside a roundabout should maintain their requests
1356  if (myLane->getEdge().isRoundabout()) {
1357  myHaveToWaitOnNextLink = false;
1358  }
1359 
1360  // XXX braking due to lane-changing is not registered
1361  bool braking = vSafe < getSpeed();
1362  // apply speed reduction due to dawdling / lane changing but ensure minimum safe speed
1363  SUMOReal vNext = MAX2(getCarFollowModel().moveHelper(this, vSafe), vSafeMin);
1364 
1365  // vNext may be higher than vSafe without implying a bug:
1366  // - when approaching a green light that suddenly switches to yellow
1367  // - when using unregulated junctions
1368  // - when using tau < step-size
1369  // - when using unsafe car following models
1370  // - when using TraCI and some speedMode / laneChangeMode settings
1371  //if (vNext > vSafe + NUMERICAL_EPS) {
1372  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
1373  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
1374  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1375  //}
1376  vNext = MAX2(vNext, (SUMOReal) 0.);
1377 #ifndef NO_TRACI
1378  if (myInfluencer != 0) {
1380  const SUMOReal vMin = MAX2(SUMOReal(0), getVehicleType().getCarFollowModel().getSpeedAfterMaxDecel(myState.mySpeed));
1381  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
1382  if (myInfluencer->isVTDControlled()) {
1383  vNext = 0;
1384  }
1385  }
1386 #endif
1387  // visit waiting time
1388  if (vNext <= SUMO_const_haltingSpeed) {
1390  braking = true;
1391  } else {
1392  myWaitingTime = 0;
1393  }
1394  if (braking) {
1396  } else {
1398  }
1399  // call reminders after vNext is set
1400  const SUMOReal pos = myState.myPos;
1401 
1402  // update position and speed
1404  myState.myPos += SPEED2DIST(vNext);
1405  myState.mySpeed = vNext;
1407  std::vector<MSLane*> passedLanes;
1408  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
1409  passedLanes.push_back(*i);
1410  }
1411  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
1412  passedLanes.push_back(myLane);
1413  }
1414  bool moved = false;
1415  std::string emergencyReason = " for unknown reasons";
1416  // move on lane(s)
1417  if (myState.myPos <= myLane->getLength()) {
1418  // we are staying at our lane
1419  // there is no need to go over succeeding lanes
1420  workOnMoveReminders(pos, pos + SPEED2DIST(vNext), vNext);
1421  } else {
1422  // we are moving at least to the next lane (maybe pass even more than one)
1423  if (myCurrEdge != myRoute->end() - 1) {
1424  MSLane* approachedLane = myLane;
1425  // move the vehicle forward
1426  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end() && approachedLane != 0 && myState.myPos > approachedLane->getLength(); ++i) {
1428  MSLink* link = (*i).myLink;
1429  // check whether the vehicle was allowed to enter lane
1430  // otherwise it is decelareted and we do not need to test for it's
1431  // approach on the following lanes when a lane changing is performed
1432  // proceed to the next lane
1433  if (link != 0) {
1434  approachedLane = link->getViaLaneOrLane();
1435 #ifndef NO_TRACI
1437 #endif
1438  if (link->getState() == LINKSTATE_TL_RED) {
1439  emergencyReason = " because of a red traffic light";
1440  break;
1441  }
1442 #ifndef NO_TRACI
1443  }
1444 #endif
1445  } else {
1446  emergencyReason = " because there is no connection to the next edge";
1447  approachedLane = 0;
1448  break;
1449  }
1450  if (approachedLane != myLane && approachedLane != 0) {
1451  myState.myPos -= myLane->getLength();
1452  assert(myState.myPos > 0);
1453  enterLaneAtMove(approachedLane);
1454  myLane = approachedLane;
1455  if (hasArrived()) {
1456  break;
1457  }
1458  if (getLaneChangeModel().isChangingLanes()) {
1459  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
1460  // abort lane change
1461  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
1462  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1464  }
1465  }
1466 #ifdef HAVE_INTERNAL_LANES
1467  // erase leaders when past the junction
1468  if (link->getViaLane() == 0) {
1469  myLinkLeaders[link->getJunction()].clear();
1470  }
1471 #endif
1472  moved = true;
1473  if (approachedLane->getEdge().isVaporizing()) {
1475  break;
1476  }
1477  }
1478  passedLanes.push_back(approachedLane);
1479  }
1480  }
1481  }
1482  // clear previously set information
1483  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1484  (*i)->resetPartialOccupation(this);
1485  }
1486  myFurtherLanes.clear();
1487 
1488  if (myInfluencer != 0 && myInfluencer->isVTDControlled()) {
1489  myWaitingTime = 0;
1490  return false;
1491  }
1492 
1493  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
1494  if (myState.myPos > myLane->getLength()) {
1495  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
1496  + emergencyReason
1497  + " (decel=" + toString(myAcceleration - myState.mySpeed)
1498  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1501  myState.mySpeed = 0;
1502  }
1503  if (myState.myPos - getVehicleType().getLength() < 0 && passedLanes.size() > 0) {
1504  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1505  std::vector<MSLane*>::reverse_iterator i = passedLanes.rbegin() + 1;
1506  while (leftLength > 0 && i != passedLanes.rend()) {
1507  myFurtherLanes.push_back(*i);
1508  leftLength -= (*i)->setPartialOccupation(this, leftLength);
1509  ++i;
1510  }
1511  }
1512  updateBestLanes();
1513  // bestLanes need to be updated before lane changing starts
1514  if (getLaneChangeModel().isChangingLanes()) {
1516  }
1517  setBlinkerInformation(); // needs updated bestLanes
1518  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1520  }
1521  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
1522  return moved;
1523 }
1524 
1525 
1526 SUMOReal
1527 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
1528  SUMOReal lengths = 0;
1529  const MSLane::VehCont& vehs = l->getVehiclesSecure();
1530  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1531  if ((*i)->getSpeed() < SUMO_const_haltingSpeed && !(*i)->getLane()->getEdge().isRoundabout()) {
1532  foundStopped = true;
1533  const SUMOReal ret = (*i)->getPositionOnLane() - (*i)->getVehicleType().getLengthWithGap() - lengths;
1534  l->releaseVehicles();
1535  return ret;
1536  }
1537  lengths += (*i)->getVehicleType().getLengthWithGap();
1538  }
1539  l->releaseVehicles();
1540  return l->getLength() - lengths;
1541 }
1542 
1543 
1544 void
1545 MSVehicle::checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector& lfLinks) const {
1546 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1547  if (gDebugSelectedVehicle == getID()) {
1548  int bla = 0;
1549  }
1550 #endif
1551 #ifdef HAVE_INTERNAL_LANES
1553  bool hadVehicle = false;
1554  SUMOReal seenSpace = -lengthsInFront;
1555 
1556  bool foundStopped = false;
1557  // compute available space until a stopped vehicle is found
1558  // this is the sum of non-interal lane length minus in-between vehicle lenghts
1559  for (unsigned int i = 0; i < lfLinks.size(); ++i) {
1560  // skip unset links
1561  DriveProcessItem& item = lfLinks[i];
1562  if (item.myLink == 0 || foundStopped) {
1563  item.availableSpace = seenSpace;
1564  item.hadVehicle = hadVehicle;
1565  continue;
1566  }
1567  // get the next lane, determine whether it is an internal lane
1568  const MSLane* approachedLane = item.myLink->getViaLane();
1569  if (approachedLane != 0) {
1570  if (item.myLink->hasFoes() && item.myLink->keepClear()/* && item.myLink->willHaveBlockedFoe()*/) {
1571  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
1572  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1573  } else {
1574  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1575  hadVehicle |= approachedLane->getVehicleNumber() != 0;
1576  }
1577  item.availableSpace = seenSpace;
1578  item.hadVehicle = hadVehicle;
1579  continue;
1580  }
1581  approachedLane = item.myLink->getLane();
1582  const MSVehicle* last = approachedLane->getLastVehicle();
1583  if (last == 0) {
1584  last = approachedLane->getPartialOccupator();
1585  if (last != 0) {
1587  item.availableSpace = MAX2(seenSpace, seenSpace + approachedLane->getPartialOccupatorEnd() + last->getCarFollowModel().brakeGap(last->getSpeed()));
1588  hadVehicle = true;
1590  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1592  if (last->myHaveToWaitOnNextLink) {
1593  foundStopped = true;
1594  }
1595  } else {
1596  seenSpace += approachedLane->getLength();
1597  item.availableSpace = seenSpace;
1598  }
1599  } else {
1600  if (last->signalSet(VEH_SIGNAL_BRAKELIGHT)) {
1601  const SUMOReal lastBrakeGap = last->getCarFollowModel().brakeGap(approachedLane->getLastVehicle()->getSpeed());
1602  const SUMOReal lastGap = last->getPositionOnLane() - last->getVehicleType().getLengthWithGap() + lastBrakeGap - last->getSpeed() * last->getCarFollowModel().getHeadwayTime();
1603  item.availableSpace = MAX2(seenSpace, seenSpace + lastGap);
1604  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
1605  } else {
1606  seenSpace += getSpaceTillLastStanding(approachedLane, foundStopped);
1607  item.availableSpace = seenSpace;
1608  }
1609  if (last->myHaveToWaitOnNextLink) {
1610  foundStopped = true;
1611  }
1612  hadVehicle = true;
1613  }
1614  item.hadVehicle = hadVehicle;
1615  }
1616 
1617 
1618 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1619  if (gDebugSelectedVehicle == getID()) {
1620  int bla = 0;
1621  }
1622 #endif
1623  // check which links allow continuation and add pass available to the previous item
1624  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
1625  DriveProcessItem& item = lfLinks[i - 1];
1626  const bool canLeaveJunction = item.myLink->getViaLane() == 0 || lfLinks[i].mySetRequest;
1627  const bool opened = item.myLink != 0 && canLeaveJunction && (item.myLink->havePriority() ||
1628 #ifndef NO_TRACI
1630 #endif
1631  item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
1634  bool allowsContinuation = item.myLink == 0 || item.myLink->isCont() || !lfLinks[i].hadVehicle || opened;
1635  if (!opened && item.myLink != 0) {
1636  if (i > 1) {
1637  DriveProcessItem& item2 = lfLinks[i - 2];
1638  if (item2.myLink != 0 && item2.myLink->isCont()) {
1639  allowsContinuation = true;
1640  }
1641  }
1642  }
1643  if (allowsContinuation) {
1644  item.availableSpace = lfLinks[i].availableSpace;
1645  }
1646  }
1647 
1648  // find removalBegin
1649  int removalBegin = -1;
1650  for (unsigned int i = 0; hadVehicle && i < lfLinks.size() && removalBegin < 0; ++i) {
1651  // skip unset links
1652  const DriveProcessItem& item = lfLinks[i];
1653  if (item.myLink == 0) {
1654  continue;
1655  }
1656  /*
1657  SUMOReal impatienceCorrection = MAX2(SUMOReal(0), SUMOReal(SUMOReal(myWaitingTime)));
1658  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
1659  removalBegin = lastLinkToInternal;
1660  }
1661  */
1662 
1663  const SUMOReal leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
1664  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
1665  SUMOReal impatienceCorrection = 0;
1666  /*
1667  if(item.myLink->getState()==LINKSTATE_MINOR) {
1668  impatienceCorrection = MAX2(SUMOReal(0), STEPS2TIME(myWaitingTime));
1669  }
1670  */
1671  if (leftSpace < -impatienceCorrection / 10. && item.myLink->hasFoes() && item.myLink->keepClear()) {
1672  removalBegin = i;
1673  }
1674  //removalBegin = i;
1675  }
1676  }
1677  // abort requests
1678  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL)) {
1679  while (removalBegin < (int)(lfLinks.size())) {
1681  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
1682  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
1683  lfLinks[removalBegin].mySetRequest = false;
1684  }
1685  ++removalBegin;
1686  }
1687  }
1688  }
1689 #else
1690  UNUSED_PARAMETER(lengthsInFront);
1691 #endif
1692  for (DriveItemVector::iterator i = lfLinks.begin(); i != lfLinks.end(); ++i) {
1693  if ((*i).myLink != 0) {
1694  if ((*i).myLink->getState() == LINKSTATE_ALLWAY_STOP) {
1695  (*i).myArrivalTime += (SUMOTime)RandHelper::rand((size_t)2); // tie braker
1696  }
1697  (*i).myLink->setApproaching(this, (*i).myArrivalTime, (*i).myArrivalSpeed, (*i).getLeaveSpeed(),
1698  (*i).mySetRequest, (*i).myArrivalTimeBraking, (*i).myArrivalSpeedBraking, getWaitingTime());
1699  }
1700  }
1701 }
1702 
1703 
1704 void
1706  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1707  if (rem->first->getLane() != 0 && rem->first->getLane() != getLane()) {
1708 #ifdef _DEBUG
1709  if (myTraceMoveReminders) {
1710  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
1711  }
1712 #endif
1713  ++rem;
1714  } else {
1715  if (rem->first->notifyEnter(*this, reason)) {
1716 #ifdef _DEBUG
1717  if (myTraceMoveReminders) {
1718  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
1719  }
1720 #endif
1721  ++rem;
1722  } else {
1723 #ifdef _DEBUG
1724  if (myTraceMoveReminders) {
1725  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
1726  }
1727 #endif
1728  rem = myMoveReminders.erase(rem);
1729  }
1730  }
1731  }
1732 }
1733 
1734 
1735 bool
1736 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
1737  myAmOnNet = !onTeleporting;
1738  // vaporizing edge?
1739  /*
1740  if (enteredLane->getEdge().isVaporizing()) {
1741  // yep, let's do the vaporization...
1742  myLane = enteredLane;
1743  return true;
1744  }
1745  */
1746  // move mover reminder one lane further
1747  adaptLaneEntering2MoveReminder(*enteredLane);
1748  // set the entered lane as the current lane
1749  myLane = enteredLane;
1750 
1751  // internal edges are not a part of the route...
1752  if (enteredLane->getEdge().getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
1753  ++myCurrEdge;
1754  }
1755  if (!onTeleporting) {
1757  } else {
1759  // normal move() isn't called so reset position here
1760  myState.myPos = 0;
1762  }
1763  return hasArrived();
1764 }
1765 
1766 
1767 void
1769  myAmOnNet = true;
1770  myLane = enteredLane;
1772  // need to update myCurrentLaneInBestLanes
1773  updateBestLanes();
1774  // switch to and activate the new lane's reminders
1775  // keep OldLaneReminders
1776  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1777  addReminder(*rem);
1778  }
1780  MSLane* lane = myLane;
1781  SUMOReal leftLength = getVehicleType().getLength() - myState.myPos;
1782  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
1783  if (lane != 0) {
1784  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
1785  }
1786  if (lane != 0) {
1787  myFurtherLanes[i]->resetPartialOccupation(this);
1788  myFurtherLanes[i] = lane;
1789  leftLength -= (lane)->setPartialOccupation(this, leftLength);
1790  } else {
1791  // keep the old values, but ensure there is no shadow
1794  }
1795  }
1796  }
1797 }
1798 
1799 
1800 void
1802  myState = State(pos, speed);
1804  assert(myState.myPos >= 0);
1805  assert(myState.mySpeed >= 0);
1806  myWaitingTime = 0;
1807  myLane = enteredLane;
1808  myAmOnNet = true;
1809  // set and activate the new lane's reminders
1810  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
1811  addReminder(*rem);
1812  }
1813  activateReminders(notification);
1814  std::string msg;
1815  if (MSGlobals::gCheckRoutes && !hasValidRoute(msg)) {
1816  throw ProcessError("Vehicle '" + getID() + "' has no valid route. " + msg);
1817  }
1818  // build the list of lanes the vehicle is lapping into
1819  SUMOReal leftLength = myType->getLength() - pos;
1820  MSLane* clane = enteredLane;
1821  while (leftLength > 0) {
1822  clane = clane->getLogicalPredecessorLane();
1823  if (clane == 0) {
1824  break;
1825  }
1826  myFurtherLanes.push_back(clane);
1827  leftLength -= (clane)->setPartialOccupation(this, leftLength);
1828  }
1829 }
1830 
1831 
1832 void
1834  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1835  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason)) {
1836 #ifdef _DEBUG
1837  if (myTraceMoveReminders) {
1838  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
1839  }
1840 #endif
1841  ++rem;
1842  } else {
1843 #ifdef _DEBUG
1844  if (myTraceMoveReminders) {
1845  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
1846  }
1847 #endif
1848  rem = myMoveReminders.erase(rem);
1849  }
1850  }
1852  // @note. In case of lane change, myFurtherLanes and partial occupation
1853  // are handled in enterLaneAtLaneChange()
1854  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1855  (*i)->resetPartialOccupation(this);
1856  }
1857  myFurtherLanes.clear();
1858  }
1859  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
1860  myAmOnNet = false;
1861  }
1863  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
1864  }
1866  while (!myStops.empty() && myStops.front().edge == myCurrEdge) {
1867  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
1868  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
1869  myStops.pop_front();
1870  }
1871  }
1872 }
1873 
1874 
1877  return *myLaneChangeModel;
1878 }
1879 
1880 
1883  return *myLaneChangeModel;
1884 }
1885 
1886 
1887 const std::vector<MSVehicle::LaneQ>&
1889  return *myBestLanes.begin();
1890 }
1891 
1892 
1893 void
1894 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
1895 #ifdef DEBUG_VEHICLE_GUI_SELECTION
1896  if (gDebugSelectedVehicle == getID()) {
1897  int bla = 0;
1898  myLastBestLanesEdge = 0;
1899  }
1900 #endif
1901  if (startLane == 0) {
1902  startLane = myLane;
1903  }
1904  assert(startLane != 0);
1905  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
1907  return;
1908  }
1909  if (startLane->getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
1910  if (myBestLanes.size() == 0 || forceRebuild) {
1911  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
1912  updateBestLanes(true, startLane->getLogicalPredecessorLane());
1913  }
1914  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
1915  return;
1916  }
1917  // adapt best lanes to fit the current internal edge:
1918  // keep the entries that are reachable from this edge
1919  const MSEdge* nextEdge = startLane->getInternalFollower();
1920  assert(nextEdge->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL);
1921  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
1922  std::vector<LaneQ>& lanes = *it;
1923  assert(lanes.size() > 0);
1924  if (&(lanes[0].lane->getEdge()) == nextEdge) {
1925  // keep those lanes which are successors of internal lanes from the edge of startLane
1926  std::vector<LaneQ> oldLanes = lanes;
1927  lanes.clear();
1928  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
1929  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
1930  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
1931  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
1932  lanes.push_back(*it_lane);
1933  break;
1934  }
1935  }
1936  }
1937  assert(lanes.size() == startLane->getEdge().getLanes().size());
1938  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
1939  for (int i = 0; i < (int)lanes.size(); ++i) {
1940  if (i + lanes[i].bestLaneOffset < 0) {
1941  lanes[i].bestLaneOffset = -i;
1942  }
1943  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
1944  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
1945  }
1946  assert(i + lanes[i].bestLaneOffset >= 0);
1947  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
1948  if (lanes[i].bestContinuations[0] != 0) {
1949  // patch length of bestContinuation to match expectations (only once)
1950  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)0);
1951  }
1952  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
1953  myCurrentLaneInBestLanes = lanes.begin() + i;
1954  }
1955  assert(&(lanes[i].lane->getEdge()) == nextEdge);
1956  }
1957  myLastBestLanesInternalLane = startLane;
1959  return;
1960  } else {
1961  // remove passed edges
1962  it = myBestLanes.erase(it);
1963  }
1964  }
1965  assert(false); // should always find the next edge
1966  }
1967  // start rebuilding
1968  myLastBestLanesEdge = &startLane->getEdge();
1969  myBestLanes.clear();
1970 
1971  // get information about the next stop
1972  const MSEdge* nextStopEdge = 0;
1973  const MSLane* nextStopLane = 0;
1974  SUMOReal nextStopPos = 0;
1975  if (!myStops.empty()) {
1976  const Stop& nextStop = myStops.front();
1977  nextStopLane = nextStop.lane;
1978  nextStopEdge = &nextStopLane->getEdge();
1979  nextStopPos = nextStop.startPos;
1980  }
1981  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == 0) {
1982  nextStopEdge = *(myRoute->end() - 1);
1983  nextStopLane = nextStopEdge->getLanes()[myParameter->arrivalLane];
1984  nextStopPos = myArrivalPos;
1985  }
1986  if (nextStopEdge != 0) {
1987  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
1988  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
1989  nextStopPos = MAX2(POSITION_EPS, MIN2((SUMOReal)nextStopPos, (SUMOReal)(nextStopEdge->getLength() - 2 * POSITION_EPS)));
1990  }
1991 
1992  // go forward along the next lanes;
1993  int seen = 0;
1994  SUMOReal seenLength = 0;
1995  bool progress = true;
1996  for (MSRouteIterator ce = myCurrEdge; progress;) {
1997  std::vector<LaneQ> currentLanes;
1998  const std::vector<MSLane*>* allowed = 0;
1999  const MSEdge* nextEdge = 0;
2000  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
2001  nextEdge = *(ce + 1);
2002  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
2003  }
2004  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
2005  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
2006  LaneQ q;
2007  MSLane* cl = *i;
2008  q.lane = cl;
2009  q.bestContinuations.push_back(cl);
2010  q.bestLaneOffset = 0;
2011  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
2012  q.allowsContinuation = allowed == 0 || find(allowed->begin(), allowed->end(), cl) != allowed->end();
2013  currentLanes.push_back(q);
2014  }
2015  //
2016  if (nextStopEdge == *ce) {
2017  progress = false;
2018  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
2019  if (nextStopLane != 0 && nextStopLane != (*q).lane) {
2020  (*q).allowsContinuation = false;
2021  (*q).length = nextStopPos;
2022  }
2023  }
2024  }
2025 
2026  myBestLanes.push_back(currentLanes);
2027  ++seen;
2028  seenLength += currentLanes[0].lane->getLength();
2029  ++ce;
2030  progress &= (seen <= 4 || seenLength < 3000);
2031  progress &= seen <= 8;
2032  progress &= ce != myRoute->end();
2033  /*
2034  if(progress) {
2035  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
2036  }
2037  */
2038  }
2039 
2040  // we are examining the last lane explicitly
2041  if (myBestLanes.size() != 0) {
2042  SUMOReal bestLength = -1;
2043  int bestThisIndex = 0;
2044  int index = 0;
2045  std::vector<LaneQ>& last = myBestLanes.back();
2046  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2047  if ((*j).length > bestLength) {
2048  bestLength = (*j).length;
2049  bestThisIndex = index;
2050  }
2051  }
2052  index = 0;
2053  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
2054  if ((*j).length < bestLength) {
2055  (*j).bestLaneOffset = bestThisIndex - index;
2056  }
2057  }
2058  }
2059 
2060  // go backward through the lanes
2061  // track back best lane and compute the best prior lane(s)
2062  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
2063  std::vector<LaneQ>& nextLanes = (*(i - 1));
2064  std::vector<LaneQ>& clanes = (*i);
2065  MSEdge& cE = clanes[0].lane->getEdge();
2066  int index = 0;
2067  SUMOReal bestConnectedLength = -1;
2068  SUMOReal bestLength = -1;
2069  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
2070  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
2071  bestConnectedLength = (*j).length;
2072  }
2073  if (bestLength < (*j).length) {
2074  bestLength = (*j).length;
2075  }
2076  }
2077  // compute index of the best lane (highest length and least offset from the best next lane)
2078  int bestThisIndex = 0;
2079  if (bestConnectedLength > 0) {
2080  index = 0;
2081  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2082  LaneQ bestConnectedNext;
2083  bestConnectedNext.length = -1;
2084  if ((*j).allowsContinuation) {
2085  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
2086  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2087  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
2088  bestConnectedNext = *m;
2089  }
2090  }
2091  }
2092  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
2093  (*j).length += bestLength;
2094  } else {
2095  (*j).length += bestConnectedNext.length;
2096  }
2097  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
2098  }
2099  if (clanes[bestThisIndex].length < (*j).length || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))) {
2100  bestThisIndex = index;
2101  }
2102  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
2103  }
2104 
2105  } else {
2106  int bestNextIndex = 0;
2107  int bestDistToNeeded = (int) clanes.size();
2108  index = 0;
2109  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2110  if ((*j).allowsContinuation) {
2111  int nextIndex = 0;
2112  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
2113  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
2114  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
2115  bestDistToNeeded = abs((*m).bestLaneOffset);
2116  bestThisIndex = index;
2117  bestNextIndex = nextIndex;
2118  }
2119  }
2120  }
2121  }
2122  }
2123  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
2124  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
2125 
2126  }
2127  // set bestLaneOffset for all lanes
2128  index = 0;
2129  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
2130  if ((*j).length < clanes[bestThisIndex].length || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))) {
2131  (*j).bestLaneOffset = bestThisIndex - index;
2132  } else {
2133  (*j).bestLaneOffset = 0;
2134  }
2135  }
2136  }
2138  return;
2139 }
2140 
2141 
2142 void
2144  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
2145  std::vector<LaneQ>::iterator i;
2146  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
2147  SUMOReal nextOccupation = 0;
2148  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
2149  nextOccupation += (*j)->getBruttoVehLenSum();
2150  }
2151  (*i).nextOccupation = nextOccupation;
2152  if ((*i).lane == startLane) {
2154  }
2155  }
2156 }
2157 
2158 
2159 const std::vector<MSLane*>&
2161  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2162  return myEmptyLaneVector;
2163  }
2164  return (*myCurrentLaneInBestLanes).bestContinuations;
2165 }
2166 
2167 
2168 const std::vector<MSLane*>&
2170  const MSLane* lane = l;
2172  // internal edges are not kept inside the bestLanes structure
2173  lane = lane->getLinkCont()[0]->getLane();
2174  }
2175  if (myBestLanes.size() == 0) {
2176  return myEmptyLaneVector;
2177  }
2178  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
2179  if ((*i).lane == lane) {
2180  return (*i).bestContinuations;
2181  }
2182  }
2183  return myEmptyLaneVector;
2184 }
2185 
2186 
2187 int
2189  if (myBestLanes.empty() || myBestLanes[0].empty()) {
2190  return 0;
2191  } else {
2192  return (*myCurrentLaneInBestLanes).bestLaneOffset;
2193  }
2194 }
2195 
2196 
2197 void
2199  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
2200  assert(laneIndex < (int)preb.size());
2201  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
2202 }
2203 
2204 
2205 bool
2207  if (getPositionOnLane() > myLane->getLength()) {
2210  return true;
2211  }
2212  return false;
2213 }
2214 
2215 
2216 SUMOReal
2218 #ifdef DEBUG_VEHICLE_GUI_SELECTION
2219  SUMOReal distance = 1000000.;
2220 #else
2222 #endif
2223  if (isOnRoad() && destEdge != NULL) {
2224  if (&myLane->getEdge() == *myCurrEdge) {
2225  // vehicle is on a normal edge
2226  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
2227  } else {
2228  // vehicle is on inner junction edge
2229  distance = myLane->getLength() - getPositionOnLane();
2230  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
2231  }
2232  }
2233  return distance;
2234 }
2235 
2236 
2237 std::pair<const MSVehicle* const, SUMOReal>
2239  if (myLane == 0) {
2240  return std::make_pair(static_cast<const MSVehicle*>(0), -1);
2241  }
2242  if (dist == 0) {
2244  }
2245  const MSVehicle* lead = 0;
2246  const MSLane::VehCont& vehs = myLane->getVehiclesSecure();
2247  MSLane::VehCont::const_iterator pred = std::find(vehs.begin(), vehs.end(), this) + 1;
2248  if (pred != vehs.end()) {
2249  lead = *pred;
2250  }
2252  if (lead != 0) {
2253  return std::make_pair(lead, lead->getPositionOnLane() - lead->getVehicleType().getLength() - getPositionOnLane() - getVehicleType().getMinGap());
2254  }
2255  const SUMOReal seen = myLane->getLength() - getPositionOnLane();
2256  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
2257  return myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
2258 }
2259 
2260 
2261 SUMOReal
2263  std::pair<const MSVehicle* const, SUMOReal> leaderInfo = getLeader();
2264  if (leaderInfo.first == 0 || getSpeed() == 0) {
2265  return -1;
2266  }
2267  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
2268 }
2269 
2270 
2271 SUMOReal
2274 }
2275 
2276 
2277 SUMOReal
2280 }
2281 
2282 
2283 SUMOReal
2286 }
2287 
2288 
2289 SUMOReal
2292 }
2293 
2294 
2295 SUMOReal
2298 }
2299 
2300 
2301 SUMOReal
2304 }
2305 
2306 
2307 SUMOReal
2310 }
2311 
2312 
2313 void
2315  if (myPersonDevice == 0) {
2317  myMoveReminders.push_back(std::make_pair(myPersonDevice, 0.));
2318  }
2319  myPersonDevice->addPerson(person);
2320  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered) {
2321  unsigned int numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2322  if (numExpected != 0) {
2323  // I added the if-statement and number retrieval, assuming that it should be a "conditional short jump" only and
2324  // in most cases we won't have the list of expected passenger - only for simulating car-sharing, probably.
2325  // Bus drivers usually do not know the names of the passengers.
2326  myStops.front().awaitedPersons.erase(person->getID());
2327  numExpected = (unsigned int) myStops.front().awaitedPersons.size();
2328  }
2329  if (numExpected == 0) {
2330  myStops.front().duration = 0;
2331  }
2332  }
2333 }
2334 
2335 void
2337  if (myContainerDevice == 0) {
2339  myMoveReminders.push_back(std::make_pair(myContainerDevice, 0.));
2340  }
2341  myContainerDevice->addContainer(container);
2342  if (myStops.size() > 0 && myStops.front().reached && myStops.front().containerTriggered) {
2343  unsigned int numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2344  if (numExpected != 0) {
2345  myStops.front().awaitedContainers.erase(container->getID());
2346  numExpected = (unsigned int) myStops.front().awaitedContainers.size();
2347  }
2348  if (numExpected == 0) {
2349  myStops.front().duration = 0;
2350  }
2351  }
2352 }
2353 
2354 
2355 unsigned int
2357  unsigned int boarded = myPersonDevice == 0 ? 0 : myPersonDevice->size();
2358  return boarded + myParameter->personNumber;
2359 }
2360 
2361 unsigned int
2363  unsigned int loaded = myContainerDevice == 0 ? 0 : myContainerDevice->size();
2364  return loaded + myParameter->containerNumber;
2365 }
2366 
2367 
2368 void
2371  int state = getLaneChangeModel().getOwnState();
2372  if ((state & LCA_LEFT) != 0) {
2374  } else if ((state & LCA_RIGHT) != 0) {
2376  } else if (getLaneChangeModel().isChangingLanes()) {
2377  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
2379  } else {
2381  }
2382  } else {
2383  const MSLane* lane = getLane();
2384  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
2385  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (SUMOReal) 7.) {
2386  switch ((*link)->getDirection()) {
2387  case LINKDIR_TURN:
2388  case LINKDIR_LEFT:
2389  case LINKDIR_PARTLEFT:
2391  break;
2392  case LINKDIR_RIGHT:
2393  case LINKDIR_PARTRIGHT:
2395  break;
2396  default:
2397  break;
2398  }
2399  }
2400  }
2401 
2402 }
2403 
2404 
2405 void
2407  if (myType->amVehicleSpecific()) {
2408  delete myType;
2409  }
2410  myType = type;
2411 }
2412 
2413 unsigned int
2415  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
2416  return (unsigned int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
2417 }
2418 
2419 
2420 void
2422  assert(lane != 0);
2423  myLane = lane;
2424  myState.myPos = pos;
2425 }
2426 
2427 
2428 #ifndef NO_TRACI
2429 bool
2430 MSVehicle::addTraciStop(MSLane* const lane, const SUMOReal startPos, const SUMOReal endPos, const SUMOTime duration, const SUMOTime until,
2431  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
2432  //if the stop exists update the duration
2433  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2434  if (iter->lane == lane && fabs(iter->endPos - endPos) < POSITION_EPS) {
2435  if (duration == 0 && !iter->reached) {
2436  myStops.erase(iter);
2437  } else {
2438  iter->duration = duration;
2439  }
2440  return true;
2441  }
2442  }
2443 
2445  newStop.lane = lane->getID();
2446  newStop.startPos = startPos;
2447  newStop.endPos = endPos;
2448  newStop.duration = duration;
2449  newStop.until = until;
2450  newStop.triggered = triggered;
2451  newStop.containerTriggered = containerTriggered;
2452  newStop.parking = parking;
2453  newStop.index = STOP_INDEX_FIT;
2454  const bool result = addStop(newStop, errorMsg);
2455  if (myLane != 0) {
2456  updateBestLanes(true);
2457  }
2458  return result;
2459 }
2460 
2461 
2462 bool
2463 MSVehicle::addTraciBusOrContainerStop(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
2464  const bool triggered, const bool containerTriggered, const bool isContainerStop, std::string& errorMsg) {
2465  //if the stop exists update the duration
2466  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
2467  const Named* const stop = isContainerStop ? (Named*)iter->containerstop : iter->busstop;
2468  if (stop != 0 && stop->getID() == stopId) {
2469  if (duration == 0 && !iter->reached) {
2470  myStops.erase(iter);
2471  } else {
2472  iter->duration = duration;
2473  }
2474  return true;
2475  }
2476  }
2477 
2479  MSStoppingPlace* bs = 0;
2480  if (isContainerStop) {
2481  newStop.containerstop = stopId;
2482  bs = MSNet::getInstance()->getContainerStop(stopId);
2483  if (bs == 0) {
2484  errorMsg = "The container stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2485  return false;
2486  }
2487  } else {
2488  newStop.busstop = stopId;
2489  bs = MSNet::getInstance()->getBusStop(stopId);
2490  if (bs == 0) {
2491  errorMsg = "The bus stop '" + stopId + "' is not known for vehicle '" + getID() + "'";
2492  return false;
2493  }
2494  }
2495  newStop.duration = duration;
2496  newStop.until = until;
2497  newStop.triggered = triggered;
2498  newStop.containerTriggered = containerTriggered;
2499  newStop.parking = parking;
2500  newStop.index = STOP_INDEX_FIT;
2501  newStop.lane = bs->getLane().getID();
2502  newStop.endPos = bs->getEndLanePosition();
2503  newStop.startPos = bs->getBeginLanePosition();
2504  const bool result = addStop(newStop, errorMsg);
2505  if (myLane != 0) {
2506  updateBestLanes(true);
2507  }
2508  return result;
2509 }
2510 
2511 
2512 bool
2514  if (isStopped()) {
2518  }
2522  }
2523  // we have waited long enough and fulfilled any passenger-requirements
2524  if (myStops.front().busstop != 0) {
2525  // inform bus stop about leaving it
2526  myStops.front().busstop->leaveFrom(this);
2527  }
2528  // we have waited long enough and fulfilled any container-requirements
2529  if (myStops.front().containerstop != 0) {
2530  // inform container stop about leaving it
2531  myStops.front().containerstop->leaveFrom(this);
2532  }
2533  // the current stop is no longer valid
2535  myStops.pop_front();
2536  // do not count the stopping time towards gridlock time.
2537  // Other outputs use an independent counter and are not affected.
2538  myWaitingTime = 0;
2539  // maybe the next stop is on the same edge; let's rebuild best lanes
2540  updateBestLanes(true);
2541  // continue as wished...
2543  return true;
2544  }
2545  return false;
2546 }
2547 
2548 
2551  return myStops.front();
2552 }
2553 
2554 
2557  if (myInfluencer == 0) {
2558  myInfluencer = new Influencer();
2559  }
2560  return *myInfluencer;
2561 }
2562 
2563 
2564 SUMOReal
2566  if (myInfluencer != 0) {
2567  return myInfluencer->getOriginalSpeed();
2568  }
2569  return myState.mySpeed;
2570 }
2571 
2572 
2573 int
2575  if (hasInfluencer()) {
2577  MSNet::getInstance()->getCurrentTimeStep(),
2578  myLane->getEdge(),
2579  getLaneIndex(),
2580  state);
2581  }
2582  return state;
2583 }
2584 #endif
2585 
2586 
2587 void
2590  // here starts the vehicle internal part (see loading)
2591  std::vector<SUMOTime> internals;
2592  internals.push_back(myDeparture);
2593  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
2594  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
2597  out.closeTag();
2598 }
2599 
2600 
2601 void
2602 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
2603  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
2604  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
2605  }
2606  unsigned int routeOffset;
2607  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
2608  bis >> myDeparture;
2609  bis >> routeOffset;
2610  if (hasDeparted()) {
2611  myDeparture -= offset;
2612  myCurrEdge += routeOffset;
2613  }
2616  // no need to reset myCachedPosition here since state loading happens directly after creation
2617 }
2618 
2619 
2620 /****************************************************************************/
void resetRoutePosition(unsigned int index)
Definition: MSVehicle.cpp:511
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:844
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1181
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:2406
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:1736
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:982
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.
void remove(MSVehicle *veh)
Remove a vehicle from this transfer object.
const SUMOReal SUMO_const_laneWidth
Definition: StdDefs.h:46
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:1324
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:1180
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:1178
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived) ...
Definition: MSVehicle.h:1206
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:879
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1183
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:1200
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1173
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:2550
A lane area vehicles can halt at.
const Position geometryPositionAtOffset(SUMOReal offset) const
Definition: MSLane.h:340
DriveItemVector myLFLinkLanes
Container for used Links/visited Lanes during lookForward.
Definition: MSVehicle.h:1273
SUMOReal pos() const
Position of this state.
Definition: MSVehicle.cpp:134
bool resumeFromStopping()
Definition: MSVehicle.cpp:2513
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition) ...
Definition: MSVehicle.h:1209
bool hasInfluencer() const
Definition: MSVehicle.h:1108
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:2369
#define M_PI
Definition: angles.h:37
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:2336
SUMOReal getLeaveSpeed() const
Definition: MSVehicle.h:1265
SUMOReal myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1197
SUMOReal getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:2565
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:1040
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:597
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:444
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
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:1092
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:451
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:914
SUMOReal getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:2284
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:74
vehicle doesn&#39;t want to change
Definition: MSVehicle.h:130
unsigned int getPersonNumber() const
Returns the number of persons.
Definition: MSVehicle.cpp:2356
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:1279
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:2272
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:1259
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:2238
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
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:1214
SUMOReal processNextStop(SUMOReal currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:829
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:251
SUMOReal x() const
Returns the x-position.
Definition: Position.h:63
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:1543
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:88
#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:1768
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:1016
#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:1876
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:1327
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:101
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:540
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.
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:1801
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:60
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.
Position getPositionAtDistance(SUMOReal offset) const
Definition: Line.cpp:101
MSLane * lane
The described lane.
Definition: MSVehicle.h:462
void checkRewindLinkLanes(const SUMOReal lengthsInFront, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:1545
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:1426
#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:2362
static MSDevice_Container * buildVehicleDevices(SUMOVehicle &v, std::vector< MSDevice * > &into)
Build devices for the given vehicle, if needed.
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:1284
The vehicle got a new route.
Definition: MSNet.h:534
void workOnMoveReminders(SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:542
MSStoppingPlace * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:775
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
static bool gCheckRoutes
Definition: MSGlobals.h:80
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:2160
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
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:499
virtual MSContainerControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:693
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:1894
static void clear()
Clears the dictionary.
Definition: MSEdge.cpp:599
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:1216
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:304
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
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:677
std::list< Stop > myStops
The vehicle&#39;s list of stops.
Definition: MSVehicle.h:1188
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:805
bool isStoppedInRange(SUMOReal pos) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:823
std::pair< MSVehicle *, SUMOReal > getLastVehicleInformation() const
Returns the last vehicle which is still on the lane.
Definition: MSLane.cpp:681
int arrivalLane
(optional) The lane the vehicle shall arrive on (not used yet)
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:1258
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1176
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:1212
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 &quot;getInfluencer&quot;.
Definition: MSVehicle.h:1331
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1184
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:1238
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:1527
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:580
Definition: Line.h:51
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:68
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:189
The brake lights are on.
Definition: MSVehicle.h:772
SUMOReal estimateSpeedAfterDistance(const SUMOReal dist, const SUMOReal v, const SUMOReal accel) const
Definition: MSVehicle.h:1293
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:2602
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:430
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:1253
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:998
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.
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:1170
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
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:811
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:1888
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:2308
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:2588
void planMoveInternal(const SUMOTime t, const MSVehicle *pred, DriveItemVector &lfLinks) const
Definition: MSVehicle.cpp:962
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:2290
std::string lane
The lane to stop at.
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:532
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.
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:1833
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:2296
SUMOReal getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:2278
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:2143
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:890
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:2556
#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:2421
Structure representing possible vehicle parameter.
SUMOReal length() const
Definition: Line.cpp:192
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
SUMOReal getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MSVehicle.cpp:586
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:685
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:2206
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:1203
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:217
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: MSVehicle.h:592
SUMOReal y() const
Returns the y-position.
Definition: Position.h:68
SUMOReal getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:2302
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:1222
The action is due to the default of keeping right &quot;Rechtsfahrgebot&quot;.
The link has red light (must brake)
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
Definition: MSBaseVehicle.h:90
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:799
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MSVehicle.cpp:944
int index
at which position in the stops list
void calculateArrivalPos()
(Re-)Calculates the arrival position from the vehicle parameters
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:566
SUMOReal getDistanceToPosition(SUMOReal destPos, const MSEdge *destEdge)
Definition: MSVehicle.cpp:2217
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:2463
const SUMOReal SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:54
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:542
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:759
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:817
std::vector< DriveProcessItem > DriveItemVector
Definition: MSVehicle.h:1270
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:954
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:624
vehicle want&#39;s to keep the current lane
Definition: MSVehicle.h:136
bool hasValidRoute(std::string &msg) const
Validates the current route.
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:215
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:2314
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1185
void adaptBestLanesOccupation(int laneIndex, SUMOReal density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:2198
MSRouteIterator myCurrEdge
Iterator to current route-edge.
#define NUMERICAL_EPS
Definition: config.h:162
#define DELTA_T
Definition: SUMOTime.h:50
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:365
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:1065
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
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:2574
void activateReminders(const MSMoveReminder::Notification reason)
&quot;Activates&quot; all current move reminder
Definition: MSVehicle.cpp:1705
The edge is an internal edge.
Definition: MSEdge.h:98
SUMOReal getTimeGap() const
Returns the time gap in seconds to the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:2262
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:2430
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:1194
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle&#39;s internal edge travel times/efforts container.
Definition: MSVehicle.cpp:520
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:566
unsigned int size() const
Return the number of passengers.
Back-at-zero position.
The link has red light (must brake) but indicates upcoming green.
unsigned int getRoutePosition() const
Definition: MSVehicle.cpp:505
Interface for lane-change models.
MSDevice_Person * myPersonDevice
The passengers this vehicle may have.
Definition: MSVehicle.h:1191
int getBestLaneOffset() const
returns the current offset from the best lane
Definition: MSVehicle.cpp:2188
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:262
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:640
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:2414