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